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, McpServer, SUPPORTED_PROTOCOL_VERSIONS,
45};
46pub use transport::JsonRpcDispatcher;
47
48/// HTTP/SSE remote transport for MCP (axum + tokio).
49#[cfg(feature = "mcp-http")]
50pub mod http;
51#[cfg(feature = "mcp-http")]
52pub use http::{HttpTransport, serve};
53
54/// MCP notification types for server-initiated messages.
55#[derive(Debug, Clone)]
56pub enum McpNotification {
57 /// The list of available tools has changed.
58 ToolsListChanged,
59 /// The list of available resources has changed.
60 ResourcesListChanged,
61 /// Progress notification for a long-running operation.
62 Progress {
63 /// Opaque token identifying the in-progress operation.
64 progress_token: String,
65 /// Current progress value.
66 progress: u64,
67 /// Total expected value, if known.
68 total: Option<u64>,
69 },
70}
71
72impl McpServer {
73 /// Format a notification as a JSON-RPC message string.
74 pub fn format_notification(&self, notification: McpNotification) -> String {
75 let method = match ¬ification {
76 McpNotification::ToolsListChanged => "notifications/tools/list_changed",
77 McpNotification::ResourcesListChanged => "notifications/resources/list_changed",
78 McpNotification::Progress { .. } => "notifications/progress",
79 };
80 let mut params = serde_json::json!({});
81 if let McpNotification::Progress {
82 progress_token,
83 progress,
84 total,
85 } = ¬ification
86 {
87 params["progressToken"] = serde_json::json!(progress_token);
88 params["progress"] = serde_json::json!(progress);
89 if let Some(t) = total {
90 params["total"] = serde_json::json!(t);
91 }
92 }
93 serde_json::to_string(&serde_json::json!({
94 "jsonrpc": "2.0",
95 "method": method,
96 "params": params,
97 }))
98 .unwrap_or_default()
99 }
100}