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