Skip to content

feat(kilo-mcp): remote MCP worker with hybrid catalog search, tRPC calls, and OAuth 2.1 sign-in (part 1/1) - #6030

Open
iscekic wants to merge 1 commit into
mainfrom
kwf/kilo-remote-mcp-c204-l1
Open

feat(kilo-mcp): remote MCP worker with hybrid catalog search, tRPC calls, and OAuth 2.1 sign-in (part 1/1)#6030
iscekic wants to merge 1 commit into
mainfrom
kwf/kilo-remote-mcp-c204-l1

Conversation

@iscekic

@iscekic iscekic commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Changelog for users

  • Agents had no way to discover or invoke the Kilo API over MCP. A new Kilo MCP worker now serves MCP Streamable HTTP with exactly two tools: search and call.
  • search turns a plain-language task into matching Kilo endpoints: exact path and keyword matches rank first.
  • A Vectorize semantic index also returns the right endpoint for queries with zero keyword overlap. If the index is unavailable, search still answers from keyword matching instead of failing.
  • call executes a Kilo API query as the signed-in user. It accepts only catalog paths and validates arguments against the published schema before sending anything.
  • Results larger than 16 KB come back cut at the cap with a [truncated] marker.
  • Connecting a client runs MCP OAuth 2.1: dynamic client registration, sign-in with the existing Kilo login, an org picker, PKCE-protected token exchange, and refresh-token rotation.
  • Access tokens are bound to the user, the chosen org, and this MCP. Requests without a valid token get a 401 challenge pointing clients at the sign-in metadata.
  • The catalog publishes all 359 tRPC queries except admin.*, debug.*, and test.*, each with a search-friendly summary authors can hand-edit.

Changelog for maintainers

  • The dump in apps/web/src/scripts/mcp-catalog walks the live rootRouter (queries only, denylist admin/debug/test) and keeps committed summaries byte-for-byte. Missing summaries are generated per router file via OpenRouter or Anthropic; a corrupt committed catalog fails loudly, and an incomplete catalog is never written.
  • CI commits a refreshed services/kilo-mcp/catalog.json to same-repo PR branches. Fork PRs fail with a catalog.patch artifact and a comment, including when GitHub withholds the LLM secret. The main-push job re-dumps and upserts Vectorize; PR jobs never touch it. scripts/kilo-mcp-catalog.test.mjs asserts this wiring.
  • The worker bundles the committed catalog at build time. The Vectorize index pins @cf/baai/bge-base-en-v1.5 (768 dimensions, cosine) with vector id = procedure path; only the search query is embedded per request. Production deploys from main keep the bundled catalog and the index in lockstep.
  • Search ranks exact-path hits above path-sequence hits above token overlap, and every lexical hit above a semantic-only hit. A Vectorize failure degrades to token-only results with a logged warning.
  • call rejects unknown paths and schema-invalid input before any upstream request. It forwards over apps/web's tRPC GET transport with the verified identity's Kilo credential and the org header from the token claims. x-kilocode-organizationid mirrors the apps/web constant — keep them in sync.
  • The OAuth 2.1 suite covers well-known metadata, public-client DCR, the /authorize pairing with consent page, a single-use status relay, and a membership-validated org picker. /token enforces single-use codes, S256 PKCE, and rotating hashed refresh tokens. State lives in one Durable Object (KiloMcpOAuthStore, DO SQLite, migration tag v1, 6-hour purge alarm).
  • /mcp accepts only this worker's HS256 tokens (issuer, audience, expiry, and jti registry checked). A deployment missing MCP_TOKEN_SECRET or the Durable Object binding refuses POSTs with 503 instead of forwarding unverified bearers.
  • Known defect: the authorize page's Continue with Kilo sign-in button opens in the same tab. The pairing-status poll then dies if the user navigates away (authorize screenshot in E2E proof).

E2E proof (stack-wide)

/home/igor_kilocode_ai/.local/share/kwf/sections/kilo-remote-mcp-c204/e2e-web/prior/e10-device-auth.png

/home/igor_kilocode_ai/.local/share/kwf/sections/kilo-remote-mcp-c204/e2e-web/prior/e10-authorize.png

/home/igor_kilocode_ai/.local/share/kwf/sections/kilo-remote-mcp-c204/e2e-web/prior/e11-expired-pairing.png

Owner request for the stack

Kilo Remote MCP

New Cloudflare Worker (services/kilo-mcp). Not MCP Gateway. Two tools: search, call.

Shape

  • Include every tRPC query except admin.*, debug.*, and test.*.
  • No mutations in v1. No per-procedure opt-in. Denylist, not allowlist.
  • Worker speaks MCP. It does not run tRPC.
  • apps/web stays the authorization server and the tRPC executor.
  • Product auth is MCP OAuth 2.1. The first slice ships without it.

Catalog

One dump script, in apps/web (only place rootRouter loads). Two jobs:

PR job

  1. Keep all queries minus the denylist.
  2. If a row has no summary, an LLM reads the procedure handler and traces what it does. It writes a search-friendly summary: what the call does, in words an agent would type. Not implementation detail. Not a restatement of the path. If a summary already exists, keep it.
  3. Emit catalog.json: path, kind, summary, JSON Schema, derived tags, search blob.
  4. Tags and keywords are derived (path, kind, schema keys). Do not author them.
  5. If catalog.json changed, CI commits it to the PR branch. Authors can edit a committed summary; CI will keep the edit.
  6. Fork PRs cannot be pushed; CI fails and posts the catalog patch.
  7. Do not generate summaries at MCP runtime. Do not write Vectorize.

Merge job (main only)

  1. Run the same dump (fill missing summaries if any slipped through).
  2. Embed every catalog row with one pinned Workers AI model. Upsert Vectorize. Vector id = procedure path.
  3. PRs do not write Vectorize. Do not embed per call.

Do not copy trpc-registry.ts. Do not put hand-written .meta({ mcp }) on each procedure.

Auth

  • MCP OAuth 2.1: PKCE, DCR, protected-resource metadata, resource indicator.
  • User signs in with existing Kilo login. Picks an org.
  • Token is bound to user + org + this MCP. Worker verifies. Forwards that identity to /api/trpc/{path}.

Agent loop

  1. search is hybrid: token overlap on the bundled catalog plus Vectorize kNN on the query embedding. Exact path/token hits rank above semantic hits.
  2. call accepts only catalog paths. Validates input against the published schema.
  3. Worker POSTs to /api/trpc/{path} as that user/org. Truncates the result.

Production Worker deploys from main, so bundled catalog and Vectorize stay in lockstep.

First slice

Bootstrap once: dump the query catalog (minus denylist), fill missing summaries, embed, upsert Vectorize. Prove dump → hybrid search → call on the Worker. No OAuth in this slice.

Owner manual verification

The workflow skipped these checks. Owner verification is pending; these checks did not pass automatically.

  • owner-manual: advisory real GitHub PR run (dump commit on same-repo PR; fork fails with catalog.patch) was not executed in this live stack session.
  • owner-manual: open a fork PR touching apps/web/src/** without a summary and assert catalog-pr fail+comment — needs a real GitHub fork PR, not run here.
  • owner-manual: merge to main requiring a new summary and observe the bot catalog.json commit before Vectorize upsert — needs a real main merge, not run here.

PR stack (merge bottom to top)

@iscekic
iscekic marked this pull request as draft September 9, 2026 23:16
Comment thread services/kilo-mcp/src/auth/token.ts
Comment thread services/kilo-mcp/wrangler.jsonc
@kilo-code-bot

kilo-code-bot Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (12 files)
  • services/kilo-mcp/src/auth/token.ts
  • services/kilo-mcp/src/store/oauth-store.ts
  • services/kilo-mcp/wrangler.jsonc
  • services/kilo-mcp/src/auth/token.test.ts
  • services/kilo-mcp/src/store/oauth-store.test.ts
  • services/kilo-mcp/src/auth/authorize.test.ts
  • services/kilo-mcp/src/auth/dcr.test.ts
  • services/kilo-mcp/src/index.test.ts
  • services/kilo-mcp/src/oauth-pages/authorize-page.test.ts
  • services/kilo-mcp/src/oauth-pages/org-picker.test.ts
  • services/kilo-mcp/catalog.json
  • pnpm-lock.yaml
Previous Review Summary (commit 513bd2f)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 513bd2f)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
services/kilo-mcp/src/auth/token.ts 306 Refresh-token reuse does not revoke the stolen grant

SUGGESTION

File Line Issue
services/kilo-mcp/wrangler.jsonc 58 env.dev omits secrets.required
Files Reviewed (32 files)
  • services/kilo-mcp/src/auth/token.ts - 1 issue
  • services/kilo-mcp/wrangler.jsonc - 1 issue
  • services/kilo-mcp/src/index.ts
  • services/kilo-mcp/src/auth.ts
  • services/kilo-mcp/src/auth/verify.ts
  • services/kilo-mcp/src/auth/authorize.ts
  • services/kilo-mcp/src/auth/dcr.ts
  • services/kilo-mcp/src/auth/jwt.ts
  • services/kilo-mcp/src/auth/pkce.ts
  • services/kilo-mcp/src/auth/metadata.ts
  • services/kilo-mcp/src/auth/http.ts
  • services/kilo-mcp/src/call.ts
  • services/kilo-mcp/src/search.ts
  • services/kilo-mcp/src/search-knn.ts
  • services/kilo-mcp/src/embedding.ts
  • services/kilo-mcp/src/types.ts
  • services/kilo-mcp/src/store/oauth-store.ts
  • services/kilo-mcp/src/db/sqlite-schema.ts
  • services/kilo-mcp/src/oauth-pages/authorize-page.ts
  • services/kilo-mcp/src/oauth-pages/org-picker.ts
  • services/kilo-mcp/drizzle/0000_happy_zaladane.sql
  • services/kilo-mcp/drizzle/0001_cynical_karen_page.sql
  • services/kilo-mcp/scripts/embed-catalog.ts
  • services/kilo-mcp/package.json
  • apps/web/src/scripts/mcp-catalog/catalog.ts
  • apps/web/src/scripts/mcp-catalog/dump.ts
  • apps/web/jest.config.ts
  • .github/workflows/kilo-mcp-catalog.yml
  • scripts/kilo-mcp-catalog.test.mjs
  • .oxfmtrc.json
  • services/kilo-mcp/src/auth/token.test.ts
  • services/kilo-mcp/catalog.json

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 68.9K · Output: 12.5K · Cached: 533.6K

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic force-pushed the kwf/kilo-remote-mcp-c204-l1 branch from cda4506 to 5df3ac4 Compare September 10, 2026 00:58
@iscekic
iscekic marked this pull request as ready for review September 10, 2026 01:10
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant