Skip to main content

MCP diagnostics

MCP diagnostics tests your own MCP server, the one you build and deploy, as an MCP client would see it. A run tells you:

  • whether the server is reachable;
  • how it authenticates;
  • which protocol version it negotiates;
  • whether its tools, resources and prompts are well formed.

It never calls your tools. Every request and response is kept in a redacted transcript that you can export as a receipt.

Connecting to Hooklistener's MCP server?

This page is about testing a server you run. To give your AI assistant Hooklistener's own tools, see Setup or Connect with one prompt.

Where to find it​

Open MCP diagnostics in the Operate section of the app's sidebar (https://app.hooklistener.com/mcp-diagnostics), or search for it with ⌘K. It used to be a tab under Real-time; old /realtime/mcp links redirect to the new pages.

MCP diagnostics is available on every plan, Free included. Runs belong to the organization: any member can start, cancel, rerun, export or delete them.

Run a diagnostic​

  1. Click Run diagnostic.
  2. Enter the MCP endpoint URL, for example https://api.example.com/mcp.
  3. Choose the Authentication: No authentication, OAuth 2.1 (recommended), Bearer token or Custom headers. See Authentication.
  4. Click Run diagnostic.

The run is queued and the page updates live as each step completes.

The URL must point to a remote server that speaks Streamable HTTP:

  • It must be reachable from the internet. Local stdio servers aren't supported. Neither are localhost, private, loopback or link-local addresses, nor hosts that don't resolve to a public IP address.
  • http:// or https://, on any port. HTTPS is required when you supply credentials of any kind.
  • No query string (put credentials in headers), no user:password@ and no #fragment. At most 2,048 characters.

What a run checks​

A run is read-only. It sends these requests in order:

  1. Reachability. Hooklistener connects to the URL. Every request in a run goes to the same IP address, so session affinity holds behind round-robin DNS.

  2. Initialize. It sends initialize, offering protocol version 2025-11-25, with clientInfo named Hooklistener MCP Diagnostics. The response must include protocolVersion, serverInfo.name, serverInfo.version and a capabilities object.

  3. Protocol version. The server may answer 2025-11-25, 2025-06-18, 2025-03-26 or 2024-11-05. Any other version fails the run, and the run stops there.

  4. Initialized notification. It sends notifications/initialized. An error answer is a warning.

  5. Ping. It sends ping. A server that doesn't implement it (-32601) gets Skipped, not a failure.

  6. Capability discovery. For each capability the server advertised, it calls tools/list, resources/list and prompts/list. It follows nextCursor for up to 10 pages and 500 items per list; past either limit the check is a warning. It also validates every descriptor:

    • Tools need a name and an inputSchema object with "type": "object", a properties object and a required array of strings. An outputSchema, if present, is checked the same way.
    • Resources need a name and a uri.
    • Prompts need a name, and arguments must be an array of objects with a name.

    A capability the server didn't advertise is Skipped.

  7. Session cleanup. If initialize returned an Mcp-Session-Id, it sends DELETE to end the session. A 2xx, a 404 (already closed) or a 405 (the server doesn't let clients end sessions) all pass.

A run never calls tools/call, resources/read or prompts/get, and never answers sampling or elicitation requests from the server.

Each check is Passed, Warning, Failed or Skipped. The run's result is Failed if any check failed, Warning if any check warned, and Passed otherwise. Skipped checks don't lower the result.

Common failures​

CheckWhat it means
AuthenticationThe server answered 401 or 403. Without credentials the message is "The server requires authentication; add credentials or choose OAuth". The server's WWW-Authenticate header is quoted.
InitializeThe server answered 429 (its Retry-After is quoted), another HTTP error, or a response without the required fields
ReachabilityTimeout, connection failure, an invalid or blocked target, a refused redirect, or a response over the size limit
Redirect (warning)The URL redirected. Configure MCP clients with the final URL: many don't replay POST bodies across redirects.

Streamable HTTP​

Hooklistener tests the Streamable HTTP transport:

  • Every request is a POST with Accept: application/json, text/event-stream and Content-Type: application/json. After initialize, requests also carry Mcp-Session-Id (when the server issued one) and MCP-Protocol-Version.
  • A JSON response or an SSE stream are both accepted. An SSE response is read until the message that answers the request arrives. Any other Content-Type fails.
  • No Accept-Encoding is sent, so the server must not compress its responses.
  • Hooklistener never opens the optional GET stream. The legacy HTTP+SSE transport (a GET that announces an endpoint event) is not supported.
  • Up to 3 redirects are followed, to the same origin only (or from http to https on the same host). The method and body are sent again.

Authentication​

Bearer token​

The token is sent as Authorization: Bearer <token>, up to 4,096 characters. It is encrypted at rest and kept with the run so that Rerun can reuse it. It never appears in the transcript or in logs.

Custom headers​

Enter one header per line as Name: value, for example X-API-Key: …. Limits: up to 20 headers, 4 KB per value and 16 KB in total. Values are encrypted at rest and kept for reruns, and the run shows only the header names ("Supplied headers").

Hooklistener manages some headers itself, and they can't be set here: Accept, Authorization (use Bearer token), Connection, Content-Length, Content-Type, Host, MCP-Protocol-Version, Mcp-Session-Id, Proxy-Authorization, TE, Trailer, Traceparent, Tracestate, Transfer-Encoding and Upgrade.

OAuth 2.1​

With OAuth 2.1 (recommended), Hooklistener discovers your server's OAuth configuration, then asks you to approve access in your browser. It uses the authorization code flow with PKCE and requests a token only for your MCP server.

When you submit the form:

  1. Challenge. Hooklistener sends initialize without credentials and reads the WWW-Authenticate challenge: its resource_metadata URL and scope.

  2. Protected resource metadata (RFC 9728) comes from the challenge's URL, or from /.well-known/oauth-protected-resource. Its resource must be HTTPS, on the server's origin, with a path matching the endpoint. If the server accepted initialize without credentials and publishes no metadata, the run fails and tells you to run it without OAuth.

  3. Authorization server metadata comes from RFC 8414 or OpenID Connect discovery. Hooklistener checks that:

    • the issuer matches exactly;
    • the authorization and token endpoints use HTTPS;
    • PKCE with S256 is supported;
    • if the endpoints are on another origin than the issuer, the server supports the iss authorization response parameter.
  4. Client registration, in this order of preference:

    • the Pre-registered client ID (and optional Client secret) from Advanced client settings;
    • Hooklistener's Client ID Metadata Document, if the server supports them;
    • Dynamic Client Registration (RFC 7591), if the server has a registration endpoint.

    If none is possible, the run fails: "The authorization server requires a pre-registered OAuth client ID".

  5. Scopes. Hooklistener requests the Requested scopes you entered, or else the challenge's scope, or else the resource's scopes_supported.

Then a confirmation page, Continue to <host>, lists the MCP endpoint, the OAuth issuer, the authorization and token hosts, and the requested scopes. Check those hosts, then click Continue with OAuth. The authorization server opens in the same tab. Sign in and approve. Hooklistener exchanges the code, sending the PKCE verifier and the resource indicator (RFC 8707), and queues the run: "OAuth connected. Diagnostic queued."

Approve within 10 minutes, or the authorization expires; use Rerun to start it again. Only the member who started the authorization can finish it. If you leave the confirmation page, the run shows OAuth required with a Continue OAuth button.

Registering Hooklistener with your authorization server​

If your authorization server needs Hooklistener registered ahead of time, use these values:

Value
Redirect URIhttps://app.hooklistener.com/realtime/mcp/oauth/callback
Client ID Metadata Documenthttps://app.hooklistener.com/realtime/mcp/oauth/client-metadata.json
Client nameHooklistener MCP Diagnostics
Grant typesauthorization_code, refresh_token
Token endpoint authenticationnone (public client), unless you give Hooklistener a client secret

These URLs keep their /realtime/mcp/oauth path, from before MCP diagnostics moved out of Real-time, because authorization servers already know them.

What is stored​

A successful approval creates an OAuth connection that belongs to the organization:

  • Encrypted at rest: the access token, the refresh token and the client secret.
  • Stored in plain text: the issuer, the endpoints, the client ID, the granted scope and the expiry.
  • Dropped once the code is exchanged: the PKCE verifier and state.

How connections are used:

  • Rerun reuses the connection. Before each run, a token that expires within 60 seconds is refreshed.
  • If the server answers 401 or 403 during a run, Hooklistener refreshes once and runs the diagnostic again.
  • If the refresh is refused, the connection shows Needs reauth, and the next Rerun asks you to approve again.
  • Each new OAuth diagnostic you start from the form creates its own connection.

The OAuth connections list on the MCP diagnostics page shows each connection's status: Active, Needs reauth, Failed or Pending. Disconnect revokes the stored tokens at the server's revocation endpoint (RFC 7009), if it has one, then deletes the connection. Runs that used it can't be rerun afterwards: Rerun answers "The OAuth connection is no longer available. Configure a new diagnostic.", and a run still queued for it stops with the same error. Start a new diagnostic to connect again.

Runs​

Statuses​

StatusMeaning
OAuth requiredWaiting for you to approve access. Use Continue OAuth.
QueuedWaiting for a worker
RunningIn progress. The page updates as each step is recorded.
PassedEvery check passed or was skipped
WarningAt least one check warned and none failed
FailedAt least one check failed. This is a problem with your server.
CancelledYou cancelled the run
Internal errorHooklistener couldn't complete the run

A run can also end with the banner The diagnostic could not complete, plus an error code. That means the run itself couldn't finish, not that your server failed a check. The causes are an OAuth setup or callback failure, an expired authorization, a worker timeout, or no worker picking the run up. Rerun to try again.

Actions​

  • Cancel: stops a run that is waiting for OAuth, queued or running.
  • Rerun: starts a new run with the same URL and stored credentials. It offers the latest protocol version again. When OAuth setup failed, the button is Configure new instead.
  • Export: downloads the receipt of a finished run.
  • Delete: removes a finished run and its transcript.

Transcript​

The Transcript shows each step in order:

  • every request (OUT), with its headers and JSON-RPC message;
  • every response (IN), with its HTTP status, duration, headers and decoded JSON-RPC messages;
  • system events (SYS), such as transport errors or a cancellation.

OAuth discovery appears only as summary events. The individual metadata, registration and token requests are not recorded.

Credentials are redacted before anything is stored:

  • Credential-like headers and JSON fields become [REDACTED]: Authorization, Cookie and Set-Cookie, Mcp-Session-Id, API keys, passwords, secrets and tokens.
  • The exact values of your bearer token, custom headers and OAuth tokens are replaced wherever they appear, even in other fields.

A transcript holds up to 200 events. Strings over 32 KB are cut, and an event over 256 KB keeps only its summary.

Receipt export​

Export downloads mcp-diagnostic-<run id>.json, built from the redacted data:

{
"format": "hooklistener.mcp_diagnostic",
"version": 1,
"exported_at": "2026-10-13T09:12:44Z",
"run": {
"target_url": "https://api.example.com/mcp",
"auth_type": "oauth",
"status": "completed",
"result_status": "passed",
"requested_protocol_version": "2025-11-25",
"negotiated_protocol_version": "2025-06-18",
"server_info": { "name": "example-mcp", "version": "1.4.0" },
"capabilities": { "tools": {} },
"checks": [ … ],
"discovery": { … }
},
"transcript": [ … ]
}

The run also includes its id, the names of the custom headers, any error code and message, and its timestamps. Each transcript event has its sequence number, phase, direction, method, JSON-RPC id, HTTP status, duration, headers, payload and time. Only signed-in members of the organization can download a receipt. There is no public link: share the file itself.

Limits​

LimitValue
Runs per hour, per organizationFree: 10. Pro, Production and Scale: 60.
Connect timeout5 seconds
Request timeout20 seconds per request
Run timeout45 seconds for the whole run
Response size1 MB per response
Discovery10 pages and 500 items per list
Redirects3, same origin only
URL2,048 characters
Bearer token4,096 characters
Custom headers20 headers, 4 KB per value, 16 KB in total

Every run created in the last hour counts toward the hourly limit, including reruns and failed or cancelled runs. When the limit is reached, the page shows Hourly run limit reached and Run diagnostic is disabled until older runs leave the one-hour window.

Retention​

  • Finished runs and their transcripts are kept for 30 days, then deleted. A run's stored bearer token and custom headers are deleted with it.
  • An OAuth connection that no run uses any more is revoked and deleted 30 days after its last update.
  • Deleting a run deletes its transcript, but not the OAuth connection. Use Disconnect for that.