@aws/nx-plugin-mcp 1.0.0-rc.6 → 1.0.0-rc.62
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 +11732 -10472
- 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 +162 -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/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 +68 -11
- package/docs/guides/fastapi.mdx +249 -9
- package/docs/guides/local-development.mdx +87 -0
- package/docs/guides/nx-generator.mdx +7 -2
- 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 +175 -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 +221 -16
- package/docs/guides/typescript-infrastructure.mdx +25 -15
- package/docs/guides/typescript-project.mdx +133 -26
- 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 +4 -1
- 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/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 +145 -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/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,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: AgentCore Gateway to Agent
|
|
3
|
+
description: Front an agent with an AgentCore Gateway as a runtime target
|
|
4
|
+
when:
|
|
5
|
+
sourceType: agentcore-gateway
|
|
6
|
+
targetType:
|
|
7
|
+
- ts#agent
|
|
8
|
+
- py#agent
|
|
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 agent (either <Link path="guides/ts-agent">TypeScript</Link> or <Link path="guides/py-agent">Python</Link>) as an [AgentCore Runtime target](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-target-http-runtime.html) of an <Link path="guides/agentcore-gateway">AgentCore Gateway</Link> generated with `protocol: http`.
|
|
18
|
+
|
|
19
|
+
Once connected, the Gateway proxies requests for the agent under `<gatewayUrl>/<targetName>/invocations`, signing outbound traffic to the runtime with IAM SigV4. This gives your agents a single governed entry point — and since callers only need to reach the Gateway, the agent runtimes themselves can be deployed inside a VPC behind it.
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
Before using this generator, ensure you have:
|
|
24
|
+
|
|
25
|
+
1. An <Link path="guides/agentcore-gateway">`agentcore-gateway`</Link> project generated with `protocol: http`
|
|
26
|
+
2. An agent component (<Link path="guides/ts-agent">`ts#agent`</Link> or <Link path="guides/py-agent">`py#agent`</Link>) created with `infra: agentcore`. Either `auth: iam` (the Gateway invokes it with its own role) or `auth: cognito` (the Gateway forwards the caller's JWT — see [Forwarding caller identity](#forwarding-caller-identity-to-the-runtime)) works.
|
|
27
|
+
|
|
28
|
+
:::caution[TypeScript HTTP agents]
|
|
29
|
+
A TypeScript `http` agent serves tRPC over WebSocket, and AgentCore Gateway does not support WebSocket or bidirectional streaming — the generator rejects this combination. Generate the agent with the `ag-ui` protocol instead.
|
|
30
|
+
:::
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
### Run the Generator
|
|
35
|
+
|
|
36
|
+
<RunGenerator generator="connection" />
|
|
37
|
+
|
|
38
|
+
Select the Gateway project as the source and the agent project as the target. If the agent project contains multiple components, specify `targetComponent` to disambiguate.
|
|
39
|
+
|
|
40
|
+
### Options
|
|
41
|
+
|
|
42
|
+
<GeneratorParameters generator="connection" />
|
|
43
|
+
|
|
44
|
+
## Generator Output
|
|
45
|
+
|
|
46
|
+
The generator wires existing projects together rather than emitting new source files. The following files are modified:
|
|
47
|
+
|
|
48
|
+
<FileTree>
|
|
49
|
+
|
|
50
|
+
- packages/\<gateway>
|
|
51
|
+
- project.json the Gateway's `dev` target gains a dependency on the agent's `<agent>-dev`
|
|
52
|
+
- local-dev.ts `ATTACHED_AGENTS` updated so the local gateway proxies to the agent
|
|
53
|
+
|
|
54
|
+
</FileTree>
|
|
55
|
+
|
|
56
|
+
## Adding the agent target to your stack
|
|
57
|
+
|
|
58
|
+
The generator **cannot** automatically wire the agent target into your infrastructure because it doesn't know which stack or module instantiates the Gateway. Add a single call to `gateway.addAgent(agent)` yourself.
|
|
59
|
+
|
|
60
|
+
<Infrastructure>
|
|
61
|
+
<Fragment slot="cdk">
|
|
62
|
+
In the stack where you instantiate the Gateway, register the agent as a target:
|
|
63
|
+
|
|
64
|
+
```ts title="packages/infra/src/stacks/application-stack.ts" {5-8}
|
|
65
|
+
const myAgent = new MyAgent(this, 'MyAgent');
|
|
66
|
+
const myGateway = new MyGateway(this, 'MyGateway');
|
|
67
|
+
|
|
68
|
+
// Register the agent as a runtime target of the Gateway. The target name
|
|
69
|
+
// defaults to the agent's `agentName` (its class name in kebab-case,
|
|
70
|
+
// e.g. `MyAgent` -> `my-agent`), and forms the target's invocation path:
|
|
71
|
+
// <gatewayUrl>/my-agent/invocations
|
|
72
|
+
myGateway.addAgent(myAgent);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
To override the default target name, pass `gatewayTargetName`:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
myGateway.addAgent(myAgent, { gatewayTargetName: 'my-target' });
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The construct grants the Gateway's execution role invoke access to the agent runtime and configures the target with the `GATEWAY_IAM_ROLE` credential provider, so the Gateway signs outbound calls with its own role.
|
|
82
|
+
|
|
83
|
+
:::tip[Deploying agents into a VPC]
|
|
84
|
+
Fronting an agent with a Gateway is what makes a VPC-deployed agent reachable: callers talk to the Gateway's public endpoint, and the Gateway reaches the runtime internally. Pass a VPC network configuration to the agent construct:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { RuntimeNetworkConfiguration } from 'aws-cdk-lib/aws-bedrockagentcore';
|
|
88
|
+
|
|
89
|
+
const myAgent = new MyAgent(this, 'MyAgent', {
|
|
90
|
+
// Give each agent its own scope for the network configuration — usingVpc
|
|
91
|
+
// creates a security group named `SecurityGroup` under the scope you pass,
|
|
92
|
+
// so passing `this` for more than one agent collides on the construct id.
|
|
93
|
+
networkConfiguration: RuntimeNetworkConfiguration.usingVpc(
|
|
94
|
+
new Construct(this, 'MyAgentNetwork'),
|
|
95
|
+
{
|
|
96
|
+
vpc,
|
|
97
|
+
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
|
98
|
+
},
|
|
99
|
+
),
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Use a **private subnet with egress**, not a private isolated subnet: the runtime needs outbound internet access to reach Bedrock and read its configuration from AWS AppConfig.
|
|
104
|
+
|
|
105
|
+
AgentCore Runtime VPC deployments are only supported in certain availability zones. If a deploy fails with `subnets are in unsupported availability zones`, restrict the VPC (or the subnet selection) to the supported zones for your region.
|
|
106
|
+
:::
|
|
107
|
+
</Fragment>
|
|
108
|
+
<Fragment slot="terraform">
|
|
109
|
+
In the Terraform file where you instantiate the Gateway, wire the agent target in:
|
|
110
|
+
|
|
111
|
+
```hcl title="packages/infra/src/main.tf" {9-20,24-40}
|
|
112
|
+
module "my_agent" {
|
|
113
|
+
source = "../../common/terraform/src/app/agents/my-agent"
|
|
114
|
+
# ...
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module "my_gateway" {
|
|
118
|
+
source = "../../common/terraform/src/app/gateways/my-gateway"
|
|
119
|
+
|
|
120
|
+
# The Gateway signs outbound calls to the runtime with its own role and
|
|
121
|
+
# validates access at target creation, so it needs invoke access first.
|
|
122
|
+
additional_iam_policy_statements = [
|
|
123
|
+
{
|
|
124
|
+
Effect = "Allow"
|
|
125
|
+
Action = [
|
|
126
|
+
"bedrock-agentcore:InvokeAgentRuntime",
|
|
127
|
+
"bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream",
|
|
128
|
+
# A2A targets additionally serve their agent card via the gateway
|
|
129
|
+
"bedrock-agentcore:GetAgentCard",
|
|
130
|
+
]
|
|
131
|
+
Resource = [
|
|
132
|
+
module.my_agent.agent_core_runtime_arn,
|
|
133
|
+
"${module.my_agent.agent_core_runtime_arn}/*",
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# Register the agent as a runtime target of the Gateway. The target name
|
|
140
|
+
# forms the invocation path: <gatewayUrl>/my-agent/invocations
|
|
141
|
+
resource "aws_bedrockagentcore_gateway_target" "my_agent" {
|
|
142
|
+
gateway_identifier = module.my_gateway.gateway_id
|
|
143
|
+
name = "my-agent"
|
|
144
|
+
# AgentCore fills in a description when none is set, which the provider
|
|
145
|
+
# reports as an inconsistent result after apply — so always set one.
|
|
146
|
+
description = "Agent runtime target my-agent"
|
|
147
|
+
|
|
148
|
+
target_configuration {
|
|
149
|
+
http {
|
|
150
|
+
agentcore_runtime {
|
|
151
|
+
arn = module.my_agent.agent_core_runtime_arn
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
credential_provider_configuration {
|
|
157
|
+
gateway_iam_role {}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
:::tip[Deploying agents into a VPC]
|
|
163
|
+
Fronting an agent with a Gateway is what makes a VPC-deployed agent reachable: callers talk to the Gateway's public endpoint, and the Gateway reaches the runtime internally. Set the agent module's VPC variables:
|
|
164
|
+
|
|
165
|
+
```hcl
|
|
166
|
+
module "my_agent" {
|
|
167
|
+
source = "../../common/terraform/src/app/agents/my-agent"
|
|
168
|
+
|
|
169
|
+
enable_vpc = true
|
|
170
|
+
vpc_id = aws_vpc.my_vpc.id
|
|
171
|
+
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Use private subnets with egress (a route to a NAT gateway), not private isolated subnets: the runtime needs outbound internet access to reach Bedrock and read its configuration from AWS AppConfig.
|
|
176
|
+
:::
|
|
177
|
+
</Fragment>
|
|
178
|
+
</Infrastructure>
|
|
179
|
+
|
|
180
|
+
## Invoking the agent through the Gateway
|
|
181
|
+
|
|
182
|
+
Requests to `<gatewayUrl origin>/<targetName>/invocations` are forwarded to the agent runtime without protocol translation, so callers use the same request shape they'd use against the runtime directly — SSE streams (AG-UI), JSON streaming (Python HTTP) and A2A JSON-RPC all proxy through. Callers authenticate with the Gateway (IAM SigV4 or Cognito JWT depending on the Gateway's `auth`) rather than with the agent.
|
|
183
|
+
|
|
184
|
+
To connect a website to the Gateway's agents, use the <Link path="guides/connection/react-agentcore-gateway">`connection` generator</Link>.
|
|
185
|
+
|
|
186
|
+
## Forwarding caller identity to the runtime
|
|
187
|
+
|
|
188
|
+
By default the Gateway signs outbound calls with its own IAM role (the `GATEWAY_IAM_ROLE` credential provider), so the runtime sees the _Gateway's_ identity, not the caller's. If instead you want the agent to authorize on the caller — for example to read the user's `sub` or `scope` claims — front a **Cognito** agent with a **Cognito** Gateway. The Gateway then forwards the caller's JWT to the runtime unchanged (the `JWT_PASSTHROUGH` credential provider), and the runtime revalidates it.
|
|
189
|
+
|
|
190
|
+
Generate both ends with `auth: cognito` and connect them as above:
|
|
191
|
+
|
|
192
|
+
- an agent (<Link path="guides/ts-agent">`ts#agent`</Link> or <Link path="guides/py-agent">`py#agent`</Link>) created with `auth: cognito`, and
|
|
193
|
+
- a Gateway created with `auth: cognito` fronting the **same** Cognito user pool.
|
|
194
|
+
|
|
195
|
+
Everything else is automatic — `gateway.addAgent(agent)` (CDK) and the generated Terraform runtime module handle the wiring for you based on the agent's `auth`:
|
|
196
|
+
|
|
197
|
+
- the target is created with the `JWT_PASSTHROUGH` credential provider (rather than `GATEWAY_IAM_ROLE`), and
|
|
198
|
+
- the runtime allowlists the `Authorization` header so the forwarded token reaches your agent code. Without this allowlist AgentCore validates the token but strips the header before your container.
|
|
199
|
+
|
|
200
|
+
Callers invoke the Gateway with `Authorization: Bearer <jwt>` (no SigV4), and the agent reads the claims from the `Authorization` header — skipping signature validation, since the runtime's inbound authorizer has already verified the token:
|
|
201
|
+
|
|
202
|
+
```python title="packages/py_project/.../my_agent/main.py"
|
|
203
|
+
import jwt # PyJWT
|
|
204
|
+
|
|
205
|
+
@app.post('/invocations')
|
|
206
|
+
async def invoke(input: InvokeInput, request: Request):
|
|
207
|
+
token = request.headers['authorization'].removeprefix('Bearer ')
|
|
208
|
+
claims = jwt.decode(token, options={'verify_signature': False})
|
|
209
|
+
# authorize on claims['sub'], claims['scope'], ...
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
:::note
|
|
213
|
+
JWT passthrough suits a single identity provider whose token audience already covers the runtime. If one Gateway fronts agents across multiple tenants or audiences, use OAuth [on-behalf-of token exchange](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-building-adding-targets-authorization.html) instead.
|
|
214
|
+
:::
|
|
215
|
+
|
|
216
|
+
## Local Development
|
|
217
|
+
|
|
218
|
+
Running the Gateway locally with:
|
|
219
|
+
|
|
220
|
+
<NxCommands commands={["dev <gateway-name>"]} />
|
|
221
|
+
|
|
222
|
+
starts a local gateway plus every attached agent on its assigned local port. The local gateway proxies `/<targetName>/...` paths to each agent's local server, matching the deployed Gateway's path-based routing.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: AgentCore Gateway to AgentCore Gateway
|
|
3
|
+
description: Connect an AgentCore Gateway to another AgentCore Gateway
|
|
4
|
+
when:
|
|
5
|
+
sourceType: agentcore-gateway
|
|
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 register an <Link path="guides/agentcore-gateway">AgentCore Gateway</Link> as a target of another AgentCore Gateway. This lets you compose gateways hierarchically — for example a team-level gateway aggregating several domain gateways, each of which fronts its own MCP servers.
|
|
16
|
+
|
|
17
|
+
Once connected, the source Gateway aggregates the target Gateway's tools into its single MCP endpoint. Since the target Gateway already prefixes its tools with its own target names, tools surface through the source Gateway as `<gateway-target-name>___<target-name>___<tool-name>` — each gateway in the chain adds one prefix. Both gateways evaluate their own Cedar policies: the source Gateway authorizes the caller for the prefixed action, then the target Gateway authorizes the source Gateway's execution role for the inner action.
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
Before using this generator, ensure you have:
|
|
22
|
+
|
|
23
|
+
1. Two <Link path="guides/agentcore-gateway">`agentcore-gateway`</Link> projects
|
|
24
|
+
|
|
25
|
+
Both gateways must have `protocol: mcp`, and the target gateway must have `auth: iam` — the source gateway invokes the target signing with its own execution role, so only the target's inbound auth needs to be IAM. The generator validates this, and also rejects connections that would create a cycle between gateways, which would otherwise recurse infinitely on `tools/list`.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Run the Generator
|
|
30
|
+
|
|
31
|
+
<RunGenerator generator="connection" />
|
|
32
|
+
|
|
33
|
+
Select the aggregating Gateway project as the source and the Gateway to be aggregated as the target.
|
|
34
|
+
|
|
35
|
+
### Options
|
|
36
|
+
|
|
37
|
+
<GeneratorParameters generator="connection" />
|
|
38
|
+
|
|
39
|
+
## Generator Output
|
|
40
|
+
|
|
41
|
+
The generator wires existing projects together rather than emitting new source files. The following files are modified:
|
|
42
|
+
|
|
43
|
+
<FileTree>
|
|
44
|
+
|
|
45
|
+
- packages/\<source-gateway>
|
|
46
|
+
- project.json the source Gateway's `dev` target gains a dependency on the target gateway's `dev` target
|
|
47
|
+
- local-dev.ts `ATTACHED_MCP_SERVERS` updated so the local gateway aggregates the target gateway
|
|
48
|
+
|
|
49
|
+
</FileTree>
|
|
50
|
+
|
|
51
|
+
The source Gateway project's `dev` target gains a dependency on the target Gateway's `dev` target, so running the source Gateway locally also starts the target gateway (and, transitively, every MCP server attached to it). The target gateway is also registered in the source Gateway project's `local-dev.ts` so the local gateway aggregates its tools.
|
|
52
|
+
|
|
53
|
+
## Adding the gateway target to your stack
|
|
54
|
+
|
|
55
|
+
The generator **cannot** automatically wire the gateway target into your infrastructure because it doesn't know which stack or module instantiates the Gateways. Add a single call to `gateway.addGateway(targetGateway)` yourself.
|
|
56
|
+
|
|
57
|
+
<Infrastructure>
|
|
58
|
+
<Fragment slot="cdk">
|
|
59
|
+
In the stack where you instantiate the Gateways, register the target gateway as a target of the source gateway:
|
|
60
|
+
|
|
61
|
+
```ts title="packages/infra/src/stacks/application-stack.ts" {4-7}
|
|
62
|
+
const innerGateway = new InnerGateway(this, 'InnerGateway');
|
|
63
|
+
const outerGateway = new OuterGateway(this, 'OuterGateway');
|
|
64
|
+
|
|
65
|
+
// Register the inner gateway as a target of the outer gateway. The target
|
|
66
|
+
// name defaults to the inner gateway's `gatewayName` (its class name in
|
|
67
|
+
// kebab-case, e.g. `InnerGateway` -> `inner-gateway`).
|
|
68
|
+
outerGateway.addGateway(innerGateway);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The Gateway target name (the target gateway's `gatewayName` by default) prefixes Cedar action names on the source gateway — the action format is ``AgentCore::Action::"<gatewayTargetName>___<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.
|
|
72
|
+
|
|
73
|
+
To override the default target name, pass `gatewayTargetName`:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
outerGateway.addGateway(innerGateway, { gatewayTargetName: 'inner' });
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The construct grants the source gateway's execution role `bedrock-agentcore:InvokeGateway` access to the target gateway, and configures the target with `iamCredentialProvider.service = 'bedrock-agentcore'` so the source gateway signs outbound calls using its own execution role. The target is created after the target gateway and all of its own targets, since AgentCore fetches the target's tools during creation.
|
|
80
|
+
</Fragment>
|
|
81
|
+
<Fragment slot="terraform">
|
|
82
|
+
In the Terraform file where you instantiate the Gateways, wire the gateway target in:
|
|
83
|
+
|
|
84
|
+
```hcl title="packages/infra/src/main.tf" {4-6,11,13-19,22-40}
|
|
85
|
+
module "inner_gateway" {
|
|
86
|
+
source = "../../common/terraform/src/app/gateways/inner-gateway"
|
|
87
|
+
|
|
88
|
+
# Target ids of the inner gateway's own targets (e.g. its MCP servers), so
|
|
89
|
+
# its gateway_url is not consumed until it serves their tools.
|
|
90
|
+
tool_dependencies = [aws_bedrockagentcore_gateway_target.my_mcp_server.target_id]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module "outer_gateway" {
|
|
94
|
+
source = "../../common/terraform/src/app/gateways/outer-gateway"
|
|
95
|
+
policy_dependencies = [aws_bedrockagentcore_gateway_target.inner_gateway.target_id]
|
|
96
|
+
|
|
97
|
+
additional_iam_policy_statements = [
|
|
98
|
+
{
|
|
99
|
+
Effect = "Allow"
|
|
100
|
+
Action = ["bedrock-agentcore:InvokeGateway"]
|
|
101
|
+
Resource = [module.inner_gateway.gateway_arn]
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# Register the inner gateway as a target of the outer gateway
|
|
107
|
+
resource "aws_bedrockagentcore_gateway_target" "inner_gateway" {
|
|
108
|
+
gateway_identifier = module.outer_gateway.gateway_id
|
|
109
|
+
name = "inner-gateway"
|
|
110
|
+
|
|
111
|
+
target_configuration {
|
|
112
|
+
mcp {
|
|
113
|
+
mcp_server {
|
|
114
|
+
endpoint = module.inner_gateway.gateway_url
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
credential_provider_configuration {
|
|
120
|
+
gateway_iam_role {
|
|
121
|
+
service = "bedrock-agentcore"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The target `name` (`inner-gateway` above) prefixes Cedar action names on the outer gateway — see the <Link path="guides/agentcore-gateway">Writing Policies section</Link>. The `additional_iam_policy_statements` entry grants the outer gateway's execution role invoke access to the inner gateway, which is required both to fetch the inner gateway's tools at target creation time and to route calls at runtime. `policy_dependencies` ensures Cedar policies referencing this target's actions are created after the target has registered them.
|
|
128
|
+
|
|
129
|
+
:::note[Target ordering]
|
|
130
|
+
AgentCore fetches the inner gateway's tools when the `aws_bedrockagentcore_gateway_target` is created, so the inner gateway must already be serving them. Set the inner gateway's `tool_dependencies` to its own targets' ids: its `gateway_url` then flows through a readiness probe that polls `tools/list` until those tools are served, so the outer gateway's target waits for the inner gateway to be ready.
|
|
131
|
+
:::
|
|
132
|
+
</Fragment>
|
|
133
|
+
</Infrastructure>
|
|
134
|
+
|
|
135
|
+
## Cedar policies across chained gateways
|
|
136
|
+
|
|
137
|
+
Each gateway in the chain evaluates its own policy set:
|
|
138
|
+
|
|
139
|
+
1. The **source gateway** evaluates the original caller (e.g. an agent's execution role) against the prefixed action, e.g. `AgentCore::Action::"inner-gateway___my-mcp___add"`.
|
|
140
|
+
2. The **target gateway** evaluates the source gateway's execution role against the inner action, e.g. `AgentCore::Action::"my-mcp___add"`.
|
|
141
|
+
|
|
142
|
+
This means a tool call through a gateway chain must be permitted at every hop. The default `permit-all.cedar` permits any caller in the same AWS account, which includes the source gateway's role; if you write narrower policies on the target gateway, remember that the principal it sees is the *source gateway's* role, not the original caller.
|
|
143
|
+
|
|
144
|
+
## Local Development
|
|
145
|
+
|
|
146
|
+
Running the source Gateway locally with:
|
|
147
|
+
|
|
148
|
+
<NxCommands commands={["dev <source-gateway-name>"]} />
|
|
149
|
+
|
|
150
|
+
starts the local source gateway, the local target gateway, and every MCP server attached to either, each on its assigned local port. Tool names are prefixed at each hop exactly as deployed (`<gateway-target-name>___<target-name>___<tool-name>`), so agent prompts and Cedar action names remain consistent across local and deployed runs.
|
|
151
|
+
|
|
152
|
+
:::caution[Local fidelity]
|
|
153
|
+
Local development uses **local stand-in gateways** — lightweight MCP aggregators started by each Gateway project, not the AgentCore Gateway service. As a consequence, **Cedar policies are not evaluated locally** at either hop. 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.
|
|
154
|
+
:::
|
|
@@ -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.
|