Skip to main content

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::{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<(), Box<dyn std::error::Error>> {
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::client::{McpClient, StdioClientTransport};
57//!
58//! #[tokio::main]
59//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
60//!     // Connect to server
61//!     let transport = StdioClientTransport::spawn("my-mcp-server", &[]).await?;
62//!     let mut client = McpClient::new(transport);
63//!
64//!     // Initialize and list tools
65//!     client.initialize("my-client", "1.0.0").await?;
66//!     let tools = client.list_tools().await?;
67//!
68//!     // Call a tool
69//!     let result = client.call_tool("greet", serde_json::json!({"name": "World"})).await?;
70//!     println!("{:?}", result);
71//!
72//!     Ok(())
73//! }
74//! ```
75//!
76//! ## Key Types
77//!
78//! ### Server
79//! - [`McpRouter`] - Routes MCP requests to tools, resources, and prompts
80//! - [`ToolBuilder`] - Builder for defining tools with type-safe handlers
81//! - [`ResourceBuilder`] - Builder for defining resources
82//! - [`PromptBuilder`] - Builder for defining prompts
83//! - [`StdioTransport`] - Stdio transport for CLI servers
84//!
85//! ### Client
86//! - [`McpClient`] - Client for connecting to MCP servers
87//! - [`StdioClientTransport`] - Spawn and connect to server subprocesses
88//!
89//! ### Protocol
90//! - [`CallToolResult`] - Tool execution result with content
91//! - [`ReadResourceResult`] - Resource read result
92//! - [`GetPromptResult`] - Prompt expansion result
93//! - [`Content`] - Text, image, audio, or resource content
94//!
95//! ## Feature Flags
96//!
97//! - `http` - HTTP/SSE transport for web servers
98//! - `websocket` - WebSocket transport for bidirectional communication
99//! - `childproc` - Child process transport for subprocess management
100//!
101//! ## MCP Specification
102//!
103//! This crate implements the MCP specification (2025-03-26):
104//! <https://modelcontextprotocol.io/specification/2025-03-26>
105
106pub mod async_task;
107pub mod auth;
108pub mod client;
109pub mod context;
110pub mod error;
111pub mod jsonrpc;
112pub mod prompt;
113pub mod protocol;
114pub mod resource;
115pub mod router;
116pub mod session;
117pub mod tool;
118pub mod transport;
119
120// Re-exports
121pub use async_task::{Task, TaskStore};
122pub use client::{ClientTransport, McpClient, StdioClientTransport};
123pub use context::{
124    ChannelClientRequester, ClientRequester, ClientRequesterHandle, NotificationReceiver,
125    NotificationSender, OutgoingRequest, OutgoingRequestReceiver, OutgoingRequestSender,
126    RequestContext, RequestContextBuilder, ServerNotification, outgoing_request_channel,
127};
128pub use error::{Error, Result, ToolError};
129pub use jsonrpc::JsonRpcService;
130pub use prompt::{Prompt, PromptBuilder, PromptHandler};
131pub use protocol::{
132    CallToolResult, CompleteParams, CompleteResult, Completion, CompletionArgument,
133    CompletionReference, CompletionsCapability, Content, ContentRole, CreateMessageParams,
134    CreateMessageResult, ElicitAction, ElicitFieldValue, ElicitFormParams, ElicitFormSchema,
135    ElicitMode, ElicitRequestParams, ElicitResult, ElicitUrlParams, ElicitationCapability,
136    ElicitationCompleteParams, GetPromptResult, GetPromptResultBuilder, IncludeContext,
137    JsonRpcMessage, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseMessage, ListRootsParams,
138    ListRootsResult, McpRequest, McpResponse, ModelHint, ModelPreferences,
139    PrimitiveSchemaDefinition, PromptMessage, PromptReference, PromptRole, ReadResourceResult,
140    ResourceContent, ResourceReference, Root, RootsCapability, SamplingCapability, SamplingContent,
141    SamplingMessage,
142};
143pub use resource::{
144    Resource, ResourceBuilder, ResourceHandler, ResourceTemplate, ResourceTemplateBuilder,
145    ResourceTemplateHandler,
146};
147pub use router::{McpRouter, RouterRequest, RouterResponse};
148pub use session::{SessionPhase, SessionState};
149pub use tool::{Tool, ToolBuilder, ToolHandler};
150pub use transport::{
151    BidirectionalStdioTransport, GenericStdioTransport, StdioTransport, SyncStdioTransport,
152};
153
154#[cfg(feature = "http")]
155pub use transport::HttpTransport;
156
157#[cfg(feature = "websocket")]
158pub use transport::WebSocketTransport;
159
160#[cfg(feature = "childproc")]
161pub use transport::{ChildProcessConnection, ChildProcessTransport};