Skip to content

MCP Server Overview

The Model Context Protocol (MCP) is a JSON-RPC 2.0 standard that lets AI agents (Claude Desktop, Cursor, custom agents) call server-defined tools, read resources, and retrieve prompt templates over plain HTTP. rust-web-server ships a first-class McpServer that implements the MCP 2024-11-05 specification with no external dependencies.

Creating an MCP server

use rust_web_server::server::Server;
use rust_web_server::mcp::{McpServer, McpContent, PromptMessage};
let mcp = McpServer::new("my-server", "1.0")
.tool(
"echo",
"Echo text back to the caller",
r#"{"type":"object","properties":{"text":{"type":"string"}},"required":["text"]}"#,
|args| {
let text = rust_web_server::mcp::extract_arg(args, "text")
.unwrap_or_else(|| "(nothing)".to_string());
Ok(McpContent::text(text))
},
)
.resource(
"docs://{topic}",
"Documentation",
"Return documentation for a topic",
|uri| Ok(McpContent::text(format!("Docs for: {uri}"))),
)
.prompt(
"summarize",
"Summarize the given text",
|args| {
let text = rust_web_server::mcp::extract_arg(args, "text")
.unwrap_or_else(|| "some text".to_string());
Ok(vec![PromptMessage::user(format!("Please summarize: {text}"))])
},
);
// Pass directly to the server — McpServer implements Application.
// let (listener, pool) = Server::setup().unwrap();
// Server::run(listener, pool, mcp);

Attaching MCP to an existing app

If you already have routes, state, or middleware, use .wrap() so that non-MCP requests fall through to your existing Application:

use rust_web_server::app::App;
use rust_web_server::core::New;
use rust_web_server::mcp::{McpContent};
let server = App::new()
.mcp("my-server", "1.0")
.tool("ping", "Ping the server", "{}", |_| Ok(McpContent::text("pong")))
.wrap(App::new()); // non-MCP requests handled by the built-in App

MCP endpoint

All JSON-RPC 2.0 messages travel over POST /mcp. The endpoint handles the full MCP lifecycle:

JSON-RPC methodPurpose
initializeCapability negotiation and server info
pingLiveness check
tools/listList all registered tools
tools/callInvoke a tool by name
resources/listList all registered resources
resources/readRead a resource by URI
prompts/listList all registered prompt templates
prompts/getRetrieve a rendered prompt by name

OPTIONS /mcp is also handled for CORS preflight. All other methods return 405 Method Not Allowed.

Override the default path with .at("/custom-path") if needed.

Built-in rws tools

The binary ships 8 built-in tools when run in MCP mode via app.mcp(...):

Tool nameDescription
server_configReturn current server configuration
feature_flagsList compiled feature flags
server_metricsPrometheus-format metrics snapshot
rate_limit_configCurrent rate limit settings
check_rate_limitCheck remaining quota for a client IP
cors_configActive CORS rules
list_static_filesFiles served from the static root
reload_configTrigger a hot config reload

Connecting Claude Desktop

Add the server to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
"mcpServers": {
"my-server": {
"url": "http://localhost:7878/mcp"
}
}
}

With bearer token authentication:

{
"mcpServers": {
"my-server": {
"url": "http://localhost:7878/mcp",
"headers": {
"Authorization": "Bearer your-token-here"
}
}
}
}

Connecting Cursor

In Cursor settings under MCP Servers, add:

{
"my-server": {
"url": "http://localhost:7878/mcp"
}
}

Or for HTTPS deployments:

{
"my-server": {
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer your-token-here"
}
}
}