tower_mcp/lib.rs
1//! # tower-mcp
2//!
3//! Tower-native Model Context Protocol (MCP) implementation for Rust.
4//!
5//! This crate provides a composable, middleware-friendly approach to building
6//! MCP servers and clients using the [Tower](https://docs.rs/tower) service abstraction.
7//!
8//! ## Philosophy
9//!
10//! Unlike framework-style MCP implementations, tower-mcp treats MCP as just another
11//! protocol that can be served through Tower's `Service` trait. This means:
12//!
13//! - Standard tower middleware (tracing, metrics, rate limiting, auth) just works
14//! - Same service can be exposed over multiple transports (stdio, HTTP, WebSocket)
15//! - Easy integration with existing tower-based applications (axum, tonic, etc.)
16//!
17//! ## Quick Start: Server
18//!
19//! Build an MCP server with tools, resources, and prompts:
20//!
21//! ```rust,no_run
22//! use tower_mcp::{BoxError, McpRouter, ToolBuilder, CallToolResult, StdioTransport};
23//! use schemars::JsonSchema;
24//! use serde::Deserialize;
25//!
26//! #[derive(Debug, Deserialize, JsonSchema)]
27//! struct GreetInput {
28//! name: String,
29//! }
30//!
31//! #[tokio::main]
32//! async fn main() -> Result<(), BoxError> {
33//! // Define a tool
34//! let greet = ToolBuilder::new("greet")
35//! .description("Greet someone by name")
36//! .handler(|input: GreetInput| async move {
37//! Ok(CallToolResult::text(format!("Hello, {}!", input.name)))
38//! })
39//! .build()?;
40//!
41//! // Create router and run over stdio
42//! let router = McpRouter::new()
43//! .server_info("my-server", "1.0.0")
44//! .tool(greet);
45//!
46//! StdioTransport::new(router).run().await?;
47//! Ok(())
48//! }
49//! ```
50//!
51//! ## Quick Start: Client
52//!
53//! Connect to an MCP server and call tools:
54//!
55//! ```rust,no_run
56//! use tower_mcp::BoxError;
57//! use tower_mcp::client::{McpClient, StdioClientTransport};
58//!
59//! #[tokio::main]
60//! async fn main() -> Result<(), BoxError> {
61//! // Connect to server
62//! let transport = StdioClientTransport::spawn("my-mcp-server", &[]).await?;
63//! let mut client = McpClient::new(transport);
64//!
65//! // Initialize and list tools
66//! client.initialize("my-client", "1.0.0").await?;
67//! let tools = client.list_tools().await?;
68//!
69//! // Call a tool
70//! let result = client.call_tool("greet", serde_json::json!({"name": "World"})).await?;
71//! println!("{:?}", result);
72//!
73//! Ok(())
74//! }
75//! ```
76//!
77//! ## Key Types
78//!
79//! ### Server
80//! - [`McpRouter`] - Routes MCP requests to tools, resources, and prompts
81//! - [`ToolBuilder`] - Builder for defining tools with type-safe handlers
82//! - [`ResourceBuilder`] - Builder for defining resources
83//! - [`PromptBuilder`] - Builder for defining prompts
84//! - [`StdioTransport`] - Stdio transport for CLI servers
85//!
86//! ### Client
87//! - [`McpClient`] - Client for connecting to MCP servers
88//! - [`StdioClientTransport`] - Spawn and connect to server subprocesses
89//!
90//! ### Protocol
91//! - [`CallToolResult`] - Tool execution result with content
92//! - [`ReadResourceResult`] - Resource read result
93//! - [`GetPromptResult`] - Prompt expansion result
94//! - [`Content`] - Text, image, audio, or resource content
95//!
96//! ## Feature Flags
97//!
98//! - `full` - Enable all optional features
99//! - `http` - HTTP/SSE transport for web servers
100//! - `websocket` - WebSocket transport for bidirectional communication
101//! - `childproc` - Child process transport for subprocess management
102//! - `oauth` - OAuth 2.1 resource server support (token validation, metadata endpoint)
103//! - `testing` - Test utilities ([`TestClient`]) for ergonomic MCP server testing
104//!
105//! ## MCP Specification
106//!
107//! This crate implements the MCP specification (2025-11-25):
108//! <https://modelcontextprotocol.io/specification/2025-11-25>
109
110pub mod async_task;
111pub mod auth;
112pub mod client;
113pub mod context;
114pub mod error;
115pub mod filter;
116pub mod jsonrpc;
117#[cfg(feature = "oauth")]
118pub mod oauth;
119pub mod prompt;
120pub mod protocol;
121pub mod resource;
122pub mod router;
123pub mod session;
124#[cfg(feature = "testing")]
125pub mod testing;
126pub mod tool;
127pub mod transport;
128
129// Re-exports
130pub use async_task::{Task, TaskStore};
131pub use client::{ClientTransport, McpClient, StdioClientTransport};
132pub use context::{
133 ChannelClientRequester, ClientRequester, ClientRequesterHandle, NotificationReceiver,
134 NotificationSender, OutgoingRequest, OutgoingRequestReceiver, OutgoingRequestSender,
135 RequestContext, RequestContextBuilder, ServerNotification, outgoing_request_channel,
136};
137pub use error::{BoxError, Error, Result, ToolError};
138pub use filter::{
139 CapabilityFilter, DenialBehavior, Filterable, PromptFilter, ResourceFilter, ToolFilter,
140};
141pub use jsonrpc::{JsonRpcLayer, JsonRpcService};
142pub use prompt::{Prompt, PromptBuilder, PromptHandler};
143pub use protocol::{
144 CallToolResult, CompleteParams, CompleteResult, Completion, CompletionArgument,
145 CompletionReference, CompletionsCapability, Content, ContentRole, CreateMessageParams,
146 CreateMessageResult, ElicitAction, ElicitFieldValue, ElicitFormParams, ElicitFormSchema,
147 ElicitMode, ElicitRequestParams, ElicitResult, ElicitUrlParams, ElicitationCapability,
148 ElicitationCompleteParams, GetPromptResult, GetPromptResultBuilder, IncludeContext,
149 JsonRpcMessage, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseMessage, ListRootsParams,
150 ListRootsResult, McpRequest, McpResponse, ModelHint, ModelPreferences,
151 PrimitiveSchemaDefinition, PromptMessage, PromptReference, PromptRole, ReadResourceResult,
152 ResourceContent, ResourceReference, Root, RootsCapability, SamplingCapability, SamplingContent,
153 SamplingContentOrArray, SamplingMessage, SamplingTool, ToolChoice,
154};
155pub use resource::{
156 Resource, ResourceBuilder, ResourceHandler, ResourceTemplate, ResourceTemplateBuilder,
157 ResourceTemplateHandler,
158};
159pub use router::{Extensions, McpRouter, RouterRequest, RouterResponse};
160pub use session::{SessionPhase, SessionState};
161pub use tool::{NoParams, Tool, ToolBuilder, ToolHandler};
162pub use transport::{
163 BidirectionalStdioTransport, CatchError, GenericStdioTransport, StdioTransport,
164 SyncStdioTransport,
165};
166
167#[cfg(feature = "http")]
168pub use transport::HttpTransport;
169
170#[cfg(feature = "websocket")]
171pub use transport::WebSocketTransport;
172
173#[cfg(any(feature = "http", feature = "websocket"))]
174pub use transport::McpBoxService;
175
176#[cfg(feature = "childproc")]
177pub use transport::{ChildProcessConnection, ChildProcessTransport};
178
179#[cfg(feature = "oauth")]
180pub use oauth::{ScopeEnforcementLayer, ScopeEnforcementService};
181
182#[cfg(feature = "jwks")]
183pub use oauth::{JwksError, JwksValidator, JwksValidatorBuilder};
184
185#[cfg(feature = "testing")]
186pub use testing::TestClient;