---
title: CIMD Authentication
sidebarTitle: CIMD
description: Use Client ID Metadata Documents for verifiable, domain-based client identity.
icon: id-badge
---

import { VersionBadge } from "/snippets/version-badge.mdx"

<VersionBadge version="3.0.0" />

<Tip>
CIMD authentication is only relevant for HTTP-based transports and requires a server that advertises CIMD support.
</Tip>

With standard OAuth, your client registers dynamically with every server it connects to, receiving a fresh `client_id` each time. This works, but the server has no way to verify *who* your client actually is — any client can claim any name during registration.

CIMD (Client ID Metadata Documents) flips this around. You host a small JSON document at an HTTPS URL you control, and that URL becomes your `client_id`. When your client connects to a server, the server fetches your metadata document and can verify your identity through your domain ownership. Users see a verified domain badge in the consent screen instead of an unverified client name.

## Client Usage

Pass your CIMD document URL to the `client_metadata_url` parameter of `OAuth`:

```python
from fastmcp import Client
from fastmcp.client.auth import OAuth

async with Client(
    "https://mcp-server.example.com/mcp",
    auth=OAuth(
        client_metadata_url="https://myapp.example.com/oauth/client.json",
    ),
) as client:
    await client.ping()
```

When the server supports CIMD, the client uses your metadata URL as its `client_id` instead of performing Dynamic Client Registration. The server fetches your document, validates it, and proceeds with the standard OAuth authorization flow.

<Note>
You don't need to pass `mcp_url` when using `OAuth` with `Client(auth=...)` — the transport provides the server URL automatically.
</Note>

## Creating a CIMD Document

A CIMD document is a JSON file that describes your client. The most important field is `client_id`, which must exactly match the URL where you host the document.

Use the FastMCP CLI to generate one:

```bash
fastmcp auth cimd create \
    --name "My Application" \
    --redirect-uri "http://localhost:*/callback" \
    --client-id "https://myapp.example.com/oauth/client.json"
```

This produces:

```json
{
  "client_id": "https://myapp.example.com/oauth/client.json",
  "client_name": "My Application",
  "redirect_uris": ["http://localhost:*/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code"],
  "response_types": ["code"]
}
```

If you omit `--client-id`, the CLI generates a placeholder value and reminds you to update it before hosting.

### CLI Options

The `create` command accepts these flags:

| Flag | Description |
|------|-------------|
| `--name` | Human-readable client name (required) |
| `--redirect-uri`, `-r` | Allowed redirect URIs — can be specified multiple times (required) |
| `--client-id` | The URL where you'll host this document (sets `client_id` directly) |
| `--output`, `-o` | Write to a file instead of stdout |
| `--scope` | Space-separated list of scopes the client may request |
| `--client-uri` | URL of the client's home page |
| `--logo-uri` | URL of the client's logo image |
| `--no-pretty` | Output compact JSON |

### Redirect URIs

The `redirect_uris` field supports wildcard port matching for localhost. The pattern `http://localhost:*/callback` matches any port, which is useful for development clients that bind to random available ports (which is what FastMCP's `OAuth` helper does by default).

## Hosting Requirements

CIMD documents must be hosted at a publicly accessible HTTPS URL with a non-root path:

- **HTTPS required** — HTTP URLs are rejected for security
- **Non-root path** — The URL must have a path component (e.g., `/oauth/client.json`, not just `/`)
- **Public accessibility** — The server must be able to fetch the document over the internet
- **Matching `client_id`** — The `client_id` field in the document must exactly match the hosting URL

Common hosting options include static file hosting services like GitHub Pages, Cloudflare Pages, Vercel, or S3 — anywhere you can serve a JSON file over HTTPS.

## Validating Your Document

Before deploying, verify your hosted document passes validation:

```bash
fastmcp auth cimd validate https://myapp.example.com/oauth/client.json
```

The validator fetches the document and checks that:
- The URL is valid (HTTPS, non-root path)
- The document is well-formed JSON conforming to the CIMD schema
- The `client_id` in the document matches the URL it was fetched from

## How It Works

When your client connects to a CIMD-enabled server, the flow works like this:

<Steps>
<Step title="Client Presents Metadata URL">
Your client sends its `client_metadata_url` as the `client_id` in the OAuth authorization request.
</Step>
<Step title="Server Recognizes CIMD URL">
The server sees that the `client_id` is an HTTPS URL with a path — the signature of a CIMD client — and skips Dynamic Client Registration.
</Step>
<Step title="Server Fetches and Validates">
The server fetches your JSON document from the URL, validates that `client_id` matches the URL, and extracts your client metadata (name, redirect URIs, scopes).
</Step>
<Step title="Authorization Proceeds">
The standard OAuth flow continues: browser opens for user consent, authorization code exchange, token issuance. The consent screen shows your verified domain.
</Step>
</Steps>

The server caches your CIMD document according to HTTP cache headers, so subsequent requests don't require re-fetching.

## Server Configuration

CIMD is a server-side feature that your MCP server must support. FastMCP's OAuth proxy providers (GitHub, Google, Auth0, etc.) support CIMD by default. See the [OAuth Proxy CIMD documentation](/servers/auth/oauth-proxy#cimd-support) for server-side configuration, including private key JWT authentication and security details.
