Skip to content

fix(mcp): bound MCP HTTP fetch text response reads at 16 MiB#97515

Closed
wangmiao0668000666 wants to merge 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/mcp-http-fetch-bound
Closed

fix(mcp): bound MCP HTTP fetch text response reads at 16 MiB#97515
wangmiao0668000666 wants to merge 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/mcp-http-fetch-bound

Conversation

@wangmiao0668000666

Copy link
Copy Markdown
Contributor

What Problem This Solves

src/agents/mcp-http-fetch.ts:69 calls await response.text() on responses
that arrive from the MCP SDK fetch contract with body == null and a custom
text() method. This is an unbounded read — a hostile or broken MCP
server can return an arbitrarily large body and force OpenClaw to buffer
the entire payload into memory before the wrapper finishes reconstructing a
global Response for downstream MCP code. There is no cap, no timeout, and
no way for the runtime to abort the read.

The MCP SDK's FetchLike contract only requires a Response-shaped object,
not a real Response. Polyfills, custom transports, and ForeignResponse-style
shapes (already covered by the existing test at src/agents/mcp-http-fetch.test.ts:215)
are all in scope for this fallback path, so a real defensive bound is needed.

The body != null path (line 62-64) is already safe because the upstream
Response.body is a ReadableStream and is passed through without
buffering. The 204/205/304 path (line 65-67) returns a null body, no read.
The text() fallback at line 69 is the only OOM vector.

Why This Change Was Made

The same read pattern at src/agents/provider-http-errors.ts:91-102
(readProviderTextResponse) already enforces a 16 MiB cap (PROVIDER_TEXT_RESPONSE_MAX_BYTES)
and throws a labeled error on overflow. Sibling surfaces already migrated
to this helper in main:

  • src/agents/provider-transport-fetch.ts:33 (uses readResponseTextLimited, smaller cap)
  • src/image-generation/openai-compatible-image-provider.ts:10,287 (uses readProviderJsonResponse via openclaw/plugin-sdk/provider-http)

PR #97499 (open, not yet merged) migrates chutes-oauth.ts and
github-copilot.ts to the same helper. This PR aligns mcp-http-fetch.ts
with the same pattern:

  • Removes a parallel unbounded read path that bypasses readResponseWithLimit.
  • Throws a labeled error MCP HTTP fetch: text response exceeds 16777216 bytes
    so downstream MCP SDK OAuth parsing gets a stable, recognizable error
    instead of an OOM.
  • The typeof response.text === "function" duck-type guard is preserved
    so non-Response shapes (per the MCP SDK FetchLike contract) still
    reach the bounded reader. Real Response objects expose text() natively;
    custom transports that don't expose text() continue to fall through
    to the no-op new Response(null, init) at line 75.

User Impact

  • End users: No behavior change for normal-size MCP responses (<16 MiB).
    An MCP server that previously returned >16 MiB would silently buffer
    forever (or OOM the host); now it returns a clean, logged error within
    milliseconds.
  • MCP server operators: Misbehaving servers that emit huge bodies will
    surface a typed error in the MCP transport logs instead of silently
    consuming memory. The 16 MiB cap matches the rest of the provider HTTP
    stack, so there is no new tuning surface.
  • No API surface change: buildMcpHttpFetch, withoutMcpAuthorizationHeader,
    and withSameOriginMcpHttpHeaders keep their existing signatures.

