agentic-community / agentic-community/mcp-gateway-registry
[Phase 4] Publish CIMD (Client ID Metadata Document) for AI Registry Tools MCP client
- Lenguaje dominante
- Python
- Estrellas
- 911
- Forks
- 234
- Merge medio
- 1 d 11 h
- PR fusionados (30 d)
- 62
Descripción
# Sub-issue B: Publish a CIMD (Client ID Metadata Document) for the AI Registry Tools MCP client
**Parent:** #988
**Labels:** `enhancement`, `oauth`, `mcp-spec`, `authentication`, `subtask`
**Phase:** 4
**Depends on:** A, E
**Blocks:** C
---
## Summary
When the Registry itself acts as an MCP client (calling out to other CIMD-aware authorization servers on behalf of AI Registry Tools), it needs a stable, publicly-fetchable Client ID Metadata Document describing itself. Publish it at a canonical URL and treat that URL as the Registry's `client_id` when it authenticates to external IdPs that have adopted CIMD.
## Background
The November 2025 MCP authorization spec update ([Aaron Parecki](https://aaronparecki.com/2025/11/25/1/mcp-authorization-spec-update)) retires RFC 7591 Dynamic Client Registration in favor of CIMD. In CIMD, a client publishes `https://example-app.com/client.json` describing itself; the authorization server fetches that document on the first auth request, caches it, and treats the URL as the `client_id`. No per-AS registration, no database growth, no DCR.
Claude Code v2.1.64+ already auto-discovers CIMD. The Registry should publish its own so it can play the client role against external IdPs that have adopted the pattern (most relevant once our AI Registry Tools server starts calling external MCP servers on behalf of users, e.g. through a token-exchange chain).
This is the **publisher** side. The consumer side (accepting an incoming CIMD URL as `client_id` on our `/authorize`) is sub-issue C.
## Scope
### In scope
- **`GET /.well-known/mcp-client-metadata`** (final path TBD based on spec landing point; track the latest CIMD draft at [draft-parecki-oauth-client-id-metadata-document](https://datatracker.ietf.org/doc/draft-parecki-oauth-client-id-metadata-document/)) returning:
- `client_name`: human-readable, e.g. "AI Registry Tools".
- `client_uri`: Registry homepage.
- `logo_uri`: static asset served by the Registry.
- `redirect_uris`: list of allowed callbacks for the AI Registry Tools client flow.
- `scope`: space-separated list of scopes the client requests.
- `grant_types`: at least `authorization_code`, `refresh_token`, and (once D lands) `urn:ietf:params:oauth:grant-type:token-exchange`.
- `token_endpoint_auth_method`: value appropriate for a public client with PKCE (typically `none`).
- `contacts`: operator contact email.
- **Canonical URL** that matches exactly what the Registry sends as `client_id` on outbound authorization requests. Any drift between the published URL and the wire `client_id` causes CIMD consumers to fail the fetch.
- **Caching**: `Cache-Control: public, max-age=3600`. The 1-hour TTL balances rollout speed against CIMD consumer cache policy.
- **Content-type**: `application/json`. No wrapper, no envelope.
- **Update path**: a single config source of truth (file or DB) so the document does not go stale after a deploy.
- **Tests**: shape, required fields, URL matches wire `client_id`, cache header, stable field ordering.
### Out of scope (tracked elsewhere)
- Accepting CIMD URLs as incoming `client_id` on our `/authorize` → sub-issue C.
- ID-JAG token-exchange support on our `/oauth/token` → sub-issue D.
- Any Domain B federation concerns → declined, see #988 §"What we considered and declined".
## Design notes
- CIMD draft spec is still moving. Use the `draft-parecki-*` URL during development; revisit once the RFC-assigned path is stable. Keep the handler behind a version-guarded path so we can bump cleanly.
- The document MUST be fetchable unauthenticated. It is public metadata.
- `redirect_uris` in the document MUST be the exact ones the Registry uses at runtime. Mismatches cause the AS to reject the auth request.
- Because the URL IS the `client_id`, operators cannot rename the endpoint without coordinating with all CIMD-aware authorization servers they interact with. Document this.
## Acceptance criteria
- [ ] Endpoint returns a valid CIMD document per the latest draft.
- [ ] Wire `client_id` sent on outbound `/authorize` matches the canonical URL byte-for-byte.
- [ ] Required fields populated: `client_name`, `client_uri`, `redirect_uris`, `scope`, `grant_types`, `token_endpoint_auth_method`.
- [ ] `Cache-Control: public, max-age=3600`.
- [ ] Unit tests: shape, HTTP caching, field ordering, URL / `client_id` parity.
- [ ] End-to-end test: mount a fake AS that fetches the CIMD document, verify the Registry can complete an authorization code flow against it using only its CIMD URL as `client_id`.
- [ ] Docs page in [docs/](docs/) explaining what CIMD is, why the Registry publishes one, and the operator consequences of renaming the endpoint.
## Risks and open questions
- **Draft spec drift.** Field names and paths could change before the final RFC. Guard the handler with a version in the URL so we can ship multiple simultaneously during transition.
- **Logo hosting.** If the `logo_uri` points at an asset subject to CDN caching, ensure the CDN URL is stable and HTTPS. Don't point at a workstation or preview environment.
- **Multi-tenant registries.** If we ever run the Registry in a multi-tenant shape, each tenant needs its own CIMD document and its own canonical URL. Out of scope for this issue; flag for future.
## References
- [CIMD draft](https://datatracker.ietf.org/doc/draft-parecki-oauth-client-id-metadata-document/)
- [Aaron Parecki, MCP Authorization Spec Update (2025-11-25)](https://aaronparecki.com/2025/11/25/1/mcp-authorization-spec-update)
- [IndieAuth's client ID pattern (prior art)](https://indieauth.spec.indieweb.org/#client-information-discovery)
- Recommendation doc §6 Phase 4: [.scratchpad/coding-assistant-oauth/recommendation-2026-05-04.md](.scratchpad/coding-assistant-oauth/recommendation-2026-05-04.md)
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.