Skip to content

feat(mcp): add MCP-024, TypeScript tool HTTP call has no timeout - #85

Open
bradAGI wants to merge 1 commit into
trustabl:mainfrom
bradAGI:feat/mcp-ts-network-timeout
Open

bradAGI wants to merge 1 commit into
trustabl:mainfrom
bradAGI:feat/mcp-ts-network-timeout

Conversation

@bradAGI

@bradAGI bradAGI commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

MCP-004 covers the Python side of network timeouts; the TypeScript half was missing, even though the pack ships TS rules (MCP-011, MCP-013). OpenAI (OAI-016, OAI-024) and the Vercel AI SDK (VAI-011) already use has_http_call_without_timeout for exactly this.

What makes the MCP case its own is that the stall crosses the server's trust boundary rather than staying local. The connecting client is waiting on a JSON-RPC response that never arrives — and MCP gives it no way to cancel an in-flight tool call, so it's left to its own timeout, an abandoned request, or a hung session, with nothing in the response saying why. The server author never sees the symptom; the client's users do.

On a stdio server it's worse than one slow tool: a single process serves the connection, so a handler parked on a dead socket is holding it.

Compounds with MCP-013 the same way VAI-011 compounds with VAI-003 — a handler that fetches a caller-controlled URL and can't time out can be steered at an internal host that never answers.

Verification — engine built at main:

$ trustabl rules validate .
OK: 85 rule pack(s), 207 rule(s) valid under rule schema version 14

Fire (bare await fetch(...) in a server.tool(...) handler): MCP-013, MCP-024
Silent (signal: AbortSignal.timeout(15_000)): MCP-013

(MCP-013 is the pre-existing SSRF rule firing on the fixture's template-string URL — also the compounding case the explanation describes.)

No new predicates, so no schema_version bump.

MCP-004 covers the Python side; the TypeScript half was missing even
though the pack ships TS rules (MCP-011, MCP-013). OpenAI (OAI-016,
OAI-024) and the Vercel AI SDK (VAI-011) already use
has_http_call_without_timeout for exactly this.

The stall crosses the server's trust boundary rather than staying local:
the connecting client waits on a JSON-RPC response that never arrives,
and MCP gives it no way to cancel an in-flight tool call, so it is left to
its own timeout, an abandoned request, or a hung session, with nothing in
the response saying why. On a stdio server a handler parked on a dead
socket is holding the single process that serves the connection.
@jhumel-code

Copy link
Copy Markdown
Collaborator

Thanks @bradAGI. MCP-024 is clean against the schema: every required field is present, mcp_tool is a valid applies_to at tool scope, and language: typescript is stated explicitly, which it has to be for a predicate that only has a TS path. You are right that no schema_version bump is needed, since has_http_call_without_timeout has been on main since schema 14, and the ID does not collide with anything on main or with any other open PR.

Severity high at confidence 0.6 matches OAI-016 and VAI-011 exactly, which is the right call. The underlying fact cannot see an options object built on an earlier line and passed by identifier, so the same blind spot that calibrated those two applies here. MCP-004 stays language: python, so there is no double fire on a repo that ships both. The explanation names the concrete MCP consequence rather than borrowing the OpenAI framing, and the cross reference to MCP-013 is a nice touch.

The fixture mirror in trustabl/agent-reliability-analyzer#159 is byte identical to this block, so the two need to land together. The one piece still outstanding is a rationale doc in trustabl-rulebook before this ships; that is on us, and we can pair on it if you want a hand.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants