@aws/nx-plugin-mcp 0.120.0 → 0.121.0
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 +23 -35
- package/docs/guides/astro-docs.mdx +142 -0
- package/docs/guides/connection/py-agent-a2a.mdx +105 -0
- package/docs/guides/connection/py-agent-mcp.mdx +147 -0
- package/docs/guides/connection/react-agui.mdx +240 -0
- package/docs/guides/connection/react-fastapi.mdx +1476 -0
- package/docs/guides/connection/react-py-agent.mdx +198 -0
- package/docs/guides/connection/react-smithy.mdx +1355 -0
- package/docs/guides/connection/react-trpc.mdx +447 -0
- package/docs/guides/connection/react-ts-agent.mdx +198 -0
- package/docs/guides/connection/smithy-rdb.mdx +161 -0
- package/docs/guides/connection/trpc-rdb.mdx +127 -0
- package/docs/guides/connection/ts-agent-a2a.mdx +106 -0
- package/docs/guides/connection/ts-agent-mcp.mdx +144 -0
- package/docs/guides/connection/ts-agent-rdb.mdx +141 -0
- package/docs/guides/connection/ts-mcp-server-rdb.mdx +135 -0
- package/docs/guides/connection.mdx +126 -0
- package/docs/guides/docker-bundling.mdx +403 -0
- package/docs/guides/fastapi.mdx +509 -0
- package/docs/guides/license.mdx +293 -0
- package/docs/guides/nx-generator.mdx +588 -0
- package/docs/guides/py-agent.mdx +483 -0
- package/docs/guides/py-mcp-server.mdx +161 -0
- package/docs/guides/python-lambda-function.mdx +207 -0
- package/docs/guides/python-project.mdx +228 -0
- package/docs/guides/react-website-auth.mdx +216 -0
- package/docs/guides/react-website.mdx +421 -0
- package/docs/guides/runtime-config.mdx +312 -0
- package/docs/guides/terraform-project.mdx +317 -0
- package/docs/guides/trpc.mdx +816 -0
- package/docs/guides/ts-agent.mdx +436 -0
- package/docs/guides/ts-lambda-function.mdx +218 -0
- package/docs/guides/ts-mcp-server.mdx +169 -0
- package/docs/guides/ts-nx-plugin.mdx +159 -0
- package/docs/guides/ts-rdb.mdx +759 -0
- package/docs/guides/ts-smithy-api.mdx +661 -0
- package/docs/guides/typescript-infrastructure.mdx +408 -0
- package/docs/guides/typescript-project.mdx +312 -0
- package/docs/guides/workspace.mdx +181 -0
- package/docs/snippets/agent/architecture.mdx +72 -0
- package/docs/snippets/agent/bedrock-deployment.mdx +172 -0
- package/docs/snippets/agent/runtime-arn.mdx +64 -0
- package/docs/snippets/api/api-architecture.mdx +93 -0
- package/docs/snippets/api/api-choice-note.mdx +6 -0
- package/docs/snippets/api/cors-configuration-cdk-note.mdx +25 -0
- package/docs/snippets/api/cors-configuration-terraform-note.mdx +28 -0
- package/docs/snippets/api/shared-constructs.mdx +38 -0
- package/docs/snippets/api/type-safe-api-integrations.mdx +643 -0
- package/docs/snippets/api/waf-configuration.mdx +37 -0
- package/docs/snippets/connection/a2a-infrastructure.mdx +63 -0
- package/docs/snippets/connection/lambda-rdb-ssl-requirements.mdx +40 -0
- package/docs/snippets/connection/mcp-server-rdb-ssl-requirements.mdx +35 -0
- package/docs/snippets/connection/rdb-api-infrastructure.mdx +72 -0
- package/docs/snippets/connection/react-agent-infrastructure.mdx +61 -0
- package/docs/snippets/connection/strands-agent-rdb-ssl-requirements.mdx +35 -0
- package/docs/snippets/lambda-function/architecture.mdx +36 -0
- package/docs/snippets/lambda-function/deploying-your-function.mdx +118 -0
- package/docs/snippets/mcp/architecture.mdx +58 -0
- package/docs/snippets/mcp/assistant-docs.mdx +10 -0
- package/docs/snippets/mcp/bedrock-deployment.mdx +167 -0
- package/docs/snippets/mcp/config.mdx +13 -0
- package/docs/snippets/mcp/configuration-py.mdx +42 -0
- package/docs/snippets/mcp/configuration-ts.mdx +53 -0
- package/docs/snippets/mcp/observability.mdx +8 -0
- package/docs/snippets/mcp/shared-constructs.mdx +32 -0
- package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +602 -0
- package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +915 -0
- package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +161 -0
- package/docs/snippets/pdk-migration/example/04-deploy.mdx +229 -0
- package/docs/snippets/pdk-migration/faq/aws-arch.mdx +17 -0
- package/docs/snippets/pdk-migration/faq/cdk-graph.mdx +29 -0
- package/docs/snippets/pdk-migration/faq/infrastructure-python-java.mdx +19 -0
- package/docs/snippets/pdk-migration/faq/pdk-nag.mdx +15 -0
- package/docs/snippets/pdk-migration/faq/pipeline.mdx +15 -0
- package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +310 -0
- package/docs/snippets/pdk-migration/faq/use-of-projen.mdx +15 -0
- package/docs/snippets/prerequisites.mdx +20 -0
- package/docs/snippets/required-prerequisites.mdx +12 -0
- package/docs/snippets/shared-constructs.mdx +40 -0
- package/docs/snippets/tools/acurl.mdx +73 -0
- package/docs/snippets/ts-bundle.mdx +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Smithy API to Relational Database
|
|
3
|
+
description: Connect a Smithy API to a Relational Database
|
|
4
|
+
when:
|
|
5
|
+
sourceType: smithy
|
|
6
|
+
targetType: ts#rdb
|
|
7
|
+
---
|
|
8
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
9
|
+
import Link from '@components/link.astro';
|
|
10
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
11
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
12
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
13
|
+
import Snippet from '@components/snippet.astro';
|
|
14
|
+
|
|
15
|
+
The `connection` generator wires a <Link path="guides/ts-smithy-api">Smithy API</Link> to a <Link path="guides/ts-rdb">Relational Database</Link> project, injecting a Prisma client into the service context so all operation implementations can access the database.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
Before using this generator, ensure you have:
|
|
20
|
+
|
|
21
|
+
1. A <Link path="guides/ts-smithy-api">`ts#smithy-api`</Link> project (TypeScript backend)
|
|
22
|
+
2. A <Link path="guides/ts-rdb">`ts#rdb`</Link> project
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Run the Generator
|
|
27
|
+
|
|
28
|
+
<RunGenerator generator="connection" />
|
|
29
|
+
|
|
30
|
+
Select your Smithy API backend project as the source and your relational database project as the target.
|
|
31
|
+
|
|
32
|
+
### Options
|
|
33
|
+
|
|
34
|
+
<GeneratorParameters generator="connection" />
|
|
35
|
+
|
|
36
|
+
## Generator Output
|
|
37
|
+
|
|
38
|
+
The generator modifies three existing files in your Smithy API backend:
|
|
39
|
+
|
|
40
|
+
<FileTree>
|
|
41
|
+
|
|
42
|
+
- packages/api/src
|
|
43
|
+
- context.ts `db` property added to `ServiceContext`
|
|
44
|
+
- handler.ts Prisma client created inside `lambdaHandler`, passed to `serviceHandler.handle`
|
|
45
|
+
- local-server.ts Prisma client created inside the request handler, passed to `serviceHandler.handle`
|
|
46
|
+
|
|
47
|
+
</FileTree>
|
|
48
|
+
|
|
49
|
+
Additionally, it updates the API's `serve-local` target to start the database automatically.
|
|
50
|
+
|
|
51
|
+
## How It Works
|
|
52
|
+
|
|
53
|
+
### ServiceContext
|
|
54
|
+
|
|
55
|
+
The generator adds a typed `db` property to `ServiceContext` in `context.ts`:
|
|
56
|
+
|
|
57
|
+
```ts title="packages/api/src/context.ts" {1,7}
|
|
58
|
+
import { getPrisma as getMyDb } from ':my-scope/my-db';
|
|
59
|
+
|
|
60
|
+
export interface ServiceContext {
|
|
61
|
+
tracer: Tracer;
|
|
62
|
+
logger: Logger;
|
|
63
|
+
metrics: Metrics;
|
|
64
|
+
myDb: Awaited<ReturnType<typeof getMyDb>>;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Lambda Handler
|
|
69
|
+
|
|
70
|
+
The Prisma client is instantiated inside `lambdaHandler` and passed through the service context:
|
|
71
|
+
|
|
72
|
+
```ts title="packages/api/src/handler.ts" {1,10}
|
|
73
|
+
import { getPrisma as getMyDb } from ':my-scope/my-db';
|
|
74
|
+
|
|
75
|
+
export const lambdaHandler = async (event: APIGatewayProxyEvent) => {
|
|
76
|
+
const httpRequest = convertEvent(event);
|
|
77
|
+
const myDb = await getMyDb();
|
|
78
|
+
const httpResponse = await serviceHandler.handle(httpRequest, {
|
|
79
|
+
tracer,
|
|
80
|
+
logger,
|
|
81
|
+
metrics,
|
|
82
|
+
myDb,
|
|
83
|
+
});
|
|
84
|
+
return convertVersion1Response(httpResponse);
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Using the Database in Operations
|
|
89
|
+
|
|
90
|
+
Access `db` from the context in your operation implementations:
|
|
91
|
+
|
|
92
|
+
```ts title="packages/api/src/operations/list-users.ts" {8}
|
|
93
|
+
import { ListUsersOperationInput, ListUsersOperationOutput } from '../generated/ssdk/index.js';
|
|
94
|
+
import { ServiceContext } from '../context.js';
|
|
95
|
+
|
|
96
|
+
export const listUsers = async (
|
|
97
|
+
input: ListUsersOperationInput,
|
|
98
|
+
ctx: ServiceContext,
|
|
99
|
+
): Promise<ListUsersOperationOutput> => {
|
|
100
|
+
const users = await ctx.myDb.user.findMany();
|
|
101
|
+
return { users };
|
|
102
|
+
};
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Multiple Databases
|
|
106
|
+
|
|
107
|
+
Running the generator again with a different target adds the second database alongside the first. Both clients are added to `ServiceContext` and instantiated in `handler.ts`:
|
|
108
|
+
|
|
109
|
+
```ts title="packages/api/src/context.ts" {5,6}
|
|
110
|
+
export interface ServiceContext {
|
|
111
|
+
tracer: Tracer;
|
|
112
|
+
logger: Logger;
|
|
113
|
+
metrics: Metrics;
|
|
114
|
+
myDb: Awaited<ReturnType<typeof getMyDb>>;
|
|
115
|
+
otherDb: Awaited<ReturnType<typeof getOtherDb>>;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```ts title="packages/api/src/handler.ts" {1,2,7,8}
|
|
120
|
+
const myDb = await getMyDb();
|
|
121
|
+
const otherDb = await getOtherDb();
|
|
122
|
+
const httpResponse = await serviceHandler.handle(httpRequest, {
|
|
123
|
+
tracer,
|
|
124
|
+
logger,
|
|
125
|
+
metrics,
|
|
126
|
+
myDb,
|
|
127
|
+
otherDb,
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Infrastructure
|
|
132
|
+
|
|
133
|
+
<Snippet name="connection/rdb-api-infrastructure" parentHeading="Infrastructure" />
|
|
134
|
+
|
|
135
|
+
### SSL Requirements When Connecting Without RDS Proxy
|
|
136
|
+
|
|
137
|
+
<Snippet name="connection/lambda-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
|
|
138
|
+
|
|
139
|
+
## Local Development
|
|
140
|
+
|
|
141
|
+
The generator applies the same Prisma client injection inside the request handler in `local-server.ts`:
|
|
142
|
+
|
|
143
|
+
```ts title="packages/api/src/local-server.ts" {1,5,10}
|
|
144
|
+
import { getPrisma as getMyDb } from ':my-scope/my-db';
|
|
145
|
+
|
|
146
|
+
const server = createServer(async function (req, res) {
|
|
147
|
+
const httpRequest = convertRequest(req);
|
|
148
|
+
const myDb = await getMyDb();
|
|
149
|
+
const httpResponse = await serviceHandler.handle(httpRequest, {
|
|
150
|
+
tracer,
|
|
151
|
+
logger,
|
|
152
|
+
metrics,
|
|
153
|
+
myDb,
|
|
154
|
+
});
|
|
155
|
+
return writeResponse(httpResponse, res);
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
<NxCommands commands={["serve-local <api-project-name>"]} />
|
|
160
|
+
|
|
161
|
+
This starts both the API and the local database. The `SERVE_LOCAL=true` environment variable is set automatically, so the Prisma client connects to the local Docker database instead of Aurora.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: tRPC API to Relational Database
|
|
3
|
+
description: Connect a tRPC API to a Relational Database
|
|
4
|
+
when:
|
|
5
|
+
sourceType: ts#trpc-api
|
|
6
|
+
targetType: ts#rdb
|
|
7
|
+
---
|
|
8
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
9
|
+
import Link from '@components/link.astro';
|
|
10
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
11
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
12
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
13
|
+
import Snippet from '@components/snippet.astro';
|
|
14
|
+
|
|
15
|
+
The `connection` generator wires a <Link path="guides/trpc">tRPC API</Link> to a <Link path="guides/ts-rdb">Relational Database</Link> project, generating a type-safe tRPC middleware plugin that makes a Prisma client available in your procedure context.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
Before using this generator, ensure you have:
|
|
20
|
+
|
|
21
|
+
1. A <Link path="guides/trpc">`ts#trpc-api`</Link> project
|
|
22
|
+
2. A <Link path="guides/ts-rdb">`ts#rdb`</Link> project
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Run the Generator
|
|
27
|
+
|
|
28
|
+
<RunGenerator generator="connection" />
|
|
29
|
+
|
|
30
|
+
Select your tRPC API project as the source and your relational database project as the target.
|
|
31
|
+
|
|
32
|
+
### Options
|
|
33
|
+
|
|
34
|
+
<GeneratorParameters generator="connection" />
|
|
35
|
+
|
|
36
|
+
## Generator Output
|
|
37
|
+
|
|
38
|
+
The generator creates a middleware file in your tRPC API project:
|
|
39
|
+
|
|
40
|
+
<FileTree>
|
|
41
|
+
|
|
42
|
+
- packages/api/src
|
|
43
|
+
- middleware
|
|
44
|
+
- \<db-name>.ts tRPC plugin exposing the Prisma client in procedure context
|
|
45
|
+
|
|
46
|
+
</FileTree>
|
|
47
|
+
|
|
48
|
+
Additionally, it updates your tRPC API's `serve-local` target to start the database automatically when running locally.
|
|
49
|
+
|
|
50
|
+
## Using the Middleware
|
|
51
|
+
|
|
52
|
+
### Register the Plugin
|
|
53
|
+
|
|
54
|
+
Add the generated plugin to your tRPC router so all procedures using it gain access to the database:
|
|
55
|
+
|
|
56
|
+
```ts title="packages/api/src/router.ts" {2,5}
|
|
57
|
+
import { t } from './init.js';
|
|
58
|
+
import { createMyDbPlugin } from './middleware/my-db.js';
|
|
59
|
+
|
|
60
|
+
export const authenticatedProcedure = t.procedure
|
|
61
|
+
.concat(createMyDbPlugin());
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Access the Database in Procedures
|
|
65
|
+
|
|
66
|
+
The plugin merges `IMyDbContext` into your procedure context, making `myDb` available as an optional property:
|
|
67
|
+
|
|
68
|
+
```ts title="packages/api/src/procedures/users.ts" {8,12}
|
|
69
|
+
import { z } from 'zod';
|
|
70
|
+
import { authenticatedProcedure } from '../router.js';
|
|
71
|
+
|
|
72
|
+
export const listUsers = authenticatedProcedure
|
|
73
|
+
.output(z.array(z.object({ id: z.string(), name: z.string() })))
|
|
74
|
+
.query(async ({ ctx }) => {
|
|
75
|
+
// ctx.myDb is the Prisma client — typed as Awaited<ReturnType<typeof getPrisma>>
|
|
76
|
+
return await ctx.myDb!.user.findMany();
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### MySQL: Disconnect After Each Request
|
|
81
|
+
|
|
82
|
+
When the target database uses the MySQL engine, the generated middleware wraps `opts.next()` in a `try/finally` block that calls `$disconnect()`:
|
|
83
|
+
|
|
84
|
+
```ts title="packages/api/src/middleware/my-db.ts" {6}
|
|
85
|
+
return t.procedure.use(async (opts) => {
|
|
86
|
+
const myDb = await getPrisma();
|
|
87
|
+
try {
|
|
88
|
+
return await opts.next({ ctx: { ...opts.ctx, myDb } });
|
|
89
|
+
} finally {
|
|
90
|
+
await myDb.$disconnect();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This addresses the MySQL adapter holding the Node.js event loop open after a query, which would otherwise prevent Lambda from flushing streaming responses. Disconnecting in `finally` releases the event loop so the response can complete. See <Link path="guides/ts-rdb#mysql-api-gateway-streaming-mode">MySQL: API Gateway Streaming Mode</Link> for details.
|
|
96
|
+
|
|
97
|
+
PostgreSQL does not require this — its adapter uses a connection pool configured with `allowExitOnIdle: true`.
|
|
98
|
+
|
|
99
|
+
:::caution[MySQL: IAM Token Expiry]
|
|
100
|
+
RDS IAM tokens expire after **15 minutes**. The MySQL adapter captures the token at connection time. If your Lambda stays warm long enough for the token to expire, new connection attempts may fail. Check for connection errors and call `getPrisma()` again to obtain a fresh client with a new token. See <Link path="guides/ts-rdb#mysql-iam-token-expiry">MySQL: IAM Token Expiry</Link> for details and workarounds.
|
|
101
|
+
:::
|
|
102
|
+
|
|
103
|
+
## Multiple Databases
|
|
104
|
+
|
|
105
|
+
You can connect additional databases by running the generator again with a different target. Each database gets its own plugin and context interface:
|
|
106
|
+
|
|
107
|
+
```ts title="packages/api/src/router.ts"
|
|
108
|
+
export const dbProcedure = t.procedure
|
|
109
|
+
.concat(createMyDbPlugin())
|
|
110
|
+
.concat(createOtherDbPlugin());
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Infrastructure
|
|
114
|
+
|
|
115
|
+
<Snippet name="connection/rdb-api-infrastructure" parentHeading="Infrastructure" />
|
|
116
|
+
|
|
117
|
+
### SSL Requirements When Connecting Without RDS Proxy
|
|
118
|
+
|
|
119
|
+
<Snippet name="connection/lambda-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
|
|
120
|
+
|
|
121
|
+
## Local Development
|
|
122
|
+
|
|
123
|
+
The generator configures your tRPC API's `serve-local` target to depend on the database's `serve-local` target, so running:
|
|
124
|
+
|
|
125
|
+
<NxCommands commands={["serve-local <api-project-name>"]} />
|
|
126
|
+
|
|
127
|
+
will automatically start the local database alongside your API.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript Agent to A2A Agent
|
|
3
|
+
description: Connect a TypeScript Agent to a remote A2A agent
|
|
4
|
+
when:
|
|
5
|
+
sourceType: ts#agent
|
|
6
|
+
targetType:
|
|
7
|
+
- ts#agent
|
|
8
|
+
- py#agent
|
|
9
|
+
---
|
|
10
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
11
|
+
import Link from '@components/link.astro';
|
|
12
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
13
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
14
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
15
|
+
import Snippet from '@components/snippet.astro';
|
|
16
|
+
|
|
17
|
+
The `connection` generator can connect your <Link path="guides/ts-agent">TypeScript Agent</Link> to a remote [A2A](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-a2a.html) agent — either <Link path="guides/ts-agent">TypeScript</Link> or <Link path="guides/py-agent">Python</Link> — so your agent can delegate to another agent as a tool.
|
|
18
|
+
|
|
19
|
+
The generator sets up all the necessary wiring so your agent can discover and invoke the remote A2A agent, both when deployed to AWS (via Bedrock AgentCore) and when running locally.
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
Before using this generator, ensure you have:
|
|
24
|
+
|
|
25
|
+
1. A TypeScript project with a <Link path="guides/ts-agent">Strands Agent</Link> component (any protocol)
|
|
26
|
+
2. A project with an Agent component generated with `--protocol=A2A` and `--auth=IAM` (either <Link path="guides/ts-agent">`ts#agent`</Link> or <Link path="guides/py-agent">`py#agent`</Link>)
|
|
27
|
+
3. Both components created with `computeType: BedrockAgentCoreRuntime`
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Run the Generator
|
|
32
|
+
|
|
33
|
+
<RunGenerator generator="connection" />
|
|
34
|
+
|
|
35
|
+
Select your host agent project as the source and your A2A agent project as the target. If your projects contain multiple components, specify the `sourceComponent` and `targetComponent` options to disambiguate.
|
|
36
|
+
|
|
37
|
+
### Options
|
|
38
|
+
|
|
39
|
+
<GeneratorParameters generator="connection" />
|
|
40
|
+
|
|
41
|
+
## Generator Output
|
|
42
|
+
|
|
43
|
+
The generator creates a shared `agent-connection` package and modifies your agent code:
|
|
44
|
+
|
|
45
|
+
<FileTree>
|
|
46
|
+
|
|
47
|
+
- packages/common/agent-connection
|
|
48
|
+
- src
|
|
49
|
+
- app
|
|
50
|
+
- \<target-agent-name>-client.ts High-level client for the connected A2A agent
|
|
51
|
+
- core
|
|
52
|
+
- agentcore-a2a-client.ts Low-level AgentCore A2A client with SigV4 authentication
|
|
53
|
+
- index.ts Exports all clients
|
|
54
|
+
- project.json
|
|
55
|
+
- tsconfig.json
|
|
56
|
+
|
|
57
|
+
</FileTree>
|
|
58
|
+
|
|
59
|
+
Additionally, it:
|
|
60
|
+
- Transforms your agent's `agent.ts` to register the remote A2A agent as a Strands `tool`
|
|
61
|
+
- Updates the agent's `serve-local` target to depend on the target agent's `serve-local` target
|
|
62
|
+
- Installs required dependencies
|
|
63
|
+
|
|
64
|
+
## Using the Connected A2A Agent
|
|
65
|
+
|
|
66
|
+
The generator transforms your agent's `agent.ts` to wrap the remote A2A agent as a tool:
|
|
67
|
+
|
|
68
|
+
```ts title="packages/example/src/my-agent/agent.ts" {2,5-11,14}
|
|
69
|
+
import { Agent, tool } from '@strands-agents/sdk';
|
|
70
|
+
import { RemoteAgentClient } from ':my-scope/agent-connection';
|
|
71
|
+
import { z } from 'zod';
|
|
72
|
+
|
|
73
|
+
export const getAgent = async (sessionId: string) => {
|
|
74
|
+
const remoteAgent = await RemoteAgentClient.create(sessionId);
|
|
75
|
+
const remoteAgentTool = tool({
|
|
76
|
+
name: 'askRemoteAgent',
|
|
77
|
+
description: 'Delegate a question to the remote RemoteAgent A2A agent and return its reply.',
|
|
78
|
+
inputSchema: z.object({ prompt: z.string() }),
|
|
79
|
+
callback: async ({ prompt }) => (await remoteAgent.invoke(prompt)).toString(),
|
|
80
|
+
});
|
|
81
|
+
return new Agent({
|
|
82
|
+
systemPrompt: '...',
|
|
83
|
+
tools: [remoteAgentTool],
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The `sessionId` parameter is plumbed through from the caller, ensuring consistency for [Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html).
|
|
89
|
+
|
|
90
|
+
Under the hood, `RemoteAgentClient.create(sessionId)` returns a Strands `A2AAgent` configured with a SigV4-signing `clientFactory` when deployed to AWS, and a plain `http://localhost:<port>/` endpoint when `SERVE_LOCAL=true`.
|
|
91
|
+
|
|
92
|
+
## Infrastructure
|
|
93
|
+
|
|
94
|
+
<Snippet name="connection/a2a-infrastructure" parentHeading="Infrastructure" />
|
|
95
|
+
|
|
96
|
+
## Local Development
|
|
97
|
+
|
|
98
|
+
The generator configures the host agent's `serve-local` target to:
|
|
99
|
+
1. Start the connected A2A agent(s) automatically
|
|
100
|
+
2. Set `SERVE_LOCAL=true` so the generated client connects directly to `http://localhost:<port>/` instead of AgentCore
|
|
101
|
+
|
|
102
|
+
Run the agent locally with:
|
|
103
|
+
|
|
104
|
+
<NxCommands commands={["<agent-name>-serve-local <project-name>"]} />
|
|
105
|
+
|
|
106
|
+
This will start both the host agent and all connected A2A agents, with the host agent calling the remote agents over plain HTTP on their assigned local ports.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript Agent to MCP
|
|
3
|
+
description: Connect a TypeScript Agent to an MCP server
|
|
4
|
+
when:
|
|
5
|
+
sourceType: ts#agent
|
|
6
|
+
targetType:
|
|
7
|
+
- ts#mcp-server
|
|
8
|
+
- py#mcp-server
|
|
9
|
+
---
|
|
10
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
11
|
+
import Link from '@components/link.astro';
|
|
12
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
13
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
14
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
15
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
16
|
+
|
|
17
|
+
The `connection` generator can connect your <Link path="guides/ts-agent">TypeScript 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
|
+
The generator sets up all the necessary wiring so your agent can discover and invoke the MCP server's tools, both when deployed to AWS (via Bedrock AgentCore) and when running locally.
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
Before using this generator, ensure you have:
|
|
24
|
+
|
|
25
|
+
1. A TypeScript project with a <Link path="guides/ts-agent">Strands Agent</Link> component
|
|
26
|
+
2. A project with an MCP server component (either <Link path="guides/ts-mcp-server">`ts#mcp-server`</Link> or <Link path="guides/py-mcp-server">`py#mcp-server`</Link>)
|
|
27
|
+
3. Both components created with `computeType: BedrockAgentCoreRuntime`
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Run the Generator
|
|
32
|
+
|
|
33
|
+
<RunGenerator generator="connection" />
|
|
34
|
+
|
|
35
|
+
Select your agent project as the source and your MCP server project as the target. If your projects contain multiple components, specify the `sourceComponent` and `targetComponent` options to disambiguate.
|
|
36
|
+
|
|
37
|
+
### Options
|
|
38
|
+
|
|
39
|
+
<GeneratorParameters generator="connection" />
|
|
40
|
+
|
|
41
|
+
## Generator Output
|
|
42
|
+
|
|
43
|
+
The generator creates a shared `agent-connection` package and modifies your agent code:
|
|
44
|
+
|
|
45
|
+
<FileTree>
|
|
46
|
+
|
|
47
|
+
- packages/common/agent-connection
|
|
48
|
+
- src
|
|
49
|
+
- app
|
|
50
|
+
- \<mcp-server-name>-client.ts High-level client for the connected MCP server
|
|
51
|
+
- core
|
|
52
|
+
- agentcore-mcp-client.ts Low-level AgentCore MCP client with SigV4/JWT authentication
|
|
53
|
+
- index.ts Exports all clients
|
|
54
|
+
- project.json
|
|
55
|
+
- tsconfig.json
|
|
56
|
+
|
|
57
|
+
</FileTree>
|
|
58
|
+
|
|
59
|
+
Additionally, it:
|
|
60
|
+
- Transforms your agent's `agent.ts` to import and use the MCP server's tools
|
|
61
|
+
- Updates the agent's `serve-local` target to depend on the MCP server's serve target
|
|
62
|
+
- Installs required dependencies
|
|
63
|
+
|
|
64
|
+
## Using the Connected MCP Server
|
|
65
|
+
|
|
66
|
+
The generator transforms your agent's `agent.ts` to use the MCP server's tools:
|
|
67
|
+
|
|
68
|
+
```ts title="packages/example/src/my-agent/agent.ts" {2,5,8}
|
|
69
|
+
import { Agent, tool } from '@strands-agents/sdk';
|
|
70
|
+
import { MyMcpServerClient } from ':my-scope/agent-connection';
|
|
71
|
+
|
|
72
|
+
export const getAgent = async (sessionId: string) => {
|
|
73
|
+
const myMcpServerClient = await MyMcpServerClient.create(sessionId);
|
|
74
|
+
return new Agent({
|
|
75
|
+
systemPrompt: '...',
|
|
76
|
+
tools: [myMcpServerClient],
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The `sessionId` parameter is plumbed through from the caller, ensuring consistency for [Bedrock AgentCore Observability](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html).
|
|
82
|
+
|
|
83
|
+
## Infrastructure
|
|
84
|
+
|
|
85
|
+
<Infrastructure>
|
|
86
|
+
<Fragment slot="cdk">
|
|
87
|
+
After running the connection generator, you need to grant the agent permission to invoke the MCP server:
|
|
88
|
+
|
|
89
|
+
```ts title="packages/infra/src/stacks/application-stack.ts" {5}
|
|
90
|
+
const mcpServer = new MyMcpServer(this, 'MyMcpServer');
|
|
91
|
+
const myAgent = new MyAgent(this, 'MyAgent');
|
|
92
|
+
|
|
93
|
+
// Grant the agent permissions to invoke the MCP server
|
|
94
|
+
mcpServer.grantInvokeAccess(myAgent);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
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.
|
|
98
|
+
</Fragment>
|
|
99
|
+
<Fragment slot="terraform">
|
|
100
|
+
After running the connection generator, you need to grant the agent permission to invoke the MCP server in your Terraform configuration:
|
|
101
|
+
|
|
102
|
+
```hcl title="packages/infra/src/main.tf" {12-24}
|
|
103
|
+
module "inventory_mcp_server" {
|
|
104
|
+
source = "../../common/terraform/src/app/mcp-servers/inventory-mcp"
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module "story_agent" {
|
|
108
|
+
source = "../../common/terraform/src/app/agents/story-agent"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Grant the agent permissions to invoke the MCP server
|
|
112
|
+
resource "aws_iam_policy" "agent_invoke_mcp" {
|
|
113
|
+
name = "AgentInvokeMcpPolicy"
|
|
114
|
+
policy = jsonencode({
|
|
115
|
+
Version = "2012-10-17"
|
|
116
|
+
Statement = [{
|
|
117
|
+
Effect = "Allow"
|
|
118
|
+
Action = "bedrock-agentcore:InvokeAgent"
|
|
119
|
+
Resource = module.inventory_mcp_server.agent_core_runtime_arn
|
|
120
|
+
}]
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
resource "aws_iam_role_policy_attachment" "agent_invoke_mcp" {
|
|
125
|
+
role = module.story_agent.agent_core_runtime_role_arn
|
|
126
|
+
policy_arn = aws_iam_policy.agent_invoke_mcp.arn
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
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 Terraform module, so the agent can discover it at runtime.
|
|
131
|
+
</Fragment>
|
|
132
|
+
</Infrastructure>
|
|
133
|
+
|
|
134
|
+
## Local Development
|
|
135
|
+
|
|
136
|
+
The generator configures the agent's `serve-local` target to:
|
|
137
|
+
1. Start the connected MCP server(s) automatically
|
|
138
|
+
2. Set `SERVE_LOCAL=true` so the generated client uses direct HTTP transport instead of AgentCore
|
|
139
|
+
|
|
140
|
+
Run the agent locally with:
|
|
141
|
+
|
|
142
|
+
<NxCommands commands={["<agent-name>-serve-local <project-name>"]} />
|
|
143
|
+
|
|
144
|
+
This will start both the agent and all connected MCP servers, with the agent connecting to the MCP servers directly via HTTP on their assigned local ports.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript Agent to Relational Database
|
|
3
|
+
description: Connect a TypeScript Agent to a Relational Database
|
|
4
|
+
when:
|
|
5
|
+
sourceType: ts#agent
|
|
6
|
+
targetType: ts#rdb
|
|
7
|
+
---
|
|
8
|
+
import { FileTree } from '@astrojs/starlight/components';
|
|
9
|
+
import Link from '@components/link.astro';
|
|
10
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
11
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
12
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
13
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
14
|
+
import Snippet from '@components/snippet.astro';
|
|
15
|
+
|
|
16
|
+
The `connection` generator wires a <Link path="guides/ts-agent">TypeScript Agent</Link> to a <Link path="guides/ts-rdb">Relational Database</Link> project, making a Prisma client available inside your agent factory.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
Before using this generator, ensure you have:
|
|
21
|
+
|
|
22
|
+
1. A <Link path="guides/ts-agent">`ts#agent`</Link> project
|
|
23
|
+
2. A <Link path="guides/ts-rdb">`ts#rdb`</Link> project
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Run the Generator
|
|
28
|
+
|
|
29
|
+
<RunGenerator generator="connection" />
|
|
30
|
+
|
|
31
|
+
Select your Agent project as the source and your relational database project as the target. If the project contains multiple agent components, specify `sourceComponent` to disambiguate.
|
|
32
|
+
|
|
33
|
+
### Options
|
|
34
|
+
|
|
35
|
+
<GeneratorParameters generator="connection" />
|
|
36
|
+
|
|
37
|
+
## Generator Output
|
|
38
|
+
|
|
39
|
+
The generator modifies two files in your agent's source directory:
|
|
40
|
+
|
|
41
|
+
<FileTree>
|
|
42
|
+
|
|
43
|
+
- packages/my-service/src/my-agent
|
|
44
|
+
- agent.ts Prisma client fetched inside `getAgent` and available to tools
|
|
45
|
+
- Dockerfile RDS CA bundle installed for SSL connections to Aurora
|
|
46
|
+
|
|
47
|
+
</FileTree>
|
|
48
|
+
|
|
49
|
+
Additionally, the agent's `<agent-name>-serve-local` target is updated to depend on the database's `serve-local` target.
|
|
50
|
+
|
|
51
|
+
## How It Works
|
|
52
|
+
|
|
53
|
+
The Prisma client is instantiated inside `getAgent()`. Since the `ts#agent` generator configures a single Agent per session, the client is also reused for the lifetime of the session.
|
|
54
|
+
|
|
55
|
+
### Agent Definition
|
|
56
|
+
|
|
57
|
+
`getAgent` is updated to import and call the Prisma getter at the top of its body:
|
|
58
|
+
|
|
59
|
+
```ts title="packages/my-service/src/my-agent/agent.ts" {1,4}
|
|
60
|
+
import { getPrisma as getMyDb } from ':my-scope/my-db';
|
|
61
|
+
|
|
62
|
+
export const getAgent = async () => {
|
|
63
|
+
const myDb = await getMyDb();
|
|
64
|
+
// ...
|
|
65
|
+
return new Agent({ /* use myDb in tools */ });
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## Multiple Databases
|
|
71
|
+
|
|
72
|
+
Running the generator again with a different target adds the second database alongside the first:
|
|
73
|
+
|
|
74
|
+
```ts title="packages/my-service/src/my-agent/agent.ts" {1,2,5,6}
|
|
75
|
+
import { getPrisma as getMyDb } from ':my-scope/my-db';
|
|
76
|
+
import { getPrisma as getOtherDb } from ':my-scope/other-db';
|
|
77
|
+
|
|
78
|
+
export const getAgent = async () => {
|
|
79
|
+
const myDb = await getMyDb();
|
|
80
|
+
const otherDb = await getOtherDb();
|
|
81
|
+
// ...
|
|
82
|
+
return new Agent({ /* use both clients in tools */ });
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Infrastructure
|
|
87
|
+
|
|
88
|
+
The generated agent construct implements `IGrantable` and `IConnectable`, so you can grant network and IAM access to the database directly on the construct.
|
|
89
|
+
|
|
90
|
+
<Infrastructure>
|
|
91
|
+
<Fragment slot="cdk">
|
|
92
|
+
|
|
93
|
+
```ts title="packages/infra/src/stacks/application-stack.ts"
|
|
94
|
+
import { MyDatabase } from ':my-scope/common-constructs';
|
|
95
|
+
|
|
96
|
+
const db = new MyDatabase(this, 'Db', { vpc, ... });
|
|
97
|
+
const myAgent = new MyAgent(this, 'MyAgent', { vpc, ... });
|
|
98
|
+
|
|
99
|
+
db.allowDefaultPortFrom(myAgent);
|
|
100
|
+
db.grantConnect(myAgent);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`allowDefaultPortFrom` opens the security group rule so the agent runtime can reach the database port. `grantConnect` grants IAM `rds-db:connect` permission to the agent's execution role.
|
|
104
|
+
|
|
105
|
+
</Fragment>
|
|
106
|
+
<Fragment slot="terraform">
|
|
107
|
+
|
|
108
|
+
Pass the database module outputs into your agent module so it can reach the database and read its runtime configuration:
|
|
109
|
+
|
|
110
|
+
```hcl title="packages/infra/src/main.tf"
|
|
111
|
+
module "my_database" {
|
|
112
|
+
source = "../../common/terraform/src/app/dbs/my-database"
|
|
113
|
+
vpc_id = module.vpc.vpc_id
|
|
114
|
+
database_subnet_ids = module.vpc.private_isolated_subnet_ids
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module "my_agent" {
|
|
118
|
+
source = "../../common/terraform/src/app/agents/my-agent"
|
|
119
|
+
|
|
120
|
+
appconfig_application_id = module.my_database.appconfig_application_id
|
|
121
|
+
database_cluster_resource_id = module.my_database.cluster_resource_id
|
|
122
|
+
database_runtime_user = module.my_database.database_runtime_user
|
|
123
|
+
database_security_group_id = module.my_database.security_group_id
|
|
124
|
+
database_port = module.my_database.cluster_port
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Ensure the agent's execution role has `rds-db:connect` permission and that its security group can reach the database security group on the database port.
|
|
129
|
+
|
|
130
|
+
</Fragment>
|
|
131
|
+
</Infrastructure>
|
|
132
|
+
|
|
133
|
+
### SSL Requirements When Connecting Without RDS Proxy
|
|
134
|
+
|
|
135
|
+
<Snippet name="connection/strands-agent-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
|
|
136
|
+
|
|
137
|
+
## Local Development
|
|
138
|
+
|
|
139
|
+
<NxCommands commands={["<agent-name>-serve-local <project-name>"]} />
|
|
140
|
+
|
|
141
|
+
This starts the agent and all connected databases. The `SERVE_LOCAL=true` environment variable causes each Prisma client to connect to its local Docker database instead of Aurora.
|