Skip to content

Commit f1f587d

Browse files
feat: add handle_tool_error and handle_validation_error to load_mcp_tools
1 parent bb26197 commit f1f587d

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

langchain_mcp_adapters/client.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55
"""
66

77
import asyncio
8-
from collections.abc import AsyncIterator
8+
from collections.abc import AsyncIterator, Callable
99
from contextlib import asynccontextmanager
1010
from types import TracebackType
1111
from typing import Any
1212

1313
from langchain_core.documents.base import Blob
1414
from langchain_core.messages import AIMessage, HumanMessage
15-
from langchain_core.tools import BaseTool
15+
from langchain_core.tools import BaseTool, ToolException
1616
from mcp import ClientSession
17+
from pydantic import ValidationError
1718

1819
from langchain_mcp_adapters.prompts import load_mcp_prompt
1920
from langchain_mcp_adapters.resources import load_mcp_resources
@@ -125,12 +126,22 @@ async def session(
125126
await session.initialize()
126127
yield session
127128

128-
async def get_tools(self, *, server_name: str | None = None) -> list[BaseTool]:
129+
async def get_tools(
130+
self,
131+
*,
132+
server_name: str | None = None,
133+
handle_tool_error: bool | str | Callable[[ToolException], str] | None = False,
134+
handle_validation_error: (
135+
bool | str | Callable[[ValidationError], str] | None
136+
) = False,
137+
) -> list[BaseTool]:
129138
"""Get a list of all tools from all connected servers.
130139
131140
Args:
132141
server_name: Optional name of the server to get tools from.
133142
If None, all tools from all servers will be returned (default).
143+
handle_tool_error: Optional error handler for tool execution errors.
144+
handle_validation_error: Optional error handler for validation errors.
134145
135146
NOTE: a new session will be created for each tool call
136147
@@ -145,13 +156,23 @@ async def get_tools(self, *, server_name: str | None = None) -> list[BaseTool]:
145156
f"expected one of '{list(self.connections.keys())}'"
146157
)
147158
raise ValueError(msg)
148-
return await load_mcp_tools(None, connection=self.connections[server_name])
159+
return await load_mcp_tools(
160+
None,
161+
connection=self.connections[server_name],
162+
handle_tool_error=handle_tool_error,
163+
handle_validation_error=handle_validation_error,
164+
)
149165

150166
all_tools: list[BaseTool] = []
151167
load_mcp_tool_tasks = []
152168
for connection in self.connections.values():
153169
load_mcp_tool_task = asyncio.create_task(
154-
load_mcp_tools(None, connection=connection)
170+
load_mcp_tools(
171+
None,
172+
connection=connection,
173+
handle_tool_error=handle_tool_error,
174+
handle_validation_error=handle_validation_error,
175+
)
155176
)
156177
load_mcp_tool_tasks.append(load_mcp_tool_task)
157178
tools_list = await asyncio.gather(*load_mcp_tool_tasks)

langchain_mcp_adapters/tools.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
tools, handle tool execution, and manage tool conversion between the two formats.
55
"""
66

7+
from collections.abc import Callable
78
from typing import Any, cast, get_args
89

910
from langchain_core.tools import (
@@ -18,7 +19,7 @@
1819
from mcp.server.fastmcp.utilities.func_metadata import ArgModelBase, FuncMetadata
1920
from mcp.types import CallToolResult, EmbeddedResource, ImageContent, TextContent
2021
from mcp.types import Tool as MCPTool
21-
from pydantic import BaseModel, create_model
22+
from pydantic import BaseModel, ValidationError, create_model
2223

2324
from langchain_mcp_adapters.sessions import Connection, create_session
2425

@@ -102,6 +103,10 @@ def convert_mcp_tool_to_langchain_tool(
102103
tool: MCPTool,
103104
*,
104105
connection: Connection | None = None,
106+
handle_tool_error: bool | str | Callable[[ToolException], str] | None = False,
107+
handle_validation_error: (
108+
bool | str | Callable[[ValidationError], str] | None
109+
) = False,
105110
) -> BaseTool:
106111
"""Convert an MCP tool to a LangChain tool.
107112
@@ -112,6 +117,8 @@ def convert_mcp_tool_to_langchain_tool(
112117
tool: MCP tool to convert
113118
connection: Optional connection config to use to create a new session
114119
if a `session` is not provided
120+
handle_tool_error: Optional error handler for tool execution errors.
121+
handle_validation_error: Optional error handler for validation errors.
115122
116123
Returns:
117124
a LangChain tool
@@ -148,19 +155,27 @@ async def call_tool(
148155
coroutine=call_tool,
149156
response_format="content_and_artifact",
150157
metadata=metadata,
158+
handle_tool_error=handle_tool_error,
159+
handle_validation_error=handle_validation_error,
151160
)
152161

153162

154163
async def load_mcp_tools(
155164
session: ClientSession | None,
156165
*,
157166
connection: Connection | None = None,
167+
handle_tool_error: bool | str | Callable[[ToolException], str] | None = False,
168+
handle_validation_error: (
169+
bool | str | Callable[[ValidationError], str] | None
170+
) = False,
158171
) -> list[BaseTool]:
159172
"""Load all available MCP tools and convert them to LangChain tools.
160173
161174
Args:
162175
session: The MCP client session. If None, connection must be provided.
163176
connection: Connection config to create a new session if session is None.
177+
handle_tool_error: Optional error handler for tool execution errors.
178+
handle_validation_error: Optional error handler for validation errors.
164179
165180
Returns:
166181
List of LangChain tools. Tool annotations are returned as part
@@ -182,7 +197,13 @@ async def load_mcp_tools(
182197
tools = await _list_all_tools(session)
183198

184199
return [
185-
convert_mcp_tool_to_langchain_tool(session, tool, connection=connection)
200+
convert_mcp_tool_to_langchain_tool(
201+
session,
202+
tool,
203+
connection=connection,
204+
handle_tool_error=handle_tool_error,
205+
handle_validation_error=handle_validation_error,
206+
)
186207
for tool in tools
187208
]
188209

0 commit comments

Comments
 (0)