使用说明
ToolAnything
定義一次工具,同時提供 MCP、OpenAI tool calling 與 CLI 使用介面。
概覽
ToolAnything 是 Python 工具層:它把 Python function、class method、HTTP API、SQL query 或 model inference 整理成同一份工具契約,再交給 MCP server、OpenAI adapter、CLI 與診斷工具使用。你不需要為每個協議各維護一份 schema,也不需要把外部來源再包成沒有實質邏輯的 wrapper function。
ToolAnything 專注在「工具如何定義、暴露、呼叫與治理」。它不是完整的 agent framework,不負責 memory、planning、workflow orchestration 或產品 UI。
適用範圍
適合:
- 把 Python function 或 class method 暴露成 MCP/OpenAI tool。
- 直接把 HTTP、SQL、ONNX 或 PyTorch source 註冊成 tool。
- 建立可重用的 MCP server,並用
doctor或inspect驗證。 - 讓同一份工具契約支援 MCP、OpenAI tool calling 與 CLI。
- 使用內建 filesystem、web、data standard tools,並保留明確的安全邊界。
如果你只需要一次性、單一 function、MCP-only 的原型,而且不需要 CLI、診斷、shared server 或 source-based API,較小的 MCP wrapper 可能更合適。
Prerequisites/Requirements/環境需求
- Python
>=3.10,<3.14 - MCP Python SDK
>=2.0.0,<3 - ToolAnything
0.0.7(目前專案版本)
安裝正式套件:
python -m pip install toolanything
在本 repo 開發:
git clone <repository-url>
cd ToolAnything
python -m pip install -e ".[dev]"
五分鐘快速開始
這條路徑會建立一支 calculator.add 工具、啟動 Streamable HTTP server,最後實際執行 MCP discovery、tools/list 與 tools/call。
1. 建立 tools.py
from toolanything import tool
@tool(name="calculator.add", description="加總兩個整數")
def add(a: int, b: int) -> int:
return a + b
2. 啟動 MCP server
toolanything serve tools.py --streamable-http --host 127.0.0.1 --port 9092
MCP endpoint 是 http://127.0.0.1:9092/mcp。新的遠端整合建議使用這個模式。
3. 在另一個終端機驗證
toolanything doctor --mode http --url http://127.0.0.1:9092
成功時,報告中的 discovery/initialize、tools/list 與 tools/call 都會是 PASS。doctor 預設先探測 modern protocol,必要時才回退到 legacy protocol。
若要手動檢查 schema 與 tool call:
toolanything inspect
4. 改用 stdio
Claude Desktop 或其他會啟動本機子程序的 host 通常使用 stdio:
toolanything serve tools.py --stdio
驗證方式:
toolanything doctor --mode stdio --tools tools
完整入門路線見 examples/quickstart。
MCP 新舊協議如何共存
預設 sdk_v2 backend 會在同一個 stdio process 或 /mcp endpoint 支援兩個明確版本:
| 協議版本 | 啟動方式 | HTTP 狀態模型 | 主要差異 |
|---|---|---|---|
2026-07-28 modern |
server/discover |
request-scoped、無 protocol session | 不使用 Mcp-Session-Id、獨立 GET /mcp 或 DELETE /mcp |
2025-11-25 legacy |
initialize |
session-based | initialize 後取得 Mcp-Session-Id,後續 request 綁定該 session |
Server 會根據 request 宣告的 protocol version 分流;不是在啟動 server 時選一個版本後永久鎖定。因此一般情況維持預設即可:
toolanything serve tools.py --streamable-http
若要分別驗證兩個世代:
toolanything doctor --mode http --url http://127.0.0.1:9092 --protocol-mode modern
toolanything doctor --mode http --url http://127.0.0.1:9092 --protocol-mode legacy
這裡的 --protocol-mode 是診斷 client 的探測選擇;在 sdk_v2 server 上不會停用另一個世代。
如果 SDK backend 發生相容問題,可以回退到只提供 legacy profile 的 built-in backend:
toolanything serve tools.py \
--streamable-http \
--mcp-backend legacy_builtin \
--protocol-mode legacy
如果 client 仍綁定舊式 GET /sse + POST /messages/{session_id} transport:
toolanything serve tools.py --legacy-http --host 127.0.0.1 --port 9090
--legacy-http 會自動選擇 legacy_builtin。協議世代、backend 與 transport 是三個不同概念,詳細對照見 MCP transports 範例。
MCP 2026-07-28 支援狀態
ToolAnything 目前以官方 MCP Python SDK v2 負責 wire protocol:
| Gate | 結果 | 範圍 |
|---|---|---|
| M1 Full Server | 37/37 PASS | Tools、Resources、Prompts、Completion、MRTR、transport、cache |
| M2 Full Client | 32/32 PASS | Tools、metadata、OAuth/CIMD/issuer/scope、MRTR、headers、$ref |
| M3 Extensions | PASS | Subscriptions、Tasks、MCP Apps security boundary、EMA 10/10 |
沒有使用 expected failures。Current advisory 的 server/client JSON Schema 2020-12 preservation 另外通過 8/8 與 9/9。可重跑證據見 MCP full-support baseline。
使用方式:工具來源怎麼選
| 來源 | 建議 API | 範例 |
|---|---|---|
| Python function | @tool(...) |
quickstart |
| Class method | @tool(...) + @classmethod |
class method tools |
| HTTP API | register_http_tool(...) 或 HTTP source spec |
HTTP source |
| SQL query | register_sql_tool(...) 或 SQL source spec |
SQL source |
| ONNX/PyTorch model | register_model_tool(...) 或 model source spec |
model sources |
| 內建通用工具 | register_standard_tools(...) |
standard tools |
判斷原則:
- 穩定的 Python callable 或 class method:使用
@tool(...)。 - 真正來源是 HTTP、SQL 或 model:使用 source-based API。
- 要給 agent 長期重用:啟動後一定執行
doctor或inspect。
Standard tools 與安全邊界
內建 standard tools 涵蓋 filesystem、web 與常見資料格式。預設註冊唯讀工具;寫入與 browser provider 必須明確 opt in。
from pathlib import Path
from toolanything import ToolRegistry, register_standard_tools
from toolanything.standard_tools import StandardToolOptions, StandardToolRoot
registry = ToolRegistry()
register_standard_tools(
registry,
StandardToolOptions(
roots=(StandardToolRoot("workspace", Path.cwd()),),
),
)
主要安全規則:
- filesystem tools 只能存取設定的 root。
standard.fs.write等寫入工具預設不註冊。- 啟用寫入時必須同時設定
include_write_tools=True與 writable root。 - 覆寫與 patch 路徑使用 SHA-256 guard,避免在內容已變更時靜默覆蓋。
standard.web.fetch只處理受 policy 限制的文字型 HTTP(S) 資源,不是互動式瀏覽器或 PDF reader。
完整清單與執行方式見 standard tools 文件。
OpenAI tool calling
同一份 registry 可以輸出 OpenAI tool schema,也可以交給 OpenAIChatRuntime 執行 tool loop:
from toolanything import OpenAIChatRuntime
runtime = OpenAIChatRuntime()
result = runtime.run(
model="<openai-model>",
prompt="請使用 calculator.add 計算 2 + 3。",
)
print(result["final_text"])
真實 API 呼叫需要 OPENAI_API_KEY。若只想驗證 schema 與本地執行流程,先使用 doctor、inspect 或 basic tool chatbot 的 deterministic requester。
Prompt-cache-friendly tool bundles
工具順序或 volatile metadata 改變時,送給模型的 tools prefix 也會改變。to_prompt_cache_bundle() 會 canonicalize 工具清單並產生 catalog_hash:
bundle = registry.to_prompt_cache_bundle(provider="openai", adapter="openai")
print(bundle.catalog_hash)
print(bundle.tools)
這個 projection 不取代 to_openai_tools() 或 to_mcp_tools()。它讓 host 可以在重連或收到 list-changed event 後,只在 catalog hash 真正改變時更新工具前綴。完整案例見 prompt cache 範例。
常用 CLI
選擇 transport
# 新的遠端 HTTP 整合
toolanything serve tools.py --streamable-http --host 127.0.0.1 --port 9092
# Desktop/本機 subprocess host
toolanything serve tools.py --stdio
# 舊式 HTTP + SSE client
toolanything serve tools.py --legacy-http --host 127.0.0.1 --port 9090
匯出成 CLI
toolanything cli export \
--module tests.fixtures.sample_tools \
--app-name mytools
toolanything cli run \
--config toolanything.cli.json \
-- math add --a 2 --b 3 --json
產生 Claude Desktop 設定
toolanything init-claude --module examples/opencv_mcp_web/server.py --port 9090
install-claude 會直接修改本機 Claude Desktop 設定;執行前先確認輸出路徑與既有設定。CLI reference 見 wiki/CLI-Reference.md。
Examples 與文件導覽
| 目標 | 入口 |
|---|---|
| 第一次成功註冊並呼叫工具 | examples/quickstart |
| 選擇 MCP transport/理解雙協議 | examples/mcp_transports |
| 研究 legacy session lifecycle | examples/streamable_http |
| 建立官方 SDK client | examples/mcp_client |
| 使用 Resources、Prompts、Completion | examples/resources_prompts |
| 直接註冊 HTTP、SQL、model source | examples/non_function_tools |
| 使用內建通用工具 | examples/standard_tools |
| 看完整 examples 地圖 | examples/README.md |
| 查 MCP 完整 API | docs/mcp-full-support-api.md |
| 升級或回退 MCP backend | docs/mcp-2026-07-28-migration.md |
| 理解架構與擴充點 | docs/architecture-walkthrough.md |
| 查所有文件 | docs/docs-map.md |
開發與驗證
完整測試:
pytest
文件建置:
python scripts/generate_api_docs.py
mkdocs build
如果修改 CLI、runtime、transport、adapter、metadata 或 examples,請執行對應測試;README 中的命令不是行為正確性的替代品。
已知限制
- Python 3.14 尚未列入支援範圍。
legacy_builtin是 rollback path,不會取得 MCP2026-07-28modern semantics。- 對外綁定
0.0.0.0前,必須自行處理 Origin、認證、權限與網路邊界。 - Model examples 可能需要額外 dependency 或本機 artifact;每個範例 README 會分開標示。
License
MIT
