Skip to content

Commit c182e88

Browse files
authored
Merge branch 'main' into fix/deep-link-dedupe-status-throttle
2 parents 07a3c17 + db1596f commit c182e88

7 files changed

Lines changed: 453 additions & 23 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/mcpmux-gateway/src/server/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@ mod startup;
1313
mod state;
1414

1515
// Exposed for integration tests that mount these routes against a real
16-
// ServiceContainer (e.g. asserting the OAuth-discovery endpoints 404 when
17-
// inbound auth is disabled). AppState is also used throughout this module.
18-
pub use handlers::{oauth_metadata, resource_metadata, AppState};
16+
// ServiceContainer — e.g. asserting the OAuth-discovery endpoints 404 when
17+
// inbound auth is disabled, and driving the full inbound OAuth flow
18+
// (register → authorize → consent → token → authenticated /mcp) end to end.
19+
// AppState is also used throughout this module.
20+
pub use handlers::{
21+
oauth_authorize, oauth_consent_approve, oauth_metadata, oauth_register, oauth_token,
22+
resource_metadata, AppState,
23+
};
1924

2025
pub use dependencies::{DependenciesBuilder, GatewayDependencies};
2126
pub use handlers::PendingAuthorization;

tests/rust/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ reqwest = { version = "0.13", features = ["json"] }
4646
# URL parsing for OAuth tests
4747
url = "2.5"
4848

49+
# PKCE + JWT-secret material for the inbound-OAuth end-to-end test
50+
base64 = "0.22"
51+
sha2 = "0.10"
52+
zeroize = "1.8"
53+
4954
# Sync primitives for tests
5055
parking_lot = "0.12"
5156

tests/rust/tests/streamable_http/auth_disable.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ impl Harness {
133133
"/.well-known/oauth-protected-resource",
134134
get(resource_metadata),
135135
)
136+
// RFC 9728 resource-specific variant — this is the one editors like
137+
// VS Code probe first (`/.well-known/oauth-protected-resource/mcp`).
138+
.route(
139+
"/.well-known/oauth-protected-resource/mcp",
140+
get(resource_metadata),
141+
)
136142
.route(
137143
"/.well-known/oauth-authorization-server",
138144
get(oauth_metadata),
@@ -211,8 +217,12 @@ async fn authless_gateway_does_not_advertise_oauth_discovery() {
211217
// without a token.
212218
let h = Harness::start(true).await;
213219
let client = reqwest::Client::new();
220+
// Includes the RFC 9728 `/mcp` sub-path — the endpoint VS Code probes first
221+
// (its 200 was what pushed editors into an OAuth flow against an authless
222+
// gateway, leaving them stuck waiting on `initialize`).
214223
for path in [
215224
"/.well-known/oauth-protected-resource",
225+
"/.well-known/oauth-protected-resource/mcp",
216226
"/.well-known/oauth-authorization-server",
217227
] {
218228
let resp = client
@@ -230,12 +240,24 @@ async fn authless_gateway_does_not_advertise_oauth_discovery() {
230240

231241
#[tokio::test]
232242
async fn auth_required_gateway_advertises_oauth_discovery() {
233-
// The default (auth required) still serves discovery so real OAuth works.
243+
// The default (auth required) still serves discovery so real OAuth works —
244+
// every endpoint, including the RFC 9728 sub-path.
234245
let h = Harness::start(false).await;
235-
let resp = reqwest::Client::new()
236-
.get(format!("{}/.well-known/oauth-protected-resource", h.base))
237-
.send()
238-
.await
239-
.expect("request");
240-
assert_eq!(resp.status(), reqwest::StatusCode::OK);
246+
let client = reqwest::Client::new();
247+
for path in [
248+
"/.well-known/oauth-protected-resource",
249+
"/.well-known/oauth-protected-resource/mcp",
250+
"/.well-known/oauth-authorization-server",
251+
] {
252+
let resp = client
253+
.get(format!("{}{path}", h.base))
254+
.send()
255+
.await
256+
.expect("request");
257+
assert_eq!(
258+
resp.status(),
259+
reqwest::StatusCode::OK,
260+
"{path} must be served when auth is required"
261+
);
262+
}
241263
}

0 commit comments

Comments
 (0)