mcpmake 0.1.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/README.md +691 -0
- package/bin/mcpmake.mjs +2 -0
- package/dist/analyzer/auth-detector.d.ts +12 -0
- package/dist/analyzer/auth-detector.js +142 -0
- package/dist/analyzer/dom-parser.d.ts +10 -0
- package/dist/analyzer/dom-parser.js +259 -0
- package/dist/analyzer/goal-crawler.d.ts +25 -0
- package/dist/analyzer/goal-crawler.js +177 -0
- package/dist/analyzer/hybrid-detector.d.ts +28 -0
- package/dist/analyzer/hybrid-detector.js +96 -0
- package/dist/analyzer/index.d.ts +12 -0
- package/dist/analyzer/index.js +8 -0
- package/dist/analyzer/screenshot-capture.d.ts +29 -0
- package/dist/analyzer/screenshot-capture.js +42 -0
- package/dist/analyzer/selector-builder.d.ts +19 -0
- package/dist/analyzer/selector-builder.js +199 -0
- package/dist/analyzer/semantic-analyzer.d.ts +13 -0
- package/dist/analyzer/semantic-analyzer.js +145 -0
- package/dist/analyzer/site-crawler.d.ts +38 -0
- package/dist/analyzer/site-crawler.js +235 -0
- package/dist/cloud/billing/billing-engine.d.ts +44 -0
- package/dist/cloud/billing/billing-engine.js +81 -0
- package/dist/cloud/billing/credit-store.d.ts +64 -0
- package/dist/cloud/billing/credit-store.js +168 -0
- package/dist/cloud/billing/index.d.ts +4 -0
- package/dist/cloud/billing/index.js +2 -0
- package/dist/cloud/billing/usage-store.d.ts +42 -0
- package/dist/cloud/billing/usage-store.js +85 -0
- package/dist/cloud/billing/usage-tracker.d.ts +38 -0
- package/dist/cloud/billing/usage-tracker.js +95 -0
- package/dist/cloud/build-pipeline.d.ts +39 -0
- package/dist/cloud/build-pipeline.js +310 -0
- package/dist/cloud/build-queue.d.ts +30 -0
- package/dist/cloud/build-queue.js +70 -0
- package/dist/cloud/caddy-manager.d.ts +18 -0
- package/dist/cloud/caddy-manager.js +97 -0
- package/dist/cloud/container-backend.d.ts +62 -0
- package/dist/cloud/container-backend.js +59 -0
- package/dist/cloud/container-manager.d.ts +64 -0
- package/dist/cloud/container-manager.js +301 -0
- package/dist/cloud/crypto.d.ts +27 -0
- package/dist/cloud/crypto.js +63 -0
- package/dist/cloud/db/index.d.ts +27 -0
- package/dist/cloud/db/index.js +53 -0
- package/dist/cloud/db/migrations.d.ts +12 -0
- package/dist/cloud/db/migrations.js +329 -0
- package/dist/cloud/db/pg-store.d.ts +45 -0
- package/dist/cloud/db/pg-store.js +336 -0
- package/dist/cloud/failure-tracker.d.ts +51 -0
- package/dist/cloud/failure-tracker.js +102 -0
- package/dist/cloud/idle-monitor.d.ts +30 -0
- package/dist/cloud/idle-monitor.js +70 -0
- package/dist/cloud/mailer.d.ts +21 -0
- package/dist/cloud/mailer.js +193 -0
- package/dist/cloud/mcp-proxy.d.ts +58 -0
- package/dist/cloud/mcp-proxy.js +203 -0
- package/dist/cloud/metric-samples.d.ts +43 -0
- package/dist/cloud/metric-samples.js +85 -0
- package/dist/cloud/metrics.d.ts +26 -0
- package/dist/cloud/metrics.js +59 -0
- package/dist/cloud/multipart.d.ts +26 -0
- package/dist/cloud/multipart.js +132 -0
- package/dist/cloud/observability.d.ts +27 -0
- package/dist/cloud/observability.js +98 -0
- package/dist/cloud/rate-limiter.d.ts +31 -0
- package/dist/cloud/rate-limiter.js +58 -0
- package/dist/cloud/request-security.d.ts +5 -0
- package/dist/cloud/request-security.js +74 -0
- package/dist/cloud/resource-monitor.d.ts +69 -0
- package/dist/cloud/resource-monitor.js +130 -0
- package/dist/cloud/secret-store.d.ts +38 -0
- package/dist/cloud/secret-store.js +103 -0
- package/dist/cloud/security.d.ts +26 -0
- package/dist/cloud/security.js +142 -0
- package/dist/cloud/server.d.ts +21 -0
- package/dist/cloud/server.js +1079 -0
- package/dist/cloud/shared-state.d.ts +72 -0
- package/dist/cloud/shared-state.js +159 -0
- package/dist/cloud/ssrf.d.ts +43 -0
- package/dist/cloud/ssrf.js +150 -0
- package/dist/cloud/store.d.ts +41 -0
- package/dist/cloud/store.js +75 -0
- package/dist/cloud/stripe.d.ts +78 -0
- package/dist/cloud/stripe.js +317 -0
- package/dist/cloud/telemetry-store.d.ts +53 -0
- package/dist/cloud/telemetry-store.js +108 -0
- package/dist/cloud/web/auth.d.ts +225 -0
- package/dist/cloud/web/auth.js +555 -0
- package/dist/cloud/web/charts.d.ts +70 -0
- package/dist/cloud/web/charts.js +178 -0
- package/dist/cloud/web/csrf.d.ts +14 -0
- package/dist/cloud/web/csrf.js +22 -0
- package/dist/cloud/web/docs.d.ts +40 -0
- package/dist/cloud/web/docs.js +174 -0
- package/dist/cloud/web/router.d.ts +25 -0
- package/dist/cloud/web/router.js +1921 -0
- package/dist/cloud/web/static/alpine.min.js +5 -0
- package/dist/cloud/web/static/favicon.svg +4 -0
- package/dist/cloud/web/static/htmx-sse.js +290 -0
- package/dist/cloud/web/static/htmx.min.js +1 -0
- package/dist/cloud/web/static/style.css +2683 -0
- package/dist/cloud/web/static-server.d.ts +13 -0
- package/dist/cloud/web/static-server.js +73 -0
- package/dist/cloud/web/template-engine.d.ts +27 -0
- package/dist/cloud/web/template-engine.js +146 -0
- package/dist/cloud/web/templates/layouts/admin.hbs +57 -0
- package/dist/cloud/web/templates/layouts/auth.hbs +138 -0
- package/dist/cloud/web/templates/layouts/base.hbs +16 -0
- package/dist/cloud/web/templates/layouts/dashboard.hbs +39 -0
- package/dist/cloud/web/templates/layouts/landing.hbs +82 -0
- package/dist/cloud/web/templates/pages/admin/overview.hbs +123 -0
- package/dist/cloud/web/templates/pages/admin/servers.hbs +129 -0
- package/dist/cloud/web/templates/pages/admin/telemetry.hbs +39 -0
- package/dist/cloud/web/templates/pages/admin/user-edit.hbs +91 -0
- package/dist/cloud/web/templates/pages/admin/users.hbs +179 -0
- package/dist/cloud/web/templates/pages/auth/forgot-password.hbs +25 -0
- package/dist/cloud/web/templates/pages/auth/login.hbs +33 -0
- package/dist/cloud/web/templates/pages/auth/register.hbs +32 -0
- package/dist/cloud/web/templates/pages/auth/reset-password.hbs +34 -0
- package/dist/cloud/web/templates/pages/dashboard/billing.hbs +140 -0
- package/dist/cloud/web/templates/pages/dashboard/create.hbs +173 -0
- package/dist/cloud/web/templates/pages/dashboard/index.hbs +8 -0
- package/dist/cloud/web/templates/pages/dashboard/server-detail.hbs +280 -0
- package/dist/cloud/web/templates/pages/dashboard/server-logs.hbs +35 -0
- package/dist/cloud/web/templates/pages/dashboard/server-metrics.hbs +63 -0
- package/dist/cloud/web/templates/pages/dashboard/servers-partial.hbs +21 -0
- package/dist/cloud/web/templates/pages/dashboard/servers.hbs +44 -0
- package/dist/cloud/web/templates/pages/docs/show.hbs +16 -0
- package/dist/cloud/web/templates/pages/errors/404.hbs +9 -0
- package/dist/cloud/web/templates/pages/errors/500.hbs +8 -0
- package/dist/cloud/web/templates/pages/landing/index.hbs +223 -0
- package/dist/cloud/web/templates/pages/legal/privacy.hbs +71 -0
- package/dist/cloud/web/templates/pages/legal/terms.hbs +73 -0
- package/dist/cloud/web/templates/partials/admin-stats.hbs +52 -0
- package/dist/cloud/web/templates/partials/flash-message.hbs +6 -0
- package/dist/cloud/web/templates/partials/pricing-table.hbs +103 -0
- package/dist/cloud/web/templates/partials/server-card.hbs +19 -0
- package/dist/cloud/web/templates/partials/status-badge.hbs +1 -0
- package/dist/commands/bundle.d.ts +18 -0
- package/dist/commands/bundle.js +82 -0
- package/dist/commands/ci.d.ts +25 -0
- package/dist/commands/ci.js +149 -0
- package/dist/commands/deploy.d.ts +24 -0
- package/dist/commands/deploy.js +145 -0
- package/dist/commands/diff.d.ts +18 -0
- package/dist/commands/diff.js +185 -0
- package/dist/commands/from/describe.d.ts +65 -0
- package/dist/commands/from/describe.js +173 -0
- package/dist/commands/from/har.d.ts +81 -0
- package/dist/commands/from/har.js +255 -0
- package/dist/commands/from/openapi.d.ts +105 -0
- package/dist/commands/from/openapi.js +302 -0
- package/dist/commands/from/postman.d.ts +51 -0
- package/dist/commands/from/postman.js +146 -0
- package/dist/commands/from/target-support.d.ts +11 -0
- package/dist/commands/from/target-support.js +33 -0
- package/dist/commands/from/url.d.ts +75 -0
- package/dist/commands/from/url.js +244 -0
- package/dist/commands/from/website.d.ts +75 -0
- package/dist/commands/from/website.js +284 -0
- package/dist/commands/lint.d.ts +24 -0
- package/dist/commands/lint.js +184 -0
- package/dist/commands/merge.d.ts +18 -0
- package/dist/commands/merge.js +161 -0
- package/dist/commands/publish.d.ts +27 -0
- package/dist/commands/publish.js +334 -0
- package/dist/commands/rescan.d.ts +40 -0
- package/dist/commands/rescan.js +255 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.js +87 -0
- package/dist/commands/verify.d.ts +14 -0
- package/dist/commands/verify.js +71 -0
- package/dist/config/configurable-command.d.ts +13 -0
- package/dist/config/configurable-command.js +70 -0
- package/dist/config/mcpmake-config.d.ts +68 -0
- package/dist/config/mcpmake-config.js +207 -0
- package/dist/docs/cli.md +400 -0
- package/dist/docs/mcp-2026-07-28-migration.md +78 -0
- package/dist/docs/migrate-from-stainless.md +94 -0
- package/dist/docs/quickstart.md +166 -0
- package/dist/docs/show-hn.md +26 -0
- package/dist/docs/website-servers.md +169 -0
- package/dist/emitter/code-writer.d.ts +8 -0
- package/dist/emitter/code-writer.js +25 -0
- package/dist/emitter/index.d.ts +32 -0
- package/dist/emitter/index.js +280 -0
- package/dist/emitter/mcpb-bundler.d.ts +31 -0
- package/dist/emitter/mcpb-bundler.js +172 -0
- package/dist/emitter/project-scaffolder.d.ts +4 -0
- package/dist/emitter/project-scaffolder.js +89 -0
- package/dist/emitter/python-template-loader.d.ts +4 -0
- package/dist/emitter/python-template-loader.js +30 -0
- package/dist/emitter/python-templates/dockerfile.hbs +14 -0
- package/dist/emitter/python-templates/env.example.hbs +6 -0
- package/dist/emitter/python-templates/requirements.txt.hbs +4 -0
- package/dist/emitter/python-templates/server.py.hbs +77 -0
- package/dist/emitter/site-scaffolder.d.ts +13 -0
- package/dist/emitter/site-scaffolder.js +70 -0
- package/dist/emitter/site-template-loader.d.ts +5 -0
- package/dist/emitter/site-template-loader.js +47 -0
- package/dist/emitter/site-templates/browser-manager.ts.hbs +233 -0
- package/dist/emitter/site-templates/config.ts.hbs +28 -0
- package/dist/emitter/site-templates/dockerfile.hbs +31 -0
- package/dist/emitter/site-templates/env.example.hbs +19 -0
- package/dist/emitter/site-templates/package.json.hbs +26 -0
- package/dist/emitter/site-templates/server-main-http.ts.hbs +108 -0
- package/dist/emitter/site-templates/server-main.ts.hbs +23 -0
- package/dist/emitter/site-templates/tool-handler-action.ts.hbs +86 -0
- package/dist/emitter/site-templates/tool-handler-form.ts.hbs +116 -0
- package/dist/emitter/site-templates/tool-handler-lifecycle.ts.hbs +146 -0
- package/dist/emitter/site-templates/tool-index.ts.hbs +11 -0
- package/dist/emitter/template-loader.d.ts +1 -0
- package/dist/emitter/template-loader.js +27 -0
- package/dist/emitter/templates/auth-provider.ts.hbs +57 -0
- package/dist/emitter/templates/config.ts.hbs +63 -0
- package/dist/emitter/templates/discovery.ts.hbs +301 -0
- package/dist/emitter/templates/dockerfile.hbs +34 -0
- package/dist/emitter/templates/env.example.hbs +28 -0
- package/dist/emitter/templates/gitignore.hbs +5 -0
- package/dist/emitter/templates/http-executor.ts.hbs +117 -0
- package/dist/emitter/templates/oauth.ts.hbs +188 -0
- package/dist/emitter/templates/package.json.hbs +25 -0
- package/dist/emitter/templates/prompts.ts.hbs +22 -0
- package/dist/emitter/templates/readme.md.hbs +123 -0
- package/dist/emitter/templates/resources.ts.hbs +63 -0
- package/dist/emitter/templates/server-main-http.ts.hbs +407 -0
- package/dist/emitter/templates/server-main.ts.hbs +40 -0
- package/dist/emitter/templates/task-handlers.ts.hbs +189 -0
- package/dist/emitter/templates/task-manager.ts.hbs +139 -0
- package/dist/emitter/templates/task-sse.ts.hbs +105 -0
- package/dist/emitter/templates/tool-handler.ts.hbs +124 -0
- package/dist/emitter/templates/tool-index.ts.hbs +11 -0
- package/dist/emitter/templates/tool-test.ts.hbs +57 -0
- package/dist/emitter/templates/trace.ts.hbs +79 -0
- package/dist/emitter/templates/tsconfig.json.hbs +16 -0
- package/dist/emitter/templates/types.ts.hbs +5 -0
- package/dist/emitter/worker-template-loader.d.ts +5 -0
- package/dist/emitter/worker-template-loader.js +33 -0
- package/dist/emitter/worker-templates/config.ts.hbs +54 -0
- package/dist/emitter/worker-templates/dev-vars.example.hbs +10 -0
- package/dist/emitter/worker-templates/gitignore.hbs +6 -0
- package/dist/emitter/worker-templates/package.json.hbs +24 -0
- package/dist/emitter/worker-templates/readme.md.hbs +53 -0
- package/dist/emitter/worker-templates/server.test.ts.hbs +20 -0
- package/dist/emitter/worker-templates/tool-handler.ts.hbs +85 -0
- package/dist/emitter/worker-templates/tool-index.ts.hbs +28 -0
- package/dist/emitter/worker-templates/tsconfig.json.hbs +17 -0
- package/dist/emitter/worker-templates/worker.ts.hbs +242 -0
- package/dist/emitter/worker-templates/wrangler.toml.hbs +19 -0
- package/dist/generator/spec-generator.d.ts +6 -0
- package/dist/generator/spec-generator.js +50 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +64 -0
- package/dist/parser/har-filter.d.ts +8 -0
- package/dist/parser/har-filter.js +71 -0
- package/dist/parser/har-loader.d.ts +2 -0
- package/dist/parser/har-loader.js +14 -0
- package/dist/parser/har-normalizer.d.ts +20 -0
- package/dist/parser/har-normalizer.js +78 -0
- package/dist/parser/index.d.ts +10 -0
- package/dist/parser/index.js +6 -0
- package/dist/parser/openapi-loader.d.ts +6 -0
- package/dist/parser/openapi-loader.js +308 -0
- package/dist/parser/operation-extractor.d.ts +13 -0
- package/dist/parser/operation-extractor.js +155 -0
- package/dist/parser/overlay-loader.d.ts +10 -0
- package/dist/parser/overlay-loader.js +184 -0
- package/dist/parser/postman-loader.d.ts +9 -0
- package/dist/parser/postman-loader.js +106 -0
- package/dist/parser/schema-converter.d.ts +12 -0
- package/dist/parser/schema-converter.js +117 -0
- package/dist/plugins/adapter.d.ts +40 -0
- package/dist/plugins/adapter.js +15 -0
- package/dist/plugins/loader.d.ts +25 -0
- package/dist/plugins/loader.js +58 -0
- package/dist/pricing.d.ts +55 -0
- package/dist/pricing.js +133 -0
- package/dist/providers/index.d.ts +15 -0
- package/dist/providers/index.js +56 -0
- package/dist/recorder/browser-recorder.d.ts +22 -0
- package/dist/recorder/browser-recorder.js +205 -0
- package/dist/registry/official-registry.d.ts +90 -0
- package/dist/registry/official-registry.js +129 -0
- package/dist/rescan/diff-engine.d.ts +5 -0
- package/dist/rescan/diff-engine.js +312 -0
- package/dist/rescan/index.d.ts +3 -0
- package/dist/rescan/index.js +2 -0
- package/dist/rescan/rescan-runner.d.ts +42 -0
- package/dist/rescan/rescan-runner.js +69 -0
- package/dist/rescan/rescan-scheduler.d.ts +41 -0
- package/dist/rescan/rescan-scheduler.js +179 -0
- package/dist/site-transformer/browser-tools.d.ts +10 -0
- package/dist/site-transformer/browser-tools.js +59 -0
- package/dist/site-transformer/index.d.ts +2 -0
- package/dist/site-transformer/index.js +2 -0
- package/dist/site-transformer/selector-healer.d.ts +8 -0
- package/dist/site-transformer/selector-healer.js +106 -0
- package/dist/site-transformer/tool-generator.d.ts +13 -0
- package/dist/site-transformer/tool-generator.js +245 -0
- package/dist/transformer/auth-detector.d.ts +13 -0
- package/dist/transformer/auth-detector.js +90 -0
- package/dist/transformer/catalog-builder.d.ts +18 -0
- package/dist/transformer/catalog-builder.js +56 -0
- package/dist/transformer/client-compat.d.ts +6 -0
- package/dist/transformer/client-compat.js +44 -0
- package/dist/transformer/har-clusterer.d.ts +9 -0
- package/dist/transformer/har-clusterer.js +27 -0
- package/dist/transformer/har-dedup.d.ts +10 -0
- package/dist/transformer/har-dedup.js +81 -0
- package/dist/transformer/har-schema-inferrer.d.ts +15 -0
- package/dist/transformer/har-schema-inferrer.js +90 -0
- package/dist/transformer/har-to-operations.d.ts +13 -0
- package/dist/transformer/har-to-operations.js +192 -0
- package/dist/transformer/index.d.ts +8 -0
- package/dist/transformer/index.js +6 -0
- package/dist/transformer/llm-namer.d.ts +6 -0
- package/dist/transformer/llm-namer.js +59 -0
- package/dist/transformer/naming.d.ts +4 -0
- package/dist/transformer/naming.js +30 -0
- package/dist/transformer/operation-filter.d.ts +13 -0
- package/dist/transformer/operation-filter.js +52 -0
- package/dist/transformer/resource-builder.d.ts +12 -0
- package/dist/transformer/resource-builder.js +80 -0
- package/dist/transformer/schema-merger.d.ts +14 -0
- package/dist/transformer/schema-merger.js +65 -0
- package/dist/transformer/tool-builder.d.ts +3 -0
- package/dist/transformer/tool-builder.js +114 -0
- package/dist/types/index.d.ts +131 -0
- package/dist/types/index.js +1 -0
- package/dist/types/site.d.ts +284 -0
- package/dist/types/site.js +8 -0
- package/dist/utils/fail.d.ts +48 -0
- package/dist/utils/fail.js +204 -0
- package/dist/utils/fs.d.ts +5 -0
- package/dist/utils/fs.js +28 -0
- package/dist/utils/interactive.d.ts +6 -0
- package/dist/utils/interactive.js +30 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.js +2 -0
- package/dist/utils/sanitize.d.ts +28 -0
- package/dist/utils/sanitize.js +44 -0
- package/dist/utils/watcher.d.ts +11 -0
- package/dist/utils/watcher.js +36 -0
- package/package.json +65 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<div class="pricing-grid">
|
|
2
|
+
<!-- Free -->
|
|
3
|
+
<article class="pricing-card">
|
|
4
|
+
<div class="pricing-card-header">
|
|
5
|
+
<h3 class="pricing-tier-name">Free</h3>
|
|
6
|
+
<div class="pricing-amount"><span class="pricing-currency">$</span><span class="pricing-value">0</span><span class="pricing-period">/mo</span></div>
|
|
7
|
+
<p class="pricing-tagline">Get started instantly</p>
|
|
8
|
+
</div>
|
|
9
|
+
<ul class="pricing-features">
|
|
10
|
+
<li>1 MCP server</li>
|
|
11
|
+
<li>500 requests / month</li>
|
|
12
|
+
<li>8-hour idle shutdown</li>
|
|
13
|
+
<li>Community support</li>
|
|
14
|
+
</ul>
|
|
15
|
+
<div class="pricing-card-footer">
|
|
16
|
+
<a href="/register" class="btn btn-secondary btn-block">Get started</a>
|
|
17
|
+
<p class="pricing-note">No credit card required</p>
|
|
18
|
+
</div>
|
|
19
|
+
</article>
|
|
20
|
+
|
|
21
|
+
<!-- Hobbyist -->
|
|
22
|
+
<article class="pricing-card">
|
|
23
|
+
<div class="pricing-card-header">
|
|
24
|
+
<h3 class="pricing-tier-name">Hobbyist</h3>
|
|
25
|
+
<div class="pricing-amount"><span class="pricing-currency">$</span><span class="pricing-value">9</span><span class="pricing-period">/mo</span></div>
|
|
26
|
+
<p class="pricing-tagline">For side projects</p>
|
|
27
|
+
</div>
|
|
28
|
+
<ul class="pricing-features">
|
|
29
|
+
<li>5 MCP servers</li>
|
|
30
|
+
<li>10,000 requests / month</li>
|
|
31
|
+
<li>24-hour keep-alive</li>
|
|
32
|
+
<li>Email support</li>
|
|
33
|
+
</ul>
|
|
34
|
+
<div class="pricing-card-footer">
|
|
35
|
+
{{#if csrfToken}}
|
|
36
|
+
<form method="POST" action="/dashboard/billing/checkout">
|
|
37
|
+
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
|
38
|
+
<input type="hidden" name="plan" value="hobbyist">
|
|
39
|
+
<button type="submit" class="btn btn-secondary btn-block">Subscribe</button>
|
|
40
|
+
</form>
|
|
41
|
+
{{else}}
|
|
42
|
+
<a href="/register?plan=hobbyist" class="btn btn-secondary btn-block">Subscribe</a>
|
|
43
|
+
{{/if}}
|
|
44
|
+
</div>
|
|
45
|
+
</article>
|
|
46
|
+
|
|
47
|
+
<!-- Pro (featured) -->
|
|
48
|
+
<article class="pricing-card pricing-card--featured">
|
|
49
|
+
<div class="pricing-badge">Popular</div>
|
|
50
|
+
<div class="pricing-card-header">
|
|
51
|
+
<h3 class="pricing-tier-name">Pro</h3>
|
|
52
|
+
<div class="pricing-amount"><span class="pricing-currency">$</span><span class="pricing-value">29</span><span class="pricing-period">/mo</span></div>
|
|
53
|
+
<p class="pricing-tagline">For production APIs</p>
|
|
54
|
+
</div>
|
|
55
|
+
<ul class="pricing-features">
|
|
56
|
+
<li>20 MCP servers</li>
|
|
57
|
+
<li>100,000 requests / month</li>
|
|
58
|
+
<li>Always-on servers</li>
|
|
59
|
+
<li>Custom domain</li>
|
|
60
|
+
<li>90-day log retention</li>
|
|
61
|
+
<li>Priority support</li>
|
|
62
|
+
</ul>
|
|
63
|
+
<div class="pricing-card-footer">
|
|
64
|
+
{{#if csrfToken}}
|
|
65
|
+
<form method="POST" action="/dashboard/billing/checkout">
|
|
66
|
+
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
|
67
|
+
<input type="hidden" name="plan" value="pro">
|
|
68
|
+
<button type="submit" class="btn btn-primary btn-block">Subscribe</button>
|
|
69
|
+
</form>
|
|
70
|
+
{{else}}
|
|
71
|
+
<a href="/register?plan=pro" class="btn btn-primary btn-block">Subscribe</a>
|
|
72
|
+
{{/if}}
|
|
73
|
+
</div>
|
|
74
|
+
</article>
|
|
75
|
+
|
|
76
|
+
<!-- Team -->
|
|
77
|
+
<article class="pricing-card">
|
|
78
|
+
<div class="pricing-card-header">
|
|
79
|
+
<h3 class="pricing-tier-name">Team</h3>
|
|
80
|
+
<div class="pricing-amount"><span class="pricing-currency">$</span><span class="pricing-value">99</span><span class="pricing-period">/mo</span></div>
|
|
81
|
+
<p class="pricing-tagline">For organizations</p>
|
|
82
|
+
</div>
|
|
83
|
+
<ul class="pricing-features">
|
|
84
|
+
<li>Unlimited MCP servers</li>
|
|
85
|
+
<li>1,000,000 requests / month</li>
|
|
86
|
+
<li>Always-on servers</li>
|
|
87
|
+
<li>RBAC & workspaces</li>
|
|
88
|
+
<li>Audit logs</li>
|
|
89
|
+
<li>Dedicated support</li>
|
|
90
|
+
</ul>
|
|
91
|
+
<div class="pricing-card-footer">
|
|
92
|
+
{{#if csrfToken}}
|
|
93
|
+
<form method="POST" action="/dashboard/billing/checkout">
|
|
94
|
+
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
|
95
|
+
<input type="hidden" name="plan" value="team">
|
|
96
|
+
<button type="submit" class="btn btn-primary btn-block">Subscribe</button>
|
|
97
|
+
</form>
|
|
98
|
+
{{else}}
|
|
99
|
+
<a href="/register?plan=team" class="btn btn-secondary btn-block">Subscribe</a>
|
|
100
|
+
{{/if}}
|
|
101
|
+
</div>
|
|
102
|
+
</article>
|
|
103
|
+
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div class="server-card">
|
|
2
|
+
<div class="server-card-header">
|
|
3
|
+
<a href="/dashboard/servers/{{slug}}" class="server-card-name">{{slug}}</a>
|
|
4
|
+
{{> status-badge status=status}}
|
|
5
|
+
</div>
|
|
6
|
+
<div class="server-card-meta">
|
|
7
|
+
<span>{{toolCount}} tools</span>
|
|
8
|
+
<span>Last active: {{formatDate lastActiveAt}}</span>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="server-card-actions">
|
|
11
|
+
<a href="/dashboard/servers/{{slug}}" class="btn btn-sm btn-secondary">View</a>
|
|
12
|
+
<a href="/dashboard/servers/{{slug}}/logs" class="btn btn-sm btn-secondary">Logs</a>
|
|
13
|
+
<form method="POST" action="/dashboard/servers/{{slug}}/delete"
|
|
14
|
+
x-data x-on:submit.prevent="if(confirm('Delete server {{slug}}?')) $el.submit()">
|
|
15
|
+
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
|
16
|
+
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
|
|
17
|
+
</form>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<span class="status-badge status-{{status}}">{{status}}</span>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare const _default: import("citty").CommandDef<{
|
|
2
|
+
directory: {
|
|
3
|
+
type: "positional";
|
|
4
|
+
description: string;
|
|
5
|
+
required: true;
|
|
6
|
+
};
|
|
7
|
+
output: {
|
|
8
|
+
type: "string";
|
|
9
|
+
alias: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
'skip-build': {
|
|
13
|
+
type: "boolean";
|
|
14
|
+
description: string;
|
|
15
|
+
default: false;
|
|
16
|
+
};
|
|
17
|
+
}>;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { execFile as execFileCb } from 'node:child_process';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
import { fail } from '../utils/fail.js';
|
|
7
|
+
import { pathExists } from '../utils/fs.js';
|
|
8
|
+
import { generateMcpb } from '../emitter/mcpb-bundler.js';
|
|
9
|
+
const execFile = promisify(execFileCb);
|
|
10
|
+
export default defineCommand({
|
|
11
|
+
meta: {
|
|
12
|
+
name: 'bundle',
|
|
13
|
+
description: 'Bundle a generated MCP server project into an .mcpb file',
|
|
14
|
+
},
|
|
15
|
+
args: {
|
|
16
|
+
directory: {
|
|
17
|
+
type: 'positional',
|
|
18
|
+
description: 'Path to the generated MCP server project',
|
|
19
|
+
required: true,
|
|
20
|
+
},
|
|
21
|
+
output: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
alias: 'o',
|
|
24
|
+
description: 'Output path for the .mcpb file',
|
|
25
|
+
},
|
|
26
|
+
'skip-build': {
|
|
27
|
+
type: 'boolean',
|
|
28
|
+
description: 'Skip npm install and build steps (use if already built)',
|
|
29
|
+
default: false,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
async run({ args }) {
|
|
33
|
+
const projectDir = resolve(args.directory);
|
|
34
|
+
const pkgPath = resolve(projectDir, 'package.json');
|
|
35
|
+
if (!(await pathExists(pkgPath))) {
|
|
36
|
+
await fail(`Not a valid project directory (no package.json): ${projectDir}`);
|
|
37
|
+
}
|
|
38
|
+
if (!args['skip-build']) {
|
|
39
|
+
await buildProject(projectDir);
|
|
40
|
+
}
|
|
41
|
+
const outputPath = args.output ? resolve(args.output) : undefined;
|
|
42
|
+
logger.info('Creating .mcpb bundle...');
|
|
43
|
+
try {
|
|
44
|
+
const mcpbPath = await generateMcpb({
|
|
45
|
+
projectDir,
|
|
46
|
+
outputPath,
|
|
47
|
+
});
|
|
48
|
+
logger.success(`MCPB bundle created: ${mcpbPath}`);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
52
|
+
await fail(`Bundle failed: ${message}`, err);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Install production dependencies and build the project.
|
|
58
|
+
*/
|
|
59
|
+
async function buildProject(projectDir) {
|
|
60
|
+
logger.info('Installing production dependencies...');
|
|
61
|
+
try {
|
|
62
|
+
await execFile('npm', ['install', '--omit=dev'], {
|
|
63
|
+
cwd: projectDir,
|
|
64
|
+
timeout: 120_000,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
69
|
+
throw new Error(`npm install failed: ${message}`);
|
|
70
|
+
}
|
|
71
|
+
logger.info('Building project...');
|
|
72
|
+
try {
|
|
73
|
+
await execFile('npm', ['run', 'build'], {
|
|
74
|
+
cwd: projectDir,
|
|
75
|
+
timeout: 120_000,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
80
|
+
throw new Error(`npm run build failed: ${message}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface WorkflowOptions {
|
|
2
|
+
/** Path to the spec, relative to the repo root (e.g. `api-spec.yaml`). */
|
|
3
|
+
spec: string;
|
|
4
|
+
/** Generated server directory (e.g. `./mcp-server`). */
|
|
5
|
+
output: string;
|
|
6
|
+
/** Source adapter. */
|
|
7
|
+
source: 'openapi' | 'har' | 'postman';
|
|
8
|
+
/** Optional server name. */
|
|
9
|
+
name?: string;
|
|
10
|
+
/** Transport mode for the generated server. */
|
|
11
|
+
transport: 'stdio' | 'http';
|
|
12
|
+
/** mcpmake version/tag to run in CI (e.g. `latest`, `0.1.0`). */
|
|
13
|
+
version: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Build the `.github/workflows/mcpmake.yaml` contents. Pure + testable.
|
|
17
|
+
*
|
|
18
|
+
* The workflow regenerates the MCP server from the spec on every change and
|
|
19
|
+
* fails if the committed output is stale — the "keep generated code in sync
|
|
20
|
+
* with the spec" guarantee (the Stainless-style auto-regenerate-on-spec-change
|
|
21
|
+
* workflow). It also runs `mcpmake verify` for OpenAPI specs.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildWorkflowYaml(opts: WorkflowOptions): string;
|
|
24
|
+
declare const _default: import("citty").CommandDef<import("citty").ArgsDef>;
|
|
25
|
+
export default _default;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import { writeFile, mkdir, access } from 'node:fs/promises';
|
|
3
|
+
import { resolve, dirname } from 'node:path';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import { fail } from '../utils/fail.js';
|
|
6
|
+
const SOURCES = new Set(['openapi', 'har', 'postman']);
|
|
7
|
+
const TRANSPORTS = new Set(['stdio', 'http']);
|
|
8
|
+
/** Shell-quote a value for safe interpolation into a `run:` step. */
|
|
9
|
+
function q(value) {
|
|
10
|
+
return `"${value.replace(/"/g, '\\"')}"`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build the `.github/workflows/mcpmake.yaml` contents. Pure + testable.
|
|
14
|
+
*
|
|
15
|
+
* The workflow regenerates the MCP server from the spec on every change and
|
|
16
|
+
* fails if the committed output is stale — the "keep generated code in sync
|
|
17
|
+
* with the spec" guarantee (the Stainless-style auto-regenerate-on-spec-change
|
|
18
|
+
* workflow). It also runs `mcpmake verify` for OpenAPI specs.
|
|
19
|
+
*/
|
|
20
|
+
export function buildWorkflowYaml(opts) {
|
|
21
|
+
const runner = `npx --yes mcpmake@${opts.version}`;
|
|
22
|
+
const genFlags = [
|
|
23
|
+
`-o ${q(opts.output)}`,
|
|
24
|
+
opts.name ? `-n ${q(opts.name)}` : '',
|
|
25
|
+
opts.transport === 'http' ? '-t http' : '',
|
|
26
|
+
'-f',
|
|
27
|
+
]
|
|
28
|
+
.filter(Boolean)
|
|
29
|
+
.join(' ');
|
|
30
|
+
const generate = `${runner} from ${opts.source} ${q(opts.spec)} ${genFlags}`;
|
|
31
|
+
const verify = `${runner} verify ${q(opts.spec)} -p ${q(opts.output)}`;
|
|
32
|
+
const lines = [
|
|
33
|
+
'# Generated by `mcpmake ci init`.',
|
|
34
|
+
'# Regenerates the MCP server from the spec on every change and fails if the',
|
|
35
|
+
'# committed output is out of date — keep your generated server in sync with',
|
|
36
|
+
'# the API spec. Re-run `mcpmake from ...` locally and commit when this fails.',
|
|
37
|
+
'name: mcpmake',
|
|
38
|
+
'',
|
|
39
|
+
'on:',
|
|
40
|
+
' push:',
|
|
41
|
+
' paths:',
|
|
42
|
+
` - ${q(opts.spec)}`,
|
|
43
|
+
" - '.github/workflows/mcpmake.yaml'",
|
|
44
|
+
' pull_request:',
|
|
45
|
+
' paths:',
|
|
46
|
+
` - ${q(opts.spec)}`,
|
|
47
|
+
' workflow_dispatch:',
|
|
48
|
+
'',
|
|
49
|
+
'jobs:',
|
|
50
|
+
' sync:',
|
|
51
|
+
' runs-on: ubuntu-latest',
|
|
52
|
+
' steps:',
|
|
53
|
+
' - uses: actions/checkout@v4',
|
|
54
|
+
' - uses: actions/setup-node@v4',
|
|
55
|
+
' with:',
|
|
56
|
+
" node-version: '20'",
|
|
57
|
+
' - name: Regenerate MCP server from spec',
|
|
58
|
+
` run: ${generate}`,
|
|
59
|
+
];
|
|
60
|
+
// `mcpmake verify` currently supports OpenAPI specs only.
|
|
61
|
+
if (opts.source === 'openapi') {
|
|
62
|
+
lines.push(' - name: Verify generated server matches the spec', ` run: ${verify}`);
|
|
63
|
+
}
|
|
64
|
+
lines.push(' - name: Fail if the generated server is out of date', ' run: |', ` if [ -n "$(git status --porcelain ${q(opts.output)})" ]; then`, ` echo "::error::The committed MCP server under ${opts.output} is out of date with ${opts.spec}. Regenerate it and commit the result."`, ` git --no-pager diff -- ${q(opts.output)}`, ' exit 1', ' fi', '');
|
|
65
|
+
return lines.join('\n');
|
|
66
|
+
}
|
|
67
|
+
const initCommand = defineCommand({
|
|
68
|
+
meta: {
|
|
69
|
+
name: 'init',
|
|
70
|
+
description: 'Generate a GitHub Actions workflow that regenerates + verifies the MCP server when the spec changes',
|
|
71
|
+
},
|
|
72
|
+
args: {
|
|
73
|
+
spec: {
|
|
74
|
+
type: 'positional',
|
|
75
|
+
description: 'Path to the API spec, relative to the repo root (e.g. api-spec.yaml)',
|
|
76
|
+
required: true,
|
|
77
|
+
},
|
|
78
|
+
output: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
alias: 'o',
|
|
81
|
+
description: 'Generated server directory',
|
|
82
|
+
default: './mcp-server',
|
|
83
|
+
},
|
|
84
|
+
source: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
alias: 's',
|
|
87
|
+
description: 'Source adapter: openapi | har | postman',
|
|
88
|
+
default: 'openapi',
|
|
89
|
+
},
|
|
90
|
+
name: {
|
|
91
|
+
type: 'string',
|
|
92
|
+
alias: 'n',
|
|
93
|
+
description: 'Server name passed to generation',
|
|
94
|
+
},
|
|
95
|
+
transport: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
alias: 't',
|
|
98
|
+
description: 'Transport for the generated server: stdio | http',
|
|
99
|
+
default: 'stdio',
|
|
100
|
+
},
|
|
101
|
+
'mcpmake-version': {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: 'mcpmake version/tag to run in CI (e.g. latest, 0.1.0)',
|
|
104
|
+
default: 'latest',
|
|
105
|
+
},
|
|
106
|
+
force: {
|
|
107
|
+
type: 'boolean',
|
|
108
|
+
alias: 'f',
|
|
109
|
+
description: 'Overwrite an existing workflow file',
|
|
110
|
+
default: false,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
async run({ args }) {
|
|
114
|
+
const source = String(args.source);
|
|
115
|
+
const transport = String(args.transport);
|
|
116
|
+
if (!SOURCES.has(source)) {
|
|
117
|
+
await fail(`Invalid --source "${source}". Use one of: openapi, har, postman.`);
|
|
118
|
+
}
|
|
119
|
+
if (!TRANSPORTS.has(transport)) {
|
|
120
|
+
await fail(`Invalid --transport "${transport}". Use one of: stdio, http.`);
|
|
121
|
+
}
|
|
122
|
+
const workflowPath = resolve('.github/workflows/mcpmake.yaml');
|
|
123
|
+
const exists = await access(workflowPath).then(() => true, () => false);
|
|
124
|
+
if (exists && !args.force) {
|
|
125
|
+
await fail(`${workflowPath} already exists. Re-run with --force to overwrite.`);
|
|
126
|
+
}
|
|
127
|
+
const yaml = buildWorkflowYaml({
|
|
128
|
+
spec: args.spec,
|
|
129
|
+
output: String(args.output),
|
|
130
|
+
source: source,
|
|
131
|
+
name: args.name ? String(args.name) : undefined,
|
|
132
|
+
transport: transport,
|
|
133
|
+
version: String(args['mcpmake-version']),
|
|
134
|
+
});
|
|
135
|
+
await mkdir(dirname(workflowPath), { recursive: true });
|
|
136
|
+
await writeFile(workflowPath, yaml, 'utf-8');
|
|
137
|
+
logger.success(`Wrote ${workflowPath}`);
|
|
138
|
+
logger.info('Commit it, and CI will keep the generated server in sync with the spec.');
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
export default defineCommand({
|
|
142
|
+
meta: {
|
|
143
|
+
name: 'ci',
|
|
144
|
+
description: 'CI integration helpers (GitHub Actions)',
|
|
145
|
+
},
|
|
146
|
+
subCommands: {
|
|
147
|
+
init: initCommand,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare const _default: import("citty").CommandDef<{
|
|
2
|
+
spec: {
|
|
3
|
+
type: "positional";
|
|
4
|
+
description: string;
|
|
5
|
+
required: true;
|
|
6
|
+
};
|
|
7
|
+
name: {
|
|
8
|
+
type: "string";
|
|
9
|
+
alias: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
server: {
|
|
13
|
+
type: "string";
|
|
14
|
+
alias: string;
|
|
15
|
+
description: string;
|
|
16
|
+
default: string;
|
|
17
|
+
};
|
|
18
|
+
token: {
|
|
19
|
+
type: "string";
|
|
20
|
+
alias: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
}>;
|
|
24
|
+
export default _default;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { defineConfigurableCommand } from '../config/configurable-command.js';
|
|
2
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import { basename, extname, resolve } from 'node:path';
|
|
4
|
+
import http from 'node:http';
|
|
5
|
+
import https from 'node:https';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
import { fail } from '../utils/fail.js';
|
|
8
|
+
const MAX_SPEC_SIZE = 5 * 1024 * 1024; // 5 MB
|
|
9
|
+
export default defineConfigurableCommand('deploy', {
|
|
10
|
+
meta: {
|
|
11
|
+
name: 'deploy',
|
|
12
|
+
description: 'Deploy an MCP server to the hosting backend',
|
|
13
|
+
},
|
|
14
|
+
args: {
|
|
15
|
+
spec: {
|
|
16
|
+
type: 'positional',
|
|
17
|
+
description: 'Path to OpenAPI spec or HAR file',
|
|
18
|
+
required: true,
|
|
19
|
+
},
|
|
20
|
+
name: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
alias: 'n',
|
|
23
|
+
description: 'Server name (default: derived from spec)',
|
|
24
|
+
},
|
|
25
|
+
server: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
alias: 's',
|
|
28
|
+
description: 'Cloud server URL',
|
|
29
|
+
default: 'http://localhost:3001',
|
|
30
|
+
},
|
|
31
|
+
token: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
alias: 't',
|
|
34
|
+
description: 'Admin token (or set MCPMAKE_ADMIN_TOKEN) for gated backends',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
async run({ args }) {
|
|
38
|
+
const specPath = resolve(args.spec);
|
|
39
|
+
// Validate file exists and size
|
|
40
|
+
let fileInfo;
|
|
41
|
+
try {
|
|
42
|
+
fileInfo = await stat(specPath);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return await fail(`File not found: ${specPath}`, err);
|
|
46
|
+
}
|
|
47
|
+
if (fileInfo.size > MAX_SPEC_SIZE) {
|
|
48
|
+
return await fail(`Spec file too large (${Math.round(fileInfo.size / 1024)}KB). Maximum is 5MB.`);
|
|
49
|
+
}
|
|
50
|
+
const ext = extname(specPath).toLowerCase();
|
|
51
|
+
const allowedExtensions = new Set(['.yaml', '.yml', '.json', '.har']);
|
|
52
|
+
if (!allowedExtensions.has(ext)) {
|
|
53
|
+
await fail('Invalid file type. Accepted: .yaml, .yml, .json, .har');
|
|
54
|
+
}
|
|
55
|
+
logger.info(`Deploying spec: ${specPath}`);
|
|
56
|
+
const serverUrl = args.server;
|
|
57
|
+
logger.info(`Target: ${serverUrl}`);
|
|
58
|
+
// Read the spec file
|
|
59
|
+
const specData = await readFile(specPath);
|
|
60
|
+
const fileName = basename(specPath);
|
|
61
|
+
// Build multipart form data
|
|
62
|
+
const boundary = `----mcpmake${Date.now()}${Math.random().toString(36).slice(2)}`;
|
|
63
|
+
const parts = [];
|
|
64
|
+
// Add name field if provided
|
|
65
|
+
if (args.name) {
|
|
66
|
+
parts.push(Buffer.from(`--${boundary}\r\nContent-Disposition: form-data; name="name"\r\n\r\n${args.name}\r\n`));
|
|
67
|
+
}
|
|
68
|
+
// Add spec file
|
|
69
|
+
parts.push(Buffer.from(`--${boundary}\r\nContent-Disposition: form-data; name="spec"; filename="${fileName}"\r\nContent-Type: application/octet-stream\r\n\r\n`));
|
|
70
|
+
parts.push(specData);
|
|
71
|
+
parts.push(Buffer.from(`\r\n--${boundary}--\r\n`));
|
|
72
|
+
const body = Buffer.concat(parts);
|
|
73
|
+
// POST to the hosting backend
|
|
74
|
+
logger.info('Uploading spec...');
|
|
75
|
+
const adminToken = args.token ?? process.env.MCPMAKE_ADMIN_TOKEN;
|
|
76
|
+
try {
|
|
77
|
+
const result = await postMultipart(serverUrl, '/api/servers', boundary, body, adminToken);
|
|
78
|
+
logger.success('Server deployed!');
|
|
79
|
+
logger.info('');
|
|
80
|
+
logger.info(` Slug: ${result.slug}`);
|
|
81
|
+
logger.info(` Endpoint: ${result.endpoint}`);
|
|
82
|
+
logger.info(` Token: ${result.bearerToken}`);
|
|
83
|
+
logger.info(` Tools: ${result.toolCount}`);
|
|
84
|
+
logger.info('');
|
|
85
|
+
logger.info('Claude Desktop config (add to claude_desktop_config.json):');
|
|
86
|
+
logger.info('');
|
|
87
|
+
logger.info(JSON.stringify(result.claudeDesktopConfig, null, 2));
|
|
88
|
+
logger.info('');
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
92
|
+
await fail(`Deploy failed: ${message}`, err);
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
/**
|
|
97
|
+
* POST multipart form data to the hosting backend.
|
|
98
|
+
*/
|
|
99
|
+
function postMultipart(serverUrl, path, boundary, body, adminToken) {
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
const url = new URL(path, serverUrl);
|
|
102
|
+
const transport = url.protocol === 'https:' ? https : http;
|
|
103
|
+
const headers = {
|
|
104
|
+
'Content-Type': `multipart/form-data; boundary=${boundary}`,
|
|
105
|
+
'Content-Length': body.length,
|
|
106
|
+
};
|
|
107
|
+
if (adminToken) {
|
|
108
|
+
headers['Authorization'] = `Bearer ${adminToken}`;
|
|
109
|
+
}
|
|
110
|
+
const req = transport.request({
|
|
111
|
+
hostname: url.hostname,
|
|
112
|
+
port: url.port,
|
|
113
|
+
path: url.pathname,
|
|
114
|
+
method: 'POST',
|
|
115
|
+
headers,
|
|
116
|
+
}, (res) => {
|
|
117
|
+
const chunks = [];
|
|
118
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
119
|
+
res.on('end', () => {
|
|
120
|
+
const responseBody = Buffer.concat(chunks).toString('utf-8');
|
|
121
|
+
if (res.statusCode && res.statusCode >= 400) {
|
|
122
|
+
try {
|
|
123
|
+
const err = JSON.parse(responseBody);
|
|
124
|
+
reject(new Error(err.error ?? `Server returned ${res.statusCode}`));
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
reject(new Error(`Server returned ${res.statusCode}: ${responseBody}`));
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
resolve(JSON.parse(responseBody));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
reject(new Error(`Invalid response from server: ${responseBody}`));
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
req.on('error', (err) => {
|
|
140
|
+
reject(new Error(`Connection failed: ${err.message}`));
|
|
141
|
+
});
|
|
142
|
+
req.write(body);
|
|
143
|
+
req.end();
|
|
144
|
+
});
|
|
145
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare const _default: import("citty").CommandDef<{
|
|
2
|
+
oldSpec: {
|
|
3
|
+
type: "positional";
|
|
4
|
+
description: string;
|
|
5
|
+
required: true;
|
|
6
|
+
};
|
|
7
|
+
newSpec: {
|
|
8
|
+
type: "positional";
|
|
9
|
+
description: string;
|
|
10
|
+
required: true;
|
|
11
|
+
};
|
|
12
|
+
format: {
|
|
13
|
+
type: "string";
|
|
14
|
+
description: string;
|
|
15
|
+
default: string;
|
|
16
|
+
};
|
|
17
|
+
}>;
|
|
18
|
+
export default _default;
|