Skip to content

fix(docs-mcp): Limit request bodies and tool input elements - #1784

Merged
BYK merged 3 commits into
mainfrom
fix/docs-mcp-request-limits
Nov 1, 2026
Merged

BYK merged 3 commits into
mainfrom
fix/docs-mcp-request-limits

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1601. This is the Docs MCP follow-up to #1780, which did the same hardening for the hosted MCP server (GHSA-46jr-4wx8-v453). Docs MCP already resolves @modelcontextprotocol/sdk 1.32.2 through the workspace override, so no SDK upgrade is needed. Both mitigations are opt-in, and this PR turns them on. It also moves the limits out of the hosted server so both servers share them.

Shared limits: @sentry/toolkit-core/mcp-limits. The new module holds:

  • MAX_MCP_REQUEST_BODY_BYTES (1 MiB) and MAX_TOOL_INPUT_ELEMENTS (10,000), moved here from mcp-cloudflare and mcp-core. Their values and sizing rationale are unchanged from fix(mcp): Limit tool input elements and request body size #1780.
  • readBoundedBody, which reads a body up to the cap. A declared Content-Length over the cap is rejected without reading, and streamed bytes are always counted, so bodies without Content-Length (or with a wrong one) are bounded too.
  • boundMcpRequestBody and mcpPayloadTooLargeResponse, which return the same JSON-RPC 413 shape the SDK uses.

The hosted server (mcp-core and mcp-cloudflare) now imports these instead of keeping private copies. Its behavior doesn't change, and its existing body-limit and element-cap tests pass unchanged.

Docs MCP. createMcpServer passes maxToolInputElements. /mcp and /internal/docs bound the body before any JSON parsing. That matters for /mcp because @hono/mcp parses the body itself, so the SDK's own transport limit wouldn't apply. The access check still runs first, so callers outside the service binding still get 403. Docs MCP inputs (at most a 2,000-character query plus 40 context strings, slugs, and a stack summary) fit well within the shared limits.

Error contracts:

  • /mcp: 413 with the JSON-RPC error (code: -32000, Payload Too Large: ...).
  • /internal/docs: 413 with { "error": "Request body must not exceed 1048576 bytes" }. Malformed JSON still gets the existing 400.
  • A tool call over the element cap gets the SDK's isError result before the handler runs, so no doctree fetch or model call happens.

Tests. The body-limit tests live in toolkit-core: a body at the limit, oversized bodies with and without Content-Length, a body larger than its declared Content-Length, the replayed request, and the 413 shape. Docs MCP keeps one test per route to check that the route applies the limits. None of the tests call a model.

I didn't add per-field .max() limits to libs/features. The element budget already bounds them, and a per-field cap would change the published tool schema.

--

View Session in Sentry

Bound /mcp and /internal/docs bodies at 64 KiB before JSON parsing, using
both the declared Content-Length and a streamed byte count. Configure the
MCP SDK's maxToolInputElements at 1,000 (GHSA-46jr-4wx8-v453).

Fixes #1601

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
@vercel

vercel Bot commented Nov 1, 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 Nov 1, 2026 6:16pm UTC

Request Review

@github-actions github-actions Bot added the risk: medium PR risk score: medium label Nov 1, 2026
Comment thread apps/docs-mcp/src/mcp.ts
Comment on lines +153 to +161
new McpServer(
{
description:
"Generates tailored Sentry integration docs by reading docs.sentry.io.",
name: "sentry-docs",
version: "1.0.0",
},
{ maxToolInputElements: MAX_TOOL_INPUT_ELEMENTS },
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

High severity vulnerability may affect your project—review required:
Line 153 lists a dependency (@modelcontextprotocol/server) with a known High severity vulnerability.

ℹ️ Why this matters

Affected versions of @modelcontextprotocol/sdk and @modelcontextprotocol/server are vulnerable to Allocation of Resources Without Limits or Throttling. McpServer places no limit on how many array elements and object keys it validates in tool-call arguments. A single unauthenticated HTTP request within the default 4 MiB body limit can exhaust the Node.js heap during validation and crash the server process (denial of service). After upgrading, also set the opt-in maxToolInputElements McpServer option and lower maxRequestBodySize.

References: GHSA

To resolve this comment:
Check if you expose the McpServer over an HTTP transport (Streamable HTTP, SSE, or createMcpHandler) rather than stdio only and it registers tools that accept input, especially arrays or records.

  • If you're affected, upgrade this dependency to at least version 2.3.0 at pnpm-lock.yaml.
  • If you're not affected, comment /fp we don't use this [condition]
💬 Ignore this finding

To ignore this, reply with:

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

You can view more details on this finding in the Semgrep AppSec Platform here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This doesn't apply to the Docs MCP Worker. The McpServer here comes from @modelcontextprotocol/sdk, which resolves to 1.32.2 through the workspace override, and this PR sets maxToolInputElements on it and caps request bodies at 64 KiB.

The @modelcontextprotocol/server@2.0.0 lockfile entry comes in through @mastra/core, which pins it to exactly 2.0.0. Mastra only imports it for types (dist/tools/types.d.ts), and none of its runtime JS references it. I bundled the Worker with wrangler deploy --dry-run --outdir to check: the only @modelcontextprotocol package in the bundle's source map is sdk@1.32.2. Upgrading the v2 server package wouldn't change what ships.

Leaving this thread open so a human can triage the finding in Semgrep.

@BYK BYK left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we share this logic/code between the main MCP and this one?

Move the body-size guard into @sentry/toolkit-core/request-body so the
hosted MCP server and Docs MCP use the same reader and JSON-RPC 413.
Each server keeps its own byte budget.
Comment thread apps/docs-mcp/src/request-limits.ts Resolved
Comment thread apps/docs-mcp/src/__tests__/mcp.test.ts Resolved
Move MAX_MCP_REQUEST_BODY_BYTES and MAX_TOOL_INPUT_ELEMENTS into
@sentry/toolkit-core/mcp-limits next to the body reader, so the hosted
MCP server and Docs MCP use the same 1 MiB and 10,000-element budgets.
Generic body-limit tests now live in toolkit-core; Docs MCP keeps only
tests that its routes apply the limits.
@BYK
BYK enabled auto-merge (squash) November 1, 2026 18:18
@BYK
BYK merged commit eb2a48d into main Nov 1, 2026
43 checks passed
@BYK
BYK deleted the fix/docs-mcp-request-limits branch November 1, 2026 18:29
betegon pushed a commit that referenced this pull request Nov 2, 2026
Main's shared input limits (#1780, #1784) cover what this branch added for
the hosted MCP, so they replace its MAX_MCP_* constants in mcp-core and the
Code Mode request body limiter. The handler keeps main's
boundMcpRequestBody() and only adds registerCodeModeTools(). Definitions
are regenerated for submit_feedback_to_sentry_team.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017M6odW3kt5i65zATxfz9RX

This branch was successfully deployed

1 active deployment
Preview — 1dfc68f1 Deployed Nov 1, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Limit Docs MCP request bodies and tool input elements

1 participant