Skip to content

Kilo Code adaptation — fork of opencode-cursor (sharing for visibility / possible cherry-picks) - #129

Open
chiarelli wants to merge 22 commits into
Nomadcxx:mainfrom
chiarelli:kilocode-adaptation-pr
Open

Kilo Code adaptation — fork of opencode-cursor (sharing for visibility / possible cherry-picks)#129
chiarelli wants to merge 22 commits into
Nomadcxx:mainfrom
chiarelli:kilocode-adaptation-pr

Conversation

@chiarelli

Copy link
Copy Markdown

Hi — I've been running a Kilo Code port of opencode-cursor in a downstream fork and wanted to put it in front of you in case any of it is useful upstream.

Fork: https://github.com/chiarelli/kilocode-cursor
Branch: kilocode-adaptation-pr (merged onto your current main so GitHub can compare)

Context

Kilo is an OpenCode fork with its own plugin system (@kilocode/plugin), auth store, and config layout (kilo.jsonc). I started from opencode-cursor and adapted the proxy/tool-loop/MCP bridge to run there under the name kilo-cursor-plugin.

The adaptation branch was originally an orphan import, so the PR includes a merge commit that connects histories to your main. The functional work is in ~21 commits on top of that.

What works in production (for us)

  • Cursor models via local proxy (cursor-agent / SDK), same overall shape as opencode-cursor
  • Kilo OAuth: kilo auth login --provider cursor wired into model sync and runtime auth
  • Tool loop in opencode mode: Kilo owns execution; plugin maps cursor-agent stream-json ↔ OpenAI tool_calls
  • MCP passthrough: Kilo-registered MCP tools (context7_*, openviking_*, etc.) execute in Kilo; proxy remaps names on the wire
  • GetMcpTools / GetDynamicTools from cursor-agent are intercepted and answered with Kilo MCP names (no mcp__ in the visible catalog). This fixed models treating an empty native MCP list as “tool doesn’t exist”
  • Hybrid chat.params tool snapshot: poll while MCP servers are pending, then fingerprint-cache so late-registered tools show up without restarting Kilo
  • Session resume (--resume) scoped per Kilo session ID; cache cleared after Kilo compaction so context % doesn’t carry over
  • Usage chunks: OpenAI-compatible token counts on final responses; omitted on intermediate tool_calls SSE chunks

Probably Kilo-only (not asking to merge as-is)

  • kilo-cursor CLI, kilo.jsonc paths, Kilo auth store / credential helpers
  • System prompt and subagent wiring for Kilo’s task tool
  • Renames (CURSOR_KILO_*, provider id cursor, package name)

Might be worth cherry-picking upstream

  • Usage omission on intermediate tool_calls responses
  • Session resume invalidation when tool fingerprint changes
  • MCP discovery/catalog behavior when mcp.tool.list() is empty but tools are already on the request
  • Grok wire ID / reasoning-effort handling (if you hit the same issues)

Tests

bun test on the merged branch: 875 pass, 114 fail. Most failures look like tests still expecting OpenCode paths/layout (~/.config/opencode, opencode-cursor CLI, V2 adapter hooks). I haven’t cleaned those up for an upstream-shaped test suite.

What I’m asking

Not necessarily “merge this whole thing.” Mainly:

  1. Are you OK with this living as a downstream fork, or do you prefer a different relationship (subtree, documented fork, etc.)?
  2. If anything above looks mergeable in small pieces, I’m happy to split those out into separate PRs against your main.

Happy to answer questions or walk through the MCP / GetDynamicTools path — that was the trickiest part.

chiarelli and others added 22 commits August 20, 2026 16:59
Fork the opencode-cursor provider and rework it to run under Kilo Code, keeping the Cursor provider integration while wiring Kilo-specific entrypoints, configuration, and runtime paths.
…ed model sync

