Connect your editor
Construct syncs host adapters to Claude Code, OpenCode, Codex, Copilot, VS Code, and Cursor. Two scopes — global keeps only the `construct` front door; project writes the front door plus skills, hooks, and MCP wiring (Single Front Door — specialists dispatch internally).
construct sync keeps one canonical registry and writes the right host-specific shape for each supported tool. The CLI runs in two scopes:
- Global (
construct sync --global, or thenpm i -gpostinstall) installs the session-level hooks and aconstructfront door for Codex and Copilot. It does not write a global Claude agent: Claude Code and VS Code both read~/.claude/agents/, so a global agent there would show up twice (once from the project, once from home) in the VS Code picker — the orchestrator is project-scoped instead. Specialists never land at global scope either; they would pollute every editor picker on your machine regardless of the workspace. - Project (
construct syncinside a Construct project,construct init, ornpm run adaptersin the tool repo) writes theconstructfront door only in agent pickers, plus slash commands, skills (.claude/skills/), MCP configs, and Cursor rules. The 28cx-*specialists are internal — reached viaorchestration_policy/orchestration_run, not editor pickers. Adapter files are gitignored (ADR-0027); run sync after clone.
construct sync auto-detects a Construct project (presence of .cx/ or .construct/) and runs project mode when inside one; global mode otherwise. Pass --global or --project to force a tier.
What each host can actually do
Construct classifies every host honestly — no surface is cosmetic. construct hosts reports the same:
| Host | Capability | What that means |
|---|---|---|
| Claude Code | full-native | Runs the multi-specialist chain natively (Agent Teams / subagent dispatch). |
| OpenCode | full-native | Config-driven agents + subagents run the chain in OpenCode itself. |
| Codex · VS Code · Cursor · Copilot | mcp-orchestrated | No native subagent primitive, but the host calls the orchestration_run MCP tool to reach the same orchestrated outcome in-process. |
mcp-orchestrated hosts get genuine multi-specialist results — the engine owns orchestration, the editor is a thin client (see orchestrated outcomes in VS Code and ADR-0022). A host would only be prompt-only if it had neither native dispatch nor MCP — none of the supported hosts are.
EXECUTE vs PLAN: which hosts need a provider key
full-native and mcp-orchestrated both describe whether a host can reach the specialist chain — not whether that chain actually calls an LLM. construct init and construct doctor print the real verdict as their last line:
specialists will EXECUTE (provider <family> + key found)
specialists will only PLAN (fix: set orchestration.workerBackend=provider + a key)
EXECUTE requires the config-resolved orchestration.workerBackend to be "provider" and a materialized (not op://...) key present for the selected provider family. Anything else — the default inline backend, host with no attached session, or provider with no key — degrades to PLAN: Construct still prepares specialist prompts/tasks, but no LLM ever reasons over them.
- Claude Code and OpenCode (
full-native) run the specialist chain through the host's own attached session, so they EXECUTE with no provider key required — the host's own model does the reasoning. - Codex, Copilot, VS Code, Cursor (
mcp-orchestrated) have no attached subagent session to fall back on. They needorchestration.workerBackend: "provider"inconstruct.config.json, plus a materializedANTHROPIC_API_KEY,OPENROUTER_API_KEY, orOPENAI_API_KEYin the environment the MCP server runs in — without both,orchestration_runon these hosts only plans. - Even inside Claude Code or OpenCode, set
orchestration.workerBackend: "provider"(+ a key) if you want a specific provider model instead of the host's own.
Verify with construct doctor (reads the last line) or construct orchestrate preflight --json (full workerBackend/credentialMaterializable/modelResolved detail).
Claude Code
Global tier writes safety hooks and global instructions — but no agent file (the orchestrator is project-scoped, so it isn't duplicated in editors that read both scopes):
~/.claude/settings.json— machine-wide safety hooks only. Claude Code does not read MCP server definitions from settings.json at any scope (confirmed against code.claude.com/docs/en/mcp and code.claude.com/docs/en/managed-mcp).~/.claude.json— the low-riskcontext7documentation MCP, in its top-levelmcpServers(Claude Code's documented user scope). Workflow, memory, browser automation, GitHub, orchestration, and learning-loop hooks/MCPs are project-scoped.~/.claude/CLAUDE.md— a Construct-managed block appended to your global Claude instructions~/.claude/agents/— intentionally left without aconstruct.md(runconstruct initin a project to get@constructthere)
Project tier writes the front door + project-local Claude config:
<project>/.claude/agents/construct.md— orchestrator only (Single Front Door)<project>/.claude/settings.json— full project-portable hook suite (relative paths via.construct/launcher/run.mjs); hooks and permissions only, never MCP server definitions<project>/.mcp.json— project-scope MCP servers (Claude Code's documented project scope, meant to be checked into version control)<project>/.claude/commands/*.md— slash commands<project>/.claude/skills/<name>/SKILL.md— Anthropic Agent Skills
In Claude Code, address the persona with @construct. Internal specialists dispatch via MCP — not as separate @cx-* picker entries.
OpenCode
Global writes only the orchestrator agent into ~/.config/opencode/opencode.json (the existing provider auth, models, and unrelated agents are preserved on merge).
Project writes <project>/.opencode/opencode.json with the construct front door, optional construct-local for Ollama setups, providers, MCP servers, and the runtime plugin.
For substantive external research, first verify attachment with orchestration_readiness (or construct orchestrate preflight --json from the shell), then classify with orchestration_policy, then execute via orchestration_run. workflow_invoke remains the plan/contract preview surface, not the evidence-execution surface.
Codex (CLI)
Global writes ~/.codex/agents/construct.toml and registers it in ~/.codex/config.toml under [agents.construct], plus any Construct MCP entries in the managed block.
Project writes <project>/.codex/agents/construct.toml and updates the project's config.toml.
Copilot
Global writes only ~/.github/prompts/construct.prompt.md and a minimal Construct-managed block in ~/.github/copilot-instructions.md listing the front-door prompt.
Project writes construct.prompt.md under <project>/.github/prompts/ and a managed block in <project>/.github/copilot-instructions.md. Copilot agent mode reads <project>/.claude/agents/construct.md — the Single Front Door. Multi-specialist runs use the orchestration_run MCP tool.
VS Code
Construct writes <project>/.vscode/mcp.json (top-level servers) per the official VS Code MCP config format. Existing entries are preserved on merge; only Construct's own servers are added. Global sync merges into the canonical user-profile mcp.json (the file VS Code's "MCP: Open User Configuration" edits) only when it already exists — it never seeds a config in a VS Code that wasn't using MCP, mirroring the non-polluting Cursor/OpenCode global behavior. The deprecated settings.json → github.copilot.mcpServers key is no longer written (it polluted every window and predates VS Code's native MCP support).
Orchestrated outcomes in VS Code
VS Code/Copilot has no extension-facing subagent primitive, so the editor's own agent can't run a multi-specialist chain itself. Construct closes that gap the way Claude Code and OpenCode do — the engine runs the orchestration; the editor is a thin client. Reach it two ways:
- From the editor's chat, via MCP — the Construct MCP server exposes
orchestration_readinessto verify attachment,orchestration_runto execute a real run and return per-specialist output, andorchestration_statusto inspect runs. Solo runs execute in-process — no daemon, no port, no token. MCP tools are exactly what VS Code/Copilot and Cursor do expose, so the host gets a genuine multi-specialist outcome through a tool it can actually call — no subagent primitive required. - From a script/CI —
construct orchestrate run "<request>"runs in-process and stores runs in the current project's.construct/. For a shared team service, setCONSTRUCT_ORCHESTRATION_URL(andCONSTRUCT_ORCHESTRATION_TOKEN) and useconstruct orchestrate run --remote "<request>", which proxies the same call over HTTP.
A run executed with the provider worker backend (set orchestration.workerBackend and a provider key) returns real specialist output — the same outcome a Claude Code user gets. See architecture → engine-as-service and ADR-0022.
Cursor
Project writes <project>/.cursor/mcp.json (Cursor's documented per-project MCP config) and <project>/.cursor/rules/construct.mdc (refreshed every sync). Cursor has no global rules concept by design. Run npm run adapters after clone — adapters are gitignored (ADR-0027).
If ~/.cursor/mcp.json already exists, global sync merges Construct's own MCP server entries in there too so construct MCP tools are reachable from any Cursor workspace.
Zed / JetBrains / VS Code (ACP)
Editors that speak the Agent Client Protocol (Zed, JetBrains, the VS Code ACP client) can drive Construct as a first-class native agent — not just an MCP tool. Construct ships an ACP server: point the editor's external-agent config at
construct acp
The editor speaks JSON-RPC 2.0 over stdio; an ACP session/prompt runs a real multi-specialist orchestration through the same engine the daemon and the MCP tool use, streaming progress as session/update events (ADR-0023). The engine owns orchestration; the editor is a thin ACP client. Run provider-backed orchestration (a provider key + the daemon) for real specialist output.
What stays global vs goes to the project
| Surface | Global tier | Project tier |
|---|---|---|
| Claude agent files | — (none — VS Code reads this scope too) | construct.md only (Single Front Door) |
| Claude hooks + settings.json | yes (always global — session-level) | project-portable copy with relative paths |
| CLAUDE.md | Construct-managed block | project CLAUDE.md |
| Codex agent TOMLs | construct.toml only | construct.toml only |
| OpenCode config | construct agent + MCP | construct (+ optional construct-local) + MCP |
| Copilot prompt files | construct.prompt.md only | construct.prompt.md |
| copilot-instructions.md | minimal Construct block | front-door listing |
| VS Code MCP | merged into user mcp.json when present | .vscode/mcp.json |
| Cursor MCP + rules | merged into existing ~/.cursor/mcp.json if present | .cursor/mcp.json + .cursor/rules/construct.mdc |
| Slash commands | — | .claude/commands/*.md |
| Skills | — | .claude/skills/<name>/SKILL.md (Claude); Cursor uses MCP get_skill |
Hooks stay global because they're session-level (pre-tool-use, session-start). Everything else follows each host's documented best-practice scope: agents/prompts/MCP-for-the-team live with the project repo. The Codex and Copilot front doors live in ~/. (those hosts don't cross-read another host's agent dir), but the Claude front door is project-scoped — Claude Code and VS Code both read ~/.claude/agents/, so a global agent there would appear twice in the VS Code picker.
Migration from older Construct versions
If you ran an older version of Construct that wrote specialists to user-scope (~/.claude/agents/cx-*.md, ~/.github/prompts/cx-*.prompt.md, ~/.codex/agents/cx-*.toml), the next construct sync --global cleans them up automatically — only files whose names match a registered specialist are removed, so any user-authored cx-* files you kept in those directories stay put.
Cross-surface parity
construct doctor includes a parity check that diffs your registry against every installed editor's adapter state. If you add a specialist and forget to sync, doctor reports the drift.
construct doctor
# ... look for "Cross-surface adapter parity"
Fix drift with construct sync.
Next: what next →