Pull requests / #3135
#3135 serve: a bare MCP tool name runs the one tool that offers it, and an unoffered name becomes an error (#3113)
open · @ctr-137 · 0 コメント · GitHub で見る
Server & APIModels & quantsDocumentationWindows
本文
Issue: #3113 (duplicate #3112; the second half of #3075) ## Summary The MCP servers load, the server window lists their tools, and the chat still never runs one. The reproduced cause: the model writes the tool's **bare** name (`list_directory`), while Strata offers the namespaced route (`filesystem__list_directory`). `run_with_mcp` treated every name that is not in `mcp_names` as one of the request's own tools, returned it as an OpenAI `tool_calls` delta - and the web chat has no handler for `tool_calls`. Nothing ran, and nothing was shown. Against the real `npx -y @modelcontextprotocol/server-filesystem`, with the 14 tools in the prompt: | the model wrote | what happened | | --- | --- | | `<function=list_directory>` | no `strata_mcp` events, a client `tool_calls` delta named `list_directory`, nothing ran | | `<function=filesystem__list_directory>` | `start` / `call` / `result`, the tool ran | That is the "backend loaded 14 tools, the Web UI never uses them" report in #3113. ## What changed - `run_with_mcp` now takes the request's own tool names (`own_names`). A call to one of those goes back to the client exactly as before - the request's tools still win a name clash. - A call with a name the request did not declare is resolved against the MCP tools this request offered: if exactly one offered tool has that bare name, it runs under its namespaced route. - If two servers offer the name, or no offered tool has it, the model gets an `error:` result naming the full `<server>__<tool>` routes, so it can correct itself; the chat page shows the block. Before, the call disappeared. - The `tool_start`/`tool_args`/`tool_call` events of an MCP call are still kept off the client stream, and the continuation prompt names the route that actually ran, so the call and its result agree. - `docs/DETAILS.md`: one bullet under "Tools from MCP servers". Only requests with `"strata_mcp": true` (the chat page's opt-in) take this path. The default API path is unchanged: a request that declares no MCP opt-in still returns tool calls to its client exactly as before. ## How this was checked `python -m unittest serve.test_mcp` - **29 tests, OK**, four of them new: - a bare `echo` runs `fake__echo`, with `start`/`call`/`result`, no client tool call, and the result in the next prompt; - an unoffered `nope` becomes an `error:` result naming `fake__echo`, and the model gets a second round; - a bare `echo` offered by two servers is an error naming both routes (no guessing); - a request that declares its own `echo` keeps it: the client answers, not the MCP server. The full `serve` suite: **852 tests; the only error is `test_winjob.TestWinJob`** (a Windows `tasklist` call returning `None` here), the same one as on unmodified `main` (848 tests). `test_keepawake` is timing-flaky under the full run and passes alone; neither is related to this change. No new skips. ## What I left alone Three neighbouring MCP failure modes are real and worth their own PRs, but are not this change: - `serve/web/app.js:407-417`: one failed `GET /mcp` disables MCP tools for the life of the tab (no retry unless a server is literally `starting`). This can produce the same symptom as #3113. - `serve/server.py`: the hard-coded `svc.mcp.wait(10)` in `_openai` omits a still-starting server from the first chat. - `serve/mcp.py` `HttpTransport._post`: `http.client.IncompleteRead` is not caught, so a truncated HTTP answer can leave the server on "Starting" instead of "Failed". Images returned by MCP tools (#2130) and the 10 s start wait are untouched as well. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
関連リンク
インストール・モデル・リリースへの站内リンク。