@aws/nx-plugin-mcp 1.0.0-rc.96 → 1.0.0-rc.98

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 (72) hide show
  1. package/bin/aws-nx-mcp.js +90 -45
  2. package/docs/get_started/existing-project.mdx +7 -4
  3. package/docs/get_started/quick-start.mdx +58 -5
  4. package/docs/get_started/tutorials/dungeon-game/1.mdx +23 -20
  5. package/docs/get_started/tutorials/dungeon-game/2.mdx +11 -3
  6. package/docs/get_started/tutorials/dungeon-game/3.mdx +4 -0
  7. package/docs/get_started/tutorials/dungeon-game/4.mdx +7 -2
  8. package/docs/get_started/tutorials/dungeon-game/wrap-up.mdx +10 -1
  9. package/docs/guides/agentcore-gateway.mdx +4 -2
  10. package/docs/guides/agentcore-harness.mdx +2 -1
  11. package/docs/guides/astro-docs.mdx +25 -7
  12. package/docs/guides/connection/py-agent-a2a.mdx +2 -0
  13. package/docs/guides/connection/py-agent-dynamodb.mdx +1 -1
  14. package/docs/guides/connection/py-agent-gateway.mdx +3 -0
  15. package/docs/guides/connection/py-agent-mcp.mdx +18 -4
  16. package/docs/guides/connection/py-agent-rdb.mdx +5 -4
  17. package/docs/guides/connection/py-fast-api-dynamodb.mdx +1 -1
  18. package/docs/guides/connection/py-fast-api-rdb.mdx +7 -2
  19. package/docs/guides/connection/py-mcp-server-dynamodb.mdx +1 -1
  20. package/docs/guides/connection/py-mcp-server-rdb.mdx +6 -6
  21. package/docs/guides/connection/react-agui.mdx +34 -25
  22. package/docs/guides/connection/react-fastapi.mdx +114 -116
  23. package/docs/guides/connection/react-py-agent.mdx +4 -0
  24. package/docs/guides/connection/react-smithy.mdx +152 -98
  25. package/docs/guides/connection/react-trpc.mdx +13 -6
  26. package/docs/guides/connection/smithy-dynamodb.mdx +2 -8
  27. package/docs/guides/connection/smithy-rdb.mdx +3 -6
  28. package/docs/guides/connection/trpc-rdb.mdx +6 -6
  29. package/docs/guides/connection/ts-agent-a2a.mdx +4 -4
  30. package/docs/guides/connection/ts-agent-dynamodb.mdx +13 -11
  31. package/docs/guides/connection/ts-agent-gateway.mdx +2 -0
  32. package/docs/guides/connection/ts-agent-mcp.mdx +19 -7
  33. package/docs/guides/connection/ts-agent-rdb.mdx +2 -2
  34. package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +11 -7
  35. package/docs/guides/connection/ts-mcp-server-rdb.mdx +4 -3
  36. package/docs/guides/docker-bundling.mdx +23 -3
  37. package/docs/guides/fastapi.mdx +16 -5
  38. package/docs/guides/license.mdx +30 -6
  39. package/docs/guides/nx-generator.mdx +11 -12
  40. package/docs/guides/py-agent.mdx +129 -54
  41. package/docs/guides/py-mcp-server.mdx +3 -1
  42. package/docs/guides/py-rdb.mdx +13 -4
  43. package/docs/guides/python-lambda-function.mdx +8 -8
  44. package/docs/guides/python-project.mdx +28 -25
  45. package/docs/guides/react-website-auth.mdx +8 -8
  46. package/docs/guides/react-website.mdx +46 -27
  47. package/docs/guides/runtime-config.mdx +24 -4
  48. package/docs/guides/security.mdx +1 -1
  49. package/docs/guides/terraform-project.mdx +8 -2
  50. package/docs/guides/trpc.mdx +96 -12
  51. package/docs/guides/ts-agent.mdx +17 -3
  52. package/docs/guides/ts-dcr-proxy.mdx +24 -6
  53. package/docs/guides/ts-lambda-function.mdx +7 -1
  54. package/docs/guides/ts-mcp-server.mdx +45 -15
  55. package/docs/guides/ts-nx-plugin.mdx +17 -7
  56. package/docs/guides/ts-rdb.mdx +9 -2
  57. package/docs/guides/ts-smithy-api.mdx +76 -7
  58. package/docs/guides/typescript-infrastructure.mdx +27 -11
  59. package/docs/guides/typescript-project.mdx +12 -5
  60. package/docs/guides/workspace.mdx +21 -9
  61. package/docs/snippets/api/type-safe-api-integrations.mdx +2 -0
  62. package/docs/snippets/connection/a2a-infrastructure.mdx +3 -0
  63. package/docs/snippets/connection/infra-project-prerequisite.mdx +8 -0
  64. package/docs/snippets/connection/strands-agent-rdb-ssl-requirements.mdx +1 -1
  65. package/docs/snippets/connection/ts-lambda-rdb-ssl-requirements.mdx +1 -1
  66. package/docs/snippets/connection/ts-mcp-server-rdb-ssl-requirements.mdx +1 -1
  67. package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +1 -1
  68. package/docs/snippets/prerequisites.mdx +1 -1
  69. package/docs/snippets/required-prerequisites.mdx +1 -1
  70. package/package.json +1 -1
  71. package/src/init/schema.json +5 -0
  72. package/src/py/project/schema.json +3 -1
