This document provides a comprehensive comparison of all platforms supported by context-mode, including their hook paradigms, capabilities, configuration, and known limitations.
context-mode supports 17 client platforms, plus the OpenClaw gateway integration, across three hook paradigms:
| Paradigm | Platforms |
|---|---|
| JSON stdin/stdout | Claude Code, Gemini CLI, VS Code Copilot, JetBrains Copilot, GitHub Copilot CLI, Cursor, Codex CLI, Qwen Code, Kimi Code, Antigravity CLI (agy), Kiro |
| TS Plugin | OpenCode, KiloCode, OpenClaw |
| MCP-only | Antigravity, Zed, Pi, OMP (Oh My Pi) |
The MCP server layer is 100% portable and needs no adapter. Only the hook layer requires platform-specific adapters.
All platforms (except Claude Code plugin install) require a global install:
npm install -g context-modeThis puts the context-mode binary in PATH, which is required for:
- MCP server:
"command": "context-mode"(replaces ephemeralnpx -y context-mode) - Hook dispatcher:
context-mode hook <platform> <event>(replacesnode ./node_modules/...paths) - Utility commands:
context-mode doctor,context-mode upgrade - Persistent upgrades:
ctx-upgradeupdates the global binary in-place
| Feature | Claude Code | Qwen Code | Gemini CLI | VS Code Copilot | JetBrains Copilot | GitHub Copilot CLI | Cursor | OpenCode | KiloCode | OpenClaw | Codex CLI | Kimi Code | Antigravity | Antigravity CLI (agy) |
Kiro | Zed | Pi | OMP |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Paradigm | json-stdio | json-stdio | json-stdio | json-stdio | json-stdio | json-stdio | json-stdio | ts-plugin | ts-plugin | ts-plugin | json-stdio | json-stdio | mcp-only | json-stdio | json-stdio | mcp-only | mcp-only | mcp-only |
| PreToolUse equivalent | PreToolUse |
PreToolUse |
BeforeTool |
PreToolUse |
PreToolUse |
preToolUse |
preToolUse |
tool.execute.before |
tool.execute.before |
tool_call:before |
PreToolUse |
PreToolUse |
-- | PreToolUse (bounded) |
preToolUse |
-- | -- | -- |
| PostToolUse equivalent | PostToolUse |
PostToolUse |
AfterTool |
PostToolUse |
PostToolUse |
postToolUse |
postToolUse |
tool.execute.after |
tool.execute.after |
tool_call:after |
PostToolUse |
PostToolUse |
-- | PostToolUse (capture-only) |
postToolUse |
-- | -- | -- |
| PreCompact equivalent | PreCompact |
PreCompact |
PreCompress |
PreCompact |
PreCompact |
preCompact |
-- | experimental.session.compacting |
experimental.session.compacting |
registerContextEngine |
-- | PreCompact |
-- | -- | -- | -- | -- | -- |
| SessionStart | SessionStart |
SessionStart |
SessionStart |
SessionStart |
SessionStart |
sessionStart |
-- (buggy in Cursor) | -- | -- | command:new |
SessionStart |
SessionStart |
-- | -- | -- | -- | -- | -- |
| Stop equivalent | -- | -- | -- | Stop |
Stop |
agentStop |
stop |
-- | -- | -- | Stop |
Stop |
-- | Stop (best-effort, unverified on agy 1.0.6) |
-- | -- | -- | -- |
| Can modify args | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | -- | -- | -- | -- | -- | -- |
| Can modify output | Yes | Yes | Yes | Yes | Yes | No | No | Yes (caveat) | Yes (caveat) | No | No | Yes | -- | -- | -- | -- | -- | -- |
| Can inject session context | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | -- | Yes | Yes | Yes | -- | -- | -- | -- | -- | -- |
| Can block tools | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes (throw) | Yes (throw) | Yes | Yes | Yes | -- | Bounded | Yes | -- | -- | -- |
| Config location | ~/.claude/settings.json |
~/.qwen/settings.json |
~/.gemini/settings.json |
.github/hooks/*.json |
.github/hooks/*.json |
~/.copilot/hooks/context-mode.json + ~/.copilot/mcp-config.json |
.cursor/hooks.json or ~/.cursor/hooks.json |
opencode.json |
kilo.json |
openclaw.json |
~/.codex/hooks.json + ~/.codex/config.toml |
~/.kimi-code/config.toml |
~/.gemini/antigravity/mcp_config.json |
~/.gemini/config/mcp_config.json + ~/.gemini/config/hooks.json |
~/.kiro/settings/mcp.json |
~/.config/zed/settings.json |
~/.pi/settings.json |
~/.omp/agent/mcp_config.json |
| Session ID field | session_id |
session_id |
session_id |
sessionId (camelCase) |
sessionId (camelCase) |
session_id (snake_case; sessionId defensive fallback) |
conversation_id |
sessionID (camelCase) |
sessionID (camelCase) |
pid-${ppid} fallback |
N/A | session_id |
N/A | conversationId (unverified) |
pid-${ppid} fallback |
N/A | N/A | N/A |
| Project dir env | CLAUDE_PROJECT_DIR |
QWEN_PROJECT_DIR |
GEMINI_PROJECT_DIR |
CLAUDE_PROJECT_DIR |
CLAUDE_PROJECT_DIR |
stdin cwd |
stdin workspace_roots |
ctx.directory (plugin init) |
ctx.directory (plugin init) |
process.cwd() |
N/A | stdin cwd |
N/A | stdin workspace.current_dir (refs-backed; workspacePaths[0] fallback) |
stdin cwd |
N/A | N/A | OMP_PROCESSING_AGENT_DIR |
| MCP/tool naming | mcp__server__tool |
mcp__server__tool |
mcp__server__tool |
f1e_ prefix |
f1e_ prefix |
mcp__server__tool |
MCP:<tool> in hook payloads |
native ctx_* plugin tools |
native ctx_* plugin tools |
native ctx_* plugin tools |
mcp__server__tool |
mcp__context-mode__tool |
mcp__server__tool |
context-mode/<tool> |
mcp__server__tool |
mcp__server__tool |
mcp__server__tool |
mcp__server__tool |
| Hook command format | context-mode hook claude-code <event> |
context-mode hook qwen-code <event> |
context-mode hook gemini-cli <event> |
context-mode hook vscode-copilot <event> |
context-mode hook jetbrains-copilot <event> |
context-mode hook copilot-cli <event> |
context-mode hook cursor <event> |
TS plugin (no command) | TS plugin (no command) | TS plugin (no command) | context-mode hook codex <event> |
context-mode hook kimi <event> |
N/A | context-mode hook antigravity-cli <event> |
context-mode hook kiro <event> |
N/A | N/A | N/A |
| Hook registration | settings.json hooks object | settings.json hooks object | settings.json hooks object | .github/hooks/*.json |
.github/hooks/*.json |
~/.copilot/hooks/context-mode.json (version: 1) |
hooks.json native hook arrays |
opencode.json plugin array | kilo.json plugin array | openclaw.json plugins.entries |
~/.codex/hooks.json |
config.toml hooks array |
N/A | plugin root hooks.json (PreToolUse, PostToolUse, Stop; bundle mirrors hooks/hooks.json for agy validate/install) |
Kiro CLI hooks (JSON stdin) | N/A | N/A | N/A |
| MCP server command | context-mode (or plugin auto) |
context-mode |
context-mode |
context-mode |
context-mode |
context-mode |
context-mode |
N/A (native plugin tools) | N/A (native plugin tools) | N/A (native plugin tools) | context-mode |
context-mode |
context-mode |
context-mode |
context-mode |
context-mode |
context-mode |
context-mode |
| Plugin distribution | Claude plugin registry | npm global | npm global | npm global | npm global | npm global | npm global | npm global | npm global | npm global | npm global | npm global | npm global | agy plugin (npm global) | npm global | npm global | npm global | npm global |
| Session dir | ~/.claude/context-mode/sessions/ |
~/.qwen/context-mode/sessions/ |
~/.gemini/context-mode/sessions/ |
.github/context-mode/sessions/ or ~/.vscode/context-mode/sessions/ |
.github/context-mode/sessions/ |
~/.copilot/context-mode/sessions/ |
~/.cursor/context-mode/sessions/ |
~/.config/opencode/context-mode/sessions/ |
~/.config/kilo/context-mode/sessions/ |
~/.openclaw/context-mode/sessions/ |
~/.codex/context-mode/sessions/ |
~/.kimi-code/context-mode/sessions/ |
~/.gemini/context-mode/sessions/ |
~/.gemini/context-mode/sessions/ |
~/.kiro/context-mode/sessions/ |
~/.config/zed/context-mode/sessions/ |
~/.pi/context-mode/sessions/ |
~/.omp/context-mode/sessions/ |
- Yes = Fully supported
- -- = Not supported
- (caveat) = Supported with known issues
Status: Fully supported (primary platform)
Hook Paradigm: JSON stdin/stdout
Claude Code is the primary platform for context-mode. All hooks communicate via JSON on stdin/stdout. The adapter reads raw JSON input, normalizes it into platform-agnostic events, and formats responses back into Claude Code's expected output format.
Hook Names:
PreToolUse-- fires before a tool is executedPostToolUse-- fires after a tool completesPreCompact-- fires before context compactionSessionStart-- fires when a session starts, resumes, or compactsUserPromptSubmit-- fires when user submits a promptStop-- fires when the assistant turn is about to end
Blocking: permissionDecision: "deny" in response JSON
Arg Modification: updatedInput field at top level of response
Output Modification: updatedMCPToolOutput for MCP tools, additionalContext for appending
Session ID Extraction Priority:
- UUID from
transcript_pathfield session_idfieldCLAUDE_SESSION_IDenvironment variable- Parent process ID fallback
Hook Commands:
context-mode hook claude-code pretooluse
context-mode hook claude-code posttooluse
context-mode hook claude-code precompact
context-mode hook claude-code sessionstart
context-mode hook claude-code userpromptsubmit
Known Issues: None significant.
Status: Fully supported
Hook Paradigm: JSON stdin/stdout
Gemini CLI uses the same JSON stdin/stdout paradigm as Claude Code but with different hook names and response format.
Hook Names:
BeforeTool-- equivalent to PreToolUseAfterTool-- equivalent to PostToolUsePreCompress-- equivalent to PreCompact (advisory only, async, cannot block)SessionStart-- fires when a session starts
Blocking: decision: "deny" in response (NOT permissionDecision)
Arg Modification: hookSpecificOutput.tool_input (merged with original, not updatedInput)
Output Modification: decision: "deny" + reason replaces output; hookSpecificOutput.additionalContext appends
Environment Variables:
GEMINI_PROJECT_DIR-- primary project directoryCLAUDE_PROJECT_DIR-- alias (also works)
Hook Commands:
context-mode hook gemini-cli beforetool
context-mode hook gemini-cli aftertool
context-mode hook gemini-cli precompress
context-mode hook gemini-cli sessionstart
Known Issues / Caveats:
PreCompressis advisory only (async, cannot block)- No
decision: "ask"support - Hooks don't fire for subagents yet
Status: Fully supported
Hook Paradigm: TS Plugin
OpenCode uses a TypeScript plugin paradigm instead of JSON stdin/stdout. Hooks and the 11 ctx_* tools are registered via the plugin array in opencode.json; no separate mcp block or stdio MCP child is required.
Hook Names:
tool.execute.before-- equivalent to PreToolUsetool.execute.after-- equivalent to PostToolUseexperimental.session.compacting-- equivalent to PreCompact (experimental)experimental.chat.system.transform-- SessionStart-equivalent (cross-session resume injection)
Blocking: throw Error in tool.execute.before handler
Arg Modification: output.args mutation
Output Modification: output.output mutation (TUI bug for bash, see issue #13575)
Session ID: input.sessionID (camelCase, note the uppercase ID)
Project Directory: Available via ctx.directory in plugin init, not via environment variable
Desktop markers: OpenCode desktop shells also export OPENCODE_CLIENT=desktop and OPENCODE_TERMINAL=1; context-mode treats those as OpenCode identity signals when the CLI markers are absent.
Configuration:
opencode.jsonor.opencode/opencode.json- Plugin registered in the
pluginarray with npm package names ctx_*tools are native plugin tools, notmcp__server__toolcalls- KiloCode uses the same plugin path via
kilo.json;context-mode upgraderemoves stalemcp.context-modeentries for both hosts while preserving other MCP servers
Cross-session resume:
When OpenCode triggers experimental.session.compacting (auto on context overflow OR manual /compact), context-mode saves a snapshot to its per-project SQLite store. The NEXT new session in the same project — typically after Ctrl+D then re-running opencode, or starting a fresh chat — claims that snapshot via experimental.chat.system.transform and prepends it to system[1] (preserves OpenCode's [header, body] cache fold). The current session never claims its OWN snapshot back (self-injection guard, v1.0.106). To verify the injection landed, run with OPENCODE_DEBUG=1 and grep for <!-- context-mode v in the system prompt — that's the visible marker.
Known Issues / Caveats:
- SessionStart is broken (issue #14808, no hook issue #5409) — we use
experimental.chat.system.transformas a surrogate - Output modification has TUI rendering bug for bash tool (issue #13575)
experimental.session.compactingis marked experimental and may change- No
canInjectSessionContextcapability - Resume snapshots are scoped per-project (DB sharded by SHA-256 of
ctx.directory); no cross-project bleed
Status: Supported (MCP active, hooks require [features].hooks = true)
Hook Paradigm: JSON stdin/stdout
Codex CLI's Rust backend (codex-rs) includes a hook system using the same JSON stdin/stdout wire protocol as Claude Code. Hooks are configured via hooks.json.
Hook Names:
PreToolUse-- fires before a tool is executedPostToolUse-- fires after a tool completesPreCompact-- fires before context compaction on Codex builds that emit itSessionStart-- fires when a session starts, resumes, or clearsUserPromptSubmit-- fires when user submits a promptStop-- fires when agent turn ends (can continue with followup)
Blocking: permissionDecision: "deny" in hookSpecificOutput, or exit code 2
Arg Modification: NOT supported (updatedInput returns error)
Output Modification: NOT supported (updatedMCPToolOutput returns error)
Context Injection: additionalContext in hookSpecificOutput (PostToolUse, SessionStart only). PreToolUse does NOT support additionalContext — the codex formatter handles this automatically (deny works, context/modify/ask responses are dropped).
Configuration:
- Hook config:
$CODEX_HOME/hooks.jsonor~/.codex/hooks.json(JSON format, same structure as Claude Code) - MCP config:
$CODEX_HOME/config.tomlor~/.codex/config.toml(TOML format,[mcp_servers]section) - Feature flags: use
[features].hooks(orcodex --enable hooks) if you need to force hooks on. Prefer[features].hooks;[features].codex_hooksremains accepted as a legacy alias in current Codex builds.
Hook Commands:
context-mode hook codex pretooluse
context-mode hook codex posttooluse
context-mode hook codex precompact
context-mode hook codex sessionstart
context-mode hook codex userpromptsubmit
context-mode hook codex stop
Known Issues / Caveats:
-
PreToolUse
additionalContextis unsupported — context injection works via PostToolUse and SessionStart instead. The codex formatter handles this automatically (deny works, context is dropped). Source:codex-rs/hooks/src/engine/output_parser.rs:267. -
PreToolUse input rewriting still needs upstream
updatedInputsupport. Track: openai/codex#18491. -
PreCompact support is runtime-gated: context-mode configures it and treats a missing registration as a warning, because older Codex builds may not emit the event. The hook stores the resume snapshot out-of-band and SessionStart restores it.
-
Codex emits structured tool names such as
Bashandapply_patch; context-mode only normalizes legacy shell aliases. -
updatedInput and updatedMCPToolOutput are in the schema but NOT implemented
-
Default hook timeout: 600 seconds
-
Older context-mode releases used a
plugins/context-mode -> ..symlink shim because Codex rejects the repository root ("./") as an empty local plugin source path. On native Windows, Git can check that symlink out as a regular file containing only.., which makescodex plugin add context-mode@context-modefail withmissing plugin.json. Current releases avoid this by declaring the Codex marketplace plugin as a relative Git source (url: "./"), so Codex materializes the installed marketplace root and finds.codex-plugin/plugin.jsonwithout any symlink or junction.After installation succeeds, verify that Codex hooks are enabled in
%USERPROFILE%\.codex\config.toml:[features] hooks = true
Some Codex builds may also require
plugin_hooks = true. Without hook support, the MCP tools can still work, but automatic session capture and persistent memory may not record events.
Status: Supported (JSON stdin/stdout hooks + MCP)
Hook Paradigm: JSON stdin/stdout
Kimi Code CLI uses the same JSON stdin/stdout wire protocol as Claude Code and Codex, configured via ~/.kimi-code/config.toml with [[hooks]] array tables. The key difference from Codex is that Kimi accepts additionalContext, updatedInput, and permissionDecision: "ask" in PreToolUse responses — the codex formatter drops these, but the kimi formatter emits them fully.
Hook Names:
PreToolUse— fires before a tool is executedPostToolUse— fires after a tool completesPreCompact— fires before context compactionSessionStart— fires when a session starts or resumesUserPromptSubmit— fires when user submits a prompt (payload isContentPart[])Stop— fires when the agent turn ends
Blocking: permissionDecision: "deny" in hookSpecificOutput, or exit code 2
Arg Modification: updatedInput inside hookSpecificOutput wrapper
Output Modification: additionalContext inside hookSpecificOutput
Context Injection: additionalContext in hookSpecificOutput (works in all hook types)
Configuration:
- Hooks:
~/.kimi-code/config.toml([[hooks]]array tables) - MCP:
~/.kimi-code/mcp.json - Sessions:
~/.kimi-code/context-mode/sessions/
Hook Commands:
context-mode hook kimi pretooluse
context-mode hook kimi posttooluse
context-mode hook kimi precompact
context-mode hook kimi sessionstart
context-mode hook kimi userpromptsubmit
context-mode hook kimi stop
Known Issues / Caveats:
UserPromptSubmitsendspromptas aContentPart[]array; the kimi hook normalizes this to a string for downstream extractors.- SessionStart
additionalContextinjection is emitted but acceptance by the host is not documented in Kimi Code CLI docs (fails-open if unsupported).
Status: Supported (MCP + hooks — identical wire protocol to Claude Code)
Hook Paradigm: JSON stdin/stdout (same as Claude Code)
Qwen Code (by Alibaba/Qwen team) uses the exact same hook wire protocol as Claude Code, verified from source (hookRunner.ts, claude-converter.ts). Hooks are configured inside ~/.qwen/settings.json under the hooks key.
Hook Names: PreToolUse, PostToolUse, SessionStart, PreCompact, UserPromptSubmit (Qwen supports 12 events total, context-mode uses these 5)
Blocking: permissionDecision: "deny" or exit code 2
Arg Modification: updatedInput in response
Output Modification: updatedMCPToolOutput in response
Context Injection: additionalContext in response
Configuration:
- Settings + hooks:
~/.qwen/settings.json - MCP:
mcpServersin settings.json - Sessions:
~/.qwen/context-mode/sessions/
Detection: MCP clientInfo (qwen-cli-mcp-client-* pattern), QWEN_PROJECT_DIR env var, or ~/.qwen/ config dir.
Hook Commands:
context-mode hook qwen-code pretooluse
context-mode hook qwen-code posttooluse
context-mode hook qwen-code sessionstart
context-mode hook qwen-code precompact
context-mode hook qwen-code userpromptsubmit
Status: MCP-only (no hooks)
Hook Paradigm: MCP-only
Google Antigravity is an AI-powered IDE by Google/DeepMind. It shares the ~/.gemini/ directory structure with Gemini CLI but uses a separate config path for MCP servers. Antigravity does not expose a public hook API — only MCP integration is available.
Configuration:
~/.gemini/antigravity/mcp_config.json(JSON format)- MCP servers configured in
mcpServersobject
Detection:
- Auto-detected via MCP protocol handshake (
clientInfo.name: "antigravity-client") - Fallback:
CONTEXT_MODE_PLATFORM=antigravityenvironment variable override
Routing Instructions:
GEMINI.mdauto-written at project root on first MCP server startup- Antigravity reads
GEMINI.mdnatively (same filename as Gemini CLI, different content — no hook references)
Capabilities:
- PreToolUse: --
- PostToolUse: --
- PreCompact: --
- SessionStart: --
- Can modify args: --
- Can modify output: --
- Can inject session context: --
Known Issues / Caveats:
- No hook support — only routing instruction files for enforcement (~60% compliance)
- Shares
~/.gemini/directory with Gemini CLI — session DB uses project hash to prevent collision - No verified Antigravity-specific environment variables exist
Sources:
- Config path: Gemini CLI Issue #16058
- MCP support: Antigravity MCP docs
- clientInfo: Apify MCP Client Capabilities Registry
Status: Plugin — MCP + routing rule + routing skill + bounded hooks
Hook Paradigm: MCP for tools + JSON stdin/stdout hooks
The standalone Antigravity CLI (agy) is the command-line companion to Google Antigravity. Unlike the Antigravity IDE, agy has a native plugin system (agy plugin install|import) and a hook surface (~/.gemini/config/hooks.json). context-mode ships as a first-class agy plugin (configs/antigravity-cli/) bundling the MCP server, a routing rule, a routing skill, and bounded PreToolUse/PostToolUse/Stop hooks. It shares the ~/.gemini/ session root with the rest of the Gemini family; agy reads its global MCP profile from ~/.gemini/config/mcp_config.json (not the IDE's ~/.gemini/antigravity/mcp_config.json).
Verified: agy 1.0.10 (Linux). The GitHub-subpath install requires agy ≥ 1.0.7 (subpath + branch resolution landed in 1.0.7 — run agy update to upgrade). No agy hook event was added, removed, or renamed through 1.0.10, and the shared ~/.gemini/config/hooks.json location has been canonical since agy 1.0.8, so the bundle's PreToolUse/PostToolUse/Stop wiring is current.
Install:
npm install -g context-mode(the plugin's MCP server + hooks run thecontext-modebinary), thenagy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli. agy clones the repo, resolves theconfigs/antigravity-clisubpath (with branch resolution), and registers the bundle's nativeplugin.json+mcp_config.json, routing rule, routing skill, and hooks into its plugin profile under~/.gemini/config/plugins/context-mode/. Ifctx_*tools don't appear after an upgrade, clear agy's stale tool-schema cache (~/.gemini/antigravity-cli/mcp/context-mode/) and restart agy (agy caches MCP schemas and doesn't refresh them).- Already on Claude Code:
agy plugin import claudecan import that existing Claude setup, but the native context-mode agy bundle above is the supported path for agy hooks. - MCP only: add context-mode to
~/.gemini/config/mcp_config.jsonundermcpServers({"command":"context-mode"}).
Detection:
- MCP protocol handshake (
clientInfo.name: "agy"/"antigravity-cli") - Config-dir markers for a bare shell:
~/.local/bin/agy,~/.gemini/antigravity-cli/, or~/.gemini/config/mcp_config.json— probed before the generic~/.claude/~/.geminifallbacks so a gemini-cli→agy migrant is not mis-detected as Claude Code (#774) - Fallback:
CONTEXT_MODE_PLATFORM=antigravity-clioverride
Hook payload: the only refs-backed field is the working directory, read from workspace.current_dir — an object field, per the upstream hook example (refs/platforms/antigravity-cli/examples/title/title.sh:10, examples/title/README.md:11). context-mode reads workspace.current_dir FIRST for the project dir, falling back to workspacePaths[0]. The remaining payload shape — { conversationId, stepIdx, toolCall: { name, args }, error, workspacePaths: [..], transcriptPath } — is empirically-derived/unverified (no upstream agy doc confirms it) and is treated as best-effort. The event name arrives via argv (set in hooks.json), and the hook CWD is ~/.gemini/config. context-mode maps these onto its routing/capture pipeline (workspace.current_dir/workspacePaths[0]→project dir, conversationId→session id [unverified], run_command→Bash, view_file→Read, grep_search→Grep, list_dir→LS, read_url_content→WebFetch, search_web→WebSearch).
Capabilities:
- PreToolUse: bounded blocking for mapped Bash/Read/Grep/WebFetch surfaces (
run_command,view_file,grep_search,web_fetch,read_url_content) - PostToolUse: capture-only (records executed tool calls into the session DB)
- Stop: best-effort capture-only session-end marker (registered, but not observed in agy
-pprobes) - PreCompact / SessionStart / PreInvocation / PostInvocation: -- (not wired)
- Can modify args / output / inject context: -- (not verified/used)
Known Issues / Caveats:
- Bounded hook enforcement. context-mode registers PreToolUse only for mapped high-flood tools with existing routing branches.
list_dirandsearch_webare normalized for PostToolUse capture but are not PreToolUse-routed. PreInvocationandPostInvocationare visible in agy's hook list but intentionally not registered; agy 1.0.6-pprobes did not emit them, and their payload/response semantics are not verified against context-mode's pipeline.- agy's
PostToolUsepayload carries no tool-output text, so byte-accounting for tool output is unavailable on this surface; the tool call + project + error state are still captured. - Shares
~/.gemini/with Gemini CLI and Antigravity — session DB uses the project hash to prevent collisions. - Gemini function-calling tool exposure. agy exposes MCP tools as Gemini function declarations, and Gemini's API rejects JSON Schema
const/additionalProperties— a rejected schema makes agy silently drop that tool from the model's function list (the agent then hand-rolls the tool via shell scripts instead of calling it). context-mode emits Gemini-safe tool schemas (const→enum,additionalPropertiesstripped) so thectx_*tools are exposed. agy also caches each server's tool schemas under~/.gemini/antigravity-cli/mcp/<server>/and does not refresh them on reconnect, so a cache captured by an older context-mode keeps the tools hidden — delete~/.gemini/antigravity-cli/mcp/context-mode/and restart agy to force a re-fetch.
Status: Supported (MCP + native PreToolUse/PostToolUse hooks)
Hook Paradigm: JSON stdin/stdout
Kiro is an AWS agentic IDE and CLI. It supports MCP servers via ~/.kiro/settings/mcp.json using the standard mcpServers JSON format. The Kiro CLI also fires preToolUse/postToolUse hooks over JSON stdin (exit code 2 blocking), which context-mode's kiro adapter implements for routing enforcement and tool-event capture. agentSpawn (the Kiro SessionStart equivalent) and stop are not yet wired, so session restore after compaction is not available.
Detection:
- Auto-detected via MCP protocol handshake (
clientInfo.name: "Kiro CLI")
Configuration:
- Global:
~/.kiro/settings/mcp.json(JSON format, standardmcpServersobject) - Project:
.kiro/settings/mcp.json
Routing Instructions:
KIRO.mdwritten at project root on first MCP server startup
Hook System:
preToolUse/postToolUsehooks via JSON stdin (implemented)- Blocking: exit code 2 (similar to Gemini CLI pattern)
agentSpawn(SessionStart equivalent) andstopare not yet wired
Hook Commands:
context-mode hook kiro pretooluse
context-mode hook kiro posttooluse
Built-in Tools:
fs_read/read,fs_write/write,execute_bash/shell,use_aws/aws
Capabilities:
- PreToolUse: Yes
- PostToolUse: Yes
- PreCompact: --
- SessionStart: -- (
agentSpawnnot yet wired) - Can modify args: --
- Can modify output: --
- Can inject session context: -- (via
agentSpawn, not yet wired) - Can block tools: Yes (exit code 2)
Known Issues / Caveats:
agentSpawn(SessionStart) andstopare not yet wired, so session restore after compaction is unavailable — copyKIRO.mdto the project root for session-start routing- Kiro IDE hooks use a UI-based "Run Command" shell action; stdin format unverified
Sources:
- clientInfo.name: Kiro GitHub Issue #5205
- MCP config: Kiro MCP Configuration docs
- CLI hooks: Kiro CLI Hooks docs
Status: Fully supported (preview)
Hook Paradigm: JSON stdin/stdout
VS Code Copilot uses the same JSON stdin/stdout paradigm as Claude Code with PascalCase hook names. It also provides unique hooks for subagent lifecycle.
Hook Names:
PreToolUse-- fires before a tool is executedPostToolUse-- fires after a tool completesPreCompact-- fires before context compactionSessionStart-- fires when a session startsStop-- fires when agent stops (unique to VS Code)SubagentStart-- fires when a subagent starts (unique to VS Code)SubagentStop-- fires when a subagent stops (unique to VS Code)
Blocking: permissionDecision: "deny" (same as Claude Code)
Arg Modification: updatedInput inside hookSpecificOutput wrapper (NOT flat like Claude Code)
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"updatedInput": { ... }
}
}Output Modification: additionalContext inside hookSpecificOutput, or decision: "block" + reason
MCP Tool Naming: Uses f1e_ prefix (not mcp__server__tool)
Session ID: sessionId (camelCase, not session_id)
Configuration:
- Primary:
.github/hooks/*.json - Also reads:
.claude/settings.json - MCP config:
.vscode/mcp.json
Environment Detection:
VSCODE_PIDenvironment variableTERM_PROGRAM=vscode
Hook Commands:
context-mode hook vscode-copilot pretooluse
context-mode hook vscode-copilot posttooluse
context-mode hook vscode-copilot precompact
context-mode hook vscode-copilot sessionstart
Known Issues / Caveats:
- Preview status -- API may change without notice
- Matchers are parsed but IGNORED (all hooks fire on all tools)
- Tool input property names use camelCase (
filePathnotfile_path) - Response must be wrapped in
hookSpecificOutputwithhookEventName
Status: Fully supported (preview)
Hook Paradigm: JSON stdin/stdout
JetBrains Copilot (GitHub Copilot plugin for JetBrains IDEs) uses the same JSON stdin/stdout paradigm and hook wire protocol as VS Code Copilot. It shares hook names, response format, and MCP tool naming conventions.
Hook Names:
PreToolUse-- fires before a tool is executedPostToolUse-- fires after a tool completesPreCompact-- fires before context compactionSessionStart-- fires when a session startsStop-- fires when agent stopsSubagentStart-- fires when a subagent startsSubagentStop-- fires when a subagent stops
Blocking: permissionDecision: "deny" (same as VS Code Copilot)
Arg Modification: updatedInput inside hookSpecificOutput wrapper (same as VS Code Copilot)
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"updatedInput": { ... }
}
}Output Modification: additionalContext inside hookSpecificOutput, or decision: "block" + reason
MCP Tool Naming: Uses f1e_ prefix (same as VS Code Copilot)
Session ID: sessionId (camelCase)
Configuration:
- Hook config:
.github/hooks/*.json - MCP config: Settings UI (Settings > Tools > AI Assistant > MCP)
Hook Commands:
context-mode hook jetbrains-copilot pretooluse
context-mode hook jetbrains-copilot posttooluse
context-mode hook jetbrains-copilot precompact
context-mode hook jetbrains-copilot sessionstart
Known Issues / Caveats:
- Preview status -- API may change without notice
- Shares the same hook wire protocol as VS Code Copilot
- MCP servers are configured via Settings UI, not a file
- Requires GitHub Copilot plugin v1.5.57+
Status: Supported (native hooks + MCP)
Hook Paradigm: JSON stdin/stdout
The standalone GitHub Copilot CLI (copilot) is user-home rooted under ~/.copilot (override with COPILOT_HOME). Its hook config uses camelCase event keys, and its command output contract is top-level (permissionDecision, modifiedArgs, additionalContext) rather than the VS Code hookSpecificOutput wrapper — context-mode's copilot-cli adapter formats responses accordingly.
Hook config keys: (Copilot CLI 1.0.59 fires six events context-mode uses; verified against the @github/copilot binary)
preToolUse-- fires before a tool is executedpostToolUse-- fires after a tool completespreCompact-- fires before context compactionsessionStart-- fires when a session startsuserPromptSubmitted-- fires when the user submits a prompt (user-prompt capture)agentStop-- fires when the agent stops (session-end capture)
Hook config shape: flat { "type": "command", "command": "..." } entries (NOT the Claude-Code nested { matcher, hooks: [...] } shape). context-mode also writes a top-level "version": 1, but this field is optional — the Copilot CLI accepts hook config files that omit it (copilot-cli changelog.md:1109). We pin it for self-documentation, not because the runtime requires it.
Blocking: top-level permissionDecision: "deny" + permissionDecisionReason
Arg Modification: top-level modifiedArgs
Output Modification: not supported (the posttooluse hook is capture-only)
Context Injection: top-level additionalContext — SessionStart is the confirmed channel (verified reaching the model). PreToolUse/PostToolUse additionalContext is best-effort/unverified; context-mode's posttooluse hook is capture-only and emits no context.
Configuration:
- Plugin (recommended): context-mode ships a Copilot CLI plugin bundle at
configs/copilot-cli/— a root.mcp.json(MCP),hooks.json(the six capture hooks), a routing skill (skills/context-mode/), and a.github/plugin/plugin.jsonmanifest.copilot plugin install mksglu/context-mode:configs/copilot-cliregisters all of it in one command (no clone, nocontext-mode upgrade/agent call). The bundle's.mcp.jsonpinsCONTEXT_MODE_PLATFORM=copilot-cli, so the server self-identifies as Copilot andctx_upgrade/detection resolvecopilot-clieven when Claude Code is co-installed (whose~/.claude/would otherwise win). Verified on Windows viacopilot --plugin-dir <bundle>:ctx_executeresolves and thePostToolUsehook captures non-MCP tool I/O into the session DB. (This.mcp.jsonis the one committed instance in the repo —.gitignoreun-ignores exactly this path, since a Copilot plugin has no other way to declare MCP.) - MCP (manual, no plugin): register with Copilot CLI's own command —
copilot mcp add context-mode -- context-mode— which writes~/.copilot/mcp-config.json(or$COPILOT_HOME/mcp-config.json). (Alsocopilot mcp list/copilot mcp remove.) - Hook config (manual, no plugin):
$COPILOT_HOME/hooks/context-mode.jsonor~/.copilot/hooks/context-mode.json(written bycontext-mode upgrade; standalone hooks fire — verified — independent of any plugin) - Instruction files:
.github/copilot-instructions.md,AGENTS.md
Detection:
- MCP protocol handshake (
clientInfo.name: "GitHub Copilot CLI"/"copilot-cli") - Config-dir marker: a context-mode-written file under
~/.copilot/(or$COPILOT_HOME— the marker check honors it) —mcp-config.jsonorhooks/context-mode.json, not a bare~/.copilot/directory, so a co-installed-but-unconfigured Copilot CLI is not mis-detected (probed before the generic~/.claudefallback) - Fallback:
CONTEXT_MODE_PLATFORM=copilot-clioverride
Hook Commands:
context-mode hook copilot-cli pretooluse
context-mode hook copilot-cli posttooluse
context-mode hook copilot-cli precompact
context-mode hook copilot-cli sessionstart
context-mode hook copilot-cli userpromptsubmit
context-mode hook copilot-cli stop
Known Issues / Caveats:
- The top-level
"version": 1is optional: the Copilot CLI accepts hook config files that omit the version field (copilot-cli changelog.md:1109). context-mode pins"version": 1for self-documentation; omitting it does not stop hooks from firing. - Event names can be camelCase or PascalCase — the Copilot CLI accepts PascalCase event names alongside camelCase (copilot-cli changelog.md:1065). context-mode uses the native camelCase names; PascalCase is not silently ignored.
COPILOT_HOMErelocates the hook config, the MCP config, and the context-mode session-DB root (the adapter'sgetSessionDir()honors it, so the server reads sessions from the same place the hook runtime writes them).
Sources:
- Hooks schema: GitHub Copilot CLI hooks configuration
- Feature request: #775
Status: Supported (native hooks, v1 scope)
Hook Paradigm: JSON stdin/stdout
Cursor uses native lower-camel hook names and flat hook entries in .cursor/hooks.json or ~/.cursor/hooks.json. context-mode treats Cursor as a first-class adapter and does not rely on Claude-compat wrappers for official support.
Hook Names:
preToolUse-- fires before a tool is executedpostToolUse-- fires after a tool completesstop-- fires when agent turn ends (can send followup_message to continue loop)afterAgentResponse-- fires after assistant response (fire-and-forget, receives full response text)sessionStart-- documented but currently rejected by Cursor's validator (forum report)
Blocking: { "permission": "deny", "user_message": "..." }
Arg Modification: not natively supported (Cursor does not have updated_input)
Output Modification: not supported in v1
Session Context Injection: { "additional_context": "..." }
Session ID Extraction Priority:
conversation_id(stdin JSON)CURSOR_TRACE_IDenvironment variable- Parent process ID fallback
Platform Detection Env Vars:
CURSOR_TRACE_ID(MCP server context)CURSOR_CLI(integrated terminal context)~/.cursor/directory fallback (medium confidence)
Configuration:
- Project:
.cursor/hooks.json - User:
~/.cursor/hooks.json - MCP config:
.cursor/mcp.jsonor~/.cursor/mcp.json - Marketplace plugin (recommended):
.cursor-plugin/plugin.jsonat the repo root auto-registers MCP, hooks, rules, and skills. Manifest explicitly pointshooksat./hooks/cursor/hooks.jsonto avoid colliding with the Claude-format./hooks/hooks.json. Local install:ln -s <repo> ~/.cursor/plugins/local/context-mode. Plugin hook commands usenpx -y context-mode hook cursor <event>so no global install is required.
Plugin/native duplication: context-mode doctor warns when both the plugin and .cursor/hooks.json register context-mode hooks (each event would otherwise fire twice). Remove one configuration to keep events single-fire.
Hook Commands:
context-mode hook cursor pretooluse
context-mode hook cursor posttooluse
context-mode hook cursor stop
Known Issues / Caveats:
preCompactis intentionally not shipped in v1stophook receives:conversation_id,status,loop_count,transcript_path; returnsfollowup_messageto continueafterAgentResponseis fire-and-forget (receivestext, no return value expected)- Hook payloads name MCP tools as
MCP:<tool>and need adapter normalization - Claude-compatible Cursor behavior exists, but native Cursor config is the supported path
additional_contextin postToolUse and sessionStart hooks is accepted but NOT surfaced to the model (Cursor upstream bug — forum #155689, forum #156157). Routing enforcement relies on.mdcrules file and MCP tool descriptions instead.
Status: Fully supported
Hook Paradigm: TS Plugin (gateway plugin via api.registerHook() / api.on())
OpenClaw is an OpenAI-stack agent gateway. context-mode ships as a native gateway plugin that registers hooks through OpenClaw's plugin API rather than the JSON stdin/stdout wire protocol. The same plugin entry also registers context-mode as a context engine, owning compaction.
Hook Names:
tool_call:before-- equivalent to PreToolUsetool_call:after-- equivalent to PostToolUsecommand:new-- equivalent to SessionStart (fires on each new gateway command)before_prompt_build-- lifecycle hook for routing instruction injectionregisterContextEngine(withownsCompaction) -- equivalent to PreCompact
Blocking: return { block: true, blockReason: "..." } from the tool_call:before handler
Arg Modification: mutate event.params in the tool_call:before handler (or return { params: ... })
Output Modification: not supported (the plugin paradigm exposes args/context, not the rendered tool output)
Context Injection: via before_prompt_build (session-level) and registerContextEngine (compaction-level)
Path Resolution:
- Detection root:
~/.openclaw/ - Plugin install:
~/.openclaw/extensions/context-mode/ - Project config:
openclaw.jsonor.openclaw/openclaw.json - Global config fallback:
~/.openclaw/openclaw.json - Project dir:
process.cwd()(the gateway provides no dedicated env var) - Memory dir: project-relative
./memory - Session dir:
~/.openclaw/context-mode/sessions/ - Routing instructions:
AGENTS.md
Configuration:
openclaw.jsonregisters context-mode underplugins.entries["context-mode"]({ "enabled": true })plugins.slots.contextEngine = "context-mode"enables ownership of compaction- No CLI hook command; OpenClaw imports the plugin module directly
Notes / Caveats:
- TS plugin paradigm — hooks run in-process, so there is no shell command to chmod and no platform-specific stdin/stdout quirks
askdecisions are converted toblock(with the original reason) since the gateway has no interactive confirmation pathcontextdecisions insidetool_call:beforeare dropped — context injection must be routed throughbefore_prompt_buildor the registered context engine- Session ID falls back to
pid-${process.ppid}when the gateway does not surface one
Status: MCP-only (no hooks)
Hook Paradigm: MCP-only
Zed is a code editor with first-class MCP support but no hook pipeline. context-mode runs purely through Zed's context_servers configuration; routing enforcement falls back to the AGENTS.md instruction file (~60% compliance).
Hook Support:
- PreToolUse: --
- PostToolUse: --
- PreCompact: --
- SessionStart: --
- Stop: --
- Can modify args: --
- Can modify output: --
- Can inject session context: --
The hook adapter exists only to satisfy the interface contract — every parser throws Error("Zed does not support hooks") and every formatter returns undefined.
Path Resolution:
- Detection root:
~/.config/zed/ - Settings file:
~/.config/zed/settings.json - MCP registration:
context_serversobject insidesettings.json - Session dir:
~/.config/zed/context-mode/sessions/ - Routing instructions:
AGENTS.md(sourced fromconfigs/zed/AGENTS.mdin the package, with an inline fallback if missing)
Detection:
- Auto-detected via the presence of
~/.config/zed/ - Override via
CONTEXT_MODE_PLATFORM=zed
Notes / Caveats:
- No hook adapter implies no automatic routing — the model must follow AGENTS.md voluntarily
- No marketplace or plugin registry for Zed;
getInstalledVersion()always reportsnot installed validateHooksalways returns a singlewarnrow reminding the user that Zed exposes only MCP integrationconfigureAllHooks,setHookPermissions, andupdatePluginRegistryare intentional no-ops
Status: MCP-only (no hooks)
Hook Paradigm: MCP-only
Oh My Pi (OMP) is a Pi-compatible harness that stores its agent state under ~/.omp/agent/ (overridable via OMP_PROCESSING_AGENT_DIR). Before the dedicated adapter, OMP detection fell through to pi and storage rooted under another harness's directory (typically ~/.claude/), per issue #473. The OMP adapter exists primarily to keep ~/.omp/context-mode/ isolated, not to provide hook integration — OMP, like Antigravity/Kiro/Zed, runs context-mode purely as an MCP server.
Hook Support:
- PreToolUse: --
- PostToolUse: --
- PreCompact: --
- SessionStart: --
- Stop: --
- Can modify args: --
- Can modify output: --
- Can inject session context: --
The hook adapter exists only to satisfy the interface contract — every parser throws Error("OMP does not support hooks") and every formatter returns undefined.
Path Resolution:
- Agent root:
$OMP_PROCESSING_AGENT_DIRif set, else~/.omp/agent/ - Settings file:
<agent root>/mcp_config.json - MCP registration:
mcpServersobject insidemcp_config.json - Session dir:
~/.omp/context-mode/sessions/(intentionally rooted at~/.omp/, not the agent dir, so multiple OMP instances on one host share an index without colliding session DBs) - Routing instructions:
PI.md(Pi-compatible filename — OMP shares the Pi instruction surface)
Detection (priority order, listed BEFORE pi so OMP is never misclassified):
OMP_PROCESSING_AGENT_DIRenv var (high confidence)~/.omp/directory presence (medium confidence)CONTEXT_MODE_PLATFORM=ompoverride
Notes / Caveats:
- No hook adapter implies no automatic routing — the model must follow
PI.mdvoluntarily (~60% compliance) - No marketplace or plugin registry for OMP;
getInstalledVersion()reportsnot installedunless anextensions/context-mode/package.jsonexists under the agent dir validateHooksalways returns a singlewarnrow reminding the user that OMP exposes only MCP integrationconfigureAllHooks,setHookPermissions, andupdatePluginRegistryare intentional no-ops
| Capability | Claude Code | Qwen Code | Gemini CLI | VS Code Copilot | JetBrains Copilot | GitHub Copilot CLI | Cursor | OpenCode | KiloCode | OpenClaw | Codex CLI | Kimi Code | Antigravity | Antigravity CLI (agy) |
Kiro | Zed | Pi | OMP |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| PreToolUse | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes*** | Yes | -- | Bounded | Yes | -- | -- | -- |
| PostToolUse | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | Yes (capture-only) | Yes | -- | -- | -- |
| PreCompact | Yes | Yes | Yes | Yes | Yes | Yes | -- | Yes* | Yes* | Yes | Yes**** | Yes | -- | -- | -- | -- | -- | -- |
| SessionStart | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | -- | Yes | Yes | Yes | -- | -- | -- | -- | -- | -- |
| Stop | -- | -- | -- | Yes | Yes | Yes | Yes | -- | -- | -- | Yes | Yes | -- | Best-effort capture | -- | -- | -- | -- |
| Modify Args | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | Yes | -- | -- | -- | -- | -- | -- |
| Modify Output | Yes | Yes | Yes | Yes | Yes | No | No | Yes** | Yes** | No | -- | Yes | -- | -- | -- | -- | -- | -- |
| Inject Context | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | -- | Yes | Yes | Yes | -- | -- | -- | -- | -- | -- |
| Block Tools | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | Bounded | Yes | -- | -- | -- |
| MCP/native tool support | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Native plugin | Native plugin | Native plugin | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
* OpenCode experimental.session.compacting is experimental
** OpenCode has a TUI rendering bug for bash tool output (#13575)
*** Codex CLI PreToolUse supports deny only (no additionalContext); context injection works via PostToolUse and SessionStart
**** Codex CLI PreCompact is runtime-gated on builds that emit the event
| Platform | Response Format |
|---|---|
| Claude Code | { "permissionDecision": "deny", "reason": "..." } |
| Gemini CLI | { "decision": "deny", "reason": "..." } |
| VS Code Copilot | { "permissionDecision": "deny", "reason": "..." } |
| JetBrains Copilot | { "permissionDecision": "deny", "reason": "..." } |
| Cursor | { "permission": "deny", "user_message": "..." } |
| OpenCode | throw new Error("...") |
| Codex CLI | { "hookSpecificOutput": { "permissionDecision": "deny" } } or exit code 2 |
| Kimi Code | { "hookSpecificOutput": { "permissionDecision": "deny" } } or exit code 2 |
| Platform | Response Format |
|---|---|
| Claude Code | { "updatedInput": { ... } } |
| Gemini CLI | { "hookSpecificOutput": { "tool_input": { ... } } } |
| VS Code Copilot | { "hookSpecificOutput": { "hookEventName": "PreToolUse", "updatedInput": { ... } } } |
| JetBrains Copilot | { "hookSpecificOutput": { "hookEventName": "PreToolUse", "updatedInput": { ... } } } |
| Cursor | { "updated_input": { ... } } |
| OpenCode | { "args": { ... } } (mutation) |
| Codex CLI | N/A (updatedInput in schema but not implemented) |
| Kimi Code | { "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow", "updatedInput": { ... } } } |
| Platform | Response Format |
|---|---|
| Claude Code | { "additionalContext": "..." } |
| Gemini CLI | { "hookSpecificOutput": { "additionalContext": "..." } } |
| VS Code Copilot | { "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "..." } } |
| JetBrains Copilot | { "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "..." } } |
| Cursor | { "additional_context": "..." } |
| OpenCode | { "additionalContext": "..." } |
| Codex CLI | { "hookSpecificOutput": { "additionalContext": "..." } } |
| Kimi Code | { "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "..." } } |
All hook-based platforms use the CLI dispatcher pattern instead of direct node paths:
context-mode hook <platform> <event>
The dispatcher resolves the hook script relative to the installed package and dynamically imports it. Stdin/stdout flow through naturally since it runs in the same process.
Advantages over node ./node_modules/... paths:
- Works from any directory (no per-project
npm installneeded) - Single global install serves all projects
context-mode upgradeupdates hooks in-place- Short, portable command strings in settings files
Supported dispatches:
| Platform | Events |
|---|---|
claude-code |
pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit |
gemini-cli |
beforetool, aftertool, precompress, sessionstart |
vscode-copilot |
pretooluse, posttooluse, precompact, sessionstart |
jetbrains-copilot |
pretooluse, posttooluse, precompact, sessionstart |
cursor |
pretooluse, posttooluse, stop |
codex |
pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit, stop |
kimi |
pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit, stop |
qwen-code |
pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit |
copilot-cli |
pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit, stop |
antigravity-cli |
pretooluse, posttooluse, stop |
kiro |
pretooluse, posttooluse |
OpenCode, KiloCode, and OpenClaw use a TS plugin paradigm (no command dispatcher). Pi and OMP register hooks through their own host APIs rather than the CLI dispatcher; Antigravity IDE and Zed are MCP-only (no hooks).
context-mode automatically selects the best SQLite backend at runtime based on the environment:
| Priority | Condition | Backend | Why |
|---|---|---|---|
| 1 | Bun runtime | bun:sqlite |
Built-in, no native addon |
| 2 | Linux + Node.js >= 22.5 | node:sqlite |
Built-in, avoids SIGSEGV from V8 madvise bug |
| 3 | All other environments | better-sqlite3 |
Mature native addon, prebuilt binaries |
Why node:sqlite on Linux? Node.js's V8 garbage collector can call madvise(MADV_DONTNEED) on memory ranges that overlap better-sqlite3's native addon .got.plt section, corrupting resolved symbol addresses and causing sporadic SIGSEGV crashes (1-4/hour on Node v22-v24). node:sqlite is compiled into the Node.js binary itself — no separate .node file, no dlopen(), no .got.plt to corrupt.
Fallback: If node:sqlite is unavailable (Node < 22.5), context-mode silently falls back to better-sqlite3. No user configuration needed.
Override: Not currently supported — backend selection is automatic. If you need to force a specific backend, open an issue.
All platforms support utility commands via MCP meta-tools:
| Command | What it does |
|---|---|
ctx stats |
Show context savings, call counts, and session statistics |
ctx doctor |
Diagnose installation: runtimes, hooks, FTS5, versions |
ctx upgrade |
Update from GitHub, rebuild, reconfigure hooks |
ctx purge |
Permanently deletes all indexed content from the knowledge base |
How they work: The MCP server exposes stats, doctor, upgrade, and purge tools. The <ctx_commands> section in routing instructions (CLAUDE.md, GEMINI.md, AGENTS.md, copilot-instructions.md) maps natural language triggers to MCP tool calls. The doctor and upgrade tools return shell commands that the LLM executes and formats as a checklist. The purge tool permanently deletes all indexed content from the knowledge base and is the sole reset mechanism.