@aws/nx-plugin-mcp 1.0.0-rc.2 → 1.0.0-rc.21

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 (70) hide show
  1. package/bin/aws-nx-mcp.js +5919 -4776
  2. package/docs/guides/agentcore-gateway.mdx +240 -0
  3. package/docs/guides/connection/agentcore-gateway-gateway.mdx +154 -0
  4. package/docs/guides/connection/agentcore-gateway-mcp.mdx +134 -0
  5. package/docs/guides/connection/py-agent-a2a.mdx +8 -5
  6. package/docs/guides/connection/py-agent-dynamodb.mdx +116 -0
  7. package/docs/guides/connection/py-agent-gateway.mdx +161 -0
  8. package/docs/guides/connection/py-agent-mcp.mdx +7 -4
  9. package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
  10. package/docs/guides/connection/py-mcp-server-dynamodb.mdx +116 -0
  11. package/docs/guides/connection/react-smithy.mdx +1 -1
  12. package/docs/guides/connection/react-trpc.mdx +1 -1
  13. package/docs/guides/connection/smithy-dynamodb.mdx +68 -0
  14. package/docs/guides/connection/smithy-rdb.mdx +1 -1
  15. package/docs/guides/connection/trpc-dynamodb.mdx +62 -0
  16. package/docs/guides/connection/trpc-rdb.mdx +1 -1
  17. package/docs/guides/connection/ts-agent-a2a.mdx +8 -5
  18. package/docs/guides/connection/ts-agent-dynamodb.mdx +128 -0
  19. package/docs/guides/connection/ts-agent-gateway.mdx +152 -0
  20. package/docs/guides/connection/ts-agent-mcp.mdx +7 -4
  21. package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +125 -0
  22. package/docs/guides/connection.mdx +89 -0
  23. package/docs/guides/docker-bundling.mdx +13 -7
  24. package/docs/guides/fastapi.mdx +213 -3
  25. package/docs/guides/license.mdx +264 -109
  26. package/docs/guides/local-development.mdx +76 -0
  27. package/docs/guides/nx-generator.mdx +5 -0
  28. package/docs/guides/py-agent.mdx +42 -3
  29. package/docs/guides/py-dynamodb.mdx +449 -0
  30. package/docs/guides/py-mcp-server.mdx +5 -1
  31. package/docs/guides/react-website-auth.mdx +15 -0
  32. package/docs/guides/react-website.mdx +12 -4
  33. package/docs/guides/trpc.mdx +8 -8
  34. package/docs/guides/ts-agent.mdx +40 -2
  35. package/docs/guides/ts-dynamodb.mdx +158 -0
  36. package/docs/guides/ts-mcp-server.mdx +5 -1
  37. package/docs/guides/ts-rdb.mdx +58 -10
  38. package/docs/guides/ts-smithy-api.mdx +148 -3
  39. package/docs/guides/typescript-project.mdx +5 -10
  40. package/docs/guides/workspace.mdx +8 -2
  41. package/docs/snippets/api/type-safe-api-integrations.mdx +31 -0
  42. package/docs/snippets/api/waf-configuration.mdx +1 -1
  43. package/docs/snippets/connection/dynamodb-local-development.mdx +7 -0
  44. package/docs/snippets/connection/lambda-dynamodb-access.mdx +80 -0
  45. package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
  46. package/docs/snippets/dynamodb/deploying-table.mdx +171 -0
  47. package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
  48. package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
  49. package/docs/snippets/dynamodb/serve-local-start.mdx +13 -0
  50. package/docs/snippets/dynamodb/serve-local-windows.mdx +15 -0
  51. package/docs/snippets/mcp/config.mdx +1 -1
  52. package/docs/snippets/required-prerequisites.mdx +1 -1
  53. package/generators.json +100 -1
  54. package/package.json +1 -1
  55. package/src/agentcore-gateway/gateway-connection/schema.json +26 -0
  56. package/src/agentcore-gateway/mcp-connection/schema.json +26 -0
  57. package/src/agentcore-gateway/schema.json +65 -0
  58. package/src/license/schema.json +6 -0
  59. package/src/preset/schema.json +5 -0
  60. package/src/py/agent/gateway-connection/schema.json +26 -0
  61. package/src/py/dynamodb/agent-connection/schema.json +22 -0
  62. package/src/py/dynamodb/fast-api-connection/schema.json +18 -0
  63. package/src/py/dynamodb/mcp-server-connection/schema.json +22 -0
  64. package/src/py/dynamodb/schema.json +70 -0
  65. package/src/ts/agent/gateway-connection/schema.json +26 -0
  66. package/src/ts/dynamodb/agent-connection/schema.json +22 -0
  67. package/src/ts/dynamodb/mcp-server-connection/schema.json +22 -0
  68. package/src/ts/dynamodb/schema.json +70 -0
  69. package/src/ts/dynamodb/smithy-connection/schema.json +18 -0
  70. package/src/ts/dynamodb/trpc-connection/schema.json +18 -0
@@ -6,10 +6,12 @@ generator: license
6
6
  import { FileTree } from '@astrojs/starlight/components';
7
7
  import RunGenerator from '@components/run-generator.astro';
8
8
  import GeneratorParameters from '@components/generator-parameters.astro';
9
+ import Drawer from '@components/drawer.astro';
10
+ import LicenseAllowlist from '@components/license-allowlist.astro';
11
+ import NxCommands from '@components/nx-commands.astro';
12
+ import PackageManagerShortCommand from '@components/package-manager-short-command.astro';
9
13
 
10
- Automatically manage `LICENSE` files and source code headers in your workspace.
11
-
12
- This generator registers a [sync generator](https://nx.dev/concepts/sync-generators) to execute as part of your `lint` targets which will ensure that your source files conform to the desired license content and format, as well as ensuring that your project's `LICENSE` files are correct, and licensing information is included in relevant project files (`package.json`, `pyproject.toml`).
14
+ Manage licensing across your workspace: synchronise `LICENSE` files and source code headers for your own code (`license.source`), and check that every dependency conforms to a license allowlist (`license.dependencies`).
13
15
 
14
16
  ## Usage
15
17
 
@@ -26,15 +28,17 @@ This generator registers a [sync generator](https://nx.dev/concepts/sync-generat
26
28
  The generator will create or update the following files:
27
29
 
28
30
  <FileTree>
29
- - nx.json The lint target is configured to run the license sync generator
30
- - aws-nx-plugin.config.mts Configuration for the license sync generator
31
+ - nx.json The lint target is configured to run the license sync generator and depends on the license-check target
32
+ - aws-nx-plugin.config.mts Configuration for license source sync (`license.source`) and dependency checking (`license.dependencies`)
31
33
  </FileTree>
32
34
 
33
- Some default configuration for license header content and format is added to `aws-nx-plugin.config.mts` to write appropriate headers for a handful of file types. You may wish to customise this further; please see the [configuration section](#configuration) below.
35
+ ## License Headers & Files
36
+
37
+ The generator registers a [sync generator](https://nx.dev/concepts/sync-generators) to execute as part of your `lint` targets which ensures that your source files contain the correct license headers, your projects contain `LICENSE` files, and licensing metadata is set in `package.json` and `pyproject.toml`.
34
38
 
35
- ## Workflow
39
+ ### Workflow
36
40
 
37
- Whenever you build your projects (and a `lint` target runs), the license sync generator will make sure that the licensing in your project matches your configuration (see [license sync behaviour below](#license-sync-behaviour)). If it detects that anything is out of sync, you will receive a message such as:
41
+ Whenever you build your projects (and a `lint` target runs), the license sync generator will make sure that the licensing in your project matches your configuration. If it detects that anything is out of sync, you will receive a message such as:
38
42
 
39
43
  ```bash
40
44
  NX The workspace is out of sync
@@ -67,40 +71,36 @@ Select `Yes` to sync the changes.
67
71
  Make sure you check the changes the license sync generator makes in to version control to ensure that any continuous integration build tasks don't fail due to licenses being out of sync.
68
72
  :::
69
73
 
70
- ## License Sync Behaviour
74
+ ### Sync Behaviour
71
75
 
72
76
  The license sync generator performs three main tasks:
73
77
 
74
- ### 1. Synchronise Source File License Headers
78
+ #### 1. Synchronise Source File License Headers
75
79
 
76
80
  When the sync generator is run, it will ensure that all source code files in your workspace (based on your configuration) contain the appropriate license header. The header is written as the first block comment or consecutive series of line comments in the file (besides the shebang/hashbang if present in a file).
77
81
 
78
- You can update the configuration at any time to change which files should be included or excluded, as well as the content or format of license headers for different file types. For more details, please see the [configuration section](#configuration) below.
79
-
80
- ### 2. Synchronise LICENSE Files
82
+ #### 2. Synchronise LICENSE Files
81
83
 
82
84
  When the sync generator is run, it will ensure that the root `LICENSE` file corresponds to your configured license, as well as ensuring that all subprojects in your workspace also contain the correct `LICENSE` file.
83
85
 
84
- You can exclude projects in the configuration if required. For more details, please see the [configuration section](#configuration) below.
85
-
86
- ### 3. Synchronise licensing information in project files
86
+ #### 3. Synchronise licensing information in project files
87
87
 
88
88
  When the sync generator is run, it will ensure the `license` fields in `package.json` and `pyproject.toml` files are set to your configured license.
89
89
 
90
- You can exclude projects in the configuration if required. For more details, please see the [configuration section](#configuration) below.
91
-
92
- ## Configuration
90
+ ### Header & File Configuration
93
91
 
94
92
  Configuration is defined in the `aws-nx-plugin.config.mts` file in the root of your workspace.
95
93
 
96
- ### SPDX and Copyright Holder
94
+ #### SPDX and Copyright Holder
97
95
 
98
96
  Your chosen license can be updated at any time via the `spdx` configuration property:
99
97
 
100
- ```typescript title="aws-nx-plugin.config.mts" {3}
98
+ ```typescript title="aws-nx-plugin.config.mts" {4}
101
99
  export default {
102
100
  license: {
103
- spdx: 'MIT',
101
+ source: {
102
+ spdx: 'MIT',
103
+ },
104
104
  },
105
105
  } satisfies AwsNxPluginConfig;
106
106
  ```
@@ -109,36 +109,38 @@ When the sync generator runs, all `LICENSE` files, `package.json` and `pyproject
109
109
 
110
110
  You can additionally configure the copyright holder and copyright year, which are included in some `LICENSE` files:
111
111
 
112
- ```typescript title="aws-nx-plugin.config.mts" {4,5}
112
+ ```typescript title="aws-nx-plugin.config.mts" {5,6}
113
113
  export default {
114
114
  license: {
115
- spdx: 'MIT',
116
- copyrightHolder: 'Amazon.com, Inc. or its affiliates',
117
- copyrightYear: 2025,
115
+ source: {
116
+ spdx: 'MIT',
117
+ copyrightHolder: 'Amazon.com, Inc. or its affiliates',
118
+ copyrightYear: 2025,
119
+ },
118
120
  },
119
121
  } satisfies AwsNxPluginConfig;
120
122
  ```
121
123
 
122
- ### License Headers
123
-
124
- #### Content
124
+ #### License Header Content
125
125
 
126
126
  The license header content can be configured in two ways:
127
127
 
128
128
  1. Using inline content:
129
129
 
130
- ```typescript title="aws-nx-plugin.config.mts" {5-9}
130
+ ```typescript title="aws-nx-plugin.config.mts" {6-10}
131
131
  export default {
132
132
  license: {
133
- header: {
134
- content: {
135
- lines: [
136
- 'Copyright: My Company, Incorporated.',
137
- 'Licensed under the MIT License',
138
- 'All rights reserved',
139
- ];
133
+ source: {
134
+ header: {
135
+ content: {
136
+ lines: [
137
+ 'Copyright: My Company, Incorporated.',
138
+ 'Licensed under the MIT License',
139
+ 'All rights reserved',
140
+ ];
141
+ }
142
+ // ... format configuration
140
143
  }
141
- // ... format configuration
142
144
  }
143
145
  }
144
146
  } satisfies AwsNxPluginConfig;
@@ -146,51 +148,55 @@ export default {
146
148
 
147
149
  2. Loading from a file:
148
150
 
149
- ```typescript title="aws-nx-plugin.config.mts" {5}
151
+ ```typescript title="aws-nx-plugin.config.mts" {6}
150
152
  export default {
151
153
  license: {
152
- header: {
153
- content: {
154
- filePath: 'license-header.txt'; // relative to workspace root
154
+ source: {
155
+ header: {
156
+ content: {
157
+ filePath: 'license-header.txt'; // relative to workspace root
158
+ }
159
+ // ... format configuration
155
160
  }
156
- // ... format configuration
157
161
  }
158
162
  }
159
163
  } satisfies AwsNxPluginConfig;
160
164
  ```
161
165
 
162
- #### Format
166
+ #### Header Format
163
167
 
164
168
  You can specify how license headers should be formatted for different file types using glob patterns. The format configuration supports line comments, block comments, or a combination of both:
165
169
 
166
- ```typescript title="aws-nx-plugin.config.mts" {7-29}
170
+ ```typescript title="aws-nx-plugin.config.mts" {8-30}
167
171
  export default {
168
172
  license: {
169
- header: {
170
- content: {
171
- lines: ['Copyright notice here'],
172
- },
173
- format: {
174
- // Line comments
175
- '**/*.ts': {
176
- lineStart: '// ',
177
- },
178
- // Block comments
179
- '**/*.css': {
180
- blockStart: '/*',
181
- blockEnd: '*/',
173
+ source: {
174
+ header: {
175
+ content: {
176
+ lines: ['Copyright notice here'],
182
177
  },
183
- // Block comments with line prefixes
184
- '**/*.java': {
185
- blockStart: '/*',
186
- lineStart: ' * ',
187
- blockEnd: ' */',
188
- },
189
- // Line comments with header/footer
190
- '**/*.py': {
191
- blockStart: '# ------------',
192
- lineStart: '# ',
193
- blockEnd: '# ------------',
178
+ format: {
179
+ // Line comments
180
+ '**/*.ts': {
181
+ lineStart: '// ',
182
+ },
183
+ // Block comments
184
+ '**/*.css': {
185
+ blockStart: '/*',
186
+ blockEnd: '*/',
187
+ },
188
+ // Block comments with line prefixes
189
+ '**/*.java': {
190
+ blockStart: '/*',
191
+ lineStart: ' * ',
192
+ blockEnd: ' */',
193
+ },
194
+ // Line comments with header/footer
195
+ '**/*.py': {
196
+ blockStart: '# ------------',
197
+ lineStart: '# ',
198
+ blockEnd: '# ------------',
199
+ },
194
200
  },
195
201
  },
196
202
  },
@@ -209,27 +215,29 @@ The format configuration supports:
209
215
 
210
216
  For file types that aren't natively supported, you can specify custom comment syntax to tell the sync generator how to identify existing license headers in these file types.
211
217
 
212
- ```typescript title="aws-nx-plugin.config.mts" {12-22}
218
+ ```typescript title="aws-nx-plugin.config.mts" {13-23}
213
219
  export default {
214
220
  license: {
215
- header: {
216
- content: {
217
- lines: ['My license header'],
218
- },
219
- format: {
220
- '**/*.xyz': {
221
- lineStart: '## ',
221
+ source: {
222
+ header: {
223
+ content: {
224
+ lines: ['My license header'],
222
225
  },
223
- },
224
- commentSyntax: {
225
- xyz: {
226
- line: '##', // Define line comment syntax
226
+ format: {
227
+ '**/*.xyz': {
228
+ lineStart: '## ',
229
+ },
227
230
  },
228
- abc: {
229
- block: {
230
- // Define block comment syntax
231
- start: '<!--',
232
- end: '-->',
231
+ commentSyntax: {
232
+ xyz: {
233
+ line: '##', // Define line comment syntax
234
+ },
235
+ abc: {
236
+ block: {
237
+ // Define block comment syntax
238
+ start: '<!--',
239
+ end: '-->',
240
+ },
233
241
  },
234
242
  },
235
243
  },
@@ -238,56 +246,203 @@ export default {
238
246
  } satisfies AwsNxPluginConfig;
239
247
  ```
240
248
 
241
- #### Excluding files
249
+ #### Excluding Files from Header Sync
242
250
 
243
251
  By default, in a git repository, all `.gitignore` files are honored to ensure that only files managed by version control are synchronized. In non-git repositories, all files are considered unless explicitly excluded in configuration.
244
252
 
245
253
  You can exclude additional files from license header synchronization using glob patterns:
246
254
 
247
- ```typescript title="aws-nx-plugin.config.mts" {12-16}
255
+ ```typescript title="aws-nx-plugin.config.mts" {13}
248
256
  export default {
249
257
  license: {
250
- header: {
251
- content: {
252
- lines: ['My license header'],
253
- },
254
- format: {
255
- '**/*.ts': {
256
- lineStart: '// ',
258
+ source: {
259
+ header: {
260
+ content: {
261
+ lines: ['My license header'],
262
+ },
263
+ format: {
264
+ '**/*.ts': {
265
+ lineStart: '// ',
266
+ },
257
267
  },
268
+ exclude: ['**/generated/**', '**/dist/**', 'some-specific-file.ts'],
258
269
  },
259
- exclude: ['**/generated/**', '**/dist/**', 'some-specific-file.ts'],
260
270
  },
261
271
  },
262
272
  } satisfies AwsNxPluginConfig;
263
273
  ```
264
274
 
265
- ### Excluding project files from sync
275
+ #### Excluding Projects from File Sync
266
276
 
267
277
  All `LICENSE` files, `package.json` files and `pyproject.toml` files are synchronised with the configured license by default.
268
278
 
269
279
  You can exclude specific projects or files from synchronization using glob patterns:
270
280
 
271
- ```typescript title="aws-nx-plugin.config.mts" {3-10}
281
+ ```typescript title="aws-nx-plugin.config.mts" {4-11}
272
282
  export default {
273
283
  license: {
274
- files: {
275
- exclude: [
276
- // do not sync LICENSE file, package.json or pyproject.toml
277
- 'packages/excluded-project',
278
- // do not sync LICENSE file, but sync package.json and/or pyproject.toml
279
- 'apps/internal/LICENSE',
280
- ];
284
+ source: {
285
+ files: {
286
+ exclude: [
287
+ // do not sync LICENSE file, package.json or pyproject.toml
288
+ 'packages/excluded-project',
289
+ // do not sync LICENSE file, but sync package.json and/or pyproject.toml
290
+ 'apps/internal/LICENSE',
291
+ ];
292
+ }
281
293
  }
282
294
  }
283
295
  } satisfies AwsNxPluginConfig;
284
296
  ```
285
297
 
286
- ## Disabling license sync
298
+ ### Disabling License Sync
287
299
 
288
- To disable the license sync generator:
300
+ License source sync is enabled by the presence of the `license.source` key in your configuration. To disable it:
289
301
 
290
- 1. Remove the `license` section from your configuration in `aws-nx-plugin.config.mts` (or remove the `aws-nx-plugin.config.mts` file)
291
- 2. Remove the `@aws/nx-plugin:license#sync` generator from `targetDefaults.lint.syncGenerators`
302
+ 1. Remove the `license.source` section from your configuration in `aws-nx-plugin.config.mts` (you can keep `license.dependencies` if you still want dependency license checking)
303
+ 2. If you also want to fully remove the sync generator, remove the `@aws/nx-plugin:license#sync` generator from `targetDefaults.lint.syncGenerators`
292
304
 
293
305
  To re-enable license sync, simply run the `license` generator again.
306
+
307
+ ## Dependency License Checks
308
+
309
+ The `license` generator also configures a `license-check` target that fails when one of your project's dependencies (or any transitive dependency) declares a license that is not in your allowlist.
310
+
311
+ ### How it runs
312
+
313
+ The generator writes a `license-check` target to your root `project.json`:
314
+
315
+ ```json title="project.json"
316
+ {
317
+ "targets": {
318
+ "license-check": {
319
+ "executor": "@aws/nx-plugin:license-check",
320
+ "cache": true,
321
+ "inputs": [
322
+ "{workspaceRoot}/pnpm-lock.yaml",
323
+ "{workspaceRoot}/aws-nx-plugin.config.mts"
324
+ ],
325
+ "options": {}
326
+ }
327
+ }
328
+ }
329
+ ```
330
+
331
+ The `inputs` are computed for your workspace: only lockfiles that are actually present are included, along with `aws-nx-plugin.config.mts`, plus a `{workspaceRoot}/**/uv.lock` glob when Python dependency checking is enabled (i.e. a Python collector is configured).
332
+
333
+ You can run the check directly:
334
+
335
+ <NxCommands commands={['license-check']} />
336
+
337
+ Results are cached against your lockfiles and `aws-nx-plugin.config.mts` — re-runs are instant when nothing has changed.
338
+
339
+ Collectors determine what gets scanned. The `npmCollector` uses [license-checker-rseidelsohn](https://github.com/nicedoc/license-checker-rseidelsohn), and the `pythonCollector` uses [pip-licenses](https://github.com/raimon49/pip-licenses). If no installed dependencies are found, the check passes with nothing to inspect.
340
+
341
+ ### Running as part of lint/build
342
+
343
+ The dependency license check runs automatically whenever you `lint` or `build` any project in your workspace. The `license` generator wires each project's `lint` target to depend on the root `license-check` target, and the project generators (`ts#*` and `py#*`) do the same when they run — so the check is wired up regardless of the order generators are run in.
344
+
345
+ This means you don't need to run the check explicitly, though you can still do so with the `license-check` target:
346
+
347
+ <NxCommands commands={['license-check']} />
348
+
349
+ The wiring is a cross-project `dependsOn` on each project's `lint` target that points at the root `license-check` target. To skip the check during a lint or build, set the `LICENSE_DEPENDENCY_CHECK=skip` environment variable:
350
+
351
+ <PackageManagerShortCommand commands={["LICENSE_DEPENDENCY_CHECK=skip lint"]} />
352
+
353
+ ### Configuration
354
+
355
+ By default the check uses a built-in set of common permissive licenses (MIT, Apache-2.0, BSD, ISC, etc.) exported as `DEFAULT_LICENSE_ALLOWLIST`. You can extend or override this in your config:
356
+
357
+ ```typescript title="aws-nx-plugin.config.mts"
358
+ import { AwsNxPluginConfig } from '@aws/nx-plugin';
359
+ import { DEFAULT_LICENSE_ALLOWLIST } from '@aws/nx-plugin/sdk/license';
360
+
361
+ export default {
362
+ license: {
363
+ // ...
364
+ dependencies: {
365
+ allow: [...DEFAULT_LICENSE_ALLOWLIST, { spdxId: 'LGPL-2.1-or-later', fullName: 'GNU Lesser General Public License v2.1 or later', aliases: [] }],
366
+ exceptions: [
367
+ { package: 'some-package', reason: 'Audited manually — ships MIT text without SPDX field' },
368
+ ],
369
+ },
370
+ },
371
+ } satisfies AwsNxPluginConfig;
372
+ ```
373
+
374
+ <Drawer title="Default License Allowlist" trigger="View the full list of licenses in DEFAULT_LICENSE_ALLOWLIST">
375
+ <LicenseAllowlist />
376
+ </Drawer>
377
+
378
+ #### Customizing the allowlist
379
+
380
+ To restrict the allowlist, replace `DEFAULT_LICENSE_ALLOWLIST` with your own array. To extend it, spread the default and add entries. Entries are matched by SPDX id, full license name, or any of the listed aliases (case-insensitive).
381
+
382
+ #### Per-package exceptions
383
+
384
+ Use `exceptions` for packages that fail the check — either because their license is not in the allowlist, or because they ship without detectable license metadata. The `reason` field is required so reviewers can see why the exception was granted.
385
+
386
+ ```typescript
387
+ exceptions: [
388
+ {
389
+ package: 'union',
390
+ version: '0.5.0',
391
+ reason: 'Package ships verbatim MIT text without declaring license',
392
+ },
393
+ ];
394
+ ```
395
+
396
+ Generators that introduce dependencies with problematic metadata (e.g. the MCP server generator) automatically add the required exceptions to your config when they run.
397
+
398
+ #### Collectors
399
+
400
+ Collectors discover dependencies and extract license metadata. The built-in collectors are `npmCollector()` (scans `node_modules`) and `pythonCollector()` (scans Python virtual environments). The license generator configures `npmCollector()` by default and adds `pythonCollector()` when Python projects are present.
401
+
402
+ To implement a custom collector, conform to the `LicenseCollector` interface:
403
+
404
+ ```typescript
405
+ import type { LicenseCollector } from '@aws/nx-plugin/sdk/license';
406
+
407
+ const myCollector = (): LicenseCollector => ({
408
+ name: 'my-ecosystem',
409
+ traceCommand: 'my-tool why <package>',
410
+ async collect({ workspaceRoot }) {
411
+ return [
412
+ { name: 'some-dep', version: '1.0.0', rawLicense: 'MIT', ecosystem: 'my-ecosystem' },
413
+ ];
414
+ },
415
+ });
416
+ ```
417
+
418
+ #### The onDependency hook
419
+
420
+ `license.dependencies` accepts an optional `onDependency` callback that is invoked once for every discovered dependency, regardless of whether it passes or fails the check. It receives `{ package, spdx }`, where `package` is the package name and `spdx` is the resolved SPDX license expression. An exception's `spdx` takes precedence over the raw declared license, and `spdx` may be an empty string if no license was declared.
421
+
422
+ This is a handy way to print out all of the licenses across your project. Run the `license-check` target to see the output:
423
+
424
+ ```typescript title="aws-nx-plugin.config.mts"
425
+ import { AwsNxPluginConfig } from '@aws/nx-plugin';
426
+ import { DEFAULT_LICENSE_ALLOWLIST } from '@aws/nx-plugin/sdk/license';
427
+
428
+ export default {
429
+ license: {
430
+ dependencies: {
431
+ allow: DEFAULT_LICENSE_ALLOWLIST,
432
+ onDependency: ({ package: pkg, spdx }) => {
433
+ console.log(`${pkg} - ${spdx}`);
434
+ },
435
+ },
436
+ },
437
+ } satisfies AwsNxPluginConfig;
438
+ ```
439
+
440
+ ### Disabling Dependency Checks
441
+
442
+ Dependency license checking is enabled by the presence of the `license.dependencies` key in your configuration.
443
+
444
+ To disable the checks for a single run, set the `LICENSE_DEPENDENCY_CHECK=skip` environment variable:
445
+
446
+ <PackageManagerShortCommand commands={["LICENSE_DEPENDENCY_CHECK=skip lint"]} />
447
+
448
+ To disable permanently, remove the `license.dependencies` key from your configuration in `aws-nx-plugin.config.mts`. You can also re-run the `license` generator with `--dependencyCheck=false` to scaffold without it.
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: Local Development
3
+ description: How local development works with the serve and serve-local targets
4
+ ---
5
+ import Link from '@components/link.astro';
6
+ import NxCommands from '@components/nx-commands.astro';
7
+ import PackageManagerShortCommand from '@components/package-manager-short-command.astro';
8
+
9
+ Connected projects expose two targets for running them on your machine: `serve` and `serve-local`. The difference is one of **scope** — how much of your application runs locally versus pointing at deployed AWS infrastructure.
10
+
11
+ Consider a workspace with the following connections: a website that calls a tRPC `api`, and also calls an `agent` which in turn calls an `mcp` server.
12
+
13
+ ## `serve`
14
+
15
+ The `serve` target runs **only the targeted project** locally. Every other project it connects to is expected to be **deployed**, and is reached at its real AWS URL.
16
+
17
+ <NxCommands commands={['serve website']} />
18
+
19
+ Because the targeted project talks to deployed resources, it needs to know where they are. For a website this is provided by its `runtime-config.json` (see <Link path="guides/react-website#local-runtime-config">Local Runtime Config</Link>), which you load from a deployed application. For server-side projects (APIs and agents) that read <Link path="guides/runtime-config">Runtime Configuration</Link>, set the `RUNTIME_CONFIG_APP_ID` environment variable to point at your deployed AppConfig application.
20
+
21
+ ```d2
22
+ direction: right
23
+
24
+ local: Local {
25
+ style.stroke-dash: 3
26
+ website: website
27
+ }
28
+ deployed: Deployed {
29
+ style.stroke-dash: 3
30
+ api: api
31
+ agent: agent
32
+ mcp: mcp
33
+ }
34
+
35
+ local.website -> deployed.api
36
+ local.website -> deployed.agent
37
+ deployed.agent -> deployed.mcp
38
+ ```
39
+
40
+ Use `serve` when you want to iterate on a single project against the "real", deployed versions of everything it depends on.
41
+
42
+ ## `serve-local`
43
+
44
+ The `serve-local` target runs the **targeted project** and **every project connected to it transitively**, all on your machine. The connection generator wires this up automatically — running `serve-local` on the website also starts local servers for the `api`, the `agent`, and the `mcp` server it reaches through the agent.
45
+
46
+ <NxCommands commands={['serve-local website']} />
47
+
48
+ When run this way, the website's `runtime-config.json` is automatically overridden (via [Vite's `MODE`](https://vite.dev/guide/env-and-mode), set to `serve-local`) so that it points at your locally running servers instead of deployed URLs.
49
+
50
+ ```d2
51
+ direction: right
52
+
53
+ local: Local {
54
+ style.stroke-dash: 3
55
+ website: website
56
+ api: api
57
+ agent: agent
58
+ mcp: mcp
59
+
60
+ website -> api
61
+ website -> agent
62
+ agent -> mcp
63
+ }
64
+ ```
65
+
66
+ Every project runs locally, so there are no deployed dependencies.
67
+
68
+ Use `serve-local` when you are working across several connected projects at once and want to iterate quickly without deploying your infrastructure.
69
+
70
+ :::tip[`dev` shortcut]
71
+ A root `dev` script is added as a shortcut for the first website you generate in your workspace, so you can spin up the website and all connected components with:
72
+
73
+ <PackageManagerShortCommand commands={["dev"]} />
74
+ :::
75
+
76
+ For more detail on each project type's local development server, see the relevant guide — for example the <Link path="guides/react-website#local-development-server">React Website</Link> guide.
@@ -395,6 +395,10 @@ import { formatFilesInSubtree } from '@aws/nx-plugin/sdk/utils/format';
395
395
  await formatFilesInSubtree(tree, 'optional/path/to/format');
396
396
  ```
397
397
 
398
+ :::note
399
+ `formatFilesInSubtree` formats TypeScript, JavaScript, JSON and CSS files with [Biome](https://biomejs.dev/), and Python files with [Ruff](https://docs.astral.sh/ruff/). When the workspace already has a `biome.json` on disk, it uses your workspace's installed version of Biome and its configuration. Otherwise it falls back to a bundled Biome, applying any `biome.json` present in the virtual tree.
400
+ :::
401
+
398
402
  #### Reading and Updating JSON Files
399
403
 
400
404
  ```typescript
@@ -579,6 +583,7 @@ When this generator is run in our repository, it'll generate the following files
579
583
  - docs/src/content/docs/guides/
580
584
  - \<name>.mdx Documentation page for your generator
581
585
  - packages/nx-plugin/generators.json Updated to include your generator
586
+ - packages/nx-plugin/sdk/\<prefix>.ts Updated to expose your generator from the SDK (for `ts#` and `py#` generators)
582
587
  </FileTree>
583
588
 
584
589
  You can then start to implement your generator.
@@ -351,19 +351,58 @@ This command uses `uv run` to execute your Agent using the [Bedrock AgentCore Py
351
351
 
352
352
  ### Chat with Your Agent
353
353
 
354
- The generator configures a `<your-agent-name>-chat` Nx target that depends on `<your-agent-name>-serve-local`. Running it starts the agent locally and drops you into an interactive terminal chat:
354
+ The generator configures a `<your-agent-name>-chat` Nx target that drops you into an interactive terminal chat with your agent.
355
+
356
+ The chat target runs standalone. By default it connects to your locally running agent, so start `<your-agent-name>-serve-local` first (in a separate terminal):
357
+
358
+ <NxCommands commands={['run your-project:agent-serve-local']} />
359
+
360
+ Then, in another terminal, start the chat:
355
361
 
356
362
  <NxCommands commands={['run your-project:agent-chat']} />
357
363
 
358
- For **HTTP** agents, the generator also emits:
364
+ The generator emits a `scripts/<your-agent-name>/chat.ts` for every protocol. It connects to the local agent by default, or to your deployed agent when `RUNTIME_CONFIG_APP_ID` is set (see [Chat with your deployed agent](#chat-with-your-deployed-agent) below).
365
+
366
+ For **HTTP** agents, the chat script uses a type-safe TypeScript client generated from the agent's OpenAPI spec. The generator also emits:
359
367
 
360
368
  - `scripts/<your-agent-name>_openapi.py` — a small script that exports the agent's OpenAPI spec
361
369
  - An `<your-agent-name>-openapi` Nx target that runs it
362
370
  - An `<your-agent-name>-generate-client` Nx target that produces a type-safe TypeScript client under `scripts/<your-agent-name>/generated/`
363
- - `scripts/<your-agent-name>/chat.ts` — a thin wrapper around the generated client
364
371
 
365
372
  When you customize the agent's input shape (e.g. add new fields to `InvokeInput`), update `chat.ts` to pass the new fields when invoking the agent and the rest works automatically.
366
373
 
374
+ <OptionFilter when={{ infra: 'agentcore' }} description="Deployed agent chat details">
375
+ #### Chat with your deployed agent
376
+
377
+ To chat with your agent deployed to Bedrock AgentCore, set the `RUNTIME_CONFIG_APP_ID` environment variable to the AppConfig application id of the deployment (output as `RuntimeConfigApplicationId` by the deployed stack). The chat script resolves your agent's runtime ARN from runtime configuration and connects to the deployed endpoint:
378
+
379
+ <Tabs syncKey="auth">
380
+ <TabItem label="IAM" _filter={{ auth: 'iam' }}>
381
+ For IAM-authenticated agents, requests are signed with [SigV4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) using your default AWS credentials. Ensure the environment has AWS credentials with permission to invoke the runtime:
382
+
383
+ <NxCommands commands={['run your-project:agent-chat']} env={{ RUNTIME_CONFIG_APP_ID: '<app-id>' }} />
384
+ </TabItem>
385
+
386
+ <TabItem label="Cognito" _filter={{ auth: 'cognito' }}>
387
+ For Cognito-authenticated agents, provide a Cognito access token via the `AGENT_ACCESS_TOKEN` environment variable, which is sent as a bearer token:
388
+
389
+ <NxCommands commands={['run your-project:agent-chat']} env={{ RUNTIME_CONFIG_APP_ID: '<app-id>', AGENT_ACCESS_TOKEN: '<access-token>' }} />
390
+
391
+ You can obtain an access token using the AWS CLI's `cognito-idp admin-initiate-auth` command, for example:
392
+
393
+ ```bash
394
+ aws cognito-idp admin-initiate-auth \
395
+ --user-pool-id <user-pool-id> \
396
+ --client-id <user-pool-client-id> \
397
+ --auth-flow ADMIN_NO_SRP_AUTH \
398
+ --auth-parameters USERNAME=<username>,PASSWORD=<password> \
399
+ --query 'AuthenticationResult.AccessToken' \
400
+ --output text
401
+ ```
402
+ </TabItem>
403
+ </Tabs>
404
+ </OptionFilter>
405
+
367
406
  <OptionFilter when={{ infra: 'agentcore' }} description="Bedrock AgentCore Runtime deployment details">
368
407
  ## Deploying Your Agent to Bedrock AgentCore Runtime
369
408