[GH-ISSUE #6452] [Bug] mcp doctor checks the wrong server when output flags precede doctor #3866

Closed
opened 2026-10-31 00:44:46 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6452

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI

Observed behavior

Moving --json before mcp or between mcp and doctor changes which MCP server the diagnostic checks. With an invalid production startup setting, mcp doctor --json returns healthy: false and exits 1. Both reordered forms instead return ok: true, a different 168-tool catalog, and exit 0. The explicitly advertised --format json option has the same behavior in either position.

Reproduction

From a fresh source checkout:

git checkout 9eb829aca34be36ff112826337996f6139f82eff
npm ci && npm run build:cached
WORK=$(mktemp -d)
mkdir -p "$WORK/home"
for ordering in canonical leading middle; do
  case "$ordering" in
    canonical) set -- mcp doctor --json ;;
    leading) set -- --json mcp doctor ;;
    middle) set -- mcp --json doctor ;;
  esac
  HOME="$WORK/home" REA_MCP_DOCTOR_DEADLINE_MS=0 \
    node scripts/rea.mjs "$@" > "$WORK/$ordering.json"
  status=$?
  printf '%s exit=%s\n' "$ordering" "$status"
  node -e 'const r=require(process.argv[1]); console.log({healthy:r.healthy,adapter:r.adapter,ok:r.ok,toolCount:r.toolCount,checks:r.checks})' "$WORK/$ordering.json"
done

The three CLI commands were each observed twice with identical status and report type. No binary fixture or external provider is needed. The dependency installation/build commands above prepare a fresh checkout; the observed runs used already installed locked dependencies and built artifacts.

Expected behavior

Output option placement should retain the production diagnostic, or an unsupported spelling should return a clear validation error. It should not successfully diagnose a different server.

The CLI guide identifies this command as the production startup check and states that output selection does not change operation status. Executed mcp --help lists --format under Global Options; executed mcp doctor --help lists both --format and --json. The ordinary argument splitter treats these output flags independently of position.

Impact and scope

P2: callers can receive a successful health check for the wrong server and lose the production report's fields. The observed failure is bounded, with a verified workaround: use mcp doctor --json in that order.

With the deadline override removed, one run of each ordering still produced different catalogs: the canonical command reported a healthy production server with 220 tools and six prompts; each reordered form reported 168 tools. No downstream automation failure was tested. The invalid deadline case demonstrates configuration refusal before production startup, rather than a failed server launch.

REA version

6.7.0 (source 9eb829aca3)

Runtime and platform

Node.js v26.12.1; macOS 27.0.1; arm64. No analysis provider was required.

Target and artifact context

Target-free MCP startup diagnostic with an isolated home directory. The only configuration fixture is REA_MCP_DOCTOR_DEADLINE_MS=0.

Interface

CLI

Earliest failure stage

Request parsing or validation

Relevant output or evidence

Selected fields from parsed stdout, obtained through the public executable:

mcp doctor --json       exit=1  healthy=false  adapter=production-stdio
--json mcp doctor       exit=0  ok=true        toolCount=168
mcp --json doctor       exit=0  ok=true        toolCount=168

The first report contains a failed check named REA_MCP_DOCTOR_DEADLINE_MS, explaining that the value must be a positive decimal integer. The other two contain tools, warnings and errors, with no healthy, adapter, inventory, identity or checks fields. All captured stderr was empty.

Each of --format json mcp doctor and mcp --format json doctor was also run once with the invalid setting; both exited 0 with ok: true and toolCount: 168.

Typed outcome or recovery expected

For the invalid setting, retain the production configuration failure and exit 1 in every accepted ordering. Preserve the canonical report contract and its healthy behavior with valid settings.

Analysis or suspected cause

Source-derived: the executable dispatcher recognizes production doctor only when the first two raw arguments are exactly mcp, doctor, before ordinary output-argument processing. Other orderings enter the general CLI, which enables Incur's MCP integration. The installed locked Incur implementation then runs its built-in doctor against the CLI-derived server. The production doctor would reject the invalid setting before starting a child.

Additional context

Related argument-sensitive dispatcher cases were observed once each using local target-free requests: bare mcp served 220 production tools, while --mcp --json served a four-tool discovery gateway; mcp --json printed group help and exited 0. These also pass through raw-argument production-mode selection.

