← Codebase Guide | ← Previous: Dashboard | Next: Maintainer Playbook →
Agent integrations should be thin adapters around Engram's Go behavior. Setup and plugin code may connect agents to MCP, sessions, hooks, and local API, but core memory semantics belong in Go.
Engram supports agents through MCP and through plugins that add lifecycle/session management.
Agent
│
├── Bare MCP
│ └── engram mcp --tools=agent
│
├── OpenCode plugin
│ ├── plugin/opencode/engram.ts
│ └── internal/setup setup opencode
│
├── Claude Code plugin
│ ├── plugin/claude-code/.claude-plugin/plugin.json
│ ├── plugin/claude-code/hooks/hooks.json
│ ├── plugin/claude-code/scripts/*.sh / *.ps1
│ └── plugin/claude-code/skills/memory/SKILL.md
│
└── Agent registry (declarative setup)
├── internal/setup/registry.go (generic injectMCP / writeInstruction driver)
└── internal/setup/agents.go (one data entry per agent)
internal/setup exposes a data-driven agent registry (agentAdapters() in
agents.go). Install() and SupportedAgents() are derived from it. Each entry
is either:
- bespoke — a
custominstaller for agents with special needs (OpenCode embeds a TS plugin, Pi runs a package manager, Claude Code drives theclaudeCLI, Codex writes TOML, Gemini CLI cleans up legacy env state), or - declarative — just an MCP path + format (
mcpServers/servers/ OpenCode'smcpobject) and instruction surfaces; the genericinjectMCP/writeInstructiondriver inregistry.godoes the writes. Antigravity CLI, Windsurf, Qwen, Kiro, Cursor, VS Code Copilot, Kilo Code, Kimi Code, and CommandCode are all declarative.
Adding a declarative agent is normally just a new entry in agentAdapters() plus
its path helpers — no new install code path. Agents not in the registry remain
manual MCP configs documented in docs/AGENT-SETUP.md.
Plugins may:
- start or find
engram serve, - create sessions,
- import chunks,
- inject the Memory Protocol,
- persist summaries on compaction,
- strip private tags,
- register MCP.
Plugins should not implement core memory semantics. If there is a dedupe, prompt capture, relation judgment, or project resolution rule, it must be in Go.
For per-agent details, use docs/AGENT-SETUP.md and docs/PLUGINS.md.
Adapters translate host runtime identity into an Engram session; they do not own persistence or decide which session an omitted ID should select.
| Adapter | Runtime-to-Engram mapping | Registration before identity use |
|---|---|---|
| Claude Code | SessionStart posts the host session_id with its resolved project and directory. |
SessionStart alone does not confirm registration. Before binding a classified Engram write/session tool, PreToolUse confirms project-owned registration for the host ID: a registered session is confirmed against its registered owner project (#1717), and only first registration derives the project from the cwd. Confirmation requires HTTP 201, matching id, and status: "created"; otherwise it denies the call with the cause the server reports. |
| Codex | Genuine startup/resume/clear registers with resume: true. Go validates HTTP 201, status: "created", and an exact root ID or numeric continuation with matching resumed_from. |
PreToolUse, prompt capture and post-compaction resolve the existing effective identity through /runtime-sessions/resolve, without registration. Failed confirmation blocks attributed writes and withholds the active protocol. Host closing uses /runtime-sessions/end; model mem_session_end is rewritten to the resolved effective ID for unchanged exact-ID MCP ending. No private identity map or raw-ID fallback is used. |
| OpenCode | The plugin follows authoritative parentID links to the root host session; child sessions do not own top-level Engram sessions. The core selects a live continuation when the root has ended. |
Before session-attributed tool writes it registers the root with resume: true, rechecks host ownership, and injects the acknowledged effective id as session_id. Injection requires an HTTP-success response with status: "created" and an id equal to the root or prefixed by <root>:resume:; missing or foreign acknowledgements block injection. |
Claude and Codex PreToolUse confirmation use a four-second total HTTP budget
by default for the session lookup followed by Claude's owner-bound registration
or Codex's health preflight, cwd project resolution and runtime resolution.
Set ENGRAM_HOOK_SESSION_CONFIRMATION_TIMEOUT in the hook process environment
to a positive Go duration (for example, 8s or 500ms) to override this budget.
Unset, blank, invalid, overflowed, zero, or negative values retain 4s.
All confirmation requests share the same deadline; there is no per-request reset.
If increasing the budget, also increase the host's configured PreToolUse timeout
so it exceeds the budget with headroom for process startup and verdict output.
The shipped host limits are five seconds for Claude and ten seconds for Codex;
this environment variable does not update either host configuration. For example,
an 8s confirmation budget needs an outer hook timeout greater than eight seconds.
This is a slow-server mitigation, not a fix for autosync latency or permission to
skip confirmation. A timeout still denies the call with
Claude host session confirmation timed out (server slow or unavailable) or
Codex host session confirmation timed out (server slow or unavailable).
Unexplained Claude failures use the registration-denial message;
server-explained denials name the reported cause (already ended,
session_project_conflict, or a first-registration project-resolution
failure) and Codex failures use
Codex host session resolution could not be confirmed, respectively.
Every gated call validates the response and the adapter's ownership requirements;
Claude confirms registration while Codex resolves the existing identity without
registering again. Neither guard caches confirmation or retries.
Codex prompt capture uses its separate, unchanged budget.
Parent/root translation is specific to OpenCode's session hierarchy, not a universal adapter rule. Hook-level binding cannot protect calls when a hook is skipped, bypassed, or timed out; independent direct/manual MCP saves remain outside these adapters. Go owns the HTTP session registration and persistence contract (Sessions), project/session validation and omitted-ID cardinality (Write tools: explicit/session/cwd project resolution).
internal/setup owns idempotent installation of implemented agent integrations. It should not promise automatic cloud bootstrap or login if that flow is still CLI-first and documented elsewhere.
- The plugin remains a thin adapter.
- Core behavior lives in Go, not duplicated shell/TypeScript.
- Setup is idempotent.
- Windows/macOS/Linux or documented paths remain correct.
-
docs/AGENT-SETUP.mdanddocs/PLUGINS.mdreflect the exact current flow. - Do not promise automatic cloud bootstrap if it is still CLI-first.