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

# heymcp probe

> Run the handshake and checks against a local server. No public URL.

```bash theme={null}
heymcp probe <target>
```

Everything the [handshake probe](/concepts/the-probe) does, straight against
your local server. No tunnel is opened, nothing is published, and no session is
recorded.

```bash theme={null}
heymcp probe localhost:8000
```

```
!  handshake ok — 3 tools, 1 thing worth fixing
!  Times might arrive in the wrong format  schema/no-format
   `place_order.collection_time` has no format constraint — clients often send
   things like "7pm". Add `"format": "date-time"` and an example like
   `2026-08-15T19:00:00Z`.
```

Each finding is a glyph, its plain-English headline, and the rule id — then the
detail, naming the exact parameter and the exact change to make. Every finding
also carries a link to its entry in the [checks reference](/lint).

The summary line varies with the verdict:

| Verdict              | Summary line                                             |
| -------------------- | -------------------------------------------------------- |
| Clean                | `✓  handshake ok — 3 tools`                              |
| Warnings only        | `!  handshake ok — 3 tools, 2 things worth fixing`       |
| Something will break | `✗  handshake has problems — 2 things worth fixing`      |
| Couldn't connect     | `✗  couldn't reach your MCP server — connection refused` |

## Options

<ParamField path="--path <PATH>" default="/mcp">
  The MCP route on the local server, if it is not `/mcp`.

  Unlike [`share`](/cli/share), there's no path policy involved here — the probe
  goes straight to the address you name, so `--path` works alone.
</ParamField>

## In CI

This is the main reason `probe` exists separately from `share`. The
[exit codes](/cli/overview#exit-codes) make it a gate:

| Code | Meaning                                                     |
| ---- | ----------------------------------------------------------- |
| `0`  | Clean.                                                      |
| `1`  | Warnings only.                                              |
| `2`  | Something will break, or the server was unreachable.        |
| `3`  | The command couldn't run — bad input, no token, no network. |

```yaml theme={null}
- name: Check the MCP server
  run: |
    npm start &
    npx wait-on http://localhost:8000/mcp
    heymcp probe localhost:8000
  env:
    HEYMCP_TOKEN: ${{ secrets.HEYMCP_TOKEN }}
```

To fail only on real breakage and let warnings through:

```bash theme={null}
heymcp probe localhost:8000 || [ $? -eq 1 ]
```

Add `--json` for a machine-readable report you can post to a PR.

## What it checks

The full handshake — `initialize`, `notifications/initialized`, `tools/list` —
then all eleven rules. See the [checks reference](/lint) for each one.

Worth knowing: `probe` talks directly to your local server, while the probe that
runs on `heymcp share` goes through the edge and hits the same routing and path
policy a real agent does. If `probe` is clean but the tunnel's handshake isn't,
the difference is in the tunnel configuration — usually the
[path policy](/concepts/urls-and-paths#what-is-shared).

## Common problems

<AccordionGroup>
  <Accordion title="Unreachable, but the server is definitely running">
    Check the path. If your MCP route isn't `/mcp`, pass `--path`.
  </Accordion>

  <Accordion title="transport/accept-sse, and you didn't expect it">
    Your server rejects `Accept: text/event-stream`. The probe names it and then
    retries without SSE, so you still get the rest of the report — but every
    real client asks for streaming, so this blocks all of them.
  </Accordion>

  <Accordion title="A protocol version warning against a server you know is fine">
    If your server is newer than your CLI, update the CLI —
    `curl -fsSL https://heymcp.dev/install.sh | sh`. The check knows a fixed
    list of revisions, and an out-of-date list produces a false alarm about
    somebody else's code.
  </Accordion>
</AccordionGroup>
