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 compiled in by the
401//! `protocol-2026-07-28` Cargo feature and enabled by default once compiled.
402//! Use [`ProtocolSupport`] to narrow the versions enabled by an individual
403//! client or 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//! Every build implements the MCP 2025-11-25 and 2025-03-26 session
467//! protocols; the `protocol-2026-07-28` feature adds the released 2026-07-28
468//! specification, enabled by default once compiled:
469//! <https://modelcontextprotocol.io/specification/2026-07-28>
470//!
471//! Enable it with `protocol-2026-07-28`; the legacy `stateless` feature name
472//! remains a compatibility alias. Major final-version work includes:
473//! - [SEP-2322](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2322) --
474//! Multi Round-Trip Requests
475//! - [SEP-2567](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2567) --
476//! `subscriptions/listen` SSE endpoint
477//! - [SEP-2575](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2575) --
478//! stateless session model, `server/discover`, per-request `_meta`
479//! - [SEP-2243](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2243) --
480//! strict HTTP headers (`Mcp-Method`, `Mcp-Name`, `MCP-Protocol-Version`)
481
482#[cfg(feature = "mcp-apps")]
483pub mod apps;
484pub mod async_task;
485pub mod auth;
486pub mod client;
487pub mod context;
488#[cfg(any(feature = "http", feature = "websocket"))]
489pub mod deployment;
490pub mod error;
491#[cfg(any(feature = "http", feature = "websocket"))]
492pub mod event_store;
493pub mod extension;
494pub mod extract;
495pub mod filter;
496pub mod guides;
497pub mod inspection;
498pub mod jsonrpc;
499pub mod middleware;
500#[cfg(feature = "stateless")]
501pub mod mrtr;
502#[cfg(feature = "oauth")]
503pub mod oauth;
504pub mod prompt;
505pub mod protocol;
506mod protocol_support;
507pub use protocol_support::{
508 COMPILED_PROTOCOL_VERSIONS, ProtocolSupport, ProtocolSupportError, is_protocol_version_compiled,
509};
510#[cfg(feature = "proxy")]
511pub mod proxy;
512#[cfg(feature = "dynamic-tools")]
513pub mod registry;
514pub mod resource;
515pub mod router;
516pub mod session;
517#[cfg(any(feature = "http", feature = "websocket"))]
518pub mod session_store;
519#[cfg(feature = "stateless")]
520pub mod stateless;
521pub mod tasks;
522#[cfg(feature = "testing")]
523pub mod testing;
524pub mod tool;
525pub mod tracing_layer;
526pub mod transport;
527
528// Re-export proc macros when the `macros` feature is enabled
529#[cfg(feature = "macros")]
530pub use tower_mcp_macros::prompt_fn;
531#[cfg(feature = "macros")]
532pub use tower_mcp_macros::resource_fn;
533#[cfg(feature = "macros")]
534pub use tower_mcp_macros::resource_template_fn;
535#[cfg(feature = "macros")]
536pub use tower_mcp_macros::tool_fn;
537
538/// Re-export of the [`schemars`] crate.
539///
540/// Tool input types passed via [`extract::Json`] derive `schemars::JsonSchema`,
541/// and the derived impl must come from the same `schemars` major version that
542/// tower-mcp uses. Depending on `schemars` through this re-export
543/// (`tower_mcp::schemars`) keeps the versions aligned and avoids the opaque
544/// `ExtractorHandler` trait-bound errors that a version skew produces.
545pub use schemars;
546
547// Re-exports
548#[cfg(feature = "mcp-apps")]
549pub use apps::{
550 MCP_APP_HTML_MIME_TYPE, MCP_APPS_EXTENSION_ID, McpAppDomain, McpAppError, McpAppHtml,
551 McpAppResourceBuilder, McpAppUri, McpAppsCapabilitySettings, McpUiPermissions,
552 McpUiResourceCsp, McpUiResourceMeta, McpUiToolMeta, McpUiToolVisibility, mcp_app_tool_result,
553 mcp_apps_extension,
554};
555pub use async_task::{MemoryTaskStore, Task, TaskStore};
556pub use client::{
557 ChannelTransport, ClientHandler, ClientTransport, McpClient, McpClientBuilder,
558 NotificationHandler, StdioClientTransport,
559};
560#[cfg(feature = "http-client")]
561pub use client::{HttpClientConfig, HttpClientTransport};
562#[cfg(feature = "oauth-client")]
563pub use client::{
564 MemoryOAuthAuthorizationStateStore, MemoryOAuthClientRegistrationStore, MemoryOAuthTokenStore,
565 OAuthApplicationType, OAuthAuthorizationAction, OAuthAuthorizationFlow,
566 OAuthAuthorizationFlowBuilder, OAuthAuthorizationHandler, OAuthAuthorizationRequest,
567 OAuthAuthorizationServerMetadata, OAuthAuthorizationStart, OAuthAuthorizationStateStore,
568 OAuthClientAssertionRequest, OAuthClientAssertionSigner, OAuthClientCredentials,
569 OAuthClientError, OAuthClientRegistration, OAuthClientRegistrationMethod,
570 OAuthClientRegistrationOptions, OAuthClientRegistrationStore, OAuthDynamicClientRegistration,
571 OAuthHttpBody, OAuthHttpClient, OAuthHttpMethod, OAuthHttpRequest, OAuthHttpResponse,
572 OAuthPendingAuthorization, OAuthPendingAuthorizationState, OAuthRedirectPolicy,
573 OAuthScopeChallenge, OAuthScopeEscalationConfig, OAuthScopeEscalationHandler,
574 OAuthScopeEscalationRequest, OAuthStoredToken, OAuthTokenBinding, OAuthTokenStore,
575 ReqwestOAuthHttpClient, TokenProvider, discover_oauth_authorization_server,
576 resolve_oauth_client_registration, resolve_oauth_client_registration_with_store,
577};
578pub use context::{
579 ChannelClientRequester, ClientRequester, ClientRequesterHandle, Extensions,
580 NotificationReceiver, NotificationSender, OutgoingRequest, OutgoingRequestReceiver,
581 OutgoingRequestSender, RequestContext, RequestContextBuilder, ServerNotification,
582 outgoing_request_channel,
583};
584pub use error::{BoxError, Error, Result, ResultExt, ToolError};
585pub use extension::{ExtensionDeclaration, NegotiatedExtension, NegotiatedExtensions};
586pub use filter::{
587 CapabilityFilter, DenialBehavior, Filterable, PromptFilter, ResourceFilter, ToolFilter,
588};
589pub use jsonrpc::{JsonRpcLayer, JsonRpcService};
590pub use middleware::{
591 AuditLayer, AuditService, McpTracingLayer, McpTracingService, ToolCallLoggingLayer,
592 ToolCallLoggingService,
593};
594#[cfg(feature = "stateless")]
595pub use mrtr::{MrtrRequest, RequestStateCodec, RequestStateError};
596#[cfg(feature = "stateless")]
597pub use prompt::MrtrPromptHandler;
598pub use prompt::{BoxPromptService, Prompt, PromptBuilder, PromptHandler, PromptRequest};
599#[allow(deprecated)]
600pub use protocol::{
601 BooleanSchema, CallToolParams, CallToolResult, CancelTaskParams, CancelledParams,
602 ClientCapabilities, ClientTasksCancelCapability, ClientTasksCapability,
603 ClientTasksElicitationCapability, ClientTasksElicitationCreateCapability,
604 ClientTasksListCapability, ClientTasksRequestsCapability, ClientTasksSamplingCapability,
605 ClientTasksSamplingCreateMessageCapability, CompleteParams, CompleteResult, Completion,
606 CompletionArgument, CompletionContext, CompletionReference, CompletionsCapability, Content,
607 ContentAnnotations, ContentRole, CreateMessageParams, CreateMessageResult, CreateTaskResult,
608 ElicitAction, ElicitFieldValue, ElicitFormParams, ElicitFormSchema, ElicitMode,
609 ElicitRequestParams, ElicitResult, ElicitUrlParams, ElicitationCapability,
610 ElicitationCompleteParams, ElicitationFormCapability, ElicitationUrlCapability, EmptyResult,
611 GetPromptParams, GetPromptResult, GetPromptResultBuilder, GetTaskInfoParams,
612 GetTaskResultParams, IconTheme, Implementation, IncludeContext, InitializeParams,
613 InitializeResult, InputRequest, InputRequests, InputRequiredResult, InputResponse,
614 InputResponses, IntegerSchema, JsonRpcErrorResponse, JsonRpcMessage, JsonRpcNotification,
615 JsonRpcRequest, JsonRpcResponse, JsonRpcResponseMessage, JsonRpcResultResponse,
616 ListPromptsParams, ListPromptsResult, ListResourceTemplatesParams, ListResourceTemplatesResult,
617 ListResourcesParams, ListResourcesResult, ListRootsParams, ListRootsResult, ListTasksParams,
618 ListTasksResult, ListToolsParams, ListToolsResult, LogLevel, LoggingCapability,
619 LoggingMessageParams, McpNotification, McpRequest, McpResponse, ModelHint, ModelPreferences,
620 MultiSelectEnumItems, MultiSelectEnumSchema, NotificationMeta, NumberSchema,
621 PrimitiveSchemaDefinition, ProgressParams, ProgressToken, PromptArgument, PromptDefinition,
622 PromptMessage, PromptReference, PromptRole, PromptsCapability, ReadResourceParams,
623 ReadResourceResult, RequestId, RequestMeta, RequestOutcome, ResourceContent,
624 ResourceDefinition, ResourceReference, ResourceTemplateDefinition, ResourcesCapability,
625 ResultType, Root, RootsCapability, SamplingCapability, SamplingContent, SamplingContentOrArray,
626 SamplingContextCapability, SamplingMessage, SamplingTool, SamplingToolsCapability,
627 ServerCapabilities, SetLogLevelParams, SingleSelectEnumSchema, StringSchema,
628 SubscribeResourceParams, SubscriptionFilter, SubscriptionsAcknowledgedParams,
629 SubscriptionsListenParams, SubscriptionsListenResult, SubscriptionsListenResultMeta, TaskInfo,
630 TaskObject, TaskRequestParams, TaskStatus, TaskStatusChangedParams, TaskStatusParams,
631 TaskSupportMode, TasksCancelCapability, TasksCapability, TasksListCapability,
632 TasksRequestsCapability, TasksToolsCallCapability, TasksToolsRequestsCapability,
633 ToolAnnotations, ToolChoice, ToolDefinition, ToolExecution, ToolIcon, ToolsCapability,
634 UnsubscribeResourceParams, UpdateTaskParams,
635};
636pub use protocol::{RESULT_TYPE_TASK, TASKS_EXTENSION_ID};
637#[cfg(feature = "dynamic-tools")]
638pub use registry::{
639 DynamicPromptRegistry, DynamicResourceRegistry, DynamicResourceTemplateRegistry,
640 DynamicToolRegistry,
641};
642pub use resource::{
643 BoxResourceService, Resource, ResourceBuilder, ResourceHandler, ResourceRequest,
644 ResourceTemplate, ResourceTemplateBuilder, ResourceTemplateHandler,
645};
646#[cfg(feature = "stateless")]
647pub use resource::{MrtrResourceHandler, MrtrResourceTemplateHandler};
648pub use router::{McpRouter, RouterRequest, RouterResponse, ToolAnnotationsMap};
649pub use session::{SessionPhase, SessionState};
650#[cfg(feature = "stateless")]
651pub use tool::MrtrToolHandler;
652pub use tool::{
653 BoxToolService, GuardLayer, NoParams, TaskContext, TaskPreparation, Tool, ToolBuilder,
654 ToolHandler, ToolRequest,
655};
656pub use transport::{
657 BidirectionalStdioTransport, CatchError, GenericStdioTransport, StdioTransport,
658 SyncStdioTransport,
659};
660
661#[cfg(feature = "stateless")]
662pub use transport::subscriptions::{
663 SubscriptionClose, SubscriptionCloseReason, SubscriptionObserver,
664};
665
666#[cfg(feature = "http")]
667pub use transport::{HttpTransport, SessionHandle, SessionInfo};
668
669#[cfg(feature = "websocket")]
670pub use transport::WebSocketTransport;
671
672#[cfg(any(feature = "http", feature = "websocket", feature = "unix"))]
673pub use transport::McpBoxService;
674
675#[cfg(all(unix, feature = "unix"))]
676pub use transport::UnixSocketTransport;
677
678#[cfg(feature = "childproc")]
679pub use transport::{ChildProcessConnection, ChildProcessTransport};
680
681#[cfg(feature = "oauth")]
682pub use oauth::{ScopeEnforcementLayer, ScopeEnforcementService};
683
684#[cfg(feature = "jwks")]
685pub use oauth::{JwksError, JwksValidator, JwksValidatorBuilder};
686
687#[cfg(feature = "testing")]
688pub use testing::TestClient;