工具定义与统一接口平台

ToolAnything 是一个 Python 工具层,将函数、类方法、HTTP API、SQL 查询或模型推理统一为工具契约,并同时暴露为 MCP、OpenAI tool calling 与 CLI,适用于需要多协议工具服务与治理的开发场景。

  • by AllanYiin
  • Python
  • 混合部署
  • 15 星标
  • 更新于
在 GitHub 查看 AllanYiin/ToolAnything

使用说明

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,不會取得 MCP 2026-07-28 modern semantics。
  • 對外綁定 0.0.0.0 前,必須自行處理 Origin、認證、權限與網路邊界。
  • Model examples 可能需要額外 dependency 或本機 artifact;每個範例 README 會分開標示。

License

MIT