Skip to content

Commit 35125c5

Browse files
committed
feat!: Use new MCP SessionMessage for Lambda client transport
1 parent 14afb34 commit 35125c5

File tree

2 files changed

+58
-40
lines changed

2 files changed

+58
-40
lines changed

src/python/src/mcp_lambda/client/lambda_client.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import mcp.types as types
77
from aiobotocore.session import get_session
88
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
9+
from mcp.shared.message import SessionMessage
910
from pydantic import BaseModel
1011

1112

@@ -23,11 +24,11 @@ async def lambda_function_client(lambda_function: LambdaFunctionParameters):
2324
Client transport for Lambda functions: this will invoke a Lambda function
2425
when requests are sent to the client.
2526
"""
26-
read_stream: MemoryObjectReceiveStream[types.JSONRPCMessage | Exception]
27-
read_stream_writer: MemoryObjectSendStream[types.JSONRPCMessage | Exception]
27+
read_stream: MemoryObjectReceiveStream[SessionMessage | Exception]
28+
read_stream_writer: MemoryObjectSendStream[SessionMessage | Exception]
2829

29-
write_stream: MemoryObjectSendStream[types.JSONRPCMessage]
30-
write_stream_reader: MemoryObjectReceiveStream[types.JSONRPCMessage]
30+
write_stream: MemoryObjectSendStream[SessionMessage]
31+
write_stream_reader: MemoryObjectReceiveStream[SessionMessage]
3132

3233
read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
3334
write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
@@ -44,7 +45,8 @@ async def invoke_function():
4445
"lambda", region_name=lambda_function.region_name
4546
) as lambda_client:
4647
async with write_stream_reader:
47-
async for message in write_stream_reader:
48+
async for session_message in write_stream_reader:
49+
message = session_message.message
4850
logging.debug(
4951
f"MCP JSON RPC message raw: {message.__class__.__name__} {message}"
5052
)
@@ -113,12 +115,15 @@ async def invoke_function():
113115
),
114116
)
115117
)
116-
await read_stream_writer.send(error_message)
118+
await read_stream_writer.send(
119+
SessionMessage(error_message)
120+
)
117121
else:
118122
await read_stream_writer.send(exc)
119123
continue
120124

121-
await read_stream_writer.send(response_message)
125+
session_message = SessionMessage(response_message)
126+
await read_stream_writer.send(session_message)
122127
except anyio.ClosedResourceError:
123128
await anyio.lowlevel.checkpoint()
124129
except Exception as exc:

src/python/tests/client/test_lambda_client.py

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import anyio
77
import pytest
8+
from mcp.shared.message import SessionMessage
89
from mcp.types import (
910
JSONRPCError,
1011
JSONRPCMessage,
@@ -56,8 +57,8 @@ async def test_lambda_function_client_success(mock_client_creator, mock_session)
5657
)
5758

5859
# Create a test message
59-
test_message = JSONRPCMessage(
60-
root=JSONRPCRequest(jsonrpc="2.0", id=1, method="ping")
60+
test_message = SessionMessage(
61+
JSONRPCMessage(root=JSONRPCRequest(jsonrpc="2.0", id=1, method="ping"))
6162
)
6263

6364
async with lambda_function_client(lambda_parameters) as (read_stream, write_stream):
@@ -70,10 +71,11 @@ async def test_lambda_function_client_success(mock_client_creator, mock_session)
7071
response = await read_stream.receive()
7172

7273
# Verify the response
73-
assert isinstance(response, JSONRPCMessage)
74-
assert isinstance(response.root, JSONRPCResponse)
75-
assert response.root.id == "response-id"
76-
assert response.root.result == {"message": "success"}
74+
assert isinstance(response, SessionMessage)
75+
assert isinstance(response.message, JSONRPCMessage)
76+
assert isinstance(response.message.root, JSONRPCResponse)
77+
assert response.message.root.id == "response-id"
78+
assert response.message.root.result == {"message": "success"}
7779

7880
# Verify Lambda was invoked with correct parameters
7981
mock_client.invoke.assert_called_once()
@@ -100,8 +102,10 @@ async def test_lambda_function_notification_success(mock_client_creator, mock_se
100102
)
101103

102104
# Create a test message
103-
test_message = JSONRPCMessage(
104-
root=JSONRPCNotification(jsonrpc="2.0", method="notifications/initialized")
105+
test_message = SessionMessage(
106+
JSONRPCMessage(
107+
root=JSONRPCNotification(jsonrpc="2.0", method="notifications/initialized")
108+
)
105109
)
106110

107111
async with lambda_function_client(lambda_parameters) as (read_stream, write_stream):
@@ -146,9 +150,11 @@ async def test_lambda_function_client_function_error(mock_client_creator, mock_s
146150
)
147151

148152
# Create a test message
149-
test_message = JSONRPCMessage(
150-
root=JSONRPCRequest(
151-
jsonrpc="2.0", id=1, method="call/tool", params={"hello": "world"}
153+
test_message = SessionMessage(
154+
JSONRPCMessage(
155+
root=JSONRPCRequest(
156+
jsonrpc="2.0", id=1, method="call/tool", params={"hello": "world"}
157+
)
152158
)
153159
)
154160

@@ -162,13 +168,15 @@ async def test_lambda_function_client_function_error(mock_client_creator, mock_s
162168
response = await read_stream.receive()
163169

164170
# Verify the response is an error message
165-
assert isinstance(response, JSONRPCMessage)
166-
assert isinstance(response.root, JSONRPCError)
167-
assert response.root.id == 1
168-
assert response.root.error is not None
169-
assert response.root.error.code == 500
171+
assert isinstance(response, SessionMessage)
172+
assert isinstance(response.message, JSONRPCMessage)
173+
assert isinstance(response.message.root, JSONRPCError)
174+
assert response.message.root.id == 1
175+
assert response.message.root.error is not None
176+
assert response.message.root.error.code == 500
170177
assert (
171-
"Function invoke returned a function error" in response.root.error.message
178+
"Function invoke returned a function error"
179+
in response.message.root.error.message
172180
)
173181

174182
# Verify Lambda was invoked with correct parameters
@@ -198,8 +206,8 @@ async def test_lambda_function_client_invoke_exception(
198206
mock_client.invoke.side_effect = Exception("Connection error")
199207

200208
# Create a test message
201-
test_message = JSONRPCMessage(
202-
root=JSONRPCRequest(jsonrpc="2.0", id=1, method="ping")
209+
test_message = SessionMessage(
210+
JSONRPCMessage(root=JSONRPCRequest(jsonrpc="2.0", id=1, method="ping"))
203211
)
204212

205213
async with lambda_function_client(lambda_parameters) as (read_stream, write_stream):
@@ -212,12 +220,13 @@ async def test_lambda_function_client_invoke_exception(
212220
response = await read_stream.receive()
213221

214222
# Verify the response is an error message
215-
assert isinstance(response, JSONRPCMessage)
216-
assert isinstance(response.root, JSONRPCError)
217-
assert response.root.id == 1
218-
assert response.root.error is not None
219-
assert response.root.error.code == 500
220-
assert "Connection error" in response.root.error.message
223+
assert isinstance(response, SessionMessage)
224+
assert isinstance(response.message, JSONRPCMessage)
225+
assert isinstance(response.message.root, JSONRPCError)
226+
assert response.message.root.id == 1
227+
assert response.message.root.error is not None
228+
assert response.message.root.error.code == 500
229+
assert "Connection error" in response.message.root.error.message
221230

222231
# Verify Lambda was invoked with correct parameters
223232
mock_client.invoke.assert_called_once()
@@ -246,8 +255,8 @@ async def test_lambda_function_client_invalid_response(
246255
)
247256

248257
# Create a test message
249-
test_message = JSONRPCMessage(
250-
root=JSONRPCRequest(jsonrpc="2.0", id=1, method="ping")
258+
test_message = SessionMessage(
259+
JSONRPCMessage(root=JSONRPCRequest(jsonrpc="2.0", id=1, method="ping"))
251260
)
252261

253262
async with lambda_function_client(lambda_parameters) as (read_stream, write_stream):
@@ -260,12 +269,16 @@ async def test_lambda_function_client_invalid_response(
260269
response = await read_stream.receive()
261270

262271
# Verify the response is an error message
263-
assert isinstance(response, JSONRPCMessage)
264-
assert isinstance(response.root, JSONRPCError)
265-
assert response.root.id == 1
266-
assert response.root.error is not None
267-
assert response.root.error.code == 500
268-
assert "4 validation errors for JSONRPCMessage" in response.root.error.message
272+
assert isinstance(response, SessionMessage)
273+
assert isinstance(response.message, JSONRPCMessage)
274+
assert isinstance(response.message.root, JSONRPCError)
275+
assert response.message.root.id == 1
276+
assert response.message.root.error is not None
277+
assert response.message.root.error.code == 500
278+
assert (
279+
"4 validation errors for JSONRPCMessage"
280+
in response.message.root.error.message
281+
)
269282

270283
# Verify Lambda was invoked with correct parameters
271284
mock_client.invoke.assert_called_once()

0 commit comments

Comments
 (0)