{"slug": "show-hn-mcp-console-an-mcp-cli-with-support-for-cimd-and-dcr", "title": "Show HN: mcp-console, an MCP CLI with Support for CIMD and DCR", "summary": "A new open-source CLI client called mcp-console supports two OAuth 2.0 authentication strategies for Model Context Protocol servers: CIMD (Client ID Metadata Document) and DCR (Dynamic Client Registration). The tool, built with Node.js ≥ 20, caches tokens and registration data locally for instant reconnections and provides commands for registration, interactive connection, and server configuration management.", "body_md": "A CLI client for [Model Context Protocol (MCP)](https://modelcontextprotocol.io) servers that supports two OAuth 2.0 client authentication strategies:\n\n**CIMD**(Client ID Metadata Document) — the client's HTTPS metadata URL is used directly as`client_id`\n\n. The authorization server fetches your public key from that URL; no prior registration is required.**DCR**(Dynamic Client Registration, RFC 7591) — the client registers itself with the server's registration endpoint at runtime and receives a`client_id`\n\n(and optionally a`client_secret`\n\n).\n\nTokens and registration data are cached locally (`~/.config/mcp-console/`\n\n) so subsequent connections are instant.\n\n- Node.js ≥ 20\n- npm ≥ 9\n\n```\n# From source\ngit clone <repo-url>\ncd mcp-console\nnpm install\nnpm run build\nnpm link          # makes mcp-console available globally\n```\n\n-\n**Register**— generate an RSA key pair and a CIMD metadata document:\n\n```\nmcp-console register \\\n  --client-id-url https://example.com/my-mcp-client.json \\\n  --client-name \"My MCP Client\"\n```\n\nThis writes\n\n`cimd-client-metadata.json`\n\nto the current directory and saves your keys to`~/.config/mcp-console/keys.json`\n\n. -\n**Host the metadata file**— make the generated JSON reachable at the URL you provided. It must be served over HTTPS and be publicly accessible. -\n**Connect**— open an interactive session with an MCP server:\n\n```\nmcp-console connect https://api.example.com/mcp\n```\n\nThe first time you connect, a browser window opens for OAuth authorization. Tokens are cached automatically.\n\nNo registration step required. Just connect and the client registers itself on the fly:\n\n```\nmcp-console --auth dcr connect https://api.example.com/mcp\n```\n\nThe `--auth`\n\nflag is a **global option** — place it before the subcommand:\n\n```\nmcp-console --auth <mode> <command> [args]\n```\n\n| Mode | Behaviour |\n|---|---|\n`auto` |\n(default) Checks per-server history. If a `clientIdUrl` is configured, tries CIMD first; falls back to DCR automatically on `invalid_client` . |\n`cimd` |\nAlways use CIMD. Requires `register` to have been run first. |\n`dcr` |\nAlways use Dynamic Client Registration. Ignores any configured `clientIdUrl` . |\n\nOnce a mode is resolved automatically, it is saved per-server in `~/.config/mcp-console/servers/`\n\n. Subsequent connects reuse the saved mode without re-probing.\n\nGenerate an RSA key pair (RS256, 2048-bit) and a CIMD client metadata document.\n\n```\nmcp-console register --client-id-url <url> [options]\n```\n\n| Option | Default | Description |\n|---|---|---|\n`--client-id-url <url>` |\n(required) |\nHTTPS URL where the metadata document will be hosted. Used as the OAuth `client_id` . |\n`--client-name <name>` |\n`mcp-console` |\nHuman-readable name included in the metadata. |\n`--redirect-uri <uri>` |\n`http://localhost:3000/callback` |\nOAuth redirect URI. |\n`--out <path>` |\n`cimd-client-metadata.json` |\nOutput file path for the metadata document. |\n`--regenerate-keys` |\n— | Force regeneration of the RSA key pair even if one already exists. |\n\nAfter running, host the generated file at the URL you specified. The authorization server will fetch it when verifying your identity.\n\nConnect to an MCP server and open an interactive REPL.\n\n```\nmcp-console [--auth <mode>] connect <server-url> [--port <number>]\n```\n\n| Option | Default | Description |\n|---|---|---|\n`--port <number>` |\n`3000` |\nLocal port for the OAuth callback server. |\n\nInside the REPL you can list and call tools, list and read resources, and list and get prompts — all through an arrow-key menu.\n\nDelete all stored configuration for an MCP server — tokens, client registration, and resolved auth mode.\n\n```\nmcp-console forget <server-url>\n```\n\nAfter running, the next `connect`\n\nto that server will go through the full OAuth authorization flow again, as if connecting for the first time.\n\n**Example:**\n\n```\nmcp-console forget https://api.example.com/mcp\nmcp-console [--auth <mode>] tools list <server-url> [--port <number>]\n```\n\nPrints all tools exposed by the server, including their names, descriptions, and argument names.\n\n```\nmcp-console [--auth <mode>] tools call <server-url> <tool-name> [--args <json>] [--port <number>]\n```\n\n| Option | Default | Description |\n|---|---|---|\n`--args <json>` |\n`{}` |\nTool arguments as a JSON object. |\n\n**Example:**\n\n```\nmcp-console tools call https://api.example.com/mcp get_weather \\\n  --args '{\"location\":\"Madrid\"}'\nmcp-console [--auth <mode>] resources list <server-url> [--port <number>]\nmcp-console [--auth <mode>] resources read <server-url> <uri> [--port <number>]\n```\n\nText resources are printed to stdout. Binary resources (blobs) are written as raw bytes — suitable for piping:\n\n```\nmcp-console resources read https://api.example.com/mcp file://image.png > image.png\nmcp-console [--auth <mode>] prompts list <server-url> [--port <number>]\nmcp-console [--auth <mode>] prompts get <server-url> <prompt-name> [--args <json>] [--port <number>]\n```\n\n| Option | Default | Description |\n|---|---|---|\n`--args <json>` |\n`{}` |\nPrompt arguments as a JSON object. |\n\n```\n~/.config/mcp-console/\n├── config.json           # Global config (clientIdUrl, clientName, …)\n├── keys.json             # RSA private + public key (JWK format)\n├── clients/\n│   └── <hash>.json       # DCR-registered client_id / client_secret per server\n├── tokens/\n│   └── <hash>.json       # Cached access + refresh tokens per server\n└── servers/\n    └── <hash>.json       # Resolved auth mode per server (avoids re-probing)\n```\n\n`<hash>`\n\nis the first 16 characters of the SHA-256 hash of the server URL.\n\nEach MCP server you connect to gets its own set of files under `~/.config/mcp-console/`\n\n, keyed by a 16-character SHA-256 hash of the server URL.\n\nStores the resolved authentication mode so subsequent connects skip re-probing.\n\n```\n{\n  \"authMode\": \"cimd\"\n}\n```\n\n| Field | Values | Description |\n|---|---|---|\n`authMode` |\n`cimd` | `dcr` |\nWritten after the first successful OAuth flow or auto-detection. |\n\nStores the OAuth client identity obtained during registration.\n\n```\n{\n  \"client_id\": \"https://example.com/my-mcp-client.json\",\n  \"client_secret\": \"optional-secret-for-dcr-clients\"\n}\n```\n\n| Field | Description |\n|---|---|\n`client_id` |\nFor CIMD: your `clientIdUrl` . For DCR: the server-assigned ID. |\n`client_secret` |\nOnly present for DCR when the server issues one. |\n\nCaches the OAuth access and refresh tokens so reconnects are instant.\n\n```\n{\n  \"access_token\": \"eyJ...\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"expires_at\": 1748000000,\n  \"refresh_token\": \"eyJ...\",\n  \"scope\": \"mcp\"\n}\n```\n\n| Field | Description |\n|---|---|\n`access_token` |\nBearer token sent with every MCP request. |\n`expires_at` |\nUnix timestamp (seconds). The client uses a 60-second buffer before expiry to trigger a refresh. |\n`refresh_token` |\nUsed to obtain a new access token without re-authorising in the browser. |\n\nTo force re-authentication with a specific server, delete or empty its `tokens/<hash>.json`\n\nfile.\n\n```\nnpm install           # install dependencies\nnpm run dev -- <args> # run from source with tsx (e.g. npm run dev -- --help)\nnpm run typecheck     # type-check without building\nnpm run build         # compile to dist/\nnpm test              # run all tests once\nnpm run test:watch    # re-run tests on file changes\nnpm run test:coverage # run tests and generate a coverage report\n```\n\nTests are co-located with their source files (`src/**/*.test.ts`\n\n) and run with [Vitest](https://vitest.dev).", "url": "https://wpnews.pro/news/show-hn-mcp-console-an-mcp-cli-with-support-for-cimd-and-dcr", "canonical_source": "https://github.com/imminent-technology/mcp-console", "published_at": "2026-07-22 07:21:59+00:00", "updated_at": "2026-07-22 07:52:29.747337+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools"], "entities": ["mcp-console", "Model Context Protocol", "CIMD", "DCR", "RFC 7591", "Node.js"], "alternates": {"html": "https://wpnews.pro/news/show-hn-mcp-console-an-mcp-cli-with-support-for-cimd-and-dcr", "markdown": "https://wpnews.pro/news/show-hn-mcp-console-an-mcp-cli-with-support-for-cimd-and-dcr.md", "text": "https://wpnews.pro/news/show-hn-mcp-console-an-mcp-cli-with-support-for-cimd-and-dcr.txt", "jsonld": "https://wpnews.pro/news/show-hn-mcp-console-an-mcp-cli-with-support-for-cimd-and-dcr.jsonld"}}