Skip to content

feat(health): add mcporter health for at-a-glance server status#176

Open
mvanhorn wants to merge 1 commit into
openclaw:mainfrom
mvanhorn:feat/mcporter-health
Open

feat(health): add mcporter health for at-a-glance server status#176
mvanhorn wants to merge 1 commit into
openclaw:mainfrom
mvanhorn:feat/mcporter-health

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

Summary

  • Adds mcporter health. Pings every configured MCP server in parallel (via Promise.allSettled), reports per-server status, initialize latency, tool count, and OAuth token state in one table. Exits non-zero when any server is not ok, so it works as a CI/uptime monitor.
  • Flags: --server <name> to check one, --timeout <seconds> per-server (default 10), --json for machine-readable output.
  • Classification handles the common failure modes:
    • auth_required for 401 / forbidden / token errors
    • unreachable for ECONNREFUSED / ETIMEDOUT / ENOTFOUND
    • error for anything else (with a 200-char preview from the error message)
    • ok with measured latency and tool count when healthy
  • Subcommand follows the existing list-command.ts / daemon-command.ts pattern: commander registration, reuses output-utils.ts / json-output.ts / terminal.ts for formatting. No new runtime deps.

Why this matters

mcporter list shows the servers configured for the current workspace and their tool counts, but not whether those servers are actually reachable or whether their cached OAuth tokens are still valid. At 10+ MCPs configured — the audience that exists at 4.4K stars — there is no way to check "is everything ok before I start a run" short of calling each tool manually.

This is operational quality-of-life that compounds at scale:

mcporter health                         # check all configured servers
mcporter health --server linear         # check one
mcporter health --json                  # CI / uptime monitor friendly
mcporter health --timeout 5             # tighter per-server budget

Parallel execution means one slow or dead server does not block the others.

Demo

Simulated demo:

mcporter health demo

The demo shows a 5-server config: 3 healthy (linear / context7 / vercel with latency + tool counts + OAuth state), 1 with an expired token (supabase → auth_required), 1 unreachable (internal-api on ECONNREFUSED). Exit code 1 because not everything is ok.

Testing

  • corepack pnpm typecheck
  • corepack pnpm lint (oxlint clean, oxfmt clean)
  • corepack pnpm test — 648 tests pass; new tests/cli-health-command.test.ts covers:
    • all-servers-reachable path returns 0, table has one row per server
    • one server returning 401 → row classified as auth_required, exit code 1
    • timeout → row classified as unreachable with error preview
    • --json produces a valid JSON array conforming to the HealthRow shape
    • --server <name> filter checks only the named server
    • --timeout 1 enforces per-server timeout via stubbed slow transport

mcporter health pings every configured MCP server (in parallel via
Promise.allSettled) and reports per-server status, initialize latency,
tool count, and OAuth token state in one table. Exits non-zero when
any server is not ok, so it works as a CI/uptime monitor.

Flags:
- --server <name>: check only this server
- --timeout <seconds>: per-server timeout (default 10)
- --json: machine-readable JSON output

Classification handles common failure modes:
- auth_required for 401/forbidden/token errors
- unreachable for ECONNREFUSED/ETIMEDOUT/ENOTFOUND
- error for anything else
- ok with latency and tool count when healthy
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 941097ca59

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/cli/health-command.ts

export async function handleHealth(runtime: Runtime, args: string[]): Promise<void> {
const flags = parseHealthFlags(args);
const previousStdioLogMode = flags.server ? undefined : setStdioLogMode('silent');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Silence stdio logs for single-server JSON/quiet health checks

When mcporter health --server <stdio-server> --json or --quiet checks a stdio server that writes stderr before failing, this leaves stdio log mode at auto, so sdk-patches can print the captured stderr to stdout during the runtime.listTools(..., autoAuthorize: false) close path. That pollutes the JSON payload and also violates --quiet; the all-server path already silences these logs, so the single-server path should do the same at least for JSON/quiet output.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant