fix(jail): expose the claude MCP config dir inside the fs-jail - #155
Merged
Conversation
A jailed claude lead with MCP servers died at spawn. The bridge writes mcp-config.json to a host /tmp directory, the fs-jail mounts a fresh tmpfs over /tmp, and the confined claude cannot see the --mcp-config path. The measured failure on discovery-lab run strong-lead-smoke-b is 'claude exited 1: Invalid MCP configuration: MCP config file not found: /tmp/cli-bridge-mcp-5F5zD4/mcp-config.json'. kimi and opencode already register their materialized config dirs through registerJailReadable, and pi writes its MCP config inside the workspace. claude was the only backend that skipped the registration. Register the config dir so the jail re-binds it read-only after the tmpfs. Tests prove a jailed claude spawn registers its --mcp-config dir as jail-readable, and a jailed codex spawn carries its MCP stanzas in the seeded writable CODEX_HOME. Verified end to end on a local fs-jailed bridge: the exact failing request now completes with the profile receipt attached.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
discovery-lab run
strong-lead-smoke-bdied with:The bridge materializes the runtime's coordination MCP servers into
mcp-config.jsonunder the host/tmp(writeMcpConfigFile,src/backends/profile-support.ts), and passes--mcp-config <path> --strict-mcp-configto claude. The fs-jail mounts a fresh tmpfs over/tmp, so the confined claude cannot see the file and exits 1 before doing any work.The jail architecture already has the mechanism for exactly this:
registerJailReadablere-binds a host config dir read-only AFTER the tmpfs. kimi (src/backends/kimi.ts:145) and opencode (src/backends/opencode.ts:113) call it for their materialized configs, and pi avoids the problem entirely by writing its MCP config inside the workspace (.cli-bridge-pi-mcp-under cwd) — that is why pi leads work daily. claude was the only MCP-consuming backend that never registered its config dir. Codex is covered separately: its MCP stanzas live in the syntheticCODEX_HOME, which #154 seeds writable into the jail.Fix
One registration in
src/backends/claude.ts, the exact kimi/opencode idiom:Proof
WORKER_FS_JAIL=1) from unfixed main with the runtime's request shape (profilemcp: { coordination: { command: ... } }):claude exited 1: Error: Invalid MCP configuration: MCP config file not found: /tmp/cli-bridge-mcp-5F0Cjz/mcp-config.json— same failure as smoke-b, and (per fix(jail): seed writable codex/claude homes and acknowledge receipts on failed turns #154) the profile receipt now rides the error so the runtime reports it verbatim instead of a masked transport fault."pong"and the receipt attached.--mcp-configdir injailSpec.extraReadablePaths(tests/docker-executor.test.ts); a jailed codex spawn carries its[mcp_servers.*]stanzas in the seed-writable syntheticCODEX_HOME(tests/codex-backend.test.ts).pnpm buildclean;pnpm test: 804 passed, 8 skipped, 44 files.No serving-bridge restart performed — deploy-ready.
🤖 Generated with Claude Code