Skip to content

Commit 16f4208

Browse files
committed
sanitize MCPTool name for LLM provider compatibility
1 parent 68f643d commit 16f4208

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

src/agentscope/tool/_adapters.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""Adapters to convert functions and MCP tools to ToolProtocol."""
33
import inspect
44
import json
5+
import re
56
from contextlib import _AsyncGeneratorContextManager
67
from datetime import timedelta
78
from typing import Callable, Any, AsyncGenerator, Generator
@@ -199,7 +200,22 @@ def __init__(
199200
The timeout in seconds for tool execution.
200201
"""
201202
self.mcp_name = mcp_name
202-
self.name = f"mcp__{self.mcp_name}__{tool.name}"
203+
204+
# OpenAI APIs enforce ^[a-zA-Z0-9_-]+$ on tool names;
205+
# MCP servers may return names with dots, colons, slashes, etc.
206+
# Sanitize here for the model-facing name (self.name) while
207+
# self._tool.name retains the original for server-side calls.
208+
sanitized_mcp = re.sub(r"[^a-zA-Z0-9_-]", "_", mcp_name)
209+
sanitized_tool = re.sub(r"[^a-zA-Z0-9_-]", "_", tool.name)
210+
self.name = f"mcp__{sanitized_mcp}__{sanitized_tool}"
211+
if sanitized_mcp != mcp_name or sanitized_tool != tool.name:
212+
logger.debug(
213+
"MCP tool name sanitized: '%s.%s' -> '%s'.",
214+
mcp_name,
215+
tool.name,
216+
self.name,
217+
)
218+
203219
self.description = tool.description or ""
204220

205221
# Preserve the full inputSchema (including $defs, anyOf, oneOf, etc.)

0 commit comments

Comments
 (0)