fix(mcp): add RFC 9728 resource to protected resource metadata - #5521
fix(mcp): add RFC 9728 resource to protected resource metadata#5521diegohh0411 wants to merge 7 commits into
Conversation
Spec for fixing missing required resource field so MCP OAuth clients (e.g. Grok/rmcp) can complete discovery.
Failing test for required resource and recommended resource_name before the metadata implementation. Refs: macro-inc#5519
Strict MCP clients (Grok/rmcp) require the resource field on protected resource metadata. Derive resource and resource_name from the existing public_url; omit scopes_supported. Fixes: macro-inc#5519
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe change adds an RFC 9728 design for Macro MCP protected-resource metadata. The service now includes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/specs/2026-08-08-mcp-protected-resource-metadata-design.md`:
- Around line 10-15: Ensure protected-resource metadata routes identify the same
resource as their returned resource value. In
docs/superpowers/specs/2026-08-08-mcp-protected-resource-metadata-design.md
lines 10-15, make /.well-known/oauth-protected-resource/mcp canonical for
{public_url}/mcp and remove or define redirects for incompatible aliases; in
services/mcp_auth_proxy/src/domain/service.rs lines 202-205, serve metadata only
on the canonical route or redirect aliases before metadata handling, and add
route-level coverage for canonical discovery.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 11b9a110-5ca9-45f7-bd01-f49817d7976d
📒 Files selected for processing (3)
docs/superpowers/specs/2026-08-08-mcp-protected-resource-metadata-design.mdservices/mcp_auth_proxy/src/domain/service.rsservices/mcp_auth_proxy/src/domain/service/test.rs
Add Grok Build to the in-app MCP setup cards and docs overview. Redirect origin-root protected-resource metadata to the RFC 9728 canonical path for /mcp, keep path-style discovery, and cover the routes with unit tests (CodeRabbit review). Refs: macro-inc#5519
df3d2ad to
092e675
Compare
Only checking the first element would miss extra or wrong entries.
Keep serving protected resource metadata at /.well-known/oauth-protected-resource instead of 308ing to the path-insertion URL. That preserves the pre-existing multi-path layout maintainers may rely on; the RFC-required resource field is still the core fix.
There was a problem hiding this comment.
please remove the spec file
Summary
Strict MCP clients (Grok Build / rmcp) fail OAuth discovery when protected resource metadata is missing the RFC 9728
resourcefield. This PR fills that out and a couple of related gaps that came up while wiring Grok.What changed:
protected_resource_metadatanow returnsresource({public_url}/mcp) andresource_name("Macro MCP"), still using the existingpublic_url/MCP_PUBLIC_URLwiring. No new env vars.authorization_server/authorization_servers. Does not inventscopes_supported(we do not have resource-level MCP scopes today; FusionAuth scopes are identity scopes, not MCP resource scopes).WWW-Authenticatestill points at/.well-known/oauth-protected-resource/mcp).apps/docs/AI/mcp/overview.mdx.Fixes #5519
Note on the
tokiodev-dependencymcp_auth_proxyproduction code is already async (axum, redisaio/tokio-comp, FusionAuth). It does not calltokio::by name, so Tokio only showed up transitively before this PR. That is fine for the service itself.The route tests for the three discovery URLs use
#[tokio::test]+tower::ServiceExt::oneshot. That needs a directtokiolink withmacros/rtso the crate can resolvetokio::test. A transitive dep is not enough.Putting
tokiounder[dev-dependencies]matches other library-style crates here (mcp_client,fusionauth, etc.). Runtime binaries likemcp_servicealready declare Tokio for the process; this crate does not need that. Test-only is the smaller footprint.Test plan
cargo test -p mcp_auth_proxy(domain metadata + route discovery)resource, AS fields,resource_name, noscopes_supportedcargo clippy -p mcp_auth_proxy --all-targets -- -D warningscurlwell-known PRM and confirmresourceis present/mcps→ authenticate Macro MCP (i) gets past metadata discoveryQuestions for maintainers
A few judgment calls where I'd rather get a maintainer read than invent house style:
Route tests vs full
mcp_router. Discovery tests use a small router that only mounts the three PRM paths (same handlers as production). That keeps JWT validation and a dummy MCP nest out of the harness. If you prefer route tests to call the realmcp_routerfactory so the path table cannot drift, I can rework that.Trailing slash on
MCP_PUBLIC_URL.resourceis built as{public_url}/mcp. RFC 9728 wants an exact string match with the client's resource URL. I have not normalized a trailing slash on the base. Worth a trim if that config is easy to mis-set in deploy.Shared test doubles.
NoopInflightAuth/DummyOAuthProviderare duplicated in the domain and route test modules. I left them local so a shared#[cfg(test)]support module does not grow the crate surface for a small metadata fix. Fine to extract if you want one place for fakes.Happy to adjust any of these in a follow-up commit.