Playwright MCP#5
Open
gsanseverino wants to merge 7 commits into
Open
Conversation
Streamable HTTP (transport: http) is flaky against many MCP servers — sessions
get dropped on the first tools/call ("HTTP 404: Session not found"). Adding sse
as a third discriminated-union arm lets configs reach those servers via the
legacy /sse endpoint, which @ai-sdk/mcp already supports.
Wires the upstream mcr.microsoft.com/playwright/mcp image into the local stack so the out-of-the-box agent has browser-automation tools. --allowed-hosts=* is required for docker-network addressing; the example config reaches it through the new sse transport since the streamable-http endpoint sheds sessions.
Records the conversation behind the sse-vs-http transport choice and the docker-compose wiring, so future readers don't have to rediscover why we expose a third transport variant instead of using streamable HTTP.
Bumps ai 5.x -> 6.x, @ai-sdk/{anthropic,google,openai} 2.x -> 3.x,
@ai-sdk/openai-compatible 1.x -> 2.x, @ai-sdk/mcp 0.x -> 1.x. Tests
follow the V2 -> V3 rename of MockLanguageModel and the new shape of
usage / finishReason in LanguageModelV3.
Attempted (and failed) as a fix for the streamable-HTTP hang against
Playwright MCP — the @ai-sdk/mcp HttpMCPTransport still drops the POST
response body's events at 1.0.42, so example.config.yaml stays on the
sse transport. Upgrade itself is worth keeping to stay current.
Pins down the actual bug (AI SDK HttpMCPTransport's processEvents drops the POST response stream, not Playwright MCP session expiry) and notes that bumping to @ai-sdk/mcp@1.0.42 did not fix it.
undici's default 5-min bodyTimeout aborts the silent SSE GET stream MCP
servers keep open between tool calls. When that abort fires on the agent
side, Playwright MCP sees res.on('close'), deletes the session and closes
the browser. The next tool call then hangs forever because @ai-sdk/mcp's
SSE transport.send() calls onerror but doesn't propagate non-2xx as a
rejection — the request promise never resolves.
Use undici's own fetch (its Dispatcher is incompatible with Node's bundled
fetch) routed through a private Agent with bodyTimeout disabled, scoped
only to MCP traffic so LLM API calls keep their normal timeouts.
Verified: 10-min idle between calls no longer triggers Playwright MCP
session/browser teardown; post-idle tool call returns in ~6s instead of
hanging.
Records the root cause (undici's default body timeout abandoning the SSE GET, server tearing down the session, AI SDK's SSE send() not propagating non-2xx as a rejection) and the dedicated-dispatcher fix.
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.
No description provided.