@@ -42,7 +42,9 @@ The generator creates a new project at `packages/<name>/`, plus a CDK construct
42
42
  - permit-all.cedar Default Cedar policy that permits authenticated callers
43
43
  - README.md Reference for writing Cedar policies
44
44
  - local-dev.ts Local gateway for local development — aggregates attached MCP servers (`mcp`) or proxies attached agents (`http`)
45
- - project.json Adds the `serve` and `dev` targets
45
+ - package.json Declares the dependencies `local-dev.ts` imports
46
+ - tsconfig.json TypeScript configuration used by the `typecheck` target
47
+ - project.json Adds the `serve`, `dev`, `build`, `lint`, `format` and `typecheck` targets
46
48
  </FileTree>
47
49
 
48
50
  ### Infrastructure
@@ -133,7 +135,7 @@ The generated infrastructure consumes an existing Cognito user pool and client
133
135
  The generated construct requires an `identity` prop supplying the user pool and client:
134
136
 
135
137
  ```ts {7,9-11} title="packages/infra/src/stacks/application-stack.ts"
136
- import { MyGateway, UserIdentity } from ':my-scope/common-constructs';
138
+ import { MyGateway, UserIdentity } from '@my-scope/common-constructs';
137
139
 
138
140
  export class ApplicationStack extends Stack {
139
141
  constructor(scope: Construct, id: string, props?: StackProps) {
@@ -32,7 +32,8 @@ The generator creates a standalone project at `packages/<name>/`. Because AWS ru
32
32
  - packages/\<name>/
33
33
  - src/PROMPT.md The Harness system prompt
34
34
  - scripts/chat.ts Multi-turn chat client for the deployed Harness
35
- - project.json Adds the `chat` target
35
+ - tsconfig.json TypeScript configuration used by the `typecheck` target
36
+ - project.json Adds the `chat`, `build`, `lint`, `format` and `typecheck` targets
36
37
  - README.md Chat and customization instructions
37
38
  </FileTree>
38
39
 
@@ -43,7 +43,9 @@ workspace root (configurable via the `name`, `directory` and `subDirectory` opti
43
43
  - scripts
44
44
  - translate.ts Translation driver — a Strands agent with a scoped file-editor tool (omitted with `--noTranslation`)
45
45
  - translate.config.json Source/target locales, glob patterns, model id, region (omitted with `--noTranslation`)
46
+ - .gitignore Ignores Astro's build output and generated types
46
47
  - src
48
+ - content.config.ts Starlight's docs content collection definition
47
49
  - components
48
50
  - link.astro Locale-aware link component (resolves paths against the current locale)
49
51
  - snippet.astro Locale-aware snippet loader component
@@ -74,14 +76,29 @@ it. To add more languages:
74
76
  ## Translation
75
77
 
76
78
  Unless you passed `--noTranslation`, the generator adds a `translate` target to
77
- `project.json`, so you can run:
79
+ `project.json`. Which locales it translates to comes from `targetLanguages` in
80
+ `scripts/translate.config.json`, which ships empty — so start by naming the
81
+ locales you want on the command line:
78
82
 
79
83
  <NxCommands commands={[
80
- 'translate docs -- --all',
81
84
  'translate docs -- --languages jp,ko',
85
+ 'translate docs -- --languages jp,ko --dry-run',
86
+ ]} />
87
+
88
+ Once you have populated `targetLanguages` (see [Configuring
89
+ translation](#configuring-translation)), `--languages` becomes optional and the
90
+ configured locales are used:
91
+
92
+ <NxCommands commands={[
93
+ 'translate docs -- --all',
82
94
  'translate docs -- --dry-run',
83
95
  ]} />
84
96
 
97
+ :::caution[Configure your target languages first]
98
+ Without `--languages` and with `targetLanguages` still empty, the target exits
99
+ non-zero with `ERROR No target languages configured`.
100
+ :::
101
+
85
102
  When run without `--all`, the script only translates files that have changed
86
103
  since the last translation commit on the current branch — meaning you can
87
104
  safely re-run it on every docs PR without re-translating the whole site.
@@ -145,8 +162,9 @@ No CI workflow is generated out of the box — add one that:
145
162
 
146
163
  <NxCommands commands={['translate docs']} />
147
164
 
148
- 3. Commits the resulting translations back to the PR branch. The commit message
149
- must match the `translationCommitMessage` value in
150
- `scripts/translate.config.json` (default `docs: update translations`) so that
151
- subsequent incremental runs can detect the baseline commit and only
152
- re-translate the files that changed since.
165
+ 3. Commits the resulting translations back to the PR branch, using
166
+ `docs: update translations` as the commit message, so that subsequent
167
+ incremental runs can detect the baseline commit and only re-translate the
168
+ files that changed since. To use a different message, add a
169
+ `translationCommitMessage` key to `scripts/translate.config.json` and match
170
+ that value instead.
@@ -48,11 +48,13 @@ The generator creates a shared `agent_connection` Python project at `packages/co
48
48
  - \<scope>\_agent\_connection
