codemode rip, part 1: inbound MCP exec_js runs on itx#1445
Merged
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 185a081. Configure here.
cc2a9cd to
9a7224d
Compare
jonastemplestein
added a commit
that referenced
this pull request
Jun 10, 2026
Bugbot finding on #1445: the legacy executeCodemodeFunctionCall delegated listProcedures to call(), which namespaces typings by cap name — legacy mount-agnostic callers got typings that no longer matched their mount path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
185a081 to
947173d
Compare
Contributor
Author
|
Bugbot finding addressed in 947173d: the legacy |
9a7224d to
825791f
Compare
jonastemplestein
added a commit
that referenced
this pull request
Jun 10, 2026
Bugbot finding on #1445: the legacy executeCodemodeFunctionCall delegated listProcedures to call(), which namespaces typings by cap name — legacy mount-agnostic callers got typings that no longer matched their mount path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
947173d to
ee96873
Compare
825791f to
f43fee8
Compare
jonastemplestein
added a commit
that referenced
this pull request
Jun 10, 2026
Bugbot finding on #1445: the legacy executeCodemodeFunctionCall delegated listProcedures to call(), which namespaces typings by cap name — legacy mount-agnostic callers got typings that no longer matched their mount path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ee96873 to
8a172a0
Compare
ProjectMcpServerConnection no longer touches codemode:
- exec_js scripts are itx scripts (async ({ itx }) => …) run through the
shared runItxScript harness, recorded as itx/execution-requested|completed
on the MCP session's stream.
- Each (MCP session, project) gets a child context (ctx_…) seeded with
ai (raw AI binding), os (OrpcCapability, path-call), and gmail
(GmailCapability, members) — instructions feed both the tool description
and itx describe().
- OrpcCapability gains a real call({ path, args }) (the legacy
executeCodemodeFunctionCall delegates to it); GmailCapability needs no
adapter — request() is a real method and members-replay reaches it.
- Registry now force-injects projectId into loopback dial props, so
DIALABLE_LOOPBACKS entrypoints that scope by project (Orpc, Gmail) are
spoof-proof; both added to the allowlist with the contract documented.
- Deleted from the MCP DO: provider registrations, codemode session
start/wait, the stream-decode result watcher, debug provider limits.
Codemode itself still exists (agents + UI); parts 2/3 take those.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bugbot finding on #1445: the legacy executeCodemodeFunctionCall delegated listProcedures to call(), which namespaces typings by cap name — legacy mount-agnostic callers got typings that no longer matched their mount path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8a172a0 to
071375e
Compare
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jonastemplestein
added a commit
that referenced
this pull request
Jun 10, 2026
Stacked on #1445. The agent's execution engine moves from CodemodeSession to the itx runner. ## What - **Each agent gets an itx child context** (`ctx_…`) seeded with its tools as caps: `chat` + `debug` via a new `AgentToolsCapability` loopback forwarder, plus `ai` / `os` / `gmail`. One `agent/capability-noted` event per cap lands on the agent stream, so the LLM keeps learning its tools from stream history exactly as before (the agent processor renders these into model-visible context). - **LLM code fences run through `runItxScript`, detached** — the two-event execution record on the agent stream is the durable trace, and `itx/execution-completed` turns into agent input (the yaml block now includes console output). LLM scripts stay written as `async (ctx) => …`: `ctx` IS the itx handle — `ctx.chat`, `ctx.ai`, `ctx.os`, `ctx.gmail`, `ctx.fetch` all line up name-for-name. - **Enqueued executions**: `itx/execution-requested` with `enqueued: true` is a queue entry the agent-host runs (first taste of processor mode from itx-next §4). Slack bang commands use this path. - **Security**: `AgentToolsCapability` derives the agent DO name from registry-injected `projectId` + definer's `agentPath` — a raw durable-object ref would have let a definer address another project's agent by name. - **Slack agent**: status side effects key on the itx events; thread-route etiquette becomes a capability-noted event. ## Behavior changes - **`ctx.slack.agent.threadInfo()` is dropped** (it was an event-mediated tool, a codemode-only mechanism). The webhook payload already carries channel/thread_ts — the old instructions said as much — and it can return as a dialable cap (`SlackAgentToolsCapability`) if missed. - Function-call-level events are gone; execution granularity is requested/completed. Slack "is using tools…" status now spans the whole script run. - Detached execution has no retry-on-DO-restart (codemode's processor had at-least-once); record-only semantics, noted in itx-next §4 as the processor-mode follow-up. ## Testing typecheck / lint / format green; unit suite updated to the new events (207 passing). Needs a deployed e2e pass for the agent loop — the existing agents e2e suite covers it once this stack deploys to a preview. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Touches core agent execution, tool dialing, and Slack paths; detached itx runs lack codemode-style retry on DO restart, and security relies on registry-injected projectId in AgentToolsCapability. > > **Overview** > Replaces **CodemodeSession** with an **itx child context** per agent: tools are registered as caps (`chat`/`debug` via new **`AgentToolsCapability`**, plus `ai`, `os`, `gmail`, `slack`, `agents`), and **`agent/capability-noted`** events on the agent stream replace **`codemode/tool-provider-registered`** for LLM-visible tool docs. > > **Agent-host** runs LLM code fences through **`runItxScript`** (detached) and maps **`itx/execution-completed`** back to agent input (including console logs). Slack bang commands enqueue **`itx/execution-requested`** with **`enqueued: true`**. **`SlackCapability`** gains an itx **`call`** path; **`ctx.slack.agent.threadInfo`** and codemode function-call events are removed. > > **`runItxScript`** accepts optional **`executionId`** and **`recordRequested: false`** when the queue entry already exists. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5b92858. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- CLOUDFLARE_PREVIEW --> ## Environment Config Lease <!-- CLOUDFLARE_PREVIEW_STATE --> <!-- { "apps": { "os": { "appDisplayName": "OS", "appSlug": "os", "status": "deployed", "updatedAt": "2026-06-10T14:47:53.981Z", "headSha": "5b92858e912f9d5f460284f9e3fffc6dfaa5c16e", "message": null, "publicUrl": "https://os.iterate-preview-4.com", "runUrl": "https://github.com/iterate/iterate/actions/runs/27284064516", "shortSha": "5b92858" }, "semaphore": { "appDisplayName": "Semaphore", "appSlug": "semaphore", "status": "deployed", "updatedAt": "2026-06-10T14:35:21.942Z", "headSha": "7b6c9e26a49ca380f25b45b218a47f371abed888", "message": null, "publicUrl": "https://semaphore.iterate-preview-4.com", "runUrl": "https://github.com/iterate/iterate/actions/runs/27283580966", "shortSha": "7b6c9e2" } }, "environmentConfigLease": { "dopplerConfig": "preview_4", "leasedUntil": 1781106059566, "leaseId": "108459b4-bf1b-4271-a050-cf9442fa648b", "slug": "preview-4", "type": "environment-config-lease" } } --> <!-- /CLOUDFLARE_PREVIEW_STATE --> Lease: `preview-4` Doppler config: `preview_4` Type: `environment-config-lease` Leased until: 2026-06-10T15:40:59.566Z ### OS Status: deployed Commit: `5b92858` Preview: https://os.iterate-preview-4.com [Workflow run](https://github.com/iterate/iterate/actions/runs/27284064516) Updated: 2026-06-10T14:47:53.981Z ### Semaphore Status: deployed Commit: `7b6c9e2` Preview: https://semaphore.iterate-preview-4.com [Workflow run](https://github.com/iterate/iterate/actions/runs/27283580966) Updated: 2026-06-10T14:35:21.942Z <!-- /CLOUDFLARE_PREVIEW --> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
jonastemplestein
added a commit
that referenced
this pull request
Jun 10, 2026
Final follow-up to the codemode rip (#1445/#1446/#1447). MCP's streamable HTTP transport is a stateless protocol — fetch with metadata — so nothing about an MCP client belongs in a Durable Object. ## What - **`OutboundMcpFromOurClientCapability` DO deleted** — class, worker export, alchemy namespace + `OUTBOUND_MCP_FROM_OUR_CLIENT_CAPABILITY` binding, vitest harness wiring. Nothing has dialed it since the codemode rip (its only caller was the deleted provider registration). - **Core helpers promoted** to `src/itx/caps/mcp-client-core.ts` with clean names: `connectMcp` (custom-fetch aware, closes on failed connect), `listMcpTools`, `executeMcpToolCall`. `McpClient` dedupes onto them; the mock-server unit test moved and adapted. - **The DO allusion is gone from the docs**: `McpClient`'s header now states statelessness as the design ("connect → call → close, per invocation; deliberately no Durable Object anywhere in this path") instead of presenting connection caching as a future optimization. ## Deploy note This is the repo's first Durable Object class deletion. The DO had no SQLite (in-memory cache only) and no inbound subscribers, so deletion is data-safe; alchemy is expected to emit the `deleted_classes` migration on deploy — **this PR's preview deploy is the proof**. If it refuses, the fallback is a tombstone class like `CodemodeSession`'s. ## Testing Repo typecheck / lint / knip / unit suite green locally (incl. the moved mock-server core test). The `McpClient` e2e remains gated on a reachable MCP server. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CLOUDFLARE_PREVIEW --> ## Environment Config Lease <!-- CLOUDFLARE_PREVIEW_STATE --> <!-- { "apps": {}, "environmentConfigLease": { "dopplerConfig": "preview_4", "leasedUntil": 1781109925654, "leaseId": "f7427e44-72e2-4e04-8617-122e174b3c57", "slug": "preview-4", "type": "environment-config-lease" } } --> <!-- /CLOUDFLARE_PREVIEW_STATE --> Lease: `preview-4` Doppler config: `preview_4` Type: `environment-config-lease` Leased until: 2026-06-10T16:45:25.654Z <!-- /CLOUDFLARE_PREVIEW --> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #1442. First slice of the codemode rip-out (itx-next.md §4): the inbound MCP server's
exec_jsno longer touches codemode.What
async ({ itx }) => { ... }— run through the sharedrunItxScriptharness, with the two-event execution record landing on the MCP session's stream. Console capture and result formatting preserved.ctx_…, the prototype chain in action) seeded with three caps:ai(raw AI binding ref),os(OrpcCapability, path-call),gmail(GmailCapability, members). The caps'instructionsfeed both the exec_js tool description anditx.describe().call({ path, args }); the legacyexecuteCodemodeFunctionCalldelegates to it. GmailCapability needs no adapter at all —request()is a real method and members-replay reaches it.projectIdinto loopback dial props (alongsidecap/context), so dialable entrypoints that scope by project can never be pointed at someone else's project by a definer. Orpc + Gmail added toDIALABLE_LOOPBACKSwith that contract documented.Codemode itself still exists (agent loop + web UI consume it); parts 2 and 3 take those, then the domain deletes.
Testing
typecheck / lint / format / unit (208 tests) green. e2e exec_js coverage rides the existing inbound-MCP suite against a deployment.
🤖 Generated with Claude Code
Note
High Risk
Changes authenticated remote code execution and project-bound API/Gmail loopback dialing; registry-injected projectId is the main cross-tenant guard.
Overview
Inbound MCP
exec_jsno longer uses codemode sessions, tool-provider registrations, or stream polling for completion. Scripts run asasync ({ itx }) => { ... }viarunItxScript, with execution recorded on the MCP session stream and the same console/result formatting for tool responses.Each (MCP session, project) gets a persisted child itx context (
ITX_CONTEXT) parented to the project, seeded withai,os(path-call →OrpcCapability), andgmail(members →GmailCapability). Capinstructionsdrive both theexec_jstool docs anditx.describe().OrpcCapabilityaddscall({ path, args })for itx path-call; legacyexecuteCodemodeFunctionCalldelegates to it (with mount-awarelistProceduresfor old callers).DIALABLE_LOOPBACKSnow includesOrpcCapabilityandGmailCapability, and the registry force-injectsprojectIdon loopback dial props so project-scoped entrypoints cannot be aimed at another project.codemode-event-payloadhelpers are removed from this path (~200 lines of MCP DO codemode wiring deleted).Reviewed by Cursor Bugbot for commit d0c631f. Bugbot is set up for automated code reviews on this repo. Configure here.
Environment Config Lease
No active environment config lease.
OS
Status: released
Commit:
d0c631fPreview: https://os.iterate-preview-3.com
Summary: Preview app released.
Workflow run
Updated: 2026-06-10T14:31:47.308Z
Semaphore
Status: released
Commit:
071375ePreview: https://semaphore.iterate-preview-3.com
Summary: Preview app released.
Workflow run
Updated: 2026-06-10T14:31:38.132Z