On-disk formats of harness primitives
Historical survey (marked 2026-10-21): this is the 2026-10-13 format survey for the removed harness adapter library, and the harnesses’ formats may have changed since; the Hub is now a standard MCP server and no longer imports or exports harness primitives. Kept as a record only.
An adapter turns the Skill, Command, Agent, Instruction, Hook, and MCP server files of one harness into a hub Asset plus a neutral manifest, then writes that manifest back into that harness’s directories. This survey records only the files, fields, and export commands stated in the official docs on 2026-10-13. It is the basis for import, export, and knownCompatible.
Permission policy is already specified in Permission policy export. It is not repeated here.
Neutral fields follow Harness primitives:
| Manifest | Fields |
|---|---|
hub-skill/1 |
name, description, version, entry, tools, inputs, outputs, triggers, model, sourceHarness, knownCompatible |
hub-command/1 |
name, description, arguments |
hub-agent/1 |
name, description, tools, model, sourceHarness |
hub-instruction/1 |
scope, applies, fileName |
hub-hook/1 |
event, order, handler, language, deterministic |
hub-provider/1 |
transport, provides, reads, writes, credentials, credentialMode |
Bytes stay frozen as they are. The neutral manifest receives an item only when both sides have it and the meanings match. A mismatch is “Cannot be expressed”. A gap in the page is “Not found”. No nearby field is added as a substitute.
sourceHarness is written by the adapter as the name of the source harness. None of the five on-disk formats has this key. knownCompatible is absent in the same way. This survey does not assign it. Filling several fields only means an import can write those items. A round trip is not verified on these pages, so the adapter leaves knownCompatible empty.
hub-hook/1 event is only verify.deviceCommand, verify.hostCommand, verify.workbook, beforeDispatch, or afterResult. Every event name below fails to match those five strings, so event cannot be expressed. Output must be {decision:"pass"} or {decision:"block", code, facts}. Each vendor page uses a different decision, which cannot be expressed either. deterministic: true requires a handler that does not call a model, open a network connection, or read the environment. No Hook file below declares that, so deterministic is not found.
hub-provider/1 transport is only stdio or streamable-http. Endpoints, headers, environment variables, and tokens stay outside Git. They are not copied into the manifest or into examples in this document. provides, reads, and writes have no static field of the same name in any of the five server configs: capabilities are listed after the connection. provides cannot be expressed. reads and writes are not found. credentials records only that the secret stays outside Git. The three credentialMode values (a static secret, a platform-issued short-lived token, external OAuth) have no key of the same name and cannot be expressed.
Each Gemini CLI page opens by stating that, from 2026-06-18, Gemini CLI for unpaid and Google One users was replaced by Antigravity CLI. The Gemini section records only the format those Gemini CLI pages still describe. The Antigravity format was not surveyed.
Paths are the project-relative and home-relative paths from the official docs. The matrix is at the end.
Claude Code
Skill
Source: Skills. Consulted 2026-10-13.
Locations, from that page’s scope table: .claude/skills/<skill-name>/SKILL.md inside the managed settings directory; personal ~/.claude/skills/<skill-name>/SKILL.md; project .claude/skills/<skill-name>/SKILL.md; nested <subdir>/.claude/skills/<skill-name>/SKILL.md; .claude/skills/ in a directory passed with --add-dir; plugin <plugin>/skills/<skill-name>/SKILL.md. A skill directory in the personal, project, or enterprise location may be a symlink. The folder name synced is reserved for skills synced from claude.ai.
Format: a directory plus SKILL.md. YAML frontmatter between --- at the start of the file, then Markdown. If the file does not open with ---, the whole file is body. If the YAML does not parse, the skill still loads with no fields set. An unrecognized field is ignored. Field names are lowercase and hyphenated, except when_to_use. Booleans accept true / false and, in any letter case, yes, no, on, off, 1, and 0.
| Field | Meaning on that page |
|---|---|
name |
Optional. Command name in the / menu. Defaults to the directory name |
description |
Recommended. If omitted, the first non-empty line of the body. Together with when_to_use, truncated at 1,536 characters in the skill listing |
when_to_use |
Optional. Extra text for when to invoke the skill, appended to description |
argument-hint |
Optional. Autocomplete hint for arguments |
arguments |
Optional. Named positional arguments for $name substitution. A space-separated string or a YAML list |
disable-model-invocation |
Optional, default false. When true, the skill is not loaded automatically |
user-invocable |
Optional, default true. When false, the user cannot invoke it with /name |
allowed-tools |
Optional. During the turn that invokes the skill, these tools are not asked one by one. Space- or comma-separated, or a YAML list. The page states that this does not restrict which tools remain callable |
disallowed-tools |
Optional. Tools removed from the available pool while the skill is active |
model |
Optional. Model while the skill is active, or inherit |
effort |
Optional. low, medium, high, xhigh, max |
context |
Optional. fork runs the skill in a forked subagent |
agent |
Optional. Which subagent type to use when context: fork |
background |
Optional. Only with context: fork. Default true |
hooks |
Optional. Hooks registered when the skill is invoked and kept for the rest of the session |
paths |
Optional. Globs that limit automatic activation. A comma-separated string or a YAML list |
shell |
Optional. bash (default) or powershell |
metadata |
Optional. Free-form YAML map. Claude Code does not act on it |
license |
Optional. Accepted, and not acted on |
compatibility |
Optional. A string of at most 500 characters. Accepted, and not acted on |
The same page states that claude.ai uploads, the Skills API, and package_skill.py from anthropics/skills accept only name, description, license, compatibility, metadata, and allowed-tools. Any other key fails packaging or upload.
| Neutral field | Result |
|---|---|
| name | name, or the directory name when omitted |
| description | description, or the first non-empty body line when omitted |
| model | model |
| entry | No key of that name was found. The page requires the entry file to be SKILL.md, so the adapter may set entry to that relative path |
| version, tools, inputs, outputs, triggers | Not found. allowed-tools is a one-turn grant that skips a prompt, and disallowed-tools removes tools. Neither is the list of tool names the skill may call, so tools cannot be expressed |
| sourceHarness, knownCompatible | See the opening |
The other frontmatter stays in the frozen bytes.
Export: no Claude Code command was found that exports an installed skill as a standalone package. /run-skill-generator writes a project skill from a run that succeeded. That is generation. package_skill.py belongs to anthropics/skills and is not a Claude Code export command.
Command
Source: the same Skills page. Consulted 2026-10-13.
That page states that custom commands have been merged into skills. .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy. Existing Markdown files keep working. A file in a subdirectory replaces each / with :, so .claude/commands/frontend/component.md becomes /frontend:component. Frontmatter matches a skill except that name and paths are absent. The command name comes from the path, not from frontmatter.
| Neutral field | Result |
|---|---|
| name | The file name, or the subdirectory path plus the file name, with / written as : |
| description | Frontmatter description |
| arguments | arguments is the set of names used for $name substitution. argument-hint is only an autocomplete hint and cannot be expressed as arguments |
The same file is also a skill inside Claude Code. This survey does not decide whether it is registered as hub-command/1 or hub-skill/1. Export: not found.
Agent
Source: Subagents. Consulted 2026-10-13.
Locations: project .claude/agents/, scanned upward from the working directory to the repository root, and the definition closer to the working directory wins on a shared name; personal ~/.claude/agents/; .claude/agents/ inside the managed settings directory; agents shipped by a plugin; .claude/agents/ in a directory added with --add-dir. --agents can also pass JSON, which is not a file on disk. A nested subdirectory does not change identity. Identity comes only from frontmatter name. The filename does not have to match name. /agents only reminds you to edit those directories or to ask Claude to write the file.
Format: Markdown plus YAML frontmatter. The body is the system prompt. Only name and description are required. An unrecognized field is ignored. name is at most 256 characters and cannot contain :.
| Field | Meaning on that page |
|---|---|
name |
Required |
description |
Required. When to delegate |
tools |
Optional. A comma-separated string or a YAML list. If omitted, every tool available to subagents is inherited |
disallowedTools |
Optional. Removed from the inherited or listed tools |
model |
Optional. sonnet, opus, haiku, fable, a full model id, or inherit |
permissionMode |
Optional. default, acceptEdits, auto, dontAsk, bypassPermissions, plan. manual is an alias of default. Ignored for plugin subagents |
maxTurns |
Optional |
skills |
Optional. Skills preloaded into context at startup |
mcpServers |
Optional. A server name, or an inline server config. Ignored for plugin subagents |
hooks |
Optional. In force only while that subagent runs. Ignored for plugin subagents |
memory |
Optional. user, project, or local |
background |
Optional |
omitClaudeMd |
Optional |
effort |
Optional. low, medium, high, xhigh, max |
isolation |
Optional. worktree |
color |
Optional. red, blue, green, yellow, purple, orange, pink, cyan |
initialPrompt |
Optional. First turn submitted automatically when this agent is the main session agent |
experimental |
Optional map. cacheTtl is 5m or 1h |
| Neutral field | Result |
|---|---|
| name | name |
| description | description |
| tools | tools. disallowedTools cannot be expressed |
| model | model |
| sourceHarness | See the opening |
The other fields cannot be expressed. skills is a list of skill names to preload, and hub-agent/1 has no such field. Export: not found.
Instruction
Source: Memory. Consulted 2026-10-13.
CLAUDE.md is plain Markdown. That page does not treat its frontmatter as a schema. Load order, broadest first: managed policy (macOS /Library/Application Support/ClaudeCode/CLAUDE.md, Linux and WSL /etc/claude-code/CLAUDE.md, Windows C:\Program Files\ClaudeCode\CLAUDE.md), user ~/.claude/CLAUDE.md, project ./CLAUDE.md or ./.claude/CLAUDE.md. CLAUDE.local.md loads beside CLAUDE.md in the same directory and should be gitignored. The working directory and its parents are concatenated at launch. A file in a subdirectory loads when Claude reads, writes, or edits a file there. @path imports another file. A relative path resolves from the file that contains the @, up to four hops.
.md files under .claude/rules/ are discovered recursively. Personal rules live in ~/.claude/rules/. Rule frontmatter is read only for paths (a YAML list or a comma-separated string). Any other field is ignored, and the frontmatter is removed before the rule enters context. A rule without paths loads at launch with the same priority as .claude/CLAUDE.md.
AGENTS.md is read by default when the working directory and its parents have no CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md. The user and managed CLAUDE.md files, and .claude/rules/, do not block it. Reading it directly requires Claude Code v2.1.277 or later. Project instructions can also be claude-md-or-agents-md (the default), claude-md-and-agents-md, claude-md, or managed-only. .claude/AGENTS.md is read in the same directory.
| Neutral field | Result |
|---|---|
| fileName | The file’s name: CLAUDE.md, CLAUDE.local.md, AGENTS.md, or the rule filename |
| applies | A rule’s paths is a path. A product line was not found. CLAUDE.md itself has no path field |
| scope | The page distinguishes managed, user, project, and subdirectory locations. hub-instruction/1 does not list the allowed scope strings, and this survey does not assign one |
The body is the frozen Markdown bytes. /init can generate a starting CLAUDE.md. When a file already exists, it suggests improvements and does not overwrite. With CLAUDE_CODE_NEW_INIT=1, /init proposes CLAUDE.md, skills, and hooks before writing. That is generation. No command was found that exports an existing instruction file. /import brings another coding agent’s configuration into Claude Code (v2.1.213 or later). That is the opposite direction.
Hook
Source: Hooks. Consulted 2026-10-13.
Locations: ~/.claude/settings.json, project .claude/settings.json, .claude/settings.local.json, managed policy settings, plugin hooks/hooks.json, and hooks in skill and subagent frontmatter. Layers merge. They do not replace one another.
Format: JSON. Under hooks, an event name, then matcher groups, each with a hooks array. matcher on a group: *, empty, or omitted matches everything. Five handler type values: command, http, mcp_tool, prompt, agent. Common fields also include if, timeout (seconds), statusMessage, and once. command also has command, args, async, asyncRewake, shell (bash or powershell), and onFailure. http also has url, headers, allowedEnvVars, and onFailure. Matching hooks run in parallel.
Event names that appear in that page’s matcher table: PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied, SessionStart, Setup, SessionEnd, Notification, SubagentStart, PreCompact, PostCompact, PreModelSwitch, PostModelSwitch, SubagentStop, ConfigChange, CwdChanged, DirectoryAdded, FileChanged, StopFailure, InstructionsLoaded, UserPromptExpansion, Elicitation, ElicitationResult, UserPromptSubmit, PostToolBatch, Stop, TeammateIdle, TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, MessageDisplay.
The command-hook example returns permissionDecision: "deny" as JSON on stdout, or uses the exit code.
| Neutral field | Result |
|---|---|
| event | Cannot be expressed. See the opening |
| order | Cannot be expressed. Matches run in parallel. There is no order integer |
| handler | For type: command, command plus optional args is the entry. http, mcp_tool, prompt, and agent cannot be expressed as one script entry |
| language | When shell is bash, or the default shell form is used, language may be shell. powershell and the other four types cannot be expressed. There is no ts value |
| deterministic | Not found. prompt and agent call a model |
Export: not found.
MCP server
Source: MCP. Consulted 2026-10-13.
Project scope is mcpServers in .mcp.json at the project root. User and local scope are in ~/.claude.json. claude mcp add and claude mcp add-json write according to --scope (project, user, local). An entry with no type is read as stdio. An entry with url and no type is reported and skipped. For type: http, streamable-http is an alias. sse and ws also exist. type: sdk is skipped by Claude Code. stdio uses command, args, and env. http, sse, and ws use url and accept headers, headersHelper, timeout, and alwaysLoad. A project .mcp.json needs approval in an interactive session. enableAllProjectMcpServers committed in project settings is ignored until the workspace is trusted. An empty url counts as not configured.
| Neutral field | Result |
|---|---|
| transport | No type, started with command, or added as stdio: stdio. type http or streamable-http: streamable-http. sse and ws cannot be expressed |
| provides, reads, writes, credentials, credentialMode | See the opening |
claude mcp list and claude mcp get print connection status. claude mcp remove deletes an entry. No command was found that exports existing servers as a portable package.
Codex CLI
The docs index is llms.txt. Consulted 2026-10-13.
Skill
Source: Build skills. Consulted 2026-10-13.
A directory: required SKILL.md, optional scripts/, references/, assets/, and agents/openai.yaml. SKILL.md must include name and description. The frontmatter shown on that page has only those two. Optional agents/openai.yaml has interface (display_name, short_description, icon_small, icon_large, brand_color, default_prompt), policy.allow_implicit_invocation (default true), and dependencies.tools (each item has type, value, description, transport, and url; the example type is mcp).
Discovery: .agents/skills on every directory from the working directory up to the repository root, $HOME/.agents/skills, /etc/codex/skills, and system skills bundled with Codex. Symlinks are followed. Skills that share a name are not merged. [[skills.config]] in ~/.codex/config.toml can disable one skill without deleting it, using path and enabled = false.
| Neutral field | Result |
|---|---|
| name, description | The same fields in SKILL.md |
| entry | No key of that name was found. The entry file is SKILL.md |
| version, tools, inputs, outputs, triggers, model | Not found. dependencies.tools declares an MCP dependency, not a list of tool names, so tools cannot be expressed |
| sourceHarness, knownCompatible | See the opening |
$skill-creator creates a skill. $skill-installer installs one from a repository. Plugins distribute skills. None of these exports an installed skill. Export: not found.
Command
Source: Custom prompts. The index line says Deprecated and points to skills. Consulted 2026-10-13.
The page still states the on-disk format: top-level Markdown under ~/.codex/prompts/. Subdirectories are not scanned. Frontmatter has description and argument-hint. The body uses $1 through $9, $ARGUMENTS, and uppercase placeholders supplied as KEY=value. Invocation looks like /prompts:<name>. Non-Markdown files are ignored.
| Neutral field | Result |
|---|---|
| name | The file name |
| description | description |
| arguments | No argument-schema field was found. argument-hint and the $1 placeholders cannot be expressed as arguments |
The reusable prompt recommended now is the skill in the previous section, not this directory. Export: not found.
Agent
Source: Subagents. Consulted 2026-10-13.
Personal ~/.codex/agents/, project .codex/agents/. One agent per TOML file. Required: name, description, developer_instructions. name is the identity. The filename does not have to match. The file may also include other config.toml keys. The page names model, model_reasoning_effort, sandbox_mode, mcp_servers, and skills.config. Omitted session settings are inherited from the parent. Built-ins are default, worker, and explorer. Global [agents] in config.toml: enabled (default true), max_concurrent_threads_per_session (legacy alias max_threads), default_subagent_model, default_subagent_reasoning_effort, interrupt_message (default true). /agent switches threads. It is not an export.
| Neutral field | Result |
|---|---|
| name, description | The same fields |
| model | model |
| tools | No tool allowlist was found. sandbox_mode and mcp_servers cannot be expressed as tools |
| sourceHarness | See the opening |
developer_instructions is the behavior body. hub-agent/1 has no matching field, so it stays in the frozen bytes. Export: not found.
Instruction
Source: AGENTS.md. Consulted 2026-10-13.
Plain Markdown. No frontmatter schema was found. Global: in the Codex home directory (default ~/.codex, overridable with CODEX_HOME), AGENTS.override.md is read if it exists, otherwise AGENTS.md. Only the first non-empty file at that level is used. Project: from the project root down to the working directory, each directory checks AGENTS.override.md, then AGENTS.md, then names in project_doc_fallback_filenames, at most one file per directory. Files are concatenated from the root downward, so a closer file appears later. Empty files are skipped. Concatenation stops at project_doc_max_bytes, default 32 KiB. The page’s example sets the fallback list to TEAM_GUIDE.md and .agents.md and sets the limit to 65536.
| Neutral field | Result |
|---|---|
| fileName | The name of the file actually read |
| applies | No path or product-line field was found. The directory location itself is not applies |
| scope | The page distinguishes global and project. No value list was found, and this survey does not assign a string |
Export: not found.
Hook
Source: Hooks. Consulted 2026-10-13.
hooks.json, or [hooks] in config.toml. Common locations: ~/.codex/hooks.json, ~/.codex/config.toml, repository .codex/hooks.json, repository .codex/config.toml. Matching hooks from more than one source all run. A higher-precedence layer does not replace a lower-precedence layer. When one layer contains both files, Codex merges them and warns at startup. A plugin may bundle hooks/hooks.json. Project hooks load only when the .codex/ layer is trusted. /hooks reviews, trusts, or disables hooks. It is not an export.
During a turn: PreToolUse, PermissionRequest, PostToolUse, PreCompact, PostCompact, UserPromptSubmit, SubagentStop, Stop. On interrupt: Interrupt. When a session or subagent starts: SessionStart, SubagentStart. When the main thread ends: SessionEnd.
The shape is event, matcher group, handler. command and mcp_tool run. prompt and agent are parsed and then skipped. Optional file-level description. Handler fields in that page’s configuration section: type, command, timeout (seconds), statusMessage, additionalContextLimit, async, and Windows commandWindows (also command_windows in TOML). Multiple command hooks for the same event start concurrently. A hook may return permissionDecision (deny, or allow with updatedInput). The older shape is decision: "block". Exit code 2 with the reason on stderr also blocks.
| Neutral field | Result |
|---|---|
| event, order, deterministic | event and deterministic: see the opening. order cannot be expressed: command hooks are concurrent, and there is no order integer |
| handler | command when type is command. mcp_tool cannot be expressed as a script entry |
| language | No ts / shell field was found. The command string may launch Python, which is not enough to fill language |
Export: not found. Import brings another agent’s settings, skills, hooks, and subagents into ChatGPT or Codex. That is the opposite direction.
MCP server
Source: MCP. Consulted 2026-10-13.
[mcp_servers.<server-name>] in ~/.codex/config.toml or project .codex/config.toml. codex mcp add writes it. stdio: command is required; args, env, env_vars, cwd, and experimental_environment are optional. The page labels the other class Streamable HTTP: url is required; auth (oauth or chatgpt), bearer_token_env_var, http_headers, env_http_headers, and http_headers_helper are optional. Both classes may set startup_timeout_sec, tool_timeout_sec, enabled, required, enabled_tools, disabled_tools, default_tools_approval_mode, tools.<tool>.approval_mode, and tools.<tool>.output_token_limit. The meaning of writes is in the permission-policy export and is not repeated here.
| Neutral field | Result |
|---|---|
| transport | A stdio entry with command: stdio. An entry the page calls Streamable HTTP, configured with url: streamable-http |
| provides | Cannot be expressed. enabled_tools and disabled_tools allow and deny tools after connection. They are not provides as tools / resources / prompts |
| reads, writes, credentials, credentialMode | See the opening |
Export: not found. codex mcp login signs in.
OpenCode
The v2 docs index is llms.txt. Config file locations come from Config. Consulted 2026-10-13. System directory: macOS /Library/Application Support/opencode, Linux /etc/opencode, Windows %ProgramData%\opencode. Global ~/.config/opencode/opencode.json(c). Project root opencode.json(c) or .opencode/opencode.json(c). opencode.json(c) means opencode.json or opencode.jsonc.
Skill
Source: Skills. Consulted 2026-10-13.
Project .opencode/skills, from the working directory up to the project root. Global ~/.config/opencode/skills. Compatibility locations: global ~/.claude/skills and ~/.agents/skills, project .claude/skills and .agents/skills. The system directory also loads skills/. A skills array may add a relative path, a ~/ path, an absolute path, or an http(s) catalog.
Two file forms: review.md at the root of a source, or SKILL.md at any depth. The id comes from the path. git-release/SKILL.md has id git-release. teams/release/SKILL.md has id release, the last segment. Frontmatter name is only a display name. An HTTP catalog’s index.json has name, version, and files on each entry.
All frontmatter is optional at runtime:
| Field | Meaning on that page |
|---|---|
name |
Display name. Defaults to the path id |
description |
Summary shown to the model. Without it, the skill is not advertised |
metadata.opencode/autoinvoke |
When false, the skill is omitted from the model’s available list and can still be loaded by id |
disable-model-invocation |
When true, the same effect as the row above. If both are set, opencode/autoinvoke wins |
license, compatibility |
Accepted and not interpreted |
| Neutral field | Result |
|---|---|
| name | The path id. Display name may differ from the id, and the neutral name is the id |
| description | description |
| entry | The file’s relative path: SKILL.md or <id>.md at the source root |
| version | Not found on SKILL.md. version on an HTTP catalog entry is a cache version and cannot be expressed as the skill version |
| tools, inputs, outputs, triggers, model | Not found |
| sourceHarness, knownCompatible | See the opening |
Export: not found.
Command
Source: Commands. Consulted 2026-10-13.
~/.config/opencode/commands/ and .opencode/commands/. Only .md is discovered. A nested path joins with /, so team/review.md becomes /team/review. The legacy singular directory command/ is still discovered. The system directory also loads commands/. JSON lives at commands.<name> in any config file and requires template. The Markdown body is the template. Do not put template in frontmatter.
| Field | Meaning on that page |
|---|---|
template |
JSON only. The prompt template |
description |
Optional |
agent |
Optional. Agent selected when the command runs |
model |
Optional. provider/model or provider/model#variant |
subagent |
Optional. When true, the command runs in a background child session |
subtask |
Deprecated alias of subagent. If both are present, subagent wins |
$ARGUMENTS is the whole argument string. $1, $2, and higher are positional. When none of these placeholders is present, non-empty arguments are appended to the template.
| Neutral field | Result |
|---|---|
| name | The path, nested with / |
| description | description |
| arguments | No argument schema was found. $ARGUMENTS and $1 cannot be expressed as arguments |
agent, model, and subagent cannot be expressed. Export: not found.
Agent
Source: Agents. Consulted 2026-10-13.
~/.config/opencode/agents/<name>.md and .opencode/agents/<name>.md. A nested path is part of the id, so team/reviewer.md has id team/reviewer. The system directory also loads agents/. The Markdown body is the system prompt. Do not put system in frontmatter. JSON lives under agents.
| Field | Meaning on that page |
|---|---|
description |
What the agent is for |
mode |
primary, subagent, or all. A new agent defaults to primary when omitted |
model |
String provider/model, optional #variant. JSON may also use providerID, model, and variant |
system |
JSON only |
permissions |
Ordered rules: action, resource, effect (allow, ask, deny). The last match wins |
steps |
Positive integer. Maximum model steps |
hidden |
Hidden from ordinary listings |
color |
UI color |
disabled |
Removes the agent at that configuration layer |
request |
Header and JSON body overlays. The page states that the session runner does not send them yet |
default_agent |
Top-level config, not a field of one agent |
Actions named on that page: shell, edit, subagent, read, glob, grep, webfetch, websearch, skill. The page also says new configuration should not use the legacy top-level fields temperature, top_p, prompt, permission, tools, disable, or maxSteps. Visible built-in agents are build, plan, general, and explore.
| Neutral field | Result |
|---|---|
| name | The id derived from the file path |
| description | description |
| model | model |
| tools | Cannot be expressed. The current field is permissions, not a tool allowlist. The page explicitly drops legacy tools |
| sourceHarness | See the opening |
Export: not found.
Instruction
Source: Instructions. Consulted 2026-10-13.
AGENTS.md only. v2 does not use CLAUDE.md as a fallback. Global ~/.config/opencode/AGENTS.md, plus every AGENTS.md from the current workspace toward the home directory. Outside the home directory, the walk stops at the project root. Files are combined. Conflicts are not resolved. An AGENTS.md below the workspace loads when that area is read, nearest first. Plain Markdown. The schema still accepts an instructions array. v2 does not currently resolve its files, globs, or URLs. OPENCODE_DISABLE_PROJECT_CONFIG=1 skips project AGENTS.md and does not disable the global file.
| Neutral field | Result |
|---|---|
| fileName | AGENTS.md |
| applies | No path pattern or product line was found |
| scope | The page distinguishes the global file from a project directory. No value list was found |
Export: not found.
Hook
Hooks returned 404 on 2026-10-13. The v2 index has no Hooks page.
Plugins puts hooks inside a plugin. On disk that is plugin code, not a hook manifest. Discovery: direct .ts and .js files and immediate plugin-package directories in every .opencode/plugins/; ~/.config/opencode/plugins/; the plugins array in config. opencode plugin add, list, check, update, and remove manage global package plugins.
Registration comes from Build plugins. Consulted 2026-10-13. A plugin calls ctx.<domain>.hook(name, callback) from setup. Hooks of the same name run in plugin registration order, and a later registration sees changes made by an earlier one. Names written on that page:
| Domain | Names |
|---|---|
| session | prompt, context, compaction, generate, title, model.request, http.request, http.response, experimental.ws.handshake, experimental.ws.send, experimental.ws.receive, retry |
| permission | evaluate |
| shell | create.before |
| tool | execute.before, execute.after |
The prompt hook has no typed rejection API. permission evaluate may change effect. One evaluate example on that page calls a model again.
| Neutral field | Result |
|---|---|
| event, order, handler, language, deterministic | Cannot be expressed, or not found. There is no key matching hub-hook/1. Registration order is not an order integer. The callback lives in plugin source, not in a handler path. language was not found. The example may call a model, so deterministic cannot be set to true |
Export: not found.
MCP server
Source: MCP servers. Consulted 2026-10-13.
The key is mcp.servers.<name>. Server names are not placed directly under mcp. opencode mcp add <name> --url … writes the project configuration. --global makes the server available in every project. A higher-precedence project config replaces the whole server object of the same name.
Local: type is required and must be local. command is required and is a string array of the executable followed by its arguments. Optional: cwd, environment, disabled (default false), codemode (default true), timeout, protocol (legacy, auto, or 2026-07-28). Environment values use {env:NAME}, not $NAME.
Remote: type is required and must be remote. url is required. The page calls it an absolute Streamable HTTP endpoint. Optional: headers, oauth (or false), and the same disabled, codemode, timeout, and protocol as local. OAuth is on unless oauth is false. Credentials stay outside the project configuration. Sign-in uses /mcps or opencode mcp auth. opencode mcp list shows status. Removal deletes the entry from the configuration.
| Neutral field | Result |
|---|---|
| transport | type: local is stdio. type: remote is streamable-http |
| provides | Cannot be expressed. codemode: false chooses whether tools are exposed directly or through Code Mode. It is not a provides list |
| reads, writes, credentials, credentialMode | See the opening |
Export: not found. opencode mcp add writes configuration.
Gemini CLI
Each page opens with the Antigravity replacement note. See the opening. Consulted 2026-10-13.
Skill
Source: Agent Skills, Creating Agent Skills. Consulted 2026-10-13.
Discovery tiers, lowest to highest: built-in, extension, user ~/.gemini/skills/ or the alias ~/.agents/skills/, workspace .gemini/skills/ or the alias .agents/skills/. On a shared name, the higher tier wins. Within one tier, the alias wins over the .gemini directory. A directory plus SKILL.md, with optional scripts/, references/, and assets/. The frontmatter those pages state is name (it should match the directory name) and description (Gemini uses it to decide). Neither page gives a larger field table.
gemini skills list, install, uninstall, and link. --scope is user (default) or workspace. Inside a session: /skills list, link, disable, enable, reload. The creating page also names node scripts/init_skill.cjs and validate_skill.cjs in the core package, and package_skill.cjs, which produces a .skill zip.
| Neutral field | Result |
|---|---|
| name, description | The same fields |
| entry | The entry file is SKILL.md |
| version, tools, inputs, outputs, triggers, model | Not found |
| sourceHarness, knownCompatible | See the opening |
gemini skills install installs into Gemini. package_skill.cjs is a packaging script in the core package, not a command that exports an installed configuration. No export command was found.
Command
Source: Custom commands. Consulted 2026-10-13.
User ~/.gemini/commands/, project <project-root>/.gemini/commands/. On a shared name, the project command overrides the user command. TOML, extension .toml. The name comes from the relative path, and a subdirectory separator becomes :: test.toml is /test, git/commit.toml is /git:commit.
prompt is required. description is optional. If omitted, a generic description is generated from the filename. Arguments use `` in the body. Without that placeholder, the full command the user typed is appended after the prompt, separated by a blank line. !{...} injects command output. @{path} injects file content. The field table on that page lists only prompt and description.
| Neutral field | Result |
|---|---|
| name | The path, separated by : |
| description | description |
| arguments | No argument schema was found. `` cannot be expressed as arguments |
/commands reload and /commands list rescan and list. Export: not found.
Agent
Source: Subagents, Remote subagents. /docs/cli/subagents and /docs/cli/agents returned 404 that day. Consulted 2026-10-13.
Local and remote agents are both .gemini/agents/*.md or ~/.gemini/agents/*.md, with YAML frontmatter. A local file must start with ---. The body is the system prompt.
Local fields:
| Field | Required | Meaning on that page |
|---|---|---|
name |
yes | Lowercase letters, numbers, hyphens, and underscores |
description |
yes | The main agent uses this to decide whether to call the subagent |
kind |
no | local (default) or remote |
tools |
no | A list of tool names. *, mcp_*, and mcp_server_* are accepted. If omitted, every tool of the parent session is inherited |
mcpServers |
no | Inline MCP configuration isolated to this agent |
model |
no | Omitted means inherit |
temperature |
no | Default 1 |
max_turns |
no | Default 30 |
timeout_mins |
no | Default 10 |
A remote file must set kind to remote. name is required, plus one of agent_card_url or agent_card_json. auth is optional. auth.type on that page lists apiKey, http, google-credentials, and oauth. A YAML list in one file may hold several remote agents. The page states that mixed local and remote agents, or several local agents, in one file are not supported. experimental.enableAgents: false in settings.json disables subagents. agents.overrides can override modelConfig per agent.
| Neutral field | Result |
|---|---|
| name | name |
| description | Local description. description was not found in the remote schema table |
| tools | Local tools. Wildcards stay as written and are not expanded. tools was not found for remote |
| model | Local model. Not found for remote |
| sourceHarness | See the opening |
kind, temperature, max_turns, timeout_mins, mcpServers, auth, and the agent card cannot be expressed. Export: not found.
Instruction
Source: GEMINI.md. Consulted 2026-10-13.
The default filename is GEMINI.md. Plain Markdown. No frontmatter schema was found. Global ~/.gemini/GEMINI.md. Project: the CLI searches configured workspace directories and their parents. When a tool accesses a directory, it scans from that directory up to a trusted root. Files found are concatenated. @file.md imports a file, by a relative or absolute path. context.fileName in settings.json may be another name or a list of names. The page’s example is AGENTS.md, CONTEXT.md, and GEMINI.md. /memory show displays the concatenated body. /memory reload scans again.
| Neutral field | Result |
|---|---|
| fileName | GEMINI.md by default, or a name in context.fileName |
| applies | Not found |
| scope | The page distinguishes global, workspace, and just-in-time directories. No value list was found |
Export: not found. /memory show displays the text. It does not write a portable file.
Hook
Source: Hooks, Hooks reference. Consulted 2026-10-13.
hooks in settings.json. Merge order, highest to lowest: project .gemini/settings.json, user ~/.gemini/settings.json, system /etc/gemini-cli/settings.json, then extensions.
Events: SessionStart, SessionEnd, BeforeAgent, AfterAgent, BeforeModel, AfterModel, BeforeToolSelection, BeforeTool, AfterTool, PreCompress, Notification.
Each event is an array of definitions. A definition has optional matcher, optional sequential, and required hooks. When sequential is true, hooks in the group run one after another. When false, they run in parallel. A handler currently has only type: command, required command, and optional name, timeout (milliseconds, default 60000), and description. stdout must be JSON only. Exit code 0 parses JSON. Exit code 2 is a system block. Any other code warns and continues. Common output fields on the reference page: systemMessage, suppressOutput, continue, stopReason, decision (allow or deny, alias block), and reason.
| Neutral field | Result |
|---|---|
| event, deterministic | See the opening |
| order | Cannot be expressed. sequential is a boolean, not an order integer |
| handler | command |
| language | The page calls command the shell command to execute, so language may be shell. There is no ts |
/hooks can show hooks and enable or disable them all, or one hook by name. Export: not found.
MCP server
Source: MCP server. Consulted 2026-10-13.
mcpServers in settings.json. gemini mcp add writes ~/.gemini/settings.json for --scope user, or .gemini/settings.json for project, which is the default. There is also a top-level mcp.serverCommand. Each server requires one of command (stdio), url (SSE), or httpUrl (the page calls this an HTTP streaming endpoint). Optional: args, headers, env, cwd, timeout (default 600000 milliseconds), trust, includeTools, excludeTools (exclude wins), targetAudience, targetServiceAccount, and authProviderType (dynamic_discovery, google_credentials, service_account_impersonation). gemini mcp list and gemini mcp remove list and delete. --transport accepts stdio, sse, and http.
| Neutral field | Result |
|---|---|
| transport | command is stdio. httpUrl matches the page’s HTTP streaming and is recorded as streamable-http. SSE that has only url cannot be expressed |
| provides | Cannot be expressed. includeTools and excludeTools filter tool names. They are not provides |
| reads, writes, credentials, credentialMode | See the opening |
Export: not found.
Cursor
Skill
Source: Agent Skills. Consulted 2026-10-13.
Project .agents/skills/ and .cursor/skills/. User ~/.agents/skills/ and ~/.cursor/skills/. Compatibility: .claude/skills/, .codex/skills/, ~/.claude/skills/, and ~/.codex/skills/. Discovery walks recursively for SKILL.md. The directory that contains SKILL.md is the identity. A category directory above it is not. A skill in a nested project directory is automatically scoped to that directory. Optional scripts/, references/, and assets/.
| Field | Required | Meaning on that page |
|---|---|---|
name |
yes | Lowercase letters, numbers, and hyphens. Must match the parent folder name |
description |
yes | What the skill does and when to use it |
paths |
no | Globs. A comma-separated string or a list. Legacy globs is still accepted |
disable-model-invocation |
no | When true, the skill is included only through an explicit /skill-name |
icon |
no | Badge icon when the skill is used as a Custom Mode |
color |
no | Badge color: default, green, cyan, blue, purple, magenta, orange, yellow, red, brand |
metadata |
no | Arbitrary key-value map |
| Neutral field | Result |
|---|---|
| name, description | The same fields |
| entry | SKILL.md |
| version, tools, inputs, outputs, triggers, model | Not found. paths is a file scope. The shape of triggers is not spelled out in the neutral manifest, so it cannot be expressed |
| sourceHarness, knownCompatible | See the opening |
/create-skill creates a skill. /migrate-to-skills (2.4) turns dynamic rules and user-level and workspace-level slash commands into skills under .cursor/skills/. A skill converted from a command has disable-model-invocation: true. Sync Skills for Cloud Agents, under Settings → Agents, copies only ~/.cursor/skills/. Sharing with a team publishes to the team marketplace. None of these exports a package the hub can read. Export: not found.
Command
No directory of the user’s own user-level or workspace-level slash commands was found that day. The skills page states that both levels exist and that /migrate-to-skills converts them into skills, and it does not name the source directory.
In Plugins, a plugin’s commands/ discovers .md, .mdc, .markdown, and .txt. Frontmatter has name and description. That path is inside a plugin package, not a standalone user command directory.
| Neutral field | Result |
|---|---|
| name, description | The same fields were found only in plugin-command frontmatter |
| arguments | Not found |
Export: not found.
Agent
Source: Subagents. Consulted 2026-10-13.
Project .cursor/agents/, .claude/agents/, and .codex/agents/. User ~/.cursor/agents/, ~/.claude/agents/, and ~/.codex/agents/. Project beats user. On a shared name, .cursor/ beats .claude/ or .codex/. Markdown plus YAML. The body is the prompt.
| Field | Required | Default | Meaning on that page |
|---|---|---|---|
name |
no | Derived from the filename | Lowercase letters and hyphens |
description |
no | None | Shown to the parent agent when it decides delegation |
model |
no | inherit |
inherit or a model id. Options such as [effort=high] may follow the id |
readonly |
no | false | When true, no file edits and no state-changing shell commands |
is_background |
no | false | When true, the subagent runs in the background |
| Neutral field | Result |
|---|---|
| name | name, or the filename when omitted |
| description | description |
| model | model |
| tools | Not found. readonly cannot be expressed as a tool allowlist |
| sourceHarness | See the opening |
/create-subagent creates one. Export: not found.
Instruction
Source: Rules. Consulted 2026-10-13.
Project rules: .mdc files under .cursor/rules. A plain .md file in that directory is ignored. Frontmatter is description, globs, and alwaysApply. When alwaysApply is true, globs and description are ignored. When alwaysApply is false and globs are set, the rule follows the file match. With a description and no globs, the agent decides. With neither, the rule is included only when @-mentioned in chat. Separate multiple globs with commas. /create-rule writes into .cursor/rules.
AGENTS.md sits at the project root or in a subdirectory. Plain Markdown, with no metadata. A subdirectory file is combined with its parents, and the more specific instructions take precedence.
User rules live in Customize → Rules. The skills page states that they are not stored on the file system. Team rules live in the dashboard. The body is free-form text and may have a glob. That page gives no file path. Precedence is team, then project, then user. When guidance conflicts, the earlier source takes precedence.
| Neutral field | Result |
|---|---|
| fileName | The .mdc filename, or AGENTS.md |
| applies | globs on an .mdc file, and a glob on a team rule, are paths. A product line was not found. AGENTS.md has no path field |
| scope | The page distinguishes project, user, and team. No value list was found. User rules have no file |
Export: not found. Bringing rules in from a GitHub repository means packaging them as a plugin with .cursor-plugin/marketplace.json. That is the opposite direction.
Hook
Source: Hooks. Consulted 2026-10-13.
Project <project-root>/.cursor/hooks.json, user ~/.cursor/hooks.json. Enterprise: macOS /Library/Application Support/Cursor/hooks.json, Linux and WSL /etc/cursor/hooks.json, Windows C:\ProgramData\Cursor\hooks.json. Team-distributed hooks also exist. Priority, highest to lowest: enterprise, team, project, user. Matching hooks from every source run. On merge, deny wins over ask, and ask wins over allow.
JSON. version is required, a positive integer. The page says to use 1. hooks maps an event name to an array of definitions. Definition fields: command is required; type is command (the default) or prompt; timeout is in seconds; loop_limit; failClosed; matcher. A prompt type also has prompt text.
Agent events: sessionStart, sessionEnd, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, beforeReadFile, afterFileEdit, beforeSubmitPrompt, preCompact, stop, afterAgentResponse, afterAgentThought. Tab: beforeTabFileRead, afterTabFileEdit. App: workspaceOpen.
Command hooks communicate over stdio with JSON in both directions. Example output uses permission: allow, deny, or ask. Cloud agents run command hooks from the repository only.
| Neutral field | Result |
|---|---|
| event, deterministic | See the opening |
| order | No order field was found |
| handler | command, when type is omitted or is command. prompt cannot be expressed |
| language | Not found. command may be a shell string or bun run of a .ts file, which is not enough to write ts or shell |
/create-hook writes hooks.json. Export: not found. Third-party hooks are at Third-party hooks. Those are distributed hooks, not an export command.
MCP server
Source: MCP. Consulted 2026-10-13.
Project .cursor/mcp.json, global ~/.cursor/mcp.json. Root key mcpServers. The stdio field table: type is required and is stdio, command is required, and args, env, and envFile are optional. An example on the same page writes only command, args, and env for a local entry, with no type. A remote example writes url and headers, annotated as HTTP or SSE, plus auth (CLIENT_ID, CLIENT_SECRET, scopes). Variable substitution applies in command, args, env, url, and headers. An MCP manifest inside a plugin marketplace may also carry type: stdio.
| Neutral field | Result |
|---|---|
| transport | type: stdio, or a local example that has only command: stdio. An entry that has only url is written on that page as both HTTP and SSE, so transport stays empty |
| provides, reads, writes, credentials, credentialMode | See the opening |
Install from Customize, or write mcp.json. No export command was found.
Path matrix
Each cell is the main file for that primitive. Compatibility directories, system directories, and plugin packages are in the sections above. A primitive with no file found is “Not found”.
| Primitive | Claude Code | Codex CLI | OpenCode | Gemini CLI | Cursor |
|---|---|---|---|---|---|
| Skill | .claude/skills/<name>/SKILL.md; ~/.claude/skills/<name>/SKILL.md |
.agents/skills/<name>/SKILL.md; ~/.agents/skills/<name>/SKILL.md |
.opencode/skills/<id>/SKILL.md; ~/.config/opencode/skills/ |
.gemini/skills/<name>/SKILL.md; ~/.gemini/skills/ |
.cursor/skills/<name>/SKILL.md; .agents/skills/<name>/SKILL.md; ~/.cursor/skills/ |
| Command | .claude/commands/<name>.md |
~/.codex/prompts/<name>.md |
.opencode/commands/<name>.md; ~/.config/opencode/commands/ |
.gemini/commands/<name>.toml; ~/.gemini/commands/ |
Not found |
| Agent | .claude/agents/<name>.md; ~/.claude/agents/ |
.codex/agents/<file>.toml; ~/.codex/agents/ |
.opencode/agents/<name>.md; ~/.config/opencode/agents/ |
.gemini/agents/<name>.md; ~/.gemini/agents/ |
.cursor/agents/<name>.md; ~/.cursor/agents/ |
| Instruction | CLAUDE.md; .claude/CLAUDE.md; .claude/rules/*.md; AGENTS.md |
AGENTS.md; AGENTS.override.md; ~/.codex/AGENTS.md |
AGENTS.md; ~/.config/opencode/AGENTS.md |
GEMINI.md; ~/.gemini/GEMINI.md |
.cursor/rules/*.mdc; AGENTS.md |
| Hook | .claude/settings.json; ~/.claude/settings.json |
~/.codex/hooks.json; .codex/hooks.json; [hooks] in config.toml in the same layer |
No separate file found. Plugin code in .opencode/plugins/, ~/.config/opencode/plugins/ |
.gemini/settings.json; ~/.gemini/settings.json |
.cursor/hooks.json; ~/.cursor/hooks.json |
| MCP server | .mcp.json; ~/.claude.json |
~/.codex/config.toml; .codex/config.toml |
mcp.servers in opencode.json(c) |
.gemini/settings.json; ~/.gemini/settings.json |
.cursor/mcp.json; ~/.cursor/mcp.json |
This document is one of circle-hub’s design specifications, licensed under CC BY 4.0: quote or build on it with attribution to Circle Hub and qingshanfeihu and a link to the original. See the design specifications index.