跳至主要內容

MCP 工具搜尋

將完整的 MCP 目錄替換為一組固定的虛擬工具(mcp_tool_search、mcp_tool_call、agent_search、skill_search),讓一個可存取數百個工具的金鑰在 tools/list 上永遠只會暴露四個工具。LLM 會依關鍵字搜尋,取得排名後的符合項目,接著以名稱呼叫找到的工具。agent_search 對 A2A 代理程式登錄檔 也採用相同做法,而 skill_search 則用於 LiteLLM 託管的技能登錄檔,兩者都改以嵌入向量而非關鍵字進行排名。

相關文件

快速開始​

在 mcp_tool_search_enabled: true 下使用 object_permission 產生一組金鑰,將其與 mcp_servers(或 mcp_access_groups)配對,讓搜尋有內容可查,接著探索並呼叫。

1. Create a key with tool search enabled
curl -X POST http://localhost:4000/key/generate \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"object_permission": {
"mcp_tool_search_enabled": true,
"mcp_servers": ["github", "slack"]
}
}'
2. tools/list returns only the virtual tools
$ curl -s http://localhost:4000/mcp-rest/tools/list \
-H "Authorization: Bearer $KEY" | jq '[.tools[].name]'
["mcp_tool_search", "mcp_tool_call", "agent_search", "skill_search"]
3. Search discovers the real tools
$ curl -s -X POST http://localhost:4000/mcp-rest/tools/call \
-H "Authorization: Bearer $KEY" \
-d '{"name":"mcp_tool_search","arguments":{"query":"add numbers"}}' \
| jq -r '.content[0].text | fromjson | [.[].name]'
["math-add", "math-multiply"]
4. Call a discovered tool
$ curl -s -X POST http://localhost:4000/mcp-rest/tools/call \
-H "Authorization: Bearer $KEY" \
-d '{"name":"mcp_tool_call","arguments":{"tool_name":"math-add","arguments":{"a":3,"b":4}}}' \
| jq '{result: .content[0].text, isError}'
{
"result": "7",
"isError": false
}

同一組金鑰也可透過 streamable-http 協定端點(/mcp/)供真正的 MCP 用戶端使用:

MCP Python SDK against /mcp/
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async with streamablehttp_client(
"http://localhost:4000/mcp/",
headers={"Authorization": f"Bearer {KEY}"},
) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()

tools = await session.list_tools()
print([t.name for t in tools.tools])
# ['mcp_tool_search', 'mcp_tool_call', 'agent_search', 'skill_search']

found = await session.call_tool("mcp_tool_search", {"query": "add numbers"})
print(found.content[0].text)

result = await session.call_tool(
"mcp_tool_call",
{"tool_name": "math-add", "arguments": {"a": 3, "b": 4}},
)
print(result.content[0].text) # "7"

未加上該旗標的金鑰會維持既有行為不變:tools/list 會回傳完整目錄,而這兩個虛擬工具名稱會因 forbidden 錯誤而遭拒。

將其設為每個新金鑰的預設值​

如果您希望每個新金鑰都預設啟用工具搜尋,而不必讓每個呼叫端都記得加上旗標,請將其放在 litellm_settings.default_key_generate_params.object_permission 中的 config.yaml 下。任何省略該欄位的 /key/generate 請求都會合併預設值;若請求設定了部分 object_permission(例如只設定 mcp_servers),則會保留其明確指定的欄位,並只補上未設定的欄位。

config.yaml
litellm_settings:
default_key_generate_params:
object_permission:
mcp_tool_search_enabled: true
mcp_servers: ["github", "slack"]

預設值會在呼叫端範圍驗證完成之後才合併,因此不會把一般的非管理員個人金鑰請求變成 403。像 mcp_servers 這類以團隊為範圍的欄位,當呼叫端明確設定時,仍會以呼叫端自己的團隊進行檢查;管理員設定的預設值只會套用到已儲存的金鑰,而不會套用到正在驗證的請求。

運作方式​

