@aws/nx-plugin-mcp 1.0.0-rc.2 → 1.0.0-rc.21
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/bin/aws-nx-mcp.js +5919 -4776
- package/docs/guides/agentcore-gateway.mdx +240 -0
- package/docs/guides/connection/agentcore-gateway-gateway.mdx +154 -0
- package/docs/guides/connection/agentcore-gateway-mcp.mdx +134 -0
- package/docs/guides/connection/py-agent-a2a.mdx +8 -5
- package/docs/guides/connection/py-agent-dynamodb.mdx +116 -0
- package/docs/guides/connection/py-agent-gateway.mdx +161 -0
- package/docs/guides/connection/py-agent-mcp.mdx +7 -4
- package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
- package/docs/guides/connection/py-mcp-server-dynamodb.mdx +116 -0
- package/docs/guides/connection/react-smithy.mdx +1 -1
- package/docs/guides/connection/react-trpc.mdx +1 -1
- package/docs/guides/connection/smithy-dynamodb.mdx +68 -0
- package/docs/guides/connection/smithy-rdb.mdx +1 -1
- package/docs/guides/connection/trpc-dynamodb.mdx +62 -0
- package/docs/guides/connection/trpc-rdb.mdx +1 -1
- package/docs/guides/connection/ts-agent-a2a.mdx +8 -5
- package/docs/guides/connection/ts-agent-dynamodb.mdx +128 -0
- package/docs/guides/connection/ts-agent-gateway.mdx +152 -0
- package/docs/guides/connection/ts-agent-mcp.mdx +7 -4
- package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +125 -0
- package/docs/guides/connection.mdx +89 -0
- package/docs/guides/docker-bundling.mdx +13 -7
- package/docs/guides/fastapi.mdx +213 -3
- package/docs/guides/license.mdx +264 -109
- package/docs/guides/local-development.mdx +76 -0
- package/docs/guides/nx-generator.mdx +5 -0
- package/docs/guides/py-agent.mdx +42 -3
- package/docs/guides/py-dynamodb.mdx +449 -0
- package/docs/guides/py-mcp-server.mdx +5 -1
- package/docs/guides/react-website-auth.mdx +15 -0
- package/docs/guides/react-website.mdx +12 -4
- package/docs/guides/trpc.mdx +8 -8
- package/docs/guides/ts-agent.mdx +40 -2
- package/docs/guides/ts-dynamodb.mdx +158 -0
- package/docs/guides/ts-mcp-server.mdx +5 -1
- package/docs/guides/ts-rdb.mdx +58 -10
- package/docs/guides/ts-smithy-api.mdx +148 -3
- package/docs/guides/typescript-project.mdx +5 -10
- package/docs/guides/workspace.mdx +8 -2
- package/docs/snippets/api/type-safe-api-integrations.mdx +31 -0
- package/docs/snippets/api/waf-configuration.mdx +1 -1
- package/docs/snippets/connection/dynamodb-local-development.mdx +7 -0
- package/docs/snippets/connection/lambda-dynamodb-access.mdx +80 -0
- package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
- package/docs/snippets/dynamodb/deploying-table.mdx +171 -0
- package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
- package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
- package/docs/snippets/dynamodb/serve-local-start.mdx +13 -0
- package/docs/snippets/dynamodb/serve-local-windows.mdx +15 -0
- package/docs/snippets/mcp/config.mdx +1 -1
- package/docs/snippets/required-prerequisites.mdx +1 -1
- package/generators.json +100 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/gateway-connection/schema.json +26 -0
- package/src/agentcore-gateway/mcp-connection/schema.json +26 -0
- package/src/agentcore-gateway/schema.json +65 -0
- package/src/license/schema.json +6 -0
- package/src/preset/schema.json +5 -0
- package/src/py/agent/gateway-connection/schema.json +26 -0
- package/src/py/dynamodb/agent-connection/schema.json +22 -0
- package/src/py/dynamodb/fast-api-connection/schema.json +18 -0
- package/src/py/dynamodb/mcp-server-connection/schema.json +22 -0
- package/src/py/dynamodb/schema.json +70 -0
- package/src/ts/agent/gateway-connection/schema.json +26 -0
- package/src/ts/dynamodb/agent-connection/schema.json +22 -0
- package/src/ts/dynamodb/mcp-server-connection/schema.json +22 -0
- package/src/ts/dynamodb/schema.json +70 -0
- package/src/ts/dynamodb/smithy-connection/schema.json +18 -0
- package/src/ts/dynamodb/trpc-connection/schema.json +18 -0
|
@@ -47,9 +47,12 @@ The generator creates a shared `agent-connection` package and modifies your agen
|
|
|
47
47
|
- packages/common/agent-connection
|
|
48
48
|
- src
|
|
49
49
|
- app
|
|
50
|
-
- \<target-agent-name>-client.ts High-level client for the connected A2A agent
|
|
50
|
+
- \<target-agent-name>-client-strands.ts High-level Strands client for the connected A2A agent
|
|
51
51
|
- core
|
|
52
|
-
- agentcore-
|
|
52
|
+
- agentcore-endpoints.ts Framework-agnostic ARN/URL resolution
|
|
53
|
+
- agentcore-fetch.ts Framework-agnostic SigV4 / JWT / session-forwarding fetch
|
|
54
|
+
- agentcore-a2a-client-config.ts Framework-agnostic A2A client config (signed `clientFactory`)
|
|
55
|
+
- agentcore-a2a-client-strands.ts Strands A2A client wrapping the config
|
|
53
56
|
- index.ts Exports all clients
|
|
54
57
|
- project.json
|
|
55
58
|
- tsconfig.json
|
|
@@ -67,11 +70,11 @@ The generator transforms your agent's `agent.ts` to wrap the remote A2A agent as
|
|
|
67
70
|
|
|
68
71
|
```ts title="packages/example/src/my-agent/agent.ts" {2,5-11,14}
|
|
69
72
|
import { Agent, tool } from '@strands-agents/sdk';
|
|
70
|
-
import {
|
|
73
|
+
import { RemoteAgentClientStrands } from ':my-scope/agent-connection';
|
|
71
74
|
import { z } from 'zod';
|
|
72
75
|
|
|
73
76
|
export const getAgent = async (sessionId: string) => {
|
|
74
|
-
const remoteAgent = await
|
|
77
|
+
const remoteAgent = await RemoteAgentClientStrands.create(sessionId);
|
|
75
78
|
const remoteAgentTool = tool({
|
|
76
79
|
name: 'askRemoteAgent',
|
|
77
80
|
description: 'Delegate a question to the remote RemoteAgent A2A agent and return its reply.',
|
|
@@ -87,7 +90,7 @@ export const getAgent = async (sessionId: string) => {
|
|
|
87
90
|
|
|
88
91
|
The `sessionId` parameter is plumbed through from the caller, ensuring consistency for [Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html).
|
|
89
92
|
|
|
90
|
-
Under the hood, `
|
|
93
|
+
Under the hood, `RemoteAgentClientStrands.create(sessionId)` returns a Strands `A2AAgent` configured with a SigV4-signing `clientFactory` when deployed to AWS, and a plain `http://localhost:<port>/` endpoint when `SERVE_LOCAL=true`. The signing and endpoint resolution live in the framework-agnostic `agentcore-a2a-client-config.ts`; only the thin `agentcore-a2a-client-strands.ts` depends on Strands.
|
|
91
94
|
|
|
92
95
|
## Infrastructure
|
|
93
96
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript Agent to DynamoDB
|
|
3
|
+
description: Connect a TypeScript Agent to a TypeScript DynamoDB project
|
|
4
|
+
when:
|
|
5
|
+
sourceType: ts#agent
|
|
6
|
+
targetType: ts#dynamodb
|
|
7
|
+
---
|
|
8
|
+
import Link from '@components/link.astro';
|
|
9
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
10
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
11
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
12
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
13
|
+
import Snippet from '@components/snippet.astro';
|
|
14
|
+
|
|
15
|
+
The `connection` generator wires a <Link path="guides/ts-agent">TypeScript Agent</Link> to a <Link path="guides/ts-dynamodb">TypeScript DynamoDB</Link> project, configuring local development so both start together automatically.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
Before using this generator, ensure you have:
|
|
20
|
+
|
|
21
|
+
1. A <Link path="guides/ts-agent">`ts#agent`</Link> project
|
|
22
|
+
2. A <Link path="guides/ts-dynamodb">`ts#dynamodb`</Link> project
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Run the Generator
|
|
27
|
+
|
|
28
|
+
<RunGenerator generator="connection" />
|
|
29
|
+
|
|
30
|
+
Select your Agent project as the source and your DynamoDB project as the target. If the project contains multiple agent components, specify `sourceComponent` to disambiguate.
|
|
31
|
+
|
|
32
|
+
### Options
|
|
33
|
+
|
|
34
|
+
<GeneratorParameters generator="connection" />
|
|
35
|
+
|
|
36
|
+
## Generator Output
|
|
37
|
+
|
|
38
|
+
The generator updates the agent's `<agent-name>-serve-local` target in `project.json` to depend on the DynamoDB project's `serve-local` target. No source files are modified.
|
|
39
|
+
|
|
40
|
+
## Using DynamoDB in Agents
|
|
41
|
+
|
|
42
|
+
Import entity factories from the DynamoDB package and use them inside your agent definition:
|
|
43
|
+
|
|
44
|
+
```ts title="packages/my-service/src/my-agent/agent.ts"
|
|
45
|
+
import { createExampleEntity } from ':my-scope/my-table';
|
|
46
|
+
|
|
47
|
+
export const getAgent = async () => {
|
|
48
|
+
// ...
|
|
49
|
+
return new Agent({
|
|
50
|
+
tools: [
|
|
51
|
+
tool({
|
|
52
|
+
name: 'list_examples',
|
|
53
|
+
description: 'List all example items',
|
|
54
|
+
func: async () => {
|
|
55
|
+
const entity = await createExampleEntity();
|
|
56
|
+
const result = await entity.scan.go();
|
|
57
|
+
return result.data;
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Infrastructure
|
|
66
|
+
|
|
67
|
+
To allow the agent's Lambda function to access the DynamoDB table, grant the necessary permissions in your infrastructure.
|
|
68
|
+
|
|
69
|
+
<Infrastructure>
|
|
70
|
+
<Fragment slot="cdk">
|
|
71
|
+
|
|
72
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
73
|
+
import { MyTable } from ':my-scope/common-constructs';
|
|
74
|
+
|
|
75
|
+
const table = new MyTable(this, 'Table');
|
|
76
|
+
const myAgent = new MyAgent(this, 'MyAgent');
|
|
77
|
+
|
|
78
|
+
table.grantReadWriteData(myAgent);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`grantReadWriteData` grants both the DynamoDB and KMS permissions to the agent's execution role.
|
|
82
|
+
</Fragment>
|
|
83
|
+
<Fragment slot="terraform">
|
|
84
|
+
|
|
85
|
+
```hcl title="packages/infra/src/main.tf"
|
|
86
|
+
module "my_table" {
|
|
87
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
resource "aws_iam_role_policy" "dynamodb_access" {
|
|
91
|
+
role = module.my_agent.lambda_role_name
|
|
92
|
+
|
|
93
|
+
policy = jsonencode({
|
|
94
|
+
Version = "2012-10-17"
|
|
95
|
+
Statement = [
|
|
96
|
+
{
|
|
97
|
+
Effect = "Allow"
|
|
98
|
+
Action = [
|
|
99
|
+
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
|
|
100
|
+
"dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan",
|
|
101
|
+
"dynamodb:BatchGetItem", "dynamodb:BatchWriteItem",
|
|
102
|
+
]
|
|
103
|
+
Resource = [
|
|
104
|
+
module.my_table.table_arn,
|
|
105
|
+
"${module.my_table.table_arn}/index/*",
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
Effect = "Allow"
|
|
110
|
+
Action = [
|
|
111
|
+
"kms:Encrypt",
|
|
112
|
+
"kms:Decrypt",
|
|
113
|
+
"kms:ReEncrypt*",
|
|
114
|
+
"kms:GenerateDataKey*",
|
|
115
|
+
"kms:DescribeKey"
|
|
116
|
+
]
|
|
117
|
+
Resource = [module.my_table.kms_key_arn]
|
|
118
|
+
},
|
|
119
|
+
]
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
</Fragment>
|
|
124
|
+
</Infrastructure>
|
|
125
|
+
|
|
126
|
+
## Local Development
|
|
127
|
+
|
|
128
|
+
<Snippet name="connection/dynamodb-local-development" />
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript Agent to Gateway
|
|
3
|
+
description: Connect a TypeScript Agent to an AgentCore Gateway
|
|
4
|
+
when:
|
|
5
|
+
sourceType: ts#agent
|
|
6
|
+
targetType: agentcore-gateway
|
|
7
|
+
---
|
|
8
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
9
|
+
import Link from '@components/link.astro';
|
|
10
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
11
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
12
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
13
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
14
|
+
|
|
15
|
+
The `connection` generator can connect your <Link path="guides/ts-agent">TypeScript Agent</Link> to an <Link path="guides/agentcore-gateway">AgentCore Gateway</Link>.
|
|
16
|
+
|
|
17
|
+
The generator wires the agent so it authenticates to the Gateway with IAM SigV4 when deployed, and connects to the local gateway started by the Gateway project when running locally.
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
Before using this generator, ensure you have:
|
|
22
|
+
|
|
23
|
+
1. A TypeScript project with a <Link path="guides/ts-agent">Agent</Link> component (`infra: agentcore`)
|
|
24
|
+
2. A <Link path="guides/agentcore-gateway">`agentcore-gateway`</Link> project
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Run the Generator
|
|
29
|
+
|
|
30
|
+
<RunGenerator generator="connection" />
|
|
31
|
+
|
|
32
|
+
Select the agent project as the source and the Gateway project as the target.
|
|
33
|
+
|
|
34
|
+
### Options
|
|
35
|
+
|
|
36
|
+
<GeneratorParameters generator="connection" />
|
|
37
|
+
|
|
38
|
+
## Generator Output
|
|
39
|
+
|
|
40
|
+
The generator emits shared core client files into your `agent-connection` package, plus a per-Gateway wrapper, and modifies your agent:
|
|
41
|
+
|
|
42
|
+
<FileTree>
|
|
43
|
+
|
|
44
|
+
- packages/common/agent-connection
|
|
45
|
+
- src
|
|
46
|
+
- core/
|
|
47
|
+
- agentcore-endpoints.ts Framework-agnostic ARN/URL resolution
|
|
48
|
+
- agentcore-gateway-mcp-transport.ts Framework-agnostic Gateway MCP transport
|
|
49
|
+
- agentcore-gateway-mcp-client-strands.ts Strands MCP client for the deployed Gateway
|
|
50
|
+
- app/
|
|
51
|
+
- \<gateway-kebab>-client-strands.ts Per-Gateway Strands client wrapper
|
|
52
|
+
- index.ts Re-exports the Gateway client
|
|
53
|
+
|
|
54
|
+
</FileTree>
|
|
55
|
+
|
|
56
|
+
Additionally, the generator:
|
|
57
|
+
|
|
58
|
+
- Modifies your agent's `agent.ts` to import the Gateway client class, call `<Gateway>ClientStrands.create()`, and register the returned client in the `tools` array
|
|
59
|
+
- Wires the agent's `<agent>-serve-local` target to depend on the Gateway's `<gateway>-serve-local` aggregator
|
|
60
|
+
- Installs the required SigV4 / MCP dependencies
|
|
61
|
+
|
|
62
|
+
## Using the connected Gateway
|
|
63
|
+
|
|
64
|
+
The generator transforms your agent's `agent.ts` to use the Gateway client:
|
|
65
|
+
|
|
66
|
+
```ts title="packages/example/src/my-agent/agent.ts" {2,5,8}
|
|
67
|
+
import { Agent } from '@strands-agents/sdk';
|
|
68
|
+
import { MyGatewayClientStrands } from ':my-scope/agent-connection';
|
|
69
|
+
|
|
70
|
+
export const getAgent = async () => {
|
|
71
|
+
const myGateway = await MyGatewayClientStrands.create();
|
|
72
|
+
return new Agent({
|
|
73
|
+
systemPrompt: '...',
|
|
74
|
+
tools: [myGateway],
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
When deployed (`SERVE_LOCAL` unset), the client points at the Gateway's MCP endpoint and authenticates with SigV4. When `SERVE_LOCAL=true`, it points at the local gateway started by the Gateway project's `serve-local` target, so the same `agent.ts` works uniformly in both modes.
|
|
80
|
+
|
|
81
|
+
The session ID is propagated to downstream MCP servers automatically via the `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` header.
|
|
82
|
+
|
|
83
|
+
## Infrastructure
|
|
84
|
+
|
|
85
|
+
After running the generator you must grant the agent permission to invoke the Gateway.
|
|
86
|
+
|
|
87
|
+
<Infrastructure>
|
|
88
|
+
<Fragment slot="cdk">
|
|
89
|
+
```ts title="packages/infra/src/stacks/application-stack.ts" {5}
|
|
90
|
+
const gateway = new MyGateway(this, 'MyGateway');
|
|
91
|
+
const myAgent = new MyAgent(this, 'MyAgent');
|
|
92
|
+
|
|
93
|
+
// Grant the agent permissions to invoke the Gateway
|
|
94
|
+
gateway.grantInvokeAccess(myAgent);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The Gateway URL is automatically registered in the `agentcore.gateways.<ClassName>` namespace of <Link path="guides/runtime-config">Runtime Configuration</Link> by the generated CDK construct, so the agent can discover it at runtime.
|
|
98
|
+
</Fragment>
|
|
99
|
+
<Fragment slot="terraform">
|
|
100
|
+
```hcl title="packages/infra/src/main.tf" {12-24}
|
|
101
|
+
module "my_gateway" {
|
|
102
|
+
source = "../../common/terraform/src/app/gateways/my-gateway"
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module "my_agent" {
|
|
106
|
+
source = "../../common/terraform/src/app/agents/my-agent"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Grant the agent permission to invoke the Gateway
|
|
110
|
+
resource "aws_iam_policy" "agent_invoke_gateway" {
|
|
111
|
+
name = "AgentInvokeGatewayPolicy"
|
|
112
|
+
policy = jsonencode({
|
|
113
|
+
Version = "2012-10-17"
|
|
114
|
+
Statement = [{
|
|
115
|
+
Effect = "Allow"
|
|
116
|
+
Action = "bedrock-agentcore:InvokeGateway"
|
|
117
|
+
Resource = module.my_gateway.gateway_arn
|
|
118
|
+
}]
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
resource "aws_iam_role_policy_attachment" "agent_invoke_gateway" {
|
|
123
|
+
role = module.my_agent.agent_core_runtime_role_arn
|
|
124
|
+
policy_arn = aws_iam_policy.agent_invoke_gateway.arn
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The Gateway URL is automatically registered in the `agentcore.gateways.<ClassName>` namespace of <Link path="guides/runtime-config">Runtime Configuration</Link> by the generated Terraform module, so the agent can discover it at runtime.
|
|
129
|
+
</Fragment>
|
|
130
|
+
</Infrastructure>
|
|
131
|
+
|
|
132
|
+
## Local Development
|
|
133
|
+
|
|
134
|
+
The generator configures the agent's `serve-local` target to:
|
|
135
|
+
|
|
136
|
+
1. Start the connected Gateway's local gateway and every attached MCP server
|
|
137
|
+
2. Set `SERVE_LOCAL=true` so the generated client points at the local gateway instead of the deployed Gateway
|
|
138
|
+
|
|
139
|
+
Run the agent locally with:
|
|
140
|
+
|
|
141
|
+
<NxCommands commands={["<agent-name>-serve-local <project-name>"]} />
|
|
142
|
+
|
|
143
|
+
To run the agent locally **against the deployed Gateway** instead (for example, to exercise Cedar policies), use the agent's `serve` target. Without `SERVE_LOCAL` set, the client resolves the deployed Gateway URL from runtime configuration and SigV4-signs requests with your local AWS credentials:
|
|
144
|
+
|
|
145
|
+
<NxCommands commands={["<agent-name>-serve <project-name>"]} />
|
|
146
|
+
|
|
147
|
+
### Local fidelity
|
|
148
|
+
|
|
149
|
+
The local gateway stands in for the deployed Gateway, so:
|
|
150
|
+
|
|
151
|
+
- **No Cedar policy evaluation.** Every tool is visible to the agent regardless of policies. Use the `serve` target to exercise policies against the deployed Gateway.
|
|
152
|
+
- **Tool-name prefixing is preserved.** Each local MCP server's tools are wrapped to expose names of the form `<target-name>___<tool-name>`, matching what the deployed Gateway emits. This keeps an agent's system prompt and the Cedar action names you reference consistent across local and deployed runs.
|
|
@@ -47,9 +47,12 @@ The generator creates a shared `agent-connection` package and modifies your agen
|
|
|
47
47
|
- packages/common/agent-connection
|
|
48
48
|
- src
|
|
49
49
|
- app
|
|
50
|
-
- \<mcp-server-name>-client.ts High-level client for the connected MCP server
|
|
50
|
+
- \<mcp-server-name>-client-strands.ts High-level Strands client for the connected MCP server
|
|
51
51
|
- core
|
|
52
|
-
- agentcore-
|
|
52
|
+
- agentcore-endpoints.ts Framework-agnostic ARN/URL resolution
|
|
53
|
+
- agentcore-fetch.ts Framework-agnostic SigV4 / JWT / session-forwarding fetch
|
|
54
|
+
- agentcore-mcp-transport.ts Framework-agnostic MCP transport
|
|
55
|
+
- agentcore-mcp-client-strands.ts Strands MCP client wrapping the transport
|
|
53
56
|
- index.ts Exports all clients
|
|
54
57
|
- project.json
|
|
55
58
|
- tsconfig.json
|
|
@@ -67,10 +70,10 @@ The generator transforms your agent's `agent.ts` to use the MCP server's tools:
|
|
|
67
70
|
|
|
68
71
|
```ts title="packages/example/src/my-agent/agent.ts" {2,5,8}
|
|
69
72
|
import { Agent, tool } from '@strands-agents/sdk';
|
|
70
|
-
import {
|
|
73
|
+
import { MyMcpServerClientStrands } from ':my-scope/agent-connection';
|
|
71
74
|
|
|
72
75
|
export const getAgent = async (sessionId: string) => {
|
|
73
|
-
const myMcpServerClient = await
|
|
76
|
+
const myMcpServerClient = await MyMcpServerClientStrands.create(sessionId);
|
|
74
77
|
return new Agent({
|
|
75
78
|
systemPrompt: '...',
|
|
76
79
|
tools: [myMcpServerClient],
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: MCP Server to DynamoDB
|
|
3
|
+
description: Connect a TypeScript MCP Server to a TypeScript DynamoDB project
|
|
4
|
+
when:
|
|
5
|
+
sourceType: ts#mcp-server
|
|
6
|
+
targetType: ts#dynamodb
|
|
7
|
+
---
|
|
8
|
+
import Link from '@components/link.astro';
|
|
9
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
10
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
11
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
12
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
13
|
+
import Snippet from '@components/snippet.astro';
|
|
14
|
+
|
|
15
|
+
The `connection` generator wires a <Link path="guides/ts-mcp-server">TypeScript MCP Server</Link> to a <Link path="guides/ts-dynamodb">TypeScript DynamoDB</Link> project, configuring local development so both start together automatically.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
Before using this generator, ensure you have:
|
|
20
|
+
|
|
21
|
+
1. A <Link path="guides/ts-mcp-server">`ts#mcp-server`</Link> project
|
|
22
|
+
2. A <Link path="guides/ts-dynamodb">`ts#dynamodb`</Link> project
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Run the Generator
|
|
27
|
+
|
|
28
|
+
<RunGenerator generator="connection" />
|
|
29
|
+
|
|
30
|
+
Select your MCP server project as the source and your DynamoDB project as the target. If the project contains multiple MCP server components, specify `sourceComponent` to disambiguate.
|
|
31
|
+
|
|
32
|
+
### Options
|
|
33
|
+
|
|
34
|
+
<GeneratorParameters generator="connection" />
|
|
35
|
+
|
|
36
|
+
## Generator Output
|
|
37
|
+
|
|
38
|
+
The generator updates the MCP server's `<mcp-server-name>-serve-local` target in `project.json` to depend on the DynamoDB project's `serve-local` target. No source files are modified.
|
|
39
|
+
|
|
40
|
+
## Using DynamoDB in Tools
|
|
41
|
+
|
|
42
|
+
Import entity factories from the DynamoDB package and use them inside `createServer`:
|
|
43
|
+
|
|
44
|
+
```ts title="packages/my-service/src/my-mcp/server.ts"
|
|
45
|
+
import { createExampleEntity } from ':my-scope/my-table';
|
|
46
|
+
|
|
47
|
+
export const createServer = async () => {
|
|
48
|
+
const server = new McpServer({ name: 'my-service', version: '1.0.0' });
|
|
49
|
+
|
|
50
|
+
server.tool('list_examples', 'List all example items', {}, async () => {
|
|
51
|
+
const entity = await createExampleEntity();
|
|
52
|
+
const result = await entity.scan.go();
|
|
53
|
+
return {
|
|
54
|
+
content: [{ type: 'text', text: JSON.stringify(result.data) }],
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return server;
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Infrastructure
|
|
63
|
+
|
|
64
|
+
To allow the MCP server to access the DynamoDB table, grant the necessary permissions in your infrastructure.
|
|
65
|
+
|
|
66
|
+
<Infrastructure>
|
|
67
|
+
<Fragment slot="cdk">
|
|
68
|
+
|
|
69
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
70
|
+
import { MyTable } from ':my-scope/common-constructs';
|
|
71
|
+
|
|
72
|
+
const table = new MyTable(this, 'Table');
|
|
73
|
+
const myMcpServer = new MyMcpServer(this, 'MyMcpServer');
|
|
74
|
+
|
|
75
|
+
table.grantReadWriteData(myMcpServer);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`grantReadWriteData` grants both the DynamoDB and KMS permissions to the MCP server's execution role.
|
|
79
|
+
</Fragment>
|
|
80
|
+
<Fragment slot="terraform">
|
|
81
|
+
|
|
82
|
+
```hcl title="packages/infra/src/main.tf"
|
|
83
|
+
module "my_table" {
|
|
84
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
resource "aws_iam_role_policy" "dynamodb_access" {
|
|
88
|
+
role = module.my_mcp_server.lambda_role_name
|
|
89
|
+
|
|
90
|
+
policy = jsonencode({
|
|
91
|
+
Version = "2012-10-17"
|
|
92
|
+
Statement = [
|
|
93
|
+
{
|
|
94
|
+
Effect = "Allow"
|
|
95
|
+
Action = [
|
|
96
|
+
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
|
|
97
|
+
"dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan",
|
|
98
|
+
"dynamodb:BatchGetItem", "dynamodb:BatchWriteItem",
|
|
99
|
+
]
|
|
100
|
+
Resource = [
|
|
101
|
+
module.my_table.table_arn,
|
|
102
|
+
"${module.my_table.table_arn}/index/*",
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
Effect = "Allow"
|
|
107
|
+
Action = [
|
|
108
|
+
"kms:Encrypt",
|
|
109
|
+
"kms:Decrypt",
|
|
110
|
+
"kms:ReEncrypt*",
|
|
111
|
+
"kms:GenerateDataKey*",
|
|
112
|
+
"kms:DescribeKey",
|
|
113
|
+
]
|
|
114
|
+
Resource = [module.my_table.kms_key_arn]
|
|
115
|
+
},
|
|
116
|
+
]
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
</Fragment>
|
|
121
|
+
</Infrastructure>
|
|
122
|
+
|
|
123
|
+
## Local Development
|
|
124
|
+
|
|
125
|
+
<Snippet name="connection/dynamodb-local-development" />
|
|
@@ -119,8 +119,97 @@ The Connection generator supports the following connections:
|
|
|
119
119
|
source="mcp"
|
|
120
120
|
target="aurora"
|
|
121
121
|
/>
|
|
122
|
+
<ConnectionCard
|
|
123
|
+
title="tRPC API to TypeScript DynamoDB"
|
|
124
|
+
description="Connect a tRPC API to a DynamoDB table"
|
|
125
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/trpc-dynamodb`}
|
|
126
|
+
source="trpc"
|
|
127
|
+
target="dynamodb"
|
|
128
|
+
/>
|
|
129
|
+
<ConnectionCard
|
|
130
|
+
title="Smithy API to TypeScript DynamoDB"
|
|
131
|
+
description="Connect a Smithy API to a DynamoDB table"
|
|
132
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/smithy-dynamodb`}
|
|
133
|
+
source="smithy"
|
|
134
|
+
target="dynamodb"
|
|
135
|
+
/>
|
|
136
|
+
<ConnectionCard
|
|
137
|
+
title="TypeScript Agent to TypeScript DynamoDB"
|
|
138
|
+
description="Connect a TypeScript Agent to a DynamoDB table"
|
|
139
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/ts-agent-dynamodb`}
|
|
140
|
+
source="strands"
|
|
141
|
+
sourceBadge="typescript"
|
|
142
|
+
target="dynamodb"
|
|
143
|
+
/>
|
|
144
|
+
<ConnectionCard
|
|
145
|
+
title="MCP Server to TypeScript DynamoDB"
|
|
146
|
+
description="Connect a TypeScript MCP Server to a DynamoDB table"
|
|
147
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/ts-mcp-server-dynamodb`}
|
|
148
|
+
source="mcp"
|
|
149
|
+
target="dynamodb"
|
|
150
|
+
/>
|
|
151
|
+
<ConnectionCard
|
|
152
|
+
title="FastAPI to Python DynamoDB"
|
|
153
|
+
description="Connect a FastAPI to a DynamoDB table"
|
|
154
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/py-fast-api-dynamodb`}
|
|
155
|
+
source="fastapi"
|
|
156
|
+
target="dynamodb"
|
|
157
|
+
targetBadge="python"
|
|
158
|
+
/>
|
|
159
|
+
<ConnectionCard
|
|
160
|
+
title="Python Agent to Python DynamoDB"
|
|
161
|
+
description="Connect a Python Agent to a DynamoDB table"
|
|
162
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/py-agent-dynamodb`}
|
|
163
|
+
source="strands"
|
|
164
|
+
sourceBadge="python"
|
|
165
|
+
target="dynamodb"
|
|
166
|
+
targetBadge="python"
|
|
167
|
+
/>
|
|
168
|
+
<ConnectionCard
|
|
169
|
+
title="Python MCP Server to Python DynamoDB"
|
|
170
|
+
description="Connect a Python MCP Server to a DynamoDB table"
|
|
171
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/py-mcp-server-dynamodb`}
|
|
172
|
+
source="mcp"
|
|
173
|
+
sourceBadge="python"
|
|
174
|
+
target="dynamodb"
|
|
175
|
+
targetBadge="python"
|
|
176
|
+
/>
|
|
177
|
+
<ConnectionCard
|
|
178
|
+
title="AgentCore Gateway to MCP Server"
|
|
179
|
+
description="Aggregate an MCP server behind an AgentCore Gateway"
|
|
180
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/agentcore-gateway-mcp`}
|
|
181
|
+
source="agentcore"
|
|
182
|
+
target="mcp"
|
|
183
|
+
/>
|
|
184
|
+
<ConnectionCard
|
|
185
|
+
title="AgentCore Gateway to AgentCore Gateway"
|
|
186
|
+
description="Aggregate an AgentCore Gateway behind another AgentCore Gateway"
|
|
187
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/agentcore-gateway-gateway`}
|
|
188
|
+
source="agentcore"
|
|
189
|
+
target="agentcore"
|
|
190
|
+
/>
|
|
191
|
+
<ConnectionCard
|
|
192
|
+
title="TypeScript Agent to AgentCore Gateway"
|
|
193
|
+
description="Connect a TypeScript Agent to an AgentCore Gateway"
|
|
194
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/ts-agent-gateway`}
|
|
195
|
+
source="strands"
|
|
196
|
+
sourceBadge="typescript"
|
|
197
|
+
target="agentcore"
|
|
198
|
+
/>
|
|
199
|
+
<ConnectionCard
|
|
200
|
+
title="Python Agent to AgentCore Gateway"
|
|
201
|
+
description="Connect a Python Agent to an AgentCore Gateway"
|
|
202
|
+
href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/py-agent-gateway`}
|
|
203
|
+
source="strands"
|
|
204
|
+
sourceBadge="python"
|
|
205
|
+
target="agentcore"
|
|
206
|
+
/>
|
|
122
207
|
</CardGrid>
|
|
123
208
|
|
|
124
209
|
:::note[Runtime Configuration]
|
|
125
210
|
The connection generator makes use of <Link path="guides/runtime-config">Runtime Configuration</Link> to pass deploy-time values (such as API URLs, Cognito settings, and agent runtime ARNs) between generated projects and components at runtime so they can discover and connect to one another.
|
|
126
211
|
:::
|
|
212
|
+
|
|
213
|
+
:::tip[Local Development]
|
|
214
|
+
Connected projects can be run on your machine with the `serve` and `serve-local` targets. See the <Link path="guides/local-development">Local Development</Link> guide for details.
|
|
215
|
+
:::
|
|
@@ -8,7 +8,7 @@ import NxCommands from '@components/nx-commands.astro';
|
|
|
8
8
|
import Link from '@components/link.astro';
|
|
9
9
|
import Infrastructure from '@components/infrastructure.astro';
|
|
10
10
|
|
|
11
|
-
Several generators (such as <Link path="/guides/ts-agent">`ts#agent`</Link> and <Link path="/guides/py-agent">`py#agent`</Link>) produce a Docker image that is pushed to Amazon ECR and consumed by AWS infrastructure. This guide describes the pattern they follow so that you can apply it to other use cases — for example, running a <Link path="/guides/fastapi"
|
|
11
|
+
Several generators (such as <Link path="/guides/ts-agent">`ts#agent`</Link> and <Link path="/guides/py-agent">`py#agent`</Link>) produce a Docker image that is pushed to Amazon ECR and consumed by AWS infrastructure. This guide describes the pattern they follow so that you can apply it to other use cases — for example, running a <Link path="/guides/fastapi">FastAPI</Link> project on Amazon ECS, or deploying a containerised Express server.
|
|
12
12
|
|
|
13
13
|
:::tip[Docker or Finch]
|
|
14
14
|
The container engine used to build images is chosen at workspace creation time via the `--containerEngine` flag (`docker`, `finch`, or `infer` — the default — which auto-detects what's installed). [Finch](https://runfinch.com/) is an open-source, drop-in alternative to Docker. The selection is recorded in `aws-nx-plugin.config.mts` and applied to every generator that emits container build commands. CDK image asset builds honour the choice via the `CDK_DOCKER` environment variable.
|
|
@@ -318,8 +318,8 @@ Terraform's AWS provider does not have a first-class "build and push a Docker im
|
|
|
318
318
|
|
|
319
319
|
1. The project's `build` target runs `docker build`, producing a local image tagged `my-scope-my-project:latest`.
|
|
320
320
|
2. An `aws_ecr_repository` to hold the image.
|
|
321
|
-
3. A `null_resource` with a `local-exec` provisioner that authenticates to ECR, re-tags the locally-built image, and pushes it.
|
|
322
|
-
4. The downstream resource (e.g. `aws_ecs_task_definition`) references
|
|
321
|
+
3. A `null_resource` with a `local-exec` provisioner that authenticates to ECR, re-tags the locally-built image with its content digest, and pushes it.
|
|
322
|
+
4. The downstream resource (e.g. `aws_ecs_task_definition`) references the image by its immutable, digest-based tag.
|
|
323
323
|
|
|
324
324
|
```d2
|
|
325
325
|
direction: down
|
|
@@ -361,7 +361,7 @@ infra.repo -> ecr
|
|
|
361
361
|
```hcl
|
|
362
362
|
resource "aws_ecr_repository" "repo" {
|
|
363
363
|
name = "my-project-repository"
|
|
364
|
-
image_tag_mutability = "
|
|
364
|
+
image_tag_mutability = "IMMUTABLE"
|
|
365
365
|
force_delete = true
|
|
366
366
|
}
|
|
367
367
|
|
|
@@ -370,24 +370,30 @@ data "external" "docker_digest" {
|
|
|
370
370
|
program = ["sh", "-c", "echo '{\"digest\":\"'$(docker inspect my-scope-my-project:latest --format '{{.Id}}')'\"}'"]
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
+
locals {
|
|
374
|
+
# Content-based, immutable image tag derived from the local image digest
|
|
375
|
+
image_tag = replace(data.external.docker_digest.result.digest, "sha256:", "")
|
|
376
|
+
}
|
|
377
|
+
|
|
373
378
|
resource "null_resource" "docker_publish" {
|
|
374
379
|
triggers = {
|
|
375
380
|
docker_digest = data.external.docker_digest.result.digest
|
|
376
381
|
repository_url = aws_ecr_repository.repo.repository_url
|
|
382
|
+
image_tag = local.image_tag
|
|
377
383
|
}
|
|
378
384
|
|
|
379
385
|
provisioner "local-exec" {
|
|
380
386
|
command = <<-EOT
|
|
381
387
|
aws ecr get-login-password --region ${data.aws_region.current.id} \
|
|
382
388
|
| docker login --username AWS --password-stdin ${self.triggers.repository_url}
|
|
383
|
-
docker tag my-scope-my-project:latest ${self.triggers.repository_url}
|
|
384
|
-
docker push ${self.triggers.repository_url}
|
|
389
|
+
docker tag my-scope-my-project:latest ${self.triggers.repository_url}:${self.triggers.image_tag}
|
|
390
|
+
docker push ${self.triggers.repository_url}:${self.triggers.image_tag}
|
|
385
391
|
EOT
|
|
386
392
|
}
|
|
387
393
|
}
|
|
388
394
|
```
|
|
389
395
|
|
|
390
|
-
The `data.external.docker_digest` block ensures the `null_resource` re-runs whenever the local image hash changes, triggering a new push on every meaningful code change.
|
|
396
|
+
The `data.external.docker_digest` block ensures the `null_resource` re-runs whenever the local image hash changes, triggering a new push on every meaningful code change. The image is pushed under an immutable, content-based tag derived from its digest, so the ECR repository can use `IMMUTABLE` tag mutability and reject any attempt to overwrite an existing tag.
|
|
391
397
|
|
|
392
398
|
:::note[Running bundle before apply]
|
|
393
399
|
`nx apply <project>` requires the image tag `my-scope-my-project:latest` to already exist locally. Run `nx build my-project` (or `nx docker my-project`) before `nx apply <project>`.
|