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 ¬ification {
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 } = ¬ification
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}