@@ -68,8 +68,143 @@ MCP-compatible applications such as Cursor, Cline, Claude Desktop, etc.
68
68
69
69
You can choose your desired OAuth server provider for this solution. The examples in this
70
70
repository use Amazon Cognito, or you can use third-party providers such as Okta or Auth0
71
- with API Gateway custom authorization. Alternatively, you can issue bearer tokens such as API keys
72
- to your clients and use API Gateway custom authorization to validate the request bearer token.
71
+ with API Gateway custom authorization.
72
+
73
+ <details >
74
+
75
+ <summary ><b >Python server example</b ></summary >
76
+
77
+ ``` python
78
+ import sys
79
+ from mcp.client.stdio import StdioServerParameters
80
+ from mcp_lambda import APIGatewayProxyEventHandler, StdioServerAdapterRequestHandler
81
+
82
+ server_params = StdioServerParameters(
83
+ command = sys.executable,
84
+ args = [
85
+ " -m" ,
86
+ " my_mcp_server_python_module" ,
87
+ " --my-server-command-line-parameter" ,
88
+ " some_value" ,
89
+ ],
90
+ )
91
+
92
+
93
+ request_handler = StdioServerAdapterRequestHandler(server_params)
94
+ event_handler = APIGatewayProxyEventHandler(request_handler)
95
+
96
+
97
+ def handler (event , context ):
98
+ return event_handler.handle(event, context)
99
+ ```
100
+
101
+ See a full, deployable example [ here] ( examples/servers/dad-jokes/ ) .
102
+
103
+ </details >
104
+
105
+ <details >
106
+
107
+ <summary ><b >Typescript server example</b ></summary >
108
+
109
+ ``` typescript
110
+ import {
111
+ Handler ,
112
+ Context ,
113
+ APIGatewayProxyWithCognitoAuthorizerEvent ,
114
+ APIGatewayProxyResult ,
115
+ } from " aws-lambda" ;
116
+ import {
117
+ APIGatewayProxyEventHandler ,
118
+ StdioServerAdapterRequestHandler ,
119
+ } from " @aws/run-mcp-servers-with-aws-lambda" ;
120
+
121
+ const serverParams = {
122
+ command: " npx" ,
123
+ args: [
124
+ " --offline" ,
125
+ " my-mcp-server-typescript-module" ,
126
+ " --my-server-command-line-parameter" ,
127
+ " some_value" ,
128
+ ],
129
+ };
130
+
131
+ const requestHandler = new APIGatewayProxyEventHandler (
132
+ new StdioServerAdapterRequestHandler (serverParams )
133
+ );
134
+
135
+ export const handler: Handler = async (
136
+ event : APIGatewayProxyWithCognitoAuthorizerEvent ,
137
+ context : Context
138
+ ): Promise <APIGatewayProxyResult > => {
139
+ return requestHandler .handle (event , context );
140
+ };
141
+ ```
142
+
143
+ See a full, deployable example [ here] ( examples/servers/dog-facts/ ) .
144
+
145
+ </details >
146
+
147
+ <details >
148
+
149
+ <summary ><b >Python client example</b ></summary >
150
+
151
+ ``` python
152
+ from mcp import ClientSession
153
+ from mcp.client.streamable_http import streamablehttp_client
154
+
155
+ # Create OAuth client provider here
156
+
157
+ async with streamablehttp_client(
158
+ url = " https://abc123.execute-api.us-east-2.amazonaws.com/prod/mcp" ,
159
+ auth = oauth_client_provider,
160
+ ) as (
161
+ read_stream,
162
+ write_stream,
163
+ _,
164
+ ):
165
+ async with ClientSession(read_stream, write_stream) as session:
166
+ await session.initialize()
167
+ tool_result = await session.call_tool(" echo" , {" message" : " hello" })
168
+ ```
169
+
170
+ See a full example as part of the sample chatbot [ here] ( examples/chatbots/python/server_clients/interactive_oauth.py ) .
171
+
172
+ </details >
173
+
174
+ <details >
175
+
176
+ <summary ><b >Typescript client example</b ></summary >
177
+
178
+ ``` typescript
179
+ import { StreamableHTTPClientTransport } from " @modelcontextprotocol/sdk/client/streamableHttp.js" ;
180
+ import { Client } from " @modelcontextprotocol/sdk/client/index.js" ;
181
+
182
+ const client = new Client (
183
+ {
184
+ name: " my-client" ,
185
+ version: " 0.0.1" ,
186
+ },
187
+ {
188
+ capabilities: {
189
+ sampling: {},
190
+ },
191
+ }
192
+ );
193
+
194
+ // Create OAuth client provider here
195
+
196
+ const transport = new StreamableHTTPClientTransport (
197
+ " https://abc123.execute-api.us-east-2.amazonaws.com/prod/mcp" ,
198
+ {
199
+ authProvider: oauthProvider ,
200
+ }
201
+ );
202
+ await client .connect (transport );
203
+ ```
204
+
205
+ See a full example as part of the sample chatbot [ here] ( examples/chatbots/typescript/src/server_clients/interactive_oauth.ts ) .
206
+
207
+ </details >
73
208
74
209
## Using a Lambda function URL
75
210
@@ -89,6 +224,140 @@ HTTP transport that signs requests with [AWS SigV4](https://docs.aws.amazon.com/
89
224
Off-the-shelf MCP-compatible applications are unlikely to have support for this custom transport,
90
225
so this solution is more appropriate for service-to-service communication rather than for end users.
91
226
227
+ <details >
228
+
229
+ <summary ><b >Python server example</b ></summary >
230
+
231
+ ``` python
232
+ import sys
233
+ from mcp.client.stdio import StdioServerParameters
234
+ from mcp_lambda import LambdaFunctionURLEventHandler, StdioServerAdapterRequestHandler
235
+
236
+ server_params = StdioServerParameters(
237
+ command = sys.executable,
238
+ args = [
239
+ " -m" ,
240
+ " my_mcp_server_python_module" ,
241
+ " --my-server-command-line-parameter" ,
242
+ " some_value" ,
243
+ ],
244
+ )
245
+
246
+
247
+ request_handler = StdioServerAdapterRequestHandler(server_params)
248
+ event_handler = LambdaFunctionURLEventHandler(request_handler)
249
+
250
+
251
+ def handler (event , context ):
252
+ return event_handler.handle(event, context)
253
+ ```
254
+
255
+ See a full, deployable example [ here] ( examples/servers/mcpdoc/ ) .
256
+
257
+ </details >
258
+
259
+ <details >
260
+
261
+ <summary ><b >Typescript server example</b ></summary >
262
+
263
+ ``` typescript
264
+ import {
265
+ Handler ,
266
+ Context ,
267
+ APIGatewayProxyEventV2WithIAMAuthorizer ,
268
+ APIGatewayProxyResultV2 ,
269
+ } from " aws-lambda" ;
270
+ import {
271
+ LambdaFunctionURLEventHandler ,
272
+ StdioServerAdapterRequestHandler ,
273
+ } from " @aws/run-mcp-servers-with-aws-lambda" ;
274
+
275
+ const serverParams = {
276
+ command: " npx" ,
277
+ args: [
278
+ " --offline" ,
279
+ " my-mcp-server-typescript-module" ,
280
+ " --my-server-command-line-parameter" ,
281
+ " some_value" ,
282
+ ],
283
+ };
284
+
285
+ const requestHandler = new LambdaFunctionURLEventHandler (
286
+ new StdioServerAdapterRequestHandler (serverParams )
287
+ );
288
+
289
+ export const handler: Handler = async (
290
+ event : APIGatewayProxyEventV2WithIAMAuthorizer ,
291
+ context : Context
292
+ ): Promise <APIGatewayProxyResultV2 > => {
293
+ return requestHandler .handle (event , context );
294
+ };
295
+ ```
296
+
297
+ See a full, deployable example [ here] ( examples/servers/cat-facts/ ) .
298
+
299
+ </details >
300
+
301
+ <details >
302
+
303
+ <summary ><b >Python client example</b ></summary >
304
+
305
+ ``` python
306
+ from mcp import ClientSession
307
+ from mcp_lambda.client.streamable_http_sigv4 import streamablehttp_client_with_sigv4
308
+
309
+ async with streamablehttp_client_with_sigv4(
310
+ url = " https://url-id-12345.lambda-url.us-east-2.on.aws" ,
311
+ service = " lambda" ,
312
+ region = " us-east-2" ,
313
+ ) as (
314
+ read_stream,
315
+ write_stream,
316
+ _,
317
+ ):
318
+ async with ClientSession(read_stream, write_stream) as session:
319
+ await session.initialize()
320
+ tool_result = await session.call_tool(" echo" , {" message" : " hello" })
321
+ ```
322
+
323
+ See a full example as part of the sample chatbot [ here] ( examples/chatbots/python/server_clients/lambda_function_url.py ) .
324
+
325
+ </details >
326
+
327
+ <details >
328
+
329
+ <summary ><b >Typescript client example</b ></summary >
330
+
331
+ ``` typescript
332
+ import { StreamableHTTPClientWithSigV4Transport } from " @aws/run-mcp-servers-with-aws-lambda" ;
333
+ import { Client } from " @modelcontextprotocol/sdk/client/index.js" ;
334
+
335
+ const client = new Client (
336
+ {
337
+ name: " my-client" ,
338
+ version: " 0.0.1" ,
339
+ },
340
+ {
341
+ capabilities: {
342
+ sampling: {},
343
+ },
344
+ }
345
+ );
346
+
347
+ const transport = new StreamableHTTPClientWithSigV4Transport (
348
+ new URL (" https://url-id-12345.lambda-url.us-east-2.on.aws" ),
349
+ {
350
+ service: " lambda" ,
351
+ region: " us-east-2" ,
352
+ }
353
+ );
354
+ await client .connect (transport );
355
+ ```
356
+
357
+ See a full example as part of the sample chatbot [ here] ( examples/chatbots/typescript/src/server_clients/lambda_function_url.ts ) .
358
+
359
+ </details >
360
+
92
361
## Using the Lambda Invoke API
93
362
94
363
``` mermaid
@@ -120,9 +389,9 @@ server_params = StdioServerParameters(
120
389
command = sys.executable,
121
390
args = [
122
391
" -m" ,
123
- " mcp_server_time " ,
124
- " --local-timezone " ,
125
- " America/New_York " ,
392
+ " my_mcp_server_python_module " ,
393
+ " --my-server-command-line-parameter " ,
394
+ " some_value " ,
126
395
],
127
396
)
128
397
@@ -141,18 +410,19 @@ See a full, deployable example [here](examples/servers/time/).
141
410
142
411
``` typescript
143
412
import { Handler , Context } from " aws-lambda" ;
413
+ import { stdioServerAdapter } from " @aws/run-mcp-servers-with-aws-lambda" ;
144
414
145
415
const serverParams = {
146
416
command: " npx" ,
147
- args: [" --offline" , " openapi-mcp-server" , " ./weather-alerts-openapi.json" ],
417
+ args: [
418
+ " --offline" ,
419
+ " my-mcp-server-typescript-module" ,
420
+ " --my-server-command-line-parameter" ,
421
+ " some_value" ,
422
+ ],
148
423
};
149
424
150
425
export const handler: Handler = async (event , context : Context ) => {
151
- // Dynamically import ES module into CommonJS Lambda function
152
- const { stdioServerAdapter } = await import (
153
- " @aws/run-mcp-servers-with-aws-lambda"
154
- );
155
-
156
426
return await stdioServerAdapter (serverParams , event , context );
157
427
};
158
428
```
@@ -170,13 +440,17 @@ from mcp import ClientSession
170
440
from mcp_lambda import LambdaFunctionParameters, lambda_function_client
171
441
172
442
server_params = LambdaFunctionParameters(
173
- function_name = " mcp-server-time " ,
443
+ function_name = " my- mcp-server-function " ,
174
444
region_name = " us-east-2" ,
175
445
)
176
446
177
- read, write = await lambda_function_client(server_params)
178
- session = ClientSession(read, write)
179
- await session.initialize()
447
+ async with lambda_function_client(server_params) as (
448
+ read_stream,
449
+ write_stream,
450
+ ):
451
+ async with ClientSession(read_stream, write_stream) as session:
452
+ await session.initialize()
453
+ tool_result = await session.call_tool(" echo" , {" message" : " hello" })
180
454
```
181
455
182
456
See a full example as part of the sample chatbot [ here] ( examples/chatbots/python/server_clients/lambda_function.py ) .
@@ -195,7 +469,7 @@ import {
195
469
import { Client } from " @modelcontextprotocol/sdk/client/index.js" ;
196
470
197
471
const serverParams: LambdaFunctionParameters = {
198
- functionName: " mcp-server-time " ,
472
+ functionName: " my- mcp-server-function " ,
199
473
regionName: " us-east-2" ,
200
474
};
201
475
0 commit comments