Files
Andrew Khadder e17cd7b8ca Canary (#2216)
* feat(client): support mixed OAuth servers

* fix(inspector): pause mixed-auth tool calls

* Revert "fix(inspector): pause mixed-auth tool calls"

This reverts commit 9bac9ddfe7.

* chore: finalize mixed OAuth changeset

* docs: explain mixed OAuth client flows

* fix: bound mixed auth metadata discovery

* docs(server): add runnable mixed oauth example

* fix(inspector): recover stale local connections

* fix(inspector): resume tools after mixed auth

* fix: address mixed auth review feedback

* fix(inspector): scope mixed auth retries

* test(inspector): remove jsdom-only regressions

* chore: enter canary prerelease mode

* chore(typescript): version packages (canary)

* fix(inspector): stream v2 subscription acknowledgements

* fix(client): discover mixed auth after ready

* test(client): preserve mocked connection compatibility

* fix(client): defer mixed auth discovery until ready

* fix(client): discover mixed auth after ready paint

* perf(client): expose tools before auxiliary inventories

* fix(client): refresh mixed auth discovery after reconnect

* chore(typescript): version packages (canary)

* fix(client): make codeMode custom executor functions actually work (#2123)

* fix(client): make codeMode custom executor functions actually work

`_ensureCodeExecutor()` handled a function-valued `codeMode.executor` by
assigning `this._customCodeExecutor` and then throwing
"Custom executor function should be handled in executeCode". Since
`executeCode()` read that field *before* calling `_ensureCodeExecutor()`,
and only `_ensureCodeExecutor()` ever populated it, the first
`executeCode()` call always rejected and only the second succeeded.
`searchTools()` had no such fallback, so it rejected on every call --
including via the `search_tools` meta tool on `CodeModeConnector`. Because
`_codeExecutor` stayed null, `close()` also skipped executor cleanup.

Route function executors through a new `FunctionCodeExecutor` adapter so
they participate in the normal executor lifecycle, and drop the now-unused
`_customCodeExecutor` field and its pre-check in `executeCode()`.

Also fix `detail_level` validation in `CodeModeConnector.callTool`: it
used `detailLevel in ["names", "descriptions", "full"]`, and `in` tests
property keys, so an array literal only has `"0"`/`"1"`/`"2"`/`"length"`.
Every valid detail level failed the guard and was silently rewritten to
`"full"`, so an agent requesting `"names"` received full input schemas for
every tool. Replaced with a `Set` membership test.

Adds 10 unit tests: first-call success, timeout forwarding, `searchTools`,
`close()` cleanup, the `BaseCodeExecutor` instance path, each valid
`detail_level`, and the unknown/omitted fallbacks.

Closes #2122

* fix(client): preserve `this` for custom executors, tighten tests, document the contract

Addresses review feedback on the code-mode custom-executor fix.

The `this` binding regression is real -- I measured it both ways. On the
pre-fix code the executor function was invoked as
`this._customCodeExecutor(code, timeout)`, so a non-arrow function saw the
`MCPClient` as its `this`; through the new adapter it saw the
`FunctionCodeExecutor`. `FunctionCodeExecutor.execute` now calls
`this.fn.call(this.client, ...)` so a `function`-form executor keeps the same
context it had before, and a test asserts it.

Two tests were weaker than their titles claimed:

- the `searchTools` test ran against an empty client, so it only proved the
  call did not throw. It now registers a stub session with one tool and
  asserts the full `{ meta, results }` payload, including the namespace and
  the tool's `input_schema`.
- the `close()` test only asserted the promise resolved, which would pass
  even if cleanup were skipped. It now spies on the resolved executor's
  `cleanup()` and asserts it ran exactly once.

Documentation: the API reference listed one "Custom" executor row saying to
implement `execute()` + `cleanup()`, which is only true for the
`BaseCodeExecutor` subclass form. Split it into separate class and function
rows, add the `CodeExecutorFunction` signature to the types block, and add a
worked example to the code-mode guide (current and v2) stating the `this`
context and that the function owns its runtime cleanup.

* docs(client): use a non-arrow custom executor in the code-mode example

The example demonstrated the documented `this` context with an arrow function,
which has lexical `this` and therefore cannot observe it. Switched to
`async function (this: MCPClient, code, timeout)` and had it actually call
`this.getServerNames()`, so the snippet exercises the contract it describes.
Type-checked the snippet shape against the real `MCPClient` type with
`tsc --noEmit` before committing.

Also reworded the surrounding paragraph: the `this` binding is specific to the
non-arrow form, whereas the cleanup-ownership rule applies to every custom
function.

* docs(client): drop v1 code-mode custom executor docs

This change is v2-only; keep the custom-executor contract on the v2 docs path.

* chore(typescript): version packages (canary)

* fix(create-app): sanitize the npm name for named projects, not just "." (#2209)

deriveProjectInfo only ran sanitizePackageName on the "." branch. A named
project passed the raw argument straight through as packageName, which is
then written into package.json and substituted into the template's index.ts.

The CLI rejects path separators, ".." and a few protected names, but not
spaces, quotes or capitals, so `create-mcp-use-app 'My "App"'` emitted
`name: "My "App""` in index.ts, which is not valid TypeScript.

Sanitize on both branches. The directory still uses the name as typed.

* chore(typescript): version packages (canary)

* fix: enable skills tab after HMR (#2220)

* chore(typescript): version packages (canary)

* fix(create-app): strip leading underscores when sanitizing a package name (#2221)

sanitizePackageName removed leading dots and dashes but not underscores, so
create-mcp-use-app _foo wrote "name": "_foo" into package.json.

npm publish rejects that outright:

  npm error code EINVALIDPACKAGENAME
  npm error Invalid package name "_foo": name cannot start with an underscore.

Widen the leading-character class to [._-] and cover both the sanitizer and a
named project starting with an underscore.

Closes #2219

* chore(typescript): version packages (canary)

* fix(client): surface auth for protected operations

* fix(inspector): resume mixed-auth chat tools (#2226)

* chore(typescript): version packages (canary)

* fix: harden stable mixed-auth flows

---------

Co-authored-by: Enrico <2827496+tonxxd@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: LHMQ878 <72402929@cityu-dg.edu.cn>
Co-authored-by: Ayaan Gazali <ayaangazali.work@gmail.com>
2026-08-11 12:52:52 +02:00

170 lines
7.7 KiB
Plaintext

---
title: "Inspector"
description: "Connect to an MCP server, run tools, inspect resources and prompts, and debug widgets."
icon: "monitor"
---
Use the Inspector when you need to test an MCP server from the browser. It lets you connect to a server, call tools with typed inputs, inspect resources and prompts, try chat, preview widgets, and copy client setup commands.
[![Try this live](/images/UseLiveSmall.svg)](https://inspector.mcp-use.com)
<Frame caption="Inspector dashboard">
<img
src="/images/inspector/inspector-dashboard.jpg"
alt="MCP Inspector dashboard"
/>
</Frame>
If your server was created with `mcp-use`, run the dev server and open the local Inspector:
```bash
npm run dev
```
The default local URLs are:
| URL | Purpose |
| ------------------------------------- | ------------ |
| `http://localhost:3000/mcp` | MCP endpoint |
| `http://localhost:3000/mcp/inspector` | Inspector UI |
You can also open the hosted Inspector at [inspector.mcp-use.com](https://inspector.mcp-use.com) or run it with [`npx @mcp-use/inspector`](/inspector/cli).
## Connect to a server
Add a server from the dashboard. Choose the transport, enter the MCP endpoint URL, and click **Connect**.
<Frame caption="Connection form">
<img
src="/images/inspector/connect-form.png"
alt="Inspector connection form"
/>
</Frame>
For most local and public HTTP servers, use **Direct**. Use **Via Proxy** only when the browser cannot reach the server directly because of CORS or network policy. See [Connection settings](/inspector/connection-settings) for the short decision guide.
When a server protects the whole MCP endpoint with OAuth, the connection waits
for authentication. Click **Authenticate**, complete the provider approval, and
return to the Inspector.
A mixed-auth server connects anonymously because its public tools are already
usable. If it publishes OAuth protected-resource metadata, the server card and
header show **This server is using mixed auth** with an **Authenticate** button.
You can authenticate immediately or wait until a protected operation returns a
wire-level OAuth challenge. The connection stays available for public
operations while authentication is optional.
## Run a tool
Open a connected server and select the **Tools** tab. Choose a tool, fill the generated form, and run it.
<Frame caption="Server tools">
<img
src="/images/inspector/server-detail.png"
alt="Inspector server detail view with tools"
/>
</Frame>
The Inspector shows the tool result, structured content, errors, and any widget returned by the tool. Use this view to verify schema validation, result shape, and widget data before testing the same server from a client.
For mixed-auth servers, a protected tool can surface the authentication action
only when it is needed. Authenticate, then retry the protected call. A normal
MCP tool result with `isError: true` is still shown as a tool error; the Inspector
does not infer OAuth from its text.
## Inspect resources and prompts
Use **Resources** to read server-provided content by URI. Use **Prompts** to test reusable prompt templates with arguments.
These tabs are useful when a client reports missing context. They show what the server actually exposes after connection and auth.
## Inspect Skills over MCP
**Skills** is always present in the Inspector navigation. When a server does not
advertise the experimental `io.modelcontextprotocol/skills` extension, the tab
is disabled, like Sampling, with an explanation that Skills over MCP is not
available from that server. When the extension is available, each skill appears
as a folder containing its `SKILL.md` and supporting resources.
When the extension is advertised but its catalog is empty, the tab is shown as
a red error state and disabled, with a tooltip explaining that the server
returned no skills.
Select a file to read it on demand. Before previewing it, the Inspector verifies the raw SHA-256 digest advertised by the skill manifest. For `SKILL.md`, it also checks that the parsed YAML frontmatter matches the catalog entry. A digest mismatch blocks the preview instead of passing changed content to the user or model.
Markdown, safe text, raster images, audio, and video have inline previews. Scripts, HTML, SVG, and other binary files are never executed; you can explicitly download verified files when needed.
## Try chat
Use **Chat** to test how an LLM calls your server's tools in a conversation. The chat view can use hosted chat where available or a provider key stored in your browser.
Keep chat testing focused on end-to-end behavior. Use the Tools tab first when you need to isolate input schemas, tool errors, or widget rendering.
For servers that advertise Skills over MCP, chat receives a compact catalog of
each skill's name, description, origin, and URI. When a skill is relevant, the
chat host loads its `SKILL.md` and supporting resources lazily through the
server's Skills over MCP and resource methods. It verifies each resource
against the manifest's raw SHA-256 digest before making it available to the
model. The Inspector never executes skill scripts or lets `allowed-tools`
widen the selected MCP tool permissions.
Skills over MCP remains experimental. Treat remote skill content as untrusted and review it before relying on its instructions. See the [working group](https://modelcontextprotocol.io/community/working-groups/skills-over-mcp), [SEP-2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640), and [Agent Skills specification](https://agentskills.io/specification).
## Debug widgets
When a tool returns an MCP App widget, the Inspector renders it below the tool result and exposes widget debug controls.
Use the widget view to check:
- the `props`, `output`, and metadata passed to the widget
- inline, picture-in-picture, and fullscreen display modes
- desktop, tablet, and mobile layout behavior
- theme, locale, timezone, hover, touch, and safe-area settings
- Content Security Policy behavior before trying the widget in a host
See [Debug widgets in the Inspector](/inspector/debugging-chatgpt-apps) for the full workflow.
## Add the server to a client
After a server connects, use **Add to Client** to install or copy setup for supported clients such as Cursor, VS Code, Claude Desktop, Claude Code, Gemini CLI, and Codex CLI.
<Frame caption="Add to Client actions">
<img
src="/images/inspector/add-to-client-dropdown.png"
alt="Add to Client dropdown in the Inspector"
/>
</Frame>
The Inspector uses the active connection settings when it prepares the client setup. Confirm the server URL and connection name before copying commands or opening client deep links.
## Command Palette
Press `Cmd/Ctrl + K` to open the [Command Palette](/inspector/command-palette). Use it to jump to tools, prompts, resources, saved requests, connected servers, and client setup actions.
For the full shortcut list, see [Keyboard shortcuts](/inspector/keyboard-shortcuts). For shareable links that open a server or tab directly, see [URL parameters](/inspector/url-parameters).
## Next steps
<CardGroup cols={2}>
<Card title="CLI usage" icon="terminal" href="/inspector/cli">
Run the Inspector from the command line and auto-connect to a server.
</Card>
<Card
title="Connection settings"
icon="settings"
href="/inspector/connection-settings"
>
Choose Direct or Via Proxy and tune connection details only when needed.
</Card>
<Card
title="Debug widgets"
icon="bug"
href="/inspector/debugging-chatgpt-apps"
>
Test MCP Apps widgets, layout behavior, CSP, and display modes.
</Card>
<Card title="Mount the Inspector" icon="plug-2" href="/inspector/integration">
Serve the Inspector from an Express, Hono, or mcp-use server.
</Card>
</CardGroup>