@aws/ml-container-creator 0.2.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.
Files changed (143) hide show
  1. package/LICENSE +202 -0
  2. package/LICENSE-THIRD-PARTY +68620 -0
  3. package/NOTICE +2 -0
  4. package/README.md +106 -0
  5. package/bin/cli.js +365 -0
  6. package/config/defaults.json +32 -0
  7. package/config/presets/transformers-djl.json +26 -0
  8. package/config/presets/transformers-gpu.json +24 -0
  9. package/config/presets/transformers-lmi.json +27 -0
  10. package/package.json +129 -0
  11. package/servers/README.md +419 -0
  12. package/servers/base-image-picker/catalogs/model-servers.json +1191 -0
  13. package/servers/base-image-picker/catalogs/python-slim.json +38 -0
  14. package/servers/base-image-picker/catalogs/triton-backends.json +51 -0
  15. package/servers/base-image-picker/catalogs/triton.json +38 -0
  16. package/servers/base-image-picker/index.js +495 -0
  17. package/servers/base-image-picker/manifest.json +17 -0
  18. package/servers/base-image-picker/package.json +15 -0
  19. package/servers/hyperpod-cluster-picker/LICENSE +202 -0
  20. package/servers/hyperpod-cluster-picker/index.js +424 -0
  21. package/servers/hyperpod-cluster-picker/manifest.json +14 -0
  22. package/servers/hyperpod-cluster-picker/package.json +17 -0
  23. package/servers/instance-recommender/LICENSE +202 -0
  24. package/servers/instance-recommender/catalogs/instances.json +852 -0
  25. package/servers/instance-recommender/index.js +284 -0
  26. package/servers/instance-recommender/manifest.json +16 -0
  27. package/servers/instance-recommender/package.json +15 -0
  28. package/servers/lib/LICENSE +202 -0
  29. package/servers/lib/bedrock-client.js +160 -0
  30. package/servers/lib/custom-validators.js +46 -0
  31. package/servers/lib/dynamic-resolver.js +36 -0
  32. package/servers/lib/package.json +11 -0
  33. package/servers/lib/schemas/image-catalog.schema.json +185 -0
  34. package/servers/lib/schemas/instances.schema.json +124 -0
  35. package/servers/lib/schemas/manifest.schema.json +64 -0
  36. package/servers/lib/schemas/model-catalog.schema.json +91 -0
  37. package/servers/lib/schemas/regions.schema.json +26 -0
  38. package/servers/lib/schemas/triton-backends.schema.json +51 -0
  39. package/servers/model-picker/catalogs/jumpstart-public.json +66 -0
  40. package/servers/model-picker/catalogs/popular-diffusors.json +88 -0
  41. package/servers/model-picker/catalogs/popular-transformers.json +226 -0
  42. package/servers/model-picker/index.js +1693 -0
  43. package/servers/model-picker/manifest.json +18 -0
  44. package/servers/model-picker/package.json +20 -0
  45. package/servers/region-picker/LICENSE +202 -0
  46. package/servers/region-picker/catalogs/regions.json +263 -0
  47. package/servers/region-picker/index.js +230 -0
  48. package/servers/region-picker/manifest.json +16 -0
  49. package/servers/region-picker/package.json +15 -0
  50. package/src/app.js +1007 -0
  51. package/src/copy-tpl.js +77 -0
  52. package/src/lib/accelerator-validator.js +39 -0
  53. package/src/lib/asset-manager.js +385 -0
  54. package/src/lib/aws-profile-parser.js +181 -0
  55. package/src/lib/bootstrap-command-handler.js +1647 -0
  56. package/src/lib/bootstrap-config.js +238 -0
  57. package/src/lib/ci-register-helpers.js +124 -0
  58. package/src/lib/ci-report-helpers.js +158 -0
  59. package/src/lib/ci-stage-helpers.js +268 -0
  60. package/src/lib/cli-handler.js +529 -0
  61. package/src/lib/comment-generator.js +544 -0
  62. package/src/lib/community-reports-validator.js +91 -0
  63. package/src/lib/config-manager.js +2106 -0
  64. package/src/lib/configuration-exporter.js +204 -0
  65. package/src/lib/configuration-manager.js +695 -0
  66. package/src/lib/configuration-matcher.js +221 -0
  67. package/src/lib/cpu-validator.js +36 -0
  68. package/src/lib/cuda-validator.js +57 -0
  69. package/src/lib/deployment-config-resolver.js +103 -0
  70. package/src/lib/deployment-entry-schema.js +125 -0
  71. package/src/lib/deployment-registry.js +598 -0
  72. package/src/lib/docker-introspection-validator.js +51 -0
  73. package/src/lib/engine-prefix-resolver.js +60 -0
  74. package/src/lib/huggingface-client.js +172 -0
  75. package/src/lib/key-value-parser.js +37 -0
  76. package/src/lib/known-flags-validator.js +200 -0
  77. package/src/lib/manifest-cli.js +280 -0
  78. package/src/lib/mcp-client.js +303 -0
  79. package/src/lib/mcp-command-handler.js +532 -0
  80. package/src/lib/neuron-validator.js +80 -0
  81. package/src/lib/parameter-schema-validator.js +284 -0
  82. package/src/lib/prompt-runner.js +1349 -0
  83. package/src/lib/prompts.js +1138 -0
  84. package/src/lib/registry-command-handler.js +519 -0
  85. package/src/lib/registry-loader.js +198 -0
  86. package/src/lib/rocm-validator.js +80 -0
  87. package/src/lib/schema-validator.js +157 -0
  88. package/src/lib/sensitive-redactor.js +59 -0
  89. package/src/lib/template-engine.js +156 -0
  90. package/src/lib/template-manager.js +341 -0
  91. package/src/lib/validation-engine.js +314 -0
  92. package/src/prompt-adapter.js +63 -0
  93. package/templates/Dockerfile +300 -0
  94. package/templates/IAM_PERMISSIONS.md +84 -0
  95. package/templates/MIGRATION.md +488 -0
  96. package/templates/PROJECT_README.md +439 -0
  97. package/templates/TEMPLATE_SYSTEM.md +243 -0
  98. package/templates/buildspec.yml +64 -0
  99. package/templates/code/chat_template.jinja +1 -0
  100. package/templates/code/flask/gunicorn_config.py +35 -0
  101. package/templates/code/flask/wsgi.py +10 -0
  102. package/templates/code/model_handler.py +387 -0
  103. package/templates/code/serve +300 -0
  104. package/templates/code/serve.py +175 -0
  105. package/templates/code/serving.properties +105 -0
  106. package/templates/code/start_server.py +39 -0
  107. package/templates/code/start_server.sh +39 -0
  108. package/templates/diffusors/Dockerfile +72 -0
  109. package/templates/diffusors/patch_image_api.py +35 -0
  110. package/templates/diffusors/serve +115 -0
  111. package/templates/diffusors/start_server.sh +114 -0
  112. package/templates/do/.gitkeep +1 -0
  113. package/templates/do/README.md +541 -0
  114. package/templates/do/build +83 -0
  115. package/templates/do/ci +681 -0
  116. package/templates/do/clean +811 -0
  117. package/templates/do/config +260 -0
  118. package/templates/do/deploy +1560 -0
  119. package/templates/do/export +306 -0
  120. package/templates/do/logs +319 -0
  121. package/templates/do/manifest +12 -0
  122. package/templates/do/push +119 -0
  123. package/templates/do/register +580 -0
  124. package/templates/do/run +113 -0
  125. package/templates/do/submit +417 -0
  126. package/templates/do/test +1147 -0
  127. package/templates/hyperpod/configmap.yaml +24 -0
  128. package/templates/hyperpod/deployment.yaml +71 -0
  129. package/templates/hyperpod/pvc.yaml +42 -0
  130. package/templates/hyperpod/service.yaml +17 -0
  131. package/templates/nginx-diffusors.conf +74 -0
  132. package/templates/nginx-predictors.conf +47 -0
  133. package/templates/nginx-tensorrt.conf +74 -0
  134. package/templates/requirements.txt +61 -0
  135. package/templates/sample_model/test_inference.py +123 -0
  136. package/templates/sample_model/train_abalone.py +252 -0
  137. package/templates/test/test_endpoint.sh +79 -0
  138. package/templates/test/test_local_image.sh +80 -0
  139. package/templates/test/test_model_handler.py +180 -0
  140. package/templates/triton/Dockerfile +128 -0
  141. package/templates/triton/config.pbtxt +163 -0
  142. package/templates/triton/model.py +130 -0
  143. package/templates/triton/requirements.txt +11 -0
