Skip to content

Commit 51dc4eb

Browse files
author
zach
authored
cleanup: use tool conversion from mcp-run client (#2)
1 parent fefc248 commit 51dc4eb

File tree

4 files changed

+167
-241
lines changed

4 files changed

+167
-241
lines changed

mcpx_pydantic_ai.py

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,14 @@
44
from pydantic import BaseModel, Field
55
from pydantic_ai.models.openai import OpenAIModel
66
from pydantic_ai.providers.openai import OpenAIProvider
7+
from mcp_run.client import _convert_type
78

89
from typing import TypedDict, List, Set, AsyncIterator, Any
910
import traceback
1011

1112
__all__ = ["BaseModel", "Field", "Agent", "mcp_run", "pydantic_ai", "pydantic"]
1213

1314

14-
def _convert_type(t):
15-
if t == "string":
16-
return str
17-
elif t == "boolean":
18-
return bool
19-
elif t == "number":
20-
return float
21-
elif t == "integer":
22-
return int
23-
elif t == "object":
24-
return dict
25-
elif t == "array":
26-
return list
27-
raise TypeError(f"Unhandled conversion type: {t}")
28-
29-
3015
def openai_compatible_model(url: str, model: str, api_key: str | None = None):
3116
"""
3217
Returns an OpenAI compatible model from the provided `url`, `model` name and optional `api_key`
@@ -71,27 +56,20 @@ def register_tool(self, tool: mcp_run.Tool, f=None):
7156
return
7257

7358
def wrap(tool, inner):
74-
props = tool.input_schema["properties"]
75-
t = {k: _convert_type(v["type"]) for k, v in props.items()}
76-
InputType = TypedDict("Input", t)
77-
7859
if inner is not None:
60+
props = tool.input_schema["properties"]
61+
t = {k: _convert_type(v["type"]) for k, v in props.items()}
62+
InputType = TypedDict("Input", t)
7963

8064
def f(input: InputType):
8165
try:
8266
return inner(input)
8367
except Exception as exc:
8468
return f"ERROR call to tool {tool.name} failed: {traceback.format_exception(exc)}"
85-
else:
86-
87-
def f(input: InputType):
88-
try:
89-
res = self.client.call_tool(tool=tool.name, params=input)
90-
return res.content[0].text
91-
except Exception as exc:
92-
return f"ERROR call to tool {tool.name} failed: {traceback.format_exception(exc)}"
9369

94-
return f
70+
return f
71+
else:
72+
return self.client._make_pydantic_function(tool)
9573

9674
self._register_tool(
9775
pydantic_ai.Tool(

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[project]
22
name = "mcpx-pydantic-ai"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
description = "Pydantic Agent with mcp.run tools"
55
readme = "README.md"
66
requires-python = ">=3.12"
77
dependencies = [
8-
"mcp-run>=0.3.0",
8+
"mcp-run>=0.4.0",
99
"pydantic>=2.10.4",
1010
"pydantic-ai>=0.0.35",
1111
]

tests/test_mcpx.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
from unittest.mock import Mock, patch
33
from mcpx_pydantic_ai import Agent, _convert_type
44
from typing import Dict, Any
5+
import os
6+
7+
os.environ["ANTHROPIC_API_KEY"] = "something"
58

69

710
class MockTool:
@@ -41,6 +44,11 @@ def call_tool(self, tool: str, params: Dict[str, Any]) -> MockResponse:
4144
def set_profile(self, profile: str):
4245
self.profile = profile
4346

47+
def _make_pydantic_function(self, tool):
48+
def test(input: dict):
49+
return self.call_tool(tool.name, input).content[0].text
50+
return test
51+
4452

4553
class TestTypeConversion(unittest.TestCase):
4654
def test_convert_basic_types(self):

0 commit comments

Comments
 (0)