Skip to main content

llm_kernel/mcp/
mod.rs

1//! MCP (Model Context Protocol) server framework.
2//!
3//! Provides a JSON-RPC 2.0 dispatch layer for building MCP servers in Rust.
4//! Supports both stdio and HTTP transports.
5//!
6//! ## Quick start
7//!
8//! ```
9//! use llm_kernel::mcp::{McpServer, ToolDescription, JsonRpcDispatcher};
10//!
11//! let mut server = McpServer::new("my-server", "1.0.0");
12//!
13//! server.register_tool(ToolDescription {
14//!     name: "greet".into(),
15//!     description: "Say hello".into(),
16//!     input_schema: serde_json::json!({
17//!         "type": "object",
18//!         "properties": {
19//!             "name": { "type": "string" }
20//!         }
21//!     }),
22//! });
23//!
24//! server.set_handler("greet", |_params| {
25//!     Ok(serde_json::json!({ "greeting": "Hello!" }))
26//! });
27//!
28//! // Route a JSON-RPC request through the stdio dispatcher.
29//! let dispatcher = JsonRpcDispatcher::new(&server);
30//! let response = dispatcher
31//!     .dispatch(r#"{"jsonrpc":"2.0","id":1,"method":"tools/list"}"#)
32//!     .unwrap();
33//! assert!(response.contains("greet"));
34//! ```
35
36pub mod auth;
37pub mod schema;
38pub mod server;
39pub mod transport;
40
41pub use auth::BearerAuth;
42pub use schema::{PromptArgument, PromptDescription, ResourceDescription, ToolDescription};
43pub use server::{
44    AsyncToolHandler, Handler, LATEST_PROTOCOL_VERSION, LEGACY_LATEST_PROTOCOL_VERSION,
45    LEGACY_PROTOCOL_VERSIONS, META_PROTOCOL_VERSION, META_SERVER_INFO, META_SUBSCRIPTION_ID,
46    McpServer, SUPPORTED_PROTOCOL_VERSIONS, request_protocol_version,
47};
48pub use transport::JsonRpcDispatcher;
49
50/// Streamable HTTP remote transport for MCP (axum + tokio).
51#[cfg(feature = "mcp-http")]
52pub mod http;
53#[cfg(feature = "mcp-http")]
54pub use http::{HttpTransport, serve};
55
56/// MCP notification types for server-initiated messages.
57#[derive(Debug, Clone)]
58pub enum McpNotification {
59    /// The list of available tools has changed.
60    ToolsListChanged,
61    /// The list of available resources has changed.
62    ResourcesListChanged,
63    /// Progress notification for a long-running operation.
64    Progress {
65        /// Opaque token identifying the in-progress operation.
66        progress_token: String,
67        /// Current progress value.
68        progress: u64,
69        /// Total expected value, if known.
70        total: Option<u64>,
71    },
72}
73
74impl McpServer {
75    /// Format a notification as a JSON-RPC message string.
76    pub fn format_notification(&self, notification: McpNotification) -> String {
77        let method = match &notification {
78            McpNotification::ToolsListChanged => "notifications/tools/list_changed",
79            McpNotification::ResourcesListChanged => "notifications/resources/list_changed",
80            McpNotification::Progress { .. } => "notifications/progress",
81        };
82        let mut params = serde_json::json!({});
83        if let McpNotification::Progress {
84            progress_token,
85            progress,
86            total,
87        } = &notification
88        {
89            params["progressToken"] = serde_json::json!(progress_token);
90            params["progress"] = serde_json::json!(progress);
91            if let Some(t) = total {
92                params["total"] = serde_json::json!(t);
93            }
94        }
95        serde_json::to_string(&serde_json::json!({
96            "jsonrpc": "2.0",
97            "method": method,
98            "params": params,
99        }))
100        .unwrap_or_default()
101    }
102}