Interoperability¶
AgentTeams includes a dedicated interoperability feature family for moving or exposing agent infrastructure across frameworks without losing team intent.
Why This Exists¶
Real projects often need to:
- keep one framework as canonical source of truth,
- run the same team in a different runtime, or
- maintain compatibility interfaces for adjacent systems.
The interoperability family supports those workflows through three explicit modes.
Three Interoperability Modes¶
| Mode | CLI Entry | Primary Use | Source Canonical Docs |
|---|---|---|---|
| Format migration | --convert-from |
Rewrite an existing team into target framework format | Preserved prose, rewritten wrappers |
| CAI interop pipeline | --interop-from |
Normalize to canonical representation then emit target | Preserved prose + optional bundle artifacts |
| Lightweight bridge | --bridge-from |
Expose source team to a target runtime without full regeneration | Source remains canonical |
What Is The Difference?¶
Use this quick rule:
- Choose
--convert-fromwhen you want a direct one-step format migration from source framework files to target framework files. - Choose
--interop-fromwhen you want normalization through the Canonical Agent Interface (CAI) and optional interop bundle artifacts before/alongside target emission. - Choose
--bridge-fromwhen you want runtime compatibility entrypoints while keeping source agent documentation canonical and not fully regenerated.
Practical distinction:
--convert-fromchanges wrapper format around existing authored content.--interop-frompasses through a canonical representation layer designed for transport/inspection.--bridge-fromdoes not replace source docs; it creates a lightweight target-facing interface over them.
Mode A: Format Migration (--convert-from)¶
Use this when you want a target framework version of an existing team while preserving agent body prose.
agentteams \
--convert-from /path/to/source/agents \
--framework claude \
--output /path/to/project/.claude/agents
Behavior:
- Preserves agent body markdown.
- Rewrites front matter/wrapper format for target framework.
- Converts instructions naming (
copilot-instructions.md<->CLAUDE.md) as needed. - Non-dry-run writes run a live security freshness preflight before files are written; stale-intel blocks can only be bypassed via a valid signed waiver (
references/security-waivers.log.csv+AGENTTEAMS_WAIVER_SIGNING_KEY).
Mode B: CAI Interop Pipeline (--interop-from)¶
Use this when you want canonical normalization and optional compatibility bundle artifacts.
agentteams \
--interop-from /path/to/source/agents \
--framework copilot-cli \
--interop-mode bundle \
--output /path/to/project/.github/copilot
Modes:
direct: write target framework files only.bundle: write target framework files plus interoperability artifacts.- Both write modes enforce the same live security freshness preflight used by the main render path, including the same signed-waiver exception model.
Bundle artifacts are written under references/interop/<source>-to-<target>/ and include:
team-manifest.cai.jsoninterop-manifest.jsonrouting-map.jsoninstructions-map.jsoncompatibility-report.md
Grants: a projection never widens one¶
A source agent's tool grant is a binding capability declaration (C-3), so every projection path checks each
projected agent before anything is written (interop_grant_check):
--interop-from, the pinned sync (multi_sync, which first dry-runs every framework so a refusal aborts before
any is written) and --convert-from. The no-widening check (1) and goose grant mode (3) apply to all three; the
enforcement-class (2) and Copilot-size (5) refusals are --interop-from's.
- No widening. Each agent is rendered, then re-read the way the target surface reads it, platform defaults
included: Copilot adds
tools: ['read', 'edit', 'search']to a header without one, Claude inherits every tool whentoolsis missing, and a goose recipe withoutextensionsloads the user's configured extensions. The re-read tool scopes must be a subset of the source's, or the run refuses, naming the agent and the surface. On goose only,readandsearchcount as one class, because itsagentteams_readfsserver serves both. An unknown tool name fails closed: a projected name that maps to no canonical scope (Copilot'srunCommands, an MCP tool such asmcp__github__create_issue, an unrecognised goose extension) refuses the run unless the source agent declares the same name. The only exception is what the target's own brief grants: theagentteams_runnertools underwrite_policy: "orchestrator-only". -
Enforcement class. Each surface either enforces the grant, declares it, or has no channel for it:
Surface Class Notes claude,copilot-vscode,copilot-clienforced the toolsfront-matter keygooseenforced on a direct goose run --recipegrant-scoped extensions; a delegategets the delegator's extensions, so each recipe carries a banner saying socodexdeclared sandbox_modeand the tool list are self-imposed; enforced only under thewrite_policy: "orchestrator-only"role gateagents-mdnone no grant channel An agent whose grant is narrower than the surface default (any of read, search, edit, execute missing) is refused on a declared or none surface.
--interop-allow-cooperative SLUG[,SLUG...]lets the operator project named agents anyway: each gets a "grant is cooperative on this surface" banner and aNOT ENFORCEDnotice, and each opt-in is recorded (Rule 15) as one row in the destination team'sreferences/security-decisions.log.csv:action_reviewedinterop-allow-cooperative:<framework>:<slug>, verdictRECORDED(not an authorizing verdict, so it clears nothing), written in that log's own schema throughgovernance_logs.append_row, with theprev_digesta hash-chained log requires. Without that log the opt-in is refused, naming the missing file. 3. goose renders grant-scoped.read/searchmap to the read-onlyagentteams_readfsserver with anavailable_toolsallowlist, never to thedeveloperbuiltin.--interop-fromand the pinned sync don't install the server: run a native goose generation once soscripts/goose-readfs-mcp.pyexists. It must match the pinnedREADFS_SHA256(the hash the runner checks); a missing, linked or edited copy refuses the projection, naming the agents that need it.--convert-fromemits goose's own files, the server included. 4. codex gets canonical tool tokens when the source names Claude tools (Read, Grep, Globbecomesread,search), so the agent carriessandbox_mode = "read-only"and the "Reading on Codex" shell allowlist. Bespoke tool names stay verbatim. 5. Copilot size. A body over the platform's 30,000-character limit is refused on this path. Native generation only warns.
Not covered: goose bridge recipes (--bridge-from … --framework goose: the entry recipe and the subagent stubs)
still declare the whole developer builtin, because the stubs read their canonical agent through it.
Projecting into a governed team never weakens its signing switch or rosters: the projection marker keeps a
signing-governed switch on and writes rosters only when absent (projection_marker).
Project directly into the target surface; never copy scratch projection output into place.
The Durable Canonical Format (canonical)¶
canonical is a recognized value for --framework (as an interop target) and
--interop-source-framework (as a source) — an interop-only pseudo-framework, not a
rendering target. It writes/reads the durable exploded on-disk form of the CAI document
(default location <project>/.agentteams/canonical/):
team.cai.json— project-level data (schema version, instructions binding, MCP servers, framework-owned configuration, source metadata).agents/<slug>.md— human-editable Markdown with YAML front matter (canonical capability vocabulary + handoffs).skills/<slug>/SKILL.md— first-class skills with co-located files.references/**— carried non-agent reference content.
Export to canonical:
agentteams \
--interop-from /path/to/source/agents \
--interop-source-framework copilot-vscode \
--framework canonical \
--output /path/to/project/.agentteams/canonical
Import from canonical:
agentteams \
--interop-from /path/to/project/.agentteams/canonical \
--interop-source-framework canonical \
--framework claude \
--output /path/to/project/.claude/agents
Both dispatch through the same CAI pipeline and the same live security freshness preflight
as every other interop write path. --interop-mode keeps its existing two values and
meanings; bundle mode is refused for the canonical target (bundle artifacts would land
inside the canonical directory and corrupt its references/ tree on load). MCP servers
carried in a canonical team.cai.json re-validate against mcp-server.schema.json —
including the security_review hard gates — at import time, so a hand-edited weakening
fails re-import instead of silently round-tripping.
Mode C: Lightweight Bridge (--bridge-from)¶
Use this when you need target runtime entrypoints that reference source canonical infrastructure without regenerating source agent docs.
Bridge artifacts are written under references/bridges/<source>-to-<target>/:
bridge-manifest.jsonagent-inventory.mdquickstart-snippet.mdentrypoint.mddomain-boundary.md— clarifies the memory-index vector-mode boundary vs project-level retrieval-integrator contracts (so consumers don't conflate them).
The bridge also writes target-framework entry files (e.g. CLAUDE.md, .claude/* for claude target) at the output root. These writes are destructive under --bridge-refresh and non-destructive (fence-aware) under --bridge-merge.
Bridge freshness checks:
agentteams \
--bridge-from /path/to/source/agents \
--framework claude \
--output /path/to/project \
--bridge-check
--bridge-check is read-only: it verifies bridge freshness against the source manifest and does not perform the write-path security freshness preflight.
First Run vs Subsequent Refresh¶
| First time generating the bridge for a project | --bridge-refresh (creates target entry files from scratch) |
| Subsequent refresh after source agents change, consumer entry files have been customized | --bridge-merge (fence-aware non-destructive update) |
| Verifying freshness without writing | --bridge-check |
--bridge-refresh overwrites consumer CLAUDE.md / .claude/* with terse bridge-stub content. If your team has rich entry files, use --bridge-merge. Consumer-managed sections should live OUTSIDE the bridge's <!-- AGENTTEAMS-BRIDGE:BEGIN ... --> fences so the merge logic preserves them.
Canonical as a bridge source¶
canonical is also a recognized --bridge-source-framework value: point --bridge-from at
a canonical directory's root (the one holding team.cai.json, not its agents/ subdirectory
— pointing at the subdirectory misdetects as copilot-vscode) and the bridge reads
agents/*.md directly. --bridge-check against a canonical source covers both agents/*.md
and team.cai.json itself, so a hand-edit to instructions/MCP/framework-extension data (which
lives inside team.cai.json, not as sibling files) is caught, not just agent-file changes.
Generic bridge target — no native adapter required¶
--framework generic is a bridge-only target (pair with --bridge-from) for a consumer with
no agentteams framework adapter of its own. It emits only the framework-agnostic pair-dir
artifacts (manifest, inventory, quickstart, entrypoint, domain-boundary) — zero native consumer
entry files (no CLAUDE.md, no AGENTS.md). The generated quickstart points the consumer at
the durable canonical tree (.agentteams/canonical/, see above) as the fuller source of truth,
and at the exact command to generate one if it doesn't already exist alongside the bridge.
Portable team package (--package-team)¶
A durable canonical directory plus its generic bridge can also be packaged as one portable
.zip — see CLI Reference: Portable Team Package.
Standalone mode (mutually exclusive with all three modes above and every other standalone CLI
op), not part of the three interoperability modes proper: it composes Mode B's canonical export
with Mode C's generic-target bridge into one distributable artifact rather than adding a fourth
mode of its own.
Directional Coverage¶
All seven registered frameworks are valid CAI interop sources and targets (durable-canonical-agent-format plan, Phase F):
copilot-vscodecopilot-cliclaudegooseagents-mdcodex(custom agents as.codex/agents/<slug>.toml; AGENTS.md rendering shared with agents-md)grok(Grok Build custom agents as.grok/agents/<slug>.md; the repo-root AGENTS.md is written only through Grok's co-ownership guard, and a narrowed agent needs--interop-allow-cooperativebecause Grok does not enforce grants)
Round-trip fidelity is exact where a target has an equivalent concept and honestly
degraded where it doesn't — surfaced via compatibility-report.md in bundle mode, never
silently. Notes per framework:
gooserecipes capture title/description/instructions plus recipe-level configuration (recipe_parameters/recipe_response/recipe_retry, builtin extension scoping) through the CAIframework_extensions.goosebucket; handoffs round-trip assub_recipes(true delegation) andload(...)context references.agents-mdsources carry no front matter, so capabilities/handoffs land inferred-or-empty on export (best-effort by nature).codexsources (.codex/agents/*.toml) round-trip name, description, tools and handoffs through each agent'scodex_translationblock.canonicaladditionally serves as the durable intermediate: any framework can export to it and import back from it with near-lossless fidelity (see the canonical section above). Modeled fields (name, description, body, capabilities/handoffs, skills, MCP servers) round-trip exactly; framework-specific keys not yet modeled travel through theraw_front_matterandcapabilities.rawescape hatches so they are preserved rather than silently dropped. Known remaining coarseness (documented per framework incapability_map.py's module docstring) is surfaced, not hidden.
Convert (--convert-from) and bridge (--bridge-from) coverage is narrower than interop:
goose is a convert/bridge target, while agents-md/codex remain generate-only for those
two paths (their interop support is the CAI path). See the
CLI Reference feature-support matrix for the
per-path detail.
Automation Support¶
Bridge automation is available through repository workflows:
.github/workflows/bridge-maintenance.ymlfor scheduled bridge refresh and check operations..github/workflows/bridge-watchdog.ymlfor stale-run monitoring and issue escalation.
API Reference Links¶
For module-level API details, see: