Skip to content

fix(cli): wrap a commented config, and rewrite only the entries wrapped - #160

Open
Cedric921 wants to merge 1 commit into
Memnox:mainfrom
Cedric921:fix/wrap-a-config-without-rewriting-it
Open

Cedric921 wants to merge 1 commit into
Memnox:mainfrom
Cedric921:fix/wrap-a-config-without-rewriting-it

Conversation

@Cedric921

Copy link
Copy Markdown
Contributor

Closes #84.

What this changes

server-configs.ts read with JSON.parse and wrote with JSON.stringify(next, null, 2). Two consequences:

  • A config with one comment was never governed. VS Code and Cline write JSONC. JSON.parse threw on the first //, the file was skipped, and its servers stayed off the proxy — no message beyond them not appearing in the list. That is the worse half: it is a reach mcp wrap claims to cover and silently does not.
  • Every line changed. A four-space file came back at two spaces, so the diff a person reviews after mcp wrap touched the whole file.

Configs are now read with jsonc-parser (comments and trailing commas allowed; a file that still will not parse is left exactly alone), and written by span through a new mcp/json-span.ts, using the indentation helper agents/managed-json.ts already has. Only the wrapped entries' text changes.

The part span editing alone does not get right

I measured before writing this. jsonc-parser keeps comments and indentation, but an args array written inline — "args": ["-y", "gh-mcp"] — comes back on five lines after a wrap and an unwrap. So span edits by themselves do not meet "unwrap stays byte-identical".

unwrap deliberately rebuilds each entry from the wrapped one, not from the backup, so it survives --purge. That stays. On top of it: before writeRelaunches replaces the backup, it reads it, and where the backup still holds an entry whose value equals the one being restored — compared with canonicalJson, since key order is not part of the value — that entry's original text is spliced back in. Otherwise (after a purge, or if the entry changed) it falls back to the span edit, which is still correct and still touches only that entry's lines.

How it was verified

In mcp-command.test.ts, against two hand-written fixtures — one with comments, a trailing comma and an inline array, one in plain four-space JSON:

  • the commented file is wrapped and both comments survive
  • for each fixture, every line before the wrapped entry and every line after it is unchanged, and no line is indented at two spaces
  • for each fixture, wrap then unwrap returns the exact original bytes
  • a file that will not parse even as JSONC is left untouched

Four fail on main — including the plain-JSON reformatting and round trip, which main does parse and then rewrites. The existing round-trip test for a two-space file still passes.

prettier, tsc and knip clean. Full suite on Node 24: every failing file also fails on main here (the Noise pairing tests, which need the native addon; no Rust on this machine).

Checklist

  • pnpm format && pnpm typecheck && pnpm test && pnpm deadcode all pass (Noise tests aside)
  • Behaviour change ships with a test
  • No any, no magic values, no console.* outside cli-output.ts
  • If this touches the decision path: n/a — though more servers now reach the proxy that rules on them
  • If this changes a verb table: n/a
  • If this changes a command, flag or file it writes: mcp wrap now writes JSONC files it used to skip, and writes less of each file; the changeset names both

@Cedric921
Cedric921 requested a review from moise10r as a code owner October 16, 2026 03:38

This branch has not been deployed

No deployments
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.

mcp wrap: a config with comments is skipped, and every line of the file is reformatted

1 participant