> ## Documentation Index
> Fetch the complete documentation index at: https://modelcontextprotocol.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Web client

> A tab-by-tab walkthrough of the graphical MCP Inspector

The web client is the Inspector's richest surface: a single-page app backed by a small Node server that owns the actual MCP connections. It is the default mode, so `npx @modelcontextprotocol/inspector` with no mode flag lands here.

```bash theme={null}
npx @modelcontextprotocol/inspector                       # empty, add servers in the UI
npx @modelcontextprotocol/inspector node build/index.js   # with an ad-hoc stdio server
npx @modelcontextprotocol/inspector --catalog ./mcp.json  # with a catalog file
```

## The session token

The Node server behind the web client guards every `/api/*` route with a per-launch token, because it can spawn processes on your machine. The launcher prints a URL containing that token: **open that URL**, and don't type `localhost:6274` from memory.

The browser recovers the token from three places, in priority order:

1. `window.__INSPECTOR_API_TOKEN__`, injected into `index.html` on every page load. This is what makes a bare-URL reload or a bookmark keep working.
2. A `?MCP_INSPECTOR_API_TOKEN=...` query string, the form used in that printed URL.
3. `sessionStorage`, as a backstop.

Set the `MCP_INSPECTOR_API_TOKEN` environment variable to pin a known token (useful for scripted launches), or set `DANGEROUSLY_OMIT_AUTH=true` to disable the check entirely, but only on a machine where nothing else can reach the port. Both are described under [Web backend environment variables](/docs/draft/tools/inspector/configuration#web-backend-environment-variables).

## Dev mode

`--dev` is a **web-only** flag. It runs the Vite dev server instead of serving the pre-built bundle, which matters if you're working on the Inspector itself:

```bash theme={null}
mcp-inspector --web --dev
```

Production `--web` serves a built bundle. In the published package that bundle always ships; in a fresh source checkout it doesn't, so the runner builds it on demand the first time you launch.

## The tab bar

| Tab           | Shown when                                                            | What it does                                                                   |
| ------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| **Servers**   | Always                                                                | The server list: add, edit, import, connect, and open per-server settings.     |
| **Apps**      | The server exposes MCP App tools                                      | Renders a tool's UI in a sandboxed frame.                                      |
| **Tools**     | `tools` capability                                                    | Browse schemas, fill arguments, call, inspect results.                         |
| **Prompts**   | `prompts` capability                                                  | List prompts, supply arguments, preview generated messages.                    |
| **Resources** | `resources` capability                                                | Browse, read, and subscribe to resources.                                      |
| **Tasks**     | `capabilities.tasks` (legacy era) or the tasks extension (modern era) | Track long-running tool calls.                                                 |
| **Logs**      | `logging` capability                                                  | Server `notifications/message` output, plus the era-appropriate level control. |
| **Protocol**  | Always                                                                | The JSON-RPC transcript: requests, responses, notifications.                   |
| **Network**   | HTTP / SSE servers                                                    | The raw HTTP view: status, headers, bodies.                                    |
| **Console**   | stdio servers                                                         | The server process's `stderr`.                                                 |

**Network** and **Console** never appear together. Legacy and modern eras are described in [Protocol eras](/docs/draft/tools/inspector/protocol-eras).

<Frame caption="The tab bar on a connected server. Which tabs appear depends on the capabilities the server reported.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-tab-bar.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=04bb61c4a45ff12e8337c701e195c386" width="3840" height="2400" data-path="images/inspector/web-tab-bar.png" />
</Frame>

### The monitoring sidebar

**Tasks**, **Logs**, **Protocol**, **Network**, and **Console** form a *monitor group*. Pin the group and they leave the tab bar and move into a resizable right-hand column, so you can watch traffic while working in Tools or Resources. The column width and the selected monitor tab persist across reloads.

<Frame caption="The monitoring sidebar pinned beside the Tools screen. The Protocol stream stays visible while you work.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-monitor-sidebar.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=eef6e546b9831b3d169e26bba8c54ce3" width="3840" height="2160" data-path="images/inspector/web-monitor-sidebar.png" />
</Frame>

## Servers

The Servers screen is the entry point. A server row carries its transport, its connection state, and a control that opens its per-server settings.

Where that list comes from, and whether it's editable, depends on how you launched:

| Launch                                       | Server list                                                             | Editable? |
| -------------------------------------------- | ----------------------------------------------------------------------- | --------- |
| `mcp-inspector --web`                        | The default catalog `~/.mcp-inspector/mcp.json`, seeded on first launch | Yes       |
| `--catalog <path>`                           | That file, seeded with the sample servers if missing                    | Yes       |
| `--config <path>`                            | That file, read-only (never written or seeded)                          | No        |
| `--server-url <url>` or a positional command | One ad-hoc server, held in memory                                       | No        |

On a first launch the web client seeds the catalog with two sample servers: a filesystem server scoped to `/tmp` and the canonical "everything" reference server. See [Configuration and flags](/docs/draft/tools/inspector/configuration) for the full rules, including why the CLI and TUI seed an empty catalog instead.

### Server Settings

* **Protocol Era**: `legacy` / `auto` / `modern`. See [Protocol eras](/docs/draft/tools/inspector/protocol-eras).
* **Log level per request**: the level a modern-era connection stamps on each outgoing request by default, or `off` to opt out (see [Logging](/docs/draft/tools/inspector/protocol-eras#logging)).
* **Advertised Extensions**: which extensions the Inspector declares in `capabilities.extensions`. A debugging knob: a server may legitimately change what it registers based on what you advertise. Uncheck the Tasks extension and reconnect against the `test-servers/configs/advertised-extensions-http.json` fixture (setup in [Reproducing each era locally](/docs/draft/tools/inspector/protocol-eras#reproducing-each-era-locally)) to watch a tool disappear.
* **Roots**: the roots advertised via the `roots` client capability. `@modelcontextprotocol/server-filesystem`, for instance, calls `roots/list` to learn its allowed directories.
* **Headers**, **timeouts**, and **OAuth** fields.
* **Fetch lists one page at a time**: when off, list results are auto-aggregated across pages on connect; when on, each list loads page 1 only with a **Load next page** control and an *N pages loaded* status. Reproduce with `test-servers/configs/pagination-http.json`, which paginates 12 tools, resources, and prompts into three pages each.

<Frame caption="Server Settings with Advertised Extensions expanded. Unchecking one changes what the Inspector declares at connect.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-server-settings.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=d42be09ee8de7e45e58a8ff1a444ba52" width="3840" height="2160" data-path="images/inspector/web-server-settings.png" />
</Frame>

## Tools

Select a tool to see its description, its input schema rendered as a form, and its annotations. Fill the form and call it; the result renders below with structured content, embedded resources, and images handled natively.

On modern-era servers this screen also shows mirrored `Mcp-Param-*` headers, excluded tools, and distinct `-32602` error panels, all covered in [Protocol eras](/docs/draft/tools/inspector/protocol-eras#tools-mirrored-headers-and-excluded-tools).

<Frame caption="A tool call and its rendered result. The argument form collapses into the result panel once the call returns.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-tools.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=7ef469a969f398ac0ec70cf019c133da" width="3840" height="2160" data-path="images/inspector/web-tools.png" />
</Frame>

## Resources

Lists resources and resource templates with their MIME types and descriptions, reads content on selection, and offers **Subscribe** on servers that support subscriptions. The subscription mechanics differ by era; see [Resource subscriptions](/docs/draft/tools/inspector/protocol-eras#resource-subscriptions).

<Frame caption="A resource read, with an active subscription listed below the resource list.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-resources.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=1a94ea452e1ef8aaf2c9f486ed810b28" width="3840" height="2160" data-path="images/inspector/web-resources.png" />
</Frame>

## Prompts

Lists prompt templates with their arguments, and renders the generated messages for the arguments you supply, which is the fastest way to confirm a prompt produces what you intended.

<Frame caption="A prompt rendered with the arguments supplied.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-prompts.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=81b16312b1adff5601622a72444b0f92" width="3840" height="2160" data-path="images/inspector/web-prompts.png" />
</Frame>

## Apps

[MCP Apps](/extensions/apps/overview) are tools that carry UI. The Apps tab renders one in a sandboxed iframe served from a **separate port**, exercises the `ui/*` bridge, and shows the view's `ui/message` submissions and its `notifications/message` logs in side panels.

* The sandbox port is dynamic by default; pin it with `MCP_SANDBOX_PORT` if you need to expose or forward it.
* The sandbox is gated by a `frame-ancestors` CSP, and a bracketed IPv6 literal is not a valid CSP host-source, so browse the Inspector at `localhost`, `127.0.0.1`, a hostname, or a LAN IPv4, **not** at a bare `http://[::1]:...`.
* The sandbox URL is always plain `http`, so an `https://` Inspector page blocks the frame as mixed content. MCP Apps need a plain-`http` origin today.

See [Recipes](/docs/draft/tools/inspector/recipes#reviewing-an-mcp-app) for the CLI-first automated review flow.

<Frame caption="An MCP App rendered in its sandboxed frame, with the app's own logs below it.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-apps.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=bd311848514f7d251640012986abfc4d" width="3840" height="2160" data-path="images/inspector/web-apps.png" />
</Frame>

## Protocol, Network, and Console

The three tabs show the same traffic at different levels of detail:

* **Protocol**: the JSON-RPC transcript. Requests paired with responses, notifications inline, [MRTR](/docs/draft/tools/inspector/protocol-eras#multi-round-tool-results-mrtr) rounds grouped as one conversation, and spec errors rendered by class.
* **Network**: the HTTP layer, for SSE and Streamable HTTP servers. Status codes, request and response headers, and bodies. On modern connections the standardized `Mcp-*` headers are highlighted and sentinel values decoded.
* **Console**: the connected stdio server process's `stderr`, which is where most stdio servers put their own diagnostics.

Secrets are masked in these views, and entries can be cleared or exported.

<Frame caption="The Protocol tab with an entry expanded, showing the full JSON-RPC exchange.">
  <img src="https://mintcdn.com/mcp/gk28X8wi_tbRYzej/images/inspector/web-protocol.png?fit=max&auto=format&n=gk28X8wi_tbRYzej&q=85&s=f31338c83a389c5588f11c0d5b2b97ed" width="3840" height="2160" data-path="images/inspector/web-protocol.png" />
</Frame>

## Deep links

A driver (a script, a CI harness, or the CLI's [`--print-handoff`](/docs/draft/tools/inspector/authorization#handing-off-from-the-web-client-to-the-cli)) can reach a *connected* Inspector with a single navigation:

```
http://127.0.0.1:6274/?serverUrl=<url>&transport=http|sse&autoConnect=<token>
```

| Parameter     | Meaning                                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------------------------- |
| `serverUrl`   | The MCP server URL. Restricted to `http:` / `https:`; a crafted `javascript:` or `file:` value is rejected.    |
| `transport`   | `http` (default) or `sse`.                                                                                     |
| `autoConnect` | **Required CSRF gate.** Must equal the per-launch session token, which only whatever started the server knows. |

Three further parameters land you on a *rendered app*: `openApp=<toolName>` names the tool, `appArgs=<base64url(JSON)>` supplies its arguments (merged over the tool's schema defaults), and `autoOpen=<token>` fires the tool call automatically. Because `autoOpen` fires a call, it carries the same mandatory token gate as `autoConnect`.

## Host binding and origins

By default the Inspector binds `localhost` and accepts requests only from the loopback origins for its port. Treat both defaults as security boundaries, since the backend spawns processes on your machine.

Binding all interfaces (`HOST=0.0.0.0`) is **refused** unless you set `DANGEROUSLY_BIND_ALL_INTERFACES=true`. Binding a *specific* non-loopback address is allowed with no opt-in, since that's a single deliberate exposure rather than every interface at once.

See the [Hosting on a network](/docs/draft/tools/inspector/recipes#hosting-on-a-network) recipe for the full matrix, and [Configuration](/docs/draft/tools/inspector/configuration#web-backend-environment-variables) for the variables.