49
49
  - \_\_init\_\_.py Re-exports per-connection clients
50
50
  - core
51
+ - \_\_init\_\_.py Python package initialization
51
52
  - agentcore\_endpoints.py Framework-agnostic ARN/URL resolution
52
53
  - agentcore\_a2a\_client\_config.py Framework-agnostic A2A client config (signed `ClientConfig`)
53
54
  - agentcore\_a2a\_client\_\<framework>.py A2A client wrapping the config for your agent's framework
54
55
  - auth/ Framework-agnostic SigV4 / session-forwarding `httpx.Auth`
55
56
  - app
57
+ - \_\_init\_\_.py Python package initialization
56
58
  - \<target\_agent\_name>\_client\_\<framework>.py Per-connection A2A client for each A2A agent
57
59
 
58
60
  </FileTree>
@@ -41,7 +41,7 @@ The generator updates the agent's `<agent-name>-dev` target in `project.json` to
41
41
  Import entity classes from the DynamoDB package and use them inside your agent tools:
42
42
 
43
43
  ```python title="packages/my_project/my_project/my_agent/agent.py"
44
- from my_scope.my_table.entities.example import ExampleModel
44
+ from my_scope_my_table.entities.example import ExampleModel
45
45
  from strands import tool
46
46
 
47
47
  @tool
@@ -50,11 +50,14 @@ The generator emits shared core-gateway modules into your `agent_connection` Pyt
50
50
  - packages/common/agent\_connection
51
51
  - \<scope>\_agent\_connection
52
52
  - core/
53
+ - \_\_init\_\_.py Python package initialization
53
54
  - agentcore\_endpoints.py Framework-agnostic ARN/URL resolution
55
+ - agentcore\_transport.py Shared AgentCore transport plumbing
54
56
  - agentcore\_gateway\_mcp\_transport.py Framework-agnostic Gateway MCP transport
55
57
  - agentcore\_gateway\_mcp\_client\_\<framework>.py Gateway MCP client for your agent's framework
56
58
  - auth/ Framework-agnostic SigV4 / session-forwarding `httpx.Auth`
57
59
  - app/
60
+ - \_\_init\_\_.py Python package initialization
58
61
  - \<gateway\_snake>\_client\_\<framework>.py Per-Gateway client wrapper
59
62
  - \_\_init\_\_.py Re-exports the Gateway client
60
63
 
@@ -13,6 +13,7 @@ import RunGenerator from '@components/run-generator.astro';
13
13
  import GeneratorParameters from '@components/generator-parameters.astro';
14
14
  import NxCommands from '@components/nx-commands.astro';
15
15
  import Infrastructure from '@components/infrastructure.astro';
16
+ import Snippet from '@components/snippet.astro';
16
17
 
17
18
  The `connection` generator can connect your <Link path="guides/py-agent">Python Agent</Link> to an MCP server (either <Link path="guides/ts-mcp-server">TypeScript</Link> or <Link path="guides/py-mcp-server">Python</Link>).
18
19
 
@@ -48,11 +49,14 @@ The generator creates a shared `agent_connection` Python project at `packages/co
48
49
  - \<scope>\_agent\_connection
