Skip to content

Commit ed2ecb6

Browse files
authored
✨ MCP Tool test run #541
2 parents 2a2787f + 87d6a9c commit ed2ecb6

File tree

18 files changed

+1547
-153
lines changed

18 files changed

+1547
-153
lines changed

backend/apps/tool_config_app.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
from fastapi import APIRouter, Header, HTTPException
66
from fastapi.responses import JSONResponse
77

8-
from consts.exceptions import MCPConnectionError
9-
from consts.model import ToolInstanceInfoRequest, ToolInstanceSearchRequest
8+
from consts.exceptions import MCPConnectionError, TimeoutException, NotFoundException
9+
from consts.model import ToolInstanceInfoRequest, ToolInstanceSearchRequest, ToolValidateRequest
1010
from services.tool_configuration_service import (
1111
search_tool_info_impl,
1212
update_tool_info_impl,
1313
update_tool_list,
1414
list_all_tools,
1515
load_last_tool_config_impl,
16+
validate_tool_impl,
1617
)
1718
from utils.auth_utils import get_current_user_id
1819

@@ -81,6 +82,7 @@ async def scan_and_update_tool(
8182
raise HTTPException(
8283
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Failed to update tool")
8384

85+
8486
@router.get("/load_config/{tool_id}")
8587
async def load_last_tool_config(tool_id: int, authorization: Optional[str] = Header(None)):
8688
try:
@@ -97,4 +99,38 @@ async def load_last_tool_config(tool_id: int, authorization: Optional[str] = Hea
9799
except Exception as e:
98100
logger.error(f"Failed to load tool config: {e}")
99101
raise HTTPException(
100-
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Failed to load tool config")
102+
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Failed to load tool config")
103+
104+
105+
@router.post("/validate")
106+
async def validate_tool(
107+
request: ToolValidateRequest,
108+
authorization: Optional[str] = Header(None)
109+
):
110+
"""Validate specific tool based on source type"""
111+
try:
112+
_, tenant_id = get_current_user_id(authorization)
113+
result = await validate_tool_impl(request, tenant_id)
114+
115+
return JSONResponse(
116+
status_code=HTTPStatus.OK,
117+
content=result
118+
)
119+
except MCPConnectionError as e:
120+
logger.error(f"MCP connection failed: {e}")
121+
raise HTTPException(
122+
status_code=HTTPStatus.SERVICE_UNAVAILABLE,
123+
detail=str(e)
124+
)
125+
except NotFoundException as e:
126+
logger.error(f"Tool not found: {e}")
127+
raise HTTPException(
128+
status_code=HTTPStatus.NOT_FOUND,
129+
detail=str(e)
130+
)
131+
except Exception as e:
132+
logger.error(f"Failed to validate tool: {e}")
133+
raise HTTPException(
134+
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
135+
detail=f"Failed to validate tool: {str(e)}"
136+
)

backend/consts/exceptions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,9 @@ class TTSConnectionException(Exception):
8585

8686
class VoiceConfigException(Exception):
8787
"""Raised when voice configuration is invalid."""
88+
pass
89+
90+
91+
class ToolExecutionException(Exception):
92+
"""Raised when mcp tool execution failed."""
8893
pass

backend/consts/model.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ class ToolInfo(BaseModel):
244244
output_type: str
245245
class_name: str
246246
usage: Optional[str]
247+
origin_name: Optional[str] = None
247248

248249

249250
# used in Knowledge Summary request
@@ -340,3 +341,14 @@ class TTSResponse(BaseModel):
340341
"""Response model for TTS conversion"""
341342
status: str = Field(..., description="Status of the TTS conversion")
342343
message: Optional[str] = Field(None, description="Additional message")
344+
345+
346+
class ToolValidateRequest(BaseModel):
347+
"""Request model for tool validation"""
348+
name: str = Field(..., description="Tool name to validate")
349+
source: str = Field(..., description="Tool source (local, mcp, langchain)")
350+
usage: Optional[str] = Field(None, description="Tool usage information")
351+
inputs: Optional[Dict[str, Any]] = Field(
352+
None, description="Tool inputs")
353+
params: Optional[Dict[str, Any]] = Field(
354+
None, description="Tool configuration parameters")

backend/database/db_models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class ToolInfo(TableBase):
167167

168168
tool_id = Column(Integer, primary_key=True, nullable=False, doc="ID")
169169
name = Column(String(100), doc="Unique key name")
170+
origin_name = Column(String(100), doc="Original name")
170171
class_name = Column(
171172
String(100), doc="Tool class name, used when the tool is instantiated")
172173
description = Column(String(2048), doc="Prompt tool description")

backend/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies = [
1313
"websocket-client>=1.8.0",
1414
"pyyaml>=6.0.2",
1515
"redis>=5.0.0",
16-
"fastmcp==2.6.0",
16+
"fastmcp==2.12.0",
1717
"langchain>=0.3.26"
1818
]
1919

0 commit comments

Comments
 (0)