@aws/nx-plugin-mcp 1.0.0-rc.7 → 1.0.0-rc.71
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 +12317 -10933
- package/docs/get_started/building-with-ai.mdx +116 -0
- package/docs/get_started/concepts.mdx +67 -0
- package/docs/get_started/existing-project.mdx +180 -0
- package/docs/get_started/graph-builder.mdx +39 -0
- package/docs/get_started/quick-start.mdx +277 -0
- package/docs/get_started/tutorials/contribute-generator.mdx +408 -0
- package/docs/get_started/tutorials/dungeon-game/1.mdx +1301 -0
- package/docs/get_started/tutorials/dungeon-game/2.mdx +237 -0
- package/docs/get_started/tutorials/dungeon-game/3.mdx +76 -0
- package/docs/get_started/tutorials/dungeon-game/4.mdx +164 -0
- package/docs/get_started/tutorials/dungeon-game/overview.mdx +145 -0
- package/docs/get_started/tutorials/dungeon-game/wrap-up.mdx +41 -0
- package/docs/get_started/tutorials/existing-project.mdx +4 -0
- package/docs/get_started/upgrading.mdx +147 -0
- package/docs/guides/agentcore-gateway.mdx +490 -0
- package/docs/guides/agentcore-harness.mdx +275 -0
- package/docs/guides/astro-docs.mdx +8 -0
- package/docs/guides/connection/agentcore-gateway-agent.mdx +222 -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 +48 -16
- package/docs/guides/connection/py-agent-dynamodb.mdx +116 -0
- package/docs/guides/connection/py-agent-gateway.mdx +178 -0
- package/docs/guides/connection/py-agent-mcp.mdx +43 -14
- package/docs/guides/connection/py-agent-rdb.mdx +178 -0
- package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
- package/docs/guides/connection/py-fast-api-rdb.mdx +184 -0
- package/docs/guides/connection/py-mcp-server-dynamodb.mdx +116 -0
- package/docs/guides/connection/py-mcp-server-rdb.mdx +187 -0
- package/docs/guides/connection/react-agentcore-gateway.mdx +112 -0
- package/docs/guides/connection/react-agui.mdx +13 -13
- package/docs/guides/connection/react-fastapi.mdx +38 -2
- package/docs/guides/connection/react-py-agent.mdx +9 -15
- package/docs/guides/connection/react-smithy.mdx +3 -3
- package/docs/guides/connection/react-trpc.mdx +1 -1
- package/docs/guides/connection/react-ts-agent.mdx +8 -8
- package/docs/guides/connection/smithy-dynamodb.mdx +5 -5
- package/docs/guides/connection/smithy-rdb.mdx +9 -9
- package/docs/guides/connection/trpc-dynamodb.mdx +5 -5
- package/docs/guides/connection/trpc-rdb.mdx +6 -6
- package/docs/guides/connection/ts-agent-a2a.mdx +14 -11
- package/docs/guides/connection/ts-agent-dynamodb.mdx +5 -5
- package/docs/guides/connection/ts-agent-gateway.mdx +143 -0
- package/docs/guides/connection/ts-agent-mcp.mdx +12 -9
- package/docs/guides/connection/ts-agent-rdb.mdx +70 -25
- package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +5 -5
- package/docs/guides/connection/ts-mcp-server-rdb.mdx +68 -18
- package/docs/guides/connection.mdx +122 -5
- package/docs/guides/docker-bundling.mdx +69 -12
- package/docs/guides/fastapi.mdx +249 -9
- package/docs/guides/local-development.mdx +87 -0
- package/docs/guides/nx-generator.mdx +4 -3
- package/docs/guides/nx-migration.mdx +165 -0
- package/docs/guides/py-agent.mdx +264 -49
- package/docs/guides/py-dynamodb.mdx +476 -0
- package/docs/guides/py-mcp-server.mdx +61 -2
- package/docs/guides/py-rdb.mdx +265 -0
- package/docs/guides/python-lambda-function.mdx +1 -1
- package/docs/guides/react-website-auth.mdx +65 -4
- package/docs/guides/react-website.mdx +149 -30
- package/docs/guides/runtime-config.mdx +1 -1
- package/docs/guides/security.mdx +75 -0
- package/docs/guides/smithy-project.mdx +167 -0
- package/docs/guides/terraform-project.mdx +2 -2
- package/docs/guides/trpc.mdx +53 -16
- package/docs/guides/ts-agent.mdx +183 -10
- package/docs/guides/ts-dcr-proxy.mdx +569 -0
- package/docs/guides/ts-dynamodb.mdx +66 -242
- package/docs/guides/ts-lambda-function.mdx +1 -1
- package/docs/guides/ts-mcp-server.mdx +109 -29
- package/docs/guides/ts-nx-plugin.mdx +3 -3
- package/docs/guides/ts-rdb.mdx +113 -467
- package/docs/guides/ts-smithy-api.mdx +258 -18
- package/docs/guides/typescript-infrastructure.mdx +46 -24
- package/docs/guides/typescript-project.mdx +134 -27
- package/docs/guides/workspace.mdx +10 -3
- package/docs/snippets/agent/architecture.mdx +1 -1
- package/docs/snippets/agent/bedrock-deployment.mdx +9 -5
- package/docs/snippets/agent/runtime-arn.mdx +23 -2
- package/docs/snippets/agent/securing-your-agent.mdx +39 -0
- package/docs/snippets/api/access-logging.mdx +33 -0
- package/docs/snippets/api/cors-configuration-cdk-note.mdx +1 -1
- package/docs/snippets/api/cors-configuration-terraform-note.mdx +1 -1
- package/docs/snippets/api/type-safe-api-integrations.mdx +33 -2
- package/docs/snippets/api/waf-configuration.mdx +3 -3
- package/docs/snippets/connection/a2a-infrastructure.mdx +1 -1
- package/docs/snippets/connection/dynamodb-local-development.mdx +2 -2
- package/docs/snippets/connection/lambda-dynamodb-access.mdx +1 -1
- package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
- package/docs/snippets/connection/py-lambda-rdb-ssl-requirements.mdx +7 -0
- package/docs/snippets/connection/rdb-api-infrastructure.mdx +51 -19
- package/docs/snippets/dynamodb/deploying-table.mdx +166 -0
- package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
- package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
- package/docs/snippets/dynamodb/local-dev-start.mdx +13 -0
- package/docs/snippets/dynamodb/local-dev-windows.mdx +15 -0
- package/docs/snippets/lambda-function/deploying-your-function.mdx +3 -3
- package/docs/snippets/mcp/architecture.mdx +1 -1
- package/docs/snippets/mcp/bedrock-deployment.mdx +9 -5
- package/docs/snippets/mcp/config.mdx +3 -2
- package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +7 -5
- package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +29 -10
- package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +4 -4
- package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +5 -111
- package/docs/snippets/prerequisites.mdx +1 -4
- package/docs/snippets/rdb/architecture.mdx +38 -0
- package/docs/snippets/rdb/cluster-instances.mdx +31 -0
- package/docs/snippets/rdb/deletion-protection.mdx +34 -0
- package/docs/snippets/rdb/deploying.mdx +187 -0
- package/docs/snippets/rdb/encryption-key-rotation.mdx +30 -0
- package/docs/snippets/rdb/engine-version.mdx +63 -0
- package/docs/snippets/rdb/infrastructure.mdx +35 -0
- package/docs/snippets/rdb/logging-mysql.mdx +5 -0
- package/docs/snippets/rdb/logging-postgres.mdx +5 -0
- package/docs/snippets/rdb/performance-insights.mdx +34 -0
- package/docs/snippets/rdb/rds-proxy.mdx +50 -0
- package/docs/snippets/rdb/removal-policy.mdx +57 -0
- package/docs/snippets/rdb/serverless-capacity.mdx +32 -0
- package/docs/snippets/recommended-prerequisites.mdx +10 -0
- package/docs/snippets/required-prerequisites.mdx +1 -4
- package/docs/snippets/runtime-config-app-id-note.mdx +8 -0
- package/docs/snippets/shared-constructs.mdx +1 -1
- package/docs/snippets/trivy-image-scan.mdx +37 -0
- package/generators.json +152 -10
- package/package.json +1 -1
- package/src/agentcore-gateway/agent-connection/schema.json +31 -0
- package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
- package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
- package/src/agentcore-gateway/react-connection/schema.json +31 -0
- package/src/agentcore-gateway/schema.json +72 -0
- package/src/agentcore-harness/schema.json +53 -0
- package/src/connection/schema.json +5 -0
- package/src/infra/app/schema.json +5 -0
- package/src/init/schema.json +35 -0
- package/src/internal/test-matrix/schema.json +21 -0
- package/src/license/schema.json +5 -0
- package/src/preset/schema.json +16 -5
- package/src/py/agent/a2a-connection/schema.json +5 -0
- package/src/py/agent/gateway-connection/schema.json +31 -0
- package/src/py/agent/mcp-connection/schema.json +5 -0
- package/src/py/agent/react-connection/schema.json +5 -0
- package/src/py/agent/schema.json +15 -1
- package/src/py/api/schema.json +5 -0
- package/src/py/dynamodb/agent-connection/schema.json +27 -0
- package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
- package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
- package/src/py/dynamodb/schema.json +76 -0
- package/src/py/fast-api/react/schema.json +5 -0
- package/src/py/fast-api/schema.json +6 -0
- package/src/py/lambda-function/schema.json +5 -0
- package/src/py/mcp-server/schema.json +6 -0
- package/src/py/project/schema.json +5 -0
- package/src/py/rdb/agent-connection/schema.json +27 -0
- package/src/py/rdb/fast-api-connection/schema.json +23 -0
- package/src/py/rdb/mcp-server-connection/schema.json +27 -0
- package/src/py/rdb/schema.json +78 -0
- package/src/smithy/project/schema.json +28 -1
- package/src/smithy/react-connection/schema.json +5 -0
- package/src/smithy/ts/api/schema.json +6 -0
- package/src/terraform/project/schema.json +5 -0
- package/src/trpc/backend/schema.json +6 -0
- package/src/trpc/react/schema.json +5 -0
- package/src/ts/agent/a2a-connection/schema.json +5 -0
- package/src/ts/agent/gateway-connection/schema.json +31 -0
- package/src/ts/agent/mcp-connection/schema.json +5 -0
- package/src/ts/agent/react-connection/schema.json +5 -0
- package/src/ts/agent/schema.json +14 -0
- package/src/ts/api/schema.json +5 -0
- package/src/ts/astro-docs/schema.json +3 -3
- package/src/ts/dcr-proxy/schema.json +44 -0
- package/src/ts/docs/schema.json +3 -3
- package/src/ts/dynamodb/agent-connection/schema.json +5 -0
- package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
- package/src/ts/dynamodb/schema.json +26 -2
- package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
- package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
- package/src/ts/lambda-function/schema.json +5 -0
- package/src/ts/lib/schema.json +5 -0
- package/src/ts/mcp-server/schema.json +6 -0
- package/src/ts/nx-generator/schema.json +5 -0
- package/src/ts/nx-migration/schema.json +63 -0
- package/src/ts/nx-plugin/schema.json +5 -0
- package/src/ts/rdb/agent-connection/schema.json +5 -0
- package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
- package/src/ts/rdb/schema.json +7 -1
- package/src/ts/rdb/smithy-connection/schema.json +5 -0
- package/src/ts/rdb/trpc-connection/schema.json +5 -0
- package/src/ts/react-website/app/schema.json +12 -6
- package/src/ts/react-website/cognito-auth/schema.json +5 -0
- package/src/ts/react-website/runtime-config/schema.json +5 -0
- package/src/ts/website/app/schema.json +11 -6
- package/src/ts/website/auth/schema.json +5 -0
- /package/docs/snippets/connection/{lambda-rdb-ssl-requirements.mdx → ts-lambda-rdb-ssl-requirements.mdx} +0 -0
- /package/docs/snippets/connection/{mcp-server-rdb-ssl-requirements.mdx → ts-mcp-server-rdb-ssl-requirements.mdx} +0 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: AgentCore Gateway to MCP Server
|
|
3
|
+
description: Connect an AgentCore Gateway to an MCP server
|
|
4
|
+
when:
|
|
5
|
+
sourceType: agentcore-gateway
|
|
6
|
+
targetType:
|
|
7
|
+
- ts#mcp-server
|
|
8
|
+
- py#mcp-server
|
|
9
|
+
---
|
|
10
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
11
|
+
import Link from '@components/link.astro';
|
|
12
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
13
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
14
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
15
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
16
|
+
|
|
17
|
+
The `connection` generator can register an MCP server (either <Link path="guides/ts-mcp-server">TypeScript</Link> or <Link path="guides/py-mcp-server">Python</Link>) as a target of an <Link path="guides/agentcore-gateway">AgentCore Gateway</Link>.
|
|
18
|
+
|
|
19
|
+
Once connected, the Gateway aggregates the MCP server's tools into its single MCP endpoint, evaluates calls against its Cedar policy engine, and signs outbound traffic to the MCP server with IAM SigV4.
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
Before using this generator, ensure you have:
|
|
24
|
+
|
|
25
|
+
1. A <Link path="guides/agentcore-gateway">`agentcore-gateway`</Link> project
|
|
26
|
+
2. An MCP server component (<Link path="guides/ts-mcp-server">`ts#mcp-server`</Link> or <Link path="guides/py-mcp-server">`py#mcp-server`</Link>) created with `infra: agentcore` and `auth: iam`
|
|
27
|
+
|
|
28
|
+
The Gateway must have `protocol: mcp` and the MCP server must have `auth: iam` — the generator validates both. Non-IAM MCP servers cannot be attached because the Gateway signs outbound traffic with SigV4.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Run the Generator
|
|
33
|
+
|
|
34
|
+
<RunGenerator generator="connection" />
|
|
35
|
+
|
|
36
|
+
Select the Gateway project as the source and the MCP server project as the target. If the MCP server project contains multiple components, specify `targetComponent` to disambiguate.
|
|
37
|
+
|
|
38
|
+
### Options
|
|
39
|
+
|
|
40
|
+
<GeneratorParameters generator="connection" />
|
|
41
|
+
|
|
42
|
+
## Generator Output
|
|
43
|
+
|
|
44
|
+
The generator wires existing projects together rather than emitting new source files. The following files are modified:
|
|
45
|
+
|
|
46
|
+
<FileTree>
|
|
47
|
+
|
|
48
|
+
- packages/\<gateway>
|
|
49
|
+
- project.json the Gateway's `dev` target gains a dependency on the MCP server's `<mcp>-dev`
|
|
50
|
+
- local-dev.ts `ATTACHED_MCP_SERVERS` updated so the local gateway aggregates the MCP server
|
|
51
|
+
|
|
52
|
+
</FileTree>
|
|
53
|
+
|
|
54
|
+
The Gateway project's `dev` target gains a dependency on the MCP server's `<mcp>-dev` target, so running the Gateway locally also starts the MCP server. The MCP server is also registered in the Gateway project's `local-dev.ts` so the local gateway aggregates its tools.
|
|
55
|
+
|
|
56
|
+
## Adding the MCP server target to your stack
|
|
57
|
+
|
|
58
|
+
The generator **cannot** automatically wire the MCP server target into your infrastructure because it doesn't know which stack or module instantiates the Gateway. Add a single call to `gateway.addMcpServer(server)` yourself.
|
|
59
|
+
|
|
60
|
+
<Infrastructure>
|
|
61
|
+
<Fragment slot="cdk">
|
|
62
|
+
In the stack where you instantiate the Gateway, register the MCP server as a target:
|
|
63
|
+
|
|
64
|
+
```ts title="packages/infra/src/stacks/application-stack.ts" {4-7}
|
|
65
|
+
const myMcpServer = new MyMcpServer(this, 'MyMcpServer');
|
|
66
|
+
const myGateway = new MyGateway(this, 'MyGateway');
|
|
67
|
+
|
|
68
|
+
// Register the MCP server as a target of the Gateway. The target name
|
|
69
|
+
// defaults to the MCP server's `mcpServerName` (its class name in
|
|
70
|
+
// kebab-case, e.g. `MyMcpServer` -> `my-mcp-server`).
|
|
71
|
+
myGateway.addMcpServer(myMcpServer);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The Gateway target name (the MCP server's `mcpServerName` by default) is used as the prefix for Cedar action names — the action format is ``AgentCore::Action::"<targetName>___<toolName>"``. See the <Link path="guides/agentcore-gateway">Writing Policies section</Link>. Keep the target name short and stable; changing it later invalidates any Cedar policies that reference the old name.
|
|
75
|
+
|
|
76
|
+
To override the default target name, pass `gatewayTargetName`:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
myGateway.addMcpServer(myMcpServer, { gatewayTargetName: 'my-mcp' });
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The construct configures the target with `iamCredentialProvider.service = 'bedrock-agentcore'` so the Gateway signs outbound calls using its own execution role.
|
|
83
|
+
</Fragment>
|
|
84
|
+
<Fragment slot="terraform">
|
|
85
|
+
In the Terraform file where you instantiate the Gateway, wire the MCP server target in:
|
|
86
|
+
|
|
87
|
+
```hcl title="packages/infra/src/main.tf" {7,10-28}
|
|
88
|
+
module "my_mcp_server" {
|
|
89
|
+
source = "../../common/terraform/src/app/mcp-servers/my-mcp-server"
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module "my_gateway" {
|
|
93
|
+
source = "../../common/terraform/src/app/gateways/my-gateway"
|
|
94
|
+
policy_dependencies = [aws_bedrockagentcore_gateway_target.my_mcp_server.target_id]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Register the MCP server as a target of the Gateway
|
|
98
|
+
resource "aws_bedrockagentcore_gateway_target" "my_mcp_server" {
|
|
99
|
+
gateway_identifier = module.my_gateway.gateway_id
|
|
100
|
+
name = "my-mcp-server"
|
|
101
|
+
|
|
102
|
+
target_configuration {
|
|
103
|
+
mcp {
|
|
104
|
+
mcp_server {
|
|
105
|
+
endpoint = module.my_mcp_server.invocation_url
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
credential_provider_configuration {
|
|
111
|
+
gateway_iam_role {
|
|
112
|
+
service = "bedrock-agentcore"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The target `name` (`my-mcp-server` above) is used as the prefix for Cedar action names — see the <Link path="guides/agentcore-gateway">Writing Policies section</Link>. `policy_dependencies` ensures Cedar policies referencing this target's actions are created after the target has registered them.
|
|
119
|
+
</Fragment>
|
|
120
|
+
</Infrastructure>
|
|
121
|
+
|
|
122
|
+
## Local Development
|
|
123
|
+
|
|
124
|
+
Running the Gateway locally with:
|
|
125
|
+
|
|
126
|
+
<NxCommands commands={["dev <gateway-name>"]} />
|
|
127
|
+
|
|
128
|
+
starts a local gateway plus every attached MCP server on its assigned local port. The local gateway exposes a single MCP endpoint that aggregates the attached servers' tools. Agents connected to the Gateway via the <Link path="guides/connection/ts-agent-gateway">TypeScript</Link> or <Link path="guides/connection/py-agent-gateway">Python</Link> gateway-connection generators point at it when running with `LOCAL_DEV=true`.
|
|
129
|
+
|
|
130
|
+
:::caution[Local fidelity]
|
|
131
|
+
Local development uses a **local stand-in gateway** — a lightweight MCP aggregator started by the Gateway project, not the AgentCore Gateway service. As a consequence, **Cedar policies are not evaluated locally**. Every agent sees every tool on every attached MCP server. To exercise Cedar policies, run the agent's `serve` target instead (see the <Link path="guides/connection/ts-agent-gateway">TypeScript</Link> / <Link path="guides/connection/py-agent-gateway">Python</Link> agent-connection guides) so the locally-running agent calls the deployed Gateway.
|
|
132
|
+
|
|
133
|
+
Tool names are still prefixed locally as `<target-name>___<tool-name>` to match the deployed Gateway's namespacing, so an agent's system prompt and the Cedar action names you reference remain consistent across local and deployed runs.
|
|
134
|
+
:::
|
|
@@ -7,7 +7,7 @@ when:
|
|
|
7
7
|
- ts#agent
|
|
8
8
|
- py#agent
|
|
9
9
|
---
|
|
10
|
-
import { FileTree } from '@astrojs/starlight/components';
|
|
10
|
+
import { FileTree, Tabs, TabItem } from '@astrojs/starlight/components';
|
|
11
11
|
import Link from '@components/link.astro';
|
|
12
12
|
import RunGenerator from '@components/run-generator.astro';
|
|
13
13
|
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
@@ -22,8 +22,8 @@ The generator sets up all the necessary wiring so your agent can discover and in
|
|
|
22
22
|
|
|
23
23
|
Before using this generator, ensure you have:
|
|
24
24
|
|
|
25
|
-
1. A Python project with a <Link path="guides/py-agent">
|
|
26
|
-
2. A project with an Agent component generated with `--protocol=
|
|
25
|
+
1. A Python project with a <Link path="guides/py-agent">Python Agent</Link> component (Strands or LangChain)
|
|
26
|
+
2. A project with an Agent component generated with `--protocol=a2a` and `--auth=iam` (either <Link path="guides/ts-agent">`ts#agent`</Link> or <Link path="guides/py-agent">`py#agent`</Link>)
|
|
27
27
|
3. Both components created with `infra: agentcore`
|
|
28
28
|
|
|
29
29
|
## Usage
|
|
@@ -48,30 +48,37 @@ The generator creates a shared `agent_connection` Python project at `packages/co
|
|
|
48
48
|
- \<scope>\_agent\_connection
|
|
49
49
|
- \_\_init\_\_.py Re-exports per-connection clients
|
|
50
50
|
- core
|
|
51
|
-
- agentcore\
|
|
51
|
+
- agentcore\_endpoints.py Framework-agnostic ARN/URL resolution
|
|
52
|
+
- agentcore\_a2a\_client\_config.py Framework-agnostic A2A client config (signed `ClientConfig`)
|
|
53
|
+
- agentcore\_a2a\_client\_\<framework>.py A2A client wrapping the config for your agent's framework
|
|
54
|
+
- auth/ Framework-agnostic SigV4 / session-forwarding `httpx.Auth`
|
|
52
55
|
- app
|
|
53
|
-
- \<target\_agent\_name>\_client
|
|
56
|
+
- \<target\_agent\_name>\_client\_\<framework>.py Per-connection A2A client for each A2A agent
|
|
54
57
|
|
|
55
58
|
</FileTree>
|
|
56
59
|
|
|
60
|
+
The client suffix matches your agent's framework (`_strands` or `_langchain`). Both wrap the same framework-agnostic signed `ClientConfig`: the Strands client wraps a Strands `A2AAgent`, while the LangChain client drives the [a2a SDK](https://pypi.org/project/a2a-sdk/) directly.
|
|
61
|
+
|
|
57
62
|
Additionally, the generator:
|
|
58
63
|
- Transforms your agent's `agent.py` to register the remote A2A agent as a tool using `@tool`
|
|
59
64
|
- Adds the `agent_connection` project as a workspace dependency of your agent project
|
|
60
|
-
- Updates the agent's `
|
|
65
|
+
- Updates the agent's `dev` target to depend on the target agent's `dev` target
|
|
61
66
|
|
|
62
67
|
## Using the Connected A2A Agent
|
|
63
68
|
|
|
64
|
-
The generator transforms your agent's `agent.py` to wrap the remote A2A agent as a tool:
|
|
69
|
+
The generator transforms your agent's `agent.py` to wrap the remote A2A agent as a tool. The remote agent is registered with a `@tool`-decorated delegate — the decorator's import and the agent constructor differ by framework:
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+
<Tabs syncKey="agent-framework">
|
|
72
|
+
<TabItem label="Strands" _filter={{ framework: 'strands' }}>
|
|
73
|
+
```python title="packages/my-project/my_module/agent/agent.py" {4,8-13,15}
|
|
67
74
|
from contextlib import contextmanager
|
|
68
75
|
from strands import Agent, tool
|
|
69
76
|
|
|
70
|
-
from my_scope_agent_connection import
|
|
77
|
+
from my_scope_agent_connection import RemoteAgentClientStrands
|
|
71
78
|
|
|
72
79
|
@contextmanager
|
|
73
|
-
def get_agent(
|
|
74
|
-
remote_agent =
|
|
80
|
+
def get_agent():
|
|
81
|
+
remote_agent = RemoteAgentClientStrands.create()
|
|
75
82
|
|
|
76
83
|
@tool
|
|
77
84
|
def ask_remote_agent(prompt: str) -> str:
|
|
@@ -83,10 +90,35 @@ def get_agent(session_id: str):
|
|
|
83
90
|
tools=[ask_remote_agent],
|
|
84
91
|
)
|
|
85
92
|
```
|
|
93
|
+
</TabItem>
|
|
94
|
+
<TabItem label="LangChain" _filter={{ framework: 'langchain' }}>
|
|
95
|
+
```python title="packages/my-project/my_module/agent/agent.py" {5,8-13,15}
|
|
96
|
+
from langchain.agents import create_agent
|
|
97
|
+
from langchain_aws import ChatBedrockConverse
|
|
98
|
+
from langchain_core.tools import tool
|
|
99
|
+
|
|
100
|
+
from my_scope_agent_connection import RemoteAgentClientLangChain
|
|
101
|
+
|
|
102
|
+
def get_agent():
|
|
103
|
+
remote_agent = RemoteAgentClientLangChain.create()
|
|
104
|
+
|
|
105
|
+
@tool
|
|
106
|
+
def ask_remote_agent(prompt: str) -> str:
|
|
107
|
+
"""Delegate a question to the remote RemoteAgent A2A agent and return its reply."""
|
|
108
|
+
return str(remote_agent(prompt))
|
|
109
|
+
|
|
110
|
+
return create_agent(
|
|
111
|
+
model=ChatBedrockConverse(model=MODEL_ID, region_name=REGION),
|
|
112
|
+
system_prompt="...",
|
|
113
|
+
tools=[ask_remote_agent],
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
</TabItem>
|
|
117
|
+
</Tabs>
|
|
86
118
|
|
|
87
|
-
|
|
119
|
+
Both clients are directly callable, returning the remote agent's reply, and wrap an `httpx.AsyncClient` that signs requests with SigV4 when deployed to AWS and uses a plain `http://localhost:<port>/` endpoint when `LOCAL_DEV=true`. The Strands client wraps a Strands `A2AAgent`; the LangChain client drives the a2a SDK directly.
|
|
88
120
|
|
|
89
|
-
|
|
121
|
+
The AgentCore session ID is propagated to the remote agent automatically via the `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` header, regardless of framework: the agent server binds the inbound request's session into an async context, and the connection client's signed `httpx.Auth` stamps it on every outbound call — ensuring consistency for [Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html).
|
|
90
122
|
|
|
91
123
|
## Infrastructure
|
|
92
124
|
|
|
@@ -94,12 +126,12 @@ Under the hood, `RemoteAgentClient.create(session_id=...)` returns a Strands `A2
|
|
|
94
126
|
|
|
95
127
|
## Local Development
|
|
96
128
|
|
|
97
|
-
The generator configures the host agent's `
|
|
129
|
+
The generator configures the host agent's `dev` target to:
|
|
98
130
|
1. Start the connected A2A agent(s) automatically
|
|
99
|
-
2. Set `
|
|
131
|
+
2. Set `LOCAL_DEV=true` so the generated client connects directly to `http://localhost:<port>/` instead of AgentCore
|
|
100
132
|
|
|
101
133
|
Run the agent locally with:
|
|
102
134
|
|
|
103
|
-
<NxCommands commands={["<agent-name>-
|
|
135
|
+
<NxCommands commands={["<agent-name>-dev <project-name>"]} />
|
|
104
136
|
|
|
105
137
|
This will start both the host agent and all connected A2A agents, with the host agent calling the remote agents over plain HTTP on their assigned local ports.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Python Agent to DynamoDB
|
|
3
|
+
description: Connect a Python Agent to a Python DynamoDB project
|
|
4
|
+
when:
|
|
5
|
+
sourceType: py#agent
|
|
6
|
+
targetType: py#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 Infrastructure from '@components/infrastructure.astro';
|
|
12
|
+
import Snippet from '@components/snippet.astro';
|
|
13
|
+
|
|
14
|
+
The `connection` generator wires a <Link path="guides/py-agent">Python Agent</Link> to a <Link path="guides/py-dynamodb">Python DynamoDB</Link> project, configuring local development so both start together automatically.
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
Before using this generator, ensure you have:
|
|
19
|
+
|
|
20
|
+
1. A <Link path="guides/py-agent">`py#agent`</Link> project
|
|
21
|
+
2. A <Link path="guides/py-dynamodb">`py#dynamodb`</Link> project
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Run the Generator
|
|
26
|
+
|
|
27
|
+
<RunGenerator generator="connection" />
|
|
28
|
+
|
|
29
|
+
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.
|
|
30
|
+
|
|
31
|
+
### Options
|
|
32
|
+
|
|
33
|
+
<GeneratorParameters generator="connection" />
|
|
34
|
+
|
|
35
|
+
## Generator Output
|
|
36
|
+
|
|
37
|
+
The generator updates the agent's `<agent-name>-dev` target in `project.json` to depend on the DynamoDB project's `dev` target, and adds the DynamoDB package as a workspace dependency. No source files are modified.
|
|
38
|
+
|
|
39
|
+
## Using DynamoDB in Agents
|
|
40
|
+
|
|
41
|
+
Import entity classes from the DynamoDB package and use them inside your agent tools:
|
|
42
|
+
|
|
43
|
+
```python title="packages/my_project/my_project/my_agent/agent.py"
|
|
44
|
+
from my_scope.my_table.entities.example import ExampleModel
|
|
45
|
+
from strands import tool
|
|
46
|
+
|
|
47
|
+
@tool
|
|
48
|
+
def list_examples() -> list:
|
|
49
|
+
"""List all example items."""
|
|
50
|
+
return [item.attribute_values for item in ExampleModel.scan()]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Infrastructure
|
|
54
|
+
|
|
55
|
+
To allow the agent's Lambda function to access the DynamoDB table, grant the necessary permissions in your infrastructure.
|
|
56
|
+
|
|
57
|
+
<Infrastructure>
|
|
58
|
+
<Fragment slot="cdk">
|
|
59
|
+
|
|
60
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
61
|
+
import { MyTable } from '@my-scope/common-constructs';
|
|
62
|
+
|
|
63
|
+
const table = new MyTable(this, 'Table');
|
|
64
|
+
const myAgent = new MyAgent(this, 'MyAgent');
|
|
65
|
+
|
|
66
|
+
table.grantReadWriteData(myAgent);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`grantReadWriteData` grants both the DynamoDB and KMS permissions to the agent's execution role.
|
|
70
|
+
</Fragment>
|
|
71
|
+
<Fragment slot="terraform">
|
|
72
|
+
|
|
73
|
+
```hcl title="packages/infra/src/main.tf"
|
|
74
|
+
module "my_table" {
|
|
75
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
resource "aws_iam_role_policy" "dynamodb_access" {
|
|
79
|
+
role = module.my_agent.lambda_role_name
|
|
80
|
+
|
|
81
|
+
policy = jsonencode({
|
|
82
|
+
Version = "2012-10-17"
|
|
83
|
+
Statement = [
|
|
84
|
+
{
|
|
85
|
+
Effect = "Allow"
|
|
86
|
+
Action = [
|
|
87
|
+
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
|
|
88
|
+
"dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan",
|
|
89
|
+
"dynamodb:BatchGetItem", "dynamodb:BatchWriteItem",
|
|
90
|
+
]
|
|
91
|
+
Resource = [
|
|
92
|
+
module.my_table.table_arn,
|
|
93
|
+
"${module.my_table.table_arn}/index/*",
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
Effect = "Allow"
|
|
98
|
+
Action = [
|
|
99
|
+
"kms:Encrypt",
|
|
100
|
+
"kms:Decrypt",
|
|
101
|
+
"kms:ReEncrypt*",
|
|
102
|
+
"kms:GenerateDataKey*",
|
|
103
|
+
"kms:DescribeKey"
|
|
104
|
+
]
|
|
105
|
+
Resource = [module.my_table.kms_key_arn]
|
|
106
|
+
},
|
|
107
|
+
]
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
</Fragment>
|
|
112
|
+
</Infrastructure>
|
|
113
|
+
|
|
114
|
+
## Local Development
|
|
115
|
+
|
|
116
|
+
<Snippet name="connection/py-dynamodb-local-development" />
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Python Agent to Gateway
|
|
3
|
+
description: Connect a Python Agent to an AgentCore Gateway
|
|
4
|
+
when:
|
|
5
|
+
sourceType: py#agent
|
|
6
|
+
targetType: agentcore-gateway
|
|
7
|
+
---
|
|
8
|
+
import { FileTree, Tabs, TabItem } 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/py-agent">Python 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 (via `httpx` request signing) 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 Python project with a <Link path="guides/py-agent">Agent</Link> component (`infra: agentcore`)
|
|
24
|
+
2. A <Link path="guides/agentcore-gateway">`agentcore-gateway`</Link> project with `auth: iam`
|
|
25
|
+
|
|
26
|
+
The Gateway must use IAM authentication — the agent signs its requests with SigV4 using its own execution role. The generator rejects Cognito-authenticated gateways.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
### Run the Generator
|
|
31
|
+
|
|
32
|
+
<RunGenerator generator="connection" />
|
|
33
|
+
|
|
34
|
+
Select the agent project as the source and the Gateway project as the target.
|
|
35
|
+
|
|
36
|
+
### Options
|
|
37
|
+
|
|
38
|
+
<GeneratorParameters generator="connection" />
|
|
39
|
+
|
|
40
|
+
## Generator Output
|
|
41
|
+
|
|
42
|
+
The generator emits shared core-gateway modules into your `agent_connection` Python project, plus a per-Gateway wrapper, and modifies your agent:
|
|
43
|
+
|
|
44
|
+
<FileTree>
|
|
45
|
+
|
|
46
|
+
- packages/common/agent\_connection
|
|
47
|
+
- \<scope>\_agent\_connection
|
|
48
|
+
- core/
|
|
49
|
+
- agentcore\_endpoints.py Framework-agnostic ARN/URL resolution
|
|
50
|
+
- agentcore\_gateway\_mcp\_transport.py Framework-agnostic Gateway MCP transport
|
|
51
|
+
- agentcore\_gateway\_mcp\_client\_\<framework>.py Gateway MCP client for your agent's framework
|
|
52
|
+
- auth/ Framework-agnostic SigV4 / session-forwarding `httpx.Auth`
|
|
53
|
+
- app/
|
|
54
|
+
- \<gateway\_snake>\_client\_\<framework>.py Per-Gateway client wrapper
|
|
55
|
+
- \_\_init\_\_.py Re-exports the Gateway client
|
|
56
|
+
|
|
57
|
+
</FileTree>
|
|
58
|
+
|
|
59
|
+
The client suffix matches your agent's framework (`_strands` or `_langchain`).
|
|
60
|
+
|
|
61
|
+
Additionally, the generator:
|
|
62
|
+
|
|
63
|
+
- Modifies your agent's `agent.py` to import the Gateway client and register its tools in `tools`
|
|
64
|
+
- Adds `agent_connection` as a workspace dependency of the agent
|
|
65
|
+
- Wires the agent's `<agent>-dev` target to depend on the Gateway's `dev` target
|
|
66
|
+
|
|
67
|
+
## Using the connected Gateway
|
|
68
|
+
|
|
69
|
+
The generator transforms your agent's `agent.py` to use the Gateway client:
|
|
70
|
+
|
|
71
|
+
<Tabs syncKey="agent-framework">
|
|
72
|
+
<TabItem label="Strands" _filter={{ framework: 'strands' }}>
|
|
73
|
+
```python title="packages/example/example/my_agent/agent.py" {4,8,9-13}
|
|
74
|
+
from contextlib import contextmanager
|
|
75
|
+
from strands import Agent
|
|
76
|
+
|
|
77
|
+
from my_scope_agent_connection import MyGatewayClientStrands
|
|
78
|
+
|
|
79
|
+
@contextmanager
|
|
80
|
+
def get_agent():
|
|
81
|
+
my_gateway = MyGatewayClientStrands.create()
|
|
82
|
+
with (
|
|
83
|
+
my_gateway,
|
|
84
|
+
):
|
|
85
|
+
yield Agent(
|
|
86
|
+
system_prompt="...",
|
|
87
|
+
tools=[*my_gateway.list_tools_sync()],
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`MyGatewayClientStrands.create()` returns a single context-manageable `MCPClient` whose `list_tools_sync()` yields every tool available through the Gateway.
|
|
92
|
+
</TabItem>
|
|
93
|
+
<TabItem label="LangChain" _filter={{ framework: 'langchain' }}>
|
|
94
|
+
```python title="packages/example/example/my_agent/agent.py" {4,7,11}
|
|
95
|
+
from langchain.agents import create_agent
|
|
96
|
+
from langchain_aws import ChatBedrockConverse
|
|
97
|
+
|
|
98
|
+
from my_scope_agent_connection import MyGatewayClientLangChain
|
|
99
|
+
|
|
100
|
+
def get_agent():
|
|
101
|
+
my_gateway = MyGatewayClientLangChain.create()
|
|
102
|
+
return create_agent(
|
|
103
|
+
model=ChatBedrockConverse(model=MODEL_ID, region_name=REGION),
|
|
104
|
+
system_prompt="...",
|
|
105
|
+
tools=[*my_gateway],
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`MyGatewayClientLangChain.create()` returns a list of tools loaded via [`langchain-mcp-adapters`](https://docs.langchain.com/oss/python/langchain/mcp). Each tool opens a fresh session per call, so no `with` block is needed.
|
|
110
|
+
</TabItem>
|
|
111
|
+
</Tabs>
|
|
112
|
+
|
|
113
|
+
In both cases the client behaves the same way per mode:
|
|
114
|
+
|
|
115
|
+
- **Deployed mode** (`LOCAL_DEV` unset): tools pointed at the Gateway's MCP endpoint, SigV4-signed.
|
|
116
|
+
- **Local mode** (`LOCAL_DEV=true`): plain-HTTP tools pointed at the local gateway started by the Gateway project's `dev` target.
|
|
117
|
+
|
|
118
|
+
The session ID is propagated to downstream MCP servers automatically via the `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` header.
|
|
119
|
+
|
|
120
|
+
## Infrastructure
|
|
121
|
+
|
|
122
|
+
After running the generator you must grant the agent permission to invoke the Gateway.
|
|
123
|
+
|
|
124
|
+
<Infrastructure>
|
|
125
|
+
<Fragment slot="cdk">
|
|
126
|
+
```ts title="packages/infra/src/stacks/application-stack.ts" {5}
|
|
127
|
+
const gateway = new MyGateway(this, 'MyGateway');
|
|
128
|
+
const myAgent = new MyAgent(this, 'MyAgent');
|
|
129
|
+
|
|
130
|
+
// Grant the agent permissions to invoke the Gateway
|
|
131
|
+
gateway.grantInvokeAccess(myAgent);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
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.
|
|
135
|
+
</Fragment>
|
|
136
|
+
<Fragment slot="terraform">
|
|
137
|
+
```hcl title="packages/infra/src/main.tf" {8-13}
|
|
138
|
+
module "my_gateway" {
|
|
139
|
+
source = "../../common/terraform/src/app/gateways/my-gateway"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module "my_agent" {
|
|
143
|
+
source = "../../common/terraform/src/app/agents/my-agent"
|
|
144
|
+
|
|
145
|
+
# Grant the agent permission to invoke the Gateway
|
|
146
|
+
additional_iam_policy_statements = [{
|
|
147
|
+
Effect = "Allow"
|
|
148
|
+
Action = ["bedrock-agentcore:InvokeGateway"]
|
|
149
|
+
Resource = [module.my_gateway.gateway_arn]
|
|
150
|
+
}]
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
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.
|
|
155
|
+
</Fragment>
|
|
156
|
+
</Infrastructure>
|
|
157
|
+
|
|
158
|
+
## Local Development
|
|
159
|
+
|
|
160
|
+
The generator configures the agent's `dev` target to:
|
|
161
|
+
|
|
162
|
+
1. Start the connected Gateway's local gateway and every attached MCP server
|
|
163
|
+
2. Set `LOCAL_DEV=true` so the generated client points at the local gateway instead of the deployed Gateway
|
|
164
|
+
|
|
165
|
+
Run the agent locally with:
|
|
166
|
+
|
|
167
|
+
<NxCommands commands={["<agent-name>-dev <project-name>"]} />
|
|
168
|
+
|
|
169
|
+
To run the agent locally **against the deployed Gateway** instead (for example, to exercise Cedar policies), use the agent's `serve` target. Without `LOCAL_DEV` set, the client resolves the deployed Gateway URL from runtime configuration and SigV4-signs requests with your local AWS credentials:
|
|
170
|
+
|
|
171
|
+
<NxCommands commands={["<agent-name>-serve <project-name>"]} />
|
|
172
|
+
|
|
173
|
+
### Local fidelity
|
|
174
|
+
|
|
175
|
+
The local gateway stands in for the deployed Gateway, so:
|
|
176
|
+
|
|
177
|
+
- **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.
|
|
178
|
+
- **Tool-name prefixing is preserved.** Each local MCP server's tools are exposed as `<target-name>___<tool-name>`, matching what the deployed Gateway emits. This keeps the agent's system prompt and the Cedar action names you reference consistent across local and deployed runs.
|
|
@@ -7,7 +7,7 @@ when:
|
|
|
7
7
|
- ts#mcp-server
|
|
8
8
|
- py#mcp-server
|
|
9
9
|
---
|
|
10
|
-
import { FileTree } from '@astrojs/starlight/components';
|
|
10
|
+
import { FileTree, Tabs, TabItem } from '@astrojs/starlight/components';
|
|
11
11
|
import Link from '@components/link.astro';
|
|
12
12
|
import RunGenerator from '@components/run-generator.astro';
|
|
13
13
|
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
@@ -22,7 +22,7 @@ The generator sets up all the necessary wiring so your agent can discover and in
|
|
|
22
22
|
|
|
23
23
|
Before using this generator, ensure you have:
|
|
24
24
|
|
|
25
|
-
1. A Python project with a <Link path="guides/py-agent">
|
|
25
|
+
1. A Python project with a <Link path="guides/py-agent">Python Agent</Link> component (Strands or LangChain)
|
|
26
26
|
2. A project with an MCP server component (either <Link path="guides/ts-mcp-server">`ts#mcp-server`</Link> or <Link path="guides/py-mcp-server">`py#mcp-server`</Link>)
|
|
27
27
|
3. Both components created with `infra: agentcore`
|
|
28
28
|
|
|
@@ -48,30 +48,37 @@ The generator creates a shared `agent_connection` Python project at `packages/co
|
|
|
48
48
|
- \<scope>\_agent\_connection
|
|
49
49
|
- \_\_init\_\_.py Re-exports per-connection clients
|
|
50
50
|
- core
|
|
51
|
-
- agentcore\
|
|
51
|
+
- agentcore\_endpoints.py Framework-agnostic ARN/URL resolution
|
|
52
|
+
- agentcore\_mcp\_transport.py Framework-agnostic MCP transport
|
|
53
|
+
- agentcore\_mcp\_client\_\<framework>.py MCP client wrapping the transport for your agent's framework
|
|
54
|
+
- auth/ Framework-agnostic SigV4 / session-forwarding `httpx.Auth`
|
|
52
55
|
- app
|
|
53
|
-
- \<mcp\_server\_name>\_client
|
|
56
|
+
- \<mcp\_server\_name>\_client\_\<framework>.py Per-connection client for each MCP server
|
|
54
57
|
|
|
55
58
|
</FileTree>
|
|
56
59
|
|
|
60
|
+
The client suffix matches your agent's framework (`_strands` or `_langchain`).
|
|
61
|
+
|
|
57
62
|
Additionally, the generator:
|
|
58
63
|
- Transforms your agent's `agent.py` to import and use the MCP server's tools via a class-based client
|
|
59
64
|
- Adds the `agent_connection` project as a workspace dependency of your agent project
|
|
60
|
-
- Updates the agent's `
|
|
65
|
+
- Updates the agent's `dev` target to depend on the MCP server's serve target
|
|
61
66
|
|
|
62
67
|
## Using the Connected MCP Server
|
|
63
68
|
|
|
64
69
|
The generator transforms your agent's `agent.py` to use the MCP server's tools:
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+
<Tabs syncKey="agent-framework">
|
|
72
|
+
<TabItem label="Strands" _filter={{ framework: 'strands' }}>
|
|
73
|
+
```python title="packages/my-project/my_module/agent/agent.py" {4,8,9-13}
|
|
67
74
|
from contextlib import contextmanager
|
|
68
75
|
from strands import Agent
|
|
69
76
|
|
|
70
|
-
from my_scope_agent_connection import
|
|
77
|
+
from my_scope_agent_connection import MyMcpServerClientStrands
|
|
71
78
|
|
|
72
79
|
@contextmanager
|
|
73
|
-
def get_agent(
|
|
74
|
-
my_mcp_server =
|
|
80
|
+
def get_agent():
|
|
81
|
+
my_mcp_server = MyMcpServerClientStrands.create()
|
|
75
82
|
with (
|
|
76
83
|
my_mcp_server,
|
|
77
84
|
):
|
|
@@ -81,7 +88,29 @@ def get_agent(session_id: str):
|
|
|
81
88
|
)
|
|
82
89
|
```
|
|
83
90
|
|
|
84
|
-
The
|
|
91
|
+
The Strands client is a context manager, entered in a `with` block around the agent.
|
|
92
|
+
</TabItem>
|
|
93
|
+
<TabItem label="LangChain" _filter={{ framework: 'langchain' }}>
|
|
94
|
+
```python title="packages/my-project/my_module/agent/agent.py" {4,7,11}
|
|
95
|
+
from langchain.agents import create_agent
|
|
96
|
+
from langchain_aws import ChatBedrockConverse
|
|
97
|
+
|
|
98
|
+
from my_scope_agent_connection import MyMcpServerClientLangChain
|
|
99
|
+
|
|
100
|
+
def get_agent():
|
|
101
|
+
my_mcp_server = MyMcpServerClientLangChain.create()
|
|
102
|
+
return create_agent(
|
|
103
|
+
model=ChatBedrockConverse(model=MODEL_ID, region_name=REGION),
|
|
104
|
+
system_prompt="...",
|
|
105
|
+
tools=[*my_mcp_server],
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The LangChain client returns a list of tools loaded via [`langchain-mcp-adapters`](https://docs.langchain.com/oss/python/langchain/mcp). Each tool opens a fresh MCP session per call, so the tools stay usable for the agent's lifetime — no `with` block is needed.
|
|
110
|
+
</TabItem>
|
|
111
|
+
</Tabs>
|
|
112
|
+
|
|
113
|
+
The AgentCore session ID is propagated to the MCP server automatically via the `X-Amzn-Bedrock-AgentCore-Runtime-Session-Id` header for both frameworks, ensuring consistency for [Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html).
|
|
85
114
|
|
|
86
115
|
## Infrastructure
|
|
87
116
|
|
|
@@ -102,7 +131,7 @@ The MCP server's AgentCore runtime ARN is automatically registered in the `agent
|
|
|
102
131
|
<Fragment slot="terraform">
|
|
103
132
|
After running the connection generator, you need to grant the agent permission to invoke the MCP server in your Terraform configuration:
|
|
104
133
|
|
|
105
|
-
```hcl title="packages/infra/src/main.tf" {
|
|
134
|
+
```hcl title="packages/infra/src/main.tf" {9-25}
|
|
106
135
|
module "inventory_mcp_server" {
|
|
107
136
|
source = "../../common/terraform/src/app/mcp-servers/inventory-mcp"
|
|
108
137
|
}
|
|
@@ -136,12 +165,12 @@ The MCP server's AgentCore runtime ARN is automatically registered in the `agent
|
|
|
136
165
|
|
|
137
166
|
## Local Development
|
|
138
167
|
|
|
139
|
-
The generator configures the agent's `
|
|
168
|
+
The generator configures the agent's `dev` target to:
|
|
140
169
|
1. Start the connected MCP server(s) automatically
|
|
141
|
-
2. Set `
|
|
170
|
+
2. Set `LOCAL_DEV=true` so the generated client uses direct HTTP transport instead of AgentCore
|
|
142
171
|
|
|
143
172
|
Run the agent locally with:
|
|
144
173
|
|
|
145
|
-
<NxCommands commands={["<agent-name>-
|
|
174
|
+
<NxCommands commands={["<agent-name>-dev <project-name>"]} />
|
|
146
175
|
|
|
147
176
|
This will start both the agent and all connected MCP servers, with the agent connecting to the MCP servers directly via HTTP on their assigned local ports.
|