mcpmake 0.1.1 → 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.
- package/dist/commands/bundle.d.ts +1 -0
- package/dist/commands/bundle.d.ts.map +1 -0
- package/dist/commands/bundle.js +5 -4
- package/dist/commands/bundle.js.map +1 -0
- package/dist/commands/ci.d.ts +1 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +3 -2
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +4 -3
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/diff.d.ts +1 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +5 -4
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/from/describe.d.ts +1 -0
- package/dist/commands/from/describe.d.ts.map +1 -0
- package/dist/commands/from/describe.js +11 -10
- package/dist/commands/from/describe.js.map +1 -0
- package/dist/commands/from/har.d.ts +1 -0
- package/dist/commands/from/har.d.ts.map +1 -0
- package/dist/commands/from/har.js +14 -13
- package/dist/commands/from/har.js.map +1 -0
- package/dist/commands/from/openapi.d.ts +1 -0
- package/dist/commands/from/openapi.d.ts.map +1 -0
- package/dist/commands/from/openapi.js +17 -16
- package/dist/commands/from/openapi.js.map +1 -0
- package/dist/commands/from/postman.d.ts +1 -0
- package/dist/commands/from/postman.d.ts.map +1 -0
- package/dist/commands/from/postman.js +13 -12
- package/dist/commands/from/postman.js.map +1 -0
- package/dist/commands/from/stainless.d.ts +110 -0
- package/dist/commands/from/stainless.d.ts.map +1 -0
- package/dist/commands/from/stainless.js +272 -0
- package/dist/commands/from/stainless.js.map +1 -0
- package/dist/commands/from/target-support.d.ts +1 -0
- package/dist/commands/from/target-support.d.ts.map +1 -0
- package/dist/commands/from/target-support.js +2 -1
- package/dist/commands/from/target-support.js.map +1 -0
- package/dist/commands/from/url.d.ts +1 -0
- package/dist/commands/from/url.d.ts.map +1 -0
- package/dist/commands/from/url.js +14 -13
- package/dist/commands/from/url.js.map +1 -0
- package/dist/commands/from/website.d.ts +1 -0
- package/dist/commands/from/website.d.ts.map +1 -0
- package/dist/commands/from/website.js +17 -16
- package/dist/commands/from/website.js.map +1 -0
- package/dist/commands/lint.d.ts +1 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +6 -5
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/merge.d.ts +1 -0
- package/dist/commands/merge.d.ts.map +1 -0
- package/dist/commands/merge.js +3 -2
- package/dist/commands/merge.js.map +1 -0
- package/dist/commands/publish.d.ts +1 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +4 -3
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/rescan.d.ts +1 -0
- package/dist/commands/rescan.d.ts.map +1 -0
- package/dist/commands/rescan.js +12 -11
- package/dist/commands/rescan.js.map +1 -0
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +10 -9
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +1 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +7 -6
- package/dist/commands/verify.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -0
- package/dist/registry/official-registry.d.ts +1 -0
- package/dist/registry/official-registry.d.ts.map +1 -0
- package/dist/registry/official-registry.js +1 -0
- package/dist/registry/official-registry.js.map +1 -0
- package/package.json +20 -46
- package/README.md +0 -691
- package/dist/analyzer/auth-detector.d.ts +0 -12
- package/dist/analyzer/auth-detector.js +0 -142
- package/dist/analyzer/dom-parser.d.ts +0 -10
- package/dist/analyzer/dom-parser.js +0 -259
- package/dist/analyzer/goal-crawler.d.ts +0 -25
- package/dist/analyzer/goal-crawler.js +0 -177
- package/dist/analyzer/hybrid-detector.d.ts +0 -28
- package/dist/analyzer/hybrid-detector.js +0 -96
- package/dist/analyzer/index.d.ts +0 -12
- package/dist/analyzer/index.js +0 -8
- package/dist/analyzer/screenshot-capture.d.ts +0 -29
- package/dist/analyzer/screenshot-capture.js +0 -42
- package/dist/analyzer/selector-builder.d.ts +0 -19
- package/dist/analyzer/selector-builder.js +0 -199
- package/dist/analyzer/semantic-analyzer.d.ts +0 -13
- package/dist/analyzer/semantic-analyzer.js +0 -145
- package/dist/analyzer/site-crawler.d.ts +0 -38
- package/dist/analyzer/site-crawler.js +0 -235
- package/dist/cloud/billing/billing-engine.d.ts +0 -44
- package/dist/cloud/billing/billing-engine.js +0 -81
- package/dist/cloud/billing/credit-store.d.ts +0 -64
- package/dist/cloud/billing/credit-store.js +0 -168
- package/dist/cloud/billing/index.d.ts +0 -4
- package/dist/cloud/billing/index.js +0 -2
- package/dist/cloud/billing/usage-store.d.ts +0 -42
- package/dist/cloud/billing/usage-store.js +0 -85
- package/dist/cloud/billing/usage-tracker.d.ts +0 -38
- package/dist/cloud/billing/usage-tracker.js +0 -95
- package/dist/cloud/build-pipeline.d.ts +0 -39
- package/dist/cloud/build-pipeline.js +0 -310
- package/dist/cloud/build-queue.d.ts +0 -30
- package/dist/cloud/build-queue.js +0 -70
- package/dist/cloud/caddy-manager.d.ts +0 -18
- package/dist/cloud/caddy-manager.js +0 -97
- package/dist/cloud/container-backend.d.ts +0 -62
- package/dist/cloud/container-backend.js +0 -59
- package/dist/cloud/container-manager.d.ts +0 -64
- package/dist/cloud/container-manager.js +0 -301
- package/dist/cloud/crypto.d.ts +0 -27
- package/dist/cloud/crypto.js +0 -63
- package/dist/cloud/db/index.d.ts +0 -27
- package/dist/cloud/db/index.js +0 -53
- package/dist/cloud/db/migrations.d.ts +0 -12
- package/dist/cloud/db/migrations.js +0 -329
- package/dist/cloud/db/pg-store.d.ts +0 -45
- package/dist/cloud/db/pg-store.js +0 -336
- package/dist/cloud/failure-tracker.d.ts +0 -51
- package/dist/cloud/failure-tracker.js +0 -102
- package/dist/cloud/idle-monitor.d.ts +0 -30
- package/dist/cloud/idle-monitor.js +0 -70
- package/dist/cloud/mailer.d.ts +0 -21
- package/dist/cloud/mailer.js +0 -193
- package/dist/cloud/mcp-proxy.d.ts +0 -58
- package/dist/cloud/mcp-proxy.js +0 -203
- package/dist/cloud/metric-samples.d.ts +0 -43
- package/dist/cloud/metric-samples.js +0 -85
- package/dist/cloud/metrics.d.ts +0 -26
- package/dist/cloud/metrics.js +0 -59
- package/dist/cloud/multipart.d.ts +0 -26
- package/dist/cloud/multipart.js +0 -132
- package/dist/cloud/observability.d.ts +0 -27
- package/dist/cloud/observability.js +0 -98
- package/dist/cloud/rate-limiter.d.ts +0 -31
- package/dist/cloud/rate-limiter.js +0 -58
- package/dist/cloud/request-security.d.ts +0 -5
- package/dist/cloud/request-security.js +0 -74
- package/dist/cloud/resource-monitor.d.ts +0 -69
- package/dist/cloud/resource-monitor.js +0 -130
- package/dist/cloud/secret-store.d.ts +0 -38
- package/dist/cloud/secret-store.js +0 -103
- package/dist/cloud/security.d.ts +0 -26
- package/dist/cloud/security.js +0 -142
- package/dist/cloud/server.d.ts +0 -21
- package/dist/cloud/server.js +0 -1079
- package/dist/cloud/shared-state.d.ts +0 -72
- package/dist/cloud/shared-state.js +0 -159
- package/dist/cloud/ssrf.d.ts +0 -43
- package/dist/cloud/ssrf.js +0 -150
- package/dist/cloud/store.d.ts +0 -41
- package/dist/cloud/store.js +0 -75
- package/dist/cloud/stripe.d.ts +0 -78
- package/dist/cloud/stripe.js +0 -317
- package/dist/cloud/telemetry-store.d.ts +0 -53
- package/dist/cloud/telemetry-store.js +0 -108
- package/dist/cloud/web/auth.d.ts +0 -225
- package/dist/cloud/web/auth.js +0 -555
- package/dist/cloud/web/charts.d.ts +0 -70
- package/dist/cloud/web/charts.js +0 -178
- package/dist/cloud/web/csrf.d.ts +0 -14
- package/dist/cloud/web/csrf.js +0 -22
- package/dist/cloud/web/docs.d.ts +0 -40
- package/dist/cloud/web/docs.js +0 -174
- package/dist/cloud/web/router.d.ts +0 -25
- package/dist/cloud/web/router.js +0 -1921
- package/dist/cloud/web/static/alpine.min.js +0 -5
- package/dist/cloud/web/static/favicon.svg +0 -4
- package/dist/cloud/web/static/htmx-sse.js +0 -290
- package/dist/cloud/web/static/htmx.min.js +0 -1
- package/dist/cloud/web/static/style.css +0 -2683
- package/dist/cloud/web/static-server.d.ts +0 -13
- package/dist/cloud/web/static-server.js +0 -73
- package/dist/cloud/web/template-engine.d.ts +0 -27
- package/dist/cloud/web/template-engine.js +0 -146
- package/dist/cloud/web/templates/layouts/admin.hbs +0 -57
- package/dist/cloud/web/templates/layouts/auth.hbs +0 -138
- package/dist/cloud/web/templates/layouts/base.hbs +0 -16
- package/dist/cloud/web/templates/layouts/dashboard.hbs +0 -39
- package/dist/cloud/web/templates/layouts/landing.hbs +0 -82
- package/dist/cloud/web/templates/pages/admin/overview.hbs +0 -123
- package/dist/cloud/web/templates/pages/admin/servers.hbs +0 -129
- package/dist/cloud/web/templates/pages/admin/telemetry.hbs +0 -39
- package/dist/cloud/web/templates/pages/admin/user-edit.hbs +0 -91
- package/dist/cloud/web/templates/pages/admin/users.hbs +0 -179
- package/dist/cloud/web/templates/pages/auth/forgot-password.hbs +0 -25
- package/dist/cloud/web/templates/pages/auth/login.hbs +0 -33
- package/dist/cloud/web/templates/pages/auth/register.hbs +0 -32
- package/dist/cloud/web/templates/pages/auth/reset-password.hbs +0 -34
- package/dist/cloud/web/templates/pages/dashboard/billing.hbs +0 -140
- package/dist/cloud/web/templates/pages/dashboard/create.hbs +0 -173
- package/dist/cloud/web/templates/pages/dashboard/index.hbs +0 -8
- package/dist/cloud/web/templates/pages/dashboard/server-detail.hbs +0 -280
- package/dist/cloud/web/templates/pages/dashboard/server-logs.hbs +0 -35
- package/dist/cloud/web/templates/pages/dashboard/server-metrics.hbs +0 -63
- package/dist/cloud/web/templates/pages/dashboard/servers-partial.hbs +0 -21
- package/dist/cloud/web/templates/pages/dashboard/servers.hbs +0 -44
- package/dist/cloud/web/templates/pages/docs/show.hbs +0 -16
- package/dist/cloud/web/templates/pages/errors/404.hbs +0 -9
- package/dist/cloud/web/templates/pages/errors/500.hbs +0 -8
- package/dist/cloud/web/templates/pages/landing/index.hbs +0 -223
- package/dist/cloud/web/templates/pages/legal/privacy.hbs +0 -71
- package/dist/cloud/web/templates/pages/legal/terms.hbs +0 -73
- package/dist/cloud/web/templates/partials/admin-stats.hbs +0 -52
- package/dist/cloud/web/templates/partials/flash-message.hbs +0 -6
- package/dist/cloud/web/templates/partials/pricing-table.hbs +0 -103
- package/dist/cloud/web/templates/partials/server-card.hbs +0 -19
- package/dist/cloud/web/templates/partials/status-badge.hbs +0 -1
- package/dist/config/configurable-command.d.ts +0 -13
- package/dist/config/configurable-command.js +0 -70
- package/dist/config/mcpmake-config.d.ts +0 -68
- package/dist/config/mcpmake-config.js +0 -207
- package/dist/docs/cli.md +0 -400
- package/dist/docs/mcp-2026-07-28-migration.md +0 -78
- package/dist/docs/migrate-from-stainless.md +0 -94
- package/dist/docs/quickstart.md +0 -166
- package/dist/docs/show-hn.md +0 -26
- package/dist/docs/website-servers.md +0 -169
- package/dist/emitter/code-writer.d.ts +0 -8
- package/dist/emitter/code-writer.js +0 -25
- package/dist/emitter/index.d.ts +0 -32
- package/dist/emitter/index.js +0 -280
- package/dist/emitter/mcpb-bundler.d.ts +0 -31
- package/dist/emitter/mcpb-bundler.js +0 -172
- package/dist/emitter/project-scaffolder.d.ts +0 -4
- package/dist/emitter/project-scaffolder.js +0 -89
- package/dist/emitter/python-template-loader.d.ts +0 -4
- package/dist/emitter/python-template-loader.js +0 -30
- package/dist/emitter/python-templates/dockerfile.hbs +0 -14
- package/dist/emitter/python-templates/env.example.hbs +0 -6
- package/dist/emitter/python-templates/requirements.txt.hbs +0 -4
- package/dist/emitter/python-templates/server.py.hbs +0 -77
- package/dist/emitter/site-scaffolder.d.ts +0 -13
- package/dist/emitter/site-scaffolder.js +0 -70
- package/dist/emitter/site-template-loader.d.ts +0 -5
- package/dist/emitter/site-template-loader.js +0 -47
- package/dist/emitter/site-templates/browser-manager.ts.hbs +0 -233
- package/dist/emitter/site-templates/config.ts.hbs +0 -28
- package/dist/emitter/site-templates/dockerfile.hbs +0 -31
- package/dist/emitter/site-templates/env.example.hbs +0 -19
- package/dist/emitter/site-templates/package.json.hbs +0 -26
- package/dist/emitter/site-templates/server-main-http.ts.hbs +0 -108
- package/dist/emitter/site-templates/server-main.ts.hbs +0 -23
- package/dist/emitter/site-templates/tool-handler-action.ts.hbs +0 -86
- package/dist/emitter/site-templates/tool-handler-form.ts.hbs +0 -116
- package/dist/emitter/site-templates/tool-handler-lifecycle.ts.hbs +0 -146
- package/dist/emitter/site-templates/tool-index.ts.hbs +0 -11
- package/dist/emitter/template-loader.d.ts +0 -1
- package/dist/emitter/template-loader.js +0 -27
- package/dist/emitter/templates/auth-provider.ts.hbs +0 -57
- package/dist/emitter/templates/config.ts.hbs +0 -63
- package/dist/emitter/templates/discovery.ts.hbs +0 -301
- package/dist/emitter/templates/dockerfile.hbs +0 -34
- package/dist/emitter/templates/env.example.hbs +0 -28
- package/dist/emitter/templates/gitignore.hbs +0 -5
- package/dist/emitter/templates/http-executor.ts.hbs +0 -117
- package/dist/emitter/templates/oauth.ts.hbs +0 -188
- package/dist/emitter/templates/package.json.hbs +0 -25
- package/dist/emitter/templates/prompts.ts.hbs +0 -22
- package/dist/emitter/templates/readme.md.hbs +0 -123
- package/dist/emitter/templates/resources.ts.hbs +0 -63
- package/dist/emitter/templates/server-main-http.ts.hbs +0 -407
- package/dist/emitter/templates/server-main.ts.hbs +0 -40
- package/dist/emitter/templates/task-handlers.ts.hbs +0 -189
- package/dist/emitter/templates/task-manager.ts.hbs +0 -139
- package/dist/emitter/templates/task-sse.ts.hbs +0 -105
- package/dist/emitter/templates/tool-handler.ts.hbs +0 -124
- package/dist/emitter/templates/tool-index.ts.hbs +0 -11
- package/dist/emitter/templates/tool-test.ts.hbs +0 -57
- package/dist/emitter/templates/trace.ts.hbs +0 -79
- package/dist/emitter/templates/tsconfig.json.hbs +0 -16
- package/dist/emitter/templates/types.ts.hbs +0 -5
- package/dist/emitter/worker-template-loader.d.ts +0 -5
- package/dist/emitter/worker-template-loader.js +0 -33
- package/dist/emitter/worker-templates/config.ts.hbs +0 -54
- package/dist/emitter/worker-templates/dev-vars.example.hbs +0 -10
- package/dist/emitter/worker-templates/gitignore.hbs +0 -6
- package/dist/emitter/worker-templates/package.json.hbs +0 -24
- package/dist/emitter/worker-templates/readme.md.hbs +0 -53
- package/dist/emitter/worker-templates/server.test.ts.hbs +0 -20
- package/dist/emitter/worker-templates/tool-handler.ts.hbs +0 -85
- package/dist/emitter/worker-templates/tool-index.ts.hbs +0 -28
- package/dist/emitter/worker-templates/tsconfig.json.hbs +0 -17
- package/dist/emitter/worker-templates/worker.ts.hbs +0 -242
- package/dist/emitter/worker-templates/wrangler.toml.hbs +0 -19
- package/dist/generator/spec-generator.d.ts +0 -6
- package/dist/generator/spec-generator.js +0 -50
- package/dist/parser/har-filter.d.ts +0 -8
- package/dist/parser/har-filter.js +0 -71
- package/dist/parser/har-loader.d.ts +0 -2
- package/dist/parser/har-loader.js +0 -14
- package/dist/parser/har-normalizer.d.ts +0 -20
- package/dist/parser/har-normalizer.js +0 -78
- package/dist/parser/index.d.ts +0 -10
- package/dist/parser/index.js +0 -6
- package/dist/parser/openapi-loader.d.ts +0 -6
- package/dist/parser/openapi-loader.js +0 -308
- package/dist/parser/operation-extractor.d.ts +0 -13
- package/dist/parser/operation-extractor.js +0 -155
- package/dist/parser/overlay-loader.d.ts +0 -10
- package/dist/parser/overlay-loader.js +0 -184
- package/dist/parser/postman-loader.d.ts +0 -9
- package/dist/parser/postman-loader.js +0 -106
- package/dist/parser/schema-converter.d.ts +0 -12
- package/dist/parser/schema-converter.js +0 -117
- package/dist/plugins/adapter.d.ts +0 -40
- package/dist/plugins/adapter.js +0 -15
- package/dist/plugins/loader.d.ts +0 -25
- package/dist/plugins/loader.js +0 -58
- package/dist/pricing.d.ts +0 -55
- package/dist/pricing.js +0 -133
- package/dist/providers/index.d.ts +0 -15
- package/dist/providers/index.js +0 -56
- package/dist/recorder/browser-recorder.d.ts +0 -22
- package/dist/recorder/browser-recorder.js +0 -205
- package/dist/rescan/diff-engine.d.ts +0 -5
- package/dist/rescan/diff-engine.js +0 -312
- package/dist/rescan/index.d.ts +0 -3
- package/dist/rescan/index.js +0 -2
- package/dist/rescan/rescan-runner.d.ts +0 -42
- package/dist/rescan/rescan-runner.js +0 -69
- package/dist/rescan/rescan-scheduler.d.ts +0 -41
- package/dist/rescan/rescan-scheduler.js +0 -179
- package/dist/site-transformer/browser-tools.d.ts +0 -10
- package/dist/site-transformer/browser-tools.js +0 -59
- package/dist/site-transformer/index.d.ts +0 -2
- package/dist/site-transformer/index.js +0 -2
- package/dist/site-transformer/selector-healer.d.ts +0 -8
- package/dist/site-transformer/selector-healer.js +0 -106
- package/dist/site-transformer/tool-generator.d.ts +0 -13
- package/dist/site-transformer/tool-generator.js +0 -245
- package/dist/transformer/auth-detector.d.ts +0 -13
- package/dist/transformer/auth-detector.js +0 -90
- package/dist/transformer/catalog-builder.d.ts +0 -18
- package/dist/transformer/catalog-builder.js +0 -56
- package/dist/transformer/client-compat.d.ts +0 -6
- package/dist/transformer/client-compat.js +0 -44
- package/dist/transformer/har-clusterer.d.ts +0 -9
- package/dist/transformer/har-clusterer.js +0 -27
- package/dist/transformer/har-dedup.d.ts +0 -10
- package/dist/transformer/har-dedup.js +0 -81
- package/dist/transformer/har-schema-inferrer.d.ts +0 -15
- package/dist/transformer/har-schema-inferrer.js +0 -90
- package/dist/transformer/har-to-operations.d.ts +0 -13
- package/dist/transformer/har-to-operations.js +0 -192
- package/dist/transformer/index.d.ts +0 -8
- package/dist/transformer/index.js +0 -6
- package/dist/transformer/llm-namer.d.ts +0 -6
- package/dist/transformer/llm-namer.js +0 -59
- package/dist/transformer/naming.d.ts +0 -4
- package/dist/transformer/naming.js +0 -30
- package/dist/transformer/operation-filter.d.ts +0 -13
- package/dist/transformer/operation-filter.js +0 -52
- package/dist/transformer/resource-builder.d.ts +0 -12
- package/dist/transformer/resource-builder.js +0 -80
- package/dist/transformer/schema-merger.d.ts +0 -14
- package/dist/transformer/schema-merger.js +0 -65
- package/dist/transformer/tool-builder.d.ts +0 -3
- package/dist/transformer/tool-builder.js +0 -114
- package/dist/types/index.d.ts +0 -131
- package/dist/types/index.js +0 -1
- package/dist/types/site.d.ts +0 -284
- package/dist/types/site.js +0 -8
- package/dist/utils/fail.d.ts +0 -48
- package/dist/utils/fail.js +0 -204
- package/dist/utils/fs.d.ts +0 -5
- package/dist/utils/fs.js +0 -28
- package/dist/utils/interactive.d.ts +0 -6
- package/dist/utils/interactive.js +0 -30
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/logger.js +0 -2
- package/dist/utils/sanitize.d.ts +0 -28
- package/dist/utils/sanitize.js +0 -44
- package/dist/utils/watcher.d.ts +0 -11
- package/dist/utils/watcher.js +0 -36
package/dist/emitter/index.js
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { writeCodeUnits } from './code-writer.js';
|
|
2
|
-
import { scaffoldProjectFiles, scaffoldSharedModules } from './project-scaffolder.js';
|
|
3
|
-
import { scaffoldSiteProjectFiles, scaffoldSiteSharedModules } from './site-scaffolder.js';
|
|
4
|
-
import { renderTemplate } from './template-loader.js';
|
|
5
|
-
import { renderSiteTemplate } from './site-template-loader.js';
|
|
6
|
-
import { renderPythonTemplate } from './python-template-loader.js';
|
|
7
|
-
import { renderWorkerTemplate } from './worker-template-loader.js';
|
|
8
|
-
import { buildCatalog } from '../transformer/catalog-builder.js';
|
|
9
|
-
import { logger } from '../utils/logger.js';
|
|
10
|
-
const SAFE_VERSION_RE = /^[0-9a-zA-Z._+-]{1,50}$/;
|
|
11
|
-
export async function emitProject(manifest, options) {
|
|
12
|
-
// Cloudflare Workers target uses a separate (stateless Fetch-handler) pipeline.
|
|
13
|
-
if (manifest.target === 'cloudflare') {
|
|
14
|
-
return emitWorkerProject(manifest, options);
|
|
15
|
-
}
|
|
16
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(manifest.serverName)) {
|
|
17
|
-
throw new Error(`Invalid server name: "${manifest.serverName}". Must match /^[a-z0-9][a-z0-9._-]*$/`);
|
|
18
|
-
}
|
|
19
|
-
if (!SAFE_VERSION_RE.test(manifest.serverVersion)) {
|
|
20
|
-
logger.warn(`Unsafe server version "${manifest.serverVersion}" sanitized to "0.0.0"`);
|
|
21
|
-
manifest = { ...manifest, serverVersion: '0.0.0' };
|
|
22
|
-
}
|
|
23
|
-
const units = [];
|
|
24
|
-
// Project skeleton
|
|
25
|
-
units.push(...scaffoldProjectFiles(manifest));
|
|
26
|
-
// Shared source modules
|
|
27
|
-
units.push(...scaffoldSharedModules(manifest));
|
|
28
|
-
// Task manager (if any async operations detected)
|
|
29
|
-
const hasAsyncTools = manifest.tools.some((t) => t.isAsync);
|
|
30
|
-
if (hasAsyncTools) {
|
|
31
|
-
units.push({
|
|
32
|
-
filePath: 'src/task-manager.ts',
|
|
33
|
-
content: renderTemplate('task-manager.ts', manifest),
|
|
34
|
-
});
|
|
35
|
-
units.push({
|
|
36
|
-
filePath: 'src/task-handlers.ts',
|
|
37
|
-
content: renderTemplate('task-handlers.ts', manifest),
|
|
38
|
-
});
|
|
39
|
-
units.push({
|
|
40
|
-
filePath: 'src/task-sse.ts',
|
|
41
|
-
content: renderTemplate('task-sse.ts', manifest),
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
// OAuth module (if OAuth2 auth detected)
|
|
45
|
-
const hasOAuth = manifest.authSchemes.some((s) => s.type === 'oauth2');
|
|
46
|
-
if (hasOAuth) {
|
|
47
|
-
units.push({
|
|
48
|
-
filePath: 'src/oauth.ts',
|
|
49
|
-
content: renderTemplate('oauth.ts', manifest),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
if (manifest.dynamicDiscovery) {
|
|
53
|
-
// Dynamic discovery mode: emit catalog + discovery meta-tools
|
|
54
|
-
const catalog = buildCatalog(manifest.tools);
|
|
55
|
-
units.push({
|
|
56
|
-
filePath: 'src/tool-catalog.json',
|
|
57
|
-
content: JSON.stringify(catalog, null, 2),
|
|
58
|
-
});
|
|
59
|
-
units.push({
|
|
60
|
-
filePath: 'src/discovery.ts',
|
|
61
|
-
content: renderTemplate('discovery.ts', manifest),
|
|
62
|
-
});
|
|
63
|
-
// Hybrid mode: also register first N tools statically
|
|
64
|
-
const staticCount = manifest.staticToolCount ?? 0;
|
|
65
|
-
const staticTools = manifest.tools.slice(0, staticCount);
|
|
66
|
-
if (staticTools.length > 0) {
|
|
67
|
-
for (const tool of staticTools) {
|
|
68
|
-
units.push({
|
|
69
|
-
filePath: `src/tools/${tool.fileName}.ts`,
|
|
70
|
-
content: renderTemplate('tool-handler.ts', tool),
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
units.push({
|
|
74
|
-
filePath: 'src/tools/index.ts',
|
|
75
|
-
content: renderTemplate('tool-index.ts', { tools: staticTools }),
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
logger.info(`Dynamic discovery: ${catalog.length} tools in catalog` +
|
|
79
|
-
(staticTools.length > 0 ? `, ${staticTools.length} static` : ''));
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
// Standard mode: emit all tools individually
|
|
83
|
-
for (const tool of manifest.tools) {
|
|
84
|
-
units.push({
|
|
85
|
-
filePath: `src/tools/${tool.fileName}.ts`,
|
|
86
|
-
content: renderTemplate('tool-handler.ts', tool),
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
units.push({
|
|
90
|
-
filePath: 'src/tools/index.ts',
|
|
91
|
-
content: renderTemplate('tool-index.ts', { tools: manifest.tools }),
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
// Resources file (if any GET list endpoints exist)
|
|
95
|
-
if (manifest.resources && manifest.resources.length > 0) {
|
|
96
|
-
units.push({
|
|
97
|
-
filePath: 'src/resources.ts',
|
|
98
|
-
content: renderTemplate('resources.ts', { resources: manifest.resources }),
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
// Prompts file (if any)
|
|
102
|
-
if (manifest.prompts && manifest.prompts.length > 0) {
|
|
103
|
-
units.push({
|
|
104
|
-
filePath: 'src/prompts.ts',
|
|
105
|
-
content: renderTemplate('prompts.ts', { prompts: manifest.prompts }),
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
// Test files for each tool
|
|
109
|
-
for (const tool of manifest.tools) {
|
|
110
|
-
units.push({
|
|
111
|
-
filePath: `test/tools/${tool.fileName}.test.ts`,
|
|
112
|
-
content: renderTemplate('tool-test.ts', tool),
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
logger.info(`Writing ${units.length} files to ${options.outputDir}`);
|
|
116
|
-
await writeCodeUnits(units, options.outputDir, options);
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Emit a Cloudflare Workers MCP server project (the `--target cloudflare` path).
|
|
120
|
-
*
|
|
121
|
-
* Workers is stateless and has no node:http server, so the SDK's
|
|
122
|
-
* StreamableHTTPServerTransport cannot run there. The entry (`src/index.ts`) is a
|
|
123
|
-
* hand-rolled JSON-RPC Fetch handler instead. The runtime-agnostic modules
|
|
124
|
-
* (`http.ts`, `auth.ts`, `trace.ts`) are reused verbatim from the Node templates —
|
|
125
|
-
* they only need `nodejs_compat`, which `wrangler.toml` enables.
|
|
126
|
-
*
|
|
127
|
-
* v1 scope is tools + initialize/ping/server-discover + bearer auth. Resources,
|
|
128
|
-
* prompts, the Tasks extension and OAuth2 outbound auth are not emitted for this
|
|
129
|
-
* target (a warning is logged and the user is pointed at `--target node`).
|
|
130
|
-
*/
|
|
131
|
-
export async function emitWorkerProject(manifest, options) {
|
|
132
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(manifest.serverName)) {
|
|
133
|
-
throw new Error(`Invalid server name: "${manifest.serverName}". Must match /^[a-z0-9][a-z0-9._-]*$/`);
|
|
134
|
-
}
|
|
135
|
-
if (!SAFE_VERSION_RE.test(manifest.serverVersion)) {
|
|
136
|
-
logger.warn(`Unsafe server version "${manifest.serverVersion}" sanitized to "0.0.0"`);
|
|
137
|
-
manifest = { ...manifest, serverVersion: '0.0.0' };
|
|
138
|
-
}
|
|
139
|
-
// Warn about features the Workers target does not emit (so nothing is silently
|
|
140
|
-
// dropped). Tools — the dominant case — are always fully emitted.
|
|
141
|
-
if ((manifest.resources?.length ?? 0) > 0 || (manifest.prompts?.length ?? 0) > 0) {
|
|
142
|
-
logger.warn(`Cloudflare target emits tools only — ${manifest.resources?.length ?? 0} resource(s) ` +
|
|
143
|
-
`and ${manifest.prompts?.length ?? 0} prompt(s) omitted. Use --target node to include them.`);
|
|
144
|
-
}
|
|
145
|
-
if (manifest.tools.some((t) => t.isAsync)) {
|
|
146
|
-
logger.warn('Cloudflare target: async tools run synchronously within the request (no Tasks extension / background polling).');
|
|
147
|
-
}
|
|
148
|
-
if (manifest.dynamicDiscovery) {
|
|
149
|
-
logger.warn('Cloudflare target does not support --dynamic-discovery; emitting all tools individually.');
|
|
150
|
-
}
|
|
151
|
-
const workerAuthSchemes = manifest.authSchemes.filter((s) => s.type !== 'oauth2');
|
|
152
|
-
if (workerAuthSchemes.length !== manifest.authSchemes.length) {
|
|
153
|
-
logger.warn('Cloudflare target: OAuth2 outbound auth is omitted (apiKey / bearer / basic are supported). Use --target node for OAuth2.');
|
|
154
|
-
}
|
|
155
|
-
const authEnvVars = manifest.envVars.filter((v) => v.name !== 'BASE_URL');
|
|
156
|
-
// The reused auth + config modules must see the filtered (no-oauth2) schemes so
|
|
157
|
-
// they never reference an un-emitted oauth.ts.
|
|
158
|
-
const templateData = {
|
|
159
|
-
...manifest,
|
|
160
|
-
authSchemes: workerAuthSchemes,
|
|
161
|
-
authEnvVars,
|
|
162
|
-
hasOAuth: false,
|
|
163
|
-
};
|
|
164
|
-
const units = [
|
|
165
|
-
// Worker-specific files.
|
|
166
|
-
{ filePath: 'src/index.ts', content: renderWorkerTemplate('worker.ts', templateData) },
|
|
167
|
-
{ filePath: 'src/config.ts', content: renderWorkerTemplate('config.ts', templateData) },
|
|
168
|
-
{ filePath: 'package.json', content: renderWorkerTemplate('package.json', templateData) },
|
|
169
|
-
{ filePath: 'tsconfig.json', content: renderWorkerTemplate('tsconfig.json', templateData) },
|
|
170
|
-
{ filePath: 'wrangler.toml', content: renderWorkerTemplate('wrangler.toml', templateData) },
|
|
171
|
-
{ filePath: 'README.md', content: renderWorkerTemplate('readme.md', templateData) },
|
|
172
|
-
{
|
|
173
|
-
filePath: '.dev.vars.example',
|
|
174
|
-
content: renderWorkerTemplate('dev-vars.example', templateData),
|
|
175
|
-
},
|
|
176
|
-
{ filePath: '.gitignore', content: renderWorkerTemplate('gitignore', templateData) },
|
|
177
|
-
// Runtime-agnostic modules reused from the Node templates (fetch / Buffer /
|
|
178
|
-
// AsyncLocalStorage — all covered by nodejs_compat).
|
|
179
|
-
{ filePath: 'src/http.ts', content: renderTemplate('http-executor.ts', templateData) },
|
|
180
|
-
{ filePath: 'src/auth.ts', content: renderTemplate('auth-provider.ts', templateData) },
|
|
181
|
-
{ filePath: 'src/trace.ts', content: renderTemplate('trace.ts', templateData) },
|
|
182
|
-
];
|
|
183
|
-
for (const tool of manifest.tools) {
|
|
184
|
-
units.push({
|
|
185
|
-
filePath: `src/tools/${tool.fileName}.ts`,
|
|
186
|
-
content: renderWorkerTemplate('tool-handler.ts', tool),
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
units.push({
|
|
190
|
-
filePath: 'src/tools/index.ts',
|
|
191
|
-
content: renderWorkerTemplate('tool-index.ts', { tools: manifest.tools }),
|
|
192
|
-
});
|
|
193
|
-
units.push({
|
|
194
|
-
filePath: 'test/server.test.ts',
|
|
195
|
-
content: renderWorkerTemplate('server.test.ts', templateData),
|
|
196
|
-
});
|
|
197
|
-
logger.info(`Writing ${units.length} Workers files to ${options.outputDir}`);
|
|
198
|
-
await writeCodeUnits(units, options.outputDir, options);
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Emit a Playwright-based MCP server project from a SiteProjectManifest.
|
|
202
|
-
* Parallel to emitProject() but uses site-specific templates.
|
|
203
|
-
*/
|
|
204
|
-
export async function emitSiteProject(manifest, options) {
|
|
205
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(manifest.serverName)) {
|
|
206
|
-
throw new Error(`Invalid server name: "${manifest.serverName}". Must match /^[a-z0-9][a-z0-9._-]*$/`);
|
|
207
|
-
}
|
|
208
|
-
if (!SAFE_VERSION_RE.test(manifest.serverVersion)) {
|
|
209
|
-
logger.warn(`Unsafe server version "${manifest.serverVersion}" sanitized to "0.0.0"`);
|
|
210
|
-
manifest = { ...manifest, serverVersion: '0.0.0' };
|
|
211
|
-
}
|
|
212
|
-
const units = [];
|
|
213
|
-
// Project skeleton (package.json, tsconfig, Dockerfile, .env.example, .gitignore)
|
|
214
|
-
units.push(...scaffoldSiteProjectFiles(manifest));
|
|
215
|
-
// Shared source modules (server entry, config, browser-manager, site-descriptor.json)
|
|
216
|
-
units.push(...scaffoldSiteSharedModules(manifest));
|
|
217
|
-
// Tool files — choose template based on tool type
|
|
218
|
-
for (const tool of manifest.tools) {
|
|
219
|
-
const templateName = getSiteToolTemplate(tool);
|
|
220
|
-
units.push({
|
|
221
|
-
filePath: `src/tools/${tool.fileName}.ts`,
|
|
222
|
-
content: renderSiteTemplate(templateName, tool),
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
// Tool index (registers all tools)
|
|
226
|
-
units.push({
|
|
227
|
-
filePath: 'src/tools/index.ts',
|
|
228
|
-
content: renderSiteTemplate('tool-index.ts', { tools: manifest.tools }),
|
|
229
|
-
});
|
|
230
|
-
logger.info(`Writing ${units.length} files to ${options.outputDir}`);
|
|
231
|
-
await writeCodeUnits(units, options.outputDir, options);
|
|
232
|
-
}
|
|
233
|
-
/** Pick the right template for a site tool based on its type. */
|
|
234
|
-
function getSiteToolTemplate(tool) {
|
|
235
|
-
switch (tool.toolType) {
|
|
236
|
-
case 'browser-lifecycle':
|
|
237
|
-
return 'tool-handler-lifecycle.ts';
|
|
238
|
-
case 'page-action':
|
|
239
|
-
return 'tool-handler-form.ts';
|
|
240
|
-
case 'element-action':
|
|
241
|
-
case 'navigation':
|
|
242
|
-
return 'tool-handler-action.ts';
|
|
243
|
-
default:
|
|
244
|
-
return 'tool-handler-action.ts';
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Emit a Python MCP server project.
|
|
249
|
-
* Generates a single server.py file with all tools, plus requirements.txt.
|
|
250
|
-
*/
|
|
251
|
-
export async function emitPythonProject(manifest, options) {
|
|
252
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(manifest.serverName)) {
|
|
253
|
-
throw new Error(`Invalid server name: "${manifest.serverName}". Must match /^[a-z0-9][a-z0-9._-]*$/`);
|
|
254
|
-
}
|
|
255
|
-
const units = [];
|
|
256
|
-
const templateData = {
|
|
257
|
-
...manifest,
|
|
258
|
-
authEnvVars: manifest.envVars.filter((v) => v.name !== 'BASE_URL'),
|
|
259
|
-
};
|
|
260
|
-
units.push({
|
|
261
|
-
filePath: 'server.py',
|
|
262
|
-
content: renderPythonTemplate('server.py', templateData),
|
|
263
|
-
});
|
|
264
|
-
units.push({
|
|
265
|
-
filePath: 'requirements.txt',
|
|
266
|
-
content: renderPythonTemplate('requirements.txt', manifest),
|
|
267
|
-
});
|
|
268
|
-
units.push({
|
|
269
|
-
filePath: '.env.example',
|
|
270
|
-
content: renderPythonTemplate('env.example', templateData),
|
|
271
|
-
});
|
|
272
|
-
if (manifest.transport === 'http') {
|
|
273
|
-
units.push({
|
|
274
|
-
filePath: 'Dockerfile',
|
|
275
|
-
content: renderPythonTemplate('dockerfile', manifest),
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
logger.info(`Writing ${units.length} Python files to ${options.outputDir}`);
|
|
279
|
-
await writeCodeUnits(units, options.outputDir, options);
|
|
280
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export interface McpbManifest {
|
|
2
|
-
schema_version: string;
|
|
3
|
-
name: string;
|
|
4
|
-
version: string;
|
|
5
|
-
description: string;
|
|
6
|
-
author: string;
|
|
7
|
-
license: string;
|
|
8
|
-
runtime: string;
|
|
9
|
-
entry_point: string;
|
|
10
|
-
tools: {
|
|
11
|
-
name: string;
|
|
12
|
-
description: string;
|
|
13
|
-
}[];
|
|
14
|
-
env_vars: {
|
|
15
|
-
name: string;
|
|
16
|
-
description: string;
|
|
17
|
-
required: boolean;
|
|
18
|
-
}[];
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Generate an .mcpb bundle from a built MCP server project.
|
|
22
|
-
*
|
|
23
|
-
* The bundle is a zip file containing:
|
|
24
|
-
* manifest.json - metadata, tool list, config schema
|
|
25
|
-
* server/ - the Node.js server code (package.json, dist/, node_modules/)
|
|
26
|
-
*/
|
|
27
|
-
export declare function generateMcpb(opts: {
|
|
28
|
-
projectDir: string;
|
|
29
|
-
outputPath?: string;
|
|
30
|
-
manifest?: Partial<McpbManifest>;
|
|
31
|
-
}): Promise<string>;
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { readFile, readdir, mkdtemp, rm, cp, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { resolve, join, basename } from 'node:path';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { execFile as execFileCb } from 'node:child_process';
|
|
5
|
-
import { promisify } from 'node:util';
|
|
6
|
-
import { logger } from '../utils/logger.js';
|
|
7
|
-
import { pathExists } from '../utils/fs.js';
|
|
8
|
-
const execFile = promisify(execFileCb);
|
|
9
|
-
/**
|
|
10
|
-
* Generate an .mcpb bundle from a built MCP server project.
|
|
11
|
-
*
|
|
12
|
-
* The bundle is a zip file containing:
|
|
13
|
-
* manifest.json - metadata, tool list, config schema
|
|
14
|
-
* server/ - the Node.js server code (package.json, dist/, node_modules/)
|
|
15
|
-
*/
|
|
16
|
-
export async function generateMcpb(opts) {
|
|
17
|
-
const { projectDir } = opts;
|
|
18
|
-
// Validate project structure
|
|
19
|
-
const pkgPath = resolve(projectDir, 'package.json');
|
|
20
|
-
if (!(await pathExists(pkgPath))) {
|
|
21
|
-
throw new Error(`Not a valid project directory (no package.json): ${projectDir}`);
|
|
22
|
-
}
|
|
23
|
-
const distDir = resolve(projectDir, 'dist');
|
|
24
|
-
if (!(await pathExists(distDir))) {
|
|
25
|
-
throw new Error(`No dist/ directory found. Build the project first: cd ${projectDir} && npm run build`);
|
|
26
|
-
}
|
|
27
|
-
// Read project metadata
|
|
28
|
-
const pkgJson = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
29
|
-
const projectName = pkgJson.name ?? 'mcp-server';
|
|
30
|
-
const projectVersion = pkgJson.version ?? '1.0.0';
|
|
31
|
-
const projectDescription = pkgJson.description ?? '';
|
|
32
|
-
// Extract tool list (reuse same strategies as publish.ts)
|
|
33
|
-
const tools = await extractToolList(projectDir);
|
|
34
|
-
// Extract env vars from .env.example
|
|
35
|
-
const envVars = await extractEnvVars(projectDir);
|
|
36
|
-
// Build the manifest
|
|
37
|
-
const manifest = {
|
|
38
|
-
schema_version: '1.0',
|
|
39
|
-
name: opts.manifest?.name ?? projectName,
|
|
40
|
-
version: opts.manifest?.version ?? projectVersion,
|
|
41
|
-
description: opts.manifest?.description ?? projectDescription,
|
|
42
|
-
author: opts.manifest?.author ?? '',
|
|
43
|
-
license: opts.manifest?.license ?? 'proprietary',
|
|
44
|
-
runtime: opts.manifest?.runtime ?? 'node',
|
|
45
|
-
entry_point: opts.manifest?.entry_point ?? 'server/dist/index.js',
|
|
46
|
-
tools: opts.manifest?.tools ?? tools,
|
|
47
|
-
env_vars: opts.manifest?.env_vars ?? envVars,
|
|
48
|
-
};
|
|
49
|
-
// Create temp staging directory
|
|
50
|
-
const stagingDir = await mkdtemp(join(tmpdir(), 'mcpb-'));
|
|
51
|
-
try {
|
|
52
|
-
// Create server/ subdirectory with the project contents
|
|
53
|
-
const serverDir = join(stagingDir, 'server');
|
|
54
|
-
// Copy dist/
|
|
55
|
-
await cp(resolve(projectDir, 'dist'), join(serverDir, 'dist'), { recursive: true });
|
|
56
|
-
// Copy package.json (stripped to essentials)
|
|
57
|
-
const minimalPkg = {
|
|
58
|
-
name: pkgJson.name,
|
|
59
|
-
version: pkgJson.version,
|
|
60
|
-
description: pkgJson.description,
|
|
61
|
-
type: pkgJson.type,
|
|
62
|
-
main: pkgJson.main,
|
|
63
|
-
dependencies: pkgJson.dependencies,
|
|
64
|
-
};
|
|
65
|
-
await writeFile(join(serverDir, 'package.json'), JSON.stringify(minimalPkg, null, 2), 'utf-8');
|
|
66
|
-
// Copy node_modules/ if present
|
|
67
|
-
const nodeModulesDir = resolve(projectDir, 'node_modules');
|
|
68
|
-
if (await pathExists(nodeModulesDir)) {
|
|
69
|
-
await cp(nodeModulesDir, join(serverDir, 'node_modules'), { recursive: true });
|
|
70
|
-
}
|
|
71
|
-
// Write manifest.json at root of the bundle
|
|
72
|
-
await writeFile(join(stagingDir, 'manifest.json'), JSON.stringify(manifest, null, 2), 'utf-8');
|
|
73
|
-
// Determine output path
|
|
74
|
-
const outputPath = opts.outputPath ?? resolve(projectDir, '..', `${basename(projectDir)}.mcpb`);
|
|
75
|
-
// Create the zip archive using the system zip command
|
|
76
|
-
await execFile('zip', ['-r', '-q', resolve(outputPath), '.'], {
|
|
77
|
-
cwd: stagingDir,
|
|
78
|
-
});
|
|
79
|
-
return outputPath;
|
|
80
|
-
}
|
|
81
|
-
finally {
|
|
82
|
-
// Clean up staging directory
|
|
83
|
-
await rm(stagingDir, { recursive: true, force: true });
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Extract tool names and descriptions from a generated project.
|
|
88
|
-
* Tries tool-catalog.json first, then scans src/tools/*.ts files.
|
|
89
|
-
*/
|
|
90
|
-
async function extractToolList(projectDir) {
|
|
91
|
-
// Strategy 1: tool-catalog.json (dynamic discovery projects)
|
|
92
|
-
const catalogPath = resolve(projectDir, 'src/tool-catalog.json');
|
|
93
|
-
if (await pathExists(catalogPath)) {
|
|
94
|
-
try {
|
|
95
|
-
const catalog = JSON.parse(await readFile(catalogPath, 'utf-8'));
|
|
96
|
-
if (Array.isArray(catalog)) {
|
|
97
|
-
return catalog.map((entry) => ({
|
|
98
|
-
name: entry.name,
|
|
99
|
-
description: entry.description ?? entry.title ?? '',
|
|
100
|
-
}));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
logger.warn('Failed to parse tool-catalog.json, falling back to tool file scanning');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Strategy 2: Parse individual tool handler files in src/tools/
|
|
108
|
-
const toolsDir = resolve(projectDir, 'src/tools');
|
|
109
|
-
if (!(await pathExists(toolsDir))) {
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
const tools = [];
|
|
113
|
-
let entries;
|
|
114
|
-
try {
|
|
115
|
-
entries = await readdir(toolsDir);
|
|
116
|
-
}
|
|
117
|
-
catch {
|
|
118
|
-
return [];
|
|
119
|
-
}
|
|
120
|
-
for (const file of entries) {
|
|
121
|
-
if (file === 'index.ts' || !file.endsWith('.ts'))
|
|
122
|
-
continue;
|
|
123
|
-
try {
|
|
124
|
-
const content = await readFile(join(toolsDir, file), 'utf-8');
|
|
125
|
-
const nameMatch = content.match(/registerTool\(\s*['"]([^'"]+)['"]/);
|
|
126
|
-
if (!nameMatch)
|
|
127
|
-
continue;
|
|
128
|
-
const descMatch = content.match(/description:\s*[`'"]([^`'"]*)[`'"]/);
|
|
129
|
-
tools.push({
|
|
130
|
-
name: nameMatch[1],
|
|
131
|
-
description: descMatch ? descMatch[1] : '',
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
// skip files that can't be read
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return tools;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Extract environment variable definitions from .env.example.
|
|
142
|
-
* Each line is expected to be: VAR_NAME=value # optional comment
|
|
143
|
-
*/
|
|
144
|
-
async function extractEnvVars(projectDir) {
|
|
145
|
-
const envPath = resolve(projectDir, '.env.example');
|
|
146
|
-
if (!(await pathExists(envPath))) {
|
|
147
|
-
return [];
|
|
148
|
-
}
|
|
149
|
-
const content = await readFile(envPath, 'utf-8');
|
|
150
|
-
const vars = [];
|
|
151
|
-
for (const line of content.split('\n')) {
|
|
152
|
-
const trimmed = line.trim();
|
|
153
|
-
if (!trimmed || trimmed.startsWith('#'))
|
|
154
|
-
continue;
|
|
155
|
-
const eqIndex = trimmed.indexOf('=');
|
|
156
|
-
if (eqIndex === -1)
|
|
157
|
-
continue;
|
|
158
|
-
const name = trimmed.slice(0, eqIndex).trim();
|
|
159
|
-
if (!name)
|
|
160
|
-
continue;
|
|
161
|
-
// Extract inline comment as description
|
|
162
|
-
const valuePart = trimmed.slice(eqIndex + 1);
|
|
163
|
-
const commentIndex = valuePart.indexOf('#');
|
|
164
|
-
const description = commentIndex >= 0 ? valuePart.slice(commentIndex + 1).trim() : '';
|
|
165
|
-
vars.push({
|
|
166
|
-
name,
|
|
167
|
-
description,
|
|
168
|
-
required: true,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
return vars;
|
|
172
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ProjectManifest } from '../types/index.js';
|
|
2
|
-
import type { CodeUnit } from './code-writer.js';
|
|
3
|
-
export declare function scaffoldProjectFiles(manifest: ProjectManifest): CodeUnit[];
|
|
4
|
-
export declare function scaffoldSharedModules(manifest: ProjectManifest): CodeUnit[];
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { renderTemplate } from './template-loader.js';
|
|
2
|
-
/**
|
|
3
|
-
* At/above this tool count, registering every tool upfront is a real token-cost
|
|
4
|
-
* problem; the README recommends `--dynamic-discovery` (the #1 buyer concern).
|
|
5
|
-
*/
|
|
6
|
-
const DISCOVERY_RECOMMEND_THRESHOLD = 50;
|
|
7
|
-
export function scaffoldProjectFiles(manifest) {
|
|
8
|
-
const dynamicDiscovery = manifest.dynamicDiscovery ?? false;
|
|
9
|
-
const units = [
|
|
10
|
-
{
|
|
11
|
-
filePath: 'package.json',
|
|
12
|
-
content: renderTemplate('package.json', manifest),
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
filePath: 'tsconfig.json',
|
|
16
|
-
content: renderTemplate('tsconfig.json', manifest),
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
filePath: '.env.example',
|
|
20
|
-
content: renderTemplate('env.example', {
|
|
21
|
-
...manifest,
|
|
22
|
-
authEnvVars: manifest.envVars.filter((v) => v.name !== 'BASE_URL'),
|
|
23
|
-
}),
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
filePath: '.gitignore',
|
|
27
|
-
content: renderTemplate('gitignore', manifest),
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
filePath: 'README.md',
|
|
31
|
-
content: renderTemplate('readme.md', {
|
|
32
|
-
...manifest,
|
|
33
|
-
authEnvVars: manifest.envVars.filter((v) => v.name !== 'BASE_URL'),
|
|
34
|
-
dynamicDiscovery,
|
|
35
|
-
recommendDiscovery: !dynamicDiscovery && manifest.tools.length >= DISCOVERY_RECOMMEND_THRESHOLD,
|
|
36
|
-
}),
|
|
37
|
-
},
|
|
38
|
-
];
|
|
39
|
-
if (manifest.transport === 'http') {
|
|
40
|
-
units.push({
|
|
41
|
-
filePath: 'Dockerfile',
|
|
42
|
-
content: renderTemplate('dockerfile', manifest),
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
return units;
|
|
46
|
-
}
|
|
47
|
-
export function scaffoldSharedModules(manifest) {
|
|
48
|
-
const hasOAuth = manifest.authSchemes.some((s) => s.type === 'oauth2');
|
|
49
|
-
const hasDynamicDiscovery = manifest.dynamicDiscovery ?? false;
|
|
50
|
-
const hasStaticTools = !hasDynamicDiscovery || (manifest.staticToolCount ?? 0) > 0;
|
|
51
|
-
const hasAsyncTools = manifest.tools.some((t) => t.isAsync);
|
|
52
|
-
const templateData = {
|
|
53
|
-
...manifest,
|
|
54
|
-
hasResources: (manifest.resources?.length ?? 0) > 0,
|
|
55
|
-
hasPrompts: (manifest.prompts?.length ?? 0) > 0,
|
|
56
|
-
hasOAuth,
|
|
57
|
-
hasDynamicDiscovery,
|
|
58
|
-
hasStaticTools,
|
|
59
|
-
hasAsyncTools,
|
|
60
|
-
};
|
|
61
|
-
return [
|
|
62
|
-
{
|
|
63
|
-
filePath: 'src/index.ts',
|
|
64
|
-
content: renderTemplate(manifest.transport === 'http' ? 'server-main-http.ts' : 'server-main.ts', templateData),
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
filePath: 'src/config.ts',
|
|
68
|
-
content: renderTemplate('config.ts', manifest),
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
filePath: 'src/auth.ts',
|
|
72
|
-
content: renderTemplate('auth-provider.ts', templateData),
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
filePath: 'src/http.ts',
|
|
76
|
-
content: renderTemplate('http-executor.ts', manifest),
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
// W3C Trace Context — the executor stamps the active traceparent onto
|
|
80
|
-
// upstream calls; the HTTP server establishes the context per request.
|
|
81
|
-
filePath: 'src/trace.ts',
|
|
82
|
-
content: renderTemplate('trace.ts', manifest),
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
filePath: 'src/types.ts',
|
|
86
|
-
content: renderTemplate('types.ts', manifest),
|
|
87
|
-
},
|
|
88
|
-
];
|
|
89
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template loader for Python MCP server templates.
|
|
3
|
-
*/
|
|
4
|
-
import { readFileSync } from 'node:fs';
|
|
5
|
-
import { resolve, dirname } from 'node:path';
|
|
6
|
-
import { fileURLToPath } from 'node:url';
|
|
7
|
-
import Handlebars from 'handlebars';
|
|
8
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const PYTHON_TEMPLATE_DIR = resolve(__dirname, 'python-templates');
|
|
10
|
-
const pythonTemplateCache = new Map();
|
|
11
|
-
Handlebars.registerHelper('eq', function (a, b) {
|
|
12
|
-
return a === b;
|
|
13
|
-
});
|
|
14
|
-
Handlebars.registerHelper('pyDocstring', function (str) {
|
|
15
|
-
if (!str)
|
|
16
|
-
return '';
|
|
17
|
-
return str.replace(/"""/g, '\\"\\"\\"').replace(/\\/g, '\\\\');
|
|
18
|
-
});
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
-
export function renderPythonTemplate(name, data) {
|
|
21
|
-
if (!pythonTemplateCache.has(name)) {
|
|
22
|
-
const templatePath = resolve(PYTHON_TEMPLATE_DIR, `${name}.hbs`);
|
|
23
|
-
if (!templatePath.startsWith(PYTHON_TEMPLATE_DIR + '/')) {
|
|
24
|
-
throw new Error(`Invalid python template name: ${name}`);
|
|
25
|
-
}
|
|
26
|
-
const raw = readFileSync(templatePath, 'utf-8');
|
|
27
|
-
pythonTemplateCache.set(name, Handlebars.compile(raw, { noEscape: true }));
|
|
28
|
-
}
|
|
29
|
-
return pythonTemplateCache.get(name)(data);
|
|
30
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
FROM python:3.12-slim
|
|
2
|
-
|
|
3
|
-
WORKDIR /app
|
|
4
|
-
COPY requirements.txt .
|
|
5
|
-
RUN pip install --no-cache-dir -r requirements.txt
|
|
6
|
-
COPY server.py .
|
|
7
|
-
COPY .env.example .env
|
|
8
|
-
|
|
9
|
-
ENV TRANSPORT=http
|
|
10
|
-
ENV PORT=3000
|
|
11
|
-
|
|
12
|
-
EXPOSE 3000
|
|
13
|
-
|
|
14
|
-
CMD ["python", "server.py"]
|