000

  • Home
  • Work
  • Skills
  • Contact

Let's work together

What's New
mcp-health
A CLI that checks MCP configs before they break.
Read the case study
  • LinkedIn
  • GitHub
  • WhatsApp
  • Email
← Back to work

08.08.2026 · 5 min read

Stop guessing why your MCP setup broke

mcp-health is a CLI and GitHub Action I publish and maintain. It checks MCP configs for Cursor, VS Code, Claude Code, Claude Desktop, Gemini CLI, Copilot, Continue, Junie, Cline, Windsurf, Zed, and Codex before those tools try to start a server.

TYPESCRIPTCLIMCPCI
github.com
Repository ↗
Terminal demo of mcp-health check failing on a broken config, then passing on a healthy one
Repository ↗

The problem

Most MCP configs start life as a paste from someone's README. Then a binary isn't on PATH, an env still says YOUR_API_KEY, or npx pulls a different package version than last week. The agent fails with a vague error, and you spend half an hour chasing it. I wanted a check I could run locally or in CI, without spinning up another dashboard.

What I built

So I built mcp-health, and I still maintain it. v1.4.0 is on npm as @leon-pixel/mcp-health. The same scan is the mcp-health-doctor action on GitHub Marketplace. It finds the config files those tools already use, walks each server entry, and reports ok, warn, or fail. Disabled servers are skipped.

Exit codes stay simple: 0 means ok, 1 means warnings only, and 2 means something failed. JSON and SARIF 2.1.0 are there when a pull request needs annotations.

What it checks

The default scan stays on disk. Ask for --online or --probe when you want more.

  • Config shape for Cursor, VS Code, Claude Code, Claude Desktop, Gemini CLI, Copilot, Continue, Junie, Cline, Windsurf, Zed, and Codex, including JSONC and Continue YAML. User-level Gemini, VS Code, and Copilot configs are included unless you pass --no-user.
  • Commands on PATH.
  • Version pinning, and npm drift when you pass --online.
  • VS Code and Cursor variables, including ${workspaceFolder}, expanded before the result is decided.
  • Disabled servers, reported and then skipped.
  • An optional live probe: a stdio or HTTP/SSE handshake, JSON-RPC ids that match, tools/list to catch a server that exposes no tools, and a 401 with an OAuth challenge treated as a warning.
  • JSON output, and SARIF 2.1.0 with GitHub pull request annotations.

How it got better

The first cut gave false results. It left ${workspaceFolder} unexpanded, waited on probes for servers that had already crashed, ignored headers, and compared semver as strings. An independent review caught them. I shipped the fixes across 1.1, 1.2, and 1.2.1, with a test for each.

1.3.0 extends discovery to Continue, Junie, and Cline, and reads Claude Code from ~/.claude.json, including the entry for the scan root. --no-user skips those user-level files.

1.4.0 discovers Gemini CLI settings, the VS Code user mcp.json, and Copilot's user mcp-config.json. It warns when uvx, bunx, pnpm dlx, pnpm exec, or yarn dlx launches an unpinned package. I tightened Claude project-path matching so the same directory still matches, including a symlink and macOS /tmp versus /private/tmp. A relative stdio command resolves from the scan root, and SARIF and GitHub annotation paths stay relative to the workspace when the scan root sits inside it. A scan with no MCP config still exits 1, with a clearer NO_CONFIG hint and --allow-missing when that is intentional. Human-readable rows now say project or user. JSON keeps the file path and adds scope.

There are 48 Vitest tests. CI runs on every pull request. A tag-driven release publishes to npm with signed provenance and moves the v1 tag. Node 22.12 or newer.

Signals

v1.4.0
On npm + GitHub Marketplace
Local first
Add --online or --probe when needed

Try it

  1. From the project you're in, run the published package with npx.
  2. In GitHub Actions, use the Marketplace action. The v1 tag moves when a stable release ships.

1. Terminal

Terminal
BASH
1npx @leon-pixel/mcp-health check

2. GitHub Action

GitHub Action
YAML
1- uses: actions/checkout@v52- uses: leon-pixel/mcp-health@v13  with:4    path: .5    args: --no-user

Note

The default scan stays offline. Only use --probe on configs you trust, since it briefly starts local server processes.

What it doesn't do

  • It won't rewrite your config or host a dashboard. That's intentional.
  • Don't run --probe against configs you don't trust.
  • Your IDE PATH might differ from the terminal, so run the check in the same place your agents run.

Links

Repository · npm · GitHub Marketplace

On this page

  • Preview
  • The problem
  • What I built
  • What it checks
  • How it got better
  • Signals
  • Try it
    • Terminal
    • GitHub Action
  • What it doesn't do
  • Links