Why additional_context Is Not Surfaced to the Model in Cursor Context-Mode

The "additional_context not surfaced to model" limitation occurs because Cursor's native hook parser accepts the JSON field from Context-Mode but fails to forward it to the LLM due to a verified upstream bug, forcing the system to rely on static .mdc routing rules instead of dynamic injected guidance.

The mksglu/context-mode repository enables intelligent tool routing for AI assistants by injecting contextual guidance through hook responses. However, when using the Cursor editor, this guidance disappears between the hook output and the model input. This article explains the architectural cause of this limitation, referencing the specific source files and line numbers where the data formatting and emission occur.

Root Cause: The Cursor Native Hook Parser Bug

The limitation originates in Cursor's implementation of native post-tool-use hooks, not in Context-Mode itself. While Context-Mode correctly formats and emits the additional_context field, Cursor's internal hook interpreter logs the JSON key but never incorporates the value into the model's prompt.

According to docs/platform-support.md at line 420, this is a documented upstream issue tracked in Cursor forum discussions #155689 and #156157. The README at line 288 explicitly lists this as a "Known limitation," confirming that Context-Mode cannot work around the platform's parser behavior.

How Context-Mode Formats the additional_context Payload

In src/adapters/cursor/index.ts (lines 152-170), the Cursor adapter converts the internal additionalContext property into the JSON structure that Cursor's native hooks expect:

// src/adapters/cursor/index.ts
if (response.decision === "context" && response.additionalContext) {
  // Cursor expects the field name `additional_context`
  return { additional_context: response.additionalContext };
}

This code ensures that when Context-Mode decides to provide additional context (such as ctx_execute or ctx_batch_execute instructions), it maps the internal naming convention to the platform-specific additional_context field that Cursor's hook system recognizes.

The Hook Scripts That Emit the Data

After formatting, the payload is emitted by Cursor-specific hook scripts that write JSON lines to stdout. In hooks/cursor/posttooluse.mjs at line 72, the script outputs:

// hooks/cursor/posttooluse.mjs
process.stdout.write(JSON.stringify({ additional_context: "" }) + "\n");

Similarly, hooks/cursor/sessionstart.mjs handles the session initialization hook at line 92 using the same emission pattern. Both scripts successfully transmit the data to Cursor's hook system, but the platform's upstream parser drops the value before it reaches Claude or ChatGPT.

Impact on Routing Behavior

Because the additional_context value never reaches the model, Context-Mode cannot use dynamic guidance to influence routing decisions in real-time. Instead, the system falls back to static routing definitions specified in the .mdc rules file. This means routing enforcement relies entirely on hook name mappings in the configuration file rather than contextually injected instructions that would normally guide the LLM's next action selection.

Summary

  • Upstream bug confirmed: Cursor accepts the additional_context field in native hook responses but fails to surface it to the LLM, as documented in docs/platform-support.md (line 420) and README.md (line 288).
  • Implementation is correct: The Context-Mode adapter in src/adapters/cursor/index.ts properly formats the payload, and both hooks/cursor/posttooluse.mjs (line 72) and hooks/cursor/sessionstart.mjs (line 92) emit valid JSON.
  • Forced fallback: Without dynamic context propagation, routing defaults to static .mdc file rules rather than injected guidance.
  • Platform limitation: This is explicitly a Cursor defect tracked in forum posts #155689 and #156157, not a flaw in the Context-Mode implementation.

Frequently Asked Questions

Is this a bug in Context-Mode or Cursor?

This is exclusively a Cursor upstream bug. The Context-Mode codebase in mksglu/context-mode correctly implements the hook response format according to Cursor's specifications. The platform-support documentation at line 420 explicitly states that Cursor accepts the field but does not forward it to the model, linking to the official bug reports in the Cursor forums.

Can I fix this by modifying the Context-Mode source code?

No. The issue resides in Cursor's native hook parser, which is closed-source and beyond the scope of the Context-Mode repository. Context-Mode already emits the correct JSON structure from src/adapters/cursor/index.ts and the hook scripts, but Cursor's internal interpreter drops the value before it reaches the LLM context window.

How does Context-Mode handle routing when additional_context is dropped?

When the dynamic context cannot reach the model, Context-Mode falls back to static routing rules defined in the .mdc configuration file. These rules map specific hook names to tool descriptors, allowing basic routing functionality even without the injected guidance that would normally influence the LLM's next action through the additional_context field.

Which Cursor hooks are affected by this limitation?

Both the postToolUse hook (implemented in hooks/cursor/posttooluse.mjs) and the sessionStart hook (implemented in hooks/cursor/sessionstart.mjs) are affected. Both emit the additional_context field correctly at lines 72 and 92 respectively, but Cursor's parser handles both identically—accepting the JSON key while failing to propagate the value to the model.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →