Skip to main content

turbomcp_protocol/
lib.rs

1//! # TurboMCP Protocol
2//!
3//! Complete Model Context Protocol (MCP) implementation in Rust, providing all protocol types,
4//! traits, context management, and message handling for building MCP applications.
5//!
6//! ## MCP Version Support
7//!
8//! TurboMCP v3.0 fully implements MCP 2025-11-25 with all specification features enabled
9//! by default. No feature flags needed for core protocol capabilities.
10//!
11//! | Specification | Status | Notes |
12//! |---------------|--------|-------|
13//! | **MCP 2025-11-25** | ✅ Full Support | Icons, URL elicitation, sampling tools, enum improvements |
14//! | **MCP 2025-06-18** | ✅ Compatible | Negotiated at runtime via protocol version |
15//!
16//! **Quick Start:**
17//! ```toml
18//! turbomcp-protocol = "3.0"
19//! ```
20//!
21//! Only the experimental Tasks API (SEP-1686) requires a feature flag:
22//! ```toml
23//! turbomcp-protocol = { version = "3.0", features = ["experimental-tasks"] }
24//! ```
25//!
26//! ## What's Inside
27//!
28//! This crate provides everything needed for MCP:
29//!
30//! - **Types**: All MCP request/response types (2025-06-18 stable + 2025-11-25 draft)
31//! - **Traits**: `ServerToClientRequests` for bidirectional communication
32//! - **Context**: Request and response context management with full observability
33//! - **JSON-RPC**: JSON-RPC 2.0 implementation with batching and notifications
34//! - **Validation**: JSON Schema validation with comprehensive constraints
35//! - **Error Handling**: Rich error types with context and tracing
36//! - **Message Handling**: Optimized message processing with zero-copy support
37//! - **Session Management**: Configurable LRU eviction and lifecycle management
38//! - **Zero-Copy**: Optional zero-copy optimizations for high performance
39//!
40//! ## Features
41//!
42//! ### Core Protocol Support (MCP 2025-06-18 Stable)
43//! - Complete MCP 2025-06-18 protocol implementation
44//! - JSON-RPC 2.0 support with batching and notifications
45//! - Type-safe capability negotiation and compatibility checking
46//! - Protocol versioning with backward compatibility
47//! - Fast serialization with SIMD acceleration
48//!
49//! ### Advanced Protocol Features (MCP 2025-06-18 Stable)
50//! - **Elicitation Protocol** - Server-initiated user input requests with rich schema validation
51//! - **Sampling Support** - Bidirectional LLM sampling with fully-typed interfaces
52//! - **Roots Protocol** - Filesystem boundaries with `roots/list` support
53//! - **Server-to-Client Requests** - Fully typed trait for sampling, elicitation, and roots
54//! - **Comprehensive Schema Builders** - Type-safe builders for all schema types
55//!
56//! ### MCP 2025-11-25 Features (Always Enabled)
57//!
58//! All core MCP 2025-11-25 specification features are now always available:
59//!
60//! | Feature | SEP | Description |
61//! |---------|-----|-------------|
62//! | URL Elicitation | SEP-1036 | URL mode for OAuth/sensitive data collection |
63//! | Sampling Tools | SEP-1577 | Tool calling in LLM sampling requests |
64//! | Icons | SEP-973 | Icon metadata for tools, resources, prompts |
65//! | Enum Improvements | SEP-1330 | Standards-based JSON Schema enum patterns |
66//!
67//! **Experimental Feature (requires feature flag):**
68//! - `experimental-tasks` - Tasks API (SEP-1686) for long-running operations
69//!
70//! **Authentication & Security** (always enabled):
71//! - SSRF protection for URL validation
72//! - Client ID Metadata Documents (CIMD) for OAuth 2.1
73//! - OpenID Connect Discovery (RFC 8414 + OIDC 1.0)
74//! - Incremental consent with WWW-Authenticate (SEP-835)
75//!
76//! ### Performance & Observability
77//! - **SIMD-Accelerated JSON** - Fast processing with `simd-json` and `sonic-rs`
78//! - **Zero-Copy Processing** - Memory-efficient message handling with `Bytes`
79//! - **Request Context** - Full request/response context tracking for observability
80//! - **Session Management** - Memory-bounded state management with cleanup tasks
81//! - **Observability Ready** - Built-in support for tracing and metrics collection
82//!
83//! ## Version Selection
84//!
85//! TurboMCP v3.0 includes all MCP 2025-11-25 features by default. Runtime protocol
86//! version negotiation determines actual feature availability per session.
87//!
88//! **Typical Usage:**
89//! ```toml
90//! [dependencies]
91//! turbomcp-protocol = "3.0"  # All core features included
92//! ```
93//!
94//! **With Experimental Tasks API:**
95//! ```toml
96//! [dependencies]
97//! turbomcp-protocol = { version = "3.0", features = ["experimental-tasks"] }
98//! ```
99//!
100//! ### Runtime Version Negotiation
101//!
102//! Clients and servers negotiate protocol versions during initialization:
103//!
104//! ```rust,no_run
105//! use turbomcp_protocol::{InitializeRequest, InitializeResult, ClientCapabilities};
106//! use turbomcp_protocol::types::{Implementation, ServerCapabilities}; // Corrected import path
107//!
108//! // Client requests draft features
109//! let request = InitializeRequest {
110//!     protocol_version: "2025-11-25".into(),  // Request draft
111//!     capabilities: ClientCapabilities::default(),
112//!     client_info: Implementation {
113//!         name: "my-client".to_string(),
114//!         title: None,
115//!         version: "1.0.0".to_string(),
116//!         ..Default::default()
117//!     },
118//!     _meta: None,
119//! };
120//!
121//! // Server responds with actual supported version
122//! // (may downgrade to 2025-06-18 if draft features unavailable)
123//! let response = InitializeResult {
124//!     protocol_version: "2025-11-25".into(),
125//!     capabilities: ServerCapabilities::default(),
126//!     server_info: Implementation {
127//!         name: "my-server".to_string(),
128//!         title: None,
129//!         version: "1.0.0".to_string(),
130//!         ..Default::default()
131//!     },
132//!     instructions: None,
133//!     _meta: None,
134//! };
135//! ```
136//!
137//! **Key Principle:** Clients request, servers decide. The negotiated version is the server's response.
138//!
139//! ## Migration from v1.x
140//!
141//! In v2.0.0, `turbomcp-core` was merged into `turbomcp-protocol` to eliminate circular
142//! dependencies and enable fully-typed bidirectional communication.
143//!
144//! ```rust,ignore
145//! // v1.x
146//! use turbomcp_protocol::{RequestContext, Error};
147//! use turbomcp_protocol::types::CreateMessageRequest;
148//!
149//! // v2.0.0
150//! use turbomcp_protocol::{RequestContext, Error, types::CreateMessageRequest};
151//! ```
152//!
153//! All functionality is preserved, just the import path changed!
154//!
155//! ## Architecture
156//!
157//! ```text
158//! turbomcp-protocol/
159//! ├── error/              # Error types and handling
160//! ├── message/            # Message types and serialization
161//! ├── context/            # Request/response context with server capabilities
162//! ├── types/              # MCP protocol types
163//! ├── jsonrpc/            # JSON-RPC 2.0 implementation
164//! ├── validation/         # Schema validation
165//! ├── session/            # Session management
166//! ├── registry/           # Component registry
167//! └── utils/              # Utility functions
168//! ```
169//!
170//! ## Server-to-Client Communication
171//!
172//! The protocol provides a `ServerToClientRequests` trait that enables server-initiated requests
173//! to clients, supporting bidirectional communication patterns like sampling and elicitation:
174//!
175//! ```rust,no_run
176//! use turbomcp_protocol::{RequestContext, types::CreateMessageRequest, ServerToClientRequests};
177//!
178//! // Tools can access server capabilities through the context
179//! async fn my_tool(ctx: RequestContext) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
180//!     if let Some(capabilities) = ctx.clone().server_to_client() {
181//!         // Make a fully-typed sampling request to the client
182//!         let request = CreateMessageRequest {
183//!             messages: vec![/* ... */],
184//!             max_tokens: 100,
185//!             model_preferences: None,
186//!             system_prompt: None,
187//!             include_context: None,
188//!             temperature: None,
189//!             stop_sequences: None,
190//!             task: None,
191//!             tools: None,
192//!             tool_choice: None,
193//!             _meta: None,
194//!         };
195//!         let response = capabilities.create_message(request, ctx).await?;
196//!     }
197//!     Ok(())
198//! }
199//! ```
200
201#![warn(
202    missing_docs,
203    missing_debug_implementations,
204    rust_2018_idioms,
205    unreachable_pub,
206    clippy::all
207)]
208#![cfg_attr(
209    all(not(feature = "mmap"), not(feature = "lock-free")),
210    deny(unsafe_code)
211)]
212#![cfg_attr(docsrs, feature(doc_cfg))]
213#![allow(
214    clippy::module_name_repetitions,
215    clippy::cast_possible_truncation,  // Intentional in metrics/performance code
216    clippy::cast_possible_wrap,  // Intentional in metrics/performance code
217    clippy::cast_precision_loss,  // Intentional for f64 metrics
218    clippy::cast_sign_loss,  // Intentional for metrics
219    clippy::must_use_candidate,  // Too pedantic for library APIs
220    clippy::return_self_not_must_use,  // Constructor methods don't need must_use
221    clippy::struct_excessive_bools,  // Sometimes bools are the right design
222    clippy::missing_panics_doc,  // Panic docs added where genuinely needed
223    clippy::default_trait_access,  // Default::default() is sometimes clearer
224    clippy::significant_drop_tightening,  // Overly pedantic about drop timing
225    clippy::used_underscore_binding,  // Sometimes underscore bindings are needed
226    clippy::wildcard_imports  // Used in test modules
227)]
228
229// v3.0: Re-export turbomcp-core foundation types
230/// Re-export of turbomcp-core, the no_std foundation layer
231pub use turbomcp_core as mcp_core;
232
233// v3.0: McpError is THE error type - re-export at crate root
234pub use turbomcp_core::error::{ErrorContext as McpErrorContext, ErrorKind, McpError, McpResult};
235/// v3.0 Result alias using McpError
236pub type Result<T> = McpResult<T>;
237/// v3.0 Error alias for migration (prefer McpError directly)
238pub type Error = McpError;
239
240// v3.0: Unified handler response types from core
241// These enable the IntoToolResponse pattern for ergonomic tool handlers
242pub use turbomcp_core::response::{Image, IntoToolError, IntoToolResponse, Json, Text, ToolError};
243
244// Core abstractions (merged from turbomcp-core in v2.0.0)
245/// Configuration for protocol components.
246pub mod config;
247/// Request/response context, including server-to-client capabilities.
248pub mod context;
249/// An advanced handler registry with metrics and enhanced features.
250pub mod enhanced_registry;
251/// Error types and handling for the protocol.
252pub mod error;
253/// Utilities for creating and working with protocol errors.
254pub mod error_utils;
255/// Traits and types for handling different MCP requests (tools, prompts, etc.).
256pub mod handlers;
257/// Lock-free data structures for high-performance concurrent scenarios.
258#[cfg(feature = "lock-free")]
259pub mod lock_free;
260/// Core message types and serialization logic.
261pub mod message;
262/// Basic handler registration and lookup.
263pub mod registry;
264/// Security-related utilities, such as path validation.
265pub mod security;
266/// Session management for client connections.
267pub mod session;
268/// Utilities for shared, concurrent state management.
269pub mod shared;
270/// State management for the protocol.
271pub mod state;
272/// General utility functions.
273pub mod utils;
274/// Zero-copy data handling utilities for performance-critical operations.
275pub mod zero_copy;
276
277/// Zero-copy rkyv bridge for internal message routing.
278///
279/// This module is only available when the `rkyv` feature is enabled.
280/// It provides efficient conversion between JSON-RPC and rkyv internal formats.
281#[cfg(feature = "rkyv")]
282#[cfg_attr(docsrs, doc(cfg(feature = "rkyv")))]
283pub mod rkyv_bridge;
284
285/// Wire codec integration for message serialization.
286///
287/// This module provides a unified interface for encoding/decoding MCP messages
288/// using the [`turbomcp_wire`] codec abstraction.
289///
290/// Enable with the `wire` feature flag. Optional SIMD acceleration available
291/// with `wire-simd`, and MessagePack support with `wire-msgpack`.
292#[cfg(feature = "wire")]
293#[cfg_attr(docsrs, doc(cfg(feature = "wire")))]
294pub mod codec;
295
296// Protocol-specific modules
297/// Capability negotiation and management.
298pub mod capabilities;
299// Old elicitation module removed - use types::elicitation instead (MCP 2025-06-18 compliant)
300/// JSON-RPC 2.0 protocol implementation.
301pub mod jsonrpc;
302/// All MCP protocol types (requests, responses, and data structures).
303pub mod types;
304/// Schema validation for protocol messages.
305pub mod validation;
306/// Protocol version management and compatibility checking.
307pub mod versioning;
308
309// Test utilities (public to allow downstream crates to use them in tests)
310// Following the pattern from axum and tokio
311/// Public test utilities for use in downstream crates.
312pub mod test_helpers;
313
314// Re-export core types
315pub use context::{
316    BidirectionalContext, ClientCapabilities as ContextClientCapabilities, ClientId,
317    ClientIdExtractor, ClientSession, CommunicationDirection, CommunicationInitiator,
318    CompletionCapabilities, CompletionContext, CompletionOption,
319    CompletionReference as ContextCompletionReference, ConnectionMetrics, ElicitationContext,
320    ElicitationState, PingContext, PingOrigin, RequestContext, RequestContextExt, RequestInfo,
321    ResourceTemplateContext, ResponseContext, RichContextExt, ServerInitiatedContext,
322    ServerInitiatedType, ServerToClientRequests, SessionStateGuard, StateError, TemplateParameter,
323    active_sessions_count, cleanup_session_state,
324};
325// Timestamp and ContentType are now in types module
326pub use enhanced_registry::{EnhancedRegistry, HandlerStats};
327// v3.0: McpError is re-exported from turbomcp_core at crate root
328pub use error::RetryInfo;
329pub use handlers::{
330    CompletionItem, CompletionProvider, ElicitationHandler, ElicitationResponse,
331    HandlerCapabilities, JsonRpcHandler, PingHandler, PingResponse, ResolvedResource,
332    ResourceTemplate as HandlerResourceTemplate, ResourceTemplateHandler, ServerInfo,
333    ServerInitiatedCapabilities, TemplateParam,
334};
335pub use message::{Message, MessageId, MessageMetadata};
336pub use registry::RegistryError;
337pub use security::{validate_file_extension, validate_path, validate_path_within};
338pub use session::{SessionAnalytics, SessionConfig, SessionManager};
339pub use shared::{ConsumableShared, Shareable, Shared, SharedError};
340pub use state::StateManager;
341
342// Re-export ONLY essential types at root (v2.0 - improved ergonomics)
343// Everything else requires module qualification: turbomcp_protocol::types::*
344pub use types::{
345    // Most common tool operations
346    CallToolRequest,
347    CallToolResult,
348
349    ClientCapabilities,
350    // Macro API types (used by generated code - not typically imported by users)
351    GetPromptRequest,
352    GetPromptResult,
353    // Most common request/response pairs (initialization flow)
354    InitializeRequest,
355    InitializeResult,
356
357    ReadResourceRequest,
358    ReadResourceResult,
359
360    // Capability negotiation (used in every initialize)
361    ServerCapabilities,
362};
363
364// Note: types module is already declared as `pub mod types;` above
365// Users access other types via turbomcp_protocol::types::Tool, etc.
366
367pub use jsonrpc::{
368    JsonRpcError, JsonRpcErrorCode, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse,
369    JsonRpcVersion,
370};
371
372pub use capabilities::{
373    CapabilityMatcher, CapabilityNegotiator, CapabilitySet,
374    builders::{
375        ClientCapabilitiesBuilder, ClientCapabilitiesBuilderState, ServerCapabilitiesBuilder,
376        ServerCapabilitiesBuilderState,
377    },
378};
379
380pub use versioning::{VersionCompatibility, VersionManager, VersionRequirement};
381
382// Re-export constants from core (single source of truth - DRY)
383pub use turbomcp_core::{
384    DEFAULT_TIMEOUT_MS, MAX_MESSAGE_SIZE, PROTOCOL_VERSION, SDK_NAME, SDK_VERSION,
385    SUPPORTED_VERSIONS, error_codes, features, methods,
386};
387
388#[cfg(test)]
389mod tests {
390    use super::*;
391
392    #[test]
393    fn test_version_constants() {
394        assert_eq!(PROTOCOL_VERSION, "2025-11-25");
395        assert!(SUPPORTED_VERSIONS.contains(&PROTOCOL_VERSION));
396        // Latest should be first in supported versions
397        assert_eq!(SUPPORTED_VERSIONS[0], PROTOCOL_VERSION);
398    }
399
400    #[test]
401    fn test_size_constants() {
402        // Constants are statically verified at compile-time
403        const _: () = assert!(
404            MAX_MESSAGE_SIZE > 1024,
405            "MAX_MESSAGE_SIZE must be larger than 1KB"
406        );
407        const _: () = assert!(
408            MAX_MESSAGE_SIZE == 1024 * 1024,
409            "MAX_MESSAGE_SIZE must be 1MB for security"
410        );
411
412        const _: () = assert!(
413            DEFAULT_TIMEOUT_MS > 1000,
414            "DEFAULT_TIMEOUT_MS must be larger than 1 second"
415        );
416        const _: () = assert!(
417            DEFAULT_TIMEOUT_MS == 30_000,
418            "DEFAULT_TIMEOUT_MS must be 30 seconds"
419        );
420    }
421
422    #[test]
423    fn test_method_names() {
424        assert_eq!(methods::INITIALIZE, "initialize");
425        assert_eq!(methods::LIST_TOOLS, "tools/list");
426        assert_eq!(methods::CALL_TOOL, "tools/call");
427    }
428
429    #[test]
430    fn test_error_codes() {
431        assert_eq!(error_codes::PARSE_ERROR, -32700);
432        assert_eq!(error_codes::TOOL_NOT_FOUND, -32001);
433    }
434}