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//! ## Familiar to axum Users
18//!
19//! If you've used [axum](https://docs.rs/axum), tower-mcp's API will feel familiar.
20//! We've adopted axum's patterns for a consistent Rust web ecosystem experience:
21//!
22//! - **Extractor pattern**: Tool handlers use extractors like [`extract::State<T>`],
23//! [`extract::Json<T>`], and [`extract::Context`] - just like axum's request extractors
24//! - **Router composition**: [`McpRouter::merge()`] and [`McpRouter::nest()`] work like
25//! axum's router methods for combining routers
26//! - **Per-route middleware**: Apply Tower layers to individual tools, resources, or
27//! prompts via `.layer()` on builders
28//! - **Builder pattern**: Fluent builders for tools, resources, and prompts
29//!
30//! ```rust
31//! use std::sync::Arc;
32//! use tower_mcp::{ToolBuilder, CallToolResult};
33//! use tower_mcp::extract::{State, Json, Context};
34//! use schemars::JsonSchema;
35//! use serde::Deserialize;
36//!
37//! #[derive(Clone)]
38//! struct AppState { db_url: String }
39//!
40//! #[derive(Deserialize, JsonSchema)]
41//! struct SearchInput { query: String }
42//!
43//! // Looks just like an axum handler!
44//! let tool = ToolBuilder::new("search")
45//! .title("Search Database")
46//! .description("Search the database")
47//! .extractor_handler(
48//! Arc::new(AppState { db_url: "postgres://...".into() }),
49//! |State(app): State<Arc<AppState>>,
50//! ctx: Context,
51//! Json(input): Json<SearchInput>| async move {
52//! ctx.report_progress(0.5, Some(1.0), Some("Searching...")).await;
53//! Ok(CallToolResult::text(format!("Found results for: {}", input.query)))
54//! },
55//! )
56//! .build();
57//! ```
58//!
59//! ## Quick Start: Server
60//!
61//! Build an MCP server with tools, resources, and prompts:
62//!
63//! ```rust,no_run
64//! use tower_mcp::{BoxError, McpRouter, ToolBuilder, CallToolResult, StdioTransport};
65//! use schemars::JsonSchema;
66//! use serde::Deserialize;
67//!
68//! #[derive(Debug, Deserialize, JsonSchema)]
69//! struct GreetInput {
70//! name: String,
71//! }
72//!
73//! #[tokio::main]
74//! async fn main() -> Result<(), BoxError> {
75//! // Define a tool
76//! let greet = ToolBuilder::new("greet")
77//! .title("Greet")
78//! .description("Greet someone by name")
79//! .handler(|input: GreetInput| async move {
80//! Ok(CallToolResult::text(format!("Hello, {}!", input.name)))
81//! })
82//! .build();
83//!
84//! // Create router and run over stdio
85//! let router = McpRouter::new()
86//! .server_info("my-server", "1.0.0")
87//! .tool(greet);
88//!
89//! StdioTransport::new(router).run().await?;
90//! Ok(())
91//! }
92//! ```
93//!
94//! ## Quick Start: Client
95//!
96//! Connect to an MCP server and call tools:
97//!
98//! ```rust,no_run
99//! use tower_mcp::BoxError;
100//! use tower_mcp::client::{McpClient, StdioClientTransport};
101//!
102//! #[tokio::main]
103//! async fn main() -> Result<(), BoxError> {
104//! // Connect to server
105//! let transport = StdioClientTransport::spawn("my-mcp-server", &[]).await?;
106//! let client = McpClient::connect(transport).await?;
107//!
108//! // Initialize and list tools
109//! client.initialize("my-client", "1.0.0").await?;
110//! let tools = client.list_tools().await?;
111//!
112//! // Call a tool
113//! let result = client.call_tool("greet", serde_json::json!({"name": "World"})).await?;
114//! println!("{:?}", result);
115//!
116//! Ok(())
117//! }
118//! ```
119//!
120//! ## Key Types
121//!
122//! ### Server
123//! - [`McpRouter`] - Routes MCP requests to tools, resources, and prompts
124//! - [`ToolBuilder`] - Builder for defining tools with type-safe handlers
125//! - [`ResourceBuilder`] - Builder for defining resources
126//! - [`PromptBuilder`] - Builder for defining prompts
127//! - [`StdioTransport`] - Stdio transport for CLI servers
128//! - [`McpAppResourceBuilder`] - Typed `ui://` resources for MCP Apps (requires `mcp-apps`)
129//!
130//! ### Client
131//! - [`McpClient`] - Client for connecting to MCP servers
132//! - [`StdioClientTransport`] - Spawn and connect to server subprocesses
133//!
134//! ### Protocol
135//! - [`CallToolResult`] - Tool execution result with content
136//! - [`ReadResourceResult`] - Resource read result
137//! - [`GetPromptResult`] - Prompt expansion result
138//! - [`Content`] - Text, image, audio, or resource content
139//!
140//! ### Released 2026-07-28 protocol (requires `protocol-2026-07-28`)
141//! - [`stateless::StatelessRequestMeta`] - Per-request `_meta` carrying protocol version,
142//! client identity, and client capabilities for sessionless 2026-07-28 requests
143//! - [`RequestOutcome`] and [`InputRequiredResult`] - SEP-2322 Multi Round-Trip Request results
144//! - [`RequestStateCodec`] - Expiring, integrity-protected continuation state
145//! - `McpClient::discover` - Sessionless client discovery with per-request metadata,
146//! runtime version selection, SEP-2243 headers, and bounded MRTR auto-driving
147//! - `McpClient::listen_subscriptions` - Long-lived, correlated notification streams with
148//! typed acknowledgments and transport-specific cancellation
149//!
150//! ## Feature Flags
151//!
152//! - `full` - Enable all optional features
153//! - `http` - HTTP/SSE transport for web servers (adds axum, hyper)
154//! - `websocket` - WebSocket transport for bidirectional communication
155//! - `childproc` - Child process transport for subprocess management
156//! - `oauth` - OAuth 2.1 resource server support (JWT validation, metadata endpoint; requires `http`)
157//! - `jwks` - JWKS endpoint fetching for remote key sets (requires `oauth`)
158//! - `testing` - Test utilities (`TestClient`) for ergonomic MCP server testing
159//! - `dynamic-tools` - Runtime registration/deregistration of tools, prompts, and resources via
160//! [`DynamicToolRegistry`], [`DynamicPromptRegistry`], [`DynamicResourceRegistry`],
161//! [`DynamicResourceTemplateRegistry`]
162//! - `proxy` - Multi-server aggregation proxy ([`McpProxy`](proxy::McpProxy))
163//! - `http-client` - HTTP client transport for connecting to remote MCP servers
164//! - `oauth-client` - OAuth client support: authorization code with PKCE,
165//! registration, refresh and scope escalation; client credentials; discovery;
166//! and custom token providers (requires `http-client`)
167//! - `macros` - Optional proc macros (`#[tool_fn]`, `#[prompt_fn]`, `#[resource_fn]`, `#[resource_template_fn]`)
168//! - `mcp-apps` - Typed server support for the stable MCP Apps extension. Runtime
169//! advertisement remains explicit through [`McpRouter::with_mcp_apps`].
170//! - `protocol-2026-07-28` - Compile the released 2026-07-28 implementation.
171//! Use [`ProtocolSupport`] to select enabled versions at runtime. Enables
172//! version-gated sessionless dispatch, `server/discover` RPC, per-request `_meta` via
173//! [`stateless::StatelessRequestMeta`], `subscriptions/listen`, SEP-2322 MRTR handlers,
174//! and the discover-based [`McpClient`] path.
175//! - `stateless` - Compatibility alias for the former 2026 protocol feature name.
176//!
177//! For complete server and client setup, registration and persistence policy,
178//! and a production checklist, see the
179//! [`guides::oauth`].
180//!
181//! ## Task-oriented Guides
182//!
183//! - [`guides::client`] —
184//! transport selection, lifecycle, callbacks, requests, caching, retries, and shutdown.
185//! - [`guides::deployment`] —
186//! mounting, reverse proxies, origin/host validation, sessions, scaling, timeouts,
187//! middleware order, health, and graceful shutdown.
188//! - [`guides::protocol_versions`] —
189//! compile-time availability, runtime allowlists, lifecycle differences,
190//! interoperability, and upgrades.
191//! - [`guides`] — OAuth, MCP Apps, and the complete task-oriented guide index.
192//! - [Examples index](https://github.com/joshrotenberg/tower-mcp/blob/main/examples/README.md) —
193//! runnable server, client, transport, middleware, OAuth, and extension patterns.
194//!
195//! ## Middleware Placement Guide
196//!
197//! tower-mcp supports Tower middleware at multiple levels. Choose based on scope:
198//!
199//! | Level | Method | Scope | Use Cases |
200//! |-------|--------|-------|-----------|
201//! | **Transport** | `StdioTransport::layer()`, `HttpTransport::layer()` | All MCP requests | Global timeout, rate limit, metrics |
202//! | **axum** | `.into_router().layer()` | HTTP layer only | CORS, compression, request logging |
203//! | **Per-tool** | `ToolBuilder::...layer()` | Single tool | Tool-specific timeout, concurrency |
204//! | **Per-resource** | `ResourceBuilder::...layer()` | Single resource | Caching, read timeout |
205//! | **Per-prompt** | `PromptBuilder::...layer()` | Single prompt | Generation timeout |
206//!
207//! ### Decision Tree
208//!
209//! ```text
210//! Where should my middleware go?
211//! │
212//! ├─ Affects ALL MCP requests?
213//! │ └─ Yes → Transport: StdioTransport::layer(), HttpTransport::layer(), or WebSocketTransport::layer()
214//! │
215//! ├─ HTTP-specific (CORS, compression, headers)?
216//! │ └─ Yes → axum: transport.into_router().layer(...)
217//! │
218//! ├─ Only one specific tool?
219//! │ └─ Yes → Per-tool: ToolBuilder::...handler(...).layer(...)
220//! │
221//! ├─ Only one specific resource?
222//! │ └─ Yes → Per-resource: ResourceBuilder::...handler(...).layer(...)
223//! │
224//! └─ Only one specific prompt?
225//! └─ Yes → Per-prompt: PromptBuilder::...handler(...).layer(...)
226//! ```
227//!
228//! ### Example: Layered Timeouts
229//!
230//! ```rust,ignore
231//! use std::time::Duration;
232//! use tower::timeout::TimeoutLayer;
233//! use tower_mcp::{McpRouter, ToolBuilder, CallToolResult, HttpTransport};
234//! use schemars::JsonSchema;
235//! use serde::Deserialize;
236//!
237//! #[derive(Debug, Deserialize, JsonSchema)]
238//! struct SearchInput { query: String }
239//!
240//! // This tool gets a longer timeout than the global default
241//! let slow_search = ToolBuilder::new("slow_search")
242//! .description("Thorough search (may take a while)")
243//! .handler(|input: SearchInput| async move {
244//! // ... slow operation ...
245//! Ok(CallToolResult::text("results"))
246//! })
247//! .layer(TimeoutLayer::new(Duration::from_secs(60))) // 60s for this tool
248//! .build();
249//!
250//! let router = McpRouter::new()
251//! .server_info("example", "1.0.0")
252//! .tool(slow_search);
253//!
254//! // Global 30s timeout for all OTHER requests
255//! let transport = HttpTransport::new(router)
256//! .layer(TimeoutLayer::new(Duration::from_secs(30)));
257//! ```
258//!
259//! In this example:
260//! - `slow_search` tool has a 60-second timeout (per-tool layer)
261//! - All other MCP requests have a 30-second timeout (transport layer)
262//! - The per-tool layer is **inner** to the transport layer
263//!
264//! ### Layer Ordering
265//!
266//! Layers wrap from outside in. The first layer added is the outermost:
267//!
268//! ```text
269//! Request → [Transport Layer] → [Per-tool Layer] → Handler → Response
270//! ```
271//!
272//! For per-tool/resource/prompt, chained `.layer()` calls also wrap outside-in:
273//!
274//! ```rust,ignore
275//! ToolBuilder::new("api")
276//! .handler(...)
277//! .layer(TimeoutLayer::new(...)) // Outer: timeout checked first
278//! .layer(ConcurrencyLimitLayer::new(5)) // Inner: concurrency after timeout
279//! .build()
280//! ```
281//!
282//! ### Full Example
283//!
284//! See [`examples/tool_middleware.rs`](https://github.com/joshrotenberg/tower-mcp/blob/main/examples/tool_middleware.rs)
285//! for a complete example demonstrating:
286//! - Different timeouts per tool
287//! - Concurrency limiting for expensive operations
288//! - Multiple layers combined on a single tool
289//!
290//! ## Advanced Features
291//!
292//! ### Sampling (LLM Requests)
293//!
294//! Tools can request LLM completions from the client via [`RequestContext::sample()`].
295//! This enables AI-assisted tools like "suggest a query" or "analyze results":
296//!
297//! ```rust,ignore
298//! use tower_mcp::{ToolBuilder, CallToolResult, CreateMessageParams, SamplingMessage};
299//! use tower_mcp::extract::Context;
300//!
301//! let tool = ToolBuilder::new("suggest")
302//! .description("Get AI suggestions")
303//! .extractor_handler(|ctx: Context| async move {
304//! if !ctx.can_sample() {
305//! return Ok(CallToolResult::error("Sampling not available"));
306//! }
307//!
308//! let params = CreateMessageParams::new()
309//! .message(SamplingMessage::user("Suggest 3 search queries for: rust async"))
310//! .max_tokens(200);
311//!
312//! let result = ctx.sample(params).await?;
313//! let text = result.first_text().unwrap_or("No response");
314//! Ok(CallToolResult::text(text))
315//! })
316//! .build();
317//! ```
318//!
319//! ### Elicitation (User Input)
320//!
321//! Tools can request user input via forms using [`RequestContext::elicit_form()`]
322//! or the convenience method [`RequestContext::confirm()`]:
323//!
324//! ```rust,ignore
325//! use tower_mcp::{ToolBuilder, CallToolResult};
326//! use tower_mcp::extract::Context;
327//!
328//! // Simple confirmation dialog
329//! let delete_tool = ToolBuilder::new("delete")
330//! .description("Delete a file")
331//! .extractor_handler(|ctx: Context| async move {
332//! if !ctx.confirm("Are you sure you want to delete this file?").await? {
333//! return Ok(CallToolResult::text("Cancelled"));
334//! }
335//! // ... perform deletion ...
336//! Ok(CallToolResult::text("Deleted"))
337//! })
338//! .build();
339//! ```
340//!
341//! For complex forms, use [`ElicitFormSchema`] to define multiple fields.
342//!
343//! ### Progress Notifications
344//!
345//! Long-running tools can report progress via [`RequestContext::report_progress()`]:
346//!
347//! ```rust,ignore
348//! use tower_mcp::{ToolBuilder, CallToolResult};
349//! use tower_mcp::extract::Context;
350//!
351//! let process_tool = ToolBuilder::new("process")
352//! .description("Process items")
353//! .extractor_handler(|ctx: Context| async move {
354//! let items = vec!["a", "b", "c", "d", "e"];
355//! let total = items.len() as f64;
356//!
357//! for (i, item) in items.iter().enumerate() {
358//! ctx.report_progress(i as f64, Some(total), Some(&format!("Processing {}", item))).await;
359//! // ... process item ...
360//! }
361//!
362//! Ok(CallToolResult::text("Done"))
363//! })
364//! .build();
365//! ```
366//!
367//! ### Stateless Mode (2026-07-28, requires `protocol-2026-07-28` + `http`)
368//!
369//! The `protocol-2026-07-28` feature enables the released 2026-07-28 MCP
370//! protocol. In this mode the initialize/initialized handshake
371//! is replaced by two new RPCs:
372//!
373//! - **`server/discover`** -- stateless capability discovery. Clients that send requests with
374//! `MCP-Protocol-Version: 2026-07-28` (SEP-2243 header) can call `server/discover` instead
375//! of `initialize` to learn what the server supports without establishing a session.
376//! - **`subscriptions/listen`** -- client-initiated SSE subscription. A POST of a
377//! `subscriptions/listen` request with `MCP-Protocol-Version: 2026-07-28` opens a
378//! server-push stream that is not tied to any session, allowing stateless clients to
379//! receive notifications. [`McpClient::listen_subscriptions`] returns a handle that
380//! exposes the accepted filter and subscription ID; dropping or cancelling the handle
381//! closes only that request's response stream.
382//!
383//! Per-request client identity and capabilities ride in each request's `_meta` object via
384//! [`stateless::StatelessRequestMeta`] rather than being negotiated once at session open.
385//! The `MCP-Protocol-Version` header value is the version gate: requests carrying exactly
386//! `2026-07-28` route through the stateless path; older requests continue through the
387//! session-based path unchanged.
388//!
389//! ```rust,ignore
390//! use tower_mcp::{McpRouter, HttpTransport};
391//! use tower_mcp::stateless::StatelessConfig;
392//!
393//! let router = McpRouter::new().server_info("my-server", "1.0.0");
394//!
395//! // Enable stateless mode alongside the session-based path.
396//! let transport = HttpTransport::new(router)
397//! .stateless(StatelessConfig::new());
398//! ```
399//!
400//! The 2026-07-28 implementation is opt-in. Enable the
401//! `protocol-2026-07-28` Cargo feature to compile it, then use
402//! [`ProtocolSupport`] to narrow the versions enabled by an individual
403//! transport at runtime.
404//!
405//! ### Router Composition
406//!
407//! Combine multiple routers using [`McpRouter::merge()`] or [`McpRouter::nest()`]:
408//!
409//! ```rust,ignore
410//! use tower_mcp::McpRouter;
411//!
412//! // Create domain-specific routers
413//! let db_router = McpRouter::new()
414//! .tool(query_tool)
415//! .tool(insert_tool);
416//!
417//! let api_router = McpRouter::new()
418//! .tool(fetch_tool);
419//!
420//! // Nest with prefixes: tools become "db.query", "db.insert", "api.fetch"
421//! let combined = McpRouter::new()
422//! .server_info("combined", "1.0")
423//! .nest("db", db_router)
424//! .nest("api", api_router);
425//!
426//! // Or merge without prefixes
427//! let merged = McpRouter::new()
428//! .merge(db_router)
429//! .merge(api_router);
430//! ```
431//!
432//! ### Multi-Server Proxy
433//!
434//! Aggregate multiple backend MCP servers behind a single endpoint using
435//! [`McpProxy`](proxy::McpProxy) (requires the `proxy` feature):
436//!
437//! ```rust,ignore
438//! use tower_mcp::proxy::McpProxy;
439//! use tower_mcp::client::StdioClientTransport;
440//!
441//! let proxy = McpProxy::builder("my-proxy", "1.0.0")
442//! .backend("db", StdioClientTransport::spawn("db-server", &[]).await?)
443//! .await
444//! .backend("fs", StdioClientTransport::spawn("fs-server", &[]).await?)
445//! .await
446//! .build()
447//! .await?;
448//!
449//! // Tools become `db_query`, `fs_read`, etc.
450//! // Serve over any transport -- stdio, HTTP, WebSocket.
451//! GenericStdioTransport::new(proxy).run().await?;
452//! ```
453//!
454//! The proxy supports per-backend Tower middleware, notification forwarding,
455//! health checks, and request coalescing. See the [`proxy`] module for details.
456//!
457//! ## Production Deployment
458//!
459//! See the [`deployment`] module for load balancer patterns, session
460//! affinity, horizontal scaling with the [`session_store`] and
461//! [`event_store`] traits, reverse proxy configuration (nginx, Caddy,
462//! Traefik), observability, and sidecar deployments.
463//!
464//! ## MCP Specification
465//!
466//! This crate implements MCP 2025-11-25 by default and provides an opt-in
467//! implementation of the released 2026-07-28 specification:
468//! <https://modelcontextprotocol.io/specification/2026-07-28>
469//!
470//! Enable it with `protocol-2026-07-28`; the legacy `stateless` feature name
471//! remains a compatibility alias. Major final-version work includes:
472//! - [SEP-2322](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2322) --
473//! Multi Round-Trip Requests
474//! - [SEP-2567](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2567) --
475//! `subscriptions/listen` SSE endpoint
476//! - [SEP-2575](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2575) --
477//! stateless session model, `server/discover`, per-request `_meta`
478//! - [SEP-2243](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2243) --
479//! strict HTTP headers (`Mcp-Method`, `Mcp-Name`, `MCP-Protocol-Version`)
480
481#[cfg(feature = "mcp-apps")]
482pub mod apps;
483pub mod async_task;
484pub mod auth;
485pub mod client;
486pub mod context;
487#[cfg(any(feature = "http", feature = "websocket"))]
488pub mod deployment;
489pub mod error;
490#[cfg(any(feature = "http", feature = "websocket"))]
491pub mod event_store;
492pub mod extension;
493pub mod extract;
494pub mod filter;
495pub mod guides;
496pub mod inspection;
497pub mod jsonrpc;
498pub mod middleware;
499#[cfg(feature = "stateless")]
500pub mod mrtr;
501#[cfg(feature = "oauth")]
502pub mod oauth;
503pub mod prompt;
504pub mod protocol;
505mod protocol_support;
506pub use protocol_support::{
507 COMPILED_PROTOCOL_VERSIONS, ProtocolSupport, ProtocolSupportError, is_protocol_version_compiled,
508};
509#[cfg(feature = "proxy")]
510pub mod proxy;
511#[cfg(feature = "dynamic-tools")]
512pub mod registry;
513pub mod resource;
514pub mod router;
515pub mod session;
516#[cfg(any(feature = "http", feature = "websocket"))]
517pub mod session_store;
518#[cfg(feature = "stateless")]
519pub mod stateless;
520pub mod tasks;
521#[cfg(feature = "testing")]
522pub mod testing;
523pub mod tool;
524pub mod tracing_layer;
525pub mod transport;
526
527// Re-export proc macros when the `macros` feature is enabled
528#[cfg(feature = "macros")]
529pub use tower_mcp_macros::prompt_fn;
530#[cfg(feature = "macros")]
531pub use tower_mcp_macros::resource_fn;
532#[cfg(feature = "macros")]
533pub use tower_mcp_macros::resource_template_fn;
534#[cfg(feature = "macros")]
535pub use tower_mcp_macros::tool_fn;
536
537/// Re-export of the [`schemars`] crate.
538///
539/// Tool input types passed via [`extract::Json`] derive `schemars::JsonSchema`,
540/// and the derived impl must come from the same `schemars` major version that
541/// tower-mcp uses. Depending on `schemars` through this re-export
542/// (`tower_mcp::schemars`) keeps the versions aligned and avoids the opaque
543/// `ExtractorHandler` trait-bound errors that a version skew produces.
544pub use schemars;
545
546// Re-exports
547#[cfg(feature = "mcp-apps")]
548pub use apps::{
549 MCP_APP_HTML_MIME_TYPE, MCP_APPS_EXTENSION_ID, McpAppDomain, McpAppError, McpAppHtml,
550 McpAppResourceBuilder, McpAppUri, McpAppsCapabilitySettings, McpUiPermissions,
551 McpUiResourceCsp, McpUiResourceMeta, McpUiToolMeta, McpUiToolVisibility, mcp_app_tool_result,
552 mcp_apps_extension,
553};
554pub use async_task::{MemoryTaskStore, Task, TaskStore};
555pub use client::{
556 ChannelTransport, ClientHandler, ClientTransport, McpClient, McpClientBuilder,
557 NotificationHandler, StdioClientTransport,
558};
559#[cfg(feature = "http-client")]
560pub use client::{HttpClientConfig, HttpClientTransport};
561#[cfg(feature = "oauth-client")]
562pub use client::{
563 MemoryOAuthAuthorizationStateStore, MemoryOAuthClientRegistrationStore, MemoryOAuthTokenStore,
564 OAuthApplicationType, OAuthAuthorizationAction, OAuthAuthorizationFlow,
565 OAuthAuthorizationFlowBuilder, OAuthAuthorizationHandler, OAuthAuthorizationRequest,
566 OAuthAuthorizationServerMetadata, OAuthAuthorizationStart, OAuthAuthorizationStateStore,
567 OAuthClientAssertionRequest, OAuthClientAssertionSigner, OAuthClientCredentials,
568 OAuthClientError, OAuthClientRegistration, OAuthClientRegistrationMethod,
569 OAuthClientRegistrationOptions, OAuthClientRegistrationStore, OAuthDynamicClientRegistration,
570 OAuthHttpBody, OAuthHttpClient, OAuthHttpMethod, OAuthHttpRequest, OAuthHttpResponse,
571 OAuthPendingAuthorization, OAuthPendingAuthorizationState, OAuthRedirectPolicy,
572 OAuthScopeChallenge, OAuthScopeEscalationConfig, OAuthScopeEscalationHandler,
573 OAuthScopeEscalationRequest, OAuthStoredToken, OAuthTokenBinding, OAuthTokenStore,
574 ReqwestOAuthHttpClient, TokenProvider, discover_oauth_authorization_server,
575 resolve_oauth_client_registration, resolve_oauth_client_registration_with_store,
576};
577pub use context::{
578 ChannelClientRequester, ClientRequester, ClientRequesterHandle, Extensions,
579 NotificationReceiver, NotificationSender, OutgoingRequest, OutgoingRequestReceiver,
580 OutgoingRequestSender, RequestContext, RequestContextBuilder, ServerNotification,
581 outgoing_request_channel,
582};
583pub use error::{BoxError, Error, Result, ResultExt, ToolError};
584pub use extension::{ExtensionDeclaration, NegotiatedExtension, NegotiatedExtensions};
585pub use filter::{
586 CapabilityFilter, DenialBehavior, Filterable, PromptFilter, ResourceFilter, ToolFilter,
587};
588pub use jsonrpc::{JsonRpcLayer, JsonRpcService};
589pub use middleware::{
590 AuditLayer, AuditService, McpTracingLayer, McpTracingService, ToolCallLoggingLayer,
591 ToolCallLoggingService,
592};
593#[cfg(feature = "stateless")]
594pub use mrtr::{MrtrRequest, RequestStateCodec, RequestStateError};
595#[cfg(feature = "stateless")]
596pub use prompt::MrtrPromptHandler;
597pub use prompt::{BoxPromptService, Prompt, PromptBuilder, PromptHandler, PromptRequest};
598#[allow(deprecated)]
599pub use protocol::{
600 BooleanSchema, CallToolParams, CallToolResult, CancelTaskParams, CancelledParams,
601 ClientCapabilities, ClientTasksCancelCapability, ClientTasksCapability,
602 ClientTasksElicitationCapability, ClientTasksElicitationCreateCapability,
603 ClientTasksListCapability, ClientTasksRequestsCapability, ClientTasksSamplingCapability,
604 ClientTasksSamplingCreateMessageCapability, CompleteParams, CompleteResult, Completion,
605 CompletionArgument, CompletionContext, CompletionReference, CompletionsCapability, Content,
606 ContentAnnotations, ContentRole, CreateMessageParams, CreateMessageResult, CreateTaskResult,
607 ElicitAction, ElicitFieldValue, ElicitFormParams, ElicitFormSchema, ElicitMode,
608 ElicitRequestParams, ElicitResult, ElicitUrlParams, ElicitationCapability,
609 ElicitationCompleteParams, ElicitationFormCapability, ElicitationUrlCapability, EmptyResult,
610 GetPromptParams, GetPromptResult, GetPromptResultBuilder, GetTaskInfoParams,
611 GetTaskResultParams, IconTheme, Implementation, IncludeContext, InitializeParams,
612 InitializeResult, InputRequest, InputRequests, InputRequiredResult, InputResponse,
613 InputResponses, IntegerSchema, JsonRpcErrorResponse, JsonRpcMessage, JsonRpcNotification,
614 JsonRpcRequest, JsonRpcResponse, JsonRpcResponseMessage, JsonRpcResultResponse,
615 ListPromptsParams, ListPromptsResult, ListResourceTemplatesParams, ListResourceTemplatesResult,
616 ListResourcesParams, ListResourcesResult, ListRootsParams, ListRootsResult, ListTasksParams,
617 ListTasksResult, ListToolsParams, ListToolsResult, LogLevel, LoggingCapability,
618 LoggingMessageParams, McpNotification, McpRequest, McpResponse, ModelHint, ModelPreferences,
619 MultiSelectEnumItems, MultiSelectEnumSchema, NotificationMeta, NumberSchema,
620 PrimitiveSchemaDefinition, ProgressParams, ProgressToken, PromptArgument, PromptDefinition,
621 PromptMessage, PromptReference, PromptRole, PromptsCapability, ReadResourceParams,
622 ReadResourceResult, RequestId, RequestMeta, RequestOutcome, ResourceContent,
623 ResourceDefinition, ResourceReference, ResourceTemplateDefinition, ResourcesCapability,
624 ResultType, Root, RootsCapability, SamplingCapability, SamplingContent, SamplingContentOrArray,
625 SamplingContextCapability, SamplingMessage, SamplingTool, SamplingToolsCapability,
626 ServerCapabilities, SetLogLevelParams, SingleSelectEnumSchema, StringSchema,
627 SubscribeResourceParams, SubscriptionFilter, SubscriptionsAcknowledgedParams,
628 SubscriptionsListenParams, SubscriptionsListenResult, SubscriptionsListenResultMeta, TaskInfo,
629 TaskObject, TaskRequestParams, TaskStatus, TaskStatusChangedParams, TaskStatusParams,
630 TaskSupportMode, TasksCancelCapability, TasksCapability, TasksListCapability,
631 TasksRequestsCapability, TasksToolsCallCapability, TasksToolsRequestsCapability,
632 ToolAnnotations, ToolChoice, ToolDefinition, ToolExecution, ToolIcon, ToolsCapability,
633 UnsubscribeResourceParams, UpdateTaskParams,
634};
635pub use protocol::{RESULT_TYPE_TASK, TASKS_EXTENSION_ID};
636#[cfg(feature = "dynamic-tools")]
637pub use registry::{
638 DynamicPromptRegistry, DynamicResourceRegistry, DynamicResourceTemplateRegistry,
639 DynamicToolRegistry,
640};
641pub use resource::{
642 BoxResourceService, Resource, ResourceBuilder, ResourceHandler, ResourceRequest,
643 ResourceTemplate, ResourceTemplateBuilder, ResourceTemplateHandler,
644};
645#[cfg(feature = "stateless")]
646pub use resource::{MrtrResourceHandler, MrtrResourceTemplateHandler};
647pub use router::{McpRouter, RouterRequest, RouterResponse, ToolAnnotationsMap};
648pub use session::{SessionPhase, SessionState};
649#[cfg(feature = "stateless")]
650pub use tool::MrtrToolHandler;
651pub use tool::{BoxToolService, GuardLayer, NoParams, Tool, ToolBuilder, ToolHandler, ToolRequest};
652pub use transport::{
653 BidirectionalStdioTransport, CatchError, GenericStdioTransport, StdioTransport,
654 SyncStdioTransport,
655};
656
657#[cfg(feature = "http")]
658pub use transport::{HttpTransport, SessionHandle, SessionInfo};
659
660#[cfg(feature = "websocket")]
661pub use transport::WebSocketTransport;
662
663#[cfg(any(feature = "http", feature = "websocket", feature = "unix"))]
664pub use transport::McpBoxService;
665
666#[cfg(all(unix, feature = "unix"))]
667pub use transport::UnixSocketTransport;
668
669#[cfg(feature = "childproc")]
670pub use transport::{ChildProcessConnection, ChildProcessTransport};
671
672#[cfg(feature = "oauth")]
673pub use oauth::{ScopeEnforcementLayer, ScopeEnforcementService};
674
675#[cfg(feature = "jwks")]
676pub use oauth::{JwksError, JwksValidator, JwksValidatorBuilder};
677
678#[cfg(feature = "testing")]
679pub use testing::TestClient;