Updated May 2026

AI harness engineering compatibility matrix

Which harness config files each AI coding tool reads, what each file controls, and where support is native, partial, or missing. Tap i on any row to learn more.

The harness is everything around the model: instructions, tools, permissions, state, checks, agents, hooks, MCP servers, and guardrails. These config files are the harness you can version, review, and improve.

Prompt engineering what you ask Context engineering what you send Harness engineering the whole system around the model
Term coined by Mitchell Hashimoto (Feb 2026). Controls taxonomy from Birgitta Böckeler / Thoughtworks.
Native support Fallback / compat Opt-in / partial Not supported
Native = read by default. Fallback = read as compatibility with another tool. Opt-in / partial = requires a setting, preview feature, or only works on some surfaces.
Category labels show the control type: guideiFeedforward control — steers the agent before it acts steers before action; sensoriFeedback control — observes after the agent acts observes, blocks, or corrects after action.
Trust boundary: rows are committed and team-shared unless flagged user-local (per-user) or both (project and user scopes both load).
Show:
Config file GitHub CopilotVS Code GitHub CopilotCLI GitHub CopilotCloud agent Claude Codeall surfaces OpenCodeall surfaces Codexall surfaces Geminiall surfaces Cursorall surfaces Windsurfall surfaces Ampall surfaces
Repo-wide instructions guideiFeedforward — steers the agent before it acts
AGENTS.mdroot of repo
Yes Yes Yes Yes Yes opt-in Yes Yes Yes
The broadest shared instruction file in this matrix. Put durable repo guidance here: stack, architecture, naming rules, forbidden patterns, and team conventions. Copilot, Codex, OpenCode, Cursor, Windsurf, and Amp read it natively; Gemini CLI can opt in. Claude Code still uses CLAUDE.md natively.
CLAUDE.mdroot + subdirectories
Yes Fallback Yes Yes Fallback Fallback
Claude Code's native repo instruction file. It serves the same purpose as AGENTS.md, with hierarchical loading from root and subdirectories. If a repo also has AGENTS.md, import it with @AGENTS.md and keep Claude-specific additions here. Copilot VS Code scans CLAUDE.md as a compatibility instruction file; Copilot CLI and cloud agent can use a root-level file too.
GEMINI.mdroot of repo
Fallback Yes Yes
Gemini CLI's native context file. Gemini loads global, project, and subdirectory GEMINI.md files with just-in-time discovery. Copilot CLI and cloud agent can use a root-level GEMINI.md as compatibility instructions. Gemini CLI can also look for alternative names, including AGENTS.md, through context.fileName.
copilot-instructions.md.github/
Yes Yes Yes
Copilot's original repo-wide instruction file. It lives at .github/copilot-instructions.md and loads into Copilot requests. Use AGENTS.md for shared rules and this file for Copilot-only additions. Copilot can generate one with /init.
Path-scoped instructions / rules guideiFeedforward — steers the agent before it acts
*.instructions.md.github/instructions/ (glob scoped)
Yes Yes Yes
Copilot path-scoped instructions. Each file uses applyTo frontmatter, such as "**/*.tsx", so rules apply only to matching files. Use these for framework, language, or directory-specific conventions. Claude Code's equivalent is .claude/rules/*.md with paths.
.claude/rules/*.mdscoped via paths property
Fallback Yes
Claude Code's scoped instruction files. They use a paths array instead of Copilot's applyTo. If paths is omitted, the rule defaults to all files. Copilot in VS Code also reads this folder as a Claude-format compatibility location.
.cursor/rules/*.mdc.cursor/rules/ (frontmatter scoped)
Yes
Cursor's native scoped rules. MDC files in .cursor/rules/ support four activation modes: always-on, glob match, model-decision, and manual @rule-name. Use them when AGENTS.md is too broad and the rule needs explicit activation control.
.windsurf/rules/*.md.windsurf/rules/ (frontmatter scoped)
Yes
Windsurf's native scoped rules. Markdown files in .windsurf/rules/ support the same four activation modes as Cursor: always-on, glob, model-decision, and manual. Global rules live at ~/.codeium/windsurf/memories/global_rules.md; enterprise teams can deploy system rules.
Custom / sub agents (persona + tool restrictions) guideiFeedforward — steers the agent before it acts
*.agent.md.github/agents/
Yeshard Yeshard Yeshard
Specialized Copilot personas invoked by name. Each file defines a role, tool access, model choice, and behavioral boundary. Invoke with @agent-name. Use these for narrow roles such as read-only reviewers, test writers, or planners.
.claude/agents/*.mdClaude subagents
Fallback Yeshard
Claude Code's subagent system. These agents run with isolated context and explicit tools. Built-ins include Explore for read-only research and Plan for planning without file edits. Skills can target an agent through frontmatter. Copilot in VS Code also supports Claude-format agent files as compatibility custom agents.
.opencode/agents/*.mdOpenCode agents
Yeshard
OpenCode's native agent definitions. Each agent can set a persona, description, model, tool permissions, and prompt. OpenCode ships with Build for full-tool work and Plan for read-only planning. Switch agents with Tab.
.gemini/agents/*.mdGemini subagents
Yeshard
Gemini CLI's custom subagents. Markdown files with YAML frontmatter define specialized local agents. Store them in project scope at .gemini/agents/ or user scope at ~/.gemini/agents/. Gemini can delegate automatically, or you can invoke one with @agent-name.
Skills (bundled capability folders with SKILL.md) guideiFeedforward — steers the agent before it acts
.github/skills/*/SKILL.mdCopilot native path
Yes Yes Yes
Copilot's native skill path. A skill is a folder with SKILL.md plus optional scripts, templates, and assets. Copilot loads metadata first and the full body only when needed. Claude Code does not read this path; use .claude/skills/ for Claude-native skills.
.claude/skills/*/SKILL.mdClaude Code native path
Yes Yes Yes Yes Fallback Fallback opt-in Fallback
Claude Code's native skill path. Claude supports auto-invocation, explicit /skill-name invocation, and forked subagent execution. Copilot also scans .claude/skills/ as a default project skill path, and OpenCode reads it as fallback.
.agents/skills/*/SKILL.mdcross-agent standard path
Yes Yes Yes Fallback Yes Yes Yes Fallback Yes
The broadest shared skill path today. Codex uses .agents/skills as its primary skill path. Copilot, Cursor, Amp, and Gemini CLI read it natively; OpenCode and Windsurf read it as fallback. VS Code can add more skill paths through chat.agentSkillsLocations. In Gemini CLI, this alias takes precedence over .gemini/skills/ within the same tier. The path follows the open Agent Skills specification.
.gemini/skills/*/SKILL.mdGemini CLI native path
Yes
Gemini CLI's native skill path. Skills live under .gemini/skills/<name>/SKILL.md and activate through activate_skill. Gemini also reads .agents/skills/ natively, so that path is usually better for cross-tool reuse.
.opencode/skills/*/SKILL.mdOpenCode native path
Yes
OpenCode's own skill directory. Same SKILL.md format. OpenCode also reads .claude/skills/ and .agents/skills/ as fallbacks, so you rarely need this unless you want OpenCode-exclusive skills.
.cursor/skills/*/SKILL.mdCursor native path
Yes
Cursor’s native skill path. Skills live at .cursor/skills/<name>/SKILL.md with name and description frontmatter. Cursor loads metadata until the skill is invoked, reads .agents/skills/ natively, and scans Claude/Codex compatibility paths.
.windsurf/skills/*/SKILL.mdWindsurf native path
Yes
Windsurf’s native skill path. Skills at .windsurf/skills/<name>/SKILL.md with YAML frontmatter. Also available globally at ~/.codeium/windsurf/skills/. Windsurf reads .agents/skills/ as a fallback and .claude/skills/ when Claude Code config reading is enabled.
Prompt files / slash commands (manual invocation) guideiFeedforward — steers the agent before it acts
*.prompt.md.github/prompts/
Yes
Lightweight reusable prompt templates for Copilot IDEs. Invoke with /prompt-name in chat. They do not create a new persona, restrict tools, or bundle assets. Use them for repeatable tasks such as /new-component, /spell-check, and /prep-pr. They are not available in Copilot CLI or cloud agent.
.claude/commands/*.mdClaude custom commands
Yes
Claude Code's custom slash commands. Markdown files in .claude/commands/ create project commands invoked as /name. Use them for lightweight prompts; use skills when the workflow needs assets, progressive loading, or auto-invocation.
.opencode/commands/*.mdOpenCode native commands
Yes
OpenCode's native custom command format. Markdown files in .opencode/commands/ define reusable slash commands. The file body becomes the prompt template, and frontmatter can choose an agent or model for execution.
.gemini/commands/*.tomlGemini custom commands
Yes
Gemini CLI's native custom command format. TOML files in .gemini/commands/ define reusable slash commands. Project commands override user commands, support argument injection, and can embed shell output or file content into the final prompt.
.windsurf/workflows/*.mdWindsurf workflows
Yes
Windsurf's reusable prompt templates. Markdown files in .windsurf/workflows/ are invoked as /workflow-name in Cascade. They are equivalent to Copilot *.prompt.md files. Global workflows live at ~/.codeium/windsurf/global_workflows/; each file has a 12,000 character limit.
Automation (lifecycle hooks) sensoriFeedback — observes after the agent acts
.github/hooks/hooks.json
opt-in Yes Yes
Copilot lifecycle hooks. Hooks run automation at agent events: format after edits, validate branch names, enforce lint, or deny/modify tool calls. They are documented for Copilot CLI and cloud agent. VS Code support is in Preview, can read Claude-format .claude/settings.json hooks, and supports chat.hookFilesLocations.
.claude/settings.jsonhooks key
opt-in Yes
Claude Code's hook system. Hooks are configured in settings files and can call shell commands, HTTP endpoints, MCP tools, prompts, or agents. Events include session, prompt, tool-use, permission, compaction, stop, and subagent lifecycle points. Use them for linting, logging, approval gates, and deterministic guardrails. Copilot VS Code Preview and Cursor CLI can read Claude-format hooks for compatibility.
.codex/hooks.json bothrepo or ~/.codex/
opt-in
Codex's lifecycle hook system. Experimental hooks run on SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, and Stop. They receive JSON on stdin and can block commands, inject context, or continue stopped turns. Codex loads ~/.codex/hooks.json and .codex/hooks.json when codex_hooks = true.
.gemini/settings.jsonhooks key
Yes
Gemini CLI's hook system. Configured under the hooks key in .gemini/settings.json, with hooksConfig controlling enablement, disabled hook names, and notifications. Events include BeforeTool, AfterTool, BeforeAgent, AfterAgent, Notification, SessionStart, SessionEnd, PreCompress, BeforeModel, AfterModel, and BeforeToolSelection.
.cursor/hooks.json bothproject or ~/.cursor/
Yes
Cursor's hook system. Project hooks live at .cursor/hooks.json; user hooks live at ~/.cursor/hooks.json. Command-based hooks receive JSON on stdin and can run on events such as preToolUse, postToolUse, beforeShellExecution, afterFileEdit, beforeSubmitPrompt, preCompact, stop, sessionStart, and sessionEnd. Cursor also documents compatibility with Claude Code hook files.
.windsurf/hooks.json both.windsurf/ (system/user/workspace)
Yes
Windsurf’s lifecycle hook system. 12 hook events including pre/post_read_code, pre/post_write_code, pre/post_run_command, pre/post_mcp_tool_use, pre_user_prompt, and post_cascade_response. Pre-hooks can block actions via exit code 2. Three config tiers merged together: system (/Library/Application Support/Windsurf/hooks.json), user (~/.codeium/windsurf/hooks.json), and workspace (.windsurf/hooks.json). Enterprise teams can deploy via cloud dashboard or MDM.
MCP server configuration guideiFeedforward — steers the agent before it acts
.vscode/mcp.jsonVS Code workspace
Yes
Copilot's MCP config for VS Code. Defines MCP servers available in the workspace. Supports stdio and HTTP servers with environment variables, auth, and sandboxing. Committable to git for team sharing. Can also configure MCP in settings.json (workspace or user), install from the MCP server gallery, or add via devcontainer.json. User-level config available via MCP: Open User Configuration.
.mcp.jsonrepo root
Yes
Claude Code's project-scoped MCP config. Defines MCP servers for all collaborators on this repository. Supports stdio, SSE, and HTTP servers. Committable to git. User-scoped servers go in ~/.claude.json instead.
opencode.jsonrepo root (mcp key)
Yes
OpenCode's MCP config. MCP servers are defined under the mcp key in opencode.json at the repo root. Supports local (stdio) and remote (HTTP) servers with OAuth support. Committable to git.
.codex/config.tomlrepo root (mcp_servers)
Yes
Codex's project-scoped MCP config. MCP servers defined under [mcp_servers.<name>] tables in TOML format. Supports stdio and streamable HTTP servers with bearer token auth and OAuth. Shared by CLI and IDE extension. User-level config at ~/.codex/config.toml.
.gemini/settings.jsonmcpServers key
Yes
Gemini CLI's MCP config. MCP servers defined under the mcpServers key in .gemini/settings.json. Supports stdio, SSE, and streamable HTTP with tool allowlists/excludelists. User-level config at ~/.gemini/settings.json. Invoke MCP tools via @server-name in prompts.
.cursor/mcp.json.cursor/ (project + global)
Yes
Cursor's MCP config. Project-scoped at .cursor/mcp.json, user-scoped at ~/.cursor/mcp.json. Supports stdio, SSE, and streamable HTTP transports. Committable to git for team sharing.
mcp_config.json user-local~/.codeium/windsurf/ (user-level)
Yes
Windsurf's MCP config — user-level only. Configured at ~/.codeium/windsurf/mcp_config.json or via the MCP Marketplace in Cascade settings. Supports stdio, streamable HTTP, and SSE transports with OAuth. Notable gap: no project-scoped committable MCP config — all MCP setup is per-user. Supports variable interpolation (${env:VAR}, ${file:path}) for secrets.
.amp/settings.jsonworkspace (amp.mcpServers)
Yes
Amp's MCP config. MCP servers defined under amp.mcpServers in .amp/settings.json (workspace) or ~/.config/amp/settings.json (user). Skills can also bundle their own MCP servers via an mcp.json file in the skill directory. Supports --mcp-config CLI flag and amp mcp add command.
Permissions / sandboxing (tool-call gating) sensoriFeedback — intercepts tool calls before they execute
permission rules (allow / deny / ask)file path or UI
Yessettings.json Yes~/.copilot/ UI onlyrepo settings Yes.claude/settings.json Yesopencode.json Yesconfig.toml Yes.gemini/settings.json Yes.cursor/cli.json Yessettings + lists Yes.amp/settings.json
How tools gate calls before execution. Most tools support allow/deny/ask rules for commands, paths, domains, or MCP tools. Codex uses approval_policy modes instead of rule arrays. Copilot Cloud Agent has no interactive approval; it runs in an ephemeral runner and humans review the resulting PR. Bypass flags on CLIs disable these controls and should be treated as privileged modes.
OS-level sandboxfilesystem + network isolation
YesActions VM YesSeatbelt / Bubblewrap YesSeatbelt / Landlock YesDocker / Seatbelt YesSeatbelt / Landlock / WSL2
OS-level isolation goes beyond permission rules. A sandbox uses the operating system to limit filesystem or network access after a process starts. Claude Code uses Seatbelt and Bubblewrap; Codex uses Seatbelt and Landlock+seccomp; Gemini CLI supports Docker, Podman, gVisor/runsc, LXC, Seatbelt, and Windows Native; Cursor uses Seatbelt, Landlock, and WSL2. Copilot Cloud Agent runs in an ephemeral GitHub Actions VM with an allowlist firewall, though MCP servers and setup steps are outside the Bash-tool firewall. The remaining local tools rely on permission rules without kernel-enforced isolation.
Key takeaways

AGENTS.md is the most portable instruction file here: Copilot, Codex, OpenCode, Cursor, Windsurf, and Amp read it natively; Gemini CLI can opt in. Claude Code still uses CLAUDE.md.

.agents/skills/ is the broadest shared skill path: Copilot, Codex, Cursor, Amp, and Gemini CLI read it natively; OpenCode and Windsurf support it as fallback.

Cursor and Windsurf have the most granular scoped rules, with repo-wide, glob, model-decision, and manual activation modes.

Claude Code has the richest hook system. Cursor, Windsurf, Gemini CLI, Codex, and Copilot also support hooks, but their event models and config scopes differ.

MCP config is still fragmented. Every tool uses a different file and format, and Windsurf's MCP config is user-local only.

Precedence & conflicts
The matrix shows which files each tool reads. This section shows what wins when files overlap: instruction load order, user/project/managed settings layers, and merge-vs-override behavior. Many instruction files are additive; many settings are not. Confidence: documented means official docs state the rule; partial means at least one dimension is undocumented.

GitHub Copilot partial

  • Instructions: all sources merged. Personal > repository > organization, but all are sent.
  • AGENTS.md / CLAUDE.md / GEMINI.md: CLI/cloud surfaces can use root compatibility files. VS Code scans AGENTS.md, CLAUDE.md, and configured workspace instruction folders; current official docs do not list GEMINI.md for VS Code. Root .github/copilot-instructions.md loads as Copilot's native repo instructions.
  • Path-scoped *.instructions.md: merges with repo-wide. excludeAgent frontmatter can opt out per surface (code-review, cloud-agent).
  • Settings: VS Code workspace > user (standard VS Code precedence).
  • MCP same-name conflicts: undocumented across .vscode/mcp.json, user, and .github/copilot-mcp.json.

Claude Code documented

  • Settings (high → low): managed (org policy) > CLI args > .claude/settings.local.json > .claude/settings.json > ~/.claude/settings.json.
  • Permissions: deny always beats allow across all scopes. Project deny overrides user allow.
  • CLAUDE.md: walk-up from cwd, all files concatenated. Subdirectory files lazy-load. CLAUDE.local.md appended after CLAUDE.md (effectively higher priority).
  • AGENTS.md: not read directly — recommended pattern is @AGENTS.md import inside CLAUDE.md.
  • Hooks: user + project both fire (merge). allowManagedHooksOnly: true blocks user/project. Array settings concat across sources.
  • MCP: managed denylist always wins over allowlist; allowManagedMcpServersOnly locks to admin list.

OpenCode documented

  • Load order (later wins): remote .well-known/opencode → global ~/.config/opencode/OPENCODE_CONFIG env → project opencode.json.opencode/ dirs → inline env → managed file → MDM (ai.opencode.managed, not user-overridable).
  • Merge semantics: conflicting keys take later config; non-conflicting settings preserved across all layers.
  • Instructions: walks up from the current directory for AGENTS.md and falls back to CLAUDE.md when no AGENTS.md exists in that directory. The explicit instructions config can add paths/globs.
  • Provider toggles: disabled_providers always beats enabled_providers.

Codex CLI documented

  • Settings (high → low): CLI flags and --config overrides > profile values > trusted project .codex/config.toml files from project root down to cwd (closest wins) > ~/.codex/config.toml > system config > built-in defaults.
  • AGENTS.md: global guidance loads first, then project files from root down to cwd. Files closer to cwd appear later in the combined prompt and override earlier guidance. AGENTS.override.md beats regular files in the same directory.
  • Hooks: ~/.codex/hooks.json and project .codex/hooks.json are both loaded when codex_hooks = true. Higher-precedence config layers do not replace lower-precedence hooks; all matching hooks run.
  • MCP per-tool approval: default_tools_approval_mode on the server, with [mcp_servers.NAME.tools.X] overrides per tool — explicit override.
  • CA certs: CODEX_CA_CERTIFICATE > SSL_CERT_FILE > system roots.

Gemini CLI documented

  • Settings: enterprise/system > workspace .gemini/settings.json > user ~/.gemini/settings.json.
  • GEMINI.md (concatenated, not overridden): global ~/.gemini/GEMINI.md + workspace + parent dirs + JIT subdirectory files when tools touch them.
  • Filename customization: context.fileName can list ["AGENTS.md", "CONTEXT.md", "GEMINI.md"] — array order = lookup order.
  • Hooks: configured under hooks in settings files; hooksConfig can disable the system or named hook commands.
  • Custom ignore files: earlier in array beats later, both beat .geminiignore and .gitignore.
  • Lockouts: disableYoloMode / disableAlwaysAllow available for security policy.

Cursor documented

  • Rules (high → low): Team Rules > Project Rules (.cursor/rules/) > User Rules. Conflicts resolved earliest-wins.
  • AGENTS.md: nested files combine with parent-dir; deeper (more specific) instructions take precedence.
  • Team Rule enforcement: admin can mark a Team Rule "Enforce" so users cannot disable it.
  • Hooks: project .cursor/hooks.json and user ~/.cursor/hooks.json both load; enterprise team and system tiers can also distribute hooks.
  • User Rules scope: Agent (Chat) only. Not applied to Inline Edit (Cmd/Ctrl+K) or Cursor Tab.
  • Same-name MCP across scopes: undocumented.

Windsurf documented

  • Rules: System (enterprise) + Workspace + Global all merge — system rules add context, do not override user-defined rules.
  • Workspace activation modes: always_on, model_decision, glob, manual (frontmatter trigger).
  • Limits: global rules 6k chars (single file); workspace rules 12k chars per file.
  • Discovery: walks up to git root; multi-folder workspaces deduplicate.
  • System rules: display "System" label, cannot be deleted/modified by end users.
  • MCP / hooks cross-scope: hook tiers merge; MCP same-name conflicts undocumented.

Amp documented

  • Settings: workspace .amp/settings.json overrides user ~/.config/amp/settings.json.
  • AGENTS.md: walk-up from cwd to $HOME + subtree (when files touched) + system-wide all merged. Falls back to AGENT.md then CLAUDE.md per directory.
  • Skills (first wins): ~/.config/agents/skills/~/.config/amp/skills/.agents/skills/.claude/skills/~/.claude/skills/ → plugins → built-in.
  • MCP load order: CLI --mcp-config > user/workspace amp.mcpServers > skill-bundled mcp.json (only if not already configured).
  • Workspace MCP trust: servers in .amp/settings.json require amp mcp approve <server> before they run.
  • Permissions: first-match wins in user list; falls through to built-in if no match. Actions: allow, reject, ask, delegate.

Canonical example