Client registration: CIMD vs DCR
ezForge supports two registration paths, matching the MCP Authorization Spec (2025-11 revision):| Path | Spec level | How it works |
|---|---|---|
| CIMD (Client ID Metadata Document) | should — preferred | Client sets client_id to its own metadata URL; the AS fetches and registers it automatically |
| DCR (RFC 7591 Dynamic Client Registration) | may — fallback | Client POSTs metadata to /api/v1/servers/:id/clients; explicit call required |
CIMD registration (preferred)
CIMD is the preferred path for clients that can host a metadata document at a stable HTTPS URL (Claude Desktop, Gemini ADK, Cursor, etc.). The client hosts a JSON document at a URL it controls, e.g.:client_id:
client_id, fetches the metadata document, validates it, and registers the client automatically. No separate registration step is required.
The metadata cache is refreshed every 24 hours using ETag-based conditional requests (RFC 7232). Metadata fetch failures degrade safely — the authorization request is rejected with a clear error and no token is issued.
You can also pre-register a CIMD client explicitly (e.g. to validate the document ahead of the auth flow):
DCR registration (fallback)
DCR (RFC 7591) remains fully supported for clients that cannot host a metadata URL. See Dynamic Client Registration below.Why OAuth 2.1?
The Model Context Protocol specification recommends OAuth 2.1 as the standard auth mechanism for HTTP-based MCP servers. It provides:- Short-lived access tokens that limit the impact of token leakage
- Refresh tokens for long-lived sessions without re-authentication
- Fine-grained scopes to control what clients can do
- PKCE to prevent authorization code interception attacks (mandatory —
plainmethod not accepted)
How it works
Resource Indicators (RFC 8707)
Access tokens are bound to a specific server URI using RFC 8707 Resource Indicators. A token issued formy-server.mcp.ezforge.ai cannot be used to call any other server. This prevents token replay attacks across servers.
MCP scopes
| Scope | Description |
|---|---|
mcp:read | List available tools on the server |
mcp:write | Call tools that modify state |
mcp:execute | Execute any tool call (most permissive) |
offline_access | Request long-lived refresh tokens |
ezforge_managed mode
When a server usesezforge_managed auth (the default), ezForge acts as the OAuth authorization server:
- ezForge registers the MCP client
- Handles the authorization flow
- Issues and validates tokens
- No configuration required from you
BYOA mode (Bring Your Own Auth)
If you already run an OAuth 2.1 authorization server, you can configure your ezForge server to accept tokens from it:- Fetching your JWKS endpoint to get public keys
- Verifying the JWT signature
- Checking the
issclaim matches your configured issuer - Checking the
audclaim includes the server’s URI (RFC 8707) - Verifying the token is not expired
Choosing between ezforge_managed and BYOA
Both modes deliver the same MCP-spec compliance (OAuth 2.1, PKCE, RFC 8707 resource binding, RFC 9728 protected resource metadata). The choice is about who owns identity issuance.
Choose ezforge_managed if… | Choose BYOA if… |
|---|---|
| You want a working spec-compliant MCP server in minutes, with zero auth configuration | You already operate an OAuth 2.1 authorization server you want to keep |
| You don’t yet have an enterprise identity provider | You have existing SSO/SCIM contracts (WorkOS, Auth0, Stytch/Twilio, etc.) you need to honor |
| You want ezForge to handle user accounts, token issuance, and JWKS rotation | You want auth audit logs and account lifecycle inside your own IdP |
| You’re an indie developer, SMB customer, or running a single-tenant deployment | You have residency, isolation, or compliance constraints that require keeping identity in your own infrastructure |
ezforge servers update --auth-mode {ezforge_managed,byoa} command — see the BYOA mode section above for the BYOA-specific flags.
Protected Resource Metadata
All ezForge-hosted servers expose the RFC 9728 standard endpoint:Token lifetimes
| Token | Lifetime | Notes |
|---|---|---|
| Authorization code | 10 minutes | Single-use; consumed on token exchange |
| Access token | 15 minutes | Short-lived; limits blast radius of leakage |
| Refresh token | 30 days | Rotated on each use |
Security recommendations
- Request only the scopes your application needs
- Use
offline_accessonly when a long-lived session is necessary - Treat access tokens as secrets — don’t log them or include them in URLs
- Rotate refresh tokens regularly; ezForge rotates them automatically on use