@aws/nx-plugin-mcp 1.0.0-rc.33 → 1.0.0-rc.34

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 (33) hide show
  1. package/bin/aws-nx-mcp.js +27 -0
  2. package/docs/guides/connection/py-agent-rdb.mdx +162 -0
  3. package/docs/guides/connection/py-fast-api-rdb.mdx +170 -0
  4. package/docs/guides/connection/py-mcp-server-rdb.mdx +171 -0
  5. package/docs/guides/connection/smithy-rdb.mdx +1 -1
  6. package/docs/guides/connection/trpc-rdb.mdx +1 -1
  7. package/docs/guides/connection/ts-agent-rdb.mdx +45 -16
  8. package/docs/guides/connection/ts-mcp-server-rdb.mdx +45 -11
  9. package/docs/guides/connection.mdx +28 -1
  10. package/docs/guides/py-rdb.mdx +250 -0
  11. package/docs/guides/ts-rdb.mdx +48 -483
  12. package/docs/snippets/connection/py-lambda-rdb-ssl-requirements.mdx +7 -0
  13. package/docs/snippets/connection/rdb-api-infrastructure.mdx +36 -15
  14. package/docs/snippets/rdb/architecture.mdx +38 -0
  15. package/docs/snippets/rdb/cluster-instances.mdx +31 -0
  16. package/docs/snippets/rdb/deletion-protection.mdx +34 -0
  17. package/docs/snippets/rdb/deploying.mdx +107 -0
  18. package/docs/snippets/rdb/encryption-key-rotation.mdx +30 -0
  19. package/docs/snippets/rdb/engine-version.mdx +63 -0
  20. package/docs/snippets/rdb/infrastructure.mdx +35 -0
  21. package/docs/snippets/rdb/logging.mdx +32 -0
  22. package/docs/snippets/rdb/rds-proxy.mdx +50 -0
  23. package/docs/snippets/rdb/removal-policy.mdx +57 -0
  24. package/docs/snippets/rdb/serverless-capacity.mdx +32 -0
  25. package/generators.json +27 -0
  26. package/package.json +1 -1
  27. package/src/py/rdb/agent-connection/schema.json +27 -0
  28. package/src/py/rdb/fast-api-connection/schema.json +23 -0
  29. package/src/py/rdb/mcp-server-connection/schema.json +27 -0
  30. package/src/py/rdb/schema.json +77 -0
  31. package/src/ts/rdb/schema.json +1 -1
  32. /package/docs/snippets/connection/{lambda-rdb-ssl-requirements.mdx → ts-lambda-rdb-ssl-requirements.mdx} +0 -0
  33. /package/docs/snippets/connection/{mcp-server-rdb-ssl-requirements.mdx → ts-mcp-server-rdb-ssl-requirements.mdx} +0 -0
package/bin/aws-nx-mcp.js CHANGED
@@ -20204,6 +20204,33 @@ var generators$1 = {
20204
20204
  "description": "Connect a py#mcp-server to a py#dynamodb project",
20205
20205
  "metric": "g55",
20206
20206
  "hidden": true
20207
+ },
20208
+ "py#rdb": {
20209
+ "factory": "./src/py/rdb/generator",
20210
+ "schema": "./src/py/rdb/schema.json",
20211
+ "description": "Create a Python relational database project",
20212
+ "metric": "g56"
20213
+ },
20214
+ "py#rdb#fast-api-connection": {
20215
+ "factory": "./src/py/rdb/fast-api-connection/generator",
20216
+ "schema": "./src/py/rdb/fast-api-connection/schema.json",
20217
+ "description": "Connect a py#fast-api project to a py#rdb project",
20218
+ "metric": "g57",
20219
+ "hidden": true
20220
+ },
20221
+ "py#rdb#agent-connection": {
20222
+ "factory": "./src/py/rdb/agent-connection/generator",
20223
+ "schema": "./src/py/rdb/agent-connection/schema.json",
20224
+ "description": "Connect a py#agent to a py#rdb project",
20225
+ "metric": "g58",
20226
+ "hidden": true
20227
+ },
20228
+ "py#rdb#mcp-server-connection": {
20229
+ "factory": "./src/py/rdb/mcp-server-connection/generator",
20230
+ "schema": "./src/py/rdb/mcp-server-connection/schema.json",
20231
+ "description": "Connect a py#mcp-server to a py#rdb project",
20232
+ "metric": "g59",
20233
+ "hidden": true
20207
20234
  }
20208
20235
  };
20209
20236
  //#endregion
@@ -0,0 +1,162 @@
1
+ ---
2
+ title: Python Agent to Relational Database
3
+ description: Connect a Python Agent to a Relational Database
4
+ when:
5
+ sourceType: py#agent
6
+ targetType: py#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
+
15
+ The `connection` generator wires a <Link path="guides/py-agent">Python Agent</Link> to a <Link path="guides/py-rdb">Python Relational Database</Link> project, making the database session available inside your agent tools.
16
+
17
+ ## Prerequisites
18
+
19
+ Before using this generator, ensure you have:
20
+
21
+ 1. A <Link path="guides/py-agent">`py#agent`</Link> project
22
+ 2. A <Link path="guides/py-rdb">`py#rdb`</Link> project
23
+
24
+ ## Usage
25
+
26
+ ### Run the Generator
27
+
28
+ <RunGenerator generator="connection" />
29
+
30
+ 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.
31
+
32
+ ### Options
33
+
34
+ <GeneratorParameters generator="connection" />
35
+
36
+ ## Generator Output
37
+
38
+ <FileTree>
39
+
40
+ - packages/my\_service
41
+ - project.json Adds a dependency from `my_agent-dev` on the database's `dev` target
42
+ - pyproject.toml Adds the database package as a workspace dependency
43
+ - my\_service
44
+ - my\_agent
45
+ - Dockerfile Adds the RDS CA bundle used for direct Aurora connections
46
+
47
+ </FileTree>
48
+
49
+ ## Using the Database in Agent Tools
50
+
51
+ Import `session_context` from your database package and use it inside your agent tools:
52
+
53
+ ```python title="packages/my_service/my_service/my_agent/agent.py"
54
+ from sqlmodel import select
55
+ from my_scope.my_db import session_context
56
+ from my_scope.my_db.models.example import ExampleModel
57
+ from strands import tool
58
+
59
+ @tool
60
+ async def list_examples() -> list:
61
+ """List all example records."""
62
+ async with session_context() as session:
63
+ return [item.model_dump() for item in (await session.execute(select(ExampleModel))).all()]
64
+ ```
65
+
66
+ ## Infrastructure
67
+
68
+ The generated agent construct implements `IGrantable` and `IConnectable`, so you can grant network and IAM access to the database directly on the construct.
69
+
70
+ <Infrastructure>
71
+ <Fragment slot="cdk">
72
+
73
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
74
+ import { RuntimeNetworkConfiguration } from 'aws-cdk-lib/aws-bedrockagentcore';
75
+ import { MyDatabase } from ':my-scope/common-constructs';
76
+
77
+ const db = new MyDatabase(this, 'Db', { vpc, ... });
78
+
79
+ const myAgent = new MyAgent(this, 'MyAgent', {
80
+ networkConfiguration: RuntimeNetworkConfiguration.usingVpc(this, {
81
+ vpc,
82
+ vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },
83
+ }),
84
+ });
85
+
86
+ db.allowDefaultPortFrom(myAgent);
87
+ db.grantConnect(myAgent);
88
+ ```
89
+
90
+ `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.
91
+
92
+ </Fragment>
93
+ <Fragment slot="terraform">
94
+
95
+ Run the agent inside the same VPC as the database, grant it `rds-db:connect` via `additional_iam_policy_statements`, and open the network path with a pair of security group rules:
96
+
97
+ ```hcl title="packages/infra/src/main.tf"
98
+ module "my_database" {
99
+ source = "../../common/terraform/src/app/dbs/my-database"
100
+ vpc_id = module.vpc.vpc_id
101
+ database_subnet_ids = module.vpc.private_isolated_subnet_ids
102
+ lambda_subnet_ids = module.vpc.private_subnet_ids
103
+ }
104
+
105
+ module "my_agent" {
106
+ source = "../../common/terraform/src/app/agents/my-agent"
107
+ enable_vpc = true
108
+ vpc_id = module.vpc.vpc_id
109
+ subnet_ids = module.vpc.private_subnet_ids
110
+
111
+ appconfig_application_id = module.runtime_config_appconfig.application_id
112
+ appconfig_application_arn = module.runtime_config_appconfig.application_arn
113
+
114
+ additional_iam_policy_statements = [
115
+ {
116
+ Effect = "Allow"
117
+ Action = ["rds-db:connect"]
118
+ Resource = [
119
+ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}"
120
+ ]
121
+ }
122
+ ]
123
+ }
124
+
125
+ resource "aws_vpc_security_group_ingress_rule" "agent_to_database" {
126
+ security_group_id = module.my_database.security_group_id
127
+ referenced_security_group_id = module.my_agent.security_group_id
128
+ from_port = module.my_database.cluster_port
129
+ to_port = module.my_database.cluster_port
130
+ ip_protocol = "tcp"
131
+ }
132
+
133
+ resource "aws_vpc_security_group_egress_rule" "agent_to_database" {
134
+ security_group_id = module.my_agent.security_group_id
135
+ referenced_security_group_id = module.my_database.security_group_id
136
+ from_port = module.my_database.cluster_port
137
+ to_port = module.my_database.cluster_port
138
+ ip_protocol = "tcp"
139
+ }
140
+ ```
141
+
142
+ `appconfig_application_id`/`appconfig_application_arn` come from the shared <Link path="guides/runtime-config">runtime configuration</Link> AppConfig application declared once in your root module, not from the database module.
143
+
144
+ </Fragment>
145
+ </Infrastructure>
146
+
147
+ ### SSL Requirements When Connecting Without RDS Proxy
148
+
149
+ When the agent connects directly to the Aurora cluster (without RDS Proxy), the connection generator updates the generated agent Dockerfile to install the Amazon RDS CA bundle into the system trust store:
150
+
151
+ ```dockerfile
152
+ ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /usr/local/share/ca-certificates/rds-global-bundle.crt
153
+ RUN update-ca-certificates
154
+ ```
155
+
156
+ When using RDS Proxy, you do not need to configure the RDS CA bundle in the agent runtime.
157
+
158
+ ## Local Development
159
+
160
+ <NxCommands commands={["<agent-name>-dev <project-name>"]} />
161
+
162
+ This starts the agent and all connected databases. The `LOCAL_DEV=true` environment variable causes the database client to connect to its local Docker database instead of Aurora.
@@ -0,0 +1,170 @@
1
+ ---
2
+ title: FastAPI to Relational Database
3
+ description: Connect a FastAPI to a Python Relational Database
4
+ when:
5
+ sourceType: py#fast-api
6
+ targetType: py#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
+
15
+ 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
+ ## Prerequisites
18
+
19
+ Before using this generator, ensure you have:
20
+
21
+ 1. A <Link path="guides/fastapi">`py#fast-api`</Link> project
22
+ 2. A <Link path="guides/py-rdb">`py#rdb`</Link> project
23
+
24
+ ## Usage
25
+
26
+ ### Run the Generator
27
+
28
+ <RunGenerator generator="connection" />
29
+
30
+ Select your FastAPI 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 your FastAPI project:
39
+
40
+ <FileTree>
41
+
42
+ - packages/my_api
43
+ - project.json Adds a dependency from `dev` on the database's `dev` target
44
+ - pyproject.toml Adds the database package as a workspace dependency
45
+ - my_api
46
+ - dependencies
47
+ - my_db.py FastAPI `MyDbSession` dependency for the database session
48
+
49
+ </FileTree>
50
+
51
+ ## Using the Database in Route Handlers
52
+
53
+ This generator configures an injectable [FastAPI Dependency](https://fastapi.tiangolo.com/tutorial/dependencies/) which you can use in your route handlers:
54
+
55
+ ```python title="packages/my_api/my_api/api.py" {2,6,10}
56
+ from sqlmodel import select
57
+ from my_api.dependencies.my_db import MyDbSession
58
+ from my_scope.my_db.models.example import ExampleModel
59
+
60
+ @app.get("/examples")
61
+ async def list_examples(my_db: MyDbSession):
62
+ return (await my_db.execute(select(ExampleModel))).all()
63
+
64
+ @app.post("/examples")
65
+ async def create_example(name: str, my_db: MyDbSession):
66
+ item = ExampleModel(name=name)
67
+ my_db.add(item)
68
+ await my_db.commit()
69
+ await my_db.refresh(item)
70
+ return item
71
+ ```
72
+
73
+ FastAPI automatically opens a new session per request and closes it when the handler returns.
74
+
75
+ ## Infrastructure
76
+
77
+ To allow the FastAPI Lambda function to connect to the database at runtime, it must be deployed into the same VPC as the database and granted network and IAM access.
78
+
79
+ <Infrastructure>
80
+ <Fragment slot="cdk">
81
+
82
+ In your application stack, deploy the API into the same VPC as the database, then call `allowDefaultPortFrom` and `grantConnect` to open the network path and grant IAM `rds-db:connect` permission to the Lambda handler:
83
+
84
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
85
+ import { MyDatabase } from ':my-scope/common-constructs';
86
+
87
+ const db = new MyDatabase(this, 'Db', { vpc, ... });
88
+
89
+ const api = new MyApi(this, 'Api', {
90
+ integrations: MyApi.defaultIntegrations(this)
91
+ .withDefaultOptions({
92
+ vpc,
93
+ vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },
94
+ })
95
+ .build(),
96
+ });
97
+
98
+ Object.entries(api.integrations).forEach(([operation, integration]) => {
99
+ db.allowDefaultPortFrom(integration.handler, `Allow ${operation} to connect to the database`);
100
+ db.grantConnect(integration.handler);
101
+ });
102
+ ```
103
+
104
+ Deploy the API Lambda functions into a **private subnet with egress**, not a private isolated subnet. At runtime, `session_context()` retrieves database configuration from AWS AppConfig, which is a public AWS service endpoint that requires outbound internet access.
105
+
106
+ :::note
107
+ This example grants every handler in your API access, but if only some handlers need access it's better to configure individually.
108
+ :::
109
+
110
+ </Fragment>
111
+ <Fragment slot="terraform">
112
+
113
+ Deploy the API into the same VPC as the database, grant it `rds-db:connect` via `additional_iam_policy_statements`, and open the network path with a pair of security group rules:
114
+
115
+ ```hcl title="packages/infra/src/main.tf"
116
+ module "my_database" {
117
+ source = "../../common/terraform/src/app/dbs/my-database"
118
+ vpc_id = module.vpc.vpc_id
119
+ database_subnet_ids = module.vpc.private_isolated_subnet_ids
120
+ lambda_subnet_ids = module.vpc.private_subnet_ids
121
+ }
122
+
123
+ module "api" {
124
+ source = "..."
125
+ enable_vpc = true
126
+ vpc_id = module.vpc.vpc_id
127
+ subnet_ids = module.vpc.private_subnet_ids
128
+
129
+ additional_iam_policy_statements = [
130
+ {
131
+ Effect = "Allow"
132
+ Action = ["rds-db:connect"]
133
+ Resource = [
134
+ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}"
135
+ ]
136
+ }
137
+ ]
138
+
139
+ env = {
140
+ RUNTIME_CONFIG_APP_ID = module.runtime_config_appconfig.application_id
141
+ }
142
+ }
143
+
144
+ resource "aws_vpc_security_group_ingress_rule" "api_to_database" {
145
+ security_group_id = module.my_database.security_group_id
146
+ referenced_security_group_id = module.api.security_group_id
147
+ from_port = module.my_database.cluster_port
148
+ to_port = module.my_database.cluster_port
149
+ ip_protocol = "tcp"
150
+ }
151
+
152
+ resource "aws_vpc_security_group_egress_rule" "api_to_database" {
153
+ security_group_id = module.api.security_group_id
154
+ referenced_security_group_id = module.my_database.security_group_id
155
+ from_port = module.my_database.cluster_port
156
+ to_port = module.my_database.cluster_port
157
+ ip_protocol = "tcp"
158
+ }
159
+ ```
160
+
161
+ Deploy the API Lambda functions into **private subnets with egress**, not private isolated subnets. `RUNTIME_CONFIG_APP_ID` should point at the shared <Link path="guides/runtime-config">runtime configuration</Link> AppConfig application, not an output of the database module.
162
+
163
+ </Fragment>
164
+ </Infrastructure>
165
+
166
+ ## Local Development
167
+
168
+ <NxCommands commands={["dev <project-name>"]} />
169
+
170
+ This starts the FastAPI and all connected databases. The `LOCAL_DEV=true` environment variable causes the database client to connect to its local Docker database instead of Aurora.
@@ -0,0 +1,171 @@
1
+ ---
2
+ title: Python MCP Server to Relational Database
3
+ description: Connect a Python MCP Server to a Relational Database
4
+ when:
5
+ sourceType: py#mcp-server
6
+ targetType: py#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
+
15
+ The `connection` generator wires a <Link path="guides/py-mcp-server">Python MCP Server</Link> to a <Link path="guides/py-rdb">Python Relational Database</Link> project, making the database session available to all tools registered in the server.
16
+
17
+ ## Prerequisites
18
+
19
+ Before using this generator, ensure you have:
20
+
21
+ 1. A <Link path="guides/py-mcp-server">`py#mcp-server`</Link> project
22
+ 2. A <Link path="guides/py-rdb">`py#rdb`</Link> project
23
+
24
+ ## Usage
25
+
26
+ ### Run the Generator
27
+
28
+ <RunGenerator generator="connection" />
29
+
30
+ Select your MCP server project as the source and your relational database project as the target. If the project contains multiple MCP server components, specify `sourceComponent` to disambiguate.
31
+
32
+ ### Options
33
+
34
+ <GeneratorParameters generator="connection" />
35
+
36
+ ## Generator Output
37
+
38
+ <FileTree>
39
+
40
+ - packages/my\_service
41
+ - project.json Adds a dependency from `my_mcp_server-dev` on the database's `dev` target
42
+ - pyproject.toml Adds the database package as a workspace dependency
43
+ - my\_service
44
+ - my\_mcp\_server
45
+ - Dockerfile Adds the RDS CA bundle used for direct Aurora connections
46
+
47
+ </FileTree>
48
+
49
+ ## Using the Database in MCP Tools
50
+
51
+ Import `session_context` from your database package and use it inside your MCP server tools:
52
+
53
+ ```python title="packages/my_service/my_service/my_mcp_server/server.py"
54
+ from sqlmodel import select
55
+ from my_scope.my_db import session_context
56
+ from my_scope.my_db.models.example import ExampleModel
57
+
58
+ @mcp.tool()
59
+ async def list_examples() -> str:
60
+ """List all example records."""
61
+ async with session_context() as session:
62
+ items = (await session.execute(select(ExampleModel))).all()
63
+ return str([item.model_dump() for item in items])
64
+ ```
65
+
66
+ ## Multiple Databases
67
+
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
+
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
73
+ ```
74
+
75
+ ## Infrastructure
76
+
77
+ The generated MCP server construct implements `IGrantable` and `IConnectable`, so you can grant network and IAM access to the database directly on the construct.
78
+
79
+ <Infrastructure>
80
+ <Fragment slot="cdk">
81
+
82
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
83
+ import { RuntimeNetworkConfiguration } from 'aws-cdk-lib/aws-bedrockagentcore';
84
+ import { MyDatabase } from ':my-scope/common-constructs';
85
+
86
+ const db = new MyDatabase(this, 'Db', { vpc, ... });
87
+
88
+ const myMcpServer = new MyMcpServer(this, 'MyMcpServer', {
89
+ networkConfiguration: RuntimeNetworkConfiguration.usingVpc(this, {
90
+ vpc,
91
+ vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },
92
+ }),
93
+ });
94
+
95
+ db.allowDefaultPortFrom(myMcpServer);
96
+ db.grantConnect(myMcpServer);
97
+ ```
98
+
99
+ `allowDefaultPortFrom` opens the security group rule so the MCP server runtime can reach the database port. `grantConnect` grants IAM `rds-db:connect` permission to the server's execution role.
100
+
101
+ </Fragment>
102
+ <Fragment slot="terraform">
103
+
104
+ Run the MCP server inside the same VPC as the database, grant it `rds-db:connect` via `additional_iam_policy_statements`, and open the network path with a pair of security group rules:
105
+
106
+ ```hcl title="packages/infra/src/main.tf"
107
+ module "my_database" {
108
+ source = "../../common/terraform/src/app/dbs/my-database"
109
+ vpc_id = module.vpc.vpc_id
110
+ database_subnet_ids = module.vpc.private_isolated_subnet_ids
111
+ lambda_subnet_ids = module.vpc.private_subnet_ids
112
+ }
113
+
114
+ module "my_mcp_server" {
115
+ source = "../../common/terraform/src/app/mcp-servers/my-mcp-server"
116
+ enable_vpc = true
117
+ vpc_id = module.vpc.vpc_id
118
+ subnet_ids = module.vpc.private_subnet_ids
119
+
120
+ appconfig_application_id = module.runtime_config_appconfig.application_id
121
+ appconfig_application_arn = module.runtime_config_appconfig.application_arn
122
+
123
+ additional_iam_policy_statements = [
124
+ {
125
+ Effect = "Allow"
126
+ Action = ["rds-db:connect"]
127
+ Resource = [
128
+ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}"
129
+ ]
130
+ }
131
+ ]
132
+ }
133
+
134
+ resource "aws_vpc_security_group_ingress_rule" "mcp_server_to_database" {
135
+ security_group_id = module.my_database.security_group_id
136
+ referenced_security_group_id = module.my_mcp_server.security_group_id
137
+ from_port = module.my_database.cluster_port
138
+ to_port = module.my_database.cluster_port
139
+ ip_protocol = "tcp"
140
+ }
141
+
142
+ resource "aws_vpc_security_group_egress_rule" "mcp_server_to_database" {
143
+ security_group_id = module.my_mcp_server.security_group_id
144
+ referenced_security_group_id = module.my_database.security_group_id
145
+ from_port = module.my_database.cluster_port
146
+ to_port = module.my_database.cluster_port
147
+ ip_protocol = "tcp"
148
+ }
149
+ ```
150
+
151
+ `appconfig_application_id`/`appconfig_application_arn` come from the shared <Link path="guides/runtime-config">runtime configuration</Link> AppConfig application declared once in your root module, not from the database module.
152
+
153
+ </Fragment>
154
+ </Infrastructure>
155
+
156
+ ### SSL Requirements When Connecting Without RDS Proxy
157
+
158
+ When the MCP server connects directly to the Aurora cluster (without RDS Proxy), the connection generator updates the generated MCP server Dockerfile to install the Amazon RDS CA bundle into the system trust store:
159
+
160
+ ```dockerfile
161
+ ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /usr/local/share/ca-certificates/rds-global-bundle.crt
162
+ RUN update-ca-certificates
163
+ ```
164
+
165
+ When using RDS Proxy, you do not need to configure the RDS CA bundle in the MCP server runtime.
166
+
167
+ ## Local Development
168
+
169
+ <NxCommands commands={["<mcp-server-name>-dev <project-name>"]} />
170
+
171
+ This starts the MCP server and all connected databases. The `LOCAL_DEV=true` environment variable causes the database client to connect to its local Docker database instead of Aurora.
@@ -134,7 +134,7 @@ const httpResponse = await serviceHandler.handle(httpRequest, {
134
134
 
135
135
  ### SSL Requirements When Connecting Without RDS Proxy
136
136
 
137
- <Snippet name="connection/lambda-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
137
+ <Snippet name="connection/ts-lambda-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
138
138
 
139
139
  ## Local Development
140
140
 
@@ -116,7 +116,7 @@ export const dbProcedure = t.procedure
116
116
 
117
117
  ### SSL Requirements When Connecting Without RDS Proxy
118
118
 
119
- <Snippet name="connection/lambda-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
119
+ <Snippet name="connection/ts-lambda-rdb-ssl-requirements" parentHeading="SSL Requirements When Connecting Without RDS Proxy" />
120
120
 
121
121
  ## Local Development
122
122
 
@@ -48,13 +48,9 @@ The generator modifies two files in your agent's source directory:
48
48
 
49
49
  Additionally, the agent's `<agent-name>-dev` target is updated to depend on the database's `dev` target.
50
50
 
51
- ## How It Works
51
+ ## Using the Database in Agent Tools
52
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:
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:
58
54
 
59
55
  ```ts title="packages/my-service/src/my-agent/agent.ts" {1,4}
60
56
  import { getPrisma as getMyDb } from ':my-scope/my-db';
@@ -66,7 +62,6 @@ export const getAgent = async () => {
66
62
  };
67
63
  ```
68
64
 
69
-
70
65
  ## Multiple Databases
71
66
 
72
67
  Running the generator again with a different target adds the second database alongside the first:
@@ -91,10 +86,17 @@ The generated agent construct implements `IGrantable` and `IConnectable`, so you
91
86
  <Fragment slot="cdk">
92
87
 
93
88
  ```ts title="packages/infra/src/stacks/application-stack.ts"
89
+ import { RuntimeNetworkConfiguration } from 'aws-cdk-lib/aws-bedrockagentcore';
94
90
  import { MyDatabase } from ':my-scope/common-constructs';
95
91
 
96
92
  const db = new MyDatabase(this, 'Db', { vpc, ... });
97
- const myAgent = new MyAgent(this, 'MyAgent', { vpc, ... });
93
+
94
+ const myAgent = new MyAgent(this, 'MyAgent', {
95
+ networkConfiguration: RuntimeNetworkConfiguration.usingVpc(this, {
96
+ vpc,
97
+ vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },
98
+ }),
99
+ });
98
100
 
99
101
  db.allowDefaultPortFrom(myAgent);
100
102
  db.grantConnect(myAgent);
@@ -105,27 +107,54 @@ db.grantConnect(myAgent);
105
107
  </Fragment>
106
108
  <Fragment slot="terraform">
107
109
 
108
- Pass the database module outputs into your agent module so it can reach the database and read its runtime configuration:
110
+ Run the agent inside the same VPC as the database, grant it `rds-db:connect` via `additional_iam_policy_statements`, and open the network path with a pair of security group rules:
109
111
 
110
112
  ```hcl title="packages/infra/src/main.tf"
111
113
  module "my_database" {
112
114
  source = "../../common/terraform/src/app/dbs/my-database"
113
115
  vpc_id = module.vpc.vpc_id
114
116
  database_subnet_ids = module.vpc.private_isolated_subnet_ids
117
+ lambda_subnet_ids = module.vpc.private_subnet_ids
115
118
  }
116
119
 
117
120
  module "my_agent" {
118
- source = "../../common/terraform/src/app/agents/my-agent"
121
+ source = "../../common/terraform/src/app/agents/my-agent"
122
+ enable_vpc = true
123
+ vpc_id = module.vpc.vpc_id
124
+ subnet_ids = module.vpc.private_subnet_ids
125
+
126
+ appconfig_application_id = module.runtime_config_appconfig.application_id
127
+ appconfig_application_arn = module.runtime_config_appconfig.application_arn
128
+
129
+ additional_iam_policy_statements = [
130
+ {
131
+ Effect = "Allow"
132
+ Action = ["rds-db:connect"]
133
+ Resource = [
134
+ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}"
135
+ ]
136
+ }
137
+ ]
138
+ }
139
+
140
+ resource "aws_vpc_security_group_ingress_rule" "agent_to_database" {
141
+ security_group_id = module.my_database.security_group_id
142
+ referenced_security_group_id = module.my_agent.security_group_id
143
+ from_port = module.my_database.cluster_port
144
+ to_port = module.my_database.cluster_port
145
+ ip_protocol = "tcp"
146
+ }
119
147
 
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
148
+ resource "aws_vpc_security_group_egress_rule" "agent_to_database" {
149
+ security_group_id = module.my_agent.security_group_id
150
+ referenced_security_group_id = module.my_database.security_group_id
151
+ from_port = module.my_database.cluster_port
152
+ to_port = module.my_database.cluster_port
153
+ ip_protocol = "tcp"
125
154
  }
126
155
  ```
127
156
 
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.
157
+ `appconfig_application_id`/`appconfig_application_arn` come from the shared <Link path="guides/runtime-config">runtime configuration</Link> AppConfig application declared once in your root module, not from the database module.
129
158
 
130
159
  </Fragment>
131
160
  </Infrastructure>