mcp-use 0.1.0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mcp-use might be problematic. Click here for more details.
- mcp_use/__init__.py +6 -6
- mcp_use/agents/langchain_agent.py +88 -64
- mcp_use/agents/mcpagent.py +216 -52
- mcp_use/agents/prompts/default.py +22 -0
- mcp_use/client.py +93 -68
- mcp_use/config.py +0 -54
- mcp_use/connectors/base.py +1 -3
- mcp_use/connectors/http.py +91 -7
- mcp_use/connectors/stdio.py +97 -33
- mcp_use/connectors/websocket.py +124 -21
- mcp_use/session.py +0 -55
- mcp_use/task_managers/__init__.py +18 -0
- mcp_use/task_managers/base.py +151 -0
- mcp_use/task_managers/http.py +62 -0
- mcp_use/task_managers/stdio.py +73 -0
- mcp_use/task_managers/websocket.py +63 -0
- mcp_use-1.0.0.dist-info/METADATA +382 -0
- mcp_use-1.0.0.dist-info/RECORD +24 -0
- {mcp_use-0.1.0.dist-info → mcp_use-1.0.0.dist-info}/WHEEL +1 -2
- mcp_use/tools/__init__.py +0 -11
- mcp_use/tools/converter.py +0 -108
- mcp_use/tools/formats.py +0 -181
- mcp_use/types.py +0 -33
- mcp_use-0.1.0.dist-info/METADATA +0 -287
- mcp_use-0.1.0.dist-info/RECORD +0 -23
- mcp_use-0.1.0.dist-info/top_level.txt +0 -1
- {mcp_use-0.1.0.dist-info → mcp_use-1.0.0.dist-info}/licenses/LICENSE +0 -0
mcp_use/client.py
CHANGED
|
@@ -9,8 +9,8 @@ import json
|
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
11
|
from .config import create_connector_from_config, load_config_file
|
|
12
|
+
from .logging import logger
|
|
12
13
|
from .session import MCPSession
|
|
13
|
-
from .tools.converter import ModelProvider
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class MCPClient:
|
|
@@ -23,19 +23,16 @@ class MCPClient:
|
|
|
23
23
|
def __init__(
|
|
24
24
|
self,
|
|
25
25
|
config: str | dict[str, Any] | None = None,
|
|
26
|
-
model_provider: str | ModelProvider = "openai",
|
|
27
26
|
) -> None:
|
|
28
27
|
"""Initialize a new MCP client.
|
|
29
28
|
|
|
30
29
|
Args:
|
|
31
30
|
config: Either a dict containing configuration or a path to a JSON config file.
|
|
32
31
|
If None, an empty configuration is used.
|
|
33
|
-
model_provider: The model provider to use for tool conversion.
|
|
34
32
|
"""
|
|
35
|
-
self.model_provider = model_provider
|
|
36
33
|
self.config: dict[str, Any] = {}
|
|
37
34
|
self.sessions: dict[str, MCPSession] = {}
|
|
38
|
-
self.
|
|
35
|
+
self.active_sessions: list[str] = []
|
|
39
36
|
|
|
40
37
|
# Load configuration if provided
|
|
41
38
|
if config is not None:
|
|
@@ -87,9 +84,9 @@ class MCPClient:
|
|
|
87
84
|
if "mcpServers" in self.config and name in self.config["mcpServers"]:
|
|
88
85
|
del self.config["mcpServers"][name]
|
|
89
86
|
|
|
90
|
-
# If we removed
|
|
91
|
-
if name
|
|
92
|
-
self.
|
|
87
|
+
# If we removed an active session, remove it from active_sessions
|
|
88
|
+
if name in self.active_sessions:
|
|
89
|
+
self.active_sessions.remove(name)
|
|
93
90
|
|
|
94
91
|
def get_server_names(self) -> list[str]:
|
|
95
92
|
"""Get the list of configured server names.
|
|
@@ -108,17 +105,11 @@ class MCPClient:
|
|
|
108
105
|
with open(filepath, "w") as f:
|
|
109
106
|
json.dump(self.config, f, indent=2)
|
|
110
107
|
|
|
111
|
-
async def create_session(
|
|
112
|
-
self,
|
|
113
|
-
server_name: str | None = None,
|
|
114
|
-
auto_initialize: bool = True,
|
|
115
|
-
) -> MCPSession:
|
|
108
|
+
async def create_session(self, server_name: str, auto_initialize: bool = True) -> MCPSession:
|
|
116
109
|
"""Create a session for the specified server.
|
|
117
110
|
|
|
118
111
|
Args:
|
|
119
112
|
server_name: The name of the server to create a session for.
|
|
120
|
-
If None, uses the first available server.
|
|
121
|
-
auto_initialize: Whether to automatically initialize the session.
|
|
122
113
|
|
|
123
114
|
Returns:
|
|
124
115
|
The created MCPSession.
|
|
@@ -131,10 +122,6 @@ class MCPClient:
|
|
|
131
122
|
if not servers:
|
|
132
123
|
raise ValueError("No MCP servers defined in config")
|
|
133
124
|
|
|
134
|
-
# If server_name not specified, use the first one
|
|
135
|
-
if not server_name:
|
|
136
|
-
server_name = next(iter(servers.keys()))
|
|
137
|
-
|
|
138
125
|
if server_name not in servers:
|
|
139
126
|
raise ValueError(f"Server '{server_name}' not found in config")
|
|
140
127
|
|
|
@@ -142,85 +129,123 @@ class MCPClient:
|
|
|
142
129
|
connector = create_connector_from_config(server_config)
|
|
143
130
|
|
|
144
131
|
# Create the session
|
|
145
|
-
session = MCPSession(connector
|
|
146
|
-
self.sessions[server_name] = session
|
|
147
|
-
|
|
148
|
-
# Make this the active session
|
|
149
|
-
self.active_session = server_name
|
|
150
|
-
|
|
151
|
-
# Initialize if requested
|
|
132
|
+
session = MCPSession(connector)
|
|
152
133
|
if auto_initialize:
|
|
153
134
|
await session.initialize()
|
|
135
|
+
self.sessions[server_name] = session
|
|
136
|
+
|
|
137
|
+
# Add to active sessions
|
|
138
|
+
if server_name not in self.active_sessions:
|
|
139
|
+
self.active_sessions.append(server_name)
|
|
154
140
|
|
|
155
141
|
return session
|
|
156
142
|
|
|
157
|
-
def
|
|
143
|
+
async def create_all_sessions(
|
|
144
|
+
self,
|
|
145
|
+
auto_initialize: bool = True,
|
|
146
|
+
) -> dict[str, MCPSession]:
|
|
147
|
+
"""Create a session for the specified server.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
auto_initialize: Whether to automatically initialize the session.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
The created MCPSession. If server_name is None, returns the first created session.
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
ValueError: If no servers are configured or the specified server doesn't exist.
|
|
157
|
+
"""
|
|
158
|
+
# Get server config
|
|
159
|
+
servers = self.config.get("mcpServers", {})
|
|
160
|
+
if not servers:
|
|
161
|
+
raise ValueError("No MCP servers defined in config")
|
|
162
|
+
|
|
163
|
+
# Create sessions for all servers
|
|
164
|
+
for name in servers:
|
|
165
|
+
session = await self.create_session(name, auto_initialize)
|
|
166
|
+
if auto_initialize:
|
|
167
|
+
await session.initialize()
|
|
168
|
+
|
|
169
|
+
return self.sessions
|
|
170
|
+
|
|
171
|
+
def get_session(self, server_name: str) -> MCPSession:
|
|
158
172
|
"""Get an existing session.
|
|
159
173
|
|
|
160
174
|
Args:
|
|
161
175
|
server_name: The name of the server to get the session for.
|
|
162
|
-
If None, uses the active session.
|
|
176
|
+
If None, uses the first active session.
|
|
163
177
|
|
|
164
178
|
Returns:
|
|
165
179
|
The MCPSession for the specified server.
|
|
166
180
|
|
|
167
181
|
Raises:
|
|
168
|
-
ValueError: If no active
|
|
182
|
+
ValueError: If no active sessions exist or the specified session doesn't exist.
|
|
169
183
|
"""
|
|
170
|
-
if server_name is None:
|
|
171
|
-
if self.active_session is None:
|
|
172
|
-
raise ValueError("No active session")
|
|
173
|
-
server_name = self.active_session
|
|
174
|
-
|
|
175
184
|
if server_name not in self.sessions:
|
|
176
185
|
raise ValueError(f"No session exists for server '{server_name}'")
|
|
177
186
|
|
|
178
187
|
return self.sessions[server_name]
|
|
179
188
|
|
|
180
|
-
|
|
189
|
+
def get_all_active_sessions(self) -> dict[str, MCPSession]:
|
|
190
|
+
"""Get all active sessions.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
Dictionary mapping server names to their MCPSession instances.
|
|
194
|
+
"""
|
|
195
|
+
return {name: self.sessions[name] for name in self.active_sessions if name in self.sessions}
|
|
196
|
+
|
|
197
|
+
async def close_session(self, server_name: str) -> None:
|
|
181
198
|
"""Close a session.
|
|
182
199
|
|
|
183
200
|
Args:
|
|
184
201
|
server_name: The name of the server to close the session for.
|
|
185
|
-
If None, uses the active session.
|
|
202
|
+
If None, uses the first active session.
|
|
186
203
|
|
|
187
204
|
Raises:
|
|
188
|
-
ValueError: If no active
|
|
205
|
+
ValueError: If no active sessions exist or the specified session doesn't exist.
|
|
189
206
|
"""
|
|
190
|
-
session
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
207
|
+
# Check if the session exists
|
|
208
|
+
if server_name not in self.sessions:
|
|
209
|
+
logger.warning(f"No session exists for server '{server_name}', nothing to close")
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
# Get the session
|
|
213
|
+
session = self.sessions[server_name]
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
# Disconnect from the session
|
|
217
|
+
logger.info(f"Closing session for server '{server_name}'")
|
|
218
|
+
await session.disconnect()
|
|
219
|
+
except Exception as e:
|
|
220
|
+
logger.error(f"Error closing session for server '{server_name}': {e}")
|
|
221
|
+
finally:
|
|
222
|
+
# Remove the session regardless of whether disconnect succeeded
|
|
198
223
|
del self.sessions[server_name]
|
|
199
224
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
225
|
+
# Remove from active_sessions
|
|
226
|
+
if server_name in self.active_sessions:
|
|
227
|
+
self.active_sessions.remove(server_name)
|
|
203
228
|
|
|
204
229
|
async def close_all_sessions(self) -> None:
|
|
205
|
-
"""Close all active sessions.
|
|
206
|
-
for server_name in list(self.sessions.keys()):
|
|
207
|
-
await self.close_session(server_name)
|
|
208
|
-
|
|
209
|
-
async def __aenter__(self) -> "MCPClient":
|
|
210
|
-
"""Enter the async context manager.
|
|
211
|
-
|
|
212
|
-
Creates a session for the first available server if no sessions exist.
|
|
213
|
-
|
|
214
|
-
Returns:
|
|
215
|
-
The client instance.
|
|
216
|
-
"""
|
|
217
|
-
if not self.sessions and self.config.get("mcpServers"):
|
|
218
|
-
await self.create_session()
|
|
219
|
-
return self
|
|
220
|
-
|
|
221
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
222
|
-
"""Exit the async context manager.
|
|
230
|
+
"""Close all active sessions.
|
|
223
231
|
|
|
224
|
-
|
|
232
|
+
This method ensures all sessions are closed even if some fail.
|
|
225
233
|
"""
|
|
226
|
-
|
|
234
|
+
# Get a list of all session names first to avoid modification during iteration
|
|
235
|
+
server_names = list(self.sessions.keys())
|
|
236
|
+
errors = []
|
|
237
|
+
|
|
238
|
+
for server_name in server_names:
|
|
239
|
+
try:
|
|
240
|
+
logger.info(f"Closing session for server '{server_name}'")
|
|
241
|
+
await self.close_session(server_name)
|
|
242
|
+
except Exception as e:
|
|
243
|
+
error_msg = f"Failed to close session for server '{server_name}': {e}"
|
|
244
|
+
logger.error(error_msg)
|
|
245
|
+
errors.append(error_msg)
|
|
246
|
+
|
|
247
|
+
# Log summary if there were errors
|
|
248
|
+
if errors:
|
|
249
|
+
logger.error(f"Encountered {len(errors)} errors while closing sessions")
|
|
250
|
+
else:
|
|
251
|
+
logger.info("All sessions closed successfully")
|
mcp_use/config.py
CHANGED
|
@@ -5,28 +5,9 @@ This module provides functionality to load MCP configuration from JSON files.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
|
-
import os
|
|
9
|
-
import subprocess
|
|
10
8
|
from typing import Any
|
|
11
9
|
|
|
12
10
|
from .connectors import BaseConnector, HttpConnector, StdioConnector, WebSocketConnector
|
|
13
|
-
from .session import MCPSession
|
|
14
|
-
from .tools.converter import ModelProvider
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _execute_command(command: str, args: list[str], env: dict[str, str] | None = None) -> None:
|
|
18
|
-
"""Execute a command with given arguments and environment variables.
|
|
19
|
-
|
|
20
|
-
Args:
|
|
21
|
-
command: The command to execute
|
|
22
|
-
args: List of command arguments
|
|
23
|
-
env: Optional environment variables to set
|
|
24
|
-
"""
|
|
25
|
-
full_env = os.environ.copy()
|
|
26
|
-
if env:
|
|
27
|
-
full_env.update(env)
|
|
28
|
-
|
|
29
|
-
subprocess.Popen([command] + args, env=full_env)
|
|
30
11
|
|
|
31
12
|
|
|
32
13
|
def load_config_file(filepath: str) -> dict[str, Any]:
|
|
@@ -76,38 +57,3 @@ def create_connector_from_config(server_config: dict[str, Any]) -> BaseConnector
|
|
|
76
57
|
)
|
|
77
58
|
|
|
78
59
|
raise ValueError("Cannot determine connector type from config")
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def create_session_from_config(
|
|
82
|
-
filepath: str,
|
|
83
|
-
server_name: str | None = None,
|
|
84
|
-
model_provider: str | ModelProvider = "openai",
|
|
85
|
-
) -> MCPSession:
|
|
86
|
-
"""Create an MCPSession from a configuration file.
|
|
87
|
-
|
|
88
|
-
Args:
|
|
89
|
-
filepath: Path to the configuration file
|
|
90
|
-
server_name: Name of the server to use from config, uses first if None
|
|
91
|
-
model_provider: Model provider to use for tool conversion
|
|
92
|
-
|
|
93
|
-
Returns:
|
|
94
|
-
Configured MCPSession instance
|
|
95
|
-
"""
|
|
96
|
-
config = load_config_file(filepath)
|
|
97
|
-
|
|
98
|
-
# Get server config
|
|
99
|
-
servers = config.get("mcpServers", {})
|
|
100
|
-
if not servers:
|
|
101
|
-
raise ValueError("No MCP servers defined in config")
|
|
102
|
-
|
|
103
|
-
# If server_name not specified, use the first one
|
|
104
|
-
if not server_name:
|
|
105
|
-
server_name = next(iter(servers.keys()))
|
|
106
|
-
|
|
107
|
-
if server_name not in servers:
|
|
108
|
-
raise ValueError(f"Server '{server_name}' not found in config")
|
|
109
|
-
|
|
110
|
-
server_config = servers[server_name]
|
|
111
|
-
connector = create_connector_from_config(server_config)
|
|
112
|
-
|
|
113
|
-
return MCPSession(connector, model_provider)
|
mcp_use/connectors/base.py
CHANGED
mcp_use/connectors/http.py
CHANGED
|
@@ -8,18 +8,25 @@ through HTTP APIs.
|
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
10
|
import aiohttp
|
|
11
|
+
from mcp.types import Tool
|
|
11
12
|
|
|
13
|
+
from ..logging import logger
|
|
14
|
+
from ..task_managers import ConnectionManager, HttpConnectionManager
|
|
12
15
|
from .base import BaseConnector
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
class HttpConnector(BaseConnector):
|
|
16
19
|
"""Connector for MCP implementations using HTTP transport.
|
|
17
20
|
|
|
18
|
-
This connector uses HTTP requests to communicate with remote MCP implementations
|
|
21
|
+
This connector uses HTTP requests to communicate with remote MCP implementations,
|
|
22
|
+
using a connection manager to handle the proper lifecycle management.
|
|
19
23
|
"""
|
|
20
24
|
|
|
21
25
|
def __init__(
|
|
22
|
-
self,
|
|
26
|
+
self,
|
|
27
|
+
base_url: str,
|
|
28
|
+
auth_token: str | None = None,
|
|
29
|
+
headers: dict[str, str] | None = None,
|
|
23
30
|
):
|
|
24
31
|
"""Initialize a new HTTP connector.
|
|
25
32
|
|
|
@@ -33,17 +40,70 @@ class HttpConnector(BaseConnector):
|
|
|
33
40
|
self.headers = headers or {}
|
|
34
41
|
if auth_token:
|
|
35
42
|
self.headers["Authorization"] = f"Bearer {auth_token}"
|
|
43
|
+
|
|
36
44
|
self.session: aiohttp.ClientSession | None = None
|
|
45
|
+
self._connection_manager: ConnectionManager | None = None
|
|
46
|
+
self._tools: list[Tool] | None = None
|
|
47
|
+
self._connected = False
|
|
37
48
|
|
|
38
49
|
async def connect(self) -> None:
|
|
39
50
|
"""Establish a connection to the MCP implementation."""
|
|
40
|
-
|
|
51
|
+
if self._connected:
|
|
52
|
+
logger.debug("Already connected to MCP implementation")
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
logger.info(f"Connecting to MCP implementation via HTTP: {self.base_url}")
|
|
56
|
+
try:
|
|
57
|
+
# Create and start the connection manager
|
|
58
|
+
self._connection_manager = HttpConnectionManager(self.base_url, self.headers)
|
|
59
|
+
self.session = await self._connection_manager.start()
|
|
60
|
+
|
|
61
|
+
# Mark as connected
|
|
62
|
+
self._connected = True
|
|
63
|
+
logger.info(f"Successfully connected to MCP implementation via HTTP: {self.base_url}")
|
|
64
|
+
|
|
65
|
+
except Exception as e:
|
|
66
|
+
logger.error(f"Failed to connect to MCP implementation via HTTP: {e}")
|
|
67
|
+
|
|
68
|
+
# Clean up any resources if connection failed
|
|
69
|
+
await self._cleanup_resources()
|
|
70
|
+
|
|
71
|
+
# Re-raise the original exception
|
|
72
|
+
raise
|
|
41
73
|
|
|
42
74
|
async def disconnect(self) -> None:
|
|
43
75
|
"""Close the connection to the MCP implementation."""
|
|
44
|
-
if self.
|
|
45
|
-
|
|
46
|
-
|
|
76
|
+
if not self._connected:
|
|
77
|
+
logger.debug("Not connected to MCP implementation")
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
logger.info("Disconnecting from MCP implementation")
|
|
81
|
+
await self._cleanup_resources()
|
|
82
|
+
self._connected = False
|
|
83
|
+
logger.info("Disconnected from MCP implementation")
|
|
84
|
+
|
|
85
|
+
async def _cleanup_resources(self) -> None:
|
|
86
|
+
"""Clean up all resources associated with this connector."""
|
|
87
|
+
errors = []
|
|
88
|
+
|
|
89
|
+
# Stop the connection manager
|
|
90
|
+
if self._connection_manager:
|
|
91
|
+
try:
|
|
92
|
+
logger.debug("Stopping connection manager")
|
|
93
|
+
await self._connection_manager.stop()
|
|
94
|
+
except Exception as e:
|
|
95
|
+
error_msg = f"Error stopping connection manager: {e}"
|
|
96
|
+
logger.warning(error_msg)
|
|
97
|
+
errors.append(error_msg)
|
|
98
|
+
finally:
|
|
99
|
+
self._connection_manager = None
|
|
100
|
+
self.session = None
|
|
101
|
+
|
|
102
|
+
# Reset tools
|
|
103
|
+
self._tools = None
|
|
104
|
+
|
|
105
|
+
if errors:
|
|
106
|
+
logger.warning(f"Encountered {len(errors)} errors during resource cleanup")
|
|
47
107
|
|
|
48
108
|
async def _request(self, method: str, endpoint: str, data: dict[str, Any] | None = None) -> Any:
|
|
49
109
|
"""Send an HTTP request to the MCP API.
|
|
@@ -60,6 +120,7 @@ class HttpConnector(BaseConnector):
|
|
|
60
120
|
raise RuntimeError("HTTP session is not connected")
|
|
61
121
|
|
|
62
122
|
url = f"{self.base_url}/{endpoint.lstrip('/')}"
|
|
123
|
+
logger.debug(f"Sending {method} request to {url}")
|
|
63
124
|
|
|
64
125
|
if method.upper() == "GET" and data:
|
|
65
126
|
# For GET requests, convert data to query parameters
|
|
@@ -74,24 +135,46 @@ class HttpConnector(BaseConnector):
|
|
|
74
135
|
|
|
75
136
|
async def initialize(self) -> dict[str, Any]:
|
|
76
137
|
"""Initialize the MCP session and return session information."""
|
|
77
|
-
|
|
138
|
+
logger.info("Initializing MCP session")
|
|
139
|
+
|
|
140
|
+
# Initialize the session
|
|
141
|
+
result = await self._request("POST", "initialize")
|
|
142
|
+
|
|
143
|
+
# Get available tools
|
|
144
|
+
tools_result = await self.list_tools()
|
|
145
|
+
self._tools = [Tool(**tool) for tool in tools_result]
|
|
146
|
+
|
|
147
|
+
logger.info(f"MCP session initialized with {len(self._tools)} tools")
|
|
148
|
+
return result
|
|
78
149
|
|
|
79
150
|
async def list_tools(self) -> list[dict[str, Any]]:
|
|
80
151
|
"""List all available tools from the MCP implementation."""
|
|
152
|
+
logger.debug("Listing tools")
|
|
81
153
|
result = await self._request("GET", "tools")
|
|
82
154
|
return result.get("tools", [])
|
|
83
155
|
|
|
156
|
+
@property
|
|
157
|
+
def tools(self) -> list[Tool]:
|
|
158
|
+
"""Get the list of available tools."""
|
|
159
|
+
if not self._tools:
|
|
160
|
+
raise RuntimeError("MCP client is not initialized")
|
|
161
|
+
return self._tools
|
|
162
|
+
|
|
84
163
|
async def call_tool(self, name: str, arguments: dict[str, Any]) -> Any:
|
|
85
164
|
"""Call an MCP tool with the given arguments."""
|
|
165
|
+
logger.debug(f"Calling tool '{name}' with arguments: {arguments}")
|
|
86
166
|
return await self._request("POST", f"tools/{name}", arguments)
|
|
87
167
|
|
|
88
168
|
async def list_resources(self) -> list[dict[str, Any]]:
|
|
89
169
|
"""List all available resources from the MCP implementation."""
|
|
170
|
+
logger.debug("Listing resources")
|
|
90
171
|
result = await self._request("GET", "resources")
|
|
91
172
|
return result
|
|
92
173
|
|
|
93
174
|
async def read_resource(self, uri: str) -> tuple[bytes, str]:
|
|
94
175
|
"""Read a resource by URI."""
|
|
176
|
+
logger.debug(f"Reading resource: {uri}")
|
|
177
|
+
|
|
95
178
|
# For resources, we may need to handle binary data
|
|
96
179
|
if not self.session:
|
|
97
180
|
raise RuntimeError("HTTP session is not connected")
|
|
@@ -122,5 +205,6 @@ class HttpConnector(BaseConnector):
|
|
|
122
205
|
|
|
123
206
|
async def request(self, method: str, params: dict[str, Any] | None = None) -> Any:
|
|
124
207
|
"""Send a raw request to the MCP implementation."""
|
|
208
|
+
logger.debug(f"Sending request: {method} with params: {params}")
|
|
125
209
|
# For custom methods, we'll use the RPC-style endpoint
|
|
126
210
|
return await self._request("POST", "rpc", {"method": method, "params": params or {}})
|