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 jsonrpc;
116#[cfg(feature = "oauth")]
117pub mod oauth;
118pub mod prompt;
119pub mod protocol;
120pub mod resource;
121pub mod router;
122pub mod session;
123#[cfg(feature = "testing")]
124pub mod testing;
125pub mod tool;
126pub mod transport;
127
128// Re-exports
129pub use async_task::{Task, TaskStore};
130pub use client::{ClientTransport, McpClient, StdioClientTransport};
131pub use context::{
132 ChannelClientRequester, ClientRequester, ClientRequesterHandle, NotificationReceiver,
133 NotificationSender, OutgoingRequest, OutgoingRequestReceiver, OutgoingRequestSender,
134 RequestContext, RequestContextBuilder, ServerNotification, outgoing_request_channel,
135};
136pub use error::{BoxError, Error, Result, ToolError};
137pub use jsonrpc::{JsonRpcLayer, JsonRpcService};
138pub use prompt::{Prompt, PromptBuilder, PromptHandler};
139pub use protocol::{
140 CallToolResult, CompleteParams, CompleteResult, Completion, CompletionArgument,
141 CompletionReference, CompletionsCapability, Content, ContentRole, CreateMessageParams,
142 CreateMessageResult, ElicitAction, ElicitFieldValue, ElicitFormParams, ElicitFormSchema,
143 ElicitMode, ElicitRequestParams, ElicitResult, ElicitUrlParams, ElicitationCapability,
144 ElicitationCompleteParams, GetPromptResult, GetPromptResultBuilder, IncludeContext,
145 JsonRpcMessage, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseMessage, ListRootsParams,
146 ListRootsResult, McpRequest, McpResponse, ModelHint, ModelPreferences,
147 PrimitiveSchemaDefinition, PromptMessage, PromptReference, PromptRole, ReadResourceResult,
148 ResourceContent, ResourceReference, Root, RootsCapability, SamplingCapability, SamplingContent,
149 SamplingContentOrArray, SamplingMessage, SamplingTool, ToolChoice,
150};
151pub use resource::{
152 Resource, ResourceBuilder, ResourceHandler, ResourceTemplate, ResourceTemplateBuilder,
153 ResourceTemplateHandler,
154};
155pub use router::{Extensions, McpRouter, RouterRequest, RouterResponse};
156pub use session::{SessionPhase, SessionState};
157pub use tool::{Tool, ToolBuilder, ToolHandler};
158pub use transport::{
159 BidirectionalStdioTransport, CatchError, GenericStdioTransport, StdioTransport,
160 SyncStdioTransport,
161};
162
163#[cfg(feature = "http")]
164pub use transport::HttpTransport;
165
166#[cfg(feature = "websocket")]
167pub use transport::WebSocketTransport;
168
169#[cfg(any(feature = "http", feature = "websocket"))]
170pub use transport::McpBoxService;
171
172#[cfg(feature = "childproc")]
173pub use transport::{ChildProcessConnection, ChildProcessTransport};
174
175#[cfg(feature = "oauth")]
176pub use oauth::{ScopeEnforcementLayer, ScopeEnforcementService};
177
178#[cfg(feature = "jwks")]
179pub use oauth::{JwksError, JwksValidator, JwksValidatorBuilder};
180
181#[cfg(feature = "testing")]
182pub use testing::TestClient;