Skip to content

Commit a918dc0

Browse files
committed
fix: show raw MCP tool names in server popup and harden MCP client init
- Expose original_tool_names alongside namespaced tools in /api/tools/mcp/servers so the MCP "available tools" popup can render human-friendly names while persona tool matching continues to use namespaced identifiers. - Render the popup list from item.original_tool_names with a fallback to item.tools for forward compatibility. - Replace `assert mcp_client is not None` in _start_mcp_server with an explicit RuntimeError so the post-init invariant still holds when running under `python -O`, which strips asserts. - Tighten the _find_mcp_tool_by_original_name docstring to match the surrounding single-line style.
1 parent 41066ce commit a918dc0

3 files changed

Lines changed: 22 additions & 16 deletions

File tree

astrbot/core/provider/func_tool_manager.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,7 @@ def remove_func(self, name: str) -> None:
321321
break
322322

323323
def _find_mcp_tool_by_original_name(self, name: str) -> MCPTool | None:
324-
"""Best-effort lookup of an MCP tool by its original (pre-namespaced) name.
325-
326-
Prefers active tools to stay consistent with the active-first rule
327-
applied for exact-name matches. When multiple candidates remain, the
328-
one with the lexicographically smallest namespaced name is returned
329-
for deterministic behavior, and a warning is logged.
330-
"""
324+
"""按原始(命名空间前)名查找 MCP 工具,active 优先。"""
331325
matches = [
332326
f
333327
for f in self.func_list
@@ -361,8 +355,7 @@ def get_func(self, name) -> FuncTool | None:
361355
return f
362356

363357
if isinstance(name, str):
364-
# Fallback: look up MCP tool by original (pre-namespaced) name
365-
# for backward compatibility with legacy persona configurations.
358+
# 老 persona 配置按原始 MCP 名回查
366359
mcp_tool = self._find_mcp_tool_by_original_name(name)
367360
if mcp_tool is not None:
368361
return mcp_tool
@@ -609,8 +602,13 @@ async def lifecycle() -> None:
609602

610603
lifecycle_task = asyncio.create_task(lifecycle(), name=f"mcp-client:{name}")
611604
async with self._runtime_lock:
612-
# After successful initialization, mcp_client is guaranteed to be non-None
613-
assert mcp_client is not None
605+
# After successful initialization mcp_client is logically non-None;
606+
# raise explicitly so this invariant still holds under `python -O`
607+
# (which strips `assert`).
608+
if mcp_client is None:
609+
raise RuntimeError(
610+
f"MCP client {name} unexpectedly None after successful initialization"
611+
)
614612
self._mcp_server_runtime[name] = _MCPServerRuntime(
615613
name=name,
616614
client=mcp_client,

astrbot/dashboard/routes/tools.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,25 @@ async def get_mcp_servers(self):
101101
if key != "active": # active 已经处理
102102
server_info[key] = value
103103

104-
# If MCP client is initialized, get tool names from client
105-
# Note: mcp_client.tools contains raw MCP tools (mcp.Tool), not MCPTool
106-
# So we use tool.name directly (no namespace prefix to strip)
104+
# tools 为 namespaced 名(与 personaForm.tools 匹配),
105+
# original_tool_names 为原始名(给 UI 显示)
107106
for name_key, runtime in self.tool_mgr.mcp_server_runtime_view.items():
108107
if name_key == name:
109108
mcp_client = runtime.client
110-
server_info["tools"] = [tool.name for tool in mcp_client.tools]
109+
mcp_tools = [
110+
f
111+
for f in self.tool_mgr.func_list
112+
if isinstance(f, MCPTool) and f.mcp_server_name == name
113+
]
114+
server_info["tools"] = [f.name for f in mcp_tools]
115+
server_info["original_tool_names"] = [
116+
f.original_tool_name for f in mcp_tools
117+
]
111118
server_info["errlogs"] = mcp_client.server_errlogs
112119
break
113120
else:
114121
server_info["tools"] = []
122+
server_info["original_tool_names"] = []
115123

116124
servers.append(server_info)
117125

dashboard/src/components/extension/McpServersSection.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
</v-card-title>
5353
<v-card-text>
5454
<ul>
55-
<li v-for="(tool, idx) in item.tools" :key="idx" style="margin: 8px 0px;">{{ tool }}</li>
55+
<li v-for="(tool, idx) in (item.original_tool_names || item.tools)" :key="idx" style="margin: 8px 0px;">{{ tool }}</li>
5656
</ul>
5757
</v-card-text>
5858
<v-card-actions class="d-flex justify-end">

0 commit comments

Comments
 (0)