update
This commit is contained in:
@@ -12,9 +12,16 @@ class MCPTool(BaseModel):
|
|||||||
|
|
||||||
name: str = Field(..., description="Unique tool identifier")
|
name: str = Field(..., description="Unique tool identifier")
|
||||||
description: str = Field(..., description="Human-readable tool description")
|
description: str = Field(..., description="Human-readable tool description")
|
||||||
input_schema: dict[str, Any] = Field(..., description="JSON schema describing input arguments")
|
input_schema: dict[str, Any] = Field(
|
||||||
|
...,
|
||||||
|
alias="inputSchema",
|
||||||
|
serialization_alias="inputSchema",
|
||||||
|
description="JSON schema describing input arguments",
|
||||||
|
)
|
||||||
write_operation: bool = Field(default=False, description="Whether tool mutates data")
|
write_operation: bool = Field(default=False, description="Whether tool mutates data")
|
||||||
|
|
||||||
|
model_config = ConfigDict(populate_by_name=True)
|
||||||
|
|
||||||
|
|
||||||
class MCPToolCallRequest(BaseModel):
|
class MCPToolCallRequest(BaseModel):
|
||||||
"""Request to invoke an MCP tool."""
|
"""Request to invoke an MCP tool."""
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ async def automation_run_job(request: AutomationJobRequest) -> JSONResponse:
|
|||||||
async def list_tools() -> JSONResponse:
|
async def list_tools() -> JSONResponse:
|
||||||
"""List all available MCP tools."""
|
"""List all available MCP tools."""
|
||||||
response = MCPListToolsResponse(tools=AVAILABLE_TOOLS)
|
response = MCPListToolsResponse(tools=AVAILABLE_TOOLS)
|
||||||
return JSONResponse(content=response.model_dump())
|
return JSONResponse(content=response.model_dump(by_alias=True))
|
||||||
|
|
||||||
|
|
||||||
async def _execute_tool_call(
|
async def _execute_tool_call(
|
||||||
@@ -519,7 +519,7 @@ async def sse_message_handler(request: Request) -> JSONResponse:
|
|||||||
content={
|
content={
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": message_id,
|
"id": message_id,
|
||||||
"result": response.model_dump(),
|
"result": response.model_dump(by_alias=True),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -183,9 +183,9 @@ def test_all_mcp_tools_discoverable(client):
|
|||||||
for tool in tools:
|
for tool in tools:
|
||||||
assert "name" in tool
|
assert "name" in tool
|
||||||
assert "description" in tool
|
assert "description" in tool
|
||||||
assert "input_schema" in tool
|
assert "inputSchema" in tool
|
||||||
assert tool["description"] # Not empty
|
assert tool["description"] # Not empty
|
||||||
assert "type" in tool["input_schema"]
|
assert "type" in tool["inputSchema"]
|
||||||
|
|
||||||
|
|
||||||
def test_error_responses_include_helpful_messages(client):
|
def test_error_responses_include_helpful_messages(client):
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ def test_list_tools_with_valid_key(client, mock_env):
|
|||||||
tool = data["tools"][0]
|
tool = data["tools"][0]
|
||||||
assert "name" in tool
|
assert "name" in tool
|
||||||
assert "description" in tool
|
assert "description" in tool
|
||||||
assert "input_schema" in tool
|
assert "inputSchema" in tool
|
||||||
|
|
||||||
|
|
||||||
def test_list_tools_with_query_param(client):
|
def test_list_tools_with_query_param(client):
|
||||||
@@ -149,6 +149,22 @@ def test_list_tools_no_auth_when_disabled(client_no_auth):
|
|||||||
assert "tools" in data
|
assert "tools" in data
|
||||||
|
|
||||||
|
|
||||||
|
def test_sse_tools_list_returns_camel_case_schema(client):
|
||||||
|
"""SSE tools/list returns MCP-compatible camelCase inputSchema."""
|
||||||
|
response = client.post(
|
||||||
|
f"/mcp/sse?api_key={'a' * 64}",
|
||||||
|
json={"jsonrpc": "2.0", "id": "1", "method": "tools/list"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
data = response.json()
|
||||||
|
assert "result" in data
|
||||||
|
assert "tools" in data["result"]
|
||||||
|
tool = data["result"]["tools"][0]
|
||||||
|
assert "inputSchema" in tool
|
||||||
|
assert "type" in tool["inputSchema"]
|
||||||
|
|
||||||
|
|
||||||
def test_call_tool_without_auth(client):
|
def test_call_tool_without_auth(client):
|
||||||
"""Test that /mcp/tool/call requires authentication."""
|
"""Test that /mcp/tool/call requires authentication."""
|
||||||
response = client.post("/mcp/tool/call", json={"tool": "list_repositories", "arguments": {}})
|
response = client.post("/mcp/tool/call", json={"tool": "list_repositories", "arguments": {}})
|
||||||
|
|||||||
Reference in New Issue
Block a user