Fixed
-
MCPTOON_CALL_TIMEOUTnow actually extends a call. The gateway read the
documented env var but used it only for its own worker-thread wait; the MCP
client underneath kept its separate 30s default, so a call configured for 900s
still died at 30s with[RESPONSE_TIMEOUT] ... within 30s (server went silent)
while the upstream process kept running and its result was lost.MCPClientPool
now takes a default per-request deadline and forwards it to every client it
creates, and both construction sites inserve.pypass_get_call_timeout().
An explicit per-server"timeout"inconfig.jsonstill wins, so the
workaround in the report keeps working. Reported as #34. -
mcptoon_callnow answers in the shape it advertises. Under the default
compact exposure every upstream call is routed throughmcptoon_call, which
declares anoutputSchemarequiringtoolandserver. The escape hatch
re-entered the direct-call path and returned that path's envelope verbatim, so
when the upstream tool answered with its ownstructuredContent(e.g.
{"entities": [], "relations": []}from a graph tool) the response did not
match the schema the gateway itself published — and a strict client rejected
every such call. The answer is now rebuilt as{tool, server, result},
including on a routed error, so the declared schema is always satisfied. A
side effect of the #22 fix; reported as #33. Workaround until release:
mcptoon config set exposure full. -
The destructive-op guard now honours MCP
annotationsand inspects
arguments._check_dangerousmatched only the tool name against a
substring list and never read theannotationsobject it exists to consume,
so it was both too loose and too strict at once: atruncate_tabletool that
declareddestructiveHint: trueran with no confirmation, a neutral
run_querycarrying{"sql": "DROP TABLE customers"}passed untouched, and a
clear_cacheannotatedreadOnlyHint: truewas refused for containing
clear. The screen now readsreadOnlyHint: truefirst and lets it clear the
name check, treatsdestructiveHint: trueas dangerous regardless of the
name, keeps the substring list as a fallback for the many servers that ship no
annotations (now also catchingtruncate/overwrite/execute/run_), and
inspectssql/command-style arguments for destructive statements. The
gateway path passes the in-memory annotations straight in; the CLI path reads
them from the tool cache (never spawning a server). Reported by an external
tester on 0.8.26 with a minimal repro and the fix location.