A Next.js App Router application for validating whether MCP OAuth clients use Client ID Metadata Documents (CIMD), fall back to Dynamic Client Registration (DCR), or send static client IDs.
- Next.js App Router and Vercel route handlers
- TypeScript
- Tailwind CSS
- Turso/libSQL
- Drizzle ORM
- Install dependencies:
npm install- Create local environment variables:
cp .env.example .env.local- Create and seed the local libSQL database:
npm run db:setup- Run the app:
npm run devOpen http://localhost:3000.
Create a Turso database and set these variables locally and in Vercel:
TURSO_DATABASE_URL=libsql://YOUR_DATABASE.turso.io
TURSO_AUTH_TOKEN=YOUR_TURSO_TOKEN
NEXT_PUBLIC_BASE_URL=https://YOUR_DOMAINThen run:
npm run db:migrate
npm run db:seedFor Vercel, add the same environment variables in the project settings before deploying.
/.well-known/oauth-authorization-server/authorize/token/register/mcp
Add this Streamable HTTP MCP server URL to the client being tested:
https://cimd-reader.akxen.tech/mcp
Codex CLI:
codex mcp add cimd_reader \
--url https://cimd-reader.akxen.tech/mcp \
--oauth-resource https://cimd-reader.akxen.tech/mcp
codex mcp login cimd_readerClaude Code:
claude mcp add --transport http \
cimd_reader \
https://cimd-reader.akxen.tech/mcpVS Code mcp.json:
{
"servers": {
"cimd_reader": {
"type": "http",
"url": "https://cimd-reader.akxen.tech/mcp",
"oauth": {
"clientId": "https://vscode.dev/oauth/client-metadata.json"
}
}
}
}The authorization server advertises CIMD support. /authorize logs the request, classifies the client behavior, validates HTTPS URL client_id values as CIMD metadata documents, stores the result, then redirects to redirect_uri with a fake authorization code. /token returns a fake bearer token. /register logs DCR attempts and returns a fake client registration.
/shows MCP client cards with claimed support, observed behavior, and latest CIMD validation./clients/[id]shows known metadata, latest OAuth attempt, raw metadata JSON, validation errors, and warnings./sessionslists validation sessions./sessions/[id]shows an OAuth request timeline./api/clientsreturns client data as JSON./api/sessionsreturns session data as JSON.
The CIMD metadata fetcher:
- Requires HTTPS.
- Rejects localhost hostnames.
- Rejects private, loopback, link-local, carrier-grade NAT, multicast, and metadata IP ranges.
- Resolves hostnames and blocks unsafe DNS results.
- Limits redirects.
- Uses a request timeout.
- Caps response body size.
- Sends no credentials or cookies.
- Parses and validates JSON only after the fetch checks pass.
The seed script creates placeholder cards for:
- Visual Studio Code.
- Claude Code.
- MCPJam.
- Cursor.
- Codex CLI.
- GitHub Copilot.
- Windsurf.