Platform Support Matrix
June 1, 2026 · View on GitHub
This document provides a comprehensive comparison of all platforms supported by context-mode, including their hook paradigms, capabilities, configuration, and known limitations.
Overview
context-mode supports sixteen platforms across three hook paradigms:
| Paradigm | Platforms |
|---|---|
| JSON stdin/stdout | Claude Code, Gemini CLI, VS Code Copilot, JetBrains Copilot, Cursor, Codex CLI, Qwen Code, Kimi Code |
| TS Plugin | OpenCode, KiloCode, OpenClaw |
| MCP-only | Antigravity, Kiro, 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.
Prerequisites
All platforms (except Claude Code plugin install) require a global install:
npm install -g context-mode
This 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
Main Comparison Table
| Feature | Claude Code | Gemini CLI | VS Code Copilot | JetBrains Copilot | Cursor | OpenCode | Codex CLI | Kimi Code | Antigravity | Kiro | OMP |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Paradigm | json-stdio | json-stdio | json-stdio | json-stdio | json-stdio | ts-plugin | json-stdio | json-stdio | mcp-only | mcp-only | mcp-only |
| PreToolUse equivalent | PreToolUse | BeforeTool | PreToolUse | PreToolUse | preToolUse | tool.execute.before | PreToolUse | PreToolUse | -- | -- | -- |
| PostToolUse equivalent | PostToolUse | AfterTool | PostToolUse | PostToolUse | postToolUse | tool.execute.after | PostToolUse | PostToolUse | -- | -- | -- |
| PreCompact equivalent | PreCompact | PreCompress | PreCompact | PreCompact | -- | experimental.session.compacting | -- | PreCompact | -- | -- | -- |
| SessionStart | SessionStart | SessionStart | SessionStart | SessionStart | -- (buggy in Cursor) | -- | SessionStart | SessionStart | -- | -- | -- |
| Stop equivalent | -- | -- | Stop | Stop | stop | -- | Stop | Stop | -- | -- | -- |
| Can modify args | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | -- | -- | -- |
| Can modify output | Yes | Yes | Yes | Yes | No | Yes (caveat) | No | Yes | -- | -- | -- |
| Can inject session context | Yes | Yes | Yes | Yes | Yes | -- | Yes | Yes | -- | -- | -- |
| Can block tools | Yes | Yes | Yes | Yes | Yes | Yes (throw) | Yes | Yes | -- | -- | -- |
| Config location | ~/.claude/settings.json | ~/.gemini/settings.json | .github/hooks/*.json | .github/hooks/*.json | .cursor/hooks.json or ~/.cursor/hooks.json | opencode.json | ~/.codex/hooks.json + ~/.codex/config.toml | ~/.kimi-code/config.toml | ~/.gemini/antigravity/mcp_config.json | ~/.kiro/settings/mcp.json | ~/.omp/agent/mcp_config.json |
| Session ID field | session_id | session_id | sessionId (camelCase) | sessionId (camelCase) | conversation_id | sessionID (camelCase) | N/A | session_id | N/A | N/A | N/A |
| Project dir env | CLAUDE_PROJECT_DIR | GEMINI_PROJECT_DIR | CLAUDE_PROJECT_DIR | CLAUDE_PROJECT_DIR | stdin workspace_roots | ctx.directory (plugin init) | N/A | stdin cwd | N/A | N/A | OMP_PROCESSING_AGENT_DIR |
| MCP/tool naming | mcp__server__tool | mcp__server__tool | f1e_ prefix | f1e_ prefix | MCP:<tool> in hook payloads | native ctx_* plugin tools | mcp__server__tool | mcp__context-mode__tool | mcp__server__tool | mcp__server__tool | mcp__server__tool |
| Hook command format | context-mode hook claude-code <event> | context-mode hook gemini-cli <event> | context-mode hook vscode-copilot <event> | context-mode hook jetbrains-copilot <event> | context-mode hook cursor <event> | TS plugin (no command) | context-mode hook codex <event> | context-mode hook kimi <event> | N/A | N/A | |
| Hook registration | settings.json hooks object | settings.json hooks object | .github/hooks/*.json | .github/hooks/*.json | hooks.json native hook arrays | opencode.json plugin array | ~/.codex/hooks.json | config.toml hooks array | N/A | N/A | |
| MCP server command | context-mode (or plugin auto) | context-mode | context-mode | context-mode | context-mode | N/A (native plugin tools) | 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 | |
| Session dir | ~/.claude/context-mode/sessions/ | ~/.gemini/context-mode/sessions/ | .github/context-mode/sessions/ or ~/.vscode/context-mode/sessions/ | .github/context-mode/sessions/ | ~/.cursor/context-mode/sessions/ | ~/.config/opencode/context-mode/sessions/ | ~/.codex/context-mode/sessions/ | ~/.kimi-code/context-mode/sessions/ | ~/.gemini/context-mode/sessions/ | ~/.kiro/context-mode/sessions/ |
Legend
- Yes = Fully supported
- -- = Not supported
- (caveat) = Supported with known issues
Platform Details
Claude Code
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 prompt
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.
Gemini CLI
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
OpenCode
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
Codex CLI
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 = trueSome 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.
Kimi Code
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).
Qwen Code
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
Antigravity
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
Kiro
Status: MCP-only (hooks planned for Phase 2)
Hook Paradigm: MCP-only
Kiro is an AWS agentic IDE and CLI. It supports MCP servers via ~/.kiro/settings/mcp.json using the standard mcpServers JSON format. Hook support for Kiro CLI (JSON stdin + exit code 2 blocking, preToolUse/postToolUse) is verified in the Kiro CLI docs but not yet implemented in context-mode — planned for Phase 2.
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 (Phase 2 — not yet implemented):
- Kiro CLI supports
preToolUse/postToolUsehooks via JSON stdin - Blocking: exit code 2 (similar to Gemini CLI pattern)
- Hook format verified in Kiro CLI docs but context-mode adapter is not yet built
Built-in Tools:
fs_read/read,fs_write/write,execute_bash/shell,use_aws/aws
Capabilities:
- PreToolUse: --
- PostToolUse: --
- PreCompact: --
- SessionStart: --
- Can modify args: --
- Can modify output: --
- Can inject session context: --
Known Issues / Caveats:
- Hook adapter not yet implemented — Phase 2 work item
- 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
VS Code Copilot
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
JetBrains Copilot
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+
Cursor
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.
OpenClaw
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
Zed
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
OMP (Oh My Pi)
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 Matrix (Quick Reference)
| Capability | Claude Code | Gemini CLI | VS Code Copilot | JetBrains Copilot | Cursor | OpenCode | Codex CLI | Kimi Code | Antigravity | Kiro | OMP |
|---|---|---|---|---|---|---|---|---|---|---|---|
| PreToolUse | Yes | Yes | Yes | Yes | Yes | Yes | Yes*** | Yes | -- | -- | -- |
| PostToolUse | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | -- | -- |
| PreCompact | Yes | Yes | Yes | Yes | -- | Yes* | Yes**** | Yes | -- | -- | -- |
| SessionStart | Yes | Yes | Yes | Yes | Yes | -- | Yes | Yes | -- | -- | -- |
| Stop | -- | -- | Yes | Yes | Yes | -- | Yes | Yes | -- | -- | -- |
| Modify Args | Yes | Yes | Yes | Yes | Yes | Yes | -- | Yes | -- | -- | -- |
| Modify Output | Yes | Yes | Yes | Yes | No | Yes** | -- | Yes | -- | -- | -- |
| Inject Context | Yes | Yes | Yes | Yes | Yes | -- | Yes | Yes | -- | -- | -- |
| Block Tools | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -- | -- | -- |
| MCP/native tool support | Yes | Yes | Yes | Yes | Yes | Native plugin | 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
Hook Response Format Comparison
Blocking a Tool
| 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 |
Modifying Tool Input
| 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": { ... } } } |
Injecting Additional Context (PostToolUse)
| 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": "..." } } |
CLI Hook Dispatcher
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 |
OpenCode uses a TS plugin paradigm (no command dispatcher). Antigravity and Kiro have no hook support.
SQLite Backend Selection
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.
Utility Commands
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.