@aws/nx-plugin 1.0.0-rc.90 → 1.0.0-rc.92
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/LICENSE-THIRD-PARTY +2 -2
- package/migrations.json +32 -27
- package/package.json +4 -4
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/internal/test-matrix/generator.js +28 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/migrations/latest/react-website-unique-dev-ports/metadata.json +3 -0
- package/src/migrations/latest/react-website-unique-dev-ports/migration.js +79 -0
- package/src/migrations/latest/react-website-unique-dev-ports/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.87/0001-add-destroy-sandbox-target/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.88/0001-python-version-drop-exact-patch/migration.d.ts +6 -0
- package/src/migrations/v1.0.0-rc.88/0001-python-version-drop-exact-patch/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.88/0002-react-website-nx-react-express-override/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.89/0001-nx-parallel-default/migration.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +2 -2
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +1 -1
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +91 -116
- package/src/py/agent/files/package/main.py.template +13 -0
- package/src/py/agent/generator.d.ts +6 -1
- package/src/py/agent/generator.js +82 -45
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/schema.d.js.map +1 -1
- package/src/py/agent/schema.d.ts +2 -1
- package/src/py/agent/schema.json +2 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +66 -115
- package/src/py/mcp-server/files/package/main.py.template +13 -0
- package/src/py/mcp-server/generator.d.ts +6 -1
- package/src/py/mcp-server/generator.js +79 -43
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/mcp-server/schema.d.js.map +1 -1
- package/src/py/mcp-server/schema.d.ts +2 -1
- package/src/py/mcp-server/schema.json +2 -2
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +14 -61
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +78 -115
- package/src/ts/agent/generator.d.ts +26 -1
- package/src/ts/agent/generator.js +71 -45
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/schema.d.js.map +1 -1
- package/src/ts/agent/schema.d.ts +2 -1
- package/src/ts/agent/schema.json +2 -2
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +65 -114
- package/src/ts/mcp-server/generator.d.ts +26 -1
- package/src/ts/mcp-server/generator.js +66 -38
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.d.js.map +1 -1
- package/src/ts/mcp-server/schema.d.ts +2 -1
- package/src/ts/mcp-server/schema.json +2 -2
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +16 -110
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +12 -10
- package/src/ts/react-website/app/generator.js +16 -0
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +1 -1
- package/src/ts/react-website/cognito-auth/generator.js +14 -2
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +25 -6
- package/src/utils/agent-core-constructs/agent-core-constructs.js +36 -7
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +20 -4
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +34 -1
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +51 -112
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core-code/runtime.tf.template +204 -0
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core-container/runtime.tf.template +235 -0
- package/src/utils/agent-core-packaging.d.ts +119 -0
- package/src/utils/agent-core-packaging.js +131 -0
- package/src/utils/agent-core-packaging.js.map +1 -0
- package/src/utils/agent-core-runtime-resolution.d.ts +35 -0
- package/src/utils/agent-core-runtime-resolution.js +68 -0
- package/src/utils/agent-core-runtime-resolution.js.map +1 -0
- package/src/utils/files/terraform/src/core/asset-ecr/asset-ecr.tf.template +137 -0
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +1 -1
- package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +1 -4
- package/src/utils/identity-constructs/identity-constructs.d.ts +22 -2
- package/src/utils/identity-constructs/identity-constructs.js +75 -5
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/port.d.ts +5 -0
- package/src/utils/port.js +1 -1
- package/src/utils/port.js.map +1 -1
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +12 -59
- package/src/utils/versions.d.ts +51 -31
- package/src/utils/versions.js +48 -31
- package/src/utils/versions.js.map +1 -1
- package/src/migrations/latest/add-destroy-sandbox-target/migration.js.map +0 -1
- package/src/migrations/latest/nx-parallel-default/migration.js.map +0 -1
- package/src/migrations/latest/python-version-drop-exact-patch/migration.js.map +0 -1
- package/src/migrations/latest/react-website-nx-react-express-override/migration.js.map +0 -1
- package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.js.map +0 -1
- /package/src/migrations/latest/{add-destroy-sandbox-target → react-website-unique-dev-ports}/migration.d.ts +0 -0
- /package/src/migrations/{latest/add-destroy-sandbox-target → v1.0.0-rc.87/0001-add-destroy-sandbox-target}/metadata.json +0 -0
- /package/src/migrations/{latest/python-version-drop-exact-patch → v1.0.0-rc.87/0001-add-destroy-sandbox-target}/migration.d.ts +0 -0
- /package/src/migrations/{latest/add-destroy-sandbox-target → v1.0.0-rc.87/0001-add-destroy-sandbox-target}/migration.js +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/__snapshots__/migration.spec.ts.snap +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/metadata.json +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/migration.d.ts +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/migration.js +0 -0
- /package/src/migrations/{latest/python-version-drop-exact-patch → v1.0.0-rc.88/0001-python-version-drop-exact-patch}/metadata.json +0 -0
- /package/src/migrations/{latest/python-version-drop-exact-patch → v1.0.0-rc.88/0001-python-version-drop-exact-patch}/migration.js +0 -0
- /package/src/migrations/{latest/react-website-nx-react-express-override → v1.0.0-rc.88/0002-react-website-nx-react-express-override}/metadata.json +0 -0
- /package/src/migrations/{latest/react-website-nx-react-express-override → v1.0.0-rc.88/0002-react-website-nx-react-express-override}/migration.d.ts +0 -0
- /package/src/migrations/{latest/react-website-nx-react-express-override → v1.0.0-rc.88/0002-react-website-nx-react-express-override}/migration.js +0 -0
- /package/src/migrations/{latest/nx-parallel-default → v1.0.0-rc.89/0001-nx-parallel-default}/metadata.json +0 -0
- /package/src/migrations/{latest/nx-parallel-default → v1.0.0-rc.89/0001-nx-parallel-default}/migration.d.ts +0 -0
- /package/src/migrations/{latest/nx-parallel-default → v1.0.0-rc.89/0001-nx-parallel-default}/migration.js +0 -0
- /package/src/ts/mcp-server/files/{http.ts.template → app/http.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{index.ts.template → app/index.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{resources → app/resources}/sample-guidance.ts.template +0 -0
- /package/src/ts/mcp-server/files/{server.ts.template → app/server.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{stdio.ts.template → app/stdio.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{tools → app/tools}/divide.ts.template +0 -0
- /package/src/ts/mcp-server/files/{Dockerfile.template → deploy/Dockerfile.template} +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/ import { generateFiles, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
5
5
|
import { addPyDependencies, addTsDependencies } from "../../utils/add-dependencies.js";
|
|
6
6
|
import { addMcpServerInfra } from "../../utils/agent-core-constructs/agent-core-constructs.js";
|
|
7
|
+
import { addPythonCodePackageTarget, agentCorePythonRuntime, isAgentCoreHosted, isContainerHosted } from "../../utils/agent-core-packaging.js";
|
|
7
8
|
import { addPythonBundleTarget } from "../../utils/bundle/bundle.js";
|
|
8
9
|
import { resolveContainers } from "../../utils/containers.js";
|
|
9
10
|
import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
|
|
@@ -89,53 +90,88 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
89
90
|
}, {
|
|
90
91
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
91
92
|
});
|
|
92
|
-
if (infra
|
|
93
|
+
if (isAgentCoreHosted(infra)) {
|
|
94
|
+
const container = isContainerHosted(infra);
|
|
93
95
|
const containers = await resolveContainers(tree, 'inherit');
|
|
94
96
|
const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;
|
|
95
97
|
// Add bundle target
|
|
96
98
|
const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(project, {
|
|
97
99
|
pythonPlatform: 'aarch64-manylinux_2_28'
|
|
98
100
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
project,
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
101
|
+
let artifact;
|
|
102
|
+
if (container) {
|
|
103
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'deploy'), targetSourceDir, {
|
|
104
|
+
mcpServerNameSnakeCase,
|
|
105
|
+
moduleName,
|
|
106
|
+
bundleOutputDir,
|
|
107
|
+
pythonBaseImage: BASE_IMAGES.python
|
|
108
|
+
}, {
|
|
109
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
110
|
+
});
|
|
111
|
+
const dockerOutputDir = joinPathFragments('dist', project.root, 'docker', name);
|
|
112
|
+
const dockerTargetName = `${mcpTargetPrefix}-docker`;
|
|
113
|
+
// Add a docker target that prepares the docker context and builds the image
|
|
114
|
+
const fs = new FsCommands(tree, DEPENDENCIES);
|
|
115
|
+
project.targets[dockerTargetName] = {
|
|
116
|
+
cache: IMAGE_BUILD_CACHE,
|
|
117
|
+
executor: 'nx:run-commands',
|
|
118
|
+
options: {
|
|
119
|
+
commands: [
|
|
120
|
+
fs.rm(dockerOutputDir),
|
|
121
|
+
fs.mkdir(dockerOutputDir),
|
|
122
|
+
fs.cp(bundleOutputDir, dockerOutputDir),
|
|
123
|
+
fs.cp(`${targetSourceDir}/Dockerfile`, `${dockerOutputDir}/Dockerfile`),
|
|
124
|
+
`${containers} build --platform linux/arm64 -t ${dockerImageTag} ${dockerOutputDir}`
|
|
125
|
+
],
|
|
126
|
+
parallel: false
|
|
127
|
+
},
|
|
128
|
+
dependsOn: [
|
|
129
|
+
bundleTargetName
|
|
130
|
+
]
|
|
131
|
+
};
|
|
132
|
+
addDependencyToTargetIfNotPresent(project, 'docker', dockerTargetName);
|
|
133
|
+
addArtifactDependencyToTargets(project, 'docker');
|
|
134
|
+
addDockerScanTarget(tree, {
|
|
135
|
+
project,
|
|
136
|
+
containerEngine: containers,
|
|
137
|
+
trivyTargetName: `${mcpTargetPrefix}-trivy`,
|
|
138
|
+
dockerTargetName,
|
|
139
|
+
imageTags: [
|
|
140
|
+
dockerImageTag
|
|
141
|
+
]
|
|
142
|
+
}, DEPENDENCIES);
|
|
143
|
+
artifact = {
|
|
144
|
+
type: 'container',
|
|
145
|
+
dockerImageTag,
|
|
146
|
+
outputDir: dockerOutputDir
|
|
147
|
+
};
|
|
148
|
+
} else {
|
|
149
|
+
// The entry point the managed runtime runs, at the package root.
|
|
150
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'package'), joinPathFragments(project.root, 'package', mcpServerNameSnakeCase), {
|
|
151
|
+
mcpServerNameSnakeCase,
|
|
152
|
+
moduleName
|
|
153
|
+
}, {
|
|
154
|
+
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
155
|
+
});
|
|
156
|
+
const packageOutputDir = joinPathFragments('dist', project.root, 'package', name);
|
|
157
|
+
addPythonCodePackageTarget(tree, {
|
|
158
|
+
project,
|
|
159
|
+
targetName: `${mcpTargetPrefix}-package`,
|
|
160
|
+
bundleTargetName,
|
|
161
|
+
bundleOutputDir,
|
|
162
|
+
packageOutputDir,
|
|
163
|
+
sourceRoot: project.sourceRoot,
|
|
164
|
+
moduleName,
|
|
165
|
+
entryPointPath: joinPathFragments(project.root, 'package', mcpServerNameSnakeCase, 'main.py'),
|
|
166
|
+
entryPointFileName: 'main.py'
|
|
167
|
+
}, DEPENDENCIES);
|
|
168
|
+
artifact = {
|
|
169
|
+
type: 'code',
|
|
170
|
+
outputDir: packageOutputDir,
|
|
171
|
+
runtime: agentCorePythonRuntime(),
|
|
172
|
+
entryPoint: 'main.py'
|
|
173
|
+
};
|
|
174
|
+
}
|
|
139
175
|
// Add shared constructs
|
|
140
176
|
await sharedConstructsGenerator(tree, {
|
|
141
177
|
iac
|
|
@@ -145,8 +181,7 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
145
181
|
mcpServerNameKebabCase: name,
|
|
146
182
|
mcpServerNameClassName,
|
|
147
183
|
projectName: project.name,
|
|
148
|
-
|
|
149
|
-
dockerOutputDir,
|
|
184
|
+
artifact,
|
|
150
185
|
iac,
|
|
151
186
|
auth,
|
|
152
187
|
containers
|
|
@@ -161,6 +196,7 @@ export const pyMcpServerGenerator = async (tree, options)=>{
|
|
|
161
196
|
// Recorded below and read by the declaration's predicates, so the packages
|
|
162
197
|
// added here are exactly the ones the version sync will own.
|
|
163
198
|
const metadata = {
|
|
199
|
+
infra,
|
|
164
200
|
port: localDevPort,
|
|
165
201
|
rc: mcpServerNameClassName,
|
|
166
202
|
auth,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n addPyDependencies,\n addTsDependencies,\n} from '../../utils/add-dependencies.js';\nimport { addMcpServerInfra } from '../../utils/agent-core-constructs/agent-core-constructs.js';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport {\n addDockerScanTarget,\n DOCKER_DEPENDENCIES,\n IMAGE_BUILD_CACHE,\n} from '../../utils/docker.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { FS_DEPENDENCIES, FsCommands } from '../../utils/fs.js';\nimport { resolveIac } from '../../utils/iac.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { kebabCase, toClassName, toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addComponentDevTarget,\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx.js';\nimport { toProjectRelativePath } from '../../utils/paths.js';\nimport { registerPnpmBuiltDependencies } from '../../utils/pnpm-workspace.js';\nimport { assignPort } from '../../utils/port.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport type { IacMetadata } from '../../utils/shared-constructs-constants.js';\nimport { BASE_IMAGES } from '../../utils/versions.js';\nimport type { PyMcpServerGeneratorSchema } from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface PyMcpServerMetadata extends IacMetadata {\n readonly port: number;\n readonly rc: string;\n readonly auth: string;\n}\n\nexport const DEPENDENCIES = declareDependencies<PyMcpServerMetadata>()({\n ts: [\n // The MCP inspector is shared tooling.\n { name: '@modelcontextprotocol/inspector', dev: true, root: true },\n // Added by the helpers that own the projects they belong to.\n ...ownedElsewhere(FS_DEPENDENCIES),\n ...ownedElsewhere(DOCKER_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: [\n { name: 'aws-lambda-powertools' },\n { name: 'mcp' },\n { name: 'uvicorn' },\n { name: 'boto3' },\n { name: 'aws-opentelemetry-distro' },\n ],\n});\n\nexport const PY_MCP_SERVER_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyMcpServerGenerator = async (\n tree: Tree,\n options: PyMcpServerGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const project = readProjectConfigurationUnqualified(tree, options.project);\n\n const pyProjectPath = joinPathFragments(project.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `Unsupported project ${options.project}. Expected a Python project (with a pyproject.toml)`,\n );\n }\n\n if (!project.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n // Module name is the last part of the source root,\n const sourceParts = project.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const name = kebabCase(\n options.name || `${kebabCase(project.name.split('.').pop())}-mcp-server`,\n );\n const mcpTargetPrefix = options.name ? name : 'mcp-server';\n\n const mcpServerNameSnakeCase = toSnakeCase(options.name || 'mcp-server');\n const mcpServerNameClassName = toClassName(name);\n\n const targetSourceDir = joinPathFragments(\n project.sourceRoot,\n mcpServerNameSnakeCase,\n );\n\n const infra = options.infra ?? 'agentcore';\n\n // Recorded in the metadata below so the version sync can tell a CDK\n // project from a Terraform one; undefined when no infrastructure was\n // generated, in which case neither provider's packages were added.\n const iac =\n infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n if (infra === 'none' && options.auth && options.auth !== 'iam') {\n console.warn(\n 'Warning: auth is ignored when no infrastructure is configured (no infrastructure is generated)',\n );\n }\n\n const auth = options.auth ?? 'iam';\n\n // Generate example server\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'app'),\n targetSourceDir,\n {\n name,\n mcpServerNameSnakeCase,\n mcpServerNameClassName,\n moduleName,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (infra === 'agentcore') {\n const containers = await resolveContainers(tree, 'inherit');\n const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;\n\n // Add bundle target\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n project,\n {\n pythonPlatform: 'aarch64-manylinux_2_28',\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'deploy'),\n targetSourceDir,\n {\n mcpServerNameSnakeCase,\n moduleName,\n bundleOutputDir,\n pythonBaseImage: BASE_IMAGES.python,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const dockerOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'docker',\n name,\n );\n const dockerTargetName = `${mcpTargetPrefix}-docker`;\n\n // Add a docker target that prepares the docker context and builds the image\n const fs = new FsCommands(tree, DEPENDENCIES);\n project.targets[dockerTargetName] = {\n cache: IMAGE_BUILD_CACHE,\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(dockerOutputDir),\n fs.mkdir(dockerOutputDir),\n fs.cp(bundleOutputDir, dockerOutputDir),\n fs.cp(\n `${targetSourceDir}/Dockerfile`,\n `${dockerOutputDir}/Dockerfile`,\n ),\n `${containers} build --platform linux/arm64 -t ${dockerImageTag} ${dockerOutputDir}`,\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n\n addDependencyToTargetIfNotPresent(project, 'docker', dockerTargetName);\n addArtifactDependencyToTargets(project, 'docker');\n\n addDockerScanTarget(\n tree,\n {\n project,\n containerEngine: containers,\n trivyTargetName: `${mcpTargetPrefix}-trivy`,\n dockerTargetName,\n imageTags: [dockerImageTag],\n },\n DEPENDENCIES,\n );\n\n // Add shared constructs\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n // Add the construct to deploy the mcp server\n await addMcpServerInfra(tree, {\n mcpServerNameKebabCase: name,\n mcpServerNameClassName,\n projectName: project.name,\n dockerImageTag,\n dockerOutputDir,\n iac,\n auth,\n containers,\n });\n }\n\n const localDevPort = assignPort(tree, project, 8000, {\n component: { info: PY_MCP_SERVER_GENERATOR_INFO, name: mcpTargetPrefix },\n });\n\n // Recorded below and read by the declaration's predicates, so the packages\n // added here are exactly the ones the version sync will own.\n const metadata: PyMcpServerMetadata = {\n port: localDevPort,\n rc: mcpServerNameClassName,\n auth,\n ...(iac ? { iac } : {}),\n };\n\n // The MCP inspector has a postinstall script that cascades installs into its\n // client packages, which no-ops when the package is installed as a dependency.\n // Register it as an explicitly-rejected build so pnpm 11's default\n // `strictDepBuilds=true` skips it instead of failing the install.\n registerPnpmBuiltDependencies(tree, {\n '@modelcontextprotocol/inspector': false,\n });\n\n addPyDependencies(tree, DEPENDENCIES, {\n metadata,\n projectRoot: project.root,\n });\n addTsDependencies(tree, DEPENDENCIES, { metadata });\n\n const mcpTargets = {\n ...project.targets,\n // Add targets for running the MCP server\n [`${mcpTargetPrefix}-serve-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [`uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-serve`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n },\n },\n },\n [`${mcpTargetPrefix}-dev`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n LOCAL_DEV: 'true',\n },\n },\n },\n [`${mcpTargetPrefix}-inspect`]: {\n executor: 'nx:run-commands',\n continuous: true,\n // Launch the inspector against the locally served HTTP server. The dev\n // target starts the server and any connected dependencies (e.g. a local\n // database).\n dependsOn: [`${mcpTargetPrefix}-dev`],\n options: {\n commands: [\n `mcp-inspector --transport http --server-url http://localhost:${localDevPort}/mcp`,\n ],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-inspect-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `mcp-inspector -- uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`,\n ],\n cwd: '{projectRoot}',\n },\n },\n };\n\n // Aggregate `<mcp>-dev` under the project-level `dev` target.\n addComponentDevTarget(mcpTargets, `${mcpTargetPrefix}-dev`);\n\n updateProjectConfiguration(tree, project.name, {\n ...project,\n targets: mcpTargets,\n });\n\n addComponentGeneratorMetadata(\n tree,\n project.name,\n PY_MCP_SERVER_GENERATOR_INFO,\n toProjectRelativePath(project, targetSourceDir),\n mcpTargetPrefix,\n metadata,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [PY_MCP_SERVER_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyMcpServerGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addPyDependencies","addTsDependencies","addMcpServerInfra","addPythonBundleTarget","resolveContainers","declareDependencies","ownedElsewhere","addDockerScanTarget","DOCKER_DEPENDENCIES","IMAGE_BUILD_CACHE","formatFilesInSubtree","FS_DEPENDENCIES","FsCommands","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toSnakeCase","getNpmScope","addArtifactDependencyToTargets","addComponentDevTarget","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","toProjectRelativePath","registerPnpmBuiltDependencies","assignPort","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","BASE_IMAGES","DEPENDENCIES","ts","name","dev","root","py","PY_MCP_SERVER_GENERATOR_INFO","filename","pyMcpServerGenerator","tree","options","project","pyProjectPath","Error","sourceRoot","sourceParts","split","moduleName","length","pop","mcpTargetPrefix","mcpServerNameSnakeCase","mcpServerNameClassName","targetSourceDir","infra","iac","undefined","auth","console","warn","dirname","overwriteStrategy","KeepExisting","containers","dockerImageTag","bundleTargetName","bundleOutputDir","pythonPlatform","pythonBaseImage","python","dockerOutputDir","dockerTargetName","fs","targets","cache","executor","commands","rm","mkdir","cp","parallel","dependsOn","containerEngine","trivyTargetName","imageTags","mcpServerNameKebabCase","projectName","localDevPort","component","info","metadata","port","rc","projectRoot","mcpTargets","continuous","cwd","env","PORT","LOCAL_DEV","preferInstallDependencies","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport {\n addPyDependencies,\n addTsDependencies,\n} from '../../utils/add-dependencies.js';\nimport {\n type AgentCoreArtifact,\n addMcpServerInfra,\n} from '../../utils/agent-core-constructs/agent-core-constructs.js';\nimport {\n addPythonCodePackageTarget,\n agentCorePythonRuntime,\n isAgentCoreHosted,\n isContainerHosted,\n} from '../../utils/agent-core-packaging.js';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport {\n addDockerScanTarget,\n DOCKER_DEPENDENCIES,\n IMAGE_BUILD_CACHE,\n} from '../../utils/docker.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { FS_DEPENDENCIES, FsCommands } from '../../utils/fs.js';\nimport { resolveIac } from '../../utils/iac.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { kebabCase, toClassName, toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addComponentDevTarget,\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx.js';\nimport { toProjectRelativePath } from '../../utils/paths.js';\nimport { registerPnpmBuiltDependencies } from '../../utils/pnpm-workspace.js';\nimport { assignPort } from '../../utils/port.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport type { IacMetadata } from '../../utils/shared-constructs-constants.js';\nimport { BASE_IMAGES } from '../../utils/versions.js';\nimport type { PyMcpServerGeneratorSchema, PyMcpServerInfra } from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface PyMcpServerMetadata extends IacMetadata {\n readonly port: number;\n readonly rc: string;\n readonly auth: string;\n /**\n * How this component is packaged and hosted, so a consumer can tell a\n * code-packaged runtime from a container-packaged one without re-deriving it.\n */\n readonly infra: PyMcpServerInfra;\n}\n\nexport const DEPENDENCIES = declareDependencies<PyMcpServerMetadata>()({\n ts: [\n // The MCP inspector is shared tooling.\n { name: '@modelcontextprotocol/inspector', dev: true, root: true },\n // Added by the helpers that own the projects they belong to.\n ...ownedElsewhere(FS_DEPENDENCIES),\n ...ownedElsewhere(DOCKER_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: [\n { name: 'aws-lambda-powertools' },\n { name: 'mcp' },\n { name: 'uvicorn' },\n { name: 'boto3' },\n { name: 'aws-opentelemetry-distro' },\n ],\n});\n\nexport const PY_MCP_SERVER_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyMcpServerGenerator = async (\n tree: Tree,\n options: PyMcpServerGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const project = readProjectConfigurationUnqualified(tree, options.project);\n\n const pyProjectPath = joinPathFragments(project.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `Unsupported project ${options.project}. Expected a Python project (with a pyproject.toml)`,\n );\n }\n\n if (!project.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n // Module name is the last part of the source root,\n const sourceParts = project.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const name = kebabCase(\n options.name || `${kebabCase(project.name.split('.').pop())}-mcp-server`,\n );\n const mcpTargetPrefix = options.name ? name : 'mcp-server';\n\n const mcpServerNameSnakeCase = toSnakeCase(options.name || 'mcp-server');\n const mcpServerNameClassName = toClassName(name);\n\n const targetSourceDir = joinPathFragments(\n project.sourceRoot,\n mcpServerNameSnakeCase,\n );\n\n const infra = options.infra ?? 'agentcore';\n\n // Recorded in the metadata below so the version sync can tell a CDK\n // project from a Terraform one; undefined when no infrastructure was\n // generated, in which case neither provider's packages were added.\n const iac =\n infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n if (infra === 'none' && options.auth && options.auth !== 'iam') {\n console.warn(\n 'Warning: auth is ignored when no infrastructure is configured (no infrastructure is generated)',\n );\n }\n\n const auth = options.auth ?? 'iam';\n\n // Generate example server\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'app'),\n targetSourceDir,\n {\n name,\n mcpServerNameSnakeCase,\n mcpServerNameClassName,\n moduleName,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (isAgentCoreHosted(infra)) {\n const container = isContainerHosted(infra);\n const containers = await resolveContainers(tree, 'inherit');\n const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;\n\n // Add bundle target\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n project,\n {\n pythonPlatform: 'aarch64-manylinux_2_28',\n },\n );\n\n let artifact: AgentCoreArtifact;\n\n if (container) {\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'deploy'),\n targetSourceDir,\n {\n mcpServerNameSnakeCase,\n moduleName,\n bundleOutputDir,\n pythonBaseImage: BASE_IMAGES.python,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const dockerOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'docker',\n name,\n );\n const dockerTargetName = `${mcpTargetPrefix}-docker`;\n\n // Add a docker target that prepares the docker context and builds the image\n const fs = new FsCommands(tree, DEPENDENCIES);\n project.targets[dockerTargetName] = {\n cache: IMAGE_BUILD_CACHE,\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(dockerOutputDir),\n fs.mkdir(dockerOutputDir),\n fs.cp(bundleOutputDir, dockerOutputDir),\n fs.cp(\n `${targetSourceDir}/Dockerfile`,\n `${dockerOutputDir}/Dockerfile`,\n ),\n `${containers} build --platform linux/arm64 -t ${dockerImageTag} ${dockerOutputDir}`,\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n\n addDependencyToTargetIfNotPresent(project, 'docker', dockerTargetName);\n addArtifactDependencyToTargets(project, 'docker');\n\n addDockerScanTarget(\n tree,\n {\n project,\n containerEngine: containers,\n trivyTargetName: `${mcpTargetPrefix}-trivy`,\n dockerTargetName,\n imageTags: [dockerImageTag],\n },\n DEPENDENCIES,\n );\n\n artifact = {\n type: 'container',\n dockerImageTag,\n outputDir: dockerOutputDir,\n };\n } else {\n // The entry point the managed runtime runs, at the package root.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'package'),\n joinPathFragments(project.root, 'package', mcpServerNameSnakeCase),\n {\n mcpServerNameSnakeCase,\n moduleName,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const packageOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'package',\n name,\n );\n addPythonCodePackageTarget(\n tree,\n {\n project,\n targetName: `${mcpTargetPrefix}-package`,\n bundleTargetName,\n bundleOutputDir,\n packageOutputDir,\n sourceRoot: project.sourceRoot,\n moduleName,\n entryPointPath: joinPathFragments(\n project.root,\n 'package',\n mcpServerNameSnakeCase,\n 'main.py',\n ),\n entryPointFileName: 'main.py',\n },\n DEPENDENCIES,\n );\n\n artifact = {\n type: 'code',\n outputDir: packageOutputDir,\n runtime: agentCorePythonRuntime(),\n entryPoint: 'main.py',\n };\n }\n\n // Add shared constructs\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n // Add the construct to deploy the mcp server\n await addMcpServerInfra(tree, {\n mcpServerNameKebabCase: name,\n mcpServerNameClassName,\n projectName: project.name,\n artifact,\n iac,\n auth,\n containers,\n });\n }\n\n const localDevPort = assignPort(tree, project, 8000, {\n component: { info: PY_MCP_SERVER_GENERATOR_INFO, name: mcpTargetPrefix },\n });\n\n // Recorded below and read by the declaration's predicates, so the packages\n // added here are exactly the ones the version sync will own.\n const metadata: PyMcpServerMetadata = {\n infra,\n port: localDevPort,\n rc: mcpServerNameClassName,\n auth,\n ...(iac ? { iac } : {}),\n };\n\n // The MCP inspector has a postinstall script that cascades installs into its\n // client packages, which no-ops when the package is installed as a dependency.\n // Register it as an explicitly-rejected build so pnpm 11's default\n // `strictDepBuilds=true` skips it instead of failing the install.\n registerPnpmBuiltDependencies(tree, {\n '@modelcontextprotocol/inspector': false,\n });\n\n addPyDependencies(tree, DEPENDENCIES, {\n metadata,\n projectRoot: project.root,\n });\n addTsDependencies(tree, DEPENDENCIES, { metadata });\n\n const mcpTargets = {\n ...project.targets,\n // Add targets for running the MCP server\n [`${mcpTargetPrefix}-serve-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [`uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-serve`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n },\n },\n },\n [`${mcpTargetPrefix}-dev`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `uv run uvicorn --reload ${moduleName}.${mcpServerNameSnakeCase}.http:app --host 0.0.0.0 --port ${localDevPort}`,\n ],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n LOCAL_DEV: 'true',\n },\n },\n },\n [`${mcpTargetPrefix}-inspect`]: {\n executor: 'nx:run-commands',\n continuous: true,\n // Launch the inspector against the locally served HTTP server. The dev\n // target starts the server and any connected dependencies (e.g. a local\n // database).\n dependsOn: [`${mcpTargetPrefix}-dev`],\n options: {\n commands: [\n `mcp-inspector --transport http --server-url http://localhost:${localDevPort}/mcp`,\n ],\n cwd: '{projectRoot}',\n },\n },\n [`${mcpTargetPrefix}-inspect-stdio`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [\n `mcp-inspector -- uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`,\n ],\n cwd: '{projectRoot}',\n },\n },\n };\n\n // Aggregate `<mcp>-dev` under the project-level `dev` target.\n addComponentDevTarget(mcpTargets, `${mcpTargetPrefix}-dev`);\n\n updateProjectConfiguration(tree, project.name, {\n ...project,\n targets: mcpTargets,\n });\n\n addComponentGeneratorMetadata(\n tree,\n project.name,\n PY_MCP_SERVER_GENERATOR_INFO,\n toProjectRelativePath(project, targetSourceDir),\n mcpTargetPrefix,\n metadata,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [PY_MCP_SERVER_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyMcpServerGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addPyDependencies","addTsDependencies","addMcpServerInfra","addPythonCodePackageTarget","agentCorePythonRuntime","isAgentCoreHosted","isContainerHosted","addPythonBundleTarget","resolveContainers","declareDependencies","ownedElsewhere","addDockerScanTarget","DOCKER_DEPENDENCIES","IMAGE_BUILD_CACHE","formatFilesInSubtree","FS_DEPENDENCIES","FsCommands","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toSnakeCase","getNpmScope","addArtifactDependencyToTargets","addComponentDevTarget","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","readProjectConfigurationUnqualified","toProjectRelativePath","registerPnpmBuiltDependencies","assignPort","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","BASE_IMAGES","DEPENDENCIES","ts","name","dev","root","py","PY_MCP_SERVER_GENERATOR_INFO","filename","pyMcpServerGenerator","tree","options","project","pyProjectPath","Error","sourceRoot","sourceParts","split","moduleName","length","pop","mcpTargetPrefix","mcpServerNameSnakeCase","mcpServerNameClassName","targetSourceDir","infra","iac","undefined","auth","console","warn","dirname","overwriteStrategy","KeepExisting","container","containers","dockerImageTag","bundleTargetName","bundleOutputDir","pythonPlatform","artifact","pythonBaseImage","python","dockerOutputDir","dockerTargetName","fs","targets","cache","executor","commands","rm","mkdir","cp","parallel","dependsOn","containerEngine","trivyTargetName","imageTags","type","outputDir","packageOutputDir","targetName","entryPointPath","entryPointFileName","runtime","entryPoint","mcpServerNameKebabCase","projectName","localDevPort","component","info","metadata","port","rc","projectRoot","mcpTargets","continuous","cwd","env","PORT","LOCAL_DEV","preferInstallDependencies","languages"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IacOption } from '../../utils/iac.js';\n\nexport type PyMcpServerInfra =
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AgentCoreInfra } from '../../utils/agent-core-packaging.js';\nimport { IacOption } from '../../utils/iac.js';\n\nexport type PyMcpServerInfra = AgentCoreInfra;\n\nexport type PyMcpServerAuth = 'iam' | 'cognito';\n\nexport interface PyMcpServerGeneratorSchema {\n project: string;\n name?: string;\n infra?: PyMcpServerInfra;\n auth?: PyMcpServerAuth;\n iac: IacOption;\n preferInstallDependencies?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GASD,WAOC"}
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { AgentCoreInfra } from '../../utils/agent-core-packaging.js';
|
|
6
7
|
import { IacOption } from '../../utils/iac.js';
|
|
7
8
|
|
|
8
|
-
export type PyMcpServerInfra =
|
|
9
|
+
export type PyMcpServerInfra = AgentCoreInfra;
|
|
9
10
|
|
|
10
11
|
export type PyMcpServerAuth = 'iam' | 'cognito';
|
|
11
12
|
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
},
|
|
40
40
|
"infra": {
|
|
41
41
|
"type": "string",
|
|
42
|
-
"description": "The type of infrastructure to host your MCP server. Select none for no hosting.",
|
|
42
|
+
"description": "The type of infrastructure to host your MCP server. agentcore deploys your code as a zip to an AgentCore managed runtime for the fastest build and deploy cycle. agentcore-ecr builds and hosts a container image instead, for OS-level control or an established container pipeline. Select none for no hosting.",
|
|
43
43
|
"x-prompt": "How would you like to host your MCP server?",
|
|
44
|
-
"enum": ["agentcore", "none"],
|
|
44
|
+
"enum": ["agentcore", "agentcore-ecr", "none"],
|
|
45
45
|
"default": "agentcore",
|
|
46
46
|
"x-priority": "important"
|
|
47
47
|
},
|
|
@@ -343,6 +343,11 @@ variable "create_db_user_docker_image_tag" {
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
|
|
346
|
+
variable "asset_ecr_repository_url" {
|
|
347
|
+
description = "URL of the shared asset ECR repository the Lambda container images are published to. Instantiate the \`core/asset-ecr\` module once per deployment and pass its \`repository_url\` output here."
|
|
348
|
+
type = string
|
|
349
|
+
}
|
|
350
|
+
|
|
346
351
|
data "aws_region" "current" {}
|
|
347
352
|
data "aws_caller_identity" "current" {}
|
|
348
353
|
|
|
@@ -420,76 +425,26 @@ module "add_rdb_to_runtime_config" {
|
|
|
420
425
|
}
|
|
421
426
|
}
|
|
422
427
|
|
|
423
|
-
resource "aws_ecr_repository" "migration_handler" {
|
|
424
|
-
#checkov:skip=CKV_AWS_136:AES256 encryption is sufficient for ECR repositories
|
|
425
|
-
name = "db-migration-\${random_string.suffix.result}"
|
|
426
|
-
image_tag_mutability = "IMMUTABLE"
|
|
427
|
-
force_delete = true
|
|
428
|
-
|
|
429
|
-
image_scanning_configuration {
|
|
430
|
-
scan_on_push = true
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
tags = var.tags
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
resource "aws_ecr_repository_policy" "migration_handler" {
|
|
437
|
-
repository = aws_ecr_repository.migration_handler.name
|
|
438
|
-
|
|
439
|
-
policy = jsonencode({
|
|
440
|
-
Version = "2012-10-17"
|
|
441
|
-
Statement = [
|
|
442
|
-
{
|
|
443
|
-
Sid = "AllowPushPull"
|
|
444
|
-
Effect = "Allow"
|
|
445
|
-
Principal = {
|
|
446
|
-
AWS = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:root"
|
|
447
|
-
}
|
|
448
|
-
Action = [
|
|
449
|
-
"ecr:BatchCheckLayerAvailability",
|
|
450
|
-
"ecr:CompleteLayerUpload",
|
|
451
|
-
"ecr:GetDownloadUrlForLayer",
|
|
452
|
-
"ecr:InitiateLayerUpload",
|
|
453
|
-
"ecr:PutImage",
|
|
454
|
-
"ecr:UploadLayerPart"
|
|
455
|
-
]
|
|
456
|
-
},
|
|
457
|
-
{
|
|
458
|
-
Sid = "AllowLambdaPull"
|
|
459
|
-
Effect = "Allow"
|
|
460
|
-
Principal = {
|
|
461
|
-
Service = "lambda.amazonaws.com"
|
|
462
|
-
}
|
|
463
|
-
Action = [
|
|
464
|
-
"ecr:BatchCheckLayerAvailability",
|
|
465
|
-
"ecr:BatchGetImage",
|
|
466
|
-
"ecr:GetDownloadUrlForLayer"
|
|
467
|
-
]
|
|
468
|
-
}
|
|
469
|
-
]
|
|
470
|
-
})
|
|
471
|
-
}
|
|
472
|
-
|
|
473
428
|
data "external" "docker_digest" {
|
|
474
429
|
program = ["sh", "-c", "echo '{\\"digest\\":\\"'$(docker inspect \${var.migration_docker_image_tag} --format '{{.Id}}')'\\"}' "]
|
|
475
430
|
}
|
|
476
431
|
|
|
477
432
|
locals {
|
|
478
433
|
# Content-based, immutable image tag derived from the local image digest
|
|
479
|
-
image_tag = replace(data.external.docker_digest.result.digest, "sha256:", "")
|
|
434
|
+
image_tag = "db-migration-\${replace(data.external.docker_digest.result.digest, "sha256:", "")}"
|
|
480
435
|
}
|
|
481
436
|
data "external" "create_db_user_docker_digest" {
|
|
482
437
|
program = ["sh", "-c", "echo '{\\"digest\\":\\"'$(docker inspect \${var.create_db_user_docker_image_tag} --format '{{.Id}}')'\\"}' "]
|
|
483
438
|
}
|
|
484
439
|
|
|
485
440
|
locals {
|
|
486
|
-
create_db_user_image_tag = replace(data.external.create_db_user_docker_digest.result.digest, "sha256:", "")
|
|
441
|
+
create_db_user_image_tag = "db-create-db-user-\${replace(data.external.create_db_user_docker_digest.result.digest, "sha256:", "")}"
|
|
487
442
|
}
|
|
488
443
|
|
|
489
444
|
resource "null_resource" "docker_publish" {
|
|
490
445
|
triggers = {
|
|
491
446
|
docker_digest = data.external.docker_digest.result.digest
|
|
492
|
-
repository_url =
|
|
447
|
+
repository_url = var.asset_ecr_repository_url
|
|
493
448
|
migration_docker_image_tag = var.migration_docker_image_tag
|
|
494
449
|
image_tag = local.image_tag
|
|
495
450
|
create_db_user_docker_digest = data.external.create_db_user_docker_digest.result.digest
|
|
@@ -502,8 +457,8 @@ resource "null_resource" "docker_publish" {
|
|
|
502
457
|
aws ecr get-login-password --region "$AWS_REGION" | docker login --username AWS --password-stdin "$REPOSITORY_URL"
|
|
503
458
|
docker tag "$MIGRATION_DOCKER_IMAGE_TAG" "$REPOSITORY_URL:$IMAGE_TAG"
|
|
504
459
|
docker push "$REPOSITORY_URL:$IMAGE_TAG"
|
|
505
|
-
docker tag "$CREATE_DB_USER_DOCKER_IMAGE_TAG" "$REPOSITORY_URL
|
|
506
|
-
docker push "$REPOSITORY_URL
|
|
460
|
+
docker tag "$CREATE_DB_USER_DOCKER_IMAGE_TAG" "$REPOSITORY_URL:$CREATE_DB_USER_IMAGE_TAG"
|
|
461
|
+
docker push "$REPOSITORY_URL:$CREATE_DB_USER_IMAGE_TAG"
|
|
507
462
|
EOT
|
|
508
463
|
environment = {
|
|
509
464
|
AWS_REGION = data.aws_region.current.region
|
|
@@ -514,8 +469,6 @@ resource "null_resource" "docker_publish" {
|
|
|
514
469
|
CREATE_DB_USER_IMAGE_TAG = self.triggers.create_db_user_image_tag
|
|
515
470
|
}
|
|
516
471
|
}
|
|
517
|
-
|
|
518
|
-
depends_on = [aws_ecr_repository_policy.migration_handler]
|
|
519
472
|
}
|
|
520
473
|
|
|
521
474
|
resource "aws_iam_role" "migration_handler" {
|
|
@@ -724,7 +677,7 @@ resource "aws_lambda_function" "create_db_user" {
|
|
|
724
677
|
#checkov:skip=CKV_AWS_173:Lambda environment variables encrypted by managed key
|
|
725
678
|
#checkov:skip=CKV_AWS_272:Code signing not configured as deployment packages are built and deployed within the same pipeline
|
|
726
679
|
package_type = "Image"
|
|
727
|
-
image_uri = "\${
|
|
680
|
+
image_uri = "\${var.asset_ecr_repository_url}:\${local.create_db_user_image_tag}"
|
|
728
681
|
function_name = local.create_db_user_function_name
|
|
729
682
|
role = aws_iam_role.create_db_user.arn
|
|
730
683
|
timeout = 300
|
|
@@ -808,7 +761,7 @@ resource "aws_lambda_function" "migration_handler" {
|
|
|
808
761
|
package_type = "Image"
|
|
809
762
|
function_name = local.migration_function_name
|
|
810
763
|
role = aws_iam_role.migration_handler.arn
|
|
811
|
-
image_uri = "\${
|
|
764
|
+
image_uri = "\${var.asset_ecr_repository_url}:\${local.image_tag}"
|
|
812
765
|
memory_size = 1024
|
|
813
766
|
timeout = 300
|
|
814
767
|
architectures = ["arm64"]
|
|
@@ -1522,11 +1475,11 @@ description = "Automatically generated by Nx."
|
|
|
1522
1475
|
requires-python = ">=3.14"
|
|
1523
1476
|
readme = "README.md"
|
|
1524
1477
|
dependencies = [
|
|
1525
|
-
"sqlmodel==0.0.
|
|
1478
|
+
"sqlmodel==0.0.42",
|
|
1526
1479
|
"alembic==1.19.1",
|
|
1527
1480
|
"greenlet==3.5.5",
|
|
1528
1481
|
"asyncpg==0.31.0",
|
|
1529
|
-
"boto3==1.43.
|
|
1482
|
+
"boto3==1.43.83",
|
|
1530
1483
|
"aws-lambda-powertools==3.34.0"
|
|
1531
1484
|
]
|
|
1532
1485
|
|