當在金鑰的 object_permission 上設定 mcp_tool_search_enabled: true 時,無論該金鑰可連到多少個 MCP 伺服器,streamable-http 端點(/mcp/)與 REST 介面(/mcp-rest/tools/list)都只會回傳剛好四個工具:

  • mcp_tool_search(query, top_k=5) 會回傳符合查詢的實際工具排名清單。
  • mcp_tool_call(tool_name, arguments) 會執行 LLM 透過搜尋發現的其中一個工具。
  • agent_search(query, top_k=5) 會回傳金鑰可連到的 A2A 代理程式,並依與 query 中描述的任務之語義相似度排序。這需要 litellm_settings.agent_search_embedding_model;請參閱 搜尋登錄檔。
  • skill_search(query, top_k=5) 會回傳金鑰可連到的 LiteLLM 託管技能(custom_llm_provider=litellm_proxy),並依語義相似度排序。這需要 litellm_settings.skill_search_embedding_model;請參閱 LiteLLM 託管技能上的語義搜尋。

兩個處理常式都會經過與一般 /tools/call 路由相同的已篩選目錄與分派路徑,因此搜尋只會顯示金鑰本來就有權看到的工具,而呼叫仍會透過 _get_allowed_mcp_servers 和 execute_mcp_tool 進行解析。

搜尋演算法​

排序是根據工具的 name 與 description 欄位進行 token 重疊計數;不使用 embeddings,也沒有額外相依性。對於每個請求,proxy 會:

  1. 將查詢轉為小寫,並以空白切分成 tokens("add numbers" 會變成 ["add", "numbers"])。
  2. 對呼叫端可存取的每個工具,建立一個由 lower(name + " " + description) 組成的 haystack。
  3. 依查詢 tokens 在 haystack 中以子字串形式出現的數量為每個工具評分。若某工具同時包含 add 與 numbers,則分數為 2;若某工具只包含 add,則分數為 1。
  4. 移除分數為 0 的項目,依分數由高到低排序,並回傳前 top_k 個(預設 5)。

除了「分數 > 0」之外沒有其他相似度門檻,因此即使查詢只命中一個 token,也仍會回傳相符結果。分數相同的工具之間,順序遵循 Python 對底層目錄的穩定排序。空查詢會回傳空清單。top_k 上的 mcp_tool_search 參數是逐次請求設定的,因此當第一輪結果集太窄時,LLM 可以自行擴大窗口。

必要條件​

需要 LiteLLM v1.92.x 或更新版本。

存取控制​

工具搜尋不會擴大存取範圍。mcp_tool_search 會走與一般 tools/list 處理器相同的已篩選目錄,因此金鑰無法存取的工具對搜尋而言是不可見的。mcp_tool_call 會解析呼叫者被允許的伺服器,套用基於請求 IP 的 filter_server_ids_by_ip 過濾,並透過 execute_mcp_tool 進行派送,而後者會強制執行伺服器允許清單與呼叫者的 mcp_tool_permissions。嘗試將 mcp_tool_call 路由到金鑰範圍之外的伺服器時,會由保護直接呼叫的同一個防護機制回傳 403:

$ curl -s -X POST http://localhost:4000/mcp-rest/tools/call \
-H "Authorization: Bearer $KEY" \
-d '{"name":"mcp_tool_call","arguments":{"tool_name":"secret-server-delete_all","arguments":{}}}'
{"detail":"User not allowed to call this tool. Allowed MCP servers: [math]"}

在任何具有 /key/info 的金鑰上檢查該旗標:

curl "http://localhost:4000/key/info?key=$KEY" \
-H "Authorization: Bearer $ADMIN_KEY" \
| jq '.info.object_permission | {mcp_tool_search_enabled, mcp_servers}'

何時使用工具搜尋與語意篩選器​

這兩項功能都用來解決大型目錄膨脹問題,但它們位於不同層級。工具搜尋是每個金鑰在 MCP 層級的選用功能;LLM 會看到三個工具,並透過 MCP 協定自行驅動探索,這適合端到端都使用 MCP 的代理程式框架。語義篩選器 位於 /v1/responses 與 /v1/chat/completions 上,並在每次請求時使用嵌入向量重寫工具清單,這適合完全不直接接觸 /mcp/ 的 chat-completion 呼叫端。兩者可以共存;開啟工具搜尋的金鑰即使在上游啟用語義篩選,也只會暴露這三個虛擬工具。

LiteLLM Enterprise
為正式環境打造的 SSO/SAML、稽核記錄、支出追蹤、多團隊管理與防護欄。
深入瞭解 →