package/package.json ADDED
@@ -0,0 +1,129 @@
1
+ {
2
+ "name": "@aws/ml-container-creator",
3
+ "version": "0.2.0",
4
+ "description": "Generator for SageMaker AI BYOC paradigm for predictive inference use-cases.",
5
+ "type": "module",
6
+ "main": "src/app.js",
7
+ "bin": {
8
+ "ml-container-creator": "bin/cli.js"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "prepublishOnly": "npm run lint:fix && npm run test:ci",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/awslabs/ml-container-creator.git"
17
+ },
18
+ "files": [
19
+ "bin/",
20
+ "src/",
21
+ "templates/",
22
+ "servers/base-image-picker/catalogs/",
23
+ "servers/base-image-picker/index.js",
24
+ "servers/base-image-picker/manifest.json",
25
+ "servers/base-image-picker/package.json",
26
+ "servers/instance-recommender/catalogs/",
27
+ "servers/instance-recommender/index.js",
28
+ "servers/instance-recommender/manifest.json",
29
+ "servers/instance-recommender/package.json",
30
+ "servers/model-picker/catalogs/",
31
+ "servers/model-picker/index.js",
32
+ "servers/model-picker/manifest.json",
33
+ "servers/model-picker/package.json",
34
+ "servers/region-picker/catalogs/",
35
+ "servers/region-picker/index.js",
36
+ "servers/region-picker/manifest.json",
37
+ "servers/region-picker/package.json",
38
+ "servers/hyperpod-cluster-picker/index.js",
39
+ "servers/hyperpod-cluster-picker/manifest.json",
40
+ "servers/hyperpod-cluster-picker/package.json",
41
+ "servers/lib/bedrock-client.js",
42
+ "servers/lib/custom-validators.js",
43
+ "servers/lib/dynamic-resolver.js",
44
+ "servers/lib/schemas/",
45
+ "servers/lib/package.json",
46
+ "servers/README.md",
47
+ "config/defaults.json",
48
+ "config/presets/",
49
+ "README.md",
50
+ "LICENSE",
51
+ "LICENSE-THIRD-PARTY",
52
+ "NOTICE"
53
+ ],
54
+ "keywords": [
55
+ "cli",
56
+ "standalone",
57
+ "sagemaker",
58
+ "byoc",
59
+ "aws",
60
+ "machine-learning",
61
+ "docker"
62
+ ],
63
+ "scripts": {
64
+ "test": "VALIDATE_ENV_VARS=false mocha test/**/*.test.js --exit --reporter test/reporters/progress-reporter.cjs",
65
+ "test:ci": "VALIDATE_ENV_VARS=false mocha test/**/*.test.js --exit --reporter spec",
66
+ "test:verbose": "VALIDATE_ENV_VARS=false mocha test/**/*.test.js --exit --reporter spec",
67
+ "test:minimal": "VALIDATE_ENV_VARS=false mocha test/**/*.test.js --reporter test/reporters/minimal-reporter.cjs",
68
+ "test:watch": "VALIDATE_ENV_VARS=false mocha test/**/*.test.js --watch --reporter test/reporters/progress-reporter.cjs",
69
+ "test:coverage": "VALIDATE_ENV_VARS=false nyc mocha test/**/*.test.js",
70
+ "test:unit": "VALIDATE_ENV_VARS=false mocha test/unit/**/*.test.js test/helpers/**/*.test.js --reporter spec",
71
+ "test:integration": "VALIDATE_ENV_VARS=false mocha test/input-parsing-and-generation/**/*.test.js --reporter spec",
72
+ "test:property": "VALIDATE_ENV_VARS=false mocha test/property/**/*.test.js --reporter spec",
73
+ "test:all": "npm run test:ci",
74
+ "test:servers": "for dir in servers/*/; do if [ -f \"$dir/package.json\" ] && node -e \"const p=JSON.parse(require('fs').readFileSync('${dir}package.json','utf8')); process.exit(p.scripts&&p.scripts.test?0:1)\"; then echo \"\\n🧪 Testing $dir\" && (cd \"$dir\" && npm test) || exit 1; fi; done",
75
+ "test:perf": "VALIDATE_ENV_VARS=false mocha test/**/*.test.js --reporter json > test-results.json && node scripts/analyze-test-performance.js",
76
+ "security-audit": "npm audit --audit-level=high",
77
+ "security-fix": "npm audit fix",
78
+ "lint": "eslint generators/**/*.js test/**/*.js",
79
+ "lint:fix": "eslint generators/**/*.js test/**/*.js --fix",
80
+ "start": "ml-container-creator",
81
+ "dev": "npm link && ml-container-creator",
82
+ "clean": "rm -rf test-output-*",
83
+ "validate": "npm run lint && npm run test:all",
84
+ "validate:namespaces": "node scripts/validate-namespaces.js",
85
+ "docs:serve": "mkdocs serve",
86
+ "docs:build": "mkdocs build",
87
+ "docs:deploy": "mkdocs gh-deploy",
88
+ "_sbom": "npm sbom --sbom-format spdx > sbom.json && for dir in servers/*/; do [ -f \"$dir/package.json\" ] && (cd \"$dir\" && npm sbom --sbom-format spdx > sbom.json); done",
89
+ "_licenses:review": "license-checker --production --exclude MIT,Apache-2.0,BSD-2-Clause,BSD-3-Clause,ISC,0BSD && for dir in servers/*/; do [ -f \"$dir/package.json\" ] && echo \"\\nChecking $dir\" && (cd \"$dir\" && npx license-checker --production --exclude MIT,Apache-2.0,BSD-2-Clause,BSD-3-Clause,ISC,0BSD); done",
90
+ "_licenses:csv": "license-checker --csv --out ./licenses.csv && for dir in servers/*/; do [ -f \"$dir/package.json\" ] && (cd \"$dir\" && npx license-checker --csv --out licenses.csv); done && cat servers/*/licenses.csv >> licenses.csv",
91
+ "_licenses:attribution": "generate-attribution && mv oss-attribution/attribution.txt LICENSE-THIRD-PARTY && rm -rf oss-attribution && for dir in servers/*/; do [ -f \"$dir/package.json\" ] && (cd \"$dir\" && generate-attribution && cat oss-attribution/attribution.txt >> ../../LICENSE-THIRD-PARTY && rm -rf oss-attribution); done"
92
+ },
93
+ "dependencies": {
94
+ "@inquirer/prompts": "^8.4.2",
95
+ "@microsoft/eslint-formatter-sarif": "^3.1.0",
96
+ "@modelcontextprotocol/sdk": "^1.27.1",
97
+ "ajv": "^8.12.0",
98
+ "cli-table3": "^0.6.5",
99
+ "commander": "13.1.0",
100
+ "ejs": "^3.1.10",
101
+ "license-report": "^6.8.0",
102
+ "lodash": "^4.17.21",
103
+ "minimatch": "^10.2.4",
104
+ "sbom": "^0.0.0",
105
+ "tinyglobby": "^0.2.16"
106
+ },
107
+ "devDependencies": {
108
+ "eslint": "^8.57.0",
109
+ "fast-check": "^4.5.2",
110
+ "mocha": "^10.2.0",
111
+ "npm-force-resolutions": "^0.0.10",
112
+ "nyc": "^15.1.0"
113
+ },
114
+ "engines": {
115
+ "node": ">=24.11.1",
116
+ "npm": ">=11.6.2"
117
+ },
118
+ "overrides": {
119
+ "cross-spawn": "^7.0.3",
120
+ "diff": "^5.2.2",
121
+ "lodash": "^4.17.21",
122
+ "semver": "^7.5.4",
123
+ "got": "^11.8.5",
124
+ "qs": "^6.14.1",
125
+ "serialize-javascript": "^7.0.5"
126
+ },
127
+ "author": "Dan Ferguson",
128
+ "license": "Apache-2.0"
129
+ }
@@ -0,0 +1,419 @@
1
+ # Bundled MCP Servers
2
+
3
+ This directory contains first-party MCP (Model Context Protocol) servers that ship with ML Container Creator. Each server is self-contained with its own `package.json` and dependencies, and shares a common Bedrock client library under `lib/`.
4
+
5
+ ## Directory Structure
6
+
7
+ ```
8
+ servers/
9
+ ├── lib/ # Shared library (Bedrock client)
10
+ │ ├── bedrock-client.js # Reusable Bedrock invocation module
11
+ │ ├── package.json # @aws-sdk/client-bedrock-runtime dependency
12
+ │ └── LICENSE
13
+ ├── instance-recommender/ # Instance type recommendation server
14
+ │ ├── index.js # MCP server entry point
15
+ │ ├── test.js # Standalone tests (node test.js)
16
+ │ ├── package.json
17
+ │ └── LICENSE
18
+ └── region-picker/ # AWS region suggestion server
19
+ ├── index.js # MCP server entry point
20
+ ├── test.js # Standalone tests (node test.js)
21
+ ├── package.json
22
+ └── LICENSE
23
+ ```
24
+
25
+ ## Available Servers
26
+
27
+ ### instance-recommender
28
+
29
+ Recommends SageMaker instance types based on the current ML framework. Traditional ML frameworks (sklearn, xgboost, tensorflow) get CPU instance suggestions; transformer frameworks get GPU instances.
30
+
31
+ **Static mode (default):** Returns hardcoded instance lists by framework category — no AWS credentials needed.
32
+
33
+ **Smart mode (`BEDROCK_SMART=true`):** Queries Amazon Bedrock for context-aware instance recommendations, then pads with static results up to the requested limit. Falls back to static on any failure.
34
+
35
+ **Tool:** `get_ml_config`
36
+
37
+ | Input Field | Type | Description |
38
+ |-------------|------|-------------|
39
+ | `parameters` | `string[]` | Must include `"instanceType"` to get results |
40
+ | `limit` | `number` | Max choices to return (default: 10) |
41
+ | `context` | `object` | Current config — `framework`, `modelServer`, etc. |
42
+
43
+ **Example response:**
44
+
45
+ ```json
46
+ {
47
+ "values": { "instanceType": "ml.g5.xlarge" },
48
+ "choices": { "instanceType": ["ml.g5.xlarge", "ml.g5.2xlarge", "ml.g4dn.xlarge"] }
49
+ }
50
+ ```
51
+
52
+ ### region-picker
53
+
54
+ Suggests AWS regions for SageMaker deployments based on a search term. Filters the built-in list of 22 SageMaker-available regions by case-insensitive substring match against both region codes and labels.
55
+
56
+ **Static mode (default):** Filters the hardcoded region list — no AWS credentials needed.
57
+
58
+ **Smart mode (`BEDROCK_SMART=true`):** Queries Amazon Bedrock for a context-aware region recommendation, uses it as the top choice, and pads with static results. Falls back to static on any failure.
59
+
60
+ **Tool:** `get_ml_config`
61
+
62
+ | Input Field | Type | Description |
63
+ |-------------|------|-------------|
64
+ | `parameters` | `string[]` | Must include `"awsRegion"` to get results |
65
+ | `limit` | `number` | Max choices to return (default: 10) |
66
+ | `context` | `object` | Use `regionSearch` for filtering (e.g., `"europe"`, `"us-east"`, `"tokyo"`) |
67
+
68
+ **Example response:**
69
+
70
+ ```json
71
+ {
72
+ "values": { "awsRegion": "eu-west-1" },
73
+ "choices": { "awsRegion": ["eu-west-1", "eu-west-2", "eu-west-3", "eu-central-1"] }
74
+ }
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ ### Adding a Bundled Server
80
+
81
+ ```bash
82
+ # Add instance-recommender
83
+ ml-container-creator mcp add instance-recommender --bundled
84
+
85
+ # Add region-picker with a search filter for European regions
86
+ ml-container-creator mcp add region-picker --bundled -e REGION_SEARCH=europe
87
+ ```
88
+
89
+ Dependencies are installed automatically on first use.
90
+
91
+ ### Listing Bundled Servers
92
+
93
+ ```bash
94
+ ml-container-creator mcp list --bundled
95
+ ```
96
+
97
+ ### Enabling Smart Mode
98
+
99
+ Pass `BEDROCK_SMART=true` as an environment variable when adding the server:
100
+
101
+ ```bash
102
+ ml-container-creator mcp add instance-recommender --bundled -e BEDROCK_SMART=true
103
+ ml-container-creator mcp add region-picker --bundled -e BEDROCK_SMART=true
104
+ ```
105
+
106
+ ## Environment Variables
107
+
108
+ Both servers share the same environment variable interface:
109
+
110
+ | Variable | Default | Description |
111
+ |----------|---------|-------------|
112
+ | `BEDROCK_SMART` | `false` | Set to `"true"` to enable Bedrock-powered recommendations |
113
+ | `BEDROCK_MODEL` | `global.anthropic.claude-sonnet-4-20250514-v1:0` | Bedrock model ID |
114
+ | `BEDROCK_REGION` | Falls back: `AWS_REGION` → `us-east-1` | AWS region for Bedrock API calls |
115
+
116
+
117
+ ## Authenticating with Amazon Bedrock
118
+
119
+ Smart mode requires valid AWS credentials and access to the configured Bedrock model. The servers use the standard AWS SDK credential chain, so any of these approaches work:
120
+
121
+ ### Option 1: Environment Variables
122
+
123
+ ```bash
124
+ export AWS_ACCESS_KEY_ID=AKIA...
125
+ export AWS_SECRET_ACCESS_KEY=...
126
+ export AWS_SESSION_TOKEN=... # if using temporary credentials
127
+ export BEDROCK_REGION=us-east-1
128
+ ```
129
+
130
+ ### Option 2: AWS CLI Profile
131
+
132
+ ```bash
133
+ aws configure # set up a default profile
134
+ # or
135
+ export AWS_PROFILE=my-profile # use a named profile
136
+ ```
137
+
138
+ ### Option 3: IAM Role (EC2, ECS, Lambda, etc.)
139
+
140
+ If running on AWS infrastructure, the instance/task role is picked up automatically. No extra configuration needed.
141
+
142
+ ### Required IAM Permission
143
+
144
+ The calling identity needs `bedrock:InvokeModel` on the inference profile:
145
+
146
+ ```json
147
+ {
148
+ "Effect": "Allow",
149
+ "Action": "bedrock:InvokeModel",
150
+ "Resource": "arn:aws:bedrock:*:*:inference-profile/global.anthropic.claude-sonnet-4-20250514-v1:0"
151
+ }
152
+ ```
153
+
154
+ The default model (`global.anthropic.claude-sonnet-4-20250514-v1:0`) uses a cross-region inference profile that routes to the nearest available region. If you override `BEDROCK_MODEL` with a region-specific model, adjust the resource ARN accordingly.
155
+
156
+ ### Enabling Model Access
157
+
158
+ Bedrock models must be explicitly enabled in your AWS account:
159
+
160
+ 1. Open the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/)
161
+ 2. Go to **Model access** in the left nav
162
+ 3. Request access to the Anthropic Claude models
163
+ 4. Wait for the status to show "Access granted"
164
+
165
+ ## How Servers Impact the Generator Flow
166
+
167
+ When you run `ml-container-creator`, the generator queries any configured MCP servers during the configuration loading phase. Here's how the bundled servers influence the flow:
168
+
169
+ ### Without MCP Servers
170
+
171
+ ```
172
+ $ ml-container-creator
173
+
174
+ ? AWS Region: (use arrow keys or type to search)
175
+ ❯ us-east-1
176
+ us-east-2
177
+ us-west-1
178
+ us-west-2
179
+ ... (all regions, alphabetical)
180
+
181
+ ? Instance type: (enter manually)
182
+ ml.m5.xlarge
183
+ ```
184
+
185
+ The user sees a generic list of regions and must know which instance type to pick.
186
+
187
+ ### With instance-recommender (Static Mode)
188
+
189
+ ```bash
190
+ ml-container-creator mcp add instance-recommender --bundled
191
+ ml-container-creator
192
+ ```
193
+
194
+ ```
195
+ ? Framework: transformers
196
+ ? Instance type: (use arrow keys)
197
+ ❯ ml.g4dn.xlarge # GPU instances suggested because framework=transformers
198
+ ml.g4dn.2xlarge
199
+ ml.g5.xlarge
200
+ ml.g5.2xlarge
201
+ Custom (enter manually)
202
+ ```
203
+
204
+ The server detects the transformer framework from context and suggests GPU instances instead of CPU ones.
205
+
206
+ ### With region-picker (Static Mode)
207
+
208
+ ```bash
209
+ ml-container-creator mcp add region-picker --bundled -e REGION_SEARCH=europe
210
+ ml-container-creator
211
+ ```
212
+
213
+ ```
214
+ ? AWS Region: (use arrow keys)
215
+ ❯ eu-west-1 # Filtered to European regions only
216
+ eu-west-2
217
+ eu-west-3
218
+ eu-central-1
219
+ eu-central-2
220
+ eu-north-1
221
+ eu-south-1
222
+ Custom (enter manually)
223
+ ```
224
+
225
+ The search term `"europe"` filters the region list to only show European regions.
226
+
227
+ ### With Smart Mode (Bedrock)
228
+
229
+ ```bash
230
+ ml-container-creator mcp add instance-recommender --bundled -e BEDROCK_SMART=true
231
+ ml-container-creator mcp add region-picker --bundled -e BEDROCK_SMART=true
232
+ ml-container-creator
233
+ ```
234
+
235
+ ```
236
+ ? Framework: transformers
237
+ ? Model: meta-llama/Llama-3.1-8B
238
+
239
+ ? Instance type: (use arrow keys)
240
+ ❯ ml.g5.2xlarge # Bedrock recommended based on Llama 3.1 8B + transformers
241
+ ml.g5.xlarge
242
+ ml.g4dn.xlarge
243
+ ml.g4dn.2xlarge
244
+ Custom (enter manually)
245
+
246
+ ? AWS Region: (use arrow keys)
247
+ ❯ us-west-2 # Bedrock recommended based on model availability + pricing
248
+ us-east-1
249
+ us-east-2
250
+ Custom (enter manually)
251
+ ```
252
+
253
+ Bedrock considers the full configuration context (framework, model, model server) to make informed recommendations. The LLM-suggested value appears first, padded with static results.
254
+
255
+ ## Troubleshooting
256
+
257
+ ### "Failed to load @aws-sdk/client-bedrock-runtime"
258
+
259
+ The Bedrock SDK isn't installed. Run:
260
+
261
+ ```bash
262
+ cd servers/lib
263
+ npm install
264
+ ```
265
+
266
+ This only affects smart mode. Static mode works without the SDK.
267
+
268
+ ### "Access denied. Ensure bedrock:InvokeModel permission"
269
+
270
+ Your AWS credentials don't have permission to call Bedrock. Either:
271
+ - Add the `bedrock:InvokeModel` permission to your IAM user/role (see the IAM section above)
272
+ - Or check that your credentials are configured correctly (`aws sts get-caller-identity`)
273
+
274
+ ### "Model not found"
275
+
276
+ The configured model ID isn't available in your account or region. Either:
277
+ - Enable model access in the Bedrock console (see "Enabling Model Access" above)
278
+ - Override with a model you have access to: `BEDROCK_MODEL=us.anthropic.claude-sonnet-4-20250514-v1:0`
279
+
280
+ ### "Bedrock rate limit hit"
281
+
282
+ You're sending too many requests. The server automatically falls back to static mode. If this happens frequently, consider:
283
+ - Using static mode for development
284
+ - Requesting a quota increase in the AWS console
285
+
286
+ ### "Bedrock request timed out"
287
+
288
+ The Bedrock API didn't respond within 10 seconds. This usually means network connectivity issues. The server falls back to static mode automatically.
289
+
290
+ ### Server Not Returning Results
291
+
292
+ 1. Check the server is registered: `ml-container-creator mcp list`
293
+ 2. Check stderr output — all diagnostic messages go to stderr
294
+ 3. Verify the tool is being called with the right parameters (e.g., `"awsRegion"` for region-picker, `"instanceType"` for instance-recommender)
295
+ 4. Try running the standalone tests to verify the server logic:
296
+
297
+ ```bash
298
+ node servers/region-picker/test.js
299
+ node servers/instance-recommender/test.js
300
+ ```
301
+
302
+ ### Smart Mode Not Activating
303
+
304
+ Smart mode only activates when `BEDROCK_SMART` is exactly `"true"`. Check:
305
+ - The env var is set in the server config: `ml-container-creator mcp get <server-name>`
306
+ - It's not `"True"`, `"TRUE"`, or `"1"` — only `"true"` works
307
+
308
+ ## Testing
309
+
310
+ Each server has standalone tests that run without AWS credentials or network access:
311
+
312
+ ```bash
313
+ # Run individual server tests
314
+ node servers/region-picker/test.js
315
+ node servers/instance-recommender/test.js
316
+
317
+ # Run all server tests from the project root
318
+ npm run test:servers
319
+ ```
320
+
321
+ Property-based tests for correctness properties are in the main test suite:
322
+
323
+ ```bash
324
+ npm test
325
+ ```
326
+
327
+ ## Creating a Custom MCP Server
328
+
329
+ Any process that speaks the MCP protocol over stdio can serve as a configuration provider. Your server needs to:
330
+
331
+ 1. Handle the MCP initialize handshake
332
+ 2. Register a tool (default name: `get_ml_config`)
333
+ 3. Accept `{ parameters, limit, context }` as tool input
334
+ 4. Return `{ values, choices }` as a JSON text response
335
+
336
+ ### Tool Interface
337
+
338
+ Your tool receives:
339
+
340
+ ```json
341
+ {
342
+ "parameters": ["instanceType", "awsRoleArn", "awsRegion"],
343
+ "limit": 10,
344
+ "context": {
345
+ "framework": "sklearn",
346
+ "modelServer": "flask"
347
+ }
348
+ }
349
+ ```
350
+
351
+ Your tool returns (as a text content block containing JSON):
352
+
353
+ ```json
354
+ {
355
+ "values": {
356
+ "instanceType": "ml.m5.xlarge"
357
+ },
358
+ "choices": {
359
+ "instanceType": ["ml.m5.xlarge", "ml.m5.2xlarge", "ml.g4dn.xlarge"]
360
+ }
361
+ }
362
+ ```
363
+
364
+ - `values` — recommended default value per parameter (merged into config)
365
+ - `choices` — list of valid options per parameter (shown during prompting)
366
+
367
+ Both fields are optional. A server may return only values, only choices, or both.
368
+
369
+ ### Minimal Example
370
+
371
+ ```javascript
372
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
373
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
374
+ import { z } from 'zod'
375
+
376
+ const server = new McpServer({ name: 'my-config-server', version: '1.0.0' })
377
+
378
+ server.tool(
379
+ 'get_ml_config',
380
+ 'Returns ML configuration values',
381
+ {
382
+ parameters: z.array(z.string()),
383
+ limit: z.number().int().positive().default(10),
384
+ context: z.record(z.string(), z.any()).optional()
385
+ },
386
+ async ({ parameters, limit, context }) => {
387
+ const values = {}
388
+ const choices = {}
389
+
390
+ // Your logic here
391
+
392
+ return {
393
+ content: [{ type: 'text', text: JSON.stringify({ values, choices }) }]
394
+ }
395
+ }
396
+ )
397
+
398
+ const transport = new StdioServerTransport()
399
+ await server.connect(transport)
400
+ ```
401
+
402
+ Register it:
403
+
404
+ ```bash
405
+ ml-container-creator mcp add my-server -- node path/to/my-server.js
406
+ ```
407
+
408
+ ## License Compliance
409
+
410
+ All bundled servers and their dependencies must use only approved licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, 0BSD.
411
+
412
+ When adding or updating a bundled server, run the compliance scripts before committing:
413
+
414
+ ```bash
415
+ npm run _sbom
416
+ npm run _licenses:review
417
+ npm run _licenses:csv
418
+ npm run _licenses:attribution
419
+ ```