@aws/run-mcp-servers-with-aws-lambda 0.5.12 → 0.5.13
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.
- package/README.md +160 -11
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -150,6 +150,158 @@ node /var/task/node_modules/@ivotoby/openapi-mcp-server/bin/mcp-server.js
|
|
|
150
150
|
|
|
151
151
|
</details>
|
|
152
152
|
|
|
153
|
+
### Passing credentials and other secrets to the MCP server
|
|
154
|
+
|
|
155
|
+
This library does not provide out-of-the-box mechanisms for managing any secrets needed by the wrapped
|
|
156
|
+
MCP server. For example, the [GitHub MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/github)
|
|
157
|
+
and the [Brave search MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search)
|
|
158
|
+
require API keys to make requests to third-party APIs.
|
|
159
|
+
You may configure these API keys as
|
|
160
|
+
[encrypted environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars-encryption.html)
|
|
161
|
+
in the Lambda function's configuration or retrieve them from Secrets Manager in the Lambda function code (examples below).
|
|
162
|
+
However, note that anyone with access to invoke the Lambda function
|
|
163
|
+
will then have access to use your API key to call the third-party APIs by invoking the function.
|
|
164
|
+
We recommend limiting access to the Lambda function using
|
|
165
|
+
[least-privilege IAM policies](https://docs.aws.amazon.com/lambda/latest/dg/security-iam.html).
|
|
166
|
+
If you use an identity-based authentication mechanism such as OAuth, you could also store and retrieve API keys per user but there are no implementation examples in this repository.
|
|
167
|
+
|
|
168
|
+
<details>
|
|
169
|
+
|
|
170
|
+
<summary><b>Python server example retrieving an API key from Secrets Manager</b></summary>
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
import sys
|
|
174
|
+
|
|
175
|
+
import boto3
|
|
176
|
+
from mcp.client.stdio import StdioServerParameters
|
|
177
|
+
|
|
178
|
+
# Retrieve API key from Secrets Manager
|
|
179
|
+
secrets_client = boto3.client("secretsmanager")
|
|
180
|
+
api_key = secrets_client.get_secret_value(SecretId="my-api-key-secret")["SecretString"]
|
|
181
|
+
|
|
182
|
+
server_params = StdioServerParameters(
|
|
183
|
+
command=sys.executable,
|
|
184
|
+
args=["-m", "my_mcp_server"],
|
|
185
|
+
env={
|
|
186
|
+
"API_KEY": api_key,
|
|
187
|
+
},
|
|
188
|
+
)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
</details>
|
|
192
|
+
|
|
193
|
+
<details>
|
|
194
|
+
|
|
195
|
+
<summary><b>Typescript server example retrieving an API key from Secrets Manager</b></summary>
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
|
|
199
|
+
|
|
200
|
+
const secretsClient = new SecretsManagerClient({});
|
|
201
|
+
const secret = await secretsClient.send(
|
|
202
|
+
new GetSecretValueCommand({ SecretId: "my-api-key-secret" })
|
|
203
|
+
);
|
|
204
|
+
const apiKey = secret.SecretString;
|
|
205
|
+
|
|
206
|
+
const serverParams = {
|
|
207
|
+
command: "npx",
|
|
208
|
+
args: ["--offline", "my-mcp-server"],
|
|
209
|
+
env: {
|
|
210
|
+
API_KEY: apiKey,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
</details>
|
|
216
|
+
<br/>
|
|
217
|
+
|
|
218
|
+
If your MCP server needs to call AWS APIs (such as the [MCP servers for AWS](https://github.com/awslabs/mcp)),
|
|
219
|
+
you can pass the Lambda function's AWS credentials to the wrapped MCP server via environment variables.
|
|
220
|
+
The wrapped MCP server's child process does not automatically inherit the Lambda execution role's credentials.
|
|
221
|
+
Again, note that anyone with access to invoke the Lambda function
|
|
222
|
+
will then have access to use the function's AWS credentials to call AWS APIs by invoking the function.
|
|
223
|
+
We recommend limiting access to the Lambda function using
|
|
224
|
+
[least-privilege IAM policies](https://docs.aws.amazon.com/lambda/latest/dg/security-iam.html).
|
|
225
|
+
|
|
226
|
+
<details>
|
|
227
|
+
|
|
228
|
+
<summary><b>Python server example using AWS credentials via environment variables</b></summary>
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
import os
|
|
232
|
+
import sys
|
|
233
|
+
|
|
234
|
+
import boto3
|
|
235
|
+
from mcp.client.stdio import StdioServerParameters
|
|
236
|
+
|
|
237
|
+
# Get AWS credentials from Lambda execution role to pass to subprocess
|
|
238
|
+
session = boto3.Session()
|
|
239
|
+
credentials = session.get_credentials()
|
|
240
|
+
if credentials is None:
|
|
241
|
+
raise RuntimeError("Unable to retrieve AWS credentials from the execution environment")
|
|
242
|
+
resolved = credentials.get_frozen_credentials()
|
|
243
|
+
|
|
244
|
+
server_params = StdioServerParameters(
|
|
245
|
+
command=sys.executable,
|
|
246
|
+
args=["-m", "my_mcp_server"],
|
|
247
|
+
env={
|
|
248
|
+
"AWS_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
249
|
+
"AWS_DEFAULT_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
250
|
+
"AWS_ACCESS_KEY_ID": resolved.access_key,
|
|
251
|
+
"AWS_SECRET_ACCESS_KEY": resolved.secret_key,
|
|
252
|
+
"AWS_SESSION_TOKEN": resolved.token or "",
|
|
253
|
+
},
|
|
254
|
+
)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
</details>
|
|
258
|
+
|
|
259
|
+
<details>
|
|
260
|
+
|
|
261
|
+
<summary><b>Python server example using AWS credentials via credentials file</b></summary>
|
|
262
|
+
|
|
263
|
+
Some MCP servers require an AWS profile and do not support credentials passed via environment variables.
|
|
264
|
+
In this case, you can write the credentials to a file and point the MCP server to it.
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
import os
|
|
268
|
+
import sys
|
|
269
|
+
|
|
270
|
+
import boto3
|
|
271
|
+
from mcp.client.stdio import StdioServerParameters
|
|
272
|
+
|
|
273
|
+
# Get AWS credentials from Lambda execution role to pass to subprocess
|
|
274
|
+
session = boto3.Session()
|
|
275
|
+
credentials = session.get_credentials()
|
|
276
|
+
if credentials is None:
|
|
277
|
+
raise RuntimeError("Unable to retrieve AWS credentials from the execution environment")
|
|
278
|
+
resolved = credentials.get_frozen_credentials()
|
|
279
|
+
|
|
280
|
+
# Write credentials to disk as default profile
|
|
281
|
+
aws_dir = "/tmp/.aws"
|
|
282
|
+
os.makedirs(aws_dir, exist_ok=True)
|
|
283
|
+
with open(f"{aws_dir}/credentials", "w") as f:
|
|
284
|
+
f.write("[default]\n")
|
|
285
|
+
f.write(f"aws_access_key_id = {resolved.access_key}\n")
|
|
286
|
+
f.write(f"aws_secret_access_key = {resolved.secret_key}\n")
|
|
287
|
+
if resolved.token:
|
|
288
|
+
f.write(f"aws_session_token = {resolved.token}\n")
|
|
289
|
+
|
|
290
|
+
server_params = StdioServerParameters(
|
|
291
|
+
command=sys.executable,
|
|
292
|
+
args=["-m", "my_mcp_server"],
|
|
293
|
+
env={
|
|
294
|
+
"AWS_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
295
|
+
"AWS_DEFAULT_REGION": os.environ.get("AWS_REGION", "us-west-2"),
|
|
296
|
+
"AWS_SHARED_CREDENTIALS_FILE": f"{aws_dir}/credentials",
|
|
297
|
+
},
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
See a full, deployable example [here](examples/servers/sns-sqs/).
|
|
302
|
+
|
|
303
|
+
</details>
|
|
304
|
+
|
|
153
305
|
## Use API Gateway
|
|
154
306
|
|
|
155
307
|
```mermaid
|
|
@@ -341,6 +493,14 @@ npx @modelcontextprotocol/inspector --cli --method tools/list <your MCP server c
|
|
|
341
493
|
npx @modelcontextprotocol/inspector --cli --method tools/list uvx mcp-server-time > tool-schema.json
|
|
342
494
|
```
|
|
343
495
|
|
|
496
|
+
Some MCP servers generate tool schemas that AgentCore Gateway rejects with strict validation,
|
|
497
|
+
such as `"items": {}`, `"default": null`, or `anyOf` with `{"type": "null"}`.
|
|
498
|
+
You may need to clean up the schema before using it:
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
python3 scripts/clean-tool-schema.py tool-schema.json
|
|
502
|
+
```
|
|
503
|
+
|
|
344
504
|
<details>
|
|
345
505
|
|
|
346
506
|
<summary><b>Python server example</b></summary>
|
|
@@ -780,17 +940,6 @@ See a full example as part of the sample chatbot [here](examples/chatbots/typesc
|
|
|
780
940
|
the [sqlite MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/sqlite),
|
|
781
941
|
the [filesystem MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem),
|
|
782
942
|
and the [git MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/git).
|
|
783
|
-
- This library does not provide mechanisms for managing any secrets needed by the wrapped
|
|
784
|
-
MCP server. For example, the [GitHub MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/github)
|
|
785
|
-
and the [Brave search MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search)
|
|
786
|
-
require API keys to make requests to third-party APIs.
|
|
787
|
-
You may configure these API keys as
|
|
788
|
-
[encrypted environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars-encryption.html)
|
|
789
|
-
in the Lambda function's configuration. However, note that anyone with access to invoke the Lambda function
|
|
790
|
-
will then have access to use your API key to call the third-party APIs by invoking the function.
|
|
791
|
-
We recommend limiting access to the Lambda function using
|
|
792
|
-
[least-privilege IAM policies](https://docs.aws.amazon.com/lambda/latest/dg/security-iam.html).
|
|
793
|
-
If you use an identity-based authentication mechanism such as OAuth, you could also store and retrieve API keys per user but there are no implementation examples in this repository.
|
|
794
943
|
|
|
795
944
|
## Deploy and run the examples
|
|
796
945
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/run-mcp-servers-with-aws-lambda",
|
|
3
3
|
"description": "Run Model Context Protocol (MCP) servers with AWS Lambda",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.13",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": {
|
|
@@ -44,21 +44,21 @@
|
|
|
44
44
|
"@tsconfig/recommended": "^1.0.13",
|
|
45
45
|
"@types/aws-lambda": "^8.10.161",
|
|
46
46
|
"@types/jest": "^30.0.0",
|
|
47
|
-
"@types/node": "^25.
|
|
47
|
+
"@types/node": "^25.5.0",
|
|
48
48
|
"aws-sdk-client-mock": "^4.1.0",
|
|
49
49
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
50
|
-
"eslint": "^10.0.
|
|
50
|
+
"eslint": "^10.0.3",
|
|
51
51
|
"eslint-plugin-check-file": "^3.3.1",
|
|
52
|
-
"jest": "^30.
|
|
52
|
+
"jest": "^30.3.0",
|
|
53
53
|
"ts-jest": "^29.4.6",
|
|
54
54
|
"tsx": "^4.21.0",
|
|
55
55
|
"typescript": "^5.9.3",
|
|
56
|
-
"typescript-eslint": "^8.
|
|
56
|
+
"typescript-eslint": "^8.57.1"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@aws-crypto/sha256-js": "^5.2.0",
|
|
60
|
-
"@aws-sdk/client-lambda": "^3.
|
|
61
|
-
"@aws-sdk/credential-provider-node": "^3.
|
|
60
|
+
"@aws-sdk/client-lambda": "^3.1010.0",
|
|
61
|
+
"@aws-sdk/credential-provider-node": "^3.972.21",
|
|
62
62
|
"@aws-sdk/protocol-http": "^3.374.0",
|
|
63
63
|
"@aws-sdk/types": "^3.910.0",
|
|
64
64
|
"@modelcontextprotocol/sdk": "^1.27.1",
|