mcpr_core/proxy/mod.rs
1//! # mcpr-proxy
2//!
3//! Proxy engine for mcpr: request routing, upstream forwarding, SSE streaming,
4//! and widget CSP rewriting.
5//!
6//! This crate sits between MCP clients and upstream MCP servers. It classifies
7//! requests, forwards them over HTTP, relays SSE streams, and rewrites widget
8//! CSP metadata on the way back.
9//!
10//! ## Responsibilities
11//!
12//! - **Request routing** (`router`): Classify incoming HTTP requests into typed
13//! variants — MCP JSON-RPC POST, MCP SSE GET, widget HTML, widget assets,
14//! OAuth callbacks, or passthrough.
15//!
16//! - **Upstream forwarding** (`forwarding`): HTTP client with connection pooling,
17//! semaphore-based concurrency limiting, configurable timeouts, and header
18//! forwarding (auth, content-type, MCP session ID).
19//!
20//! - **SSE handling** (`sse`): Extract JSON from SSE-wrapped responses, re-wrap
21//! JSON as SSE, and split upstream URLs into (base, path) components.
22//!
23//! - **Widget CSP** (`csp`, `rewrite`): Declarative CSP config with per-directive
24//! modes and widget-scoped overrides. `csp::effective_domains` computes the
25//! final domain list for one directive; `rewrite::rewrite_response` applies
26//! that to every CSP array in a JSON-RPC response.
27//!
28//! - **Proxy state** (`state`): Shared runtime state tracking MCP upstream
29//! health, tunnel status, widget discovery, cloud sync, and request counters.
30//!
31//! ## Module layout
32//!
33//! ```text
34//! proxy/
35//! ├── router.rs ClassifiedRequest, classify()
36//! ├── forwarding.rs UpstreamClient, forward_request()
37//! ├── sse.rs SSE extract/wrap helpers
38//! ├── csp.rs CspConfig, DirectivePolicy, WidgetScoped, effective_domains
39//! ├── rewrite.rs RewriteConfig, rewrite_response()
40//! └── state.rs ProxyState, ConnectionStatus, SharedProxyState
41//! ```
42
43pub mod csp;
44pub mod forwarding;
45pub mod rewrite;
46pub mod router;
47pub mod sse;
48pub mod state;
49
50pub use csp::{
51 CspConfig, Directive, DirectivePolicy, Mode, WidgetScoped, effective_domains, glob_match,
52};
53pub use rewrite::{RewriteConfig, rewrite_response};
54pub use state::{ConnectionStatus, ProxyState, SharedProxyState, lock_state, new_shared_state};