49
50
  - \_\_init\_\_.py Re-exports per-connection clients
50
51
  - core
52
+ - \_\_init\_\_.py Python package initialization
51
53
  - agentcore\_endpoints.py Framework-agnostic ARN/URL resolution
54
+ - agentcore\_transport.py Shared AgentCore transport plumbing
52
55
  - agentcore\_mcp\_transport.py Framework-agnostic MCP transport
53
56
  - agentcore\_mcp\_client\_\<framework>.py MCP client wrapping the transport for your agent's framework
54
57
  - auth/ Framework-agnostic SigV4 / session-forwarding `httpx.Auth`
55
58
  - app
59
+ - \_\_init\_\_.py Python package initialization
56
60
  - \<mcp\_server\_name>\_client\_\<framework>.py Per-connection client for each MCP server
57
61
 
58
62
  </FileTree>
@@ -114,6 +118,8 @@ The AgentCore session ID is propagated to the MCP server automatically via the `
114
118
 
115
119
  ## Infrastructure
116
120
 
121
+ <Snippet name="connection/infra-project-prerequisite" />
122
+
117
123
  <Infrastructure>
118
124
  <Fragment slot="cdk">
119
125
  After running the connection generator, you need to grant the agent permission to invoke the MCP server:
@@ -126,12 +132,14 @@ const myAgent = new MyAgent(this, 'MyAgent');
126
132
  mcpServer.grantInvokeAccess(myAgent);
127
133
  ```
128
134
 
135
+ `grantInvokeAccess` wires up the AgentCore invoke actions (`InvokeAgentRuntime`, `InvokeAgentRuntimeForUser` and `InvokeAgentRuntimeWithWebSocketStream`) on the MCP server's runtime ARN.
136
+
129
137
  The MCP server's AgentCore runtime ARN is automatically registered in the `agentcore` namespace of <Link path="guides/runtime-config">Runtime Configuration</Link> by the generated CDK construct, so the agent can discover it at runtime.
130
138
  </Fragment>
131
139
  <Fragment slot="terraform">
132
140
  After running the connection generator, you need to grant the agent permission to invoke the MCP server in your Terraform configuration:
133
141
 
134
- ```hcl title="packages/infra/src/main.tf" {9-25}
142
+ ```hcl title="packages/infra/src/main.tf" {9-31}
135
143
  module "inventory_mcp_server" {
136
144
  source = "../../common/terraform/src/app/mcp-servers/inventory-mcp"
137
145
  }
