Harnesses
The eight target harnesses and what each one supports.
agent-plugin-sdk compiles one portable plugin to the native artifacts each
of these coding-agent harnesses loads on its own. A feature a target can't
represent surfaces as a structured warning — never a broken file.
Support matrix
The table below is generated from the SDK's own supportMatrix() at build time,
so it can never drift from the code.
| Feature | Claude Code | Codex | Pi | OpenCode | Gemini CLI | GitHub Copilot | Cursor | Windsurf |
|---|---|---|---|---|---|---|---|---|
| instructions | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| skills | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — | ✅ |
| commands | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| subagents | ✅ | ✅ | — | ✅ | ✅ | ✅ | — | — |
| hooks | ✅ | ✅ | — | — | ✅ | ✅ | — | — |
| mcpServers | ✅ | ✅ | — | ✅ | ✅ | ✅ | ✅ | ✅ |
| tools | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
What happens when a feature isn't supported
There is no silent fallback. When a plugin uses a feature a target can't
represent, the build follows ai-sdk's warnings[] contract:
- Whole feature unsupported — the feature is dropped from that harness's
output and the build records an
unsupported-featureBuildWarningnaming the dropped items (e.g. Pi has no subagents, so a plugin's subagents are skipped for the Pi target only). Every other harness still gets them. Nothing broken or half-written is emitted. - One option unsupported — the feature emits, but a single field can't be
represented, so it's dropped with an
unsupported-optionwarning (e.g. Codex prompts ignore a per-commandmodel; a harness with no native form for a hook event skips just that hook).
Warnings never throw — only a structurally invalid plugin does. They're printed
by ap-sdk build, returned on each HarnessBuild.warnings, and surfaced in
installSkills results, so you always see exactly what a target couldn't take
and why. Many harnesses also attach an actionable note (“use the harness
override…”) telling you how to bridge the gap.
Native formats
Each harness emits at the exact paths and frontmatter it expects:
| Harness | Skill / command home | Notes |
|---|---|---|
| Claude Code | .claude/ · .mcp.json · CLAUDE.md | Reference harness — supports every feature. |
| Codex | .agents/skills/ · .codex/ | Subagents are TOML; commands are global-only. |
| Gemini CLI | gemini-extension.json extension | TOML commands ({{args}}), .gemini/agents/*.md, MCP in the manifest. |
| GitHub Copilot | .github/ · .vscode/mcp.json | Prompt files, custom agents, PascalCase hooks. |
| Cursor | .cursor/ · AGENTS.md | No Agent Skills / subagents / mapped hooks. |
| Windsurf | .windsurf/ · mcp_config.json | Skills + workflows; global-only MCP. |
| Pi | .pi/ · package.json | No subagents / hooks / native MCP. |
| OpenCode | .opencode/ · opencode.json | No hooks. |
See Authoring a harness for the common-denominator-plus-bespoke model behind the matrix.