Release v0.10.0: Cloudflare Workers deployment#3
Conversation
Enables oddkit as MCP server for Claude Code in this repo. https://claude.ai/code/session_014FSYqtokXmcQADW4tTsgci
Remote MCP server for oddkit enabling Claude.ai on iOS/iPad/web. Features: - oddkit_orchestrate, oddkit_librarian, oddkit_validate tools - Streamable HTTP transport for MCP - GitHub raw content API for baseline fetching (no git clone) - CORS enabled for cross-origin requests Build output: 36.84 KiB / gzip: 9.41 KiB To deploy: cd workers && npm install && npm run deploy https://claude.ai/code/session_014FSYqtokXmcQADW4tTsgci
Now exposes same capabilities as CLI version: Resources: - oddkit://instructions — Decision gate - oddkit://quickstart — Agent quick start - oddkit://examples — Usage patterns Prompts: - Fetched from klappy.dev/canon/instructions/REGISTRY.json - Returns agent prompts like odd-epistemic-guide, odd-scribe Build: 44.18 KiB / gzip: 11.25 KiB https://claude.ai/code/session_014FSYqtokXmcQADW4tTsgci
Major feature: Remote MCP server for Claude.ai on iOS/iPad/web. Three deployment methods: - CLI: npx oddkit <command> - MCP (local): npx oddkit-mcp for Cursor/Claude Code - MCP (remote): Cloudflare Worker for Claude.ai mobile/web Updated docs: - README.md: Added deployment methods table - QUICKSTART.md: Added MCP (remote) layer - MCP.md: Added deployment options section - CLAUDE-CODE.md: Added Option 4 for mobile/web https://claude.ai/code/session_014FSYqtokXmcQADW4tTsgci
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 4 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| }; | ||
| default: | ||
| return await runLibrarian(message, baselineUrl, cache); | ||
| } |
There was a problem hiding this comment.
Orient action advertised but silently falls back to librarian
Medium Severity
The tool schema declares orient as a valid action in the enum, and the examples resource documents it as supported. However, the runOrchestrate switch statement has no case for "orient", causing it to silently fall through to the default case which runs runLibrarian instead. Users who explicitly request the orient action will receive librarian behavior without any indication that orient wasn't actually executed.
Additional Locations (1)
| @@ -0,0 +1,1527 @@ | |||
| { | |||
| "name": "oddkit-mcp-worker", | |||
| "version": "0.9.1", | |||
There was a problem hiding this comment.
Worker package-lock.json version mismatches package.json
Low Severity
The workers/package-lock.json declares version 0.9.1 in two places (root and packages[""] entries), while workers/package.json declares version 0.10.0. The lock file wasn't regenerated after the version bump.
Additional Locations (1)
| status: 204, | ||
| headers: corsHeaders(origin), | ||
| }); | ||
| } |
There was a problem hiding this comment.
Requests with id zero silently return empty response
Medium Severity
The notification detection check !response.id incorrectly treats id: 0, id: null, and id: "" as falsy. If a client sends a valid JSON-RPC request with id: 0, the condition !response.id && !response.error evaluates to true, causing the server to return 204 No Content instead of the actual result. Clients using sequential numeric IDs starting from zero would have their first request silently fail.
| // Check for required evidence types | ||
| const hasScreenshot = artifacts.some((a) => /\.(png|jpg|jpeg|gif)$/i.test(a)); | ||
| const hasVideo = artifacts.some((a) => /\.(mp4|mov)$/i.test(a)); | ||
| const hasLog = artifacts.some((a) => /\.(log|txt)$/i.test(a)); |
There was a problem hiding this comment.
…and dead branch Two issues from bugbot's 14:29 review: 1. Reframing 'none' check applies same defensive pattern as the tiersRaw fix in fetchStakesCalibration. The cell may be 'none' or 'none (parenthetical reason)' — strict equality would silently surface all reframings via the 'all' fallback when authors include explanatory text. Same defect class as bug #3 in the evidence note; sweep applied. 2. Remove unreachable questionTiers.length === 0 branch in the question- surfacing condition. The SUPPRESSED early-return at line 1635 already handles that case, so the branch was dead code that misleadingly suggested 'surface all questions for empty tiers' semantics — the actual semantic is full suppression. Verified: typecheck clean, parser test 97/97 against main, smoke 6/6. Defect-class sweep on governance cell strict-equality checks: only two sites (tiersRaw, surfacing), both now defensive.
The three Cursor Agent fix commits on this PR addressed all three Bugbot findings correctly, but only the count() collision (Bug #1) got dedicated test coverage. Bugs #2 and #3 — both about literal handling — landed without regression tests, so a future refactor that reverts the literal-skip logic would not be caught by CI. This commit closes the gap. Test 1: rewriteSqlToRaw — semantic names inside single-quoted literals - 'klappy://sources/scientific-method' must not have method → blob2 - SQL doubled-quote escape '' must keep word inside literal preserved - Mixed case: column ref outside literal still rewrites; same word inside a literal stays untouched Test 2: detectRawSlotNames — raw slot names inside literals do not trigger rejection - 'https://example.com/blob1/readme' must not be falsely rejected - 'klappy://reports/double5-summary' likewise - Sanity guard: bare blob1 outside any literal STILL gets rejected - Mixed case: raw slot outside a literal is rejected even when another raw slot appears inside a literal in the same query All 17 tests pass locally: 17 passed, 0 failed (was 15 — added 2) This addresses the test-coverage gap I noted in the PR review, not a code defect — the fixes themselves are correct and these tests verify they hold.


Summary
Test plan
Note
Medium Risk
Introduces a new internet-exposed MCP endpoint with CORS and remote baseline fetching, which adds operational/security surface area despite being largely additive and isolated.
Overview
Adds a Cloudflare Worker deployment (
workers/) that exposes oddkit as a remote MCP server over HTTP (/mcpJSON-RPC) with CORS, health endpoints, and support for tools, resources, and prompts (prompts fetched from the baseline registry).Includes a Worker-specific
runOrchestrateimplementation that fetches the baseline index/docs from GitHub raw content (optional KV caching) and provides simplifiedlibrarian/catalog/preflight/validatebehavior.Bumps the package version to
0.10.0, adds a project-local.mcp.jsonexample, and updates README + MCP/quickstart docs to describe CLI, local MCP, and remote MCP deployment paths.Written by Cursor Bugbot for commit 9911109. This will update automatically on new commits. Configure here.