Skip to content

feat(mcp): add HTTP Code Mode with explicit API permissions - #1670

Open
betegon wants to merge 6 commits into
mainfrom
bt/code-mode-http
Open

betegon wants to merge 6 commits into
mainfrom
bt/code-mode-http

Conversation

@betegon

@betegon betegon commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Code Mode is the MCP equivalent of sentry api: agents can use published API operations without a dedicated MCP tool.
The client's agent writes JavaScript; our Cloudflare sandbox executes authenticated HTTP calls and returns the result.

For example: “Copy this dashboard for two projects, preserving its widgets and filters.” The existing tool catalog cannot do this; Code Mode can.

search_sentry_api discovers the schema and execute_sentry_code runs the program. This version is HTTP-only; the SDK remains future work.

Server-side Code Mode over standard MCP: the client sends code through tools/call, Sentry executes it in a Cloudflare sandbox, and only the selected result returns to the model.

Prerequisite #1676 is merged. Stack: this PR → #1675 (agent evals). Runtime and permission safety tests remain here.

Code Mode architecture: generated code calls an RPC broker in the parent Worker; the token stays outside the sandbox.

Permissions

The Sentry token authenticates API calls; its OAuth scopes and the user's Sentry permissions set the maximum access.
The permission screen controls which of those actions this MCP connection may perform, without changing the token or its scopes.

  • API Read permits reads. API Write includes reads and enables create/update/delete. It starts unchecked; explicitly remembered selections are preserved.
  • Permissions are additive: API Write can modify issues even with Triage Issues unchecked, and projects/teams with Manage Projects & Teams unchecked. The consent screen explains this before approval.
  • The screen shows the scope: /mcp covers organizations authorized by the Sentry token; /mcp/{org} is restricted to that organization. Project-scoped connections do not expose Code Mode.
  • Direct Sentry-Bearer connections default to all active skills, including API Write: the client already holds the token. skills / disable-skills can narrow access; token permissions and connection constraints still apply.
  • Existing grants gain no new permissions. Shared upstream OAuth scopes stay unchanged; the broker checks the MCP grant on every call, and Sentry still enforces token, role and resource permissions. Credentials stay outside generated code.
Sentry MCP permissions: organization scope, API Write unchecked, and additive permissions warning

Validation and before production

Executions now close pending RPC, abort in-flight HTTP and block requests whose authorization finishes after execution ends. Programs must await API calls before returning; accepted writes cannot be rolled back. See the lifecycle validation.

Passed locally on c50537e7: 476 hosted-handler Cloudflare tests + 32 isolated runtime/access tests, 1,884 core tests (six skipped), 89 stdio tests, workspace typecheck/lint and documentation links. Coverage includes settled unawaited HTTP failures, handled-error controls, consent preference round trips, and a real 30-second timeout that closes the upstream connection while preserving an accepted write.

The full workspace test run remains blocked in unchanged CLI code: malformed delta-patch fixture, a musl test on macOS, missing Xcode actool, and an issue-unlink assertion (12,683 CLI tests passed). Published with an explicit exception for these CLI failures; no CLI fixes are included. CI for this commit is pending.

Pending before production: real hosted OAuth-to-API authorization and Cloudflare CPU/termination/concurrency enforcement. Local workerd tests do not establish these platform guarantees. No production deployment performed.

@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
sentry-local Ready Ready Preview Oct 30, 2026 5:54pm UTC

Request Review

Comment thread packages/mcp-core/src/server.ts Resolved
@betegon
betegon changed the base branch from main to bt/cloudflare-test-runtime October 27, 2026 10:32
@betegon
betegon force-pushed the bt/cloudflare-test-runtime branch from 7fb178a to 49d10be Compare October 27, 2026 13:28
betegon added a commit that referenced this pull request Oct 27, 2026
The Cloudflare test plugin still used an older Miniflare/workerd than
Wrangler, so updating the direct dependency alone left different
runtimes in local and integration tests.

Switch to `@cloudflare/vitest-plugin` 1.4.6 and align Miniflare/workerd
with Wrangler. Miniflare 5 removed `fetchMock`; an Undici outbound
service preserves the existing fixtures and `disableNetConnect()`
policy.

This is the prerequisite for #1670 (HTTP Code Mode), followed by #1675
(agent evals). Only seven test/dependency files move here; the broker,
permissions and production integration remain in #1670.

Validated independently on Node 24: **443 Cloudflare tests across 34
files**, root typechecks, lint and frozen install. The earlier full
workspace run had unrelated CLI fixture/platform failures; CLI fixes are
excluded. No deployment performed.
Base automatically changed from bt/cloudflare-test-runtime to main October 27, 2026 13:42
@betegon
betegon requested a review from BYK October 28, 2026 12:27
@betegon
betegon marked this pull request as ready for review October 29, 2026 21:17
@github-actions github-actions Bot added the risk: high PR risk score: high label Oct 29, 2026

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Bound broker access and HTTP work to one execution so unawaited calls and late authorization cannot start writes after the result. Cover cleanup and the real deadline with Worker integration tests.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4e625e9. Configure here.

Comment thread packages/mcp-core/src/skills.ts Resolved
@github-actions github-actions Bot added risk: medium PR risk score: medium and removed risk: high PR risk score: high labels Oct 30, 2026
@github-actions github-actions Bot added risk: high PR risk score: high and removed risk: medium PR risk score: medium labels Oct 30, 2026
import type { ServerContext } from "@sentry/mcp-core/types";
import { createMcpHandler } from "agents/mcp/server";
import { limitMcpRequestBody } from "../../code-mode/http";
import { registerProductionCodeModeTools } from "../../code-mode/production";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Mode catch-path errors omit structuredContent despite outputSchema

search_sentry_api and execute_sentry_code declare outputSchema, but evaluate()'s catch path in code-mode/worker.ts returns an isError result without structuredContent, breaking the outputSchema contract.

Evidence
  • getCodeModeToolDefinitions() assigns codeModeResultSchema as the output schema for both Code Mode tools; the schema requires stats and exactly one of result or error.
  • registerProductionCodeModeTools() registers these tools on the authenticated server when the relevant skills are granted.
  • evaluate() returns structuredContent for parsed results and sandbox-returned errors, but its catch block returns only isError and text content.
  • The worker test exercises invalid code as a reachable catch-path error; that result has no structuredContent.

Identified by Warden · mcp-audit · 3B9-2CT

This branch was successfully deployed

1 active and 1 inactive (outdated) deployments
Preview — c50537e7 Deployed Oct 30, 2026 by vercel[bot]
Actions — 2718d905 Deployed Oct 26, 2026 by betegon via eval #1365
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants