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}