1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! OAuth 2.1 resource server support for MCP.
//!
//! This module implements the resource server side of OAuth 2.1 as specified
//! in the MCP authorization specification. The MCP server acts as
//! a **resource server** -- it validates tokens issued by an external
//! authorization server and serves Protected Resource Metadata for discovery.
//!
//! # Architecture
//!
//! - **Protected Resource Metadata** ([`ProtectedResourceMetadata`]): Served at
//! `/.well-known/oauth-protected-resource` so OAuth clients can discover
//! which authorization server to use (RFC 9728).
//!
//! - **Token Validation** ([`TokenValidator`]): Pluggable trait for validating
//! access tokens. [`JwtValidator`] provides JWT validation with static keys.
//! [`ValidateAdapter`] bridges the existing [`Validate`](crate::auth::Validate) trait.
//!
//! - **Scope Policy** ([`ScopePolicy`]): Per-operation scope requirements for
//! tools, resources, and prompts.
//!
//! - **HTTP Middleware** ([`OAuthLayer`]/[`OAuthService`]): Tower middleware that
//! extracts bearer tokens, validates them, checks scopes, and injects
//! [`TokenClaims`] into request extensions.
//!
//! # Example
//!
//! ```rust,no_run
//! use tower_mcp::{McpRouter, HttpTransport, ToolBuilder, CallToolResult};
//! use tower_mcp::oauth::{
//! ProtectedResourceMetadata, JwtValidator, ScopePolicy,
//! };
//!
//! #[tokio::main]
//! async fn main() -> Result<(), tower_mcp::BoxError> {
//! // Define MCP tools
//! let tool = ToolBuilder::new("echo")
//! .description("Echo input back")
//! .handler(|input: serde_json::Value| async move {
//! Ok(CallToolResult::text(format!("{}", input)))
//! })
//! .build();
//!
//! let router = McpRouter::new()
//! .server_info("oauth-server", "1.0.0")
//! .tool(tool);
//!
//! // Configure OAuth metadata
//! let metadata = ProtectedResourceMetadata::new("https://mcp.example.com")
//! .authorization_server("https://auth.example.com")
//! .scope("mcp:read")
//! .scope("mcp:write");
//!
//! // Configure token validator
//! let validator = JwtValidator::from_secret(b"shared-secret")
//! .expected_audience("https://mcp.example.com")
//! .expected_issuer("https://auth.example.com");
//!
//! // Configure scope policy
//! let policy = ScopePolicy::new()
//! .default_scope("mcp:read");
//!
//! // Build a complete, fail-closed resource server. This validates and
//! // serves metadata, checks bearer tokens and audience, and applies both
//! // default and per-operation scope policy.
//! let app = HttpTransport::new(router)
//! .into_oauth_router(validator, metadata, policy)?;
//!
//! let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
//! axum::serve(listener, app).await?;
//! Ok(())
//! }
//! ```
//!
//! # Middleware order and scope levels
//!
//! [`HttpTransport::into_oauth_router`](crate::HttpTransport::into_oauth_router)
//! is the recommended setup because it fixes the security-sensitive order:
//! [`OAuthLayer`] is the outer HTTP middleware, the transport bridges validated
//! [`TokenClaims`] into MCP request extensions, and [`ScopeEnforcementLayer`]
//! runs inside the MCP router. The HTTP layer's policy checks scopes that apply
//! to every request; the router layer additionally selects tool-, resource-,
//! and prompt-specific requirements from the same [`ScopePolicy`].
//!
//! For a custom composition, preserve that order and serve
//! [`ProtectedResourceMetadata`] outside authentication. The scope layer is
//! fail closed by default; its explicitly named permissive constructor is only
//! for applications that intentionally mix authenticated and anonymous MCP
//! operations.
//!
//! # Discovery Flow
//!
//! 1. Client requests MCP endpoint without a token
//! 2. Server returns `401` with `WWW-Authenticate: Bearer resource_metadata="..."`
//! 3. Client fetches the resource's RFC 9728 well-known metadata URL
//! 4. Client obtains token from the authorization server
//! 5. Client retries with `Authorization: Bearer <token>`
//!
//! See [`crate::guides::oauth`] for complete resource-server and client setup,
//! registration and persistence policy, identity-provider integration, and a
//! production checklist.
// Re-exports
pub use OAuthError;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;