mcp_proxy/lib.rs
1//! Config-driven MCP reverse proxy with auth, resilience middleware, and observability.
2//!
3//! Aggregates multiple MCP backends behind a single HTTP endpoint with namespace
4//! isolation, per-backend middleware, and a comprehensive admin API. Built on
5//! [tower-mcp](https://docs.rs/tower-mcp) and the [tower](https://docs.rs/tower) ecosystem.
6//!
7//! # Quick Start
8//!
9//! ## From a config file
10//!
11//! ```rust,no_run
12//! use mcp_proxy::{Proxy, ProxyConfig};
13//!
14//! # async fn example() -> anyhow::Result<()> {
15//! let config = ProxyConfig::load("proxy.toml".as_ref())?;
16//! let proxy = Proxy::from_config(config).await?;
17//! proxy.serve().await?;
18//! # Ok(())
19//! # }
20//! ```
21//!
22//! ## Programmatic builder
23//!
24//! ```rust,no_run
25//! use mcp_proxy::ProxyBuilder;
26//!
27//! # async fn example() -> anyhow::Result<()> {
28//! let proxy = ProxyBuilder::new("my-proxy")
29//! .listen("0.0.0.0", 9090)
30//! .http_backend("api", "http://api:8080")
31//! .timeout(30)
32//! .rate_limit(100, 1)
33//! .stdio_backend("files", "npx", &["-y", "@mcp/server-files"])
34//! .build()
35//! .await?;
36//!
37//! proxy.serve().await?;
38//! # Ok(())
39//! # }
40//! ```
41//!
42//! ## Embed in an existing axum app
43//!
44//! ```rust,no_run
45//! use mcp_proxy::{Proxy, ProxyConfig};
46//!
47//! # async fn example() -> anyhow::Result<()> {
48//! let config = ProxyConfig::load("proxy.toml".as_ref())?;
49//! let proxy = Proxy::from_config(config).await?;
50//! let (router, session_handle) = proxy.into_router();
51//! // Mount `router` in your axum app
52//! # Ok(())
53//! # }
54//! ```
55//!
56//! # Backend Transports
57//!
58//! | Transport | Config | Use Case |
59//! |-----------|--------|----------|
60//! | `stdio` | `command`, `args`, `env` | Local subprocess (npx, python, etc.) |
61//! | `http` | `url`, `bearer_token` | Remote HTTP+SSE MCP server |
62//! | `websocket` | `url`, `bearer_token` | Remote WebSocket MCP server |
63//!
64//! Backends are namespaced: a backend named `"files"` exposes tools as
65//! `files/read_file`, `files/write_file`, etc.
66//!
67//! # Per-Backend Middleware
68//!
69//! Each backend can independently configure:
70//!
71//! - **Timeout** -- per-request deadline
72//! - **Circuit breaker** -- failure-rate based with observable state handles
73//! - **Rate limit** -- request volume caps
74//! - **Retry** -- exponential backoff with budget control
75//! - **Hedging** -- parallel requests for tail latency reduction
76//! - **Outlier detection** -- passive health tracking with ejection
77//! - **Response caching** -- per-backend TTL with memory, Redis, or SQLite backends
78//! - **Argument injection** -- merge default args into tool calls
79//! - **Parameter overrides** -- hide or rename tool parameters
80//! - **Capability filtering** -- allowlist/denylist tools, resources, prompts
81//! (glob patterns and `re:` regex support)
82//! - **Annotation filtering** -- hide destructive tools, read-only-only mode
83//!
84//! # Traffic Routing
85//!
86//! - **Failover** -- N-way priority chains with automatic fallback
87//! - **Canary routing** -- weight-based traffic splitting
88//! - **Traffic mirroring** -- fire-and-forget shadow traffic
89//! - **Composite tools** -- fan-out a single call to multiple backends
90//! - **Tool aliasing** -- rename tools across backends
91//!
92//! # Authentication
93//!
94//! Three auth modes, configured via `[auth]`:
95//!
96//! - **Bearer tokens** -- simple static tokens with optional per-token tool scoping
97//! - **JWT/JWKS** -- validate JWTs via remote JWKS endpoint with RBAC role mapping
98//! - **OAuth 2.1** -- auto-discovery (RFC 8414), token introspection (RFC 7662),
99//! JWT+introspection fallback
100//!
101//! # Admin API
102//!
103//! REST API at `/admin/` for monitoring and management:
104//!
105//! - Backend health, history, and circuit breaker states
106//! - Session listing and termination
107//! - Cache stats and clearing
108//! - Config viewing, validation, and updates
109//! - Prometheus metrics and OpenAPI spec
110//! - Optional bearer token auth (`security.admin_token`)
111//!
112//! # Tool Discovery
113//!
114//! When `tool_discovery = true`, BM25 full-text search indexes all backend tools
115//! and exposes `proxy/search_tools`, `proxy/similar_tools`, and
116//! `proxy/tool_categories` for finding tools across large deployments.
117//!
118//! Set `tool_exposure = "search"` to hide individual tools from listing and expose
119//! only meta-tools (search + call_tool), scaling to hundreds of backends.
120//!
121//! # Agent Skills
122//!
123//! MCP prompts following the [agentskills.io](https://agentskills.io) specification
124//! for agent-assisted proxy management: setup, auth configuration, resilience tuning,
125//! config validation, diagnostics, and status reporting.
126//!
127//! # Config Formats
128//!
129//! - **TOML** (default): `proxy.toml`
130//! - **YAML** (`yaml` feature): `proxy.yaml` / `proxy.yml`
131//! - **`.mcp.json`**: `mcp-proxy --from-mcp-json .mcp.json` for zero-config mode
132//!
133//! # Hot Reload
134//!
135//! Enable `hot_reload = true` to watch the config file. Backends are added,
136//! removed, or replaced dynamically without restart. Discovery indexes are
137//! automatically re-indexed.
138//!
139//! # Feature Flags
140//!
141//! | Feature | Default | Description |
142//! |---------|---------|-------------|
143//! | `otel` | Yes | OpenTelemetry tracing export |
144//! | `metrics` | Yes | Prometheus metrics at `/admin/metrics` |
145//! | `oauth` | Yes | JWT/JWKS auth, OAuth 2.1, bearer scoping, RBAC |
146//! | `openapi` | Yes | OpenAPI spec at `/admin/openapi.json` |
147//! | `websocket` | Yes | WebSocket backend transport |
148//! | `discovery` | Yes | BM25 tool discovery via jpx-engine |
149//! | `yaml` | Yes | YAML config format support |
150//! | `skills` | Yes | agentskills.io management prompts |
151//! | `redis-cache` | No | Redis cache backend |
152//! | `sqlite-cache` | No | SQLite cache backend |
153//!
154//! Minimal build: `cargo install mcp-proxy --no-default-features`
155//!
156//! # Performance
157//!
158//! Middleware stack overhead is sub-microsecond (~115ns per request). Cache hits
159//! are 33x faster than backend round-trips. See `benches/proxy_overhead.rs`.
160
161pub mod access_log;
162pub mod admin;
163pub mod admin_tools;
164pub mod alias;
165#[cfg(feature = "oauth")]
166pub mod bearer_scope;
167pub mod builder;
168pub mod cache;
169pub mod canary;
170pub mod coalesce;
171pub mod composite;
172pub mod config;
173#[cfg(feature = "discovery")]
174pub mod discovery;
175pub mod failover;
176pub mod filter;
177pub mod inject;
178#[cfg(feature = "oauth")]
179pub mod introspection;
180pub mod mcp_json;
181#[cfg(feature = "metrics")]
182pub mod metrics;
183pub mod mirror;
184pub mod outlier;
185pub mod param_override;
186#[cfg(feature = "oauth")]
187pub mod rbac;
188pub mod reload;
189pub mod retry;
190#[cfg(feature = "skills")]
191pub mod skills;
192#[cfg(feature = "oauth")]
193pub mod token;
194pub mod validation;
195#[cfg(feature = "websocket")]
196pub mod ws_transport;
197
198#[cfg(test)]
199mod test_util;
200
201mod proxy;
202
203pub use builder::ProxyBuilder;
204pub use config::ProxyConfig;
205pub use proxy::Proxy;