Route Cursor provider authentication through Kilo OAuth and enable authenticated model synchronization so models are resolved with the user's Kilo session.
Introduce a Kilo-native MCP passthrough bridge that forwards tool calls to OpenCode MCP servers, and fix streamed response duplication in the proxy handler.
Relax the sync-models config parser to tolerate JSONC (comments/whitespace) and absolute URLs so user configs are not rejected.
Turn the direct MCP bridge on by default and correct the passthrough cli.json stub generation so the bridge initializes with valid configuration.
Update documentation for the Kilo OAuth flow, the MCP passthrough bridge, and the CURSOR_KILO environment variable usage.
During model sync, populate the per-model limit.context and limit.output fields so downstream consumers get accurate context window sizes.
Increase the stdout maxBuffer for the local glob and grep tool handlers to prevent crashes on large directory trees.
Keep full cursor-agent model IDs during sync so grok variants resolve correctly, and fix error parsing for model names that include version dots.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drain cursor-agent stdout after tool_call intercept to capture result.usage, map it to OpenAI usage fields for Kilo, and deny destructive tools in project cli.json while draining.

Co-authored-by: Cursor <cursoragent@cursor.com>
Session resume is now on when CURSOR_KILO_SESSION_RESUME is unset; set false/0/off/no/disabled to opt out.

Co-authored-by: Cursor <cursoragent@cursor.com>
Cursor resume IDs desync when Kilo compacts context; track Kilo sessions and force a fresh Cursor turn on the next proxy request.

Co-authored-by: Cursor <cursoragent@cursor.com>
Real kilo.jsonc configs often include trailing commas; sync-models failed with parseConfigJson returned null.

Co-authored-by: Cursor <cursoragent@cursor.com>
Group fast variants into separate entries (including thinking families), add Grok 4.6 and Composer 2.5 costs, and preserve generated costs on catalog merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
Inject the Kilo subagent roster into system and bridge prompts, forbid Cursor-style subagentType/custom wrappers, and rewrite Unknown agent type: custom failures with retry instructions for Kilo task delegation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Include X-Kilo-Session-ID in the resume sessionKey so concurrent tabs stay isolated while compaction keeps the same Kilo session and still forces a fresh Cursor chat on the next turn.

Co-authored-by: Cursor <cursoragent@cursor.com>
Repair bare cursor-grok-4.6 configs to tiered wire IDs, read variant from message.model in chat.params, and honor reasoning_effort on proxy requests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Kilo records a step-finish per provider round-trip; emitting usage when
finish_reason is tool_calls inflated context % via large cache.read values.
Only attach usage chunks on final stop responses.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wait for async MCP registration only while servers are pending, then cache
merged tool defs until the fingerprint changes so late-registered tools like
openviking_* appear without reloading Kilo.

Co-authored-by: Cursor <cursoragent@cursor.com>
Cursor models treated empty GetMcpTools as missing MCP servers. Serve
the same Kilo names (no mcp__), remember tools from the proxy wire when
mcp.tool.list() is empty, and keep natives/viking wrappers off that catalog.

Co-authored-by: Cursor <cursoragent@cursor.com>
…sion features

The README was rewritten in English and expanded to describe the features landed on `kilocode-adaptation`:

- **MCP catalog on Kilo names** — `GetDynamicTools` / `GetMcpTools` now expose tools using the same identifiers Kilo executes (e.g. `openviking_search`, `context7_query_docs`), without the `mcp__` prefix in the visible catalog.
- **Hybrid tool snapshot** — MCP is polled while servers are pending, then `chat.params` is served from a fingerprint cache so late-discovered tools surface without a Kilo reload.
- **Session resume** — cursor-agent resume cache is now scoped per Kilo session; the Cursor chat is reset after Kilo compaction so context-usage % does not stick.
- **OpenAI-compatible usage** — usage is emitted on final responses and omitted on intermediate `tool_calls` chunks.
- **Subagents** — Cursor `Task` calls are routed to Kilo subagents instead of Cursor-native task types.
- **Model sync** — authenticated catalog with fast/standard tiers, pricing, and `limit.context` / `limit.output`.

Also aligned install options, prerequisites, and config snippets with current behavior.
Connects the orphan kilocode-adaptation branch to upstream/main so GitHub can open a compare/PR. Functional changes are in the Kilo adaptation commits; this merge commit only links unrelated histories.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant