@aws/nx-plugin-mcp 1.0.0-rc.0 → 1.0.0-rc.10
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 +3556 -2476
- package/docs/guides/connection/py-agent-a2a.mdx +1 -1
- package/docs/guides/connection/py-agent-mcp.mdx +1 -1
- package/docs/guides/connection/react-agui.mdx +1 -1
- package/docs/guides/connection/react-py-agent.mdx +1 -1
- package/docs/guides/connection/react-smithy.mdx +1 -1
- package/docs/guides/connection/react-trpc.mdx +2 -2
- package/docs/guides/connection/react-ts-agent.mdx +1 -1
- package/docs/guides/connection/smithy-dynamodb.mdx +68 -0
- package/docs/guides/connection/smithy-rdb.mdx +1 -1
- package/docs/guides/connection/trpc-dynamodb.mdx +62 -0
- package/docs/guides/connection/trpc-rdb.mdx +1 -1
- package/docs/guides/connection/ts-agent-a2a.mdx +1 -1
- package/docs/guides/connection/ts-agent-dynamodb.mdx +128 -0
- package/docs/guides/connection/ts-agent-mcp.mdx +1 -1
- package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +125 -0
- package/docs/guides/connection.mdx +29 -0
- package/docs/guides/docker-bundling.mdx +1 -1
- package/docs/guides/fastapi.mdx +11 -11
- package/docs/guides/license.mdx +264 -109
- package/docs/guides/nx-generator.mdx +4 -0
- package/docs/guides/py-agent.mdx +18 -18
- package/docs/guides/py-mcp-server.mdx +10 -6
- package/docs/guides/python-lambda-function.mdx +4 -4
- package/docs/guides/react-website-auth.mdx +15 -0
- package/docs/guides/react-website.mdx +12 -6
- package/docs/guides/trpc.mdx +19 -18
- package/docs/guides/ts-agent.mdx +18 -18
- package/docs/guides/ts-dynamodb.mdx +364 -0
- package/docs/guides/ts-lambda-function.mdx +4 -4
- package/docs/guides/ts-mcp-server.mdx +10 -6
- package/docs/guides/ts-rdb.mdx +53 -9
- package/docs/guides/ts-smithy-api.mdx +9 -8
- package/docs/guides/typescript-project.mdx +5 -10
- package/docs/guides/workspace.mdx +9 -3
- package/docs/snippets/agent/architecture.mdx +4 -4
- package/docs/snippets/agent/bedrock-deployment.mdx +1 -1
- package/docs/snippets/api/api-architecture.mdx +2 -2
- package/docs/snippets/api/type-safe-api-integrations.mdx +2 -2
- package/docs/snippets/connection/dynamodb-local-development.mdx +7 -0
- package/docs/snippets/connection/lambda-dynamodb-access.mdx +80 -0
- package/docs/snippets/lambda-function/deploying-your-function.mdx +2 -2
- package/docs/snippets/mcp/architecture.mdx +4 -4
- package/docs/snippets/mcp/bedrock-deployment.mdx +1 -1
- package/docs/snippets/mcp/config.mdx +1 -1
- package/docs/snippets/required-prerequisites.mdx +1 -1
- package/generators.json +44 -5
- package/package.json +1 -1
- package/src/infra/app/schema.json +1 -1
- package/src/license/schema.json +6 -0
- package/src/preset/schema.json +9 -4
- package/src/py/agent/schema.json +18 -18
- package/src/py/api/schema.json +15 -15
- package/src/py/fast-api/schema.json +15 -15
- package/src/py/lambda-function/schema.json +15 -7
- package/src/py/mcp-server/schema.json +15 -15
- package/src/py/project/schema.json +2 -2
- package/src/smithy/ts/api/schema.json +15 -15
- package/src/trpc/backend/schema.json +15 -15
- package/src/ts/agent/schema.json +18 -18
- package/src/ts/api/schema.json +15 -15
- package/src/ts/dynamodb/agent-connection/schema.json +22 -0
- package/src/ts/dynamodb/mcp-server-connection/schema.json +22 -0
- package/src/ts/dynamodb/schema.json +52 -0
- package/src/ts/dynamodb/smithy-connection/schema.json +18 -0
- package/src/ts/dynamodb/trpc-connection/schema.json +18 -0
- package/src/ts/lambda-function/schema.json +15 -7
- package/src/ts/mcp-server/schema.json +15 -15
- package/src/ts/rdb/schema.json +13 -13
- package/src/ts/react-website/app/schema.json +13 -13
- package/src/ts/react-website/cognito-auth/schema.json +4 -4
- package/src/ts/website/app/schema.json +21 -13
- package/src/ts/website/auth/schema.json +4 -4
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: DynamoDB
|
|
3
|
+
description: Create a DynamoDB project
|
|
4
|
+
generator: ts#dynamodb
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
8
|
+
import Link from '@components/link.astro';
|
|
9
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
10
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
11
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
12
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
13
|
+
import Snippet from '@components/snippet.astro';
|
|
14
|
+
import OptionFilter from '@components/option-filter.astro';
|
|
15
|
+
|
|
16
|
+
This generator creates a new TypeScript project backed by [Amazon DynamoDB](https://aws.amazon.com/dynamodb/), using [ElectroDB](https://electrodb.dev/) for type-safe entity modelling. It generates the application code and infrastructure needed to provision and manage a DynamoDB table using AWS CDK or Terraform, with single-table design support and built-in local development via DynamoDB Local.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Generate a DynamoDB Project
|
|
21
|
+
|
|
22
|
+
<RunGenerator generator="ts#dynamodb" />
|
|
23
|
+
|
|
24
|
+
### Options
|
|
25
|
+
|
|
26
|
+
<GeneratorParameters generator="ts#dynamodb" />
|
|
27
|
+
|
|
28
|
+
## Generator Output
|
|
29
|
+
|
|
30
|
+
The generator creates the following project structure in the `<directory>/<name>` directory:
|
|
31
|
+
|
|
32
|
+
<FileTree>
|
|
33
|
+
- scripts
|
|
34
|
+
- create-local-table.ts Creates the DynamoDB table in the local DynamoDB Local instance
|
|
35
|
+
- pull-image.ts Pulls the DynamoDB Local image
|
|
36
|
+
- start-container.ts Starts the DynamoDB Local container
|
|
37
|
+
- src
|
|
38
|
+
- index.ts Project entry point and exports
|
|
39
|
+
- constants.ts Local development constants and runtime config key
|
|
40
|
+
- client.ts DynamoDB client singleton and table name resolution
|
|
41
|
+
- entities
|
|
42
|
+
- example.ts Example ElectroDB entity definition
|
|
43
|
+
- index.ts Entity exports
|
|
44
|
+
- project.json Project configuration and build targets
|
|
45
|
+
</FileTree>
|
|
46
|
+
|
|
47
|
+
### Infrastructure
|
|
48
|
+
|
|
49
|
+
<Snippet name="shared-constructs" />
|
|
50
|
+
|
|
51
|
+
<Infrastructure>
|
|
52
|
+
<Fragment slot="cdk">
|
|
53
|
+
<FileTree>
|
|
54
|
+
- packages/common/constructs/src
|
|
55
|
+
- app
|
|
56
|
+
- dynamodb
|
|
57
|
+
- \<name>.ts Infrastructure specific to your table
|
|
58
|
+
- core
|
|
59
|
+
- dynamodb.ts Generic DynamoDB table construct
|
|
60
|
+
</FileTree>
|
|
61
|
+
</Fragment>
|
|
62
|
+
<Fragment slot="terraform">
|
|
63
|
+
<FileTree>
|
|
64
|
+
- packages/common/terraform/src
|
|
65
|
+
- app
|
|
66
|
+
- dynamodb
|
|
67
|
+
- \<name>
|
|
68
|
+
- \<name>.tf Module specific to your table
|
|
69
|
+
- core
|
|
70
|
+
- dynamodb
|
|
71
|
+
- dynamodb.tf Generic DynamoDB module
|
|
72
|
+
</FileTree>
|
|
73
|
+
</Fragment>
|
|
74
|
+
</Infrastructure>
|
|
75
|
+
|
|
76
|
+
## Local Development
|
|
77
|
+
|
|
78
|
+
### Starting Local DynamoDB
|
|
79
|
+
|
|
80
|
+
The generator configures a `serve-local` target that starts a [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html) instance and creates the table:
|
|
81
|
+
|
|
82
|
+
<NxCommands commands={['run <project-name>:serve-local']} />
|
|
83
|
+
|
|
84
|
+
This automatically:
|
|
85
|
+
1. Pulls the DynamoDB Local image (`pull-image` target)
|
|
86
|
+
2. Starts a container
|
|
87
|
+
3. Creates a local table with pre-defined indexes
|
|
88
|
+
|
|
89
|
+
### Data Modelling
|
|
90
|
+
|
|
91
|
+
The generated project uses [ElectroDB](https://electrodb.dev/) for type-safe entity modelling on a single DynamoDB table. Add or update entity files under `src/entities/`, using the generated example entity as a starting point.
|
|
92
|
+
|
|
93
|
+
Example entity definition:
|
|
94
|
+
|
|
95
|
+
```ts title="packages/my-table/src/entities/example.ts"
|
|
96
|
+
import { Entity } from 'electrodb';
|
|
97
|
+
import { getDynamoDBClient, resolveTableName } from '../client.js';
|
|
98
|
+
|
|
99
|
+
export const createExampleEntity = async () =>
|
|
100
|
+
new Entity(
|
|
101
|
+
{
|
|
102
|
+
model: {
|
|
103
|
+
entity: 'example',
|
|
104
|
+
version: '1',
|
|
105
|
+
service: 'MyTable',
|
|
106
|
+
},
|
|
107
|
+
attributes: {
|
|
108
|
+
id: {
|
|
109
|
+
type: 'string',
|
|
110
|
+
required: true,
|
|
111
|
+
},
|
|
112
|
+
createdAt: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
required: true,
|
|
115
|
+
default: () => new Date().toISOString(),
|
|
116
|
+
readOnly: true,
|
|
117
|
+
},
|
|
118
|
+
updatedAt: {
|
|
119
|
+
type: 'string',
|
|
120
|
+
required: true,
|
|
121
|
+
default: () => new Date().toISOString(),
|
|
122
|
+
watch: '*',
|
|
123
|
+
set: () => new Date().toISOString(),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
indexes: {
|
|
127
|
+
primary: {
|
|
128
|
+
pk: {
|
|
129
|
+
field: 'pk',
|
|
130
|
+
composite: ['id'],
|
|
131
|
+
},
|
|
132
|
+
sk: {
|
|
133
|
+
field: 'sk',
|
|
134
|
+
composite: [],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{ client: getDynamoDBClient(), table: await resolveTableName() },
|
|
140
|
+
);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
For more details, see the [ElectroDB entity documentation](https://electrodb.dev/en/modeling/entities/).
|
|
144
|
+
|
|
145
|
+
### Using the DynamoDB Client
|
|
146
|
+
|
|
147
|
+
The generated `src/client.ts` exports two key utilities:
|
|
148
|
+
|
|
149
|
+
- `getDynamoDBClient()` — returns a cached singleton `DynamoDBClient`. When `SERVE_LOCAL=true`, connects to the local DynamoDB Local instance; otherwise creates an AWS client using the default credential chain.
|
|
150
|
+
- `resolveTableName()` — returns the DynamoDB table name. When `SERVE_LOCAL=true`, returns the local table name constant; otherwise fetches the name from AWS AppConfig using the `RUNTIME_CONFIG_APP_ID` environment variable and caches it for subsequent calls.
|
|
151
|
+
|
|
152
|
+
### Stopping Local DynamoDB
|
|
153
|
+
|
|
154
|
+
Stopping `serve-local` (e.g. with `Ctrl+C`) automatically removes the DynamoDB Local container, but preserves the named volume so your data persists across restarts.
|
|
155
|
+
|
|
156
|
+
:::caution[Windows]
|
|
157
|
+
Due to limitations with signal handling on Windows, the container is not automatically removed when `serve-local` is stopped. You will need to remove it manually:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
<engine> rm -f <scope>-dynamodb
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Replace `<engine>` with your container engine (`docker` or `finch`) and `<scope>` with your Nx workspace scope (e.g. `proj`).
|
|
164
|
+
:::
|
|
165
|
+
|
|
166
|
+
## Adding/Removing Global Secondary Indexes
|
|
167
|
+
|
|
168
|
+
Start by updating `GLOBAL_SECONDARY_INDEXES` in `src/gsi.ts` — this is the source of truth for your GSI definitions, and on the next `serve-local` run the script will automatically add or remove indexes on the local table to reflect the new list. When using CDK, these changes are also automatically reflected in your AWS table on the next deployment.
|
|
169
|
+
|
|
170
|
+
<OptionFilter when={{ iac: 'terraform' }}>
|
|
171
|
+
Unlike CDK, changes to `src/gsi.ts` are not automatically reflected in your Terraform module. You must also manually update your Terraform module to add or remove the corresponding GSI definitions before deploying.
|
|
172
|
+
</OptionFilter>
|
|
173
|
+
|
|
174
|
+
## Connecting to the Table
|
|
175
|
+
|
|
176
|
+
In any TypeScript project, import entity factories from your DynamoDB package and use them directly:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { createExampleEntity } from ':my-scope/my-table';
|
|
180
|
+
|
|
181
|
+
const entity = await createExampleEntity();
|
|
182
|
+
const result = await entity.query.primary({ id: '123' }).go();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
:::note[Runtime config]
|
|
186
|
+
When running in AWS, `resolveTableName()` fetches the table name from AWS AppConfig using the `RUNTIME_CONFIG_APP_ID` environment variable. Projects built with this plugin (tRPC APIs, Smithy APIs, agents, MCP servers) already have this variable configured automatically. For other TypeScript projects, ensure `RUNTIME_CONFIG_APP_ID` is set in the runtime environment with the AppConfig application ID provisioned by your infrastructure. For more information, see the <Link path="guides/runtime-config">Runtime Configuration guide</Link>.
|
|
187
|
+
:::
|
|
188
|
+
|
|
189
|
+
### Connection Generators
|
|
190
|
+
|
|
191
|
+
For specific project types, use the `connection` generator to automatically wire up local development dependencies so DynamoDB Local starts automatically alongside your project:
|
|
192
|
+
|
|
193
|
+
- <Link path="guides/connection/trpc-dynamodb">tRPC API → DynamoDB</Link>
|
|
194
|
+
- <Link path="guides/connection/smithy-dynamodb">Smithy API → DynamoDB</Link>
|
|
195
|
+
- <Link path="guides/connection/ts-agent-dynamodb">TypeScript Agent → DynamoDB</Link>
|
|
196
|
+
- <Link path="guides/connection/ts-mcp-server-dynamodb">MCP Server → DynamoDB</Link>
|
|
197
|
+
|
|
198
|
+
## Deploying your Table
|
|
199
|
+
|
|
200
|
+
The DynamoDB generator creates CDK or Terraform infrastructure based on your selected `iac`.
|
|
201
|
+
|
|
202
|
+
<Infrastructure>
|
|
203
|
+
<Fragment slot="cdk">
|
|
204
|
+
The CDK construct is created in `common/constructs`. Example usage:
|
|
205
|
+
|
|
206
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
207
|
+
import { MyTable } from ':my-scope/common-constructs';
|
|
208
|
+
|
|
209
|
+
export class ApplicationStack extends Stack {
|
|
210
|
+
constructor(scope: Construct, id: string, props?: StackProps) {
|
|
211
|
+
super(scope, id, props);
|
|
212
|
+
|
|
213
|
+
const table = new MyTable(this, 'Table');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
This provisions a DynamoDB table with:
|
|
219
|
+
- `pk` (partition key) and `sk` (sort key), both `String` type
|
|
220
|
+
- 2 Global Secondary Indexes by default, as defined in `src/gsi.ts`
|
|
221
|
+
- On-demand (`PAY_PER_REQUEST`) billing
|
|
222
|
+
- Customer-managed KMS encryption with automatic key rotation
|
|
223
|
+
- Point-in-time recovery enabled
|
|
224
|
+
- Deletion protection enabled
|
|
225
|
+
- Table name registered in Runtime Config under the `dynamodb` namespace in AWS AppConfig
|
|
226
|
+
</Fragment>
|
|
227
|
+
<Fragment slot="terraform">
|
|
228
|
+
The Terraform module is created in `common/terraform`. Example usage:
|
|
229
|
+
|
|
230
|
+
```hcl title="packages/infra/src/main.tf"
|
|
231
|
+
module "my_table" {
|
|
232
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
This provisions a DynamoDB table with:
|
|
237
|
+
- `pk` (partition key) and `sk` (sort key), both `String` type
|
|
238
|
+
- 2 Global Secondary Indexes by default, as defined in `src/gsi.ts`
|
|
239
|
+
- On-demand (`PAY_PER_REQUEST`) billing
|
|
240
|
+
- Customer-managed KMS encryption with automatic key rotation
|
|
241
|
+
- Point-in-time recovery enabled
|
|
242
|
+
- Deletion protection enabled
|
|
243
|
+
- Table name registered in Runtime Config
|
|
244
|
+
</Fragment>
|
|
245
|
+
</Infrastructure>
|
|
246
|
+
|
|
247
|
+
### Granting Access
|
|
248
|
+
|
|
249
|
+
<Snippet name="connection/lambda-dynamodb-access" />
|
|
250
|
+
|
|
251
|
+
### Deletion Protection
|
|
252
|
+
|
|
253
|
+
Deletion protection is enabled by default to prevent accidental table deletion.
|
|
254
|
+
|
|
255
|
+
#### Disable Deletion Protection
|
|
256
|
+
|
|
257
|
+
Disable it for environments where table deletion is expected, such as short-lived development or preview stacks.
|
|
258
|
+
|
|
259
|
+
<Infrastructure>
|
|
260
|
+
<Fragment slot="cdk">
|
|
261
|
+
|
|
262
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
263
|
+
import { MyTable } from ':my-scope/common-constructs';
|
|
264
|
+
|
|
265
|
+
const table = new MyTable(this, 'Table', {
|
|
266
|
+
deletionProtection: false,
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
</Fragment>
|
|
270
|
+
<Fragment slot="terraform">
|
|
271
|
+
|
|
272
|
+
```hcl title="packages/infra/src/main.tf"
|
|
273
|
+
module "my_table" {
|
|
274
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
275
|
+
deletion_protection_enabled = false
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
</Fragment>
|
|
279
|
+
</Infrastructure>
|
|
280
|
+
|
|
281
|
+
### Billing Mode
|
|
282
|
+
|
|
283
|
+
The table defaults to on-demand (`PAY_PER_REQUEST`) billing. Switch to provisioned capacity for predictable, high-throughput workloads.
|
|
284
|
+
|
|
285
|
+
<Infrastructure>
|
|
286
|
+
<Fragment slot="cdk">
|
|
287
|
+
|
|
288
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
289
|
+
import { BillingMode } from 'aws-cdk-lib/aws-dynamodb';
|
|
290
|
+
import { MyTable } from ':my-scope/common-constructs';
|
|
291
|
+
|
|
292
|
+
const table = new MyTable(this, 'Table', {
|
|
293
|
+
billingMode: BillingMode.PROVISIONED,
|
|
294
|
+
readCapacity: 5,
|
|
295
|
+
writeCapacity: 5,
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
</Fragment>
|
|
299
|
+
<Fragment slot="terraform">
|
|
300
|
+
|
|
301
|
+
```hcl title="packages/infra/src/main.tf"
|
|
302
|
+
module "my_table" {
|
|
303
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
304
|
+
billing_mode = "PROVISIONED"
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
</Fragment>
|
|
308
|
+
</Infrastructure>
|
|
309
|
+
|
|
310
|
+
### Point-in-time Recovery
|
|
311
|
+
|
|
312
|
+
[Point-in-time recovery](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Point-in-time-recovery.html) is enabled by default, allowing you to restore the table to any point in the last 35 days.
|
|
313
|
+
|
|
314
|
+
#### Disable Point-in-time Recovery
|
|
315
|
+
|
|
316
|
+
<Infrastructure>
|
|
317
|
+
<Fragment slot="cdk">
|
|
318
|
+
|
|
319
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
320
|
+
import { MyTable } from ':my-scope/common-constructs';
|
|
321
|
+
|
|
322
|
+
const table = new MyTable(this, 'Table', {
|
|
323
|
+
pointInTimeRecoverySpecification: { pointInTimeRecoveryEnabled: false },
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
</Fragment>
|
|
327
|
+
<Fragment slot="terraform">
|
|
328
|
+
|
|
329
|
+
```hcl title="packages/infra/src/main.tf"
|
|
330
|
+
module "my_table" {
|
|
331
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
332
|
+
point_in_time_recovery_enabled = false
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
</Fragment>
|
|
336
|
+
</Infrastructure>
|
|
337
|
+
|
|
338
|
+
### Encryption Key Rotation
|
|
339
|
+
|
|
340
|
+
The KMS key used to encrypt the table has automatic key rotation enabled by default. Disable it if your security policy manages rotation externally.
|
|
341
|
+
|
|
342
|
+
#### Disable Encryption Key Rotation
|
|
343
|
+
|
|
344
|
+
<Infrastructure>
|
|
345
|
+
<Fragment slot="cdk">
|
|
346
|
+
|
|
347
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
348
|
+
import { MyTable } from ':my-scope/common-constructs';
|
|
349
|
+
|
|
350
|
+
const table = new MyTable(this, 'Table', {
|
|
351
|
+
enableKeyRotation: false,
|
|
352
|
+
});
|
|
353
|
+
```
|
|
354
|
+
</Fragment>
|
|
355
|
+
<Fragment slot="terraform">
|
|
356
|
+
|
|
357
|
+
```hcl title="packages/infra/src/main.tf"
|
|
358
|
+
module "my_table" {
|
|
359
|
+
source = "../../common/terraform/src/app/dynamodb/my-table"
|
|
360
|
+
enable_key_rotation = false
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
</Fragment>
|
|
364
|
+
</Infrastructure>
|
|
@@ -179,8 +179,8 @@ export const handler = middy()
|
|
|
179
179
|
|
|
180
180
|
### Type Safety
|
|
181
181
|
|
|
182
|
-
<OptionFilter not when={{
|
|
183
|
-
If you chose an `
|
|
182
|
+
<OptionFilter not when={{ event: 'Any' }} description="event provides a typed Zod schema for the incoming event">
|
|
183
|
+
If you chose an `event` when generating your lambda function, your function is instrumented with the [`parser` middleware from AWS Lambda Powertools](https://docs.powertools.aws.dev/lambda/typescript/latest/utilities/parser/). For example:
|
|
184
184
|
|
|
185
185
|
```typescript {4}
|
|
186
186
|
export const myFunction = async (
|
|
@@ -205,8 +205,8 @@ If you have custom data nested within an event, for example a DynamoDB stream or
|
|
|
205
205
|
:::
|
|
206
206
|
</OptionFilter>
|
|
207
207
|
|
|
208
|
-
<OptionFilter when={{
|
|
209
|
-
If you selected `Any` for your `
|
|
208
|
+
<OptionFilter when={{ event: 'Any' }} description="event=Any — no parser middleware, event is typed as `any`">
|
|
209
|
+
If you selected `Any` for your `event`, the `parser` middleware is not wired in and the `event` parameter is typed as `any`. Regenerate the function with a specific `event` if you want compile-time type safety and runtime validation.
|
|
210
210
|
</OptionFilter>
|
|
211
211
|
|
|
212
212
|
## Bundling
|
|
@@ -53,21 +53,21 @@ The generator will add the following files to your existing TypeScript project:
|
|
|
53
53
|
- divide.ts Sample tool
|
|
54
54
|
- resources/
|
|
55
55
|
- sample-guidance.ts Sample resource
|
|
56
|
-
- Dockerfile Entry point for hosting your MCP server (excluded when `
|
|
56
|
+
- Dockerfile Entry point for hosting your MCP server (excluded when `infra` is set to `None`)
|
|
57
57
|
- package.json Updated with bin entry and MCP dependencies
|
|
58
58
|
- project.json Updated with MCP server serve target
|
|
59
59
|
</FileTree>
|
|
60
60
|
|
|
61
61
|
### Infrastructure
|
|
62
62
|
|
|
63
|
-
<OptionFilter when={{
|
|
63
|
+
<OptionFilter when={{ infra: 'agentcore' }} description="Bedrock AgentCore Runtime deployment">
|
|
64
64
|
<Snippet name="shared-constructs" />
|
|
65
65
|
|
|
66
66
|
<Snippet name="mcp/shared-constructs" />
|
|
67
67
|
</OptionFilter>
|
|
68
68
|
|
|
69
|
-
<OptionFilter when={{
|
|
70
|
-
If you selected `
|
|
69
|
+
<OptionFilter when={{ infra: 'none' }} description="No infrastructure is vended for infra=none">
|
|
70
|
+
If you selected `none` for `infra`, no CDK constructs or Terraform modules are generated — the MCP server is configured for local STDIO / HTTP use only. The `auth` option is ignored in this mode since there is no hosted endpoint to authenticate.
|
|
71
71
|
</OptionFilter>
|
|
72
72
|
|
|
73
73
|
#### Architecture
|
|
@@ -122,12 +122,16 @@ server.registerResource('dynamic-resource', 'dynamic://resource', {}, async (uri
|
|
|
122
122
|
|
|
123
123
|
### Inspector
|
|
124
124
|
|
|
125
|
-
The generator configures a target named `<your-server-name>-inspect`, which starts the [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
|
|
125
|
+
The generator configures a target named `<your-server-name>-inspect`, which starts your MCP server locally (via the `<your-server-name>-serve-local` target, including any connected dependencies such as a local database) and launches the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) pre-configured to connect to it over Streamable HTTP transport.
|
|
126
126
|
|
|
127
127
|
<NxCommands commands={['your-server-name-inspect your-project']} />
|
|
128
128
|
|
|
129
129
|
This will start the inspector at `http://localhost:6274`. Get started by clicking on the "Connect" button.
|
|
130
130
|
|
|
131
|
+
:::tip
|
|
132
|
+
To inspect the server using STDIO transport instead, use the `<your-server-name>-inspect-stdio` target, which launches the inspector against a STDIO instance of your server.
|
|
133
|
+
:::
|
|
134
|
+
|
|
131
135
|
### STDIO
|
|
132
136
|
|
|
133
137
|
The easiest way to test and use an MCP server is by using the inspector or configuring it with an AI assistant (as above).
|
|
@@ -146,7 +150,7 @@ If you would like to run your MCP server locally using [Streamable HTTP transpor
|
|
|
146
150
|
|
|
147
151
|
This command uses `tsx --watch` to automatically restart the server when files change.
|
|
148
152
|
|
|
149
|
-
<OptionFilter when={{
|
|
153
|
+
<OptionFilter when={{ infra: 'agentcore' }} description="Bedrock AgentCore Runtime deployment details">
|
|
150
154
|
## Deploying Your MCP Server to Bedrock AgentCore Runtime
|
|
151
155
|
|
|
152
156
|
<Snippet name="mcp/bedrock-deployment" parentHeading="Deploying Your MCP Server to Bedrock AgentCore Runtime" />
|
package/docs/guides/ts-rdb.mdx
CHANGED
|
@@ -38,8 +38,8 @@ The generator will create the following project structure in the `<directory>/<n
|
|
|
38
38
|
- example.prisma Example model definition
|
|
39
39
|
- schema.prisma Main Prisma schema (references models)
|
|
40
40
|
- scripts
|
|
41
|
-
-
|
|
42
|
-
-
|
|
41
|
+
- pull-image.ts Pulls the database container image for local development
|
|
42
|
+
- start-container.ts Starts a local database container
|
|
43
43
|
- wait-for-db.ts Waits for the local database to be ready
|
|
44
44
|
- src
|
|
45
45
|
- index.ts Project entry point
|
|
@@ -169,7 +169,7 @@ The client automatically:
|
|
|
169
169
|
|
|
170
170
|
After adding or updating models under `prisma/models/`, use `migrate dev` to generate migration files and apply them to your local database at the same time.
|
|
171
171
|
|
|
172
|
-
The generated `prisma` target automatically starts a local database
|
|
172
|
+
The generated `prisma` target automatically starts a local database container before running:
|
|
173
173
|
|
|
174
174
|
<NxCommands commands={['run <project>:prisma migrate dev']} />
|
|
175
175
|
|
|
@@ -204,12 +204,26 @@ The generated `prisma` target exposes the Prisma CLI, so you can use it to run a
|
|
|
204
204
|
|
|
205
205
|
<NxCommands commands={['run <project>:prisma <prisma-command>']} />
|
|
206
206
|
|
|
207
|
-
### Prisma Studio
|
|
207
|
+
### Using Prisma Studio
|
|
208
208
|
|
|
209
209
|
[Prisma Studio](https://www.prisma.io/studio) is a visual editor for your local database. Use it to browse tables, inspect and edit records, filter data, follow relations, and run raw SQL via the built-in SQL console. It is useful for verifying migrations and seeding test data during development. Launch it with:
|
|
210
210
|
|
|
211
211
|
<NxCommands commands={['run <project>:prisma studio']} />
|
|
212
212
|
|
|
213
|
+
### Stopping the Local Database
|
|
214
|
+
|
|
215
|
+
Stopping `serve-local` (e.g. with `Ctrl+C`) automatically removes the local database container, but preserves the named volume so your data persists across restarts.
|
|
216
|
+
|
|
217
|
+
:::caution[Windows]
|
|
218
|
+
Due to limitations with signal handling on Windows, the container is not automatically removed when `serve-local` is stopped. You will need to remove it manually:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
<engine> rm -f <scope>-<db-name>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Replace `<engine>` with your container engine (`docker` or `finch`), `<scope>` with your Nx workspace scope (e.g. `proj`), and `<db-name>` with your database project name (e.g. `my-db`).
|
|
225
|
+
:::
|
|
226
|
+
|
|
213
227
|
## Connecting to the Database
|
|
214
228
|
|
|
215
229
|
In any TypeScript project, import `getPrisma` from your database package and call it to get a type-safe Prisma client:
|
|
@@ -524,11 +538,11 @@ module "my_database" {
|
|
|
524
538
|
|
|
525
539
|
Pin a specific Aurora engine version.
|
|
526
540
|
|
|
527
|
-
By default, the generated local
|
|
541
|
+
By default, the generated local database container image matches the default Aurora engine version. If you change the Aurora engine version, it's recommended to also use a matching local container image version for maximum compatibility. See the AWS release notes for [Aurora PostgreSQL versions](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/aurorapostgresql-release-calendar.html) and [Aurora MySQL versions](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraMySQLReleaseNotes/AuroraMySQL.Updates.30Updates.html) to identify the corresponding community database version.
|
|
528
542
|
|
|
529
|
-
The local database image is configured in the generated database project's `serve-local` target in `project.json`. Update the image argument passed to `scripts/
|
|
543
|
+
The local database image is configured in the generated database project's `serve-local` target in `project.json`. Update the image argument passed to `scripts/start-container.ts` when you change engine versions.
|
|
530
544
|
|
|
531
|
-
<OptionFilter when={{ engine: '
|
|
545
|
+
<OptionFilter when={{ engine: 'postgres' }}>
|
|
532
546
|
<Infrastructure>
|
|
533
547
|
<Fragment slot="cdk">
|
|
534
548
|
|
|
@@ -554,7 +568,7 @@ module "my_database" {
|
|
|
554
568
|
</Infrastructure>
|
|
555
569
|
</OptionFilter>
|
|
556
570
|
|
|
557
|
-
<OptionFilter when={{ engine: '
|
|
571
|
+
<OptionFilter when={{ engine: 'mysql' }}>
|
|
558
572
|
<Infrastructure>
|
|
559
573
|
<Fragment slot="cdk">
|
|
560
574
|
|
|
@@ -659,6 +673,36 @@ module "my_database" {
|
|
|
659
673
|
</Fragment>
|
|
660
674
|
</Infrastructure>
|
|
661
675
|
|
|
676
|
+
### Logging and Monitoring
|
|
677
|
+
|
|
678
|
+
Performance Insights is enabled on the Aurora writer instance by default (encrypted with the cluster's KMS key). You can also export the Aurora engine logs to [CloudWatch Logs](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_LogAccess.html) (`postgresql` for [Aurora PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.CloudWatch.html); `audit`, `error`, `general` and `slowquery` for [Aurora MySQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.CloudWatch.html)). Enable log export per database:
|
|
679
|
+
|
|
680
|
+
<Infrastructure>
|
|
681
|
+
<Fragment slot="cdk">
|
|
682
|
+
|
|
683
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
684
|
+
import { MyDatabase } from ':my-scope/common-constructs';
|
|
685
|
+
|
|
686
|
+
const db = new MyDatabase(this, 'Db', {
|
|
687
|
+
...
|
|
688
|
+
enableCloudwatchLogs: true,
|
|
689
|
+
enablePerformanceInsights: false, // disable if not required
|
|
690
|
+
});
|
|
691
|
+
```
|
|
692
|
+
</Fragment>
|
|
693
|
+
<Fragment slot="terraform">
|
|
694
|
+
|
|
695
|
+
```hcl title="packages/infra/src/main.tf"
|
|
696
|
+
module "my_database" {
|
|
697
|
+
source = "../../common/terraform/src/app/dbs/my-database"
|
|
698
|
+
...
|
|
699
|
+
enable_cloudwatch_logs = true
|
|
700
|
+
enable_performance_insights = false # disable if not required
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
</Fragment>
|
|
704
|
+
</Infrastructure>
|
|
705
|
+
|
|
662
706
|
### Encryption Key Rotation
|
|
663
707
|
|
|
664
708
|
The KMS key used to encrypt the Aurora cluster and its credentials secret has automatic key rotation enabled by default. Disable it if your security policy manages rotation externally.
|
|
@@ -689,7 +733,7 @@ module "my_database" {
|
|
|
689
733
|
|
|
690
734
|
## Limitations
|
|
691
735
|
|
|
692
|
-
<OptionFilter when={{ engine: '
|
|
736
|
+
<OptionFilter when={{ engine: 'mysql' }}>
|
|
693
737
|
|
|
694
738
|
### MySQL: API Gateway Streaming Mode
|
|
695
739
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Smithy TypeScript API
|
|
3
3
|
description: Reference documentation for Smithy TypeScript API
|
|
4
|
-
generator: ts#
|
|
4
|
+
generator: ts#api
|
|
5
5
|
when:
|
|
6
6
|
framework: [smithy]
|
|
7
|
+
infra: [rest-lambda]
|
|
7
8
|
---
|
|
8
9
|
|
|
9
10
|
import { FileTree } from '@astrojs/starlight/components';
|
|
@@ -26,11 +27,11 @@ The Smithy TypeScript API generator creates a new API using Smithy for service d
|
|
|
26
27
|
|
|
27
28
|
You can generate a new Smithy TypeScript API in two ways:
|
|
28
29
|
|
|
29
|
-
<RunGenerator generator="ts#
|
|
30
|
+
<RunGenerator generator="ts#api" requiredParameters={{ framework: 'smithy' }} />
|
|
30
31
|
|
|
31
32
|
### Options
|
|
32
33
|
|
|
33
|
-
<GeneratorParameters generator="ts#
|
|
34
|
+
<GeneratorParameters generator="ts#api" />
|
|
34
35
|
|
|
35
36
|
:::tip[Integration Pattern]
|
|
36
37
|
The `integrationPattern` option defaults to `isolated`, which creates one Lambda per Smithy operation. Select `shared` if you would prefer a single shared Lambda handler for the whole API, with optional per-operation overrides.
|
|
@@ -462,7 +463,7 @@ This sets up:
|
|
|
462
463
|
|
|
463
464
|
<Snippet name="api/cors-configuration-cdk-note" />
|
|
464
465
|
|
|
465
|
-
<OptionFilter when={{ auth: '
|
|
466
|
+
<OptionFilter when={{ auth: 'cognito' }} description="Cognito identity construct wiring">
|
|
466
467
|
:::note[Cognito Authentication]
|
|
467
468
|
If you selected `Cognito` authentication, you will need to supply the `identity` property to the API construct:
|
|
468
469
|
|
|
@@ -485,7 +486,7 @@ The `UserIdentity` construct can be generated using the <Link path="/guides/reac
|
|
|
485
486
|
:::
|
|
486
487
|
</OptionFilter>
|
|
487
488
|
|
|
488
|
-
<OptionFilter when={{ auth: '
|
|
489
|
+
<OptionFilter when={{ auth: 'custom' }} description="Custom Lambda Authorizer CDK usage">
|
|
489
490
|
:::caution[Custom Lambda Authorizer]
|
|
490
491
|
When using `Custom` auth, the construct creates a Lambda Authorizer internally from the generated `src/authorizer.ts` file, which **denies all requests by default**. You must implement your authorization logic in that file before your API will accept any traffic.
|
|
491
492
|
:::
|
|
@@ -532,7 +533,7 @@ This sets up:
|
|
|
532
533
|
|
|
533
534
|
<Snippet name="api/cors-configuration-terraform-note" />
|
|
534
535
|
|
|
535
|
-
<OptionFilter when={{ auth: '
|
|
536
|
+
<OptionFilter when={{ auth: 'cognito' }} description="Cognito module wiring">
|
|
536
537
|
:::note[Cognito Authentication]
|
|
537
538
|
If you selected `Cognito` authentication, you will need to supply the Cognito configuration:
|
|
538
539
|
|
|
@@ -556,7 +557,7 @@ module "my_api" {
|
|
|
556
557
|
:::
|
|
557
558
|
</OptionFilter>
|
|
558
559
|
|
|
559
|
-
<OptionFilter when={{ auth: '
|
|
560
|
+
<OptionFilter when={{ auth: 'custom' }} description="Custom Lambda Authorizer usage with Terraform">
|
|
560
561
|
:::caution[Custom Lambda Authorizer]
|
|
561
562
|
When using `Custom` auth, your API is protected by a Lambda Authorizer that **denies all requests by default**. You must implement your authorization logic in the generated `src/authorizer.ts` file before your API will accept any traffic.
|
|
562
563
|
:::
|
|
@@ -618,7 +619,7 @@ We do not support type-safe integrations for Terraform, and therefore no code ge
|
|
|
618
619
|
</Fragment>
|
|
619
620
|
</Infrastructure>
|
|
620
621
|
|
|
621
|
-
<OptionFilter when={{ auth: '
|
|
622
|
+
<OptionFilter when={{ auth: 'iam' }} description="IAM-authenticated APIs only">
|
|
622
623
|
### Granting Access (IAM Only)
|
|
623
624
|
|
|
624
625
|
If you selected `IAM` authentication, you can use the `grantInvokeAccess` method to grant access to your API:
|