anthropics / anthropics/claude-ai-mcp
Tool search force-loads every ui-family ("Interactive") tool into each search payload — ~35k unrequested tokens per search, truncating real hits
- Ngôn ngữ chính
- Không có dữ liệu ngôn ngữ
- Star
- 471
- Fork
- 76
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Mô tả
## Summary
On claude.ai, host-side tool search (`tool_search`) appends **every tool whose declaration carries ui-family `_meta`** (`ui` object or legacy `ui/resourceUri`) to **every search result payload**, regardless of the query. With 33 such tools on our connector this adds ~35k tokens of unrequested full definitions per search, and past ~30 appended definitions the payload is **truncated mid-definition** ("Output abbreviated due to length limit"), damaging the actual hits.
## Controlled experiment (2026-08-28)
We served the **same 100-tool MCP server** under four endpoints differing ONLY in widget `_meta` keys, connected each to claude.ai, and ran the identical prompt ("show my meetings for tomorrow", one search each, fresh chat). Loaded-definition counts as reported from inside the conversation:
| Variant (declaration meta) | `ui` obj | legacy `ui/resourceUri` | `openai/outputTemplate` | "Interactive tools" class in connector settings | Full definitions loaded by ONE search | Widget renders |
|---|---|---|---|---|---|---|
| control (all keys) | ✓ | ✓ | ✓ | ✓ (33) | **38** (4 hits + 34 appended) | ✓ |
| no `openai/*` | ✓ | — | — | ✓ (35) | **36** (4 hits + 32 appended) | ✗ |
| no ui-family | — | — | ✓ | **none** | **4 (hits only, zero appended)** | ✗ |
| no `ui` obj, legacy kept | — | ✓ | ✓ | ✓ (35) | **36** (4 hits + 32 appended) | ✓ |
Conclusions:
- The force-load keys on the **ui-family** (either `ui` or legacy `ui/resourceUri`); `openai/outputTemplate` is irrelevant to it.
- Render requires the same ui-family keys, so **the preload is the unavoidable price of having a widget** — a server cannot offer interactive widgets without paying ~1k tokens × (number of widget tools) on every search its users make.
- The appended block is labelled "Interactive UI tools (also loaded)" in the search result and ignores the query entirely: a read-only calendar question loaded 9 invoice/warehouse **write** tools.
## Truncation makes it worse than a cost problem
With 30+ appended definitions the search response is cut mid-definition — in our runs the cut landed **inside the schema of a legitimate hit**, so the model received a broken definition of a tool it actually needed. The preload thus degrades answer quality, not just token cost.
## Expected behaviour
Widget-capable tools should participate in deferred loading like any other tool (load on hit or on first use). If the host needs them pre-registered for rendering, register the **template/resource linkage** without injecting full input schemas of unrelated tools into every search payload — or at minimum cap/lazy-load the appended block instead of truncating real hits.
## Environment
- claude.ai web, Opus 5 (High), custom connector (Streamable HTTP, OAuth DCR+PKCE), ~100 tools, 33 declaring widgets via MCP Apps ext (`@modelcontextprotocol/ext-apps`: `ui.resourceUri` + `openai/outputTemplate`).
- Adjacent but distinct from #401 (deferral not applying at all): here deferral works for plain tools and is **bypassed wholesale for the Interactive class**.
Happy to provide the four endpoint variants for reproduction.
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Đánh giá
Issue này chưa được đánh giá.