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
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared singletons used by both the API server and the web router.
|
|
3
|
-
* Extracted to break circular dependencies between server.ts and router.ts.
|
|
4
|
-
*
|
|
5
|
-
* Environment variables:
|
|
6
|
-
* DATABASE_URL — PostgreSQL connection string (optional; in-memory when unset)
|
|
7
|
-
* ENCRYPTION_KEY — Master key for secret encryption (>=32 chars in production)
|
|
8
|
-
* ADMIN_EMAIL — Email address auto-promoted to admin on registration
|
|
9
|
-
* ADMIN_TOKEN — Bearer token for API-level admin endpoints
|
|
10
|
-
* IDLE_THRESHOLD_MS — Idle timeout before containers are stopped (default: 3600000)
|
|
11
|
-
* TRUST_PROXY — Set to "true" to trust X-Forwarded-* headers
|
|
12
|
-
* STRIPE_SECRET_KEY — Stripe secret API key (optional; billing disabled when unset)
|
|
13
|
-
* STRIPE_WEBHOOK_SECRET — Stripe webhook signing secret for signature verification
|
|
14
|
-
* STRIPE_PRICE_HOBBYIST — Stripe Price ID for the Hobbyist plan ($9/mo)
|
|
15
|
-
* STRIPE_PRICE_PRO — Stripe Price ID for the Pro plan ($29/mo)
|
|
16
|
-
* STRIPE_PRICE_TEAM — Stripe Price ID for the Team plan ($99/mo)
|
|
17
|
-
*/
|
|
18
|
-
import { ServerStore, PortAllocator } from './store.js';
|
|
19
|
-
import { MetricsStore } from './metrics.js';
|
|
20
|
-
import { RateLimiter } from './rate-limiter.js';
|
|
21
|
-
import { UsageTracker } from './billing/usage-tracker.js';
|
|
22
|
-
import { type UsageStore } from './billing/usage-store.js';
|
|
23
|
-
import { type CreditStore } from './billing/credit-store.js';
|
|
24
|
-
import { FailureTracker } from './failure-tracker.js';
|
|
25
|
-
import { type MetricSampleStore } from './metric-samples.js';
|
|
26
|
-
import { type TelemetryStore } from './telemetry-store.js';
|
|
27
|
-
import { SecretStore } from './secret-store.js';
|
|
28
|
-
import type { Database } from './db/index.js';
|
|
29
|
-
import type { PgServerStore } from './db/pg-store.js';
|
|
30
|
-
import type { PgUserStore, PgSessionStore } from './db/pg-store.js';
|
|
31
|
-
export declare const MAX_SPEC_SIZE: number;
|
|
32
|
-
export declare const MAX_NAME_LENGTH = 100;
|
|
33
|
-
export declare const UPLOAD_DIR = "/tmp/mcpmake-uploads";
|
|
34
|
-
export declare const store: ServerStore;
|
|
35
|
-
export declare const ports: PortAllocator;
|
|
36
|
-
export declare const uploadLimiter: RateLimiter;
|
|
37
|
-
export declare const loginLimiter: RateLimiter;
|
|
38
|
-
export declare const resetLimiter: RateLimiter;
|
|
39
|
-
export declare const telemetryLimiter: RateLimiter;
|
|
40
|
-
export declare const metrics: MetricsStore;
|
|
41
|
-
export declare const usageTracker: UsageTracker;
|
|
42
|
-
/** Rolling per-minute API failure-rate counter (in-memory, bounded). */
|
|
43
|
-
export declare const failureTracker: FailureTracker;
|
|
44
|
-
/** Returns the active Database instance, or null when running in-memory. */
|
|
45
|
-
export declare function getDb(): Database | null;
|
|
46
|
-
/** Returns the Pg-backed server store, or null when running in-memory. */
|
|
47
|
-
export declare function getPgServerStore(): PgServerStore | null;
|
|
48
|
-
/** Returns the Pg-backed user store, or null when running in-memory. */
|
|
49
|
-
export declare function getPgUserStore(): PgUserStore | null;
|
|
50
|
-
/** Returns the Pg-backed session store, or null when running in-memory. */
|
|
51
|
-
export declare function getPgSessionStore(): PgSessionStore | null;
|
|
52
|
-
/** Returns the active usage store (Pg-backed when a database is configured). */
|
|
53
|
-
export declare function getUsageStore(): UsageStore;
|
|
54
|
-
/** Returns the active credit store (Pg-backed when a database is configured). */
|
|
55
|
-
export declare function getCreditStore(): CreditStore;
|
|
56
|
-
/** Returns the active metric-sample store (Pg-backed when a database is configured). */
|
|
57
|
-
export declare function getMetricSampleStore(): MetricSampleStore;
|
|
58
|
-
/** Returns the active telemetry store (Pg-backed when a database is configured). */
|
|
59
|
-
export declare function getTelemetryStore(): TelemetryStore;
|
|
60
|
-
/** Returns the secret store. Lazily initialised on first access. */
|
|
61
|
-
export declare function getSecretStore(): SecretStore;
|
|
62
|
-
/**
|
|
63
|
-
* Initialise stores from environment.
|
|
64
|
-
*
|
|
65
|
-
* When `DATABASE_URL` is set, creates PostgreSQL-backed stores and runs
|
|
66
|
-
* pending migrations. The Pg stores are exposed via getter functions above
|
|
67
|
-
* so that callers can be migrated incrementally.
|
|
68
|
-
*
|
|
69
|
-
* The original in-memory `store`, `userStore`, and `sessionStore` remain
|
|
70
|
-
* available for code that hasn't been ported to async yet.
|
|
71
|
-
*/
|
|
72
|
-
export declare function initStores(): Promise<void>;
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared singletons used by both the API server and the web router.
|
|
3
|
-
* Extracted to break circular dependencies between server.ts and router.ts.
|
|
4
|
-
*
|
|
5
|
-
* Environment variables:
|
|
6
|
-
* DATABASE_URL — PostgreSQL connection string (optional; in-memory when unset)
|
|
7
|
-
* ENCRYPTION_KEY — Master key for secret encryption (>=32 chars in production)
|
|
8
|
-
* ADMIN_EMAIL — Email address auto-promoted to admin on registration
|
|
9
|
-
* ADMIN_TOKEN — Bearer token for API-level admin endpoints
|
|
10
|
-
* IDLE_THRESHOLD_MS — Idle timeout before containers are stopped (default: 3600000)
|
|
11
|
-
* TRUST_PROXY — Set to "true" to trust X-Forwarded-* headers
|
|
12
|
-
* STRIPE_SECRET_KEY — Stripe secret API key (optional; billing disabled when unset)
|
|
13
|
-
* STRIPE_WEBHOOK_SECRET — Stripe webhook signing secret for signature verification
|
|
14
|
-
* STRIPE_PRICE_HOBBYIST — Stripe Price ID for the Hobbyist plan ($9/mo)
|
|
15
|
-
* STRIPE_PRICE_PRO — Stripe Price ID for the Pro plan ($29/mo)
|
|
16
|
-
* STRIPE_PRICE_TEAM — Stripe Price ID for the Team plan ($99/mo)
|
|
17
|
-
*/
|
|
18
|
-
import os from 'node:os';
|
|
19
|
-
import { ServerStore, PortAllocator } from './store.js';
|
|
20
|
-
import { MetricsStore } from './metrics.js';
|
|
21
|
-
import { RateLimiter } from './rate-limiter.js';
|
|
22
|
-
import { UsageTracker } from './billing/usage-tracker.js';
|
|
23
|
-
import { InMemoryUsageStore } from './billing/usage-store.js';
|
|
24
|
-
import { InMemoryCreditStore } from './billing/credit-store.js';
|
|
25
|
-
import { FailureTracker } from './failure-tracker.js';
|
|
26
|
-
import { InMemoryMetricSampleStore } from './metric-samples.js';
|
|
27
|
-
import { InMemoryTelemetryStore } from './telemetry-store.js';
|
|
28
|
-
import { SecretStore } from './secret-store.js';
|
|
29
|
-
import { logger } from '../utils/logger.js';
|
|
30
|
-
export const MAX_SPEC_SIZE = 5 * 1024 * 1024; // 5 MB
|
|
31
|
-
export const MAX_NAME_LENGTH = 100;
|
|
32
|
-
export const UPLOAD_DIR = '/tmp/mcpmake-uploads';
|
|
33
|
-
export const store = new ServerStore();
|
|
34
|
-
export const ports = new PortAllocator();
|
|
35
|
-
export const uploadLimiter = new RateLimiter({ maxRequests: 10, windowMs: 86_400_000 }); // 10/day
|
|
36
|
-
export const loginLimiter = new RateLimiter({ maxRequests: 10, windowMs: 3_600_000 }); // 10/hour per key
|
|
37
|
-
export const resetLimiter = new RateLimiter({ maxRequests: 3, windowMs: 3_600_000 }); // 3/hour per key
|
|
38
|
-
// Per-IP flood cap for the unauthenticated telemetry endpoint. NOTE: behind a
|
|
39
|
-
// reverse proxy without TRUST_PROXY=true every request appears to come from
|
|
40
|
-
// 127.0.0.1, so this degrades to a single global bucket (a coarse but still
|
|
41
|
-
// useful flood cap). Same limitation as uploadLimiter/loginLimiter.
|
|
42
|
-
export const telemetryLimiter = new RateLimiter({ maxRequests: 20, windowMs: 3_600_000 }); // 20/hour per key
|
|
43
|
-
export const metrics = new MetricsStore();
|
|
44
|
-
export const usageTracker = new UsageTracker();
|
|
45
|
-
/** Rolling per-minute API failure-rate counter (in-memory, bounded). */
|
|
46
|
-
export const failureTracker = new FailureTracker();
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
48
|
-
// PostgreSQL-backed stores (populated by initStores when DATABASE_URL is set)
|
|
49
|
-
// ---------------------------------------------------------------------------
|
|
50
|
-
let _db = null;
|
|
51
|
-
let _pgServerStore = null;
|
|
52
|
-
let _pgUserStore = null;
|
|
53
|
-
let _pgSessionStore = null;
|
|
54
|
-
let _secretStore = null;
|
|
55
|
-
let _usageStore = new InMemoryUsageStore();
|
|
56
|
-
let _creditStore = new InMemoryCreditStore();
|
|
57
|
-
let _metricSampleStore = new InMemoryMetricSampleStore();
|
|
58
|
-
let _telemetryStore = new InMemoryTelemetryStore();
|
|
59
|
-
/** Returns the active Database instance, or null when running in-memory. */
|
|
60
|
-
export function getDb() {
|
|
61
|
-
return _db;
|
|
62
|
-
}
|
|
63
|
-
/** Returns the Pg-backed server store, or null when running in-memory. */
|
|
64
|
-
export function getPgServerStore() {
|
|
65
|
-
return _pgServerStore;
|
|
66
|
-
}
|
|
67
|
-
/** Returns the Pg-backed user store, or null when running in-memory. */
|
|
68
|
-
export function getPgUserStore() {
|
|
69
|
-
return _pgUserStore;
|
|
70
|
-
}
|
|
71
|
-
/** Returns the Pg-backed session store, or null when running in-memory. */
|
|
72
|
-
export function getPgSessionStore() {
|
|
73
|
-
return _pgSessionStore;
|
|
74
|
-
}
|
|
75
|
-
/** Returns the active usage store (Pg-backed when a database is configured). */
|
|
76
|
-
export function getUsageStore() {
|
|
77
|
-
return _usageStore;
|
|
78
|
-
}
|
|
79
|
-
/** Returns the active credit store (Pg-backed when a database is configured). */
|
|
80
|
-
export function getCreditStore() {
|
|
81
|
-
return _creditStore;
|
|
82
|
-
}
|
|
83
|
-
/** Returns the active metric-sample store (Pg-backed when a database is configured). */
|
|
84
|
-
export function getMetricSampleStore() {
|
|
85
|
-
return _metricSampleStore;
|
|
86
|
-
}
|
|
87
|
-
/** Returns the active telemetry store (Pg-backed when a database is configured). */
|
|
88
|
-
export function getTelemetryStore() {
|
|
89
|
-
return _telemetryStore;
|
|
90
|
-
}
|
|
91
|
-
/** Returns the secret store. Lazily initialised on first access. */
|
|
92
|
-
export function getSecretStore() {
|
|
93
|
-
if (!_secretStore) {
|
|
94
|
-
_secretStore = createSecretStore();
|
|
95
|
-
}
|
|
96
|
-
return _secretStore;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Create a SecretStore from the ENCRYPTION_KEY env var.
|
|
100
|
-
* Falls back to a machine-specific derived key in development.
|
|
101
|
-
*/
|
|
102
|
-
function createSecretStore(db) {
|
|
103
|
-
let masterKey = process.env.ENCRYPTION_KEY;
|
|
104
|
-
if (!masterKey || masterKey.length < 32) {
|
|
105
|
-
if (process.env.NODE_ENV === 'production' || process.env.DOMAIN) {
|
|
106
|
-
throw new Error('ENCRYPTION_KEY must be set to at least 32 characters in production');
|
|
107
|
-
}
|
|
108
|
-
const devKey = `dev-insecure-${os.hostname()}`;
|
|
109
|
-
logger.warn('ENCRYPTION_KEY is not set or is shorter than 32 characters. ' +
|
|
110
|
-
'Using a derived dev key — NOT suitable for production.');
|
|
111
|
-
masterKey = devKey;
|
|
112
|
-
}
|
|
113
|
-
return new SecretStore(masterKey, db);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Initialise stores from environment.
|
|
117
|
-
*
|
|
118
|
-
* When `DATABASE_URL` is set, creates PostgreSQL-backed stores and runs
|
|
119
|
-
* pending migrations. The Pg stores are exposed via getter functions above
|
|
120
|
-
* so that callers can be migrated incrementally.
|
|
121
|
-
*
|
|
122
|
-
* The original in-memory `store`, `userStore`, and `sessionStore` remain
|
|
123
|
-
* available for code that hasn't been ported to async yet.
|
|
124
|
-
*/
|
|
125
|
-
export async function initStores() {
|
|
126
|
-
const databaseUrl = process.env.DATABASE_URL;
|
|
127
|
-
if (!databaseUrl)
|
|
128
|
-
return;
|
|
129
|
-
try {
|
|
130
|
-
const { createDatabase } = await import('./db/index.js');
|
|
131
|
-
const { runMigrations } = await import('./db/migrations.js');
|
|
132
|
-
const { PgServerStore: PgSS, PgUserStore: PgUS, PgSessionStore: PgSesS, } = await import('./db/pg-store.js');
|
|
133
|
-
const db = await createDatabase(databaseUrl);
|
|
134
|
-
await runMigrations(db);
|
|
135
|
-
_db = db;
|
|
136
|
-
_pgServerStore = new PgSS(db);
|
|
137
|
-
_pgUserStore = new PgUS(db);
|
|
138
|
-
_pgSessionStore = new PgSesS(db);
|
|
139
|
-
const { PgUsageStore } = await import('./billing/usage-store.js');
|
|
140
|
-
_usageStore = new PgUsageStore(db);
|
|
141
|
-
const { PgCreditStore } = await import('./billing/credit-store.js');
|
|
142
|
-
_creditStore = new PgCreditStore(db);
|
|
143
|
-
const { PgMetricSampleStore } = await import('./metric-samples.js');
|
|
144
|
-
_metricSampleStore = new PgMetricSampleStore(db);
|
|
145
|
-
const { PgTelemetryStore } = await import('./telemetry-store.js');
|
|
146
|
-
_telemetryStore = new PgTelemetryStore(db);
|
|
147
|
-
// Wire the secret store to the database
|
|
148
|
-
if (_secretStore) {
|
|
149
|
-
_secretStore.setDatabase(db);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
_secretStore = createSecretStore(db);
|
|
153
|
-
}
|
|
154
|
-
logger.info('PostgreSQL stores initialized');
|
|
155
|
-
}
|
|
156
|
-
catch (err) {
|
|
157
|
-
logger.warn(`PostgreSQL initialization failed, using in-memory stores: ${err instanceof Error ? err.message : err}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
package/dist/cloud/ssrf.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SSRF protection for user-supplied URLs.
|
|
3
|
-
*
|
|
4
|
-
* Before the backend fetches a spec URL or crawls a website on behalf of a
|
|
5
|
-
* user, we must ensure the target is a genuinely public host. Otherwise an
|
|
6
|
-
* attacker could point us at internal services, the cloud metadata endpoint
|
|
7
|
-
* (169.254.169.254), or other private infrastructure.
|
|
8
|
-
*
|
|
9
|
-
* Guards:
|
|
10
|
-
* - protocol must be http/https
|
|
11
|
-
* - the hostname's resolved IP(s) must all be public (no loopback,
|
|
12
|
-
* private, link-local, CGNAT, unique-local, etc.)
|
|
13
|
-
* - redirects are followed manually and each hop is re-validated
|
|
14
|
-
*/
|
|
15
|
-
export declare class SsrfError extends Error {
|
|
16
|
-
constructor(message: string);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Return true if an IP address string falls in a blocked (non-public) range.
|
|
20
|
-
*/
|
|
21
|
-
export declare function isBlockedIp(ip: string): boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Validate that a URL targets a public host. Resolves DNS and checks every
|
|
24
|
-
* returned address. Throws {@link SsrfError} on any violation.
|
|
25
|
-
*
|
|
26
|
-
* @returns the resolved public IP and address family for connection pinning.
|
|
27
|
-
*/
|
|
28
|
-
export declare function assertPublicUrl(rawUrl: string): Promise<{
|
|
29
|
-
url: URL;
|
|
30
|
-
address: string;
|
|
31
|
-
family: number;
|
|
32
|
-
}>;
|
|
33
|
-
/**
|
|
34
|
-
* Fetch a URL with SSRF protection, following up to `maxRedirects` redirects
|
|
35
|
-
* and re-validating each hop. Returns the final Response.
|
|
36
|
-
*
|
|
37
|
-
* Note: Node's global fetch resolves DNS itself, so there is a small TOCTOU
|
|
38
|
-
* gap between our lookup and the connect. The network-level egress allowlist
|
|
39
|
-
* (see deploy/harden-egress.sh) is the backstop for that residual risk.
|
|
40
|
-
*/
|
|
41
|
-
export declare function safeFetch(rawUrl: string, init?: RequestInit & {
|
|
42
|
-
timeoutMs?: number;
|
|
43
|
-
}, maxRedirects?: number): Promise<Response>;
|
package/dist/cloud/ssrf.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SSRF protection for user-supplied URLs.
|
|
3
|
-
*
|
|
4
|
-
* Before the backend fetches a spec URL or crawls a website on behalf of a
|
|
5
|
-
* user, we must ensure the target is a genuinely public host. Otherwise an
|
|
6
|
-
* attacker could point us at internal services, the cloud metadata endpoint
|
|
7
|
-
* (169.254.169.254), or other private infrastructure.
|
|
8
|
-
*
|
|
9
|
-
* Guards:
|
|
10
|
-
* - protocol must be http/https
|
|
11
|
-
* - the hostname's resolved IP(s) must all be public (no loopback,
|
|
12
|
-
* private, link-local, CGNAT, unique-local, etc.)
|
|
13
|
-
* - redirects are followed manually and each hop is re-validated
|
|
14
|
-
*/
|
|
15
|
-
import { lookup } from 'node:dns/promises';
|
|
16
|
-
import { isIP } from 'node:net';
|
|
17
|
-
export class SsrfError extends Error {
|
|
18
|
-
constructor(message) {
|
|
19
|
-
super(message);
|
|
20
|
-
this.name = 'SsrfError';
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Return true if an IP address string falls in a blocked (non-public) range.
|
|
25
|
-
*/
|
|
26
|
-
export function isBlockedIp(ip) {
|
|
27
|
-
const family = isIP(ip);
|
|
28
|
-
if (family === 4)
|
|
29
|
-
return isBlockedIpv4(ip);
|
|
30
|
-
if (family === 6)
|
|
31
|
-
return isBlockedIpv6(ip);
|
|
32
|
-
return true; // not a valid IP — refuse
|
|
33
|
-
}
|
|
34
|
-
function isBlockedIpv4(ip) {
|
|
35
|
-
const parts = ip.split('.').map((p) => parseInt(p, 10));
|
|
36
|
-
if (parts.length !== 4 || parts.some((p) => Number.isNaN(p) || p < 0 || p > 255))
|
|
37
|
-
return true;
|
|
38
|
-
const [a, b] = parts;
|
|
39
|
-
if (a === 0)
|
|
40
|
-
return true; // 0.0.0.0/8 "this host"
|
|
41
|
-
if (a === 10)
|
|
42
|
-
return true; // 10.0.0.0/8 private
|
|
43
|
-
if (a === 127)
|
|
44
|
-
return true; // 127.0.0.0/8 loopback
|
|
45
|
-
if (a === 169 && b === 254)
|
|
46
|
-
return true; // 169.254.0.0/16 link-local incl. cloud metadata
|
|
47
|
-
if (a === 172 && b >= 16 && b <= 31)
|
|
48
|
-
return true; // 172.16.0.0/12 private
|
|
49
|
-
if (a === 192 && b === 168)
|
|
50
|
-
return true; // 192.168.0.0/16 private
|
|
51
|
-
if (a === 100 && b >= 64 && b <= 127)
|
|
52
|
-
return true; // 100.64.0.0/10 CGNAT
|
|
53
|
-
if (a === 192 && b === 0)
|
|
54
|
-
return true; // 192.0.0.0/24 + 192.0.2.0/24 special-use
|
|
55
|
-
if (a === 198 && (b === 18 || b === 19))
|
|
56
|
-
return true; // 198.18.0.0/15 benchmarking
|
|
57
|
-
if (a >= 224)
|
|
58
|
-
return true; // 224.0.0.0/4 multicast + 240.0.0.0/4 reserved
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
function isBlockedIpv6(ip) {
|
|
62
|
-
const lower = ip.toLowerCase();
|
|
63
|
-
// IPv4-mapped (::ffff:a.b.c.d) — validate the embedded IPv4
|
|
64
|
-
const mapped = lower.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
|
|
65
|
-
if (mapped)
|
|
66
|
-
return isBlockedIpv4(mapped[1]);
|
|
67
|
-
if (lower === '::1' || lower === '::')
|
|
68
|
-
return true; // loopback / unspecified
|
|
69
|
-
if (lower.startsWith('fe80'))
|
|
70
|
-
return true; // link-local
|
|
71
|
-
if (lower.startsWith('fc') || lower.startsWith('fd'))
|
|
72
|
-
return true; // fc00::/7 unique-local
|
|
73
|
-
if (lower.startsWith('ff'))
|
|
74
|
-
return true; // multicast
|
|
75
|
-
if (lower.startsWith('::ffff:'))
|
|
76
|
-
return true; // other v4-mapped forms — refuse
|
|
77
|
-
if (lower.startsWith('2001:db8'))
|
|
78
|
-
return true; // documentation
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Validate that a URL targets a public host. Resolves DNS and checks every
|
|
83
|
-
* returned address. Throws {@link SsrfError} on any violation.
|
|
84
|
-
*
|
|
85
|
-
* @returns the resolved public IP and address family for connection pinning.
|
|
86
|
-
*/
|
|
87
|
-
export async function assertPublicUrl(rawUrl) {
|
|
88
|
-
let url;
|
|
89
|
-
try {
|
|
90
|
-
url = new URL(rawUrl);
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
throw new SsrfError('Invalid URL');
|
|
94
|
-
}
|
|
95
|
-
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
96
|
-
throw new SsrfError(`Unsupported protocol: ${url.protocol}`);
|
|
97
|
-
}
|
|
98
|
-
const hostname = url.hostname.replace(/^\[|\]$/g, ''); // strip IPv6 brackets
|
|
99
|
-
// Literal IP — check directly.
|
|
100
|
-
if (isIP(hostname)) {
|
|
101
|
-
if (isBlockedIp(hostname)) {
|
|
102
|
-
throw new SsrfError(`Blocked non-public address: ${hostname}`);
|
|
103
|
-
}
|
|
104
|
-
return { url, address: hostname, family: isIP(hostname) };
|
|
105
|
-
}
|
|
106
|
-
// Hostname — resolve ALL addresses and ensure every one is public.
|
|
107
|
-
let addresses;
|
|
108
|
-
try {
|
|
109
|
-
addresses = await lookup(hostname, { all: true });
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
throw new SsrfError(`Could not resolve host: ${hostname}`);
|
|
113
|
-
}
|
|
114
|
-
if (addresses.length === 0) {
|
|
115
|
-
throw new SsrfError(`Host did not resolve: ${hostname}`);
|
|
116
|
-
}
|
|
117
|
-
for (const addr of addresses) {
|
|
118
|
-
if (isBlockedIp(addr.address)) {
|
|
119
|
-
throw new SsrfError(`Host ${hostname} resolves to a blocked address: ${addr.address}`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return { url, address: addresses[0].address, family: addresses[0].family };
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Fetch a URL with SSRF protection, following up to `maxRedirects` redirects
|
|
126
|
-
* and re-validating each hop. Returns the final Response.
|
|
127
|
-
*
|
|
128
|
-
* Note: Node's global fetch resolves DNS itself, so there is a small TOCTOU
|
|
129
|
-
* gap between our lookup and the connect. The network-level egress allowlist
|
|
130
|
-
* (see deploy/harden-egress.sh) is the backstop for that residual risk.
|
|
131
|
-
*/
|
|
132
|
-
export async function safeFetch(rawUrl, init = {}, maxRedirects = 5) {
|
|
133
|
-
const { timeoutMs = 15_000, ...rest } = init;
|
|
134
|
-
let current = rawUrl;
|
|
135
|
-
for (let hop = 0; hop <= maxRedirects; hop++) {
|
|
136
|
-
await assertPublicUrl(current);
|
|
137
|
-
const res = await fetch(current, {
|
|
138
|
-
...rest,
|
|
139
|
-
redirect: 'manual',
|
|
140
|
-
signal: rest.signal ?? AbortSignal.timeout(timeoutMs),
|
|
141
|
-
});
|
|
142
|
-
if (res.status >= 300 && res.status < 400 && res.headers.has('location')) {
|
|
143
|
-
const location = res.headers.get('location');
|
|
144
|
-
current = new URL(location, current).toString();
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
return res;
|
|
148
|
-
}
|
|
149
|
-
throw new SsrfError(`Too many redirects (>${maxRedirects})`);
|
|
150
|
-
}
|
package/dist/cloud/store.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory server metadata store (MVP).
|
|
3
|
-
* Will be replaced with Postgres in a later phase.
|
|
4
|
-
*/
|
|
5
|
-
export interface ServerRecord {
|
|
6
|
-
slug: string;
|
|
7
|
-
userId?: string;
|
|
8
|
-
specHash: string;
|
|
9
|
-
containerId: string;
|
|
10
|
-
port: number;
|
|
11
|
-
bearerToken: string;
|
|
12
|
-
status: 'building' | 'running' | 'stopped' | 'error';
|
|
13
|
-
toolCount: number;
|
|
14
|
-
/** Type of MCP server: 'http' for API proxies, 'playwright' for website scrapers. Defaults to 'http'. */
|
|
15
|
-
serverType?: 'http' | 'playwright';
|
|
16
|
-
createdAt: string;
|
|
17
|
-
lastActiveAt: string;
|
|
18
|
-
}
|
|
19
|
-
export declare class ServerStore {
|
|
20
|
-
private servers;
|
|
21
|
-
create(record: ServerRecord): void;
|
|
22
|
-
get(slug: string): ServerRecord | undefined;
|
|
23
|
-
list(): ServerRecord[];
|
|
24
|
-
update(slug: string, updates: Partial<ServerRecord>): void;
|
|
25
|
-
delete(slug: string): void;
|
|
26
|
-
findByPort(port: number): ServerRecord | undefined;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Port allocator for assigning host ports to containers.
|
|
30
|
-
* Allocates from a configurable range (default 4000-4999).
|
|
31
|
-
*/
|
|
32
|
-
export declare class PortAllocator {
|
|
33
|
-
private readonly minPort;
|
|
34
|
-
private readonly maxPort;
|
|
35
|
-
private allocated;
|
|
36
|
-
private nextCandidate;
|
|
37
|
-
constructor(minPort?: number, maxPort?: number);
|
|
38
|
-
allocate(): number;
|
|
39
|
-
release(port: number): void;
|
|
40
|
-
get allocatedCount(): number;
|
|
41
|
-
}
|
package/dist/cloud/store.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory server metadata store (MVP).
|
|
3
|
-
* Will be replaced with Postgres in a later phase.
|
|
4
|
-
*/
|
|
5
|
-
export class ServerStore {
|
|
6
|
-
servers = new Map();
|
|
7
|
-
create(record) {
|
|
8
|
-
if (this.servers.has(record.slug)) {
|
|
9
|
-
throw new Error(`Server with slug "${record.slug}" already exists`);
|
|
10
|
-
}
|
|
11
|
-
// Default serverType to 'http' for backwards compatibility
|
|
12
|
-
this.servers.set(record.slug, { serverType: 'http', ...record });
|
|
13
|
-
}
|
|
14
|
-
get(slug) {
|
|
15
|
-
const record = this.servers.get(slug);
|
|
16
|
-
return record ? { ...record } : undefined;
|
|
17
|
-
}
|
|
18
|
-
list() {
|
|
19
|
-
return [...this.servers.values()].map((r) => ({ ...r }));
|
|
20
|
-
}
|
|
21
|
-
update(slug, updates) {
|
|
22
|
-
const existing = this.servers.get(slug);
|
|
23
|
-
if (!existing) {
|
|
24
|
-
throw new Error(`Server with slug "${slug}" not found`);
|
|
25
|
-
}
|
|
26
|
-
// Prevent changing the slug via update
|
|
27
|
-
const { slug: _ignored, ...safeUpdates } = updates;
|
|
28
|
-
this.servers.set(slug, { ...existing, ...safeUpdates });
|
|
29
|
-
}
|
|
30
|
-
delete(slug) {
|
|
31
|
-
this.servers.delete(slug);
|
|
32
|
-
}
|
|
33
|
-
findByPort(port) {
|
|
34
|
-
for (const record of this.servers.values()) {
|
|
35
|
-
if (record.port === port) {
|
|
36
|
-
return { ...record };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Port allocator for assigning host ports to containers.
|
|
44
|
-
* Allocates from a configurable range (default 4000-4999).
|
|
45
|
-
*/
|
|
46
|
-
export class PortAllocator {
|
|
47
|
-
minPort;
|
|
48
|
-
maxPort;
|
|
49
|
-
allocated = new Set();
|
|
50
|
-
nextCandidate;
|
|
51
|
-
constructor(minPort = 4000, maxPort = 4999) {
|
|
52
|
-
this.minPort = minPort;
|
|
53
|
-
this.maxPort = maxPort;
|
|
54
|
-
this.nextCandidate = minPort;
|
|
55
|
-
}
|
|
56
|
-
allocate() {
|
|
57
|
-
const range = this.maxPort - this.minPort + 1;
|
|
58
|
-
// Try sequential allocation first for simplicity
|
|
59
|
-
for (let attempts = 0; attempts < range; attempts++) {
|
|
60
|
-
const port = this.nextCandidate;
|
|
61
|
-
this.nextCandidate = this.minPort + ((this.nextCandidate - this.minPort + 1) % range);
|
|
62
|
-
if (!this.allocated.has(port)) {
|
|
63
|
-
this.allocated.add(port);
|
|
64
|
-
return port;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
throw new Error(`No available ports in range ${this.minPort}-${this.maxPort} (${this.allocated.size} allocated)`);
|
|
68
|
-
}
|
|
69
|
-
release(port) {
|
|
70
|
-
this.allocated.delete(port);
|
|
71
|
-
}
|
|
72
|
-
get allocatedCount() {
|
|
73
|
-
return this.allocated.size;
|
|
74
|
-
}
|
|
75
|
-
}
|
package/dist/cloud/stripe.d.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stripe payment integration.
|
|
3
|
-
*
|
|
4
|
-
* Optional module — if STRIPE_SECRET_KEY is not set, all functions return
|
|
5
|
-
* null or throw descriptive errors. Uses dynamic import for the `stripe`
|
|
6
|
-
* package to avoid a hard dependency (same pattern as `pg`).
|
|
7
|
-
*
|
|
8
|
-
* Environment variables:
|
|
9
|
-
* STRIPE_SECRET_KEY — Stripe secret API key
|
|
10
|
-
* STRIPE_WEBHOOK_SECRET — Webhook endpoint signing secret
|
|
11
|
-
* STRIPE_PRICE_HOBBYIST — Price ID for the Hobbyist plan
|
|
12
|
-
* STRIPE_PRICE_PRO — Price ID for the Pro plan
|
|
13
|
-
* STRIPE_PRICE_TEAM — Price ID for the Team plan
|
|
14
|
-
*/
|
|
15
|
-
/** Minimal subset of the Stripe SDK we actually use. */
|
|
16
|
-
interface StripeClient {
|
|
17
|
-
checkout: {
|
|
18
|
-
sessions: {
|
|
19
|
-
create(params: Record<string, unknown>): Promise<{
|
|
20
|
-
url: string | null;
|
|
21
|
-
}>;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
billingPortal: {
|
|
25
|
-
sessions: {
|
|
26
|
-
create(params: Record<string, unknown>): Promise<{
|
|
27
|
-
url: string;
|
|
28
|
-
}>;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
webhooks: {
|
|
32
|
-
constructEvent(payload: Buffer | string, sig: string, secret: string): unknown;
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
export declare const PLAN_PRICE_IDS: Record<string, string>;
|
|
36
|
-
/**
|
|
37
|
-
* Get a configured Stripe client. Returns `null` when STRIPE_SECRET_KEY
|
|
38
|
-
* is not set. Caches the instance after first successful creation.
|
|
39
|
-
*/
|
|
40
|
-
export declare function getStripeClient(): Promise<StripeClient | null>;
|
|
41
|
-
/**
|
|
42
|
-
* Returns true when Stripe is configured (secret key is present).
|
|
43
|
-
* Does NOT load the Stripe SDK — just checks the env var.
|
|
44
|
-
*/
|
|
45
|
-
export declare function isStripeConfigured(): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Create a Stripe Checkout session for a plan upgrade.
|
|
48
|
-
*
|
|
49
|
-
* @returns The checkout session URL to redirect the user to.
|
|
50
|
-
* @throws If Stripe is not configured or the plan has no price ID.
|
|
51
|
-
*/
|
|
52
|
-
export declare function createCheckoutSession(opts: {
|
|
53
|
-
userId: string;
|
|
54
|
-
email: string;
|
|
55
|
-
plan: string;
|
|
56
|
-
successUrl: string;
|
|
57
|
-
cancelUrl: string;
|
|
58
|
-
}): Promise<string>;
|
|
59
|
-
/**
|
|
60
|
-
* Create a Stripe billing portal session so the customer can manage
|
|
61
|
-
* their subscription (cancel, change payment method, view invoices).
|
|
62
|
-
*
|
|
63
|
-
* @returns The portal session URL to redirect the user to.
|
|
64
|
-
*/
|
|
65
|
-
export declare function createPortalSession(customerId: string, returnUrl: string): Promise<string>;
|
|
66
|
-
/**
|
|
67
|
-
* Verify and handle an incoming Stripe webhook event.
|
|
68
|
-
*
|
|
69
|
-
* Handles:
|
|
70
|
-
* - checkout.session.completed — activate subscription, store customer ID
|
|
71
|
-
* - customer.subscription.updated — plan change / renewal
|
|
72
|
-
* - customer.subscription.deleted — cancellation, downgrade to free
|
|
73
|
-
*
|
|
74
|
-
* @param payload - The raw request body as a Buffer (required for signature verification)
|
|
75
|
-
* @param signature - The `stripe-signature` header value
|
|
76
|
-
*/
|
|
77
|
-
export declare function handleWebhookEvent(payload: Buffer, signature: string): Promise<void>;
|
|
78
|
-
export {};
|