Related issues #1127, #2673, #5435, #1454 and #5528 cover help, envelope preservation, whitespace, probe-schema validation and completion, respectively. None reports this doctor-selection behavior. NOT_ENOUGH_INFO: no last-known-good revision was established.

Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6452 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI ### Observed behavior Moving `--json` before `mcp` or between `mcp` and `doctor` changes which MCP server the diagnostic checks. With an invalid production startup setting, `mcp doctor --json` returns `healthy: false` and exits 1. Both reordered forms instead return `ok: true`, a different 168-tool catalog, and exit 0. The explicitly advertised `--format json` option has the same behavior in either position. ### Reproduction From a fresh source checkout: ```sh git checkout 9eb829aca34be36ff112826337996f6139f82eff npm ci && npm run build:cached WORK=$(mktemp -d) mkdir -p "$WORK/home" for ordering in canonical leading middle; do case "$ordering" in canonical) set -- mcp doctor --json ;; leading) set -- --json mcp doctor ;; middle) set -- mcp --json doctor ;; esac HOME="$WORK/home" REA_MCP_DOCTOR_DEADLINE_MS=0 \ node scripts/rea.mjs "$@" > "$WORK/$ordering.json" status=$? printf '%s exit=%s\n' "$ordering" "$status" node -e 'const r=require(process.argv[1]); console.log({healthy:r.healthy,adapter:r.adapter,ok:r.ok,toolCount:r.toolCount,checks:r.checks})' "$WORK/$ordering.json" done ``` The three CLI commands were each observed twice with identical status and report type. No binary fixture or external provider is needed. The dependency installation/build commands above prepare a fresh checkout; the observed runs used already installed locked dependencies and built artifacts. ### Expected behavior Output option placement should retain the production diagnostic, or an unsupported spelling should return a clear validation error. It should not successfully diagnose a different server. The [CLI guide](https://github.com/morluto/rea/blob/9eb829aca34be36ff112826337996f6139f82eff/docs/cli.md#L535) identifies this command as the production startup check and [states that output selection does not change operation status](https://github.com/morluto/rea/blob/9eb829aca34be36ff112826337996f6139f82eff/docs/cli.md#L543). Executed `mcp --help` lists `--format` under Global Options; executed `mcp doctor --help` lists both `--format` and `--json`. The [ordinary argument splitter](https://github.com/morluto/rea/blob/9eb829aca34be36ff112826337996f6139f82eff/src/cliOutput.ts#L24) treats these output flags independently of position. ### Impact and scope P2: callers can receive a successful health check for the wrong server and lose the production report's fields. The observed failure is bounded, with a verified workaround: use `mcp doctor --json` in that order. With the deadline override removed, one run of each ordering still produced different catalogs: the canonical command reported a healthy production server with 220 tools and six prompts; each reordered form reported 168 tools. No downstream automation failure was tested. The invalid deadline case demonstrates configuration refusal before production startup, rather than a failed server launch. ### REA version 6.7.0 (source 9eb829aca34be36ff112826337996f6139f82eff) ### Runtime and platform Node.js v26.12.1; macOS 27.0.1; arm64. No analysis provider was required. ### Target and artifact context Target-free MCP startup diagnostic with an isolated home directory. The only configuration fixture is `REA_MCP_DOCTOR_DEADLINE_MS=0`. ### Interface CLI ### Earliest failure stage Request parsing or validation ### Relevant output or evidence Selected fields from parsed stdout, obtained through the public executable: ```text mcp doctor --json exit=1 healthy=false adapter=production-stdio --json mcp doctor exit=0 ok=true toolCount=168 mcp --json doctor exit=0 ok=true toolCount=168 ``` The first report contains a failed check named `REA_MCP_DOCTOR_DEADLINE_MS`, explaining that the value must be a positive decimal integer. The other two contain `tools`, `warnings` and `errors`, with no `healthy`, `adapter`, `inventory`, `identity` or `checks` fields. All captured stderr was empty. Each of `--format json mcp doctor` and `mcp --format json doctor` was also run once with the invalid setting; both exited 0 with `ok: true` and `toolCount: 168`. ### Typed outcome or recovery expected For the invalid setting, retain the production configuration failure and exit 1 in every accepted ordering. Preserve the canonical report contract and its healthy behavior with valid settings. ### Analysis or suspected cause Source-derived: the [executable dispatcher](https://github.com/morluto/rea/blob/9eb829aca34be36ff112826337996f6139f82eff/scripts/rea.mjs#L15) recognizes production doctor only when the first two raw arguments are exactly `mcp`, `doctor`, before ordinary output-argument processing. Other orderings enter the general CLI, which [enables Incur's MCP integration](https://github.com/morluto/rea/blob/9eb829aca34be36ff112826337996f6139f82eff/src/cli.ts#L105). The installed locked Incur implementation then runs its built-in doctor against the CLI-derived server. The [production doctor](https://github.com/morluto/rea/blob/9eb829aca34be36ff112826337996f6139f82eff/src/mcpDoctor.ts#L90) would reject the invalid setting before starting a child. ### Additional context Related argument-sensitive dispatcher cases were observed once each using local target-free requests: bare `mcp` served 220 production tools, while `--mcp --json` served a four-tool discovery gateway; `mcp --json` printed group help and exited 0. These also pass through raw-argument production-mode selection. Related issues #1127, #2673, #5435, #1454 and #5528 cover help, envelope preservation, whitespace, probe-schema validation and completion, respectively. None reports this doctor-selection behavior. NOT_ENOUGH_INFO: no last-known-good revision was established.
Author
Owner

@coygeek commented on GitHub (Oct 24, 2026):

Verified resolved on main at d87e73f2db.

I rebuilt that revision with its pinned Node 24.22.1 and npm 11.16.0, then replayed the invalid-deadline reproduction in an isolated home. All five forms (mcp doctor --json, --json mcp doctor, mcp --json doctor, --format json mcp doctor, and mcp --format json doctor) now exit 1 with healthy: false, adapter: "production-stdio", and the same REA_MCP_DOCTOR_DEADLINE_MS validation check. None switches to the Incur doctor.

The dispatcher now uses the shared argument owner, and the regression covers output-option placement. Closing as completed on main; this verification does not establish publication in an npm release.

<!-- gh-comment-id:6380592583 --> @coygeek commented on GitHub (Oct 24, 2026): Verified resolved on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. I rebuilt that revision with its pinned Node 24.22.1 and npm 11.16.0, then replayed the invalid-deadline reproduction in an isolated home. All five forms (`mcp doctor --json`, `--json mcp doctor`, `mcp --json doctor`, `--format json mcp doctor`, and `mcp --format json doctor`) now exit 1 with `healthy: false`, `adapter: "production-stdio"`, and the same `REA_MCP_DOCTOR_DEADLINE_MS` validation check. None switches to the Incur doctor. The [dispatcher now uses the shared argument owner](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/scripts/rea.mjs#L22-L34), and [the regression covers output-option placement](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/boundary/cli/dispatcher.test.ts#L243-L255). Closing as completed on main; this verification does not establish publication in an npm release.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3866
No description provided.