Skip to content

Commit 7ff9929

Browse files
authored
linting: clean up code a bit (#246)
1 parent 601e8e9 commit 7ff9929

File tree

12 files changed

+132
-175
lines changed

12 files changed

+132
-175
lines changed

langchain_mcp_adapters/client.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import asyncio
2+
from collections.abc import AsyncIterator
23
from contextlib import asynccontextmanager
34
from types import TracebackType
4-
from typing import Any, AsyncIterator
5+
from typing import Any
56

67
from langchain_core.documents.base import Blob
78
from langchain_core.messages import AIMessage, HumanMessage
@@ -35,10 +36,7 @@
3536
class MultiServerMCPClient:
3637
"""Client for connecting to multiple MCP servers and loading LangChain-compatible tools, prompts and resources from them."""
3738

38-
def __init__(
39-
self,
40-
connections: dict[str, Connection] | None = None,
41-
) -> None:
39+
def __init__(self, connections: dict[str, Connection] | None = None) -> None:
4240
"""Initialize a MultiServerMCPClient with MCP servers connections.
4341
4442
Args:
@@ -78,15 +76,13 @@ def __init__(
7876
async with client.session("math") as session:
7977
tools = await load_mcp_tools(session)
8078
```
79+
8180
"""
8281
self.connections: dict[str, Connection] = connections if connections is not None else {}
8382

8483
@asynccontextmanager
8584
async def session(
86-
self,
87-
server_name: str,
88-
*,
89-
auto_initialize: bool = True,
85+
self, server_name: str, *, auto_initialize: bool = True
9086
) -> AsyncIterator[ClientSession]:
9187
"""Connect to an MCP server and initialize a session.
9288
@@ -99,6 +95,7 @@ async def session(
9995
10096
Yields:
10197
An initialized ClientSession
98+
10299
"""
103100
if server_name not in self.connections:
104101
raise ValueError(
@@ -121,6 +118,7 @@ async def get_tools(self, *, server_name: str | None = None) -> list[BaseTool]:
121118
122119
Returns:
123120
A list of LangChain tools
121+
124122
"""
125123
if server_name is not None:
126124
if server_name not in self.connections:
@@ -158,6 +156,7 @@ async def get_resources(
158156
159157
Returns:
160158
A list of LangChain Blobs
159+
161160
"""
162161
async with self.session(server_name) as session:
163162
resources = await load_mcp_resources(session, uris=uris)
@@ -176,8 +175,8 @@ def __aexit__(
176175

177176

178177
__all__ = [
179-
"MultiServerMCPClient",
180178
"McpHttpClientFactory",
179+
"MultiServerMCPClient",
181180
"SSEConnection",
182181
"StdioConnection",
183182
"StreamableHttpConnection",

langchain_mcp_adapters/prompts.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ def convert_mcp_prompt_message_to_langchain_message(
1515
1616
Returns:
1717
A LangChain message
18+
1819
"""
1920
if message.content.type == "text":
2021
if message.role == "user":
2122
return HumanMessage(content=message.content.text)
22-
elif message.role == "assistant":
23+
if message.role == "assistant":
2324
return AIMessage(content=message.content.text)
24-
else:
25-
raise ValueError(f"Unsupported prompt message role: {message.role}")
25+
raise ValueError(f"Unsupported prompt message role: {message.role}")
2626

2727
raise ValueError(f"Unsupported prompt message content type: {message.content.type}")
2828

langchain_mcp_adapters/resources.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
from mcp.types import BlobResourceContents, ResourceContents, TextResourceContents
66

77

8-
def convert_mcp_resource_to_langchain_blob(
9-
resource_uri: str,
10-
contents: ResourceContents,
11-
) -> Blob:
8+
def convert_mcp_resource_to_langchain_blob(resource_uri: str, contents: ResourceContents) -> Blob:
129
"""Convert an MCP resource content to a LangChain Blob.
1310
1411
Args:
@@ -17,6 +14,7 @@ def convert_mcp_resource_to_langchain_blob(
1714
1815
Returns:
1916
A LangChain Blob
17+
2018
"""
2119
if isinstance(contents, TextResourceContents):
2220
data = contents.text
@@ -25,11 +23,7 @@ def convert_mcp_resource_to_langchain_blob(
2523
else:
2624
raise ValueError(f"Unsupported content type for URI {resource_uri}")
2725

28-
return Blob.from_data(
29-
data=data,
30-
mime_type=contents.mimeType,
31-
metadata={"uri": resource_uri},
32-
)
26+
return Blob.from_data(data=data, mime_type=contents.mimeType, metadata={"uri": resource_uri})
3327

3428

3529
async def get_mcp_resource(session: ClientSession, uri: str) -> list[Blob]:
@@ -41,6 +35,7 @@ async def get_mcp_resource(session: ClientSession, uri: str) -> list[Blob]:
4135
4236
Returns:
4337
A list of LangChain Blobs
38+
4439
"""
4540
contents_result = await session.read_resource(uri)
4641
if not contents_result.contents or len(contents_result.contents) == 0:
@@ -52,9 +47,7 @@ async def get_mcp_resource(session: ClientSession, uri: str) -> list[Blob]:
5247

5348

5449
async def load_mcp_resources(
55-
session: ClientSession,
56-
*,
57-
uris: str | list[str] | None = None,
50+
session: ClientSession, *, uris: str | list[str] | None = None
5851
) -> list[Blob]:
5952
"""Load MCP resources and convert them to LangChain Blobs.
6053
@@ -68,6 +61,7 @@ async def load_mcp_resources(
6861
6962
Returns:
7063
A list of LangChain Blobs
64+
7165
"""
7266
blobs = []
7367

langchain_mcp_adapters/sessions.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__ import annotations
22

33
import os
4+
from collections.abc import AsyncIterator
45
from contextlib import asynccontextmanager
56
from datetime import timedelta
67
from pathlib import Path
7-
from typing import Any, AsyncIterator, Literal, Protocol
8+
from typing import Any, Literal, Protocol
89

910
import httpx
1011
from mcp import ClientSession, StdioServerParameters
@@ -152,6 +153,7 @@ async def _create_stdio_session(
152153
encoding: Character encoding
153154
encoding_error_handler: How to handle encoding errors
154155
session_kwargs: Additional keyword arguments to pass to the ClientSession
156+
155157
"""
156158
# NOTE: execution commands (e.g., `uvx` / `npx`) require PATH envvar to be set.
157159
# To address this, we automatically inject existing PATH envvar into the `env` value,
@@ -196,6 +198,7 @@ async def _create_sse_session(
196198
session_kwargs: Additional keyword arguments to pass to the ClientSession
197199
httpx_client_factory: Custom factory for httpx.AsyncClient (optional)
198200
auth: httpx.Auth | None = None
201+
199202
"""
200203
# Create and store the connection
201204
kwargs = {}
@@ -233,6 +236,7 @@ async def _create_streamable_http_session(
233236
session_kwargs: Additional keyword arguments to pass to the ClientSession
234237
httpx_client_factory: Custom factory for httpx.AsyncClient (optional)
235238
auth: httpx.Auth | None = None
239+
236240
"""
237241
# Create and store the connection
238242
kwargs = {}
@@ -248,9 +252,7 @@ async def _create_streamable_http_session(
248252

249253
@asynccontextmanager
250254
async def _create_websocket_session(
251-
*,
252-
url: str,
253-
session_kwargs: dict[str, Any] | None = None,
255+
*, url: str, session_kwargs: dict[str, Any] | None = None
254256
) -> AsyncIterator[ClientSession]:
255257
"""Create a new session to an MCP server using Websockets.
256258
@@ -260,6 +262,7 @@ async def _create_websocket_session(
260262
261263
Raises:
262264
ImportError: If websockets package is not installed
265+
263266
"""
264267
try:
265268
from mcp.client.websocket import websocket_client
@@ -276,9 +279,7 @@ async def _create_websocket_session(
276279

277280

278281
@asynccontextmanager
279-
async def create_session(
280-
connection: Connection,
281-
) -> AsyncIterator[ClientSession]:
282+
async def create_session(connection: Connection) -> AsyncIterator[ClientSession]:
282283
"""Create a new session to an MCP server.
283284
284285
Args:
@@ -290,8 +291,8 @@ async def create_session(
290291
291292
Yields:
292293
A ClientSession
293-
"""
294294
295+
"""
295296
if "transport" not in connection:
296297
raise ValueError(
297298
"Configuration error: Missing 'transport' key in server configuration. "
@@ -350,8 +351,7 @@ async def create_session(
350351
if "url" not in connection:
351352
raise ValueError("'url' parameter is required for Websocket connection")
352353
async with _create_websocket_session(
353-
url=connection["url"],
354-
session_kwargs=connection.get("session_kwargs"),
354+
url=connection["url"], session_kwargs=connection.get("session_kwargs")
355355
) as session:
356356
yield session
357357
else:

langchain_mcp_adapters/tools.py

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,8 @@
55
from mcp import ClientSession
66
from mcp.server.fastmcp.tools import Tool as FastMCPTool
77
from mcp.server.fastmcp.utilities.func_metadata import ArgModelBase, FuncMetadata
8-
from mcp.types import (
9-
CallToolResult,
10-
EmbeddedResource,
11-
ImageContent,
12-
TextContent,
13-
)
14-
from mcp.types import (
15-
Tool as MCPTool,
16-
)
8+
from mcp.types import CallToolResult, EmbeddedResource, ImageContent, TextContent
9+
from mcp.types import Tool as MCPTool
1710
from pydantic import BaseModel, create_model
1811

1912
from langchain_mcp_adapters.sessions import Connection, create_session
@@ -69,10 +62,7 @@ async def _list_all_tools(session: ClientSession) -> list[MCPTool]:
6962

7063

7164
def convert_mcp_tool_to_langchain_tool(
72-
session: ClientSession | None,
73-
tool: MCPTool,
74-
*,
75-
connection: Connection | None = None,
65+
session: ClientSession | None, tool: MCPTool, *, connection: Connection | None = None
7666
) -> BaseTool:
7767
"""Convert an MCP tool to a LangChain tool.
7868
@@ -86,6 +76,7 @@ def convert_mcp_tool_to_langchain_tool(
8676
8777
Returns:
8878
a LangChain tool
79+
8980
"""
9081
if session is None and connection is None:
9182
raise ValueError("Either a session or a connection config must be provided")
@@ -97,7 +88,7 @@ async def call_tool(
9788
# If a session is not provided, we will create one on the fly
9889
async with create_session(connection) as tool_session:
9990
await tool_session.initialize()
100-
call_tool_result = await cast(ClientSession, tool_session).call_tool(
91+
call_tool_result = await cast("ClientSession", tool_session).call_tool(
10192
tool.name, arguments
10293
)
10394
else:
@@ -115,15 +106,14 @@ async def call_tool(
115106

116107

117108
async def load_mcp_tools(
118-
session: ClientSession | None,
119-
*,
120-
connection: Connection | None = None,
109+
session: ClientSession | None, *, connection: Connection | None = None
121110
) -> list[BaseTool]:
122111
"""Load all available MCP tools and convert them to LangChain tools.
123112
124113
Returns:
125114
list of LangChain tools. Tool annotations are returned as part
126115
of the tool metadata object.
116+
127117
"""
128118
if session is None and connection is None:
129119
raise ValueError("Either a session or a connection config must be provided")
@@ -171,11 +161,7 @@ def to_fastmcp(tool: BaseTool) -> FastMCPTool:
171161
field: (field_info.annotation, field_info)
172162
for field, field_info in tool.tool_call_schema.model_fields.items()
173163
}
174-
arg_model = create_model(
175-
f"{tool.name}Arguments",
176-
**field_definitions,
177-
__base__=ArgModelBase,
178-
)
164+
arg_model = create_model(f"{tool.name}Arguments", **field_definitions, __base__=ArgModelBase)
179165
fn_metadata = FuncMetadata(arg_model=arg_model)
180166

181167
async def fn(**arguments: dict[str, Any]) -> Any:

0 commit comments

Comments
 (0)