Other formats agents might prefer:
markdownjsonllms.txt

Agent? You probably want markdown or json, or Pod over MCP.

Reported issues for MCP Stdio

Pod holds 19 of 72 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to MCP Stdio.

Most discussed

Design: dual-mode Streamable HTTP for the MCP 2026-07-28 draft revision (stateless transport, SEP-2575)

Summary

The next MCP spec revision — draft dated 2026-07-28 — rewrites the Streamable HTTP transport into a stateless, per-request-metadata model (draft changelog). Most of the changes land squarely on gateway code paths. This issue captures the design for supporting both the current revision (2025-11-25, sessioned) and the draft revision (stateless) side by side.

**Revised — see [the design revision comment](https://git

Read the thread · 2026-07-01 · closed · 26 comments

Firestore token store: revoked-family tokens can be resurrected by a stale concurrent writer (residual to #406)

Summary

While implementing the #406 fix (union-merge inside a Firestore transaction for --token-store-firestore's blind-overwrite race), I audited every place that removes an entry from one of _OAuthProvider's six in-memory stores (src/mcp_stdio/server.py). Two categories exist:

  1. Expiry-driven deletes (_gc_locked, the lazy expiry check in _live_entry, the expired-token branch of _token_refresh) — safe to resurrect via merge, because expiry is re-checked independently on ev

Read the thread · 2026-08-23 · closed · 3 comments

Phase 3.5-C′: modern pool polish (reaper, --modern-only, advisories, docs truth-up)

Phase 3.5-C′ per the #270 Phase 3 Re-scope (pool polish + carried advisories).

Scope

  • Idle-TTL/eviction reaper for modern pool children (today: cap-based eviction only, no reaper — the cap is a soft policy that can be exceeded when every child is pending/busy, by design).
  • --modern-only posture flag (re-scope decision D2): opt-in 405 on GET/DELETE for deployments with no legacy clients (405 is SHOULD-strength and scoped to modern-only servers; a dual-era default must keep GET/SSE + DELE

Read the thread · 2026-07-31 · closed · 3 comments

Phase 3.5-E: reverse MRTR bridge (child-initiated sampling/elicitation/roots on the modern face)

Phase 3.5-E per the #270 Phase 3 Re-scope (deferred from Phase 3 by decision D4).

Scope

The reverse MRTR bridge: a pooled legacy child's server-initiated sampling/elicitation/roots requests, translated to InputRequiredResult + client retry on the modern face — the mirror of the relay's Phase 2 PR C.

  • O14 obligations: server-to-client requests ONLY via MRTR; InputRequiredResult only on tools/call/resources/read/prompts/get; requestState is attacker-controlled input — inte

Read the thread · 2026-07-31 · closed · 3 comments

Phase 3.5-D: serve-side subscriptions/listen (modern notification channel)

Phase 3.5-D per the #270 Phase 3 Re-scope (deferred from Phase 3 by decision D4 — not required by AC1/AC2/AC4).

Scope

Serve-side subscriptions/listen: the modern face's notification channel, mirroring what the relay's client side consumes (Phase 2 PR A).

  • O17 obligations (spec-verified in the re-scope): notifications/subscriptions/acknowledged MUST be the first message; io.modelcontextprotocol/subscriptionId stamping on every stream message; filter honoring (echo the honored subset)

Read the thread · 2026-07-31 · closed · 3 comments

Integration test harness: python-sdk v2.0.0 (MCPServer) as the 2026-07-28 reference peer

Motivation

Phase 2 of #270 (PRs #352 / #356 / #358 / #362, shipped v0.32.0–v0.35.0) is pinned by 1,635 unit tests — every one of them against hand-built mocks shaped by our own reading of the 2026-07-28 spec. That blind spot is not hypothetical: PR B initially placed resourceSubscriptions at the top level of params, the relay and its mocks agreed with each other, every test was green — and a compliant server would have silently ignored the filter while the relay read the ack echo as "not

Read the thread · 2026-07-31 · closed · 3 comments

serve: a legacy GET SSE stream leaves its client hanging when the child dies

Found while reviewing #382 (Copilot's first finding on that PR, followed through).

The bug

do_GET's SSE loop is while not backend.closed:, so it ends server-side when the session's child process dies. But the response sends Connection: keep-alive, and BaseHTTPRequestHandler.send_header treats that header as a command — it sets close_connection = False as a side effect.

An SSE body has neither Content-Length nor chunked framing, so the connection close is its delimiter

Read the thread · 2026-08-01 · closed · 2 comments

Phase 3.5-D2: serve-side resourceSubscriptions + child subscribe driving (+ O16 decision)

Split out of #374 by its Final Design (§1.1 — see the design comment there): #374 ships the listChanged trio only; this issue tracks the second half of serve-side subscriptions.

Scope

  • resourceSubscriptions honoring: read the URI list at params.notifications.resourceSubscriptions (A9 nesting), echo the honored subset in the ack at the same path, route notifications/resources/updated per-URI per-stream.
  • Child-side subscribe driving: the gateway sends legacy `resources/subscr

Read the thread · 2026-08-01 · closed · 2 comments

Most recent

Firestore token store: cap-eviction and client-recycling resurrection (residual to #428)

Summary

Follow-up to #406/#428/#429: while adding per-token tombstones for _revoke_family_locked (#428, closing the security-relevant residual — a family-wide revocation is now protected the same way an individual rotation/code-redemption already was), two lower-severity bare-delete paths were deliberately left out to keep that fix focused:

  1. Cap-based eviction (_evict_to_capacity_locked, called from _issue() on access/refresh/consumed_codes/consumed_refresh/`consumed_acc

Read the thread · 2026-08-23 · open · 1 comment

OAuth HTTP traffic (oauth.py, cli.py) is not covered by --max-message-size

Background

PR #417 (--max-message-size, closing #416) bounds unbounded response reads in relay.py's MCP JSON-RPC traffic and serve.py's incoming request body. /code-review medium on that PR found the same CWE-770 class is still open on a different code path: the OAuth HTTP client traffic never goes through _read_bounded/_iter_text_bounded or gets the Accept-Encoding: identity default.

Concretely, unbounded (buffered client.get()/client.post()) reads remain in:

  • `src/mcp_

Read the thread · 2026-08-22 · closed · 0 comments

Support bounded (zip-bomb-resistant) decompression for --max-message-size

Background

PR #417 (--max-message-size, closing #416) bounds how much of an upstream response relay buffers before parsing, and how large a request body serve accepts. During review, ai-review flagged that the cap can be bypassed: httpx.Client() advertises Accept-Encoding: gzip, deflate by default, and resp.iter_bytes()/resp.iter_text() transparently decompress a Content-Encoding-compressed response before the byte count is

Read the thread · 2026-08-22 · closed · 0 comments

Unbounded response/request body reads can OOM the gateway (relay + serve)

Problem

Neither direction of the gateway bounds the size of a message it reads into memory before parsing:

  • relay (client side): every response-consuming call site — resp.read() (used by _post_probe, _post_and_stream's JSON path, _post_parsed, and the initial probe reader) and resp.iter_text() (used by every SSE-consuming path, including run_sse's long-lived reader and the modern era's subscriptions/listen stream) — buffers the remote MCP server's response with no upper

Read the thread · 2026-08-22 · closed · 0 comments

test_poison_cancel_lines_log_once fails on CPython 3.14.7 (passed on 3.14.6)

Symptom

tests/test_relay.py::TestRunModernStdinHandoff::test_poison_cancel_lines_log_once fails on the test (ubuntu-latest, 3.14) job:

FAILED tests/test_relay.py::TestRunModernStdinHandoff::test_poison_cancel_lines_log_once
  - AssertionError: assert 0 == 1
1 failed, 1941 passed

The assertion is err.count("cancel detection failed") == 1, and it gets 0 — the failure path never fires at all, so nothing is logged.

Root cause: a CPython patch bump, not a code change

The runn

Read the thread · 2026-08-13 · closed · 0 comments

--token-store-firestore: blind overwrite races during Cloud Run instance overlap

Context

`--token-store-firestore`'s own `--help` text documents "no lock against two processes sharing one document -- safe ONLY when exactly one serve process ever writes to a given document at a time." A caller can approximate that with Cloud Run's `min/max-instances=1`, but that setting only bounds concurrent instances of a single revision -- it does not prevent the outgoing and incoming instance from running simultaneously during Cloud Run's normal instance lifecycle (a redeploy'

Read the thread · 2026-08-09 · closed · 1 comment

ci(docs): PR runs can evict a queued Pages deployment (shared concurrency group)

Found by AI review on shigechika/zapi-mcp#54, where docs.yml was copied verbatim from here. The template is the right place to fix it.

Problem

docs.yml declares the concurrency group at workflow level:

on:
  push:
    branches: [main]
    paths: [...]
  pull_request:
    paths: [...]

concurrency:
  group: pages
  cancel-in-progress: false

Both event types share the group pages. GitHub keeps only one pending run per group — a newly queued run replaces the previously

Read the thread · 2026-08-06 · closed · 0 comments

Feature request: lightweight FastMCP-free server helper (companion to serve mode)

Problem

mcp-stdio's serve mode is a great way to publish an existing stdio MCP server over HTTP, but it doesn't help with writing that stdio server in the first place. Most small MCP servers reach for mcp.server.fastmcp.FastMCP for that job, which means they inherit a real risk: a major-version bump of the mcp SDK removed mcp.server.fastmcp outright, breaking every FastMCP-based server on the machine in one shot (this actually happened to a fleet of stdio servers I run behind `mcp-

Read the thread · 2026-08-03 · open · 0 comments

ai-review: rendered comment silently drops malformed severity lines, hiding why a finding was mis-classified

Split out of the code review on #392, which fixed the counting/verdict half of PR #363's bot finding R2F1 but not this half.

Background

R2F1 (from #363's AI review) had two clauses:

  1. The unanchored severity: blocking grep miscounted severity: blockingish as blocking, inverting the verdict.
  2. "the rendering filter also removes the invalid severity line, hiding why the finding was classified as blocking."

Issue #365 (closed by #392) only carried clause 1 forward into its "Fix:" text,

Read the thread · 2026-08-02 · closed · 1 comment

test: test_backend_timeout_returns_504 is load-flaky — its monkeypatch also covers its own initialize

Found while gating #384 (the #383 fix). Pre-existing and unrelated to that change — it lives in tests/test_server.py, which #384 does not touch.

Symptom

FAILED tests/test_server.py::test_backend_timeout_returns_504 - assert 404 == 504

Seen once during a full-suite run on a loaded machine (that run took 479 s; an unloaded run of the same suite takes ~197 s). Passes in isolation and on re-runs.

Mechanism — reproduced deterministically

def test_backend_timeout_ret

[Read the thread](https://github.com/shigechika/mcp-stdio/issues/386) · 2026-08-01 · closed · 0 comments

### serve: no session reaping when --session-idle-ttl is unset (dead-child sessions linger)

Split out of #383 per its final design §4 / §6 Q3, so a narrow provable bug fix does not carry a policy change.

## The gap

`SessionRegistry.reap_idle()` checks `backend.closed` **unconditionally**, independent of the TTL math — so a session whose child has died is a reap candidate whenever the reaper runs at all. But `start_reaper()` is a no-op when `--session-idle-ttl` is unset:

```python
def start_reaper(self) -> None:
    """Start the background idle-eviction thread (no-op if TTL disabled)

[Read the thread](https://github.com/shigechika/mcp-stdio/issues/385) · 2026-08-01 · closed · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/shigechika/mcp-stdio/issues).