@aws/nx-plugin-mcp 1.0.0 → 1.0.1
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 +17 -9
- package/docs/get_started/existing-project.mdx +1 -1
- package/docs/get_started/quick-start.mdx +38 -54
- package/docs/get_started/tutorials/contribute-generator.mdx +5 -5
- package/docs/get_started/tutorials/dungeon-game/1.mdx +17 -17
- package/docs/get_started/tutorials/dungeon-game/overview.mdx +4 -70
- package/docs/guides/agentcore-gateway.mdx +2 -26
- package/docs/guides/connection/agentcore-gateway-agent.mdx +1 -1
- package/docs/guides/connection/py-agent-a2a.mdx +2 -2
- package/docs/guides/connection/py-agent-gateway.mdx +1 -1
- package/docs/guides/connection/py-agent-mcp.mdx +1 -1
- package/docs/guides/connection/react-trpc.mdx +1 -1
- package/docs/guides/connection/react-ts-agent.mdx +1 -1
- package/docs/guides/open-api-py-client.mdx +270 -0
- package/docs/guides/py-dynamodb.mdx +7 -0
- package/docs/guides/react-website-auth.mdx +3 -33
- package/docs/guides/react-website.mdx +3 -28
- package/docs/guides/runtime-config.mdx +2 -34
- package/docs/guides/terraform-project.mdx +1 -1
- package/docs/guides/ts-dynamodb.mdx +7 -0
- package/docs/guides/ts-smithy-api.mdx +8 -47
- package/docs/guides/typescript-project.mdx +2 -2
- package/docs/guides/workspace.mdx +7 -10
- package/docs/snippets/agent/architecture.mdx +9 -52
- package/docs/snippets/agent/bedrock-deployment.mdx +1 -1
- package/docs/snippets/agent/runtime-arn.mdx +1 -1
- package/docs/snippets/api/access-logging.mdx +1 -1
- package/docs/snippets/api/api-architecture.mdx +4 -75
- package/docs/snippets/api/type-safe-api-integrations.mdx +2 -4
- package/docs/snippets/lambda-function/architecture.mdx +3 -29
- package/docs/snippets/mcp/architecture.mdx +9 -38
- package/docs/snippets/mcp/bedrock-deployment.mdx +1 -1
- package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +1 -1
- package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +5 -6
- package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +1 -1
- package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +2 -2
- package/docs/snippets/rdb/architecture.mdx +2 -33
- package/generators.json +7 -0
- package/package.json +1 -1
- package/src/agentcore-gateway/schema.json +1 -0
- package/src/open-api/py-client/schema.json +28 -0
- package/src/py/agent/schema.json +2 -0
- package/src/py/mcp-server/schema.json +1 -0
- package/src/ts/agent/schema.json +1 -0
- package/src/ts/api/schema.json +2 -0
- package/src/ts/mcp-server/schema.json +1 -0
- package/src/ts/react-website/app/schema.json +1 -0
- package/src/ts/website/app/schema.json +1 -0
package/bin/aws-nx-mcp.js
CHANGED
|
@@ -21942,14 +21942,14 @@ const NX_VERSION = {
|
|
|
21942
21942
|
"@middy/core": "7.9.2",
|
|
21943
21943
|
"@nxlv/python": "23.0.0",
|
|
21944
21944
|
"@nx-extend/terraform": "10.4.1",
|
|
21945
|
-
nx: "23.2.
|
|
21946
|
-
"@nx/devkit": "23.2.
|
|
21947
|
-
"@nx/js": "23.2.
|
|
21948
|
-
"@nx/react": "23.2.
|
|
21949
|
-
"@nx/vite": "23.2.
|
|
21950
|
-
"@nx/vitest": "23.2.
|
|
21951
|
-
"@nx/workspace": "23.2.
|
|
21952
|
-
"create-nx-workspace": "23.2.
|
|
21945
|
+
nx: "23.2.1",
|
|
21946
|
+
"@nx/devkit": "23.2.1",
|
|
21947
|
+
"@nx/js": "23.2.1",
|
|
21948
|
+
"@nx/react": "23.2.1",
|
|
21949
|
+
"@nx/vite": "23.2.1",
|
|
21950
|
+
"@nx/vitest": "23.2.1",
|
|
21951
|
+
"@nx/workspace": "23.2.1",
|
|
21952
|
+
"create-nx-workspace": "23.2.1",
|
|
21953
21953
|
"@swc-node/register": "1.12.1",
|
|
21954
21954
|
"@swc/core": "1.16.1",
|
|
21955
21955
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
@@ -54646,6 +54646,7 @@ const renderComponent = (node, opts, pm, deps) => {
|
|
|
54646
54646
|
if (!commands) return void 0;
|
|
54647
54647
|
return [codeBlock(commands.map((c) => buildPackageManagerExecCommand(pm, c)).join("\n"))];
|
|
54648
54648
|
}
|
|
54649
|
+
case "ArchitectureDiagram": return [];
|
|
54649
54650
|
default: return;
|
|
54650
54651
|
}
|
|
54651
54652
|
};
|
|
@@ -54694,7 +54695,7 @@ const filterableValuesForProperty = (prop) => {
|
|
|
54694
54695
|
/**
|
|
54695
54696
|
* Pull out every filterable property (enum or boolean valued) as a
|
|
54696
54697
|
* `FilterableOption`. Shared between the MCP server (deriving options from a
|
|
54697
|
-
* generator's schema) and the docs
|
|
54698
|
+
* generator's schema) and the docs site (mapping user-referenced keys
|
|
54698
54699
|
* onto their values).
|
|
54699
54700
|
*/
|
|
54700
54701
|
const filterableOptionsFromSchema = (schema) => {
|
|
@@ -55424,6 +55425,13 @@ const generatorsJsonEntries = {
|
|
|
55424
55425
|
"metric": "g15",
|
|
55425
55426
|
"hidden": true
|
|
55426
55427
|
},
|
|
55428
|
+
"open-api#py-client": {
|
|
55429
|
+
"factory": "./src/open-api/py-client/generator",
|
|
55430
|
+
"schema": "./src/open-api/py-client/schema.json",
|
|
55431
|
+
"description": "Generate a Python httpx client from an OpenAPI specification",
|
|
55432
|
+
"metric": "g73",
|
|
55433
|
+
"hidden": true
|
|
55434
|
+
},
|
|
55427
55435
|
"open-api#ts-client": {
|
|
55428
55436
|
"factory": "./src/open-api/ts-client/generator",
|
|
55429
55437
|
"schema": "./src/open-api/ts-client/schema.json",
|
|
@@ -13,7 +13,6 @@ import RunGenerator from '@components/run-generator.astro';
|
|
|
13
13
|
import NxCommands from '@components/nx-commands.astro';
|
|
14
14
|
import Infrastructure from '@components/infrastructure.astro';
|
|
15
15
|
import EmbeddedGraph from '@components/embedded-graph.astro';
|
|
16
|
-
import Diff from '@components/diff.astro';
|
|
17
16
|
import Prompt from '@components/prompt.astro';
|
|
18
17
|
|
|
19
18
|
This guide walks you through the basics of installing and using `@aws/nx-plugin` to rapidly build projects on AWS.
|
|
@@ -28,13 +27,13 @@ The following global dependencies are needed before proceeding:
|
|
|
28
27
|
|
|
29
28
|
Create an <Link path="guides/workspace">Nx workspace</Link> with the package manager of your choice, and open the directory it creates:
|
|
30
29
|
|
|
31
|
-
<CreateNxWorkspaceCommand workspace="my-project" />
|
|
30
|
+
<CreateNxWorkspaceCommand workspace="my-project" readonly editable={['iac', 'containers']} />
|
|
32
31
|
|
|
33
32
|
```sh
|
|
34
33
|
cd my-project
|
|
35
34
|
```
|
|
36
35
|
|
|
37
|
-
You are prompted to choose your infrastructure as code provider, either [CDK](https://docs.aws.amazon.com/cdk/) or [Terraform](https://developer.hashicorp.com/terraform)
|
|
36
|
+
You are prompted to choose your infrastructure as code provider, either [CDK](https://docs.aws.amazon.com/cdk/) or [Terraform](https://developer.hashicorp.com/terraform).
|
|
38
37
|
|
|
39
38
|
## Step 2: Build Your Application
|
|
40
39
|
|
|
@@ -73,25 +72,25 @@ Depending on the type of project you're building, you can choose any combination
|
|
|
73
72
|
|
|
74
73
|
#### Add a tRPC API
|
|
75
74
|
|
|
76
|
-
<RunGenerator generator="ts#api" requiredParameters={{ name: 'demo-api', framework: 'trpc' }} positional={['name']} noInteractive />
|
|
75
|
+
<RunGenerator generator="ts#api" requiredParameters={{ name: 'demo-api', framework: 'trpc' }} positional={['name']} noInteractive readonly />
|
|
77
76
|
|
|
78
77
|
This will create the API inside the `packages/demo-api` folder.
|
|
79
78
|
|
|
80
79
|
#### Add a React Website
|
|
81
80
|
|
|
82
|
-
<RunGenerator generator="ts#website" requiredParameters={{ name: 'demo-website' }} positional={['name']} noInteractive />
|
|
81
|
+
<RunGenerator generator="ts#website" requiredParameters={{ name: 'demo-website' }} positional={['name']} noInteractive readonly />
|
|
83
82
|
|
|
84
83
|
This scaffolds a new React website in `packages/demo-website`.
|
|
85
84
|
|
|
86
85
|
#### Add Cognito Authentication
|
|
87
86
|
|
|
88
|
-
<RunGenerator generator="ts#website#auth" requiredParameters={{ project: 'demo-website' }} noInteractive />
|
|
87
|
+
<RunGenerator generator="ts#website#auth" requiredParameters={{ project: 'demo-website' }} noInteractive readonly />
|
|
89
88
|
|
|
90
89
|
This sets up the necessary infrastructure and React code to add Cognito Authentication to your website.
|
|
91
90
|
|
|
92
91
|
#### Connect Frontend to Backend
|
|
93
92
|
|
|
94
|
-
<RunGenerator generator="connection" requiredParameters={{ sourceProject: 'demo-website', targetProject: 'demo-api' }} noInteractive />
|
|
93
|
+
<RunGenerator generator="connection" requiredParameters={{ sourceProject: 'demo-website', targetProject: 'demo-api' }} noInteractive readonly />
|
|
95
94
|
|
|
96
95
|
This configures the necessary providers to ensure your website can call your tRPC API.
|
|
97
96
|
|
|
@@ -101,12 +100,12 @@ Add the infrastructure project based on your chosen IAC provider.
|
|
|
101
100
|
|
|
102
101
|
<Infrastructure>
|
|
103
102
|
<Fragment slot="cdk">
|
|
104
|
-
<RunGenerator generator="ts#infra" requiredParameters={{ name: 'infra' }} positional={['name']} noInteractive />
|
|
103
|
+
<RunGenerator generator="ts#infra" requiredParameters={{ name: 'infra' }} positional={['name']} noInteractive readonly />
|
|
105
104
|
|
|
106
105
|
This configures a CDK App which you can use to deploy your infrastructure on AWS.
|
|
107
106
|
</Fragment>
|
|
108
107
|
<Fragment slot="terraform">
|
|
109
|
-
<RunGenerator generator="terraform#project" requiredParameters={{ name: 'infra' }} positional={['name']} noInteractive />
|
|
108
|
+
<RunGenerator generator="terraform#project" requiredParameters={{ name: 'infra' }} positional={['name']} noInteractive readonly />
|
|
110
109
|
|
|
111
110
|
This configures a Terraform project which you can use to deploy your infrastructure on AWS.
|
|
112
111
|
</Fragment>
|
|
@@ -128,54 +127,39 @@ Connecting the website to the API added a `useDemoApi` hook, which returns a [tR
|
|
|
128
127
|
|
|
129
128
|
Update `packages/demo-website/src/routes/index.tsx` to call the API's `echo` procedure, showing a spinner while the request is in flight:
|
|
130
129
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
export const Route = createFileRoute('/')({
|
|
134
|
-
component: RouteComponent,
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
function RouteComponent() {
|
|
138
|
-
return (
|
|
139
|
-
<div className="text-center">
|
|
140
|
-
<header>
|
|
141
|
-
<h1>Welcome</h1>
|
|
142
|
-
<p>Welcome to your new React website!</p>
|
|
143
|
-
</header>
|
|
144
|
-
</div>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
`} after={`import { useQuery } from '@tanstack/react-query';
|
|
130
|
+
```diff lang="tsx"
|
|
131
|
+
+import { useQuery } from '@tanstack/react-query';
|
|
148
132
|
import { createFileRoute } from '@tanstack/react-router';
|
|
149
|
-
import { Spinner } from '../components/spinner';
|
|
150
|
-
import { useDemoApi } from '../hooks/useDemoApi';
|
|
133
|
+
+import { Spinner } from '../components/spinner';
|
|
134
|
+
+import { useDemoApi } from '../hooks/useDemoApi';
|
|
151
135
|
|
|
152
136
|
export const Route = createFileRoute('/')({
|
|
153
137
|
component: RouteComponent,
|
|
154
138
|
});
|
|
155
139
|
|
|
156
140
|
function RouteComponent() {
|
|
157
|
-
const trpc = useDemoApi();
|
|
158
|
-
const echo = useQuery(
|
|
159
|
-
trpc.echo.queryOptions({ message: 'Hello from the API!' }),
|
|
160
|
-
);
|
|
161
|
-
|
|
141
|
+
+ const trpc = useDemoApi();
|
|
142
|
+
+ const echo = useQuery(
|
|
143
|
+
+ trpc.echo.queryOptions({ message: 'Hello from the API!' }),
|
|
144
|
+
+ );
|
|
145
|
+
+
|
|
162
146
|
return (
|
|
163
147
|
<div className="text-center">
|
|
164
148
|
<header>
|
|
165
149
|
<h1>Welcome</h1>
|
|
166
150
|
<p>Welcome to your new React website!</p>
|
|
167
151
|
</header>
|
|
168
|
-
{echo.isLoading ? (
|
|
169
|
-
<Spinner />
|
|
170
|
-
) : echo.error ? (
|
|
171
|
-
<p>Error: {echo.error.message}</p>
|
|
172
|
-
) : (
|
|
173
|
-
<p>{echo.data?.message}</p>
|
|
174
|
-
)}
|
|
152
|
+
+ {echo.isLoading ? (
|
|
153
|
+
+ <Spinner />
|
|
154
|
+
+ ) : echo.error ? (
|
|
155
|
+
+ <p>Error: {echo.error.message}</p>
|
|
156
|
+
+ ) : (
|
|
157
|
+
+ <p>{echo.data?.message}</p>
|
|
158
|
+
+ )}
|
|
175
159
|
</div>
|
|
176
160
|
);
|
|
177
161
|
}
|
|
178
|
-
|
|
162
|
+
```
|
|
179
163
|
|
|
180
164
|
Save the file and the page reloads with the message your API echoed back. The call is type-safe end to end — rename `message` in `packages/demo-api/src/schema/echo.ts` and your website stops compiling until you follow the change through.
|
|
181
165
|
|
|
@@ -189,12 +173,12 @@ See the <Link path="guides/connection/react-trpc">React to tRPC connection guide
|
|
|
189
173
|
<Fragment slot="cdk">
|
|
190
174
|
Open `packages/infra/src/stacks/application-stack.ts` and add the following code:
|
|
191
175
|
|
|
192
|
-
```
|
|
193
|
-
import {
|
|
194
|
-
DemoApi,
|
|
195
|
-
DemoWebsite,
|
|
196
|
-
UserIdentity,
|
|
197
|
-
} from '@my-project/common-constructs';
|
|
176
|
+
```diff lang="ts"
|
|
177
|
+
+import {
|
|
178
|
+
+ DemoApi,
|
|
179
|
+
+ DemoWebsite,
|
|
180
|
+
+ UserIdentity,
|
|
181
|
+
+} from '@my-project/common-constructs';
|
|
198
182
|
import { Stack, StackProps } from 'aws-cdk-lib';
|
|
199
183
|
import { Construct } from 'constructs';
|
|
200
184
|
|
|
@@ -202,13 +186,13 @@ export class ApplicationStack extends Stack {
|
|
|
202
186
|
constructor(scope: Construct, id: string, props?: StackProps) {
|
|
203
187
|
super(scope, id, props);
|
|
204
188
|
|
|
205
|
-
const identity = new UserIdentity(this, 'identity');
|
|
206
|
-
const api = new DemoApi(this, 'api', {
|
|
207
|
-
integrations: DemoApi.defaultIntegrations(this).build(),
|
|
208
|
-
});
|
|
209
|
-
api.grantInvokeAccess(identity.identityPool.authenticatedRole);
|
|
210
|
-
|
|
211
|
-
new DemoWebsite(this, 'website');
|
|
189
|
+
+ const identity = new UserIdentity(this, 'identity');
|
|
190
|
+
+ const api = new DemoApi(this, 'api', {
|
|
191
|
+
+ integrations: DemoApi.defaultIntegrations(this).build(),
|
|
192
|
+
+ });
|
|
193
|
+
+ api.grantInvokeAccess(identity.identityPool.authenticatedRole);
|
|
194
|
+
+
|
|
195
|
+
+ new DemoWebsite(this, 'website');
|
|
212
196
|
}
|
|
213
197
|
}
|
|
214
198
|
```
|
|
@@ -54,7 +54,7 @@ Let's create the new generator in `packages/nx-plugin/src/trpc/procedure`.
|
|
|
54
54
|
|
|
55
55
|
We provide a generator for creating new generators so you can quickly scaffold your new generator! You can run this generator as follows:
|
|
56
56
|
|
|
57
|
-
<RunGenerator generator="ts#nx-generator" requiredParameters={{ project: '@aws/nx-plugin', name: 'ts#trpc-api#procedure', directory: 'trpc/procedure', description: 'Adds a procedure to a tRPC API' }} />
|
|
57
|
+
<RunGenerator generator="ts#nx-generator" requiredParameters={{ project: '@aws/nx-plugin', name: 'ts#trpc-api#procedure', directory: 'trpc/procedure', description: 'Adds a procedure to a tRPC API' }} readonly />
|
|
58
58
|
|
|
59
59
|
You will notice the following files have been generated for you:
|
|
60
60
|
|
|
@@ -313,11 +313,11 @@ If you have completed the <Link path="get_started/tutorials/dungeon-game/overvie
|
|
|
313
313
|
|
|
314
314
|
In a separate directory, create a new test workspace:
|
|
315
315
|
|
|
316
|
-
<CreateNxWorkspaceCommand workspace="trpc-generator-test" />
|
|
316
|
+
<CreateNxWorkspaceCommand workspace="trpc-generator-test" readonly />
|
|
317
317
|
|
|
318
318
|
Next, let's generate a tRPC API to add the procedure to:
|
|
319
319
|
|
|
320
|
-
<RunGenerator generator="ts#api" requiredParameters={{name:"test-api", framework:"trpc"}} noInteractive />
|
|
320
|
+
<RunGenerator generator="ts#api" requiredParameters={{name:"test-api", framework:"trpc"}} noInteractive readonly />
|
|
321
321
|
|
|
322
322
|
#### Link our local Nx Plugin for AWS
|
|
323
323
|
|
|
@@ -337,7 +337,7 @@ Notice above we linked to the compiled plugin in `dist/packages/nx-plugin` rathe
|
|
|
337
337
|
|
|
338
338
|
Let's try the new generator:
|
|
339
339
|
|
|
340
|
-
<RunGenerator generator="ts#trpc-api#procedure" />
|
|
340
|
+
<RunGenerator generator="ts#trpc-api#procedure" readonly />
|
|
341
341
|
|
|
342
342
|
:::note[Generator Not Showing]
|
|
343
343
|
If you don't see the new generator in the list in VSCode, you might need to refresh the Nx workspace:
|
|
@@ -397,7 +397,7 @@ In practice, this process might look like:
|
|
|
397
397
|
|
|
398
398
|
1. Create a new workspace
|
|
399
399
|
|
|
400
|
-
<CreateNxWorkspaceCommand workspace="my-project" />
|
|
400
|
+
<CreateNxWorkspaceCommand workspace="my-project" readonly />
|
|
401
401
|
|
|
402
402
|
1. Run any generators that may be prerequisites to your new generator/feature/fix
|
|
403
403
|
1. Commit your changes (`git commit`)
|
|
@@ -26,7 +26,7 @@ import gameConversationPng from '@assets/game-conversation.png'
|
|
|
26
26
|
|
|
27
27
|
To create a new monorepo, from within your desired directory, run the following command:
|
|
28
28
|
|
|
29
|
-
<CreateNxWorkspaceCommand workspace="dungeon-adventure" iac="cdk" />
|
|
29
|
+
<CreateNxWorkspaceCommand workspace="dungeon-adventure" iac="cdk" readonly />
|
|
30
30
|
|
|
31
31
|
:::note[CDK as IaC Provider]
|
|
32
32
|
We use `--iac=cdk` as we will use CDK for infrastructure as code in this tutorial. The Nx Plugin for AWS also supports `terraform`.
|
|
@@ -72,7 +72,7 @@ Rather than copying the commands all at once, you can run each generator individ
|
|
|
72
72
|
|
|
73
73
|
First, let's create our Game API. To do this, create a tRPC API called `GameApi` using these steps:
|
|
74
74
|
|
|
75
|
-
<RunGenerator generator="ts#api" requiredParameters={{ name: "GameApi", framework: "trpc" }} noInteractive />
|
|
75
|
+
<RunGenerator generator="ts#api" requiredParameters={{ name: "GameApi", framework: "trpc" }} noInteractive readonly />
|
|
76
76
|
|
|
77
77
|
<br />
|
|
78
78
|
|
|
@@ -137,7 +137,7 @@ Below is a list of all files which have been generated by the `ts#api` generator
|
|
|
137
137
|
|
|
138
138
|
Let us look at these key files:
|
|
139
139
|
|
|
140
|
-
```ts {
|
|
140
|
+
```ts {8}
|
|
141
141
|
// packages/game-api/src/router.ts
|
|
142
142
|
import { echo } from './procedures/echo.js';
|
|
143
143
|
import { t } from './init.js';
|
|
@@ -152,7 +152,7 @@ export type AppRouter = typeof appRouter;
|
|
|
152
152
|
```
|
|
153
153
|
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.
|
|
154
154
|
|
|
155
|
-
```ts {
|
|
155
|
+
```ts {5-7}
|
|
156
156
|
// packages/game-api/src/procedures/echo.ts
|
|
157
157
|
import { publicProcedure } from '../init.js';
|
|
158
158
|
import { EchoInputSchema, EchoOutputSchema } from '../schema/index.js';
|
|
@@ -403,7 +403,7 @@ Now let's create our Story Agent.
|
|
|
403
403
|
|
|
404
404
|
To create a Python project:
|
|
405
405
|
|
|
406
|
-
<RunGenerator generator="py#project" requiredParameters={{name:"story"}} noInteractive />
|
|
406
|
+
<RunGenerator generator="py#project" requiredParameters={{name:"story"}} noInteractive readonly />
|
|
407
407
|
|
|
408
408
|
You will see some new files appear in your file tree.
|
|
409
409
|
<details>
|
|
@@ -433,7 +433,7 @@ This has configured a Python project and [UV Workspace](https://docs.astral.sh/u
|
|
|
433
433
|
|
|
434
434
|
To add a Strands agent to the project with the `py#agent` generator:
|
|
435
435
|
|
|
436
|
-
<RunGenerator generator="py#agent" requiredParameters={{project:"story", auth:"cognito", protocol:"ag-ui"}} noInteractive />
|
|
436
|
+
<RunGenerator generator="py#agent" requiredParameters={{project:"story", auth:"cognito", protocol:"ag-ui"}} noInteractive readonly />
|
|
437
437
|
|
|
438
438
|
:::note[AG-UI protocol]
|
|
439
439
|
We choose `--protocol=ag-ui` so the agent speaks the [Agent-User Interaction protocol](https://docs.copilotkit.ai/aws-strands/protocol) — this lets our React website talk to it directly via [CopilotKit](https://docs.copilotkit.ai/), with streaming, tool calls, and conversation history handled by the protocol instead of a hand-rolled HTTP client.
|
|
@@ -916,7 +916,7 @@ Let us create an MCP server to provide tools for our Story Agent to manage a pla
|
|
|
916
916
|
|
|
917
917
|
First, we create a TypeScript project:
|
|
918
918
|
|
|
919
|
-
<RunGenerator generator="ts#project" requiredParameters={{name:"inventory"}} noInteractive />
|
|
919
|
+
<RunGenerator generator="ts#project" requiredParameters={{name:"inventory"}} noInteractive readonly />
|
|
920
920
|
|
|
921
921
|
This will create an empty TypeScript project.
|
|
922
922
|
|
|
@@ -944,7 +944,7 @@ The `ts#project` generator generates these files.
|
|
|
944
944
|
|
|
945
945
|
Next, we'll add an MCP server to our TypeScript project:
|
|
946
946
|
|
|
947
|
-
<RunGenerator generator="ts#mcp-server" requiredParameters={{project:"inventory"}} noInteractive />
|
|
947
|
+
<RunGenerator generator="ts#mcp-server" requiredParameters={{project:"inventory"}} noInteractive readonly />
|
|
948
948
|
|
|
949
949
|
This will add an MCP server.
|
|
950
950
|
<details>
|
|
@@ -977,7 +977,7 @@ The `ts#mcp-server` generator generates these files.
|
|
|
977
977
|
|
|
978
978
|
Our game state — saved games and each player's inventory — lives in [Amazon DynamoDB](https://aws.amazon.com/dynamodb/). Create a DynamoDB project called `DungeonDb` with the `ts#dynamodb` generator:
|
|
979
979
|
|
|
980
|
-
<RunGenerator generator="ts#dynamodb" requiredParameters={{name:"DungeonDb"}} noInteractive />
|
|
980
|
+
<RunGenerator generator="ts#dynamodb" requiredParameters={{name:"DungeonDb"}} noInteractive readonly />
|
|
981
981
|
|
|
982
982
|
:::tip[Local-first development]
|
|
983
983
|
The `ts#dynamodb` generator vends a `dev` target that runs [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html) in a container. Combined with the `connection` generator (which we run below), this means **the entire game runs on your machine without a deployment** until the end of the tutorial.
|
|
@@ -1029,7 +1029,7 @@ Next, we will create the UI which will allow you to interact with the game.
|
|
|
1029
1029
|
|
|
1030
1030
|
To create the UI, create a website called `GameUI` using these steps:
|
|
1031
1031
|
|
|
1032
|
-
<RunGenerator generator="ts#website" requiredParameters={{name:"GameUI", ux:"shadcn"}} noInteractive />
|
|
1032
|
+
<RunGenerator generator="ts#website" requiredParameters={{name:"GameUI", ux:"shadcn"}} noInteractive readonly />
|
|
1033
1033
|
|
|
1034
1034
|
:::note[Shadcn UI]
|
|
1035
1035
|
We select `--ux=shadcn` so the generated website uses [shadcn/ui](https://ui.shadcn.com/) components styled with Tailwind — all our route code uses shadcn primitives like `Card`, `Button`, and `Input`, and the `connection` generator later wires a matching shadcn-themed [CopilotKit](https://docs.copilotkit.ai/) chat surface.
|
|
@@ -1166,7 +1166,7 @@ A component will be rendered when navigating to the `/` route. `@tanstack/react-
|
|
|
1166
1166
|
|
|
1167
1167
|
Let us configure our Game UI to require authenticated access via Amazon Cognito using these steps:
|
|
1168
1168
|
|
|
1169
|
-
<RunGenerator generator="ts#website#auth" requiredParameters={{cognitoDomain:"game-ui", project:"@dungeon-adventure/game-ui", allowSignup:true}} noInteractive />
|
|
1169
|
+
<RunGenerator generator="ts#website#auth" requiredParameters={{cognitoDomain:"game-ui", project:"@dungeon-adventure/game-ui", allowSignup:true}} noInteractive readonly />
|
|
1170
1170
|
|
|
1171
1171
|
You will see some new files appear/change in your file tree.
|
|
1172
1172
|
|
|
@@ -1250,7 +1250,7 @@ The `RuntimeConfigProvider` and `CognitoAuth` components have been added to the
|
|
|
1250
1250
|
|
|
1251
1251
|
Let us configure our Game UI to connect to our previously created Game API.
|
|
1252
1252
|
|
|
1253
|
-
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/game-ui", targetProject:"@dungeon-adventure/game-api"}} noInteractive />
|
|
1253
|
+
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/game-ui", targetProject:"@dungeon-adventure/game-api"}} noInteractive readonly />
|
|
1254
1254
|
|
|
1255
1255
|
You will see some new files have appear/change in your file tree.
|
|
1256
1256
|
|
|
@@ -1344,7 +1344,7 @@ The `main.tsx` file has been updated via an AST transform to inject the tRPC pro
|
|
|
1344
1344
|
|
|
1345
1345
|
Let us connect our Story Agent to the Inventory MCP server so the agent can discover and invoke the MCP server's tools.
|
|
1346
1346
|
|
|
1347
|
-
<RunGenerator generator="connection" requiredParameters={{sourceProject:"story", targetProject:"inventory"}} noInteractive />
|
|
1347
|
+
<RunGenerator generator="connection" requiredParameters={{sourceProject:"story", targetProject:"inventory"}} noInteractive readonly />
|
|
1348
1348
|
|
|
1349
1349
|
<details>
|
|
1350
1350
|
<summary>Examine the Story Agent → Inventory MCP connection files</summary>
|
|
@@ -1384,7 +1384,7 @@ For more details, refer to the <Link path="guides/connection/py-agent-mcp">Pytho
|
|
|
1384
1384
|
|
|
1385
1385
|
Let us connect our Game UI to the Story Agent. Since the agent speaks AG-UI, the `connection` generator wires up [CopilotKit](https://docs.copilotkit.ai/): a themed chat component and an `@ag-ui/client` `HttpAgent` ready to render.
|
|
1386
1386
|
|
|
1387
|
-
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/game-ui", targetProject:"story"}} noInteractive />
|
|
1387
|
+
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/game-ui", targetProject:"story"}} noInteractive readonly />
|
|
1388
1388
|
|
|
1389
1389
|
<details>
|
|
1390
1390
|
<summary>Examine the UI → Story Agent connection files</summary>
|
|
@@ -1419,9 +1419,9 @@ For more details, refer to the <Link path="guides/connection/react-agui">React t
|
|
|
1419
1419
|
|
|
1420
1420
|
Both the Game API and the Inventory MCP server read and write our DynamoDB table, so let us connect them to the `DungeonDb` project. The `connection` generator detects that the target is a `ts#dynamodb` project and wires each source project's `dev` target to start DynamoDB Local automatically.
|
|
1421
1421
|
|
|
1422
|
-
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/game-api", targetProject:"@dungeon-adventure/dungeon-db"}} noInteractive />
|
|
1422
|
+
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/game-api", targetProject:"@dungeon-adventure/dungeon-db"}} noInteractive readonly />
|
|
1423
1423
|
|
|
1424
|
-
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/inventory", targetProject:"@dungeon-adventure/dungeon-db"}} noInteractive />
|
|
1424
|
+
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/inventory", targetProject:"@dungeon-adventure/dungeon-db"}} noInteractive readonly />
|
|
1425
1425
|
|
|
1426
1426
|
<Aside type="tip" title="One command boots the whole stack locally">
|
|
1427
1427
|
Because the Story Agent's `agent-dev` already depends on the Inventory MCP server's `mcp-server-dev` (via the `story → inventory` connection above), and both the Game API and MCP server now depend on `dungeon-db:dev`, running any one project's `dev` target starts every dependency it needs in the right order.
|
|
@@ -1431,7 +1431,7 @@ Because the Story Agent's `agent-dev` already depends on the Inventory MCP serve
|
|
|
1431
1431
|
|
|
1432
1432
|
Let us create the final sub-project for the CDK infrastructure.
|
|
1433
1433
|
|
|
1434
|
-
<RunGenerator generator="ts#infra" requiredParameters={{name:"infra"}} noInteractive />
|
|
1434
|
+
<RunGenerator generator="ts#infra" requiredParameters={{name:"infra"}} noInteractive readonly />
|
|
1435
1435
|
|
|
1436
1436
|
You will see some new files have appear/change in your file tree.
|
|
1437
1437
|
|
|
@@ -16,6 +16,7 @@ import baselineGamePng from '@assets/baseline-game.png'
|
|
|
16
16
|
import nxGraphPng from '@assets/nx-graph.png'
|
|
17
17
|
import gameSelectPng from '@assets/game-select.png'
|
|
18
18
|
import gameConversationPng from '@assets/game-conversation.png'
|
|
19
|
+
import EmbeddedGraph from '@components/embedded-graph.astro';
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
Using this tutorial, you will build an Agentic AI-powered dungeon adventure game with `@aws/nx-plugin`. This tutorial does not assume any existing knowledge of the `@aws/nx-plugin` or related technologies.
|
|
@@ -51,76 +52,9 @@ The game interface will resemble something like this diagram:
|
|
|
51
52
|
|
|
52
53
|
### Application architecture
|
|
53
54
|
|
|
54
|
-
The Agentic AI-powered dungeon adventure game is built using the following architecture:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
direction: down
|
|
58
|
-
|
|
59
|
-
browser: Web Browser {
|
|
60
|
-
shape: image
|
|
61
|
-
icon: /nx-plugin-for-aws/icons/aws/client.svg
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
cognito: Cognito / IAM {
|
|
65
|
-
shape: image
|
|
66
|
-
icon: /nx-plugin-for-aws/icons/aws/cognito.svg
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
cloudfront: CloudFront {
|
|
70
|
-
shape: image
|
|
71
|
-
icon: /nx-plugin-for-aws/icons/aws/cloudfront.svg
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
s3: Static Assets\n(S3) {
|
|
75
|
-
shape: image
|
|
76
|
-
icon: /nx-plugin-for-aws/icons/aws/s3.svg
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
apigw: API Gateway\n(Game API) {
|
|
80
|
-
shape: image
|
|
81
|
-
icon: /nx-plugin-for-aws/icons/aws/api-gateway.svg
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
lambda: tRPC API\n(Lambda) {
|
|
85
|
-
shape: image
|
|
86
|
-
icon: /nx-plugin-for-aws/icons/aws/lambda.svg
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
story: Story Agent\n(AgentCore) {
|
|
90
|
-
shape: image
|
|
91
|
-
icon: /nx-plugin-for-aws/icons/aws/bedrock-agentcore-runtime.svg
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
mcp: Inventory MCP\n(AgentCore) {
|
|
95
|
-
shape: image
|
|
96
|
-
icon: /nx-plugin-for-aws/icons/aws/bedrock-agentcore-runtime.svg
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
ddb: Game State\n(DynamoDB) {
|
|
100
|
-
shape: image
|
|
101
|
-
icon: /nx-plugin-for-aws/icons/aws/dynamodb.svg
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
sessions: Story Sessions\n(S3) {
|
|
105
|
-
shape: image
|
|
106
|
-
icon: /nx-plugin-for-aws/icons/aws/s3.svg
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
browser -> cognito: Sign in
|
|
110
|
-
browser -> cloudfront
|
|
111
|
-
cloudfront -> s3
|
|
112
|
-
browser -> apigw
|
|
113
|
-
apigw -> lambda
|
|
114
|
-
lambda -> ddb
|
|
115
|
-
lambda -> sessions: Read transcripts
|
|
116
|
-
browser -> story: AG-UI stream
|
|
117
|
-
story -> sessions: Persist turns
|
|
118
|
-
story -> mcp: Tool calls
|
|
119
|
-
mcp -> ddb
|
|
120
|
-
ddb -> sessions: {
|
|
121
|
-
style.opacity: 0
|
|
122
|
-
}
|
|
123
|
-
```
|
|
55
|
+
The Agentic AI-powered dungeon adventure game is built using the following architecture — switch to **Projects** to see the workspace it is built from, which you scaffold in Module 1:
|
|
56
|
+
|
|
57
|
+
<EmbeddedGraph preset="dungeon-adventure" workspace="dungeon-adventure" iac="cdk" view="infrastructure" copyable={false} />
|
|
124
58
|
|
|
125
59
|
- React/Vite frontend website utilising:
|
|
126
60
|
- Amazon Cognito/Identity Pools for secure API calls.
|
|
@@ -14,6 +14,7 @@ import Snippet from '@components/snippet.astro';
|
|
|
14
14
|
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
|
+
import ArchitectureDiagram from '@components/architecture-diagram.astro';
|
|
17
18
|
|
|
18
19
|
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
|
|
|
@@ -89,32 +90,7 @@ The Gateway URL is automatically registered in the `agentcore.gateways.<ClassNam
|
|
|
89
90
|
|
|
90
91
|
The deployed Gateway has the following architecture, with an [AWS WAFv2](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html) Web ACL in front of the Gateway, which routes on to its downstream MCP server targets:
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
direction: right
|
|
94
|
-
|
|
95
|
-
client: Client {
|
|
96
|
-
shape: image
|
|
97
|
-
icon: /nx-plugin-for-aws/icons/aws/client.svg
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
waf: WAF {
|
|
101
|
-
shape: image
|
|
102
|
-
icon: /nx-plugin-for-aws/icons/aws/waf.svg
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
gateway: AgentCore Gateway\n(MCP, IAM or Cognito auth) {
|
|
106
|
-
shape: image
|
|
107
|
-
icon: /nx-plugin-for-aws/icons/aws/bedrock-agentcore-gateway.svg
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
targets: Downstream MCP Servers\n(Gateway targets) {
|
|
111
|
-
shape: rectangle
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
client -> waf
|
|
115
|
-
waf -> gateway
|
|
116
|
-
gateway -> targets
|
|
117
|
-
```
|
|
93
|
+
<ArchitectureDiagram />
|
|
118
94
|
|
|
119
95
|
## Authentication
|
|
120
96
|
|
|
@@ -108,7 +108,7 @@ AgentCore Runtime VPC deployments are only supported in certain availability zon
|
|
|
108
108
|
<Fragment slot="terraform">
|
|
109
109
|
In the Terraform file where you instantiate the Gateway, wire the agent target in:
|
|
110
110
|
|
|
111
|
-
```hcl title="packages/infra/src/main.tf" {9-
|
|
111
|
+
```hcl title="packages/infra/src/main.tf" {9-25,28-48}
|
|
112
112
|
module "my_agent" {
|
|
113
113
|
source = "../../common/terraform/src/app/agents/my-agent"
|
|
114
114
|
# ...
|
|
@@ -72,7 +72,7 @@ The generator transforms your agent's `agent.py` to wrap the remote A2A agent as
|
|
|
72
72
|
|
|
73
73
|
<Tabs syncKey="agent-framework">
|
|
74
74
|
<TabItem label="Strands" _filter={{ framework: 'strands' }}>
|
|
75
|
-
```python title="packages/my-project/my_module/agent/agent.py" {4,8-13,15}
|
|
75
|
+
```python title="packages/my-project/my_module/agent/agent.py" {4,8-13,15,17}
|
|
76
76
|
from contextlib import contextmanager
|
|
77
77
|
from strands import Agent, tool
|
|
78
78
|
|
|
@@ -94,7 +94,7 @@ def get_agent():
|
|
|
94
94
|
```
|
|
95
95
|
</TabItem>
|
|
96
96
|
<TabItem label="LangChain" _filter={{ framework: 'langchain' }}>
|
|
97
|
-
```python title="packages/my-project/my_module/agent/agent.py" {5,8-13,15}
|
|
97
|
+
```python title="packages/my-project/my_module/agent/agent.py" {5,8-13,15,18}
|
|
98
98
|
from langchain.agents import create_agent
|
|
99
99
|
from langchain_aws import ChatBedrockConverse
|
|
100
100
|
from langchain_core.tools import tool
|
|
@@ -77,7 +77,7 @@ The generator transforms your agent's `agent.py` to use the Gateway client:
|
|
|
77
77
|
|
|
78
78
|
<Tabs syncKey="agent-framework">
|
|
79
79
|
<TabItem label="Strands" _filter={{ framework: 'strands' }}>
|
|
80
|
-
```python title="packages/example/example/my_agent/agent.py" {4,8,
|
|
80
|
+
```python title="packages/example/example/my_agent/agent.py" {4,8-11,14}
|
|
81
81
|
from contextlib import contextmanager
|
|
82
82
|
from strands import Agent
|
|
83
83
|
|
|
@@ -74,7 +74,7 @@ The generator transforms your agent's `agent.py` to use the MCP server's tools:
|
|
|
74
74
|
|
|
75
75
|
<Tabs syncKey="agent-framework">
|
|
76
76
|
<TabItem label="Strands" _filter={{ framework: 'strands' }}>
|
|
77
|
-
```python title="packages/my-project/my_module/agent/agent.py" {4,8,
|
|
77
|
+
```python title="packages/my-project/my_module/agent/agent.py" {4,8-11,14}
|
|
78
78
|
from contextlib import contextmanager
|
|
79
79
|
from strands import Agent
|
|
80
80
|
|
|
@@ -186,7 +186,7 @@ For information on how to define subscription procedures in your backend, see th
|
|
|
186
186
|
|
|
187
187
|
You can consume subscriptions using the `useSubscription` hook with `subscriptionOptions` from the options proxy:
|
|
188
188
|
|
|
189
|
-
```tsx {1-2,7-
|
|
189
|
+
```tsx {1-2,7-23}
|
|
190
190
|
import { useSubscription } from '@trpc/tanstack-react-query';
|
|
191
191
|
import { useMyApi } from './hooks/useMyApi';
|
|
192
192
|
|
|
@@ -84,7 +84,7 @@ The generated code handles authentication depending on your agent's configuratio
|
|
|
84
84
|
|
|
85
85
|
The most common use case is streaming the agent's response using the `invoke` subscription with the `use<AgentName>Agent` hook, which returns a [tRPC options proxy](https://trpc.io/docs/client/tanstack-react-query) for use with TanStack Query:
|
|
86
86
|
|
|
87
|
-
```tsx {1-2,7-
|
|
87
|
+
```tsx {1-2,7-23}
|
|
88
88
|
import { useSubscription } from '@trpc/tanstack-react-query';
|
|
89
89
|
import { useMyAgentAgent } from './hooks/useMyAgentAgent';
|
|
90
90
|
|