Skip to content

feat: every agent runtime gets the work's MCP servers in the file it reads - #664

Merged
jonwiggins merged 2 commits into
mainfrom
feat/harness-mcp-config
Oct 10, 2026
Merged

jonwiggins merged 2 commits into
mainfrom
feat/harness-mcp-config

Conversation

@jonwiggins

Copy link
Copy Markdown
Owner

What

Connections' tools and MCP servers reached only Claude Code (.mcp.json) and Codex (config.toml). A Job on Gemini, a persistent agent on Copilot, or a Task on OpenCode or Cursor got the connections' credentials and notes but no tools. Each runtime now gets the same servers in the file it reads, established from the versions the agent image installs by reading their installed code and docs (sources in utils/harness-config.ts):

Runtime File Pointed at it by
Codex 0.160 <run home>/codex/config.toml ([mcp_servers.*]) CODEX_HOME (as before, now under the run home)
Gemini CLI 0.62 <run home>/gemini/.gemini/settings.json — the adapter's settings + mcpServers, each trust: true GEMINI_CLI_HOME
OpenCode 1.14 <run home>/opencode/opencode.json — mcp: { name: { type: "local", command: [cmd, ...args], environment } } OPENCODE_CONFIG (merged after the global, before the project file)
GitHub Copilot CLI 1.0.20 <run home>/copilot/mcp-config.json — type: "local", tools: ["*"] --additional-mcp-config @<file>
Cursor CLI 2026.10 .cursor/mcp.json in the working directory, merged into the repo's own --approve-mcps

OpenClaw manages MCP servers through its own openclaw mcp config (mcp.servers); its entry schema and the launch Optio uses were not verified, so it is left out.

The run home

Per-run files live in /home/agent/optio/runs/<run id> (OPTIO_RUN_HOME), named after the task, Job run, or agent turn — a retry lands in the same place — and removed when the run's script exits (an EXIT trap in both exec scripts) and again with the task's worktree (repo-pool-service, repo-cleanup-worker). Codex's per-run home moves there too; it used to be a random directory that was never removed from the repo pod's home volume.

Writer

WRITE_SETUP_FILES merges a merge: "json" file into the JSON object already at its path (a repo's own .cursor/mcp.json) and marks a tracked file it wrote over skip-worktree, so an agent's git add -A can never commit Optio's servers and their credentials. The image entrypoint maps /opt/optio/… into the agent's home like the exec scripts do. Connections can no longer set GEMINI_CLI_HOME, OPENCODE_CONFIG*, COPILOT_HOME, CURSOR_CONFIG_DIR.

Tests

  • Unit: renderers, run home naming, launch lines, the cleanup trap (run in bash), the writer's merge + skip-worktree (real git), both command builders.
  • Integration: agent-environment-service.int.test.ts — each runtime's file and env from the real service; sensitive only when a server carries credentials; the untrusted pod's copy has none.
  • Pipeline e2e: harness-mcp.e2e.test.ts — a Cursor Job with a Pylon connection: .cursor/mcp.json content, --approve-mcps, the cleanup line in the script (new fake directives [[mock:file:*suffix]], [[mock:script:TEXT]]).
  • All tiers green: format, typecheck, unit (all packages), integration (one unrelated flaky local-run test passes alone), e2e (22 files).

Live

Rebuilt + redeployed the API on the local cluster. An OpenCode Job with an HTTP API connection pointed at a mock OpenAI server (host.docker.internal:4999): the model's tool list carried Probe_API_describe / Probe_API_request from the per-run opencode.json, the model called Probe_API_request, the REST bridge reached the mock with the connection's Bearer token, and the result came back in the run's logs. After the run, /home/agent/optio/runs/ on the Job pod was empty.

…reads

Gemini CLI, OpenCode, GitHub Copilot CLI and Cursor runs had their
connections' credentials and notes but no tools, since only Claude Code
reads .mcp.json. Each now gets the same servers in its own file and shape,
established from the versions the agent image installs: Gemini's user
settings.json in a GEMINI_CLI_HOME of the run's own, an OPENCODE_CONFIG
file, Copilot's --additional-mcp-config @<file>, and Cursor's project
.cursor/mcp.json with --approve-mcps.

The per-run files live in one run home, /home/agent/optio/runs/<run id>,
named after the task, Job run or agent turn and removed when the run's
script exits and with the task's worktree; Codex's per-run CODEX_HOME moves
there too (it was a random, never-removed directory). The setup-file writer
merges a runtime's project config into the repo's own file and marks a
tracked file it wrote over skip-worktree, so Optio's servers and their
credentials can never be committed.
@jonwiggins
jonwiggins merged commit 3383e44 into main Oct 10, 2026
13 checks passed
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