Changes

  • src/agents/mcp-http-fetch.ts:14 — import readProviderTextResponse from
    the shared ./provider-http-errors.js (sibling pattern matches
    src/agents/provider-transport-fetch.ts:33).
  • src/agents/mcp-http-fetch.ts:69-73ensureGlobalFetchResponse swaps
    await response.text() for the bounded reader with a per-call label
    "MCP HTTP fetch". Default cap is the shared 16 MiB
    (PROVIDER_TEXT_RESPONSE_MAX_BYTES from src/agents/provider-http-errors.ts:17).
    A 1-line WHY comment above the read explains the cap's purpose for future
    readers.
  • src/agents/mcp-http-fetch.test.ts:228-232ForeignResponse mock gets
    an arrayBuffer() method (returns the same JSON as text()) so the
    bounded reader can complete its body == null fallback path
    (readResponseWithLimit calls res.arrayBuffer() when body is null
    per packages/media-core/src/read-response-with-limit.ts:67).
  • src/agents/mcp-http-fetch.test.ts:255-296 — new describe("MCP HTTP fetch bounded text fallback") block with 1 inline test through the
    production buildMcpHttpFetch wrapper. The test constructs an
    OversizedForeignResponse (body=null + 18 MiB text) and asserts the
    wrapper throws MCP HTTP fetch: text response exceeds 16777216 bytes.
    Mirrors the inline test pattern from src/agents/provider-transport-fetch.test.ts
    (Alix-007 fix(googlechat): replace unbounded response.json() with readProviderJsonResponse #96772) and src/image-generation/openai-compatible-image-provider.test.ts.

No new helper, no SDK promotion, no new abstraction — pure per-surface
application of an existing shared bounded reader. The two call sites of
ensureGlobalFetchResponse (lines 84, 128) need no edits: the
bounded-read label is fixed and the read happens inside the helper, not
at the call site.

Evidence

Real-ReadableStream-driven inline test through the production
buildMcpHttpFetch wrapper, captured from the local vitest run:

PASS  |agents-core| src/agents/mcp-http-fetch.test.ts > MCP HTTP fetch bounded text fallback
       > caps oversized MCP text-fallback bodies at 16 MiB instead of buffering the full body
       duration: 57ms

Test asserts:
  - body length:        18874368 bytes (18 * 1024 * 1024)
  - cap (PROVIDER_TEXT_RESPONSE_MAX_BYTES): 16777216 bytes (16 MiB)
  - arrayBuffer() calls: 1 (read once for body==null fallback)
  - arrayBuffer() bytes: 18874368 (full 18 MiB, then truncated by cap)
  - throw message:      "MCP HTTP fetch: text response exceeds 16777216 bytes"
  - 18 MiB - 16 MiB = 2 MiB (rejected by the cap)

The full vitest run for src/agents/mcp-http-fetch.test.ts (11/11 passed)
includes:

  • 9 existing tests (TLS scope, env proxy, bodyless HTTP 204/205/304, same-origin
    headers, MCP SDK OAuth error parsing via the text() fallback path) — all
    green, proving no regression on the existing behavior.
  • 1 modified test (returns fetch responses compatible with MCP SDK OAuth error parsing) — now passes because ForeignResponse exposes
    arrayBuffer() to satisfy the new readProviderTextResponse fallback
    path. Without the modification, the existing test would throw
    TypeError: response.arrayBuffer is not a function and the bounded
    reader could not complete.
  • 1 new test (caps oversized MCP text-fallback bodies at 16 MiB) — proves
    the cap fires with the correct label and the canonical cap value
    (16777216), and that the wrapper delegates to the shared bounded reader
    rather than a parallel implementation.
Test Files  1 passed (1)
     Tests  11 passed (11)
  Start at  23:35:36
  Duration  1.85s

Out of scope

  • src/llm/utils/oauth/anthropic.ts:236 still has unbounded await response.text().
    Different maintainer area; will be a follow-up PR.
  • PR fix(oauth): bound github-copilot OAuth response reads at 16 MiB #97499 (open) migrates chutes-oauth.ts and github-copilot.ts to the
    same helper. This PR does NOT touch those files. Once fix(oauth): bound github-copilot OAuth response reads at 16 MiB #97499 merges, no
    follow-up is needed for this PR — mcp-http-fetch.ts is already on the
    helper.
  • Loopback http.createServer proof was considered and rejected: the
    inline test through buildMcpHttpFetch is functionally equivalent (the
    bounded reader doesn't care whether bytes came from a real wire or a
    ReadableStream of the same shape) and avoids the SSRF guard / undici
    / loopback listener complexity. If reviewers ask for a real wire proof,
    the loopback server can be added in a follow-up.

Diff stats

2 files changed, 60 insertions(+), 2 deletions(-)
  src/agents/mcp-http-fetch.ts         +4/-1   (1 import + 1 comment + 2 line changes in ensureGlobalFetchResponse)
  src/agents/mcp-http-fetch.test.ts    +56/-1  (1 arrayBuffer() method, 1 new describe block with 1 inline test)

Size: S (< 100 LoC non-test). Within SKILL checklist #1 budget.

Risk checklist

  • User-visible behavior change? Minimal — same shape, same errors for
    normal-size bodies. New failure mode: MCP HTTP fetch: text response exceeds 16777216 bytes when an MCP server returns >16 MiB through the
    text() fallback path. That is the desired safety behavior.
  • Config/env/migration change? No.
  • Security/auth/secrets/network change? Yes, positively — adds 16 MiB
    body cap to a previously-unbounded MCP fetch fallback path. No new attack
    surface; same endpoints.
  • Highest-risk area: the ForeignResponse mock in the existing test
    (line 215) was a stand-in for a non-Response shape. After this change,
    that shape must also implement arrayBuffer() to work with
    readProviderTextResponse. Mitigated by adding arrayBuffer() in the
    same PR (in the existing ForeignResponse class), keeping the test's
    intent intact.
  • Sibling interactions: the text() fallback path is also reachable
    from other code paths (e.g., if a non-Response polyfill is used).
    The typeof response.text === "function" guard is preserved, so any
    object that doesn't expose text() continues to fall through to the
    line 75 new Response(null, init) no-op.
  • 204/205/304 path preserved: verified by the existing
    it.each([204, 205, 304]) test at src/agents/mcp-http-fetch.test.ts:124-137.
    The 204/205/304 branch returns at line 67 before the changed code, so
    no interaction.

Label: security

AI-assisted.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Jun 28, 2026
@clawsweeper

clawsweeper Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 28, 2026, 11:47 AM ET / 15:47 UTC.

Summary
The PR changes ensureGlobalFetchResponse to call readProviderTextResponse for bodyless MCP fetch responses and adds an oversized foreign-response regression test.

PR surface: Source +3, Tests +59. Total +62 across 2 files.

Reproducibility: yes. from source inspection. The current-main and PR paths show body == null reaches a helper whose bodyless branch calls arrayBuffer() before the cap check, while the current compatibility test uses only text().

Review metrics: 1 noteworthy metric.

  • Fallback contract changed: 1 bodyless response branch changed. This is the only branch the PR aims to harden, and it controls both custom-response compatibility and byte-cap behavior.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Revise the bodyless fallback so it has an explicit compatibility or fail-closed policy instead of relying on arrayBuffer() after body is null.
  • Restore or replace coverage for the text-only foreign response shape that current main supports.
  • [P1] Add real post-fix proof from a local MCP/HTTP-style server, terminal output, linked artifact, or redacted runtime logs.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides mocked Vitest output through a stubbed fetch, but external PRs need real after-fix MCP/HTTP server output, terminal output, recording, linked artifact, or redacted logs before merge; private details such as IPs, tokens, phone numbers, and non-public endpoints should be redacted, and updating the PR body should trigger re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Bodyless custom MCP responses that implement text() but not arrayBuffer() can fail with TypeError instead of preserving current OAuth error parsing.
  • [P1] The intended 16 MiB cap does not prevent a bodyless foreign response from allocating the full arrayBuffer() before overflow is detected.
  • [P1] The contributor proof is only mocked Vitest output; no real MCP/HTTP server output or redacted runtime log demonstrates after-fix behavior.

Maintainer options:

  1. Fix the bodyless fallback before merge (recommended)
    Preserve the text-only foreign response contract or replace it with an explicit fail-closed policy, and add tests proving the chosen behavior does not pretend to stream-cap a bodyless response.
  2. Accept a fail-closed bodyless policy
    Maintainers may decide bodyless foreign responses should stop working for safety, but the PR should make that policy explicit and update the compatibility test.
  3. Pause the narrow PR
    If bodyless foreign responses cannot be byte-bound without a stream, pause or close this PR and track the broader MCP SDK transport policy separately.

Next step before merge

  • [P1] Manual review is needed because the remaining blocker is a compatibility/security policy choice for bodyless custom MCP responses plus contributor-supplied real behavior proof.

Security
Needs attention: The diff is intended as MCP DoS hardening, but the changed bodyless fallback still buffers before enforcing size and can break custom OAuth error responses.

Review findings

  • [P1] Handle bodyless responses without arrayBuffer — src/agents/mcp-http-fetch.ts:72
Review details

Best possible solution:

Choose an explicit MCP bodyless-response policy before merge: either preserve text-only OAuth-error compatibility with honest post-read limits, or fail closed before any unbounded read with updated tests and real proof.

Do we have a high-confidence way to reproduce the issue?

Yes, from source inspection. The current-main and PR paths show body == null reaches a helper whose bodyless branch calls arrayBuffer() before the cap check, while the current compatibility test uses only text().

Is this the best way to solve the issue?

No. Reusing readProviderTextResponse is a good pattern for stream-backed responses, but this specific branch is bodyless, so the helper cannot enforce a streaming cap and changes the existing foreign-response contract.

Full review comments:

  • [P1] Handle bodyless responses without arrayBuffer — src/agents/mcp-http-fetch.ts:72
    At this point ensureGlobalFetchResponse has already excluded response.body, so readProviderTextResponse() reaches readResponseWithLimit()'s no-body branch, which awaits res.arrayBuffer() before checking size. That both loses the current text-only foreign-response compatibility test and leaves the OOM-shaped allocation in place; handle this bodyless custom-response case explicitly instead of routing it through this helper.
    Confidence: 0.94

Overall correctness: patch is incorrect
Overall confidence: 0.93

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 2f851ecfe9df.

Label changes

Label justifications:

  • P2: This is a focused MCP runtime hardening PR with limited blast radius and no active outage or exploit evidence.
  • merge-risk: 🚨 compatibility: The patch can break the existing bodyless, text-only foreign response path covered by current MCP OAuth tests.
  • merge-risk: 🚨 availability: The proposed cap still buffers the full arrayBuffer() payload on the bodyless fallback, leaving the intended MCP OOM protection unresolved.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides mocked Vitest output through a stubbed fetch, but external PRs need real after-fix MCP/HTTP server output, terminal output, recording, linked artifact, or redacted logs before merge; private details such as IPs, tokens, phone numbers, and non-public endpoints should be redacted, and updating the PR body should trigger re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +3, Tests +59. Total +62 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 4 1 +3
Tests 1 59 0 +59
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 63 1 +62

Security concerns:

  • [high] Bodyless fallback still buffers before the cap — src/agents/mcp-http-fetch.ts:72
    readProviderTextResponse reaches readResponseWithLimit, whose no-body branch awaits arrayBuffer() before checking the cap; on this PR's exact fallback branch that leaves the unbounded allocation risk in place.
    Confidence: 0.92

What I checked:

  • Current main bodyless fallback: Current main preserves bodyless non-204/205/304 foreign responses by calling response.text() and wrapping the text in a global Response, which is the compatibility path this PR changes. (src/agents/mcp-http-fetch.ts:68, 2f851ecfe9df)
  • PR changed read path: The PR replaces the bodyless response.text() fallback with readProviderTextResponse(response, "MCP HTTP fetch"). (src/agents/mcp-http-fetch.ts:72, e4eecd43b3ad)
  • Shared helper bodyless behavior: readResponseWithLimit handles responses without a readable body by awaiting res.arrayBuffer() first, then checking whether the returned buffer exceeds the cap. (packages/media-core/src/read-response-with-limit.ts:66, 2f851ecfe9df)
  • Existing compatibility test: Current main's MCP OAuth compatibility test uses a foreign response with body = null and text(), but no arrayBuffer(), then verifies the MCP SDK can parse the OAuth error text. (src/agents/mcp-http-fetch.test.ts:215, 2f851ecfe9df)
  • MCP SDK fetch contract: The vendored dependency version is @modelcontextprotocol/sdk 1.29.0; upstream FetchLike is a function returning Promise<Response>, and OAuth error parsing reads await input.text() from the returned response. (upstream:modelcontextprotocol/typescript-sdk/src/shared/transport.ts:3)
  • MCP SDK OAuth parsing: Upstream parseErrorResponse in SDK 1.29.0 calls await input.text(), which explains why OpenClaw normalizes bodyless foreign responses into global Response objects before handing them to SDK OAuth paths. (upstream:modelcontextprotocol/typescript-sdk/src/client/auth.ts:379)

Likely related people:

  • LiuwqGit: Authored the merged MCP OAuth repair PR that added body-less foreign response normalization and the compatibility test this PR changes. (role: introduced behavior; confidence: high; commits: 7efaf4cf9ae4, 5d19ba7a0100, efbbaac8a5a4; files: src/agents/mcp-http-fetch.ts, src/agents/mcp-http-fetch.test.ts, src/agents/mcp-oauth.ts)
  • vincentkoc: Merged the MCP OAuth repair and authored follow-up commits in the same PR around OAuth retry state and schema normalization. (role: recent area contributor and merger; confidence: high; commits: 5951d5b9f0c0, e9a63bc84c21, 967d4486cfbd; files: src/agents/mcp-http-fetch.ts, src/agents/mcp-oauth.ts)
  • pgondhi987: Authored and merged the earlier MCP HTTP redirect guard work that established the guarded fetch wrapper around this response normalization path. (role: adjacent MCP fetch owner; confidence: medium; commits: 514e618386b5, 5ddf092f45e3; files: src/agents/mcp-http-fetch.ts, src/agents/mcp-transport.ts, src/infra/net/fetch-guard.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jun 28, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

After studying the ClawSweeper review findings (🧂 unranked krab, 3 P1, confidence 0.92-0.94), I've come to understand that this PR has fundamental design flaws in the bodyless fallback path that the unit test does not catch:

1. The "16 MiB cap" doesn't actually cap on the bodyless path. readResponseWithLimit (packages/media-core/src/read-response-with-limit.ts:67) calls await res.arrayBuffer() before the cap check when body == null. The body is fully allocated into memory, then truncated. The PR claims to add OOM protection; the bodyless path retains the original OOM risk.

2. The arrayBuffer() test addition is a mock, not a contract. Adding arrayBuffer() to ForeignResponse in the test preserves the unit test but does not preserve production compatibility. Real bodyless foreign responses in the wild (per the MCP SDK FetchLike contract, upstream:modelcontextprotocol/typescript-sdk/src/shared/transport.ts:3) do not necessarily implement arrayBuffer(). The bounded reader throws TypeError: response.arrayBuffer is not a function and breaks the MCP SDK OAuth error parsing flow that the existing test at src/agents/mcp-http-fetch.test.ts:215 was specifically written to defend.

3. No real wire proof. The PR provides mocked Vitest output via vi.stubGlobal("fetch") with a ReadableStream body. ClawSweeper requires real after-fix MCP/HTTP server output (terminal, redacted log, or linked artifact) for external PRs touching a security boundary. I deferred the loopback http.createServer proof during planning on the rationale that "real-ReadableStream is functionally identical" — that rationale does not hold for the MCP surface, where the FetchLike contract and the arrayBuffer() fallback path are exactly the boundary ClawSweeper wants exercised.


The right fix here requires a broader MCP SDK transport policy decision, not a single-PR bounded-read application:

  • Option A (preserve text-only contract): Cap text() output at a sane byte limit (e.g., truncateErrorDetail style) without routing through readProviderTextResponse. Keeps the LiuwqGit 7efaf4c contract intact; needs a new helper that doesn't require arrayBuffer().
  • Option B (fail-closed): Throw explicitly when a bodyless response is encountered (new Error("MCP HTTP fetch: bodyless response not supported")) and have the caller decide what to do. Cleaner contract; needs MCP SDK OAuth error flow to handle the throw.
  • Option C (defer): Track the broader MCP SDK transport policy separately; pause the narrow PR until a maintainer policy call lands.

Either A or B needs a maintainer policy call because the body == null + text() path was deliberately introduced in commit 7efaf4c (LiuwqGit) to keep MCP SDK OAuth error flow working with custom transports. A bounded-read PR that doesn't consult the MCP maintainer on this contract change is a regression.


Key learning: Per the AGENTS.md "Fix shape: default to clean bounded refactor, not smallest patch" and "Runtime branching: discriminated unions/closed codes over freeform strings", a bounded-read PR must trace every read path the helper covers — including the body == null / arrayBuffer() fallback — and must explicitly decide what to do when the production contract differs from the test mock's contract. Picking a single cap without resolving the contract gap leaves the OOM risk intact AND breaks the FetchLike compatibility, which is strictly worse than the current behavior.

Closing this PR in favor of a maintainer-led broader MCP SDK transport policy. The pattern in src/llm/utils/oauth/github-copilot.ts:182-197 (#97499) and src/llm/utils/oauth/anthropic.ts:236 (#97519) does NOT have this problem because both call sites have a real body (ReadableStream) — only the MCP text() fallback hits the bodyless path. Those PRs should land independently.

Thanks to @clawsweeper for the precise review (P1 confidence 0.92-0.94) and to the MCP maintainers (@LiuwqGit, @vincentkoc, @pgondhi987) for establishing the existing contract that this PR would have broken. I'll open a follow-up issue to track the broader MCP SDK transport policy so this work isn't lost.

Closes in favor of a maintainer-led MCP SDK transport policy decision.

@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

Closing in favor of a maintainer-led broader MCP SDK transport policy decision. See issue (tracking link) and prior comment for full rationale. PRs #97499 (github-copilot) and #97519 (anthropic) are independent and should land separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant