Skip to content

Commit c8bdf76

Browse files
fix: Add array schema validation fix to HTTP-Streaming MCP client
- Add _fix_array_schemas method to HTTPStreamingMCPTool class - Apply schema fix in to_openai_tool method to ensure array types have 'items' property - Remove unused imports (Callable, BaseSession, RequestContext, Tool) This fixes OpenAI function calling validation errors for MCP tools with array parameters. Co-authored-by: Mervin Praison <[email protected]>
1 parent 3570545 commit c8bdf76

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

src/praisonai-agents/praisonaiagents/mcp/mcp_http_streaming.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@
99
import logging
1010
import threading
1111
import inspect
12-
from typing import List, Dict, Any, Optional, Callable, Iterable, AsyncIterator
12+
from typing import List, Dict, Any, Optional, Iterable, AsyncIterator
1313
import httpx
1414
from mcp import ClientSession
15-
from mcp.client.session import BaseSession
16-
from mcp.shared.context import RequestContext
17-
from mcp.types import Tool
1815

1916
logger = logging.getLogger("mcp-http-streaming")
2017

@@ -259,14 +256,54 @@ async def _async_call(self, **kwargs) -> Any:
259256
logger.error(f"Error calling tool {self.name}: {e}")
260257
raise
261258

259+
def _fix_array_schemas(self, schema):
260+
"""
261+
Fix array schemas by adding missing 'items' attribute required by OpenAI.
262+
263+
This ensures compatibility with OpenAI's function calling format which
264+
requires array types to specify the type of items they contain.
265+
266+
Args:
267+
schema: The schema dictionary to fix
268+
269+
Returns:
270+
dict: The fixed schema
271+
"""
272+
if not isinstance(schema, dict):
273+
return schema
274+
275+
# Create a copy to avoid modifying the original
276+
fixed_schema = schema.copy()
277+
278+
# Fix array types at the current level
279+
if fixed_schema.get("type") == "array" and "items" not in fixed_schema:
280+
# Add a default items schema for arrays without it
281+
fixed_schema["items"] = {"type": "string"}
282+
283+
# Recursively fix nested schemas
284+
if "properties" in fixed_schema:
285+
fixed_properties = {}
286+
for prop_name, prop_schema in fixed_schema["properties"].items():
287+
fixed_properties[prop_name] = self._fix_array_schemas(prop_schema)
288+
fixed_schema["properties"] = fixed_properties
289+
290+
# Fix items schema if it exists
291+
if "items" in fixed_schema:
292+
fixed_schema["items"] = self._fix_array_schemas(fixed_schema["items"])
293+
294+
return fixed_schema
295+
262296
def to_openai_tool(self) -> Dict[str, Any]:
263297
"""Convert this tool to OpenAI function calling format."""
298+
# Fix array schemas to include 'items' attribute
299+
fixed_schema = self._fix_array_schemas(self.input_schema)
300+
264301
return {
265302
"type": "function",
266303
"function": {
267304
"name": self.name,
268305
"description": self.description,
269-
"parameters": self.input_schema
306+
"parameters": fixed_schema
270307
}
271308
}
272309

0 commit comments

Comments
 (0)