@@ -146,9 +154,15 @@ resource "aws_iam_policy" "agent_invoke_mcp" {
146
154
  policy = jsonencode({
147
155
  Version = "2012-10-17"
148
156
  Statement = [{
149
- Effect = "Allow"
150
- Action = "bedrock-agentcore:InvokeAgent"
151
- Resource = module.inventory_mcp_server.agent_core_runtime_arn
157
+ Effect = "Allow"
158
+ Action = [
159
+ "bedrock-agentcore:InvokeAgentRuntime",
160
+ "bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream",
161
+ ]
162
+ Resource = [
163
+ module.inventory_mcp_server.agent_core_runtime_arn,
164
+ "${module.inventory_mcp_server.agent_core_runtime_arn}/*",
165
+ ]
152
166
  }]
153
167
  })
154
168
  }
@@ -42,7 +42,7 @@ Select your Agent project as the source and your relational database project as
42
42
  - pyproject.toml Adds the database package as a workspace dependency
43
43
  - my\_service
44
44
  - my\_agent
45
- - Dockerfile Adds the RDS CA bundle used for direct Aurora connections
45
+ - Dockerfile Adds the RDS CA bundle used for direct Aurora connections (only when the agent's `infra` is `agentcore-ecr`)
46
46
 
47
47
  </FileTree>
48
48
 
@@ -52,15 +52,16 @@ Import `session_context` from your database package and use it inside your agent
52
52
 
53
53
  ```python title="packages/my_service/my_service/my_agent/agent.py"
54
54
  from sqlmodel import select
55
- from my_scope.my_db import session_context
56
- from my_scope.my_db.models.example import ExampleModel
55
+ from my_scope_my_db import session_context
56
+ from my_scope_my_db.models.example import ExampleModel
57
57
  from strands import tool
58
58
 
59
59
  @tool
60
60
  async def list_examples() -> list:
61
61
  """List all example records."""
62
62
  async with session_context() as session:
63
- return [item.model_dump() for item in (await session.execute(select(ExampleModel))).all()]
63
+ items = (await session.execute(select(ExampleModel))).scalars().all()
64
+ return [item.model_dump() for item in items]
64
65
  ```
65
66
 
66
67
  ## Infrastructure
@@ -40,7 +40,7 @@ The generator updates the FastAPI's `project.json` to add a dependency from its
40
40
  Import entity classes from the DynamoDB package and use them inside your route handlers:
41
41
 
42
42
  ```python title="packages/my_api/my_api/api.py"
43
- from my_scope.my_table.entities.example import ExampleModel
43
+ from my_scope_my_table.entities.example import ExampleModel
44
44
 
45
45
  @app.get("/examples")
46
46
  def list_examples():
@@ -11,6 +11,7 @@ import RunGenerator from '@components/run-generator.astro';
11
11
  import GeneratorParameters from '@components/generator-parameters.astro';
12
12
  import NxCommands from '@components/nx-commands.astro';
13
13
  import Infrastructure from '@components/infrastructure.astro';
14
+ import Snippet from '@components/snippet.astro';
14
15
 
15
16
  The `connection` generator wires a <Link path="guides/fastapi">FastAPI</Link> to a <Link path="guides/py-rdb">Python Relational Database</Link> project, injecting a typed SQLModel session into your route handlers via a FastAPI dependency.
16
17
 
@@ -55,11 +56,11 @@ This generator configures an injectable [FastAPI Dependency](https://fastapi.tia
55
56
  ```python title="packages/my_api/my_api/api.py" {2,6,10}
56
57
  from sqlmodel import select
57
58
  from my_api.dependencies.my_db import MyDbSession
58
- from my_scope.my_db.models.example import ExampleModel
59
+ from my_scope_my_db.models.example import ExampleModel
59
60
 
60
61
  @app.get("/examples")
61
62
  async def list_examples(my_db: MyDbSession):
62
- return (await my_db.execute(select(ExampleModel))).all()
63
+ return (await my_db.execute(select(ExampleModel))).scalars().all()
63
64
 
64
65
  @app.post("/examples")
65
66
  async def create_example(name: str, my_db: MyDbSession):
@@ -168,6 +169,10 @@ The AppConfig application exposes the `database` namespace by default, so the da
168
169
  </Fragment>
169
170
  </Infrastructure>
170
171
 
172
+ ### SSL Requirements When Connecting Without RDS Proxy
173
+
174
+ <Snippet name="connection/py-lambda-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
175
+
171
176
  ## Local Development
172
177
 
173
178
  <NxCommands commands={["dev <project-name>"]} />
@@ -41,7 +41,7 @@ The generator updates the MCP server's `<mcp-server-name>-dev` target in `projec
41
41
  Import entity classes from the DynamoDB package and use them inside your MCP server tools:
42
42
 
43
43
  ```python title="packages/my_project/my_project/my_mcp_server/server.py"
44
- from my_scope.my_table.entities.example import ExampleModel
44
+ from my_scope_my_table.entities.example import ExampleModel
45
45
 
46
46
  @mcp.tool()
47
47
  def list_examples() -> str:
@@ -42,7 +42,7 @@ Select your MCP server project as the source and your relational database projec
42
42
  - pyproject.toml Adds the database package as a workspace dependency
43
43
  - my\_service
44
44
  - my\_mcp\_server
45
- - Dockerfile Adds the RDS CA bundle used for direct Aurora connections
45
+ - Dockerfile Adds the RDS CA bundle used for direct Aurora connections (only when the MCP server's `infra` is `agentcore-ecr`)
46
46
 
47
47
  </FileTree>
48
48
 
@@ -52,14 +52,14 @@ Import `session_context` from your database package and use it inside your MCP s
52
52
 
53
53
  ```python title="packages/my_service/my_service/my_mcp_server/server.py"
54
54
  from sqlmodel import select
55
- from my_scope.my_db import session_context
56
- from my_scope.my_db.models.example import ExampleModel
55
+ from my_scope_my_db import session_context
56
+ from my_scope_my_db.models.example import ExampleModel
57
57
 
58
58
  @mcp.tool()
59
59
  async def list_examples() -> str:
60
60
  """List all example records."""
61
61
  async with session_context() as session:
62
- items = (await session.execute(select(ExampleModel))).all()
62
+ items = (await session.execute(select(ExampleModel))).scalars().all()
63
63
  return str([item.model_dump() for item in items])
64
64
  ```
65
65
 
@@ -68,8 +68,8 @@ async def list_examples() -> str:
68
68
  Running the generator again with a different target adds the second database alongside the first. Both session contexts are available to all tools:
69
69
 
70
70
  ```python title="packages/my_service/my_service/my_mcp_server/server.py"
71
- from my_scope.my_db import session_context as my_db_session_context
72
- from my_scope.other_db import session_context as other_db_session_context
71
+ from my_scope_my_db import session_context as my_db_session_context
72
+ from my_scope_other_db import session_context as other_db_session_context
73
73
  ```
74
74
 
75
75
  ## Infrastructure
@@ -46,16 +46,17 @@ The generator creates a **single shared** `AguiProvider` component, one hook per
46
46
  - src
47
47
  - components
48
48
  - AguiProvider.tsx Single `CopilotKitProvider` for every AG-UI agent. Created on the first `connection` run and updated on subsequent runs to register each new agent.
49
+ - \<agent-name>-chat.tsx A themed `<AgentName>Chat` bound to this agent's id. One file per `connection` run.
49
50
  - copilot
50
51
  - index.tsx Re-exports `CopilotChat`, `CopilotSidebar` and `CopilotPopup` with slot defaults that match your website's `ux` (Cloudscape, Shadcn, or no theme at all).
51
52
  - *ThemeComponents*.tsx Per-slot theme components (e.g. `CloudscapeAssistantMessage.tsx`, `ShadcnChatInput.tsx`). Only vended when `ux` is `cloudscape` or `shadcn`.
52
53
  - hooks
53
- - useAgui\<AgentName>.tsx Registers one AG-UI agent. One file per `connection` run.
54
+ - useAgui\<AgentName>.tsx Registers one AG-UI agent and exports its id as `<AGENT_NAME>_ID`. One file per `connection` run.
54
55
  - useSigV4.tsx SigV4 signing (IAM only)
55
56
 
56
57
  </FileTree>
57
58
 
58
- Running `connection` a second time for a different agent **adds a new `useAgui<AgentName>.tsx` hook** and updates `AguiProvider.tsx` to register both hooks — any custom edits you've made to the provider are preserved. `main.tsx` keeps its single `<AguiProvider>` wrapper — you never end up with nested providers.
59
+ Running `connection` a second time for a different agent **adds a new `useAgui<AgentName>.tsx` hook and `<agent-name>-chat.tsx` component** and updates `AguiProvider.tsx` to register both hooks — any custom edits you've made to the provider are preserved. `main.tsx` keeps its single `<AguiProvider>` wrapper — you never end up with nested providers.
59
60
 
60
61
  The following dependencies are added to the root `package.json`:
61
62
 
@@ -119,17 +120,14 @@ Both Session ID and Thread ID are provided by the browser. To restrict each user
119
120
 
120
121
  ### Adding a Chat Interface
121
122
 
122
- Instantiate CopilotKit components with `agentId` to select which agent to use. The id is the agent's name — the same one you chose when you ran the <Link path="guides/ts-agent">`ts#agent`</Link> or <Link path="guides/py-agent">`py#agent`</Link> generator — and you can also find it in the generated hook file (e.g. the key returned from `packages/web/src/hooks/useAgui<AgentName>.tsx`).
123
-
124
- Import the chat components from the generated `./components/copilot` module so the theme that matches your website's `ux` is applied automatically:
123
+ The generator vends a `<AgentName>Chat` component per connected agent, already bound to that agent's id and themed to match your website's `ux`. Drop it anywhere inside the `<AguiProvider>` wrapper:
125
124
 
126
125
  ```tsx
127
- import { CopilotChat } from './components/copilot';
126
+ import { StoryAgentChat } from './components/story-agent-chat';
128
127
 
129
128
  function ChatPage() {
130
129
  return (
131
- <CopilotChat
132
- agentId="agent"
130
+ <StoryAgentChat
133
131
  labels={{
134
132
  welcomeMessageText: 'How can I help you today?',
135
133
  chatInputPlaceholder: 'Ask me anything...',
@@ -139,15 +137,24 @@ function ChatPage() {
139
137
  }
140
138
  ```
141
139
 
140
+ It forwards every `CopilotChat` prop except `agentId`, so anything you can pass to `<CopilotChat />` works here too.
141
+
142
142
  ### Connecting Multiple AG-UI Agents
143
143
 
144
- Run the `connection` generator once per agent. Every agent registered via the shared `AguiProvider` is visible from anywhere in the app — instantiate a CopilotKit component with a different `agentId` to route each chat to the agent you want:
144
+ Run the `connection` generator once per agent. Each run vends that agent's own chat component, so routing a chat to a particular agent is a matter of which component you render:
145
145
 
146
146
  ```tsx
147
- import { CopilotChat } from './components/copilot';
147
+ import { StoryAgentChat } from './components/story-agent-chat';
148
+ import { ResearchAgentChat } from './components/research-agent-chat';
148
149
 
149
- <CopilotChat agentId="story" /> {/* talks to StoryAgent */}
150
- <CopilotChat agentId="research" /> {/* talks to ResearchAgent */}
150
+ <StoryAgentChat /> {/* talks to StoryAgent */}
151
+ <ResearchAgentChat /> {/* talks to ResearchAgent */}
152
+ ```
153
+
154
+ If you need the raw id — to call CopilotKit's own hooks, say — each generated hook exports it:
155
+
156
+ ```tsx
157
+ import { STORY_AGENT_ID } from './hooks/useAguiStoryAgent';
151
158
  ```
152
159
 
153
160
  ## Customising the Look and Feel
@@ -164,12 +171,13 @@ The generator reads `metadata.ux` from your React website project and vends a th
164
171
  | `shadcn` | Assistant messages render in a `bg-muted` bubble with a `Sparkles` avatar; user messages render right-aligned in a `bg-primary` bubble with a `User` avatar. The input is a rounded `Textarea` + pill-shaped send/stop `Button` (Enter submits, Shift+Enter newlines). Uses shadcn primitives from the shared `common-shadcn` package. |
165
172
  | `none` (or anything else) | No theme — the module just re-exports the default CopilotKit components. |
166
173
 
167
- Import the themed components from the **local theme module** (not `@copilotkit/react-core/v2` directly) so the theme is applied automatically:
174
+ The vended `<AgentName>Chat` components are already themed. For a chat you wire up yourself, import from the **local theme module** (not `@copilotkit/react-core/v2` directly) so the theme is applied automatically:
168
175
 
169
176
  ```tsx
170
177
  import { CopilotChat } from './components/copilot';
178
+ import { STORY_AGENT_ID } from './hooks/useAguiStoryAgent';
171
179
 
172
- <CopilotChat agentId="agent" />
180
+ <CopilotChat agentId={STORY_AGENT_ID} />
173
181
  ```
174
182
 
175
183
  The theme is applied as slot defaults, so any slot you explicitly pass still wins — you keep full control whenever you need a one-off override.
@@ -188,8 +196,7 @@ For example, to drop in your own user-message renderer while keeping the rest of
188
196
  Per-chat overrides still work alongside the theme — anything you pass as a slot prop overrides the themed default:
189
197
 
190
198
  ```tsx
191
- <CopilotChat
192
- agentId="agent"
199
+ <StoryAgentChat
193
200
  // style the input and its children
194
201
  input={{
195
202
  textArea: 'text-blue-600',
@@ -205,28 +212,26 @@ Per-chat overrides still work alongside the theme — anything you pass as a slo
205
212
 
206
213
  ### Replacing a slot with a custom component
207
214
 
208
- Any slot can take a React component instead of a className, so you can replace the default entirely:
215
+ Any slot can take a React component instead of a className, so you can replace the default entirely. Type your component against the props the slot declares — `sendButton` renders a `<button>`, so it receives `ButtonHTMLAttributes`:
209
216
 
210
217
  ```tsx
211
- import { CopilotChat } from './components/copilot';
218
+ import { StoryAgentChat } from './components/story-agent-chat';
212
219
 
213
- const MySendButton: React.FC<{ onClick: () => void }> = ({ onClick }) => (
220
+ const MySendButton: React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>> = ({
221
+ onClick,
222
+ }) => (
214
223
  <button onClick={onClick} className="my-send-btn">
215
224
  Send
216
225
  </button>
217
226
  );
218
227
 
219
- <CopilotChat
220
- agentId="agent"
221
- input={{ sendButton: MySendButton }}
222
- />;
228
+ <StoryAgentChat input={{ sendButton: MySendButton }} />;
223
229
  ```
224
230
 
225
231
  Deeper overrides follow the same shape — e.g. replace just the copy button on assistant messages:
226
232
 
227
233
  ```tsx
228
- <CopilotChat
229
- agentId="agent"
234
+ <StoryAgentChat
230
235
  messageView={{
231
236
  assistantMessage: {
232
237
  copyButton: ({ onClick }) => <button onClick={onClick}>Copy</button>,
@@ -249,6 +254,10 @@ The connection generator automatically configures `dev` integration:
249
254
  The website and connected agent hot-reload together, enabling you to quickly iterate on both sides without deploying to AWS.
250
255
  :::
251
256
 
257
+ :::note[The dev target requires the Nx Daemon]
258
+ The `dev` target hot-reloads local dev servers. Many of these rely on [`nx watch`](https://nx.dev/docs/guides/tasks--caching/workspace-watching) to achieve this, which requires the [Nx Daemon](https://nx.dev/docs/concepts/nx-daemon) to be enabled.
259
+ :::
260
+
252
261
  ## More Information
253
262
 
254
263
  - <Link path="guides/ts-agent">TypeScript Agent Guide</Link>