Skip to content

Let an MCP probe name the ways its authorization server registers clients - #191

Draft
jeremy wants to merge 1 commit into
mainfrom
mcp-client-registration
Draft

jeremy wants to merge 1 commit into
mainfrom
mcp-client-registration

Conversation

@jeremy

@jeremy jeremy commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Adds an optional client_registration field to the mcp probe from #183, so a probe can say which ways of registering a client its authorization server must advertise.

For Lewis when it's ready.

Why

#183 requires a registration_endpoint from every authorization server. That holds for Basecamp and for Fizzy's OAuth train, but not for HEY:

  • haystack's RFC 8414 document (basecamp/haystack#8698, metadata_controller.rb) has no registration_endpoint: "HEY has no PAR, DCR, device, or introspection endpoints to advertise".
  • HEY's roadmap lights MCP up with pre-registered clients first. Client ID metadata documents (W2.6) and DCR (W2.7) arrive at M3, the directory listing (roadmap.md). Its design doc says each field is advertised "only in the environment where it's live" (oauth-for-mcp.md D1).
  • MCP's authorization spec now calls DCR deprecated, so a server that offers only client ID metadata documents is a correct setup. A probe for it should require the metadata document, not the endpoint.

So a HEY probe on #183 would fail from the day it's deployed, for a reason that isn't an outage.

What it does

- name: Example MCP Server
  url: https://mcp.example.com/mcp
  authorization_server: https://auth.example.com
  client_registration: [ metadata_document ]
  • dynamic requires a registration_endpoint, as before.
  • metadata_document requires client_id_metadata_document_supported: true.
  • Every value listed must be advertised. Unset means [dynamic], so existing probes don't change. [] requires neither, while the authorization and token endpoints and S256 are still required.
  • An unknown value fails the check before any request, and the log names the valid values.

README, CHANGELOG (Unreleased → Added) and the install template's field list are updated.

Verification

  • 6 new tests in mcp_probe_test.rb; that file passes (17 runs). Against the old probe, 5 of the 6 fail. The sixth, which requires both and gets a server without registration_endpoint, passes either way, so it guards the "all listed" rule against a later change to "any listed".
  • Full suite: 491 of 496 pass locally. The 5 that fail are Playwright and traceroute tests that need a Playwright browser and mtr, neither installed here. CI runs them.
  • rubocop is clean on the changed files.
  • I ran the probe live against Basecamp staging (https://mcp.bc4-staging.com/mcp, AS https://app.bc4-staging.com) with the field unset, set to [], and set to [dynamic, metadata_document]. All three pass.

Not included

  • An "either one" mode. A probe asserts what this particular server advertises, so you list exactly that. "Any of" would let a server drop the mechanism its clients depend on without the probe noticing.
  • The 37upright side. basecamp/37upright's HEY probe draft uses client_registration: [] and needs Upright bumped once this merges.

…ents

The probe required a registration_endpoint from every authorization server.
HEY's lights up with pre-registered clients only and adds client ID metadata
documents and dynamic registration later, and MCP now calls dynamic
registration deprecated, so a server may offer only metadata documents.

client_registration lists what must be advertised: dynamic (a
registration_endpoint) and metadata_document
(client_id_metadata_document_supported: true). Unset keeps [dynamic]; []
requires neither.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant