Core API
Commands, Skills, Subagents, Memory, Statusline & Actions#
Content surfaces are content-only (markdown / TOML files): no runtime dispatch, no telemetry wrapping, no home-bin pointer — pure file writers. Each supporting adapter writes the native file(s); unsupporting adapters skip + warn. memory is the fourth content surface with the same contract, except it edits a shared, user-authored memory/rules file (AGENTS.md / CLAUDE.md / GEMINI.md) via marker-fenced managed blocks instead of writing files agent-connector wholly owns — see MemoryDef below.
SurfaceToolPolicy is shared: { allow?: string[]; deny?: string[] } — rendered to each host's allowed-tools / tools[] / readonly.
Plus two runtime-dispatched handler surfaces beyond the content writers — a singular statusline and actions, each set up below.
Status line#
A singular statusline — a HUD render(ctx) handler with top-level/per-host options; claude-code and antigravity-cli (top-level statusLine) and qwen-code (nested ui.statusLine in settings.json) today, other hosts skip-warn.
Actions#
actions — user-invokable run(ctx) handlers dispatched by agent-connector action with label/icon/placement/confirm metadata; v1 ships the dispatch backbone, and host affordance emitters now ship for droid, hermes, kiro, omp, openclaw, pi, warp, and zed (plus the nemoclaw fork, which inherits openclaw's emitter); hosts with no verifiable emission target skip-warn.
CommandDef#
A slash command.
| Field | Type | Default | Notes |
|---|---|---|---|
namerequired | string | — | kebab-case; slash name + filename stem (source of truth). |
description | string | — | One-line, for /help + model auto-selection. |
promptrequired | string | — | Markdown prompt template body (non-empty). |
argumentHint | string | — | e.g. "[environment]". |
tools | SurfaceToolPolicy | — | { allow?: string[]; deny?: string[] }. |
model | string | — | Raw id or alias; adapters pass through or drop + warn. |
subtask | boolean | — | Force subagent / forked context where supported. |
extra | Record<string, unknown> | — | Verbatim per-platform frontmatter additions. |
SkillDef#
An Agent Skill (folder + SKILL.md, Agent Skills open standard).
| Field | Type | Default | Notes |
|---|---|---|---|
namerequired | string | — | <=64 chars, [a-z0-9-]; MUST equal the skill dir name. |
descriptionrequired | string | — | <=1024 chars, 3rd-person "what + when" (drives auto-selection). |
bodyrequired | string | — | SKILL.md markdown body (non-empty). |
tools | SurfaceToolPolicy | — | Allowed / denied tools. |
model | string | — | Model override. |
disableModelInvocation | boolean | — | → disable-model-invocation. |
resources | Record<string, string> | — | relpath → contents, bundled beside SKILL.md (safe paths only). |
extra | Record<string, unknown> | — | Escape hatch. |
SubagentDef#
A named subagent (system-prompt + tool/model scoping).
| Field | Type | Default | Notes |
|---|---|---|---|
namerequired | string | — | kebab-case; filename stem on most platforms. |
descriptionrequired | string | — | Delegation hint (non-empty). |
promptrequired | string | — | System prompt / instructions (non-empty). |
tools | SurfaceToolPolicy | — | Allowed / denied tools. |
model | string | — | alias | full-id | "inherit". |
readonly | boolean | — | Coarse permission knob (Cursor readonly, opencode/kilo perms). |
extra | Record<string, unknown> | — | Escape hatch. |
commands: [
{
name: "deploy",
description: "Deploy the current service to an environment.",
argumentHint: "[environment]",
prompt: "Deploy {{args}} using the project's release runbook.",
tools: { allow: ["Bash", "Read"] },
},
],
skills: [
{
name: "db-triage",
description:
"Triage a failing query. Use when a SQL error or slow query is reported.",
body: "# DB triage\nInspect the plan, check indexes, suggest a fix.",
resources: { "references/indexes.md": "..." },
},
],
subagents: [
{
name: "schema-reviewer",
description: "Reviews migrations for backwards-compatibility.",
prompt: "You are a careful schema reviewer...",
readonly: true,
},
],MemoryDef#
Standing guidance declared once and upserted by every supporting adapter as a managed block into the memory/rules file that host actually reads. Unlike the three surfaces above, the target file is shared and user-authored — agent-connector never touches bytes outside its own marker pair.
| Field | Type | Default | Notes |
|---|---|---|---|
name | string | "memory" | kebab-case; suffixes the connector id in the block marker (<connectorId>/<name>) — keep it STABLE across versions. |
description | string | — | Status/docs output only; never written to the host file. |
contentrequired | string | — | Plain CommonMark, host-agnostic (no @imports, no frontmatter) — inlined verbatim into every targeted host's prompt context. Hard 16 KiB cap (ConnectorConfigError); soft 4 KiB install-time warn; must not contain the literal marker tokens. |
memory: [
{
// name defaults to "memory" → blockId "acme-db/memory"
description: "Standing guidance for agents working with acme-db.",
content:
"Use the acme-db MCP tools for schema questions; never hand-edit migrations.",
},
],
platforms: {
// optional per-host tuning — both fields are escape hatches:
"claude-code": { memory: { mode: "agents-import" } }, // opt-in @AGENTS.md bridge
codex: { memory: { path: "docs/AGENTS.md" } }, // org convention override
},Managed blocks: markers, hashes, reversibility#
Every memory write goes through one dependency-free engine (core/managed-block.ts). The block is fenced by HTML-comment markers carrying the blockId (<connectorId>/<name> — unique per connector, so multiple connectors coexist in one file) and a content hash (first 12 hex of sha256 over the normalized inner content):
<!-- agent-connector:begin acme-db/memory hash=3f9c2a81d04e -->
<!-- Managed by agent-connector for "acme-db". Do not edit between these markers: run your connector package's upgrade/sync command to rewrite this block; run its uninstall command to remove it (framework fallback: `agent-connector uninstall acme-db`). -->
Use the acme-db MCP tools for schema questions; never hand-edit migrations.
<!-- agent-connector:end acme-db/memory -->- Idempotent: unchanged content → an O(1)
skip(no mtime/git churn); replacement is in place — zero bytes outside the marker pair ever change, no move-to-top, no blank-line reflow. New blocks append at EOF with exactly one blank separator line; a missing file is created and recorded as agent-connector-created. - Edit detection: if the actual inner hash differs from the recorded
hash=, the user edited inside the block — syncwarns and leaves the edit intact; onlyinstall --forceoverwrites, after a timestamped backup. - Robust scanning: line-anchored, CRLF-preserving, BOM-safe, and fence-aware (marker text quoted inside code fences never matches); lone stray markers are recovered safely and duplicate pairs collapse on upsert.
- Fully reversible: memory installs last among the content surfaces and is removed first on uninstall — a prefix scan over the connector's marker namespace (plus the persisted ownership ledger) excises every block, reclaims the blank separator line, and deletes the file only when agent-connector created it and nothing else remains.
doctorverifies each installed block: file present / block present / hash intact / user-edited.
AGENTS.md-first: where the block goes#
AGENTS.md adopters read the open AGENTS.md standard file (the Linux Foundation-stewarded "README for agents" format) — so you write the guidance once and it lands in the standard file across adopter hosts. agent-connector never flips host settings to make AGENTS.md readable (probe-and-respect only), and the non-reader hosts are wired per their own official docs — CLAUDE.md and GEMINI.md, plus the dedicated rules-dir hosts (.amazonq/rules, .continue/rules, .windsurf/rules):
| Host | project scope | user scope | Notes |
|---|---|---|---|
33 AGENTS.md adopter hosts | <projectDir>/AGENTS.md — exclusive/first-match readers are probed so the block lands where the host actually reads (zed's nine-candidate first-match, warp's WARP.md priority, hermes' .hermes.md, opencode's CLAUDE.md fallback, codex's AGENTS.override.md; openclaw → its agent workspace) | the host's documented global memory file: AGENTS.md where one exists (e.g. ~/.codex/AGENTS.md, ~/.config/zed/AGENTS.md, ~/.config/amp/AGENTS.md, ~/.factory/AGENTS.md), else the host's own file (~/.qwen/QWEN.md, goose .goosehints, ~/.copilot/copilot-instructions.md, kilo/roo/kiro rules-dir agent-connector.md) — else skip-warn | One canonical copy in the open agents.md standard file; convergent writes dedupe via the content hash (first adapter writes, the rest skip). Hosts whose user rules are app/UI-managed (cursor, warp, trae, jetbrains-copilot, …) skip-warn at user scope. |
claude-code | <projectDir>/CLAUDE.md | ~/.claude/CLAUDE.md | Official docs: "Claude Code reads CLAUDE.md, not AGENTS.md". HTML-comment markers are stripped from the model's context — invisible to Claude, still parseable for sync/doctor/uninstall. Opt-in memory.mode: "agents-import" writes AGENTS.md + a managed @AGENTS.md import bridge in CLAUDE.md; pre-existing user imports/symlinks are auto-detected and respected. |
gemini-cli | <projectDir>/GEMINI.md | ~/.gemini/GEMINI.md | AGENTS.md is targeted instead when the user's context.fileName setting includes "AGENTS.md" — probed and respected, never edited by agent-connector. |
cline | <projectDir>/.clinerules/agent-connector.md | ~/Documents/Cline/Rules/agent-connector.md | Cline reads its own `.clinerules` rules tree (NOT AGENTS.md), so AC writes a dedicated agent-connector-owned file in the rules dir at both scopes — `.clinerules/agent-connector.md` (project, the DIRECTORY form) and `~/Documents/Cline/Rules/agent-connector.md` (user; the Documents dir is resolved cross-OS, honoring XDG_DOCUMENTS_DIR). FILE-vs-DIRECTORY caveat: when `.clinerules` already exists as a single FILE (the legacy single-file form), the project memory write is skip-warned rather than nesting `agent-connector.md` under a file path. |
amazon-q | <projectDir>/.amazonq/rules/agent-connector.md | skip-warn | Dedicated rules-dir file AC owns (a marker-fenced managed block inside it). Amazon Q "will automatically use" plain Markdown files in .amazonq/rules as context (AWS context-project-rules docs) — no frontmatter. No verified user/global rules dir, so user scope skip-warns. |
continue | <projectDir>/.continue/rules/agent-connector.md | skip-warn | Dedicated rules-dir file AC owns end-to-end (install writes, uninstall deletes), leading with `alwaysApply: true` frontmatter — "always included, regardless of file context" (Continue rules docs). The user/global rules dir is unverified → user scope skip-warns. |
windsurf | <projectDir>/.windsurf/rules/agent-connector.md | skip-warn | Dedicated rules-dir file AC owns end-to-end, leading with `trigger: always_on` frontmatter — full content in the system prompt on every message (Windsurf Cascade rules docs). global_rules.md is a shared global file (not an AC-owned dir) → user scope skip-warns. |
Why HTML-comment markers are correct for CLAUDE.md
Claude Code strips HTML comments from CLAUDE.md before injecting it into the model's context — so the markers and the do-not-edit notice are invisible to Claude while remaining fully parseable by agent-connector for sync / doctor / uninstall. On AGENTS.md hosts (which inline the whole file into the prompt) the one-line notice doubles as an in-prompt "do not edit" instruction to the host's own agent.Validation rules#
- Each
namemust be kebab-case^[a-z0-9][a-z0-9-]*$; no duplicatenamewithin a single surface array. - Required non-empty strings: command
prompt; skilldescription+body; subagentdescription+prompt. - Skill
descriptionlength must be<= 1024(throws otherwise). - Skill
resourceskeys must be SAFE relative paths inside the skill dir — empty,., absolute, or any..-traversal key is rejected. - Memory
contentmust be non-empty; hardConnectorConfigErrorabove 16 KiB (it is injected into every prompt of every targeted host) or when it contains the literal marker tokensagent-connector:begin/agent-connector:end. A soft 4 KiB budget is an install-timewarn, not a config error.
Per-platform surface support#
Adapters that don't support a surface skip with a warning. <n> is the surface name; skills are uniformly folder-per-skill SKILL.md (only the parent dir differs per platform). Memory targets are listed separately under AGENTS.md-first above.
| Platform | command | skill | subagent |
|---|---|---|---|
claude-code | .claude/commands/<n>.md | .claude/skills/<n>/SKILL.md | .claude/agents/<n>.md |
gemini-cli | .gemini/commands/<n>.toml | .gemini/skills/<n>/SKILL.md | .gemini/agents/<n>.md |
qwen-code | .qwen/commands/<n>.toml | — | .qwen/agents/<n>.md |
vscode-copilot (+ jetbrains) | .github/prompts/<n>.prompt.md | .github/skills/<n>/SKILL.md | .github/agents/<n>.agent.md (vscode only — jetbrains skips+warns) |
copilot-cli | — | .github/skills/<n>/SKILL.md | ~/.copilot/agents/<n>.agent.md |
cursor | .cursor/commands/<n>.md (body-only) | .cursor/skills/<n>/SKILL.md | .cursor/agents/<n>.md |
codex | ~/.codex/prompts/<n>.md (user-only) | .codex/skills/<n>/SKILL.md | .codex/agents/<n>.toml |
opencode | .opencode/commands/<n>.md | .opencode/skills/<n>/SKILL.md | .opencode/agent/<n>.md |
kilo | .kilocode/commands/<n>.md | .kilo/skills/<n>/SKILL.md | .kilocode/agents/<n>.md |
pi | .pi/prompts/<n>.md | .pi/skills/<n>/SKILL.md | — |
antigravity (+ antigravity-cli) | .agent/workflows/<n>.md (project; user → ~/.gemini/antigravity/global_workflows/<n>.md) | .agents/skills/<n>/SKILL.md | — |
all others | — | — | — |