Skip to content

fix(mcp): preserve unindented examples in Codex TOML - #1651

Merged
SaulMoro merged 1 commit into
Tencent:mainfrom
ydflow:fix/codex-mcp-multiline
Nov 1, 2026
Merged

SaulMoro merged 1 commit into
Tencent:mainfrom
ydflow:fix/codex-mcp-multiline

Conversation

@ydflow

@ydflow ydflow commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Summary

An unindented table example inside a Codex TOML multiline string is mistaken for a real table. For example, mcp inject can replace [mcp_servers.team-mcp] inside developer_instructions, destroying the closing quotes and the member's instructions. A table-like line inside a server value can also truncate the block when it is removed.

Check the TOML prefix before recognizing unindented headers too, using the same guard introduced for indented headers in #1626. Keep the original text for splicing.

Test plan

  • npm run typecheck and npm run lint passed.
  • Codex-focused MCP tests: 46 passed (npx vitest run src/__tests__/mcp-reconcile.test.ts src/__tests__/local-agent-mcp.test.ts -t '^(?!.*symlinked Codex project config)(?!.*allows retrying uninstall of codex user after a manifest write fails)(?!.*keeps Codex config and ownership when .* cannot read the config).*(Codex|codex|spliceCodexBlock)' --maxWorkers=2 --reporter=dot --silent).
  • Real CLI: npm run test:e2e -- src/__tests__/e2e/mcp-command-errors.test.ts --maxWorkers=1 --reporter=dot built the CLI and passed all 13 tests on Windows. It injects, updates and removes a server while preserving both indented and unindented examples in member instructions.
  • Full unit run (npx vitest run --maxWorkers=4 --reporter=dot --silent --bail=1) stopped after 85 passed and 12 skipped at workflow-workspace.test.ts's dirty-file mode test; the same test fails on the unchanged base 9f9f36b4 on this machine. The full MCP test file also stopped on Windows EPERM creating a symlink after 44 passed and 7 skipped; symlink privileges are unavailable here.

Related

#1626 explicitly left unindented multiline examples as a separate case. Dotted-key MCP declarations remain outside this change.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

No confident findings in the specified PR diff.

The testing record satisfies the review criteria: it documents typecheck, lint, focused unit tests, and a built real-CLI E2E run covering inject, update, and removal. The reported Windows limitations and unchanged-base failure are not blocking findings.

Review was read-only; I did not run, build, or install anything from the PR.

@SaulMoro SaulMoro left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This was generated by AI during triage.

Approving at 42a6ef4f. Header-like lines are now masked whether or not they are indented, using the same complete-prefix check #1626 added, so an unindented [mcp_servers.…] inside a multiline value is no longer taken for a table.

Built and run from source, base 9f9f36b4 vs this head, isolated home and Codex home:

"""/''' example with an unindented [mcp_servers.team-mcp], fresh config
  base: inject/update/remove exit 0, team server skipped each time
  head: added / updated / removed; after remove the file equals the original
example above a managed block
  base: update exit 0 but leaves the string unterminated (codex mcp list: failed to load configuration); remove exit 1
  head: update keeps the example; remove leaves the file equal to the original
managed server value holding a [projects.example] line, team drops the server
  base: removed, config left invalid
  head: removed, valid TOML
codex mcp list (codex-cli 0.165.0) on the head configs: lists team-mcp

The masking agrees with a TOML parser on escaped quotes, ''' holding """, """" closings, comments with quotes and CRLF.

  • [P3 nit] The prefix parse now runs for every [-led line; injecting 5 servers into a 2,000-line config went from 0.18 s to 0.39 s.

@SaulMoro
SaulMoro merged commit 3e8896a into Tencent:main Nov 1, 2026
18 checks passed
Walternater pushed a commit to Walternater/teamai-cli that referenced this pull request Nov 2, 2026
An unindented table example inside a Codex TOML multiline string (for example in `developer_instructions`) is no longer taken for a real table: `mcp inject` no longer skips or overwrites the server, and update and remove keep the member's text. A table-like line inside a managed server's value no longer leaves the config invalid when the server is removed. Header-like lines are masked with the complete-prefix check from Tencent#1626, indented or not.
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.

3 participants