@aws/nx-plugin-mcp 1.0.0-rc.57 → 1.0.0-rc.59

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.
Files changed (50) hide show
  1. package/bin/aws-nx-mcp.js +149 -156
  2. package/docs/get_started/graph-builder.mdx +37 -0
  3. package/docs/get_started/tutorials/contribute-generator.mdx +2 -2
  4. package/docs/get_started/tutorials/dungeon-game/1.mdx +2 -2
  5. package/docs/guides/agentcore-gateway.mdx +37 -10
  6. package/docs/guides/connection/agentcore-gateway-agent.mdx +282 -0
  7. package/docs/guides/connection/agentcore-gateway-gateway.mdx +2 -2
  8. package/docs/guides/connection/agentcore-gateway-mcp.mdx +2 -2
  9. package/docs/guides/connection/py-agent-a2a.mdx +1 -1
  10. package/docs/guides/connection/py-agent-gateway.mdx +2 -2
  11. package/docs/guides/connection/py-agent-mcp.mdx +3 -3
  12. package/docs/guides/connection/react-agentcore-gateway.mdx +112 -0
  13. package/docs/guides/connection/smithy-rdb.mdx +1 -1
  14. package/docs/guides/connection/trpc-rdb.mdx +1 -1
  15. package/docs/guides/connection/ts-agent-a2a.mdx +1 -1
  16. package/docs/guides/connection/ts-agent-gateway.mdx +1 -1
  17. package/docs/guides/connection/ts-agent-mcp.mdx +1 -1
  18. package/docs/guides/connection.mdx +18 -0
  19. package/docs/guides/fastapi.mdx +1 -1
  20. package/docs/guides/py-agent.mdx +7 -0
  21. package/docs/guides/react-website.mdx +9 -2
  22. package/docs/guides/terraform-project.mdx +1 -1
  23. package/docs/guides/trpc.mdx +2 -2
  24. package/docs/guides/ts-agent.mdx +7 -0
  25. package/docs/guides/ts-smithy-api.mdx +8 -8
  26. package/docs/snippets/agent/bedrock-deployment.mdx +1 -1
  27. package/docs/snippets/agent/runtime-arn.mdx +1 -1
  28. package/docs/snippets/api/cors-configuration-terraform-note.mdx +1 -1
  29. package/docs/snippets/api/type-safe-api-integrations.mdx +2 -2
  30. package/docs/snippets/api/waf-configuration.mdx +2 -2
  31. package/docs/snippets/connection/a2a-infrastructure.mdx +1 -1
  32. package/docs/snippets/mcp/bedrock-deployment.mdx +1 -1
  33. package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +1 -1
  34. package/generators.json +17 -1
  35. package/package.json +1 -1
  36. package/src/agentcore-gateway/agent-connection/schema.json +31 -0
  37. package/src/agentcore-gateway/react-connection/schema.json +31 -0
  38. package/src/agentcore-gateway/schema.json +3 -2
  39. package/src/py/agent/schema.json +1 -0
  40. package/src/py/dynamodb/schema.json +1 -0
  41. package/src/py/fast-api/schema.json +1 -0
  42. package/src/py/mcp-server/schema.json +1 -0
  43. package/src/py/rdb/schema.json +1 -0
  44. package/src/smithy/ts/api/schema.json +1 -0
  45. package/src/trpc/backend/schema.json +1 -0
  46. package/src/ts/agent/schema.json +1 -0
  47. package/src/ts/dynamodb/schema.json +1 -0
  48. package/src/ts/mcp-server/schema.json +1 -0
  49. package/src/ts/rdb/schema.json +1 -0
  50. package/src/ts/react-website/app/schema.json +1 -0
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: Graph Builder
3
+ description: Design your workspace visually, then copy the commands that scaffold it.
4
+ # The builder needs the full content width, which the table of contents column
5
+ # would otherwise take.
6
+ tableOfContents: false
7
+ ---
8
+ import Link from '@components/link.astro';
9
+ import GraphBuilder from '@components/graph-builder.astro';
10
+
11
+ Sketch the projects your workspace needs and the connections between them, and the builder generates the commands that scaffold exactly what you drew. Copy them, run them, and you have a working workspace.
12
+
13
+ Drag components from the palette onto the canvas, drag from a component's right edge to another to connect them, and edit each component's properties on the right. The generated commands at the bottom update with every change — hit **Copy** to take the whole script.
14
+
15
+ <GraphBuilder />
16
+
17
+ ## How it works
18
+
19
+ Each component on the canvas maps to a generator, and each connection to the <Link path="guides/connection">connection generator</Link>. The commands are emitted in dependency order: the workspace first, then the projects, then the components they host, then the connections wiring them together.
20
+
21
+ A website always gets <Link path="guides/react-website-auth">Cognito authentication</Link> added straight after it, since `ts#website` leaves that to a follow-up generator.
22
+
23
+ An `infra` project is added at the end — <Link path="guides/typescript-infrastructure">`ts#infra`</Link> or <Link path="guides/terraform-project">`terraform#project`</Link>, matching your IaC choice. Every generated project vends constructs for it to instantiate, so this is what you deploy. Because it owns that name, no component on the canvas can be called `infra`.
24
+
25
+ Drag the canvas background to pan around, and drag a component to reposition it. Shift-click to select several components and move them as a group. Click a connection to select it, then press <kbd>Delete</kbd> to remove it (or use the ✕ on the connection itself).
26
+
27
+ The palette lists every project and component type that can take part in a connection, and you can only draw the connections the plugin supports — so a graph that validates is a graph that scaffolds.
28
+
29
+ Three rules are worth knowing:
30
+
31
+ - **Components share a host project.** An agent and an MCP server are added _to_ a project rather than being projects of their own. Give them the same host project name to put them in one project, or different names for one project each.
32
+ - **Some connections constrain their endpoints.** Connecting an agent to another agent requires the target to use the `a2a` protocol, for instance. Where a property setting would break a connection you have drawn, the builder says so against the component and the connection.
33
+ - **Drawing a connection can adjust the target.** Connecting a website to an agent switches that agent to the `ag-ui` protocol, and connecting an agent to another agent switches the target to `a2a` — the protocols those connections are built on. A property you have set yourself is never changed.
34
+
35
+ :::tip[Prefer to build with AI?]
36
+ The plugin ships an MCP server, so your coding agent can scaffold and connect projects for you. See <Link path="get_started/building-with-ai">Building with AI</Link>.
37
+ :::
@@ -182,7 +182,7 @@ So we'll need to make sure we pass those to `generateFiles`, as well as the dire
182
182
 
183
183
  Let's update the generator to do that:
184
184
 
185
- ```ts title="procedure/generator.ts" {8-19}
185
+ ```ts title="procedure/generator.ts" {16-30}
186
186
  import {
187
187
  generateFiles,
188
188
  joinPathFragments,
@@ -230,7 +230,7 @@ Next, we want the generator to hook up the new procedure to the router. This mea
230
230
 
231
231
  We use [GritQL](https://docs.grit.io/) to declaratively search and transform source code. The `addDestructuredImport` helper adds named imports, and `applyGritQL` applies a GritQL pattern to add the procedure to the router's object literal.
232
232
 
233
- ```ts title="procedure/generator.ts" {6, 23-36}
233
+ ```ts title="procedure/generator.ts" {11, 33-46}
234
234
  import {
235
235
  generateFiles,
236
236
  joinPathFragments,
@@ -120,7 +120,7 @@ Below is a list of all files which have been generated by the `ts#api` generator
120
120
 
121
121
  Let us look at these key files:
122
122
 
123
- ```ts {5}
123
+ ```ts {7}
124
124
  // packages/game-api/src/router.ts
125
125
  import { echo } from './procedures/echo.js';
126
126
  import { t } from './init.js';
@@ -135,7 +135,7 @@ export type AppRouter = typeof appRouter;
135
135
  ```
136
136
  The router defines the tRPC router for your API and is the place where you will declare all of your API methods. As you can see above, we have a method called `echo` with it's implementation in the `./procedures/echo.ts` file. The Lambda handler entrypoint is in `handler.ts`, which is configured automatically by the generator.
137
137
 
138
- ```ts {2-5}
138
+ ```ts {7-10}
139
139
  // packages/game-api/src/procedures/echo.ts
140
140
  import { publicProcedure } from '../init.js';
141
141
  import {
@@ -15,7 +15,12 @@ import Link from '@components/link.astro';
15
15
  import NxCommands from '@components/nx-commands.astro';
16
16
  import OptionFilter from '@components/option-filter.astro';
17
17
 
18
- Generate an [Amazon Bedrock AgentCore Gateway](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html) project. An AgentCore Gateway is a managed entry point that aggregates one or more MCP server targets behind a single MCP endpoint, authenticates inbound requests (IAM or Cognito), evaluates every tool call against a [Cedar policy engine](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/policy.html), and signs outbound traffic to MCP servers with IAM SigV4.
18
+ Generate an [Amazon Bedrock AgentCore Gateway](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html) project. An AgentCore Gateway is a managed entry point in front of your MCP servers or agents, authenticating inbound requests (IAM or Cognito) and signing outbound traffic to its targets with IAM SigV4.
19
+
20
+ The `protocol` option selects what the Gateway fronts:
21
+
22
+ - **`mcp`** (default) — aggregates one or more MCP server targets behind a single MCP endpoint, and evaluates every tool call against a [Cedar policy engine](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/policy.html).
23
+ - **`http`** — proxies requests directly to [AgentCore Runtime targets](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-target-http-runtime.html) (your agents) via path-based routing (`/<targetName>/invocations`), without aggregation or protocol translation. Use this to front agents with a single governed endpoint — for example so a website can reach agents that are deployed inside a VPC through the Gateway.
19
24
 
20
25
  ## Usage
21
26
 
@@ -33,10 +38,10 @@ The generator creates a new project at `packages/<name>/`, plus a CDK construct
33
38
 
34
39
  <FileTree>
35
40
  - packages/\<name>/
36
- - policies/ Cedar policy source files (omitted when `cedarPolicy: false`)
41
+ - policies/ Cedar policy source files (`mcp` protocol only; omitted when `cedarPolicy: false`)
37
42
  - permit-all.cedar Default Cedar policy that permits authenticated callers
38
43
  - README.md Reference for writing Cedar policies
39
- - local-dev.ts Local gateway aggregating attached MCP servers for local development
44
+ - local-dev.ts Local gateway for local development — aggregates attached MCP servers (`mcp`) or proxies attached agents (`http`)
40
45
  - project.json Adds the `serve` and `dev` targets
41
46
  </FileTree>
42
47
 
@@ -71,9 +76,9 @@ Infrastructure is generated when `infra` is `agentcore` (the default). With `inf
71
76
 
72
77
  The generated construct creates the following AWS resources:
73
78
 
74
- - An `AgentCore::Gateway` configured for the MCP protocol with inbound IAM authentication (default) or Cognito JWT authentication (see <a href="#authentication">Authentication</a>)
75
- - An `AgentCore::PolicyEngine` running in `ENFORCE` mode, attached to the Gateway (omitted when `cedarPolicy: false`)
76
- - One `AgentCore::Policy` per `.cedar` file in `policies/`
79
+ - An `AgentCore::Gateway` with inbound IAM authentication (default) or Cognito JWT authentication (see <a href="#authentication">Authentication</a>). An `mcp` gateway is configured for the MCP protocol; an `http` gateway has no protocol type, which AgentCore requires for its runtime targets
80
+ - An `AgentCore::PolicyEngine` running in `ENFORCE` mode, attached to the Gateway (`mcp` gateways only; omitted when `cedarPolicy: false`)
81
+ - One `AgentCore::Policy` per `.cedar` file in `policies/` (`mcp` gateways only)
77
82
  - An AWS WAFv2 Web ACL associated with the Gateway, with request logging to CloudWatch (enabled by default — see <a href="#aws-waf">AWS WAF</a>)
78
83
 
79
84
  The Gateway URL is automatically registered in the `agentcore.gateways.<ClassName>` namespace of <Link path="guides/runtime-config">Runtime Configuration</Link> so agents can discover it at runtime.
@@ -146,7 +151,7 @@ export class ApplicationStack extends Stack {
146
151
  <Fragment slot="terraform">
147
152
  The generated module requires `user_pool_id` and `user_pool_client_ids` variables:
148
153
 
149
- ```hcl {6-7} title="packages/infra/src/main.tf"
154
+ ```hcl {7-8} title="packages/infra/src/main.tf"
150
155
  module "user_identity" {
151
156
  source = "../../common/terraform/src/core/user-identity"
152
157
  }
@@ -207,7 +212,7 @@ Add new variables where the policies are rendered, for example to pass an agent'
207
212
  <Fragment slot="cdk">
208
213
  In `packages/common/constructs/src/app/gateways/<name>/<name>.ts`, pass `cedarPolicyVariables` through to the shared construct:
209
214
 
210
- ```ts {4-6}
215
+ ```ts {5-6}
211
216
  super(scope, id, {
212
217
  cedarPolicyPath: path.join(
213
218
  ...
@@ -347,11 +352,19 @@ This denies the Python agent role from calling `ts-mcp___divide` while leaving t
347
352
 
348
353
  ## Local Development
349
354
 
350
- The generator adds a `dev` target to the Gateway project, which runs `local-dev.ts`: a local gateway exposing a single MCP endpoint that aggregates every attached MCP server (connected via the <Link path="guides/connection/agentcore-gateway-mcp">`agentcore-gateway#mcp-connection` generator</Link>), with tools prefixed `<target>___<tool>` to match the deployed Gateway. Running it starts the local gateway and all attached MCP servers together:
355
+ The generator adds a `dev` target to the Gateway project, which runs `local-dev.ts`. Running it starts the local gateway and every attached target together:
351
356
 
352
357
  <NxCommands commands={["dev <name>"]} />
353
358
 
354
- See the connection guide for the full local development story.
359
+ <OptionFilter when={{ protocol: 'mcp' }} description="MCP aggregator local gateway">
360
+ The local gateway exposes a single MCP endpoint that aggregates every attached MCP server (connected via the <Link path="guides/connection/agentcore-gateway-mcp">`agentcore-gateway#mcp-connection` generator</Link>), with tools prefixed `<target>___<tool>` to match the deployed Gateway.
361
+ </OptionFilter>
362
+
363
+ <OptionFilter when={{ protocol: 'http' }} description="Path-routing proxy local gateway">
364
+ The local gateway proxies `/<targetName>/...` paths to each attached agent's local server (connected via the <Link path="guides/connection/agentcore-gateway-agent">`agentcore-gateway#agent-connection` generator</Link>), matching the deployed Gateway's path-based routing.
365
+ </OptionFilter>
366
+
367
+ See the connection guides for the full local development story.
355
368
 
356
369
  ## Deploying your AgentCore Gateway
357
370
 
@@ -460,4 +473,18 @@ Use the <Link path="guides/connection">`connection`</Link> generator to integrat
460
473
  sourceBadge="python"
461
474
  target="agentcore"
462
475
  />
476
+ <ConnectionCard
477
+ title="AgentCore Gateway to Agent"
478
+ description="Front an agent with an AgentCore Gateway as a runtime target"
479
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/agentcore-gateway-agent`}
480
+ source="agentcore"
481
+ target="strands"
482
+ />
483
+ <ConnectionCard
484
+ title="React Website to AgentCore Gateway"
485
+ description="Connect a React website to agents through an AgentCore Gateway"
486
+ href={`/nx-plugin-for-aws/${Astro.currentLocale || 'en'}/guides/connection/react-agentcore-gateway`}
487
+ source="react"
488
+ target="agentcore"
489
+ />
463
490
  </CardGrid>
@@ -0,0 +1,282 @@
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` and `auth: iam`
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
+ networkConfiguration: RuntimeNetworkConfiguration.usingVpc(this, {
91
+ vpc,
92
+ vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
93
+ }),
94
+ });
95
+ ```
96
+
97
+ 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.
98
+ :::
99
+ </Fragment>
100
+ <Fragment slot="terraform">
101
+ In the Terraform file where you instantiate the Gateway, wire the agent target in:
102
+
103
+ ```hcl title="packages/infra/src/main.tf" {9-20,24-40}
104
+ module "my_agent" {
105
+ source = "../../common/terraform/src/app/agents/my-agent"
106
+ # ...
107
+ }
108
+
109
+ module "my_gateway" {
110
+ source = "../../common/terraform/src/app/gateways/my-gateway"
111
+
112
+ # The Gateway signs outbound calls to the runtime with its own role and
113
+ # validates access at target creation, so it needs invoke access first.
114
+ additional_iam_policy_statements = [
115
+ {
116
+ Effect = "Allow"
117
+ Action = [
118
+ "bedrock-agentcore:InvokeAgentRuntime",
119
+ "bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream",
120
+ # A2A targets additionally serve their agent card via the gateway
121
+ "bedrock-agentcore:GetAgentCard",
122
+ ]
123
+ Resource = [
124
+ module.my_agent.agent_core_runtime_arn,
125
+ "${module.my_agent.agent_core_runtime_arn}/*",
126
+ ]
127
+ }
128
+ ]
129
+ }
130
+
131
+ # Register the agent as a runtime target of the Gateway. The target name
132
+ # forms the invocation path: <gatewayUrl>/my-agent/invocations
133
+ resource "aws_bedrockagentcore_gateway_target" "my_agent" {
134
+ gateway_identifier = module.my_gateway.gateway_id
135
+ name = "my-agent"
136
+ # AgentCore fills in a description when none is set, which the provider
137
+ # reports as an inconsistent result after apply — so always set one.
138
+ description = "Agent runtime target my-agent"
139
+
140
+ target_configuration {
141
+ http {
142
+ agentcore_runtime {
143
+ arn = module.my_agent.agent_core_runtime_arn
144
+ }
145
+ }
146
+ }
147
+
148
+ credential_provider_configuration {
149
+ gateway_iam_role {}
150
+ }
151
+ }
152
+ ```
153
+
154
+ :::tip[Deploying agents into a VPC]
155
+ 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:
156
+
157
+ ```hcl
158
+ module "my_agent" {
159
+ source = "../../common/terraform/src/app/agents/my-agent"
160
+
161
+ enable_vpc = true
162
+ vpc_id = aws_vpc.my_vpc.id
163
+ subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
164
+ }
165
+ ```
166
+
167
+ 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.
168
+ :::
169
+ </Fragment>
170
+ </Infrastructure>
171
+
172
+ ## Invoking the agent through the Gateway
173
+
174
+ 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.
175
+
176
+ To connect a website to the Gateway's agents, use the <Link path="guides/connection/react-agentcore-gateway">`connection` generator</Link>.
177
+
178
+ ## Forwarding caller identity to the runtime
179
+
180
+ 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 you want the agent to authorize on the caller — for example to read the user's `sub` or `scope` claims — the Gateway can instead forward the caller's JWT to the runtime unchanged. This requires three changes:
181
+
182
+ 1. **The Gateway accepts JWTs.** Generate the Gateway with `auth: cognito` so its inbound authorizer validates a Cognito (or other OIDC) bearer token.
183
+ 2. **The runtime accepts the same JWTs.** Generate the agent with `auth: cognito` (same user pool) so the runtime revalidates the forwarded token.
184
+ 3. **The target uses the `JWT_PASSTHROUGH` credential provider** instead of `GATEWAY_IAM_ROLE`, and the **runtime allowlists the `Authorization` header** so it reaches your agent code. Without the allowlist, AgentCore validates the token but strips the header before your container.
185
+
186
+ Callers then 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:
187
+
188
+ ```python title="packages/py_project/.../my_agent/main.py"
189
+ import jwt # PyJWT
190
+
191
+ @app.post('/invocations')
192
+ async def invoke(input: InvokeInput, request: Request):
193
+ token = request.headers['authorization'].removeprefix('Bearer ')
194
+ claims = jwt.decode(token, options={'verify_signature': False})
195
+ # authorize on claims['sub'], claims['scope'], ...
196
+ ```
197
+
198
+ <Infrastructure>
199
+ <Fragment slot="cdk">
200
+ Pass `requestHeaderConfiguration` to the agent so the runtime receives the header, and create the target yourself (instead of `gateway.addAgent(agent)`) with the `JWT_PASSTHROUGH` credential provider:
201
+
202
+ ```ts title="packages/infra/src/stacks/application-stack.ts" {5-7,17-19}
203
+ import { CfnGatewayTarget } from 'aws-cdk-lib/aws-bedrockagentcore';
204
+ import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
205
+
206
+ const myAgent = new MyAgent(this, 'MyAgent', {
207
+ identity,
208
+ // Let the runtime receive the forwarded Authorization header.
209
+ requestHeaderConfiguration: { allowlistedHeaders: ['Authorization'] },
210
+ });
211
+ const myGateway = new MyGateway(this, 'MyGateway', { identity });
212
+
213
+ const target = new CfnGatewayTarget(this, 'Target-my-agent', {
214
+ gatewayIdentifier: myGateway.gateway.gatewayId,
215
+ name: myAgent.agentName,
216
+ targetConfiguration: {
217
+ http: { agentcoreRuntime: { arn: myAgent.agentCoreRuntime.agentRuntimeArn } },
218
+ },
219
+ // Forward the caller's validated JWT to the runtime unchanged.
220
+ credentialProviderConfigurations: [
221
+ { credentialProviderType: 'JWT_PASSTHROUGH' },
222
+ ],
223
+ });
224
+
225
+ // The Gateway role still needs invoke access to the runtime.
226
+ myGateway.gateway.role.addToPrincipalPolicy(
227
+ new PolicyStatement({
228
+ actions: ['bedrock-agentcore:InvokeAgentRuntime'],
229
+ resources: [
230
+ myAgent.agentCoreRuntime.agentRuntimeArn,
231
+ `${myAgent.agentCoreRuntime.agentRuntimeArn}/*`,
232
+ ],
233
+ }),
234
+ );
235
+ ```
236
+ </Fragment>
237
+ <Fragment slot="terraform">
238
+ Add a `request_header_configuration` block to the runtime so it receives the header, and configure the target with the `JWT_PASSTHROUGH` credential provider (instead of `gateway_iam_role {}`):
239
+
240
+ ```hcl title="packages/infra/src/main.tf" {5-7,20-22}
241
+ # Let the runtime receive the forwarded Authorization header. Add this block
242
+ # to the runtime resource in the agent module (packages/common/terraform/...).
243
+ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
244
+ # ...
245
+ request_header_configuration {
246
+ request_header_allowlist = ["Authorization"]
247
+ }
248
+ }
249
+
250
+ resource "aws_bedrockagentcore_gateway_target" "my_agent" {
251
+ gateway_identifier = module.my_gateway.gateway_id
252
+ name = "my-agent"
253
+ description = "Agent runtime target my-agent"
254
+
255
+ target_configuration {
256
+ http {
257
+ agentcore_runtime {
258
+ arn = module.my_agent.agent_core_runtime_arn
259
+ }
260
+ }
261
+ }
262
+
263
+ # Forward the caller's validated JWT to the runtime unchanged.
264
+ credential_provider_configuration {
265
+ credential_provider_type = "JWT_PASSTHROUGH"
266
+ }
267
+ }
268
+ ```
269
+ </Fragment>
270
+ </Infrastructure>
271
+
272
+ :::note
273
+ `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.
274
+ :::
275
+
276
+ ## Local Development
277
+
278
+ Running the Gateway locally with:
279
+
280
+ <NxCommands commands={["dev <gateway-name>"]} />
281
+
282
+ 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.
@@ -58,7 +58,7 @@ The generator **cannot** automatically wire the gateway target into your infrast
58
58
  <Fragment slot="cdk">
59
59
  In the stack where you instantiate the Gateways, register the target gateway as a target of the source gateway:
60
60
 
61
- ```ts title="packages/infra/src/stacks/application-stack.ts" {5-6}
61
+ ```ts title="packages/infra/src/stacks/application-stack.ts" {4-7}
62
62
  const innerGateway = new InnerGateway(this, 'InnerGateway');
63
63
  const outerGateway = new OuterGateway(this, 'OuterGateway');
64
64
 
@@ -81,7 +81,7 @@ The construct grants the source gateway's execution role `bedrock-agentcore:Invo
81
81
  <Fragment slot="terraform">
82
82
  In the Terraform file where you instantiate the Gateways, wire the gateway target in:
83
83
 
84
- ```hcl title="packages/infra/src/main.tf" {2-5,11-15,18-36}
84
+ ```hcl title="packages/infra/src/main.tf" {4-6,11,13-19,22-40}
85
85
  module "inner_gateway" {
86
86
  source = "../../common/terraform/src/app/gateways/inner-gateway"
87
87
 
@@ -61,7 +61,7 @@ The generator **cannot** automatically wire the MCP server target into your infr
61
61
  <Fragment slot="cdk">
62
62
  In the stack where you instantiate the Gateway, register the MCP server as a target:
63
63
 
64
- ```ts title="packages/infra/src/stacks/application-stack.ts" {5-6}
64
+ ```ts title="packages/infra/src/stacks/application-stack.ts" {4-7}
65
65
  const myMcpServer = new MyMcpServer(this, 'MyMcpServer');
66
66
  const myGateway = new MyGateway(this, 'MyGateway');
67
67
 
@@ -84,7 +84,7 @@ The construct configures the target with `iamCredentialProvider.service = 'bedro
84
84
  <Fragment slot="terraform">
85
85
  In the Terraform file where you instantiate the Gateway, wire the MCP server target in:
86
86
 
87
- ```hcl title="packages/infra/src/main.tf" {7,11-27}
87
+ ```hcl title="packages/infra/src/main.tf" {7,10-28}
88
88
  module "my_mcp_server" {
89
89
  source = "../../common/terraform/src/app/mcp-servers/my-mcp-server"
90
90
  }
@@ -92,7 +92,7 @@ def get_agent():
92
92
  ```
93
93
  </TabItem>
94
94
  <TabItem label="LangChain" _filter={{ framework: 'langchain' }}>
95
- ```python title="packages/my-project/my_module/agent/agent.py" {4,7-12,14}
95
+ ```python title="packages/my-project/my_module/agent/agent.py" {5,8-13,15}
96
96
  from langchain.agents import create_agent
97
97
  from langchain_aws import ChatBedrockConverse
98
98
  from langchain_core.tools import tool
@@ -91,7 +91,7 @@ def get_agent():
91
91
  `MyGatewayClientStrands.create()` returns a single context-manageable `MCPClient` whose `list_tools_sync()` yields every tool available through the Gateway.
92
92
  </TabItem>
93
93
  <TabItem label="LangChain" _filter={{ framework: 'langchain' }}>
94
- ```python title="packages/example/example/my_agent/agent.py" {4,8,12}
94
+ ```python title="packages/example/example/my_agent/agent.py" {4,7,11}
95
95
  from langchain.agents import create_agent
96
96
  from langchain_aws import ChatBedrockConverse
97
97
 
@@ -134,7 +134,7 @@ gateway.grantInvokeAccess(myAgent);
134
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
135
  </Fragment>
136
136
  <Fragment slot="terraform">
137
- ```hcl title="packages/infra/src/main.tf" {6-13}
137
+ ```hcl title="packages/infra/src/main.tf" {8-13}
138
138
  module "my_gateway" {
139
139
  source = "../../common/terraform/src/app/gateways/my-gateway"
140
140
  }
@@ -70,7 +70,7 @@ The generator transforms your agent's `agent.py` to use the MCP server's tools:
70
70
 
71
71
  <Tabs syncKey="agent-framework">
72
72
  <TabItem label="Strands" _filter={{ framework: 'strands' }}>
73
- ```python title="packages/my-project/my_module/agent/agent.py" {4,9-13}
73
+ ```python title="packages/my-project/my_module/agent/agent.py" {4,8,9-13}
74
74
  from contextlib import contextmanager
75
75
  from strands import Agent
76
76
 
@@ -91,7 +91,7 @@ def get_agent():
91
91
  The Strands client is a context manager, entered in a `with` block around the agent.
92
92
  </TabItem>
93
93
  <TabItem label="LangChain" _filter={{ framework: 'langchain' }}>
94
- ```python title="packages/my-project/my_module/agent/agent.py" {4,8,13}
94
+ ```python title="packages/my-project/my_module/agent/agent.py" {4,7,11}
95
95
  from langchain.agents import create_agent
96
96
  from langchain_aws import ChatBedrockConverse
97
97
 
@@ -131,7 +131,7 @@ The MCP server's AgentCore runtime ARN is automatically registered in the `agent
131
131
  <Fragment slot="terraform">
132
132
  After running the connection generator, you need to grant the agent permission to invoke the MCP server in your Terraform configuration:
133
133
 
134
- ```hcl title="packages/infra/src/main.tf" {12-24}
134
+ ```hcl title="packages/infra/src/main.tf" {9-25}
135
135
  module "inventory_mcp_server" {
136
136
  source = "../../common/terraform/src/app/mcp-servers/inventory-mcp"
137
137
  }