inspector/clients/cli/README.md
2026-07-02 16:35:31 -07:00

179 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MCP Inspector CLI Client
The CLI mode enables programmatic interaction with MCP servers from the command line. It is ideal for scripting, automation, continuous integration, and establishing an efficient feedback loop with AI coding assistants.
## Running the CLI
You can run the CLI client directly via `npx`:
```bash
npx @modelcontextprotocol/inspector --cli node build/index.js
```
The CLI mode supports operations across tools, resources, and prompts, returning structured JSON output.
### Examples
**Basic usage**
```bash
npx @modelcontextprotocol/inspector --cli node build/index.js
```
**With a configuration file**
```bash
npx @modelcontextprotocol/inspector --cli --config path/to/config.json --server myserver
```
**List available tools**
```bash
npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list
```
**Call a specific tool**
```bash
npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/call --tool-name mytool --tool-arg key=value --tool-arg another=value2
```
**Call a tool with JSON arguments**
```bash
npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/call --tool-name mytool --tool-arg 'options={"format": "json", "max_tokens": 100}'
```
**List available resources**
```bash
npx @modelcontextprotocol/inspector --cli node build/index.js --method resources/list
```
**List available prompts**
```bash
npx @modelcontextprotocol/inspector --cli node build/index.js --method prompts/list
```
### Remote Servers
You can also connect to remote MCP servers using HTTP or SSE transports.
**Connect to a remote MCP server (default is SSE)**
```bash
npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com
```
**Connect with Streamable HTTP transport**
```bash
npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --transport http --method tools/list
```
**Pass custom headers**
```bash
npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --transport http --method tools/list --header "X-API-Key: your-api-key"
```
When a server is loaded from a `--catalog`/`--config` file, its per-server settings (headers, connection/request timeouts, and OAuth) are applied to the connection — the same resolution the TUI uses. A `--header` flag overrides the file's headers for that run while leaving the file's timeouts and OAuth in place.
## Options
### MCP server (which server to connect to)
Options that specify the MCP server (catalog/config file, ad-hoc command/URL, env vars, headers) are shared by the Web, CLI, and TUI and are documented in [MCP server configuration](../../docs/mcp-server-configuration.md): `--catalog` (writable catalog, seeded if missing; default `~/.mcp-inspector/mcp.json` or `MCP_CATALOG_PATH`), `--config` (read-only session, errors if absent), `--server`, `-e`, `--cwd`, `--header`, `--transport`, `--server-url`, and the positional `[target...]`. `--catalog` and `--config` are mutually exclusive, and neither combines with an ad-hoc target.
### CLI-specific (what to invoke)
| Option | Description |
| ----------------------------- | ----------------------------------------------------------------------------------------- |
| `--method <method>` | MCP method to invoke (e.g. `tools/list`, `tools/call`, `resources/list`, `prompts/list`). |
| `--tool-name <name>` | Tool name (for `tools/call`). |
| `--tool-arg <key=value>` | Tool argument; repeat for multiple. Use `key='{"json":true}'` for JSON. |
| `--uri <uri>` | Resource URI (for `resources/read`). |
| `--prompt-name <name>` | Prompt name (for `prompts/get`). |
| `--prompt-args <key=value>` | Prompt arguments; repeat for multiple. |
| `--log-level <level>` | Logging level for `logging/setLevel` (e.g. `debug`, `info`). |
| `--metadata <key=value>` | General metadata (key=value); applied to all methods. |
| `--tool-metadata <key=value>` | Tool-specific metadata for `tools/call`. |
### CLI-specific (OAuth for HTTP servers)
The CLI runs the same loopback callback server as the TUI (`http://127.0.0.1:6276/oauth/callback` by default). On connect **401** or mid-session interactive auth (re-login / step-up), it:
1. Starts the callback listener on `--callback-url` (or `MCP_OAUTH_CALLBACK_URL`)
2. Prints the authorization URL to the console (`ConsoleNavigation`)
3. Waits for the browser redirect, exchanges the code, and retries connect or the failed RPC
**Step-up (standard OAuth):** when an RPC needs extra scopes, the CLI prompts on stderr: `Proceed with step-up authorization? [y/N]`. **y** continues; **N** exits with an error. EMA step-up re-mints silently (no prompt).
**Shared OAuth storage:** the CLI **reuses** tokens from `~/.mcp-inspector/storage/oauth.json` when they already exist (same file as other Inspector clients). That is passive file sharing, not launching another app.
**Shared with TUI** (config only, not interactive login):
- Per-server OAuth fields from `mcp.json` (static client, EMA resource credentials, scopes)
- Install-level settings from **`~/.mcp-inspector/storage/client.json`** (or `--client-config` / `MCP_CLIENT_CONFIG_PATH`) — EMA IdP, CIMD
- CLI flags `--client-id`, `--client-secret`, `--client-metadata-url` override `client.json` when set
- Keychain-backed secrets in `mcp.json` are rehydrated on catalog load (same as TUI)
#### OAuth callback URL
| Surface | Default callback |
| ------- | ---------------- |
| **Web** | `http://localhost:6274/oauth/callback` |
| **TUI** | `http://127.0.0.1:6276/oauth/callback` (interactive — callback server) |
| **CLI** | `http://127.0.0.1:6276/oauth/callback` (interactive — same callback server as TUI) |
Register `http://127.0.0.1:6276/oauth/callback` on static or enterprise IdPs that require pre-registered redirect URIs before using the **TUI** or **CLI**. Override with `--callback-url` or `MCP_OAUTH_CALLBACK_URL`. Only one process should bind the default port at a time.
#### Flags
| Option | Env | Description |
| ------ | --- | ----------- |
| `--client-config <path>` | `MCP_CLIENT_CONFIG_PATH` | Install-level client config (default: `~/.mcp-inspector/storage/client.json`). |
| `--client-id <id>` | — | OAuth client ID (static client); overrides `client.json`. |
| `--client-secret <secret>` | — | OAuth client secret; overrides `client.json`. |
| `--client-metadata-url <url>` | — | CIMD metadata URL; overrides `client.json`. |
| `--callback-url <url>` | `MCP_OAUTH_CALLBACK_URL` | Redirect URI sent to the authorization server (default: `http://127.0.0.1:6276/oauth/callback`). |
**Example** — list tools on an OAuth-protected server using stored tokens and CIMD from the command line:
```bash
npx @modelcontextprotocol/inspector --cli --catalog mcp.json --server my-http-server \
--client-metadata-url https://example.com/.well-known/oauth/client-metadata.json \
--method tools/list
```
See [EMA / enterprise-managed auth](../../specification/v2_auth_ema.md) and [OAuth smoke testing](../../specification/v2_auth_smoke_testing.md) (§3 Stytch/CIMD; [§5 mid-session manual validation](v2_auth_smoke_testing.md#5-mid-session-auth--step-up--manual-validation) — CLI **C1–C2**).
## Why use the CLI?
While the Web Client provides a rich visual interface, the CLI is designed for:
- **Automation**: Ideal for CI/CD pipelines and batch processing.
- **AI Coding Assistants**: Provides a direct, machine-readable interface (JSON) for tools like Cursor or Claude to verify changes immediately.
- **Log Analysis**: Easier integration with command-line utilities (like `jq`) to process and analyze MCP server output.
## Development
Like the other clients, the CLI self-validates from its own folder:
```bash
npm run validate # format:check && lint && test:coverage
npm test # build test-servers + binary, then run all tests
npm run test:coverage # build + tests under the per-file coverage gate
```
The CLI's `test:coverage` **builds the binary first** (its out-of-process
`e2e.test.ts` spawns it, so it must run against a fresh build). `validate`
therefore folds the build into `test:coverage` rather than repeating it — it is
`format:check && lint && test:coverage`, with no separate `build` step (the
other clients, whose tests don't spawn their bundle, keep an explicit `build`).
The repo-root `validate:cli` just delegates here.
Tests run the CLI **in-process** (importing `runCli()`) so `src/` is measured
under coverage, with a thin out-of-process spawn layer for the real binary. See
[`__tests__/README.md`](./__tests__/README.md) for details.