Skip to content

Blog Article

MCP Inspector: Debug a Connection Step by Step

Use MCP Inspector to isolate connection, authentication, tool discovery, and read-call failures. Follow a safe local example and an AppHandoff walkthrough.

By AppHandoff Team · Published · 10 min read

Illustration of an MCP connection linking a coding agent with shared project context
MCPTroubleshooting

MCP Inspector helps answer a narrow but important question: what happens when a separate MCP client connects to this server and makes one request? Use it to split a vague “my agent cannot see the tool” report into connection, authorization, discovery, and tool-call outcomes. Then compare those findings with the configuration in the editor that failed. A successful Inspector run proves the Inspector's path worked at that moment; it does not prove that another client is configured or signed in the same way.

This walkthrough follows the current official MCP Inspector guide and its CLI method reference, checked October 9, 2026. The local example below is illustrative and was reviewed against those docs, not executed against a server. The AppHandoff sequence is also documentation-based; it does not claim a fresh Inspector connection, a customer result, or a production benchmark. Keep any real session tokens and response data out of shared debugging notes.

Choose one question before opening Inspector

If you maintain a local stdio server, start with its launch command. If an HTTP service is failing, start with its exact endpoint and supported transport. Record the expected tool name and one read-only request whose result you recognize. Do not begin with a mutation: a successful write would change project data and would make diagnosis harder. A simple result is enough to distinguish a network problem from a handler problem.

  1. Connection: Can Inspector reach and initialize the server over the intended transport?
  2. Authentication: Does the same session have a usable grant for this endpoint?
  3. Discovery: Does tools/list return the expected tool name and input schema?
  4. Execution: Does one documented read call return data or a structured error?
  5. Client comparison: Does the failing editor use the same endpoint, transport, identity, and current tool catalog?

Those stages are separate. An HTTP health response proves a service answered that HTTP request; it does not prove MCP authentication or tool enumeration. A visible tool name proves discovery in one session; it does not prove the account can call it. A successful read call is stronger evidence, but only for that request and its arguments. Write down the exact stage that first fails before changing settings.

Start with the current Inspector package

The official guide currently requires Node 22.19.0 or newer. The same @modelcontextprotocol/inspector package has a browser interface, CLI, and terminal interface. The mode flag must come before the server target: --cli or --tui placed after a server command can instead become that server's argument. Running npx @modelcontextprotocol/inspector without a target opens the browser interface so you can add a server there. Its launch URL contains a per-launch API token; open it locally, but never copy it into a ticket, screenshot, chat, or terminal transcript you plan to share.

node --version
# Browser interface, with no target yet:
npx @modelcontextprotocol/inspector

# CLI: discover tools on an illustrative local stdio server:
npx @modelcontextprotocol/inspector --cli node path/to/server/index.js --method tools/list

# Terminal interface for the same illustrative server:
npx @modelcontextprotocol/inspector --tui node path/to/server/index.js

Replace path/to/server/index.js with the real command from that server's own documentation. It is a placeholder path, not an AppHandoff install step. The browser interface can show Tools, Protocol, and, for HTTP servers, Network views. Compare the request, response, status, and any tool error there. For stdio servers the Console view shows the launched process's stderr. The official web-client reference explains which panels appear for each transport.

Reproduce a read-only call in the CLI

The CLI connects, makes one named request, prints a result, and exits. Start with tools/list; inspect the returned names and argument schemas before selecting a call. For a local fixture with an illustrative read tool named lookup, this pattern passes a string argument named id. It is not a claim that every MCP server implements that tool. The current CLI accepts --tool-name for tools/call, and --tool-args-json for an entire argument object. Use your server's actual schema; an invented argument will fail validation even when the connection is healthy.

npx @modelcontextprotocol/inspector --cli node path/to/server/index.js \
  --method tools/list --format json

npx @modelcontextprotocol/inspector --cli node path/to/server/index.js \
  --method tools/call --tool-name lookup \
  --tool-args-json '{"id":"example-read-only-id"}' --format json

The first command discovers; the second actually invokes a tool. Run the second only after confirming lookup is a read operation in your own server. A CLI exit code of 3 represents an authentication failure, 4 an unreachable server, and 5 a tool error or missing tool. An in-band tool error can still include a useful result payload, so read the returned isError and structured fields instead of assuming that every HTTP 200 means success. The Inspector exit-code reference documents the codes and JSON error envelope.

Use AppHandoff as a remote example

AppHandoff's canonical MCP URL is https://api.apphandoff.com/mcp. It is a remote HTTP server with OAuth 2.1 or a user-created personal access token, not a local stdio process. In Inspector's browser interface, add that URL with HTTP transport, connect, and complete the authorized sign-in flow for the intended account. The Inspector's authorization guide describes its OAuth flow. AppHandoff's client connection guide describes its endpoint and client setup. Do not paste a bearer into an article example or share an Inspector session URL.

Once connected, inspect tools/list. AppHandoff currently serves eight tools: bootstrap, get, find, ticket, plan, message, project, and decide_lifecycle_proposal. Clients without approval-card support list seven tools; the eighth served tool remains a human-only UI action. The first read call should be bootstrap with a project the account can reach. It resolves project context and returns guidance; get or find can then read a named work item. The AppHandoff MCP overview explains this shared context, and the Claude Code MCP guide offers a client-specific setup comparison. Tool visibility alone never grants project access or permission to write.

For a quick check after Inspector already holds a valid grant on the same machine, the CLI can reuse stored authentication. Its documented --use-stored-auth option looks up the web Inspector token by server URL and returns an error if none matches. For an automated job that must never start interactive OAuth, the separate --stored-auth-only option uses a stored token or fails immediately. This sample lists tools and makes no write call. It is documentation-based and has not been run here. If it returns an auth error, complete sign-in in the browser interface or use your organization's approved credential route; do not work around the refusal by pasting tokens into a shell command.

npx @modelcontextprotocol/inspector --cli \
  --server-url https://api.apphandoff.com/mcp --transport http \
  --use-stored-auth --method tools/list --format json

After discovery, select bootstrap in the browser Tools tab and enter a project identifier you are authorized to access. For example, a project parameter can be a repository-shaped name such as owner/app; that string is illustrative, not a real accessible project. Inspect the returned guidance and project selection before moving to get or find. Avoid testing ticket, plan, message, or project as a casual next step: their actions can write, depending on the operation. A lifecycle approval card is for a signed-in human to decide through the approved flow; a model cannot treat Inspector output as that approval.

Locate the first failing layer

  • Connection fails before initialize: verify the exact endpoint, HTTP versus stdio choice, network reachability, and whether a local server process starts. Record the transport error without copying secrets.
  • Authentication fails: inspect the HTTP status and authorization error. A token for another resource, an expired token, or an incomplete OAuth grant requires a fresh authorized session, not another tools/list retry.
  • Discovery fails or a tool is absent: distinguish an auth error from an empty or stale catalog. Compare the listed names with current server documentation, then reconnect the editor to refresh its cached list.
  • A read tool fails: compare its actual input schema with the sent arguments, then inspect isError and any structured code, hint, or required scope. Retry only after changing the cause.
  • Inspector succeeds but an editor fails: compare that editor's URL, transport, identity, granted scopes, and cached tool list. Inspector's separate session cannot validate the editor's local settings.

For AppHandoff specifically, a 401 with AUTH_REQUIRED or TOKEN_EXPIRED points to authentication or expiry. A tool result can instead arrive over HTTP 200 with isError: true and structuredContent.code: INSUFFICIENT_SCOPE; read its required and granted scopes. A token's scopes are fixed when minted. For OAuth, obtain the needed consent and refresh after the grant changes; for a personal access token, mint a replacement with the required scope. If tools enumerate but bootstrap fails, inspect that call's error and project context rather than assuming the network is down. These behaviors come from AppHandoff's current MCP getting-started guide and served tool contract.

The public AppHandoff health response is useful for separating service reachability from an editor's tool hydration. Its tool count describes the server registry, not the tools a particular editor has loaded. Health does not establish that OAuth succeeded. If you suspect a client-file error, the MCP config checker examines selected core fields of strict JSON for Claude Code, Cursor, or VS Code in the browser. Use placeholder credentials. It does not launch a command, contact the endpoint, validate OAuth, or prove full client acceptance. Inspector supplies the live connection and read-call evidence; neither check grants access or certifies compatibility with every client.

Share a useful debug report without leaking access

A report should let someone else repeat the reasoning, not inherit your credentials. Note the date, Node and Inspector versions, which mode you used, the transport and host/path, the first failing stage, the tool name, and a sanitized error code. If you used a real project or work item, replace its identifier and content with a descriptive placeholder before sharing. Include whether the observation came from a local fixture, production, or a documentation-based example. Do not call a command successful unless it actually ran.

  • Keep the endpoint host and path, but remove URL query values, user information, and any bearer header.
  • Replace project IDs, work-item text, email addresses, and user names with placeholders.
  • Never attach the browser Inspector launch URL: it contains a per-launch API token.
  • Keep the error code, HTTP status, method name, and a short redacted response shape.
  • State the next check: reconnect the editor, renew authorization, correct arguments, or investigate the server handler.

Inspector may store OAuth tokens and other secrets in the OS keychain; on systems without a usable keychain, its documented fallback is a local secrets file that can be unencrypted unless configured otherwise. Treat a copied Inspector profile or debug bundle as sensitive. For a handoff between coding agents, put the sanitized observation and next action in the shared task record, never the raw token or full Protocol transcript. The agent handoff generator can format facts you enter, but it does not run Inspector or validate the claims. The best outcome is a small reproducible distinction: exactly which layer failed, what evidence supports it, and what a teammate should test next.

Frequently asked questions

What does MCP Inspector actually test?

MCP Inspector connects as a separate client. It can show whether that client can initialize, discover tools, and call a tool with its own transport and credentials. It cannot prove that another editor has the same configuration, cached tool list, or account access.

Can I test a remote MCP server without calling a write tool?

Yes. Connect with the server's documented transport and authentication, inspect tools/list, then choose a read-only tool and harmless arguments. Check the tool's description and required scopes before calling it; discovery alone does not execute the tool.

Why does tools/list succeed while a tool call fails?

Enumeration and execution cross different checks. The named tool may require a scope or project context that the current session lacks, its arguments may be invalid, or its handler may fail. Inspect the returned isError flag and structured error fields before retrying.