use std::net::SocketAddr;
use fastmcp_rs::{
FastMcpServer,
http::start_http,
mcp_register_tools,
mcp_response,
mcp_text,
tool::ToolResponse,
};
use serde_json::Value;
#[fastmcp_rs_macros::mcp_tool(
name = "url_info",
description = "Returns simple info about a URL string",
parameters_json(
"type": "object",
"required": ["url"],
"properties": { "url": { "type": "string" } }
)
)]
async fn url_info(_: fastmcp_rs::InvocationContext, payload: Value) -> fastmcp_rs::Result<ToolResponse> {
let url = payload.get("url").and_then(Value::as_str).ok_or_else(|| fastmcp_rs::FastMcpError::InvalidInvocation("expected string 'url'".into()))?;
let info = format!("url='{}' length={}", url, url.len());
Ok(mcp_response!([ mcp_text!(info) ]))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();
let server = FastMcpServer::builder()
.name("HttpAttr")
.instructions("Call url_info over HTTP")
.build()
.into_shared();
mcp_register_tools!(server, [ url_info_tool() ]);
let addr = SocketAddr::from(([127, 0, 0, 1], 0));
let handle = start_http(server.clone(), addr).await?;
tracing::info!("HTTP server listening on {}", handle.addr());
tokio::signal::ctrl_c().await?;
handle.shutdown().await;
Ok(())
}