mcpmake 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/README.md +88 -635
  2. package/dist/commands/bundle.d.ts +1 -0
  3. package/dist/commands/bundle.d.ts.map +1 -0
  4. package/dist/commands/bundle.js +5 -4
  5. package/dist/commands/bundle.js.map +1 -0
  6. package/dist/commands/ci.d.ts +1 -0
  7. package/dist/commands/ci.d.ts.map +1 -0
  8. package/dist/commands/ci.js +3 -2
  9. package/dist/commands/ci.js.map +1 -0
  10. package/dist/commands/deploy.d.ts +1 -0
  11. package/dist/commands/deploy.d.ts.map +1 -0
  12. package/dist/commands/deploy.js +4 -3
  13. package/dist/commands/deploy.js.map +1 -0
  14. package/dist/commands/diff.d.ts +1 -0
  15. package/dist/commands/diff.d.ts.map +1 -0
  16. package/dist/commands/diff.js +5 -4
  17. package/dist/commands/diff.js.map +1 -0
  18. package/dist/commands/from/describe.d.ts +1 -0
  19. package/dist/commands/from/describe.d.ts.map +1 -0
  20. package/dist/commands/from/describe.js +11 -10
  21. package/dist/commands/from/describe.js.map +1 -0
  22. package/dist/commands/from/har.d.ts +1 -0
  23. package/dist/commands/from/har.d.ts.map +1 -0
  24. package/dist/commands/from/har.js +14 -13
  25. package/dist/commands/from/har.js.map +1 -0
  26. package/dist/commands/from/openapi.d.ts +1 -0
  27. package/dist/commands/from/openapi.d.ts.map +1 -0
  28. package/dist/commands/from/openapi.js +17 -16
  29. package/dist/commands/from/openapi.js.map +1 -0
  30. package/dist/commands/from/postman.d.ts +1 -0
  31. package/dist/commands/from/postman.d.ts.map +1 -0
  32. package/dist/commands/from/postman.js +13 -12
  33. package/dist/commands/from/postman.js.map +1 -0
  34. package/dist/commands/from/stainless.d.ts +110 -0
  35. package/dist/commands/from/stainless.d.ts.map +1 -0
  36. package/dist/commands/from/stainless.js +272 -0
  37. package/dist/commands/from/stainless.js.map +1 -0
  38. package/dist/commands/from/target-support.d.ts +1 -0
  39. package/dist/commands/from/target-support.d.ts.map +1 -0
  40. package/dist/commands/from/target-support.js +2 -1
  41. package/dist/commands/from/target-support.js.map +1 -0
  42. package/dist/commands/from/url.d.ts +1 -0
  43. package/dist/commands/from/url.d.ts.map +1 -0
  44. package/dist/commands/from/url.js +14 -13
  45. package/dist/commands/from/url.js.map +1 -0
  46. package/dist/commands/from/website.d.ts +1 -0
  47. package/dist/commands/from/website.d.ts.map +1 -0
  48. package/dist/commands/from/website.js +17 -16
  49. package/dist/commands/from/website.js.map +1 -0
  50. package/dist/commands/lint.d.ts +1 -0
  51. package/dist/commands/lint.d.ts.map +1 -0
  52. package/dist/commands/lint.js +6 -5
  53. package/dist/commands/lint.js.map +1 -0
  54. package/dist/commands/merge.d.ts +1 -0
  55. package/dist/commands/merge.d.ts.map +1 -0
  56. package/dist/commands/merge.js +3 -2
  57. package/dist/commands/merge.js.map +1 -0
  58. package/dist/commands/publish.d.ts +1 -0
  59. package/dist/commands/publish.d.ts.map +1 -0
  60. package/dist/commands/publish.js +4 -3
  61. package/dist/commands/publish.js.map +1 -0
  62. package/dist/commands/rescan.d.ts +1 -0
  63. package/dist/commands/rescan.d.ts.map +1 -0
  64. package/dist/commands/rescan.js +12 -11
  65. package/dist/commands/rescan.js.map +1 -0
  66. package/dist/commands/update.d.ts +1 -0
  67. package/dist/commands/update.d.ts.map +1 -0
  68. package/dist/commands/update.js +10 -9
  69. package/dist/commands/update.js.map +1 -0
  70. package/dist/commands/verify.d.ts +1 -0
  71. package/dist/commands/verify.d.ts.map +1 -0
  72. package/dist/commands/verify.js +7 -6
  73. package/dist/commands/verify.js.map +1 -0
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +23 -2
  77. package/dist/index.js.map +1 -0
  78. package/dist/registry/official-registry.d.ts +1 -0
  79. package/dist/registry/official-registry.d.ts.map +1 -0
  80. package/dist/registry/official-registry.js +1 -0
  81. package/dist/registry/official-registry.js.map +1 -0
  82. package/package.json +20 -46
  83. package/dist/analyzer/auth-detector.d.ts +0 -12
  84. package/dist/analyzer/auth-detector.js +0 -142
  85. package/dist/analyzer/dom-parser.d.ts +0 -10
  86. package/dist/analyzer/dom-parser.js +0 -259
  87. package/dist/analyzer/goal-crawler.d.ts +0 -25
  88. package/dist/analyzer/goal-crawler.js +0 -177
  89. package/dist/analyzer/hybrid-detector.d.ts +0 -28
  90. package/dist/analyzer/hybrid-detector.js +0 -96
  91. package/dist/analyzer/index.d.ts +0 -12
  92. package/dist/analyzer/index.js +0 -8
  93. package/dist/analyzer/screenshot-capture.d.ts +0 -29
  94. package/dist/analyzer/screenshot-capture.js +0 -42
  95. package/dist/analyzer/selector-builder.d.ts +0 -19
  96. package/dist/analyzer/selector-builder.js +0 -199
  97. package/dist/analyzer/semantic-analyzer.d.ts +0 -13
  98. package/dist/analyzer/semantic-analyzer.js +0 -145
  99. package/dist/analyzer/site-crawler.d.ts +0 -38
  100. package/dist/analyzer/site-crawler.js +0 -235
  101. package/dist/cloud/billing/billing-engine.d.ts +0 -44
  102. package/dist/cloud/billing/billing-engine.js +0 -81
  103. package/dist/cloud/billing/credit-store.d.ts +0 -64
  104. package/dist/cloud/billing/credit-store.js +0 -168
  105. package/dist/cloud/billing/index.d.ts +0 -4
  106. package/dist/cloud/billing/index.js +0 -2
  107. package/dist/cloud/billing/usage-store.d.ts +0 -42
  108. package/dist/cloud/billing/usage-store.js +0 -85
  109. package/dist/cloud/billing/usage-tracker.d.ts +0 -38
  110. package/dist/cloud/billing/usage-tracker.js +0 -95
  111. package/dist/cloud/build-pipeline.d.ts +0 -39
  112. package/dist/cloud/build-pipeline.js +0 -310
  113. package/dist/cloud/build-queue.d.ts +0 -30
  114. package/dist/cloud/build-queue.js +0 -70
  115. package/dist/cloud/caddy-manager.d.ts +0 -18
  116. package/dist/cloud/caddy-manager.js +0 -97
  117. package/dist/cloud/container-backend.d.ts +0 -62
  118. package/dist/cloud/container-backend.js +0 -59
  119. package/dist/cloud/container-manager.d.ts +0 -64
  120. package/dist/cloud/container-manager.js +0 -301
  121. package/dist/cloud/crypto.d.ts +0 -27
  122. package/dist/cloud/crypto.js +0 -63
  123. package/dist/cloud/db/index.d.ts +0 -27
  124. package/dist/cloud/db/index.js +0 -53
  125. package/dist/cloud/db/migrations.d.ts +0 -12
  126. package/dist/cloud/db/migrations.js +0 -329
  127. package/dist/cloud/db/pg-store.d.ts +0 -45
  128. package/dist/cloud/db/pg-store.js +0 -336
  129. package/dist/cloud/failure-tracker.d.ts +0 -51
  130. package/dist/cloud/failure-tracker.js +0 -102
  131. package/dist/cloud/idle-monitor.d.ts +0 -30
  132. package/dist/cloud/idle-monitor.js +0 -70
  133. package/dist/cloud/mailer.d.ts +0 -21
  134. package/dist/cloud/mailer.js +0 -193
  135. package/dist/cloud/mcp-proxy.d.ts +0 -58
  136. package/dist/cloud/mcp-proxy.js +0 -203
  137. package/dist/cloud/metric-samples.d.ts +0 -43
  138. package/dist/cloud/metric-samples.js +0 -85
  139. package/dist/cloud/metrics.d.ts +0 -26
  140. package/dist/cloud/metrics.js +0 -59
  141. package/dist/cloud/multipart.d.ts +0 -26
  142. package/dist/cloud/multipart.js +0 -132
  143. package/dist/cloud/observability.d.ts +0 -27
  144. package/dist/cloud/observability.js +0 -98
  145. package/dist/cloud/rate-limiter.d.ts +0 -31
  146. package/dist/cloud/rate-limiter.js +0 -58
  147. package/dist/cloud/request-security.d.ts +0 -5
  148. package/dist/cloud/request-security.js +0 -74
  149. package/dist/cloud/resource-monitor.d.ts +0 -69
  150. package/dist/cloud/resource-monitor.js +0 -130
  151. package/dist/cloud/secret-store.d.ts +0 -38
  152. package/dist/cloud/secret-store.js +0 -103
  153. package/dist/cloud/security.d.ts +0 -26
  154. package/dist/cloud/security.js +0 -142
  155. package/dist/cloud/server.d.ts +0 -21
  156. package/dist/cloud/server.js +0 -1079
  157. package/dist/cloud/shared-state.d.ts +0 -72
  158. package/dist/cloud/shared-state.js +0 -159
  159. package/dist/cloud/ssrf.d.ts +0 -43
  160. package/dist/cloud/ssrf.js +0 -150
  161. package/dist/cloud/store.d.ts +0 -41
  162. package/dist/cloud/store.js +0 -75
  163. package/dist/cloud/stripe.d.ts +0 -78
  164. package/dist/cloud/stripe.js +0 -317
  165. package/dist/cloud/telemetry-store.d.ts +0 -53
  166. package/dist/cloud/telemetry-store.js +0 -108
  167. package/dist/cloud/web/auth.d.ts +0 -225
  168. package/dist/cloud/web/auth.js +0 -555
  169. package/dist/cloud/web/charts.d.ts +0 -70
  170. package/dist/cloud/web/charts.js +0 -178
  171. package/dist/cloud/web/csrf.d.ts +0 -14
  172. package/dist/cloud/web/csrf.js +0 -22
  173. package/dist/cloud/web/docs.d.ts +0 -40
  174. package/dist/cloud/web/docs.js +0 -174
  175. package/dist/cloud/web/router.d.ts +0 -25
  176. package/dist/cloud/web/router.js +0 -1921
  177. package/dist/cloud/web/static/alpine.min.js +0 -5
  178. package/dist/cloud/web/static/favicon.svg +0 -4
  179. package/dist/cloud/web/static/htmx-sse.js +0 -290
  180. package/dist/cloud/web/static/htmx.min.js +0 -1
  181. package/dist/cloud/web/static/style.css +0 -2683
  182. package/dist/cloud/web/static-server.d.ts +0 -13
  183. package/dist/cloud/web/static-server.js +0 -73
  184. package/dist/cloud/web/template-engine.d.ts +0 -27
  185. package/dist/cloud/web/template-engine.js +0 -146
  186. package/dist/cloud/web/templates/layouts/admin.hbs +0 -57
  187. package/dist/cloud/web/templates/layouts/auth.hbs +0 -138
  188. package/dist/cloud/web/templates/layouts/base.hbs +0 -16
  189. package/dist/cloud/web/templates/layouts/dashboard.hbs +0 -39
  190. package/dist/cloud/web/templates/layouts/landing.hbs +0 -82
  191. package/dist/cloud/web/templates/pages/admin/overview.hbs +0 -123
  192. package/dist/cloud/web/templates/pages/admin/servers.hbs +0 -129
  193. package/dist/cloud/web/templates/pages/admin/telemetry.hbs +0 -39
  194. package/dist/cloud/web/templates/pages/admin/user-edit.hbs +0 -91
  195. package/dist/cloud/web/templates/pages/admin/users.hbs +0 -179
  196. package/dist/cloud/web/templates/pages/auth/forgot-password.hbs +0 -25
  197. package/dist/cloud/web/templates/pages/auth/login.hbs +0 -33
  198. package/dist/cloud/web/templates/pages/auth/register.hbs +0 -32
  199. package/dist/cloud/web/templates/pages/auth/reset-password.hbs +0 -34
  200. package/dist/cloud/web/templates/pages/dashboard/billing.hbs +0 -140
  201. package/dist/cloud/web/templates/pages/dashboard/create.hbs +0 -173
  202. package/dist/cloud/web/templates/pages/dashboard/index.hbs +0 -8
  203. package/dist/cloud/web/templates/pages/dashboard/server-detail.hbs +0 -280
  204. package/dist/cloud/web/templates/pages/dashboard/server-logs.hbs +0 -35
  205. package/dist/cloud/web/templates/pages/dashboard/server-metrics.hbs +0 -63
  206. package/dist/cloud/web/templates/pages/dashboard/servers-partial.hbs +0 -21
  207. package/dist/cloud/web/templates/pages/dashboard/servers.hbs +0 -44
  208. package/dist/cloud/web/templates/pages/docs/show.hbs +0 -16
  209. package/dist/cloud/web/templates/pages/errors/404.hbs +0 -9
  210. package/dist/cloud/web/templates/pages/errors/500.hbs +0 -8
  211. package/dist/cloud/web/templates/pages/landing/index.hbs +0 -223
  212. package/dist/cloud/web/templates/pages/legal/privacy.hbs +0 -71
  213. package/dist/cloud/web/templates/pages/legal/terms.hbs +0 -73
  214. package/dist/cloud/web/templates/partials/admin-stats.hbs +0 -52
  215. package/dist/cloud/web/templates/partials/flash-message.hbs +0 -6
  216. package/dist/cloud/web/templates/partials/pricing-table.hbs +0 -103
  217. package/dist/cloud/web/templates/partials/server-card.hbs +0 -19
  218. package/dist/cloud/web/templates/partials/status-badge.hbs +0 -1
  219. package/dist/config/configurable-command.d.ts +0 -13
  220. package/dist/config/configurable-command.js +0 -70
  221. package/dist/config/mcpmake-config.d.ts +0 -68
  222. package/dist/config/mcpmake-config.js +0 -207
  223. package/dist/docs/cli.md +0 -400
  224. package/dist/docs/mcp-2026-07-28-migration.md +0 -78
  225. package/dist/docs/migrate-from-stainless.md +0 -94
  226. package/dist/docs/quickstart.md +0 -166
  227. package/dist/docs/show-hn.md +0 -26
  228. package/dist/docs/website-servers.md +0 -169
  229. package/dist/emitter/code-writer.d.ts +0 -8
  230. package/dist/emitter/code-writer.js +0 -25
  231. package/dist/emitter/index.d.ts +0 -32
  232. package/dist/emitter/index.js +0 -280
  233. package/dist/emitter/mcpb-bundler.d.ts +0 -31
  234. package/dist/emitter/mcpb-bundler.js +0 -172
  235. package/dist/emitter/project-scaffolder.d.ts +0 -4
  236. package/dist/emitter/project-scaffolder.js +0 -89
  237. package/dist/emitter/python-template-loader.d.ts +0 -4
  238. package/dist/emitter/python-template-loader.js +0 -30
  239. package/dist/emitter/python-templates/dockerfile.hbs +0 -14
  240. package/dist/emitter/python-templates/env.example.hbs +0 -6
  241. package/dist/emitter/python-templates/requirements.txt.hbs +0 -4
  242. package/dist/emitter/python-templates/server.py.hbs +0 -77
  243. package/dist/emitter/site-scaffolder.d.ts +0 -13
  244. package/dist/emitter/site-scaffolder.js +0 -70
  245. package/dist/emitter/site-template-loader.d.ts +0 -5
  246. package/dist/emitter/site-template-loader.js +0 -47
  247. package/dist/emitter/site-templates/browser-manager.ts.hbs +0 -233
  248. package/dist/emitter/site-templates/config.ts.hbs +0 -28
  249. package/dist/emitter/site-templates/dockerfile.hbs +0 -31
  250. package/dist/emitter/site-templates/env.example.hbs +0 -19
  251. package/dist/emitter/site-templates/package.json.hbs +0 -26
  252. package/dist/emitter/site-templates/server-main-http.ts.hbs +0 -108
  253. package/dist/emitter/site-templates/server-main.ts.hbs +0 -23
  254. package/dist/emitter/site-templates/tool-handler-action.ts.hbs +0 -86
  255. package/dist/emitter/site-templates/tool-handler-form.ts.hbs +0 -116
  256. package/dist/emitter/site-templates/tool-handler-lifecycle.ts.hbs +0 -146
  257. package/dist/emitter/site-templates/tool-index.ts.hbs +0 -11
  258. package/dist/emitter/template-loader.d.ts +0 -1
  259. package/dist/emitter/template-loader.js +0 -27
  260. package/dist/emitter/templates/auth-provider.ts.hbs +0 -57
  261. package/dist/emitter/templates/config.ts.hbs +0 -63
  262. package/dist/emitter/templates/discovery.ts.hbs +0 -301
  263. package/dist/emitter/templates/dockerfile.hbs +0 -34
  264. package/dist/emitter/templates/env.example.hbs +0 -28
  265. package/dist/emitter/templates/gitignore.hbs +0 -5
  266. package/dist/emitter/templates/http-executor.ts.hbs +0 -117
  267. package/dist/emitter/templates/oauth.ts.hbs +0 -188
  268. package/dist/emitter/templates/package.json.hbs +0 -25
  269. package/dist/emitter/templates/prompts.ts.hbs +0 -22
  270. package/dist/emitter/templates/readme.md.hbs +0 -123
  271. package/dist/emitter/templates/resources.ts.hbs +0 -63
  272. package/dist/emitter/templates/server-main-http.ts.hbs +0 -407
  273. package/dist/emitter/templates/server-main.ts.hbs +0 -40
  274. package/dist/emitter/templates/task-handlers.ts.hbs +0 -189
  275. package/dist/emitter/templates/task-manager.ts.hbs +0 -139
  276. package/dist/emitter/templates/task-sse.ts.hbs +0 -105
  277. package/dist/emitter/templates/tool-handler.ts.hbs +0 -124
  278. package/dist/emitter/templates/tool-index.ts.hbs +0 -11
  279. package/dist/emitter/templates/tool-test.ts.hbs +0 -57
  280. package/dist/emitter/templates/trace.ts.hbs +0 -79
  281. package/dist/emitter/templates/tsconfig.json.hbs +0 -16
  282. package/dist/emitter/templates/types.ts.hbs +0 -5
  283. package/dist/emitter/worker-template-loader.d.ts +0 -5
  284. package/dist/emitter/worker-template-loader.js +0 -33
  285. package/dist/emitter/worker-templates/config.ts.hbs +0 -54
  286. package/dist/emitter/worker-templates/dev-vars.example.hbs +0 -10
  287. package/dist/emitter/worker-templates/gitignore.hbs +0 -6
  288. package/dist/emitter/worker-templates/package.json.hbs +0 -24
  289. package/dist/emitter/worker-templates/readme.md.hbs +0 -53
  290. package/dist/emitter/worker-templates/server.test.ts.hbs +0 -20
  291. package/dist/emitter/worker-templates/tool-handler.ts.hbs +0 -85
  292. package/dist/emitter/worker-templates/tool-index.ts.hbs +0 -28
  293. package/dist/emitter/worker-templates/tsconfig.json.hbs +0 -17
  294. package/dist/emitter/worker-templates/worker.ts.hbs +0 -242
  295. package/dist/emitter/worker-templates/wrangler.toml.hbs +0 -19
  296. package/dist/generator/spec-generator.d.ts +0 -6
  297. package/dist/generator/spec-generator.js +0 -50
  298. package/dist/parser/har-filter.d.ts +0 -8
  299. package/dist/parser/har-filter.js +0 -71
  300. package/dist/parser/har-loader.d.ts +0 -2
  301. package/dist/parser/har-loader.js +0 -14
  302. package/dist/parser/har-normalizer.d.ts +0 -20
  303. package/dist/parser/har-normalizer.js +0 -78
  304. package/dist/parser/index.d.ts +0 -10
  305. package/dist/parser/index.js +0 -6
  306. package/dist/parser/openapi-loader.d.ts +0 -6
  307. package/dist/parser/openapi-loader.js +0 -308
  308. package/dist/parser/operation-extractor.d.ts +0 -13
  309. package/dist/parser/operation-extractor.js +0 -155
  310. package/dist/parser/overlay-loader.d.ts +0 -10
  311. package/dist/parser/overlay-loader.js +0 -184
  312. package/dist/parser/postman-loader.d.ts +0 -9
  313. package/dist/parser/postman-loader.js +0 -106
  314. package/dist/parser/schema-converter.d.ts +0 -12
  315. package/dist/parser/schema-converter.js +0 -117
  316. package/dist/plugins/adapter.d.ts +0 -40
  317. package/dist/plugins/adapter.js +0 -15
  318. package/dist/plugins/loader.d.ts +0 -25
  319. package/dist/plugins/loader.js +0 -58
  320. package/dist/pricing.d.ts +0 -55
  321. package/dist/pricing.js +0 -133
  322. package/dist/providers/index.d.ts +0 -15
  323. package/dist/providers/index.js +0 -56
  324. package/dist/recorder/browser-recorder.d.ts +0 -22
  325. package/dist/recorder/browser-recorder.js +0 -205
  326. package/dist/rescan/diff-engine.d.ts +0 -5
  327. package/dist/rescan/diff-engine.js +0 -312
  328. package/dist/rescan/index.d.ts +0 -3
  329. package/dist/rescan/index.js +0 -2
  330. package/dist/rescan/rescan-runner.d.ts +0 -42
  331. package/dist/rescan/rescan-runner.js +0 -69
  332. package/dist/rescan/rescan-scheduler.d.ts +0 -41
  333. package/dist/rescan/rescan-scheduler.js +0 -179
  334. package/dist/site-transformer/browser-tools.d.ts +0 -10
  335. package/dist/site-transformer/browser-tools.js +0 -59
  336. package/dist/site-transformer/index.d.ts +0 -2
  337. package/dist/site-transformer/index.js +0 -2
  338. package/dist/site-transformer/selector-healer.d.ts +0 -8
  339. package/dist/site-transformer/selector-healer.js +0 -106
  340. package/dist/site-transformer/tool-generator.d.ts +0 -13
  341. package/dist/site-transformer/tool-generator.js +0 -245
  342. package/dist/transformer/auth-detector.d.ts +0 -13
  343. package/dist/transformer/auth-detector.js +0 -90
  344. package/dist/transformer/catalog-builder.d.ts +0 -18
  345. package/dist/transformer/catalog-builder.js +0 -56
  346. package/dist/transformer/client-compat.d.ts +0 -6
  347. package/dist/transformer/client-compat.js +0 -44
  348. package/dist/transformer/har-clusterer.d.ts +0 -9
  349. package/dist/transformer/har-clusterer.js +0 -27
  350. package/dist/transformer/har-dedup.d.ts +0 -10
  351. package/dist/transformer/har-dedup.js +0 -81
  352. package/dist/transformer/har-schema-inferrer.d.ts +0 -15
  353. package/dist/transformer/har-schema-inferrer.js +0 -90
  354. package/dist/transformer/har-to-operations.d.ts +0 -13
  355. package/dist/transformer/har-to-operations.js +0 -192
  356. package/dist/transformer/index.d.ts +0 -8
  357. package/dist/transformer/index.js +0 -6
  358. package/dist/transformer/llm-namer.d.ts +0 -6
  359. package/dist/transformer/llm-namer.js +0 -59
  360. package/dist/transformer/naming.d.ts +0 -4
  361. package/dist/transformer/naming.js +0 -30
  362. package/dist/transformer/operation-filter.d.ts +0 -13
  363. package/dist/transformer/operation-filter.js +0 -52
  364. package/dist/transformer/resource-builder.d.ts +0 -12
  365. package/dist/transformer/resource-builder.js +0 -80
  366. package/dist/transformer/schema-merger.d.ts +0 -14
  367. package/dist/transformer/schema-merger.js +0 -65
  368. package/dist/transformer/tool-builder.d.ts +0 -3
  369. package/dist/transformer/tool-builder.js +0 -114
  370. package/dist/types/index.d.ts +0 -131
  371. package/dist/types/index.js +0 -1
  372. package/dist/types/site.d.ts +0 -284
  373. package/dist/types/site.js +0 -8
  374. package/dist/utils/fail.d.ts +0 -48
  375. package/dist/utils/fail.js +0 -204
  376. package/dist/utils/fs.d.ts +0 -5
  377. package/dist/utils/fs.js +0 -28
  378. package/dist/utils/interactive.d.ts +0 -6
  379. package/dist/utils/interactive.js +0 -30
  380. package/dist/utils/logger.d.ts +0 -1
  381. package/dist/utils/logger.js +0 -2
  382. package/dist/utils/sanitize.d.ts +0 -28
  383. package/dist/utils/sanitize.js +0 -44
  384. package/dist/utils/watcher.d.ts +0 -11
  385. package/dist/utils/watcher.js +0 -36
@@ -1,193 +0,0 @@
1
- /**
2
- * Minimal email sender for transactional emails (password reset, etc.).
3
- *
4
- * Supports two modes:
5
- * 1. Console (default) — logs the email to stdout. Useful for development
6
- * and self-hosted instances without email infrastructure.
7
- * 2. SMTP — sends via an external SMTP relay. Requires env vars:
8
- * SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, MAIL_FROM
9
- *
10
- * Uses Node.js built-in `net`/`tls` modules — zero external dependencies.
11
- */
12
- import { createConnection } from 'node:net';
13
- import { connect as tlsConnect } from 'node:tls';
14
- import { logger } from '../utils/logger.js';
15
- /**
16
- * Send an email. Falls back to console logging when SMTP is not configured.
17
- */
18
- export async function sendMail(options) {
19
- const host = process.env.SMTP_HOST;
20
- if (!host) {
21
- logger.info(`[mailer] No SMTP configured — logging email to console`);
22
- logger.info(`[mailer] To: ${options.to}`);
23
- logger.info(`[mailer] Subject: ${options.subject}`);
24
- logger.info(`[mailer] Body:\n${options.text}`);
25
- return;
26
- }
27
- await sendSmtp(options);
28
- }
29
- // ---------------------------------------------------------------------------
30
- // Minimal SMTP client (STARTTLS on 587, implicit TLS on 465, plain on 25)
31
- // ---------------------------------------------------------------------------
32
- async function sendSmtp(options) {
33
- const host = process.env.SMTP_HOST;
34
- const port = parseInt(process.env.SMTP_PORT ?? '587', 10);
35
- const user = process.env.SMTP_USER ?? '';
36
- const pass = process.env.SMTP_PASS ?? '';
37
- const from = process.env.MAIL_FROM ?? 'noreply@mcpmake.dev';
38
- const implicitTls = port === 465;
39
- const boundary = `----mcpmake${Date.now()}`;
40
- const body = options.html
41
- ? [
42
- `MIME-Version: 1.0`,
43
- `Content-Type: multipart/alternative; boundary="${boundary}"`,
44
- ``,
45
- `--${boundary}`,
46
- `Content-Type: text/plain; charset=utf-8`,
47
- ``,
48
- options.text,
49
- `--${boundary}`,
50
- `Content-Type: text/html; charset=utf-8`,
51
- ``,
52
- options.html,
53
- `--${boundary}--`,
54
- ].join('\r\n')
55
- : options.text;
56
- const message = [
57
- `From: ${from}`,
58
- `To: ${options.to}`,
59
- `Subject: ${options.subject}`,
60
- `Date: ${new Date().toUTCString()}`,
61
- ...(options.html ? [] : [`MIME-Version: 1.0`, `Content-Type: text/plain; charset=utf-8`]),
62
- ``,
63
- body,
64
- ].join('\r\n');
65
- return new Promise((resolve, reject) => {
66
- const timeout = setTimeout(() => {
67
- reject(new Error('SMTP timeout after 30s'));
68
- }, 30_000);
69
- let socket;
70
- let buffer = '';
71
- function cleanup() {
72
- clearTimeout(timeout);
73
- socket?.removeAllListeners();
74
- socket?.destroy();
75
- }
76
- function readLine() {
77
- return new Promise((res) => {
78
- const check = () => {
79
- const idx = buffer.indexOf('\r\n');
80
- if (idx !== -1) {
81
- const line = buffer.slice(0, idx);
82
- buffer = buffer.slice(idx + 2);
83
- res(line);
84
- }
85
- else {
86
- socket.once('data', (chunk) => {
87
- buffer += chunk.toString();
88
- check();
89
- });
90
- }
91
- };
92
- check();
93
- });
94
- }
95
- async function waitReply() {
96
- let full = '';
97
- // eslint-disable-next-line no-constant-condition
98
- while (true) {
99
- const line = await readLine();
100
- full += line + '\r\n';
101
- // Multi-line replies have "-" after the code, last line has " "
102
- if (line.length >= 4 && line[3] === ' ') {
103
- return { code: parseInt(line.slice(0, 3), 10), text: full };
104
- }
105
- }
106
- }
107
- function send(cmd) {
108
- socket.write(cmd + '\r\n');
109
- }
110
- async function run() {
111
- // Greeting
112
- await waitReply();
113
- send(`EHLO mcpmake`);
114
- await waitReply();
115
- // STARTTLS for port 587
116
- if (!implicitTls && port === 587) {
117
- send('STARTTLS');
118
- const tlsReply = await waitReply();
119
- if (tlsReply.code !== 220) {
120
- throw new Error(`STARTTLS failed: ${tlsReply.text}`);
121
- }
122
- // Upgrade socket to TLS
123
- const tlsSocket = tlsConnect({ socket, host, servername: host });
124
- await new Promise((res, rej) => {
125
- tlsSocket.once('secureConnect', res);
126
- tlsSocket.once('error', rej);
127
- });
128
- socket = tlsSocket;
129
- buffer = '';
130
- send(`EHLO mcpmake`);
131
- await waitReply();
132
- }
133
- // AUTH LOGIN
134
- if (user && pass) {
135
- send('AUTH LOGIN');
136
- const authReply = await waitReply();
137
- if (authReply.code !== 334) {
138
- throw new Error(`AUTH LOGIN rejected: ${authReply.text}`);
139
- }
140
- send(Buffer.from(user).toString('base64'));
141
- await waitReply();
142
- send(Buffer.from(pass).toString('base64'));
143
- const loginReply = await waitReply();
144
- if (loginReply.code !== 235) {
145
- throw new Error(`SMTP authentication failed: ${loginReply.text}`);
146
- }
147
- }
148
- send(`MAIL FROM:<${from}>`);
149
- const fromReply = await waitReply();
150
- if (fromReply.code !== 250) {
151
- throw new Error(`MAIL FROM rejected: ${fromReply.text}`);
152
- }
153
- send(`RCPT TO:<${options.to}>`);
154
- const toReply = await waitReply();
155
- if (toReply.code !== 250) {
156
- throw new Error(`RCPT TO rejected: ${toReply.text}`);
157
- }
158
- send('DATA');
159
- const dataReply = await waitReply();
160
- if (dataReply.code !== 354) {
161
- throw new Error(`DATA rejected: ${dataReply.text}`);
162
- }
163
- send(message + '\r\n.');
164
- const msgReply = await waitReply();
165
- if (msgReply.code !== 250) {
166
- throw new Error(`Message rejected: ${msgReply.text}`);
167
- }
168
- send('QUIT');
169
- cleanup();
170
- resolve();
171
- }
172
- if (implicitTls) {
173
- socket = tlsConnect({ host, port }, () => {
174
- run().catch((err) => {
175
- cleanup();
176
- reject(err);
177
- });
178
- });
179
- }
180
- else {
181
- socket = createConnection({ host, port }, () => {
182
- run().catch((err) => {
183
- cleanup();
184
- reject(err);
185
- });
186
- });
187
- }
188
- socket.on('error', (err) => {
189
- cleanup();
190
- reject(new Error(`SMTP connection error: ${err.message}`));
191
- });
192
- });
193
- }
@@ -1,58 +0,0 @@
1
- /**
2
- * Backend reverse-proxy for served MCP traffic.
3
- *
4
- * Each hosted server is reached at `{slug}.{domain}`. Caddy proxies the
5
- * wildcard subdomain to this backend (port 3001); the backend is the single
6
- * authoritative entry point: it validates the hashed `mf_` bearer token,
7
- * enforces quota, meters usage, and streams the request through to the
8
- * container listening on `127.0.0.1:{port}`.
9
- *
10
- * This resolves the data-path question in the launch plan: Caddy routes the
11
- * wildcard to the backend, the backend authenticates + meters, and the
12
- * container (which also validates MCP_AUTH_TOKEN) is the in-depth backstop.
13
- */
14
- import http from 'node:http';
15
- /** Body buffered for metering must never exceed this (MCP JSON-RPC is small). */
16
- export declare const MAX_PROXY_BODY: number;
17
- /**
18
- * Extract the server slug from a Host header given the apex domain.
19
- *
20
- * Returns the slug for `{slug}.{domain}` hosts, or null for the apex domain,
21
- * `www`, multi-label subdomains, or anything that isn't a valid slug.
22
- */
23
- export declare function extractSlug(host: string | undefined, domain: string): string | null;
24
- export type AuthResult = {
25
- ok: true;
26
- } | {
27
- ok: false;
28
- status: number;
29
- error: string;
30
- };
31
- /**
32
- * Validate the request's bearer token against a server's stored SHA-256 hash.
33
- */
34
- export declare function authorizeBearer(req: http.IncomingMessage, tokenHash: string): AuthResult;
35
- /**
36
- * Read a request body up to MAX_PROXY_BODY. Resolves `null` if the limit is
37
- * exceeded (caller should respond 413). Returns an empty buffer for bodyless
38
- * methods without touching the stream.
39
- */
40
- export declare function readBoundedBody(req: http.IncomingMessage): Promise<Buffer | null>;
41
- /**
42
- * Count billable tool calls in an MCP JSON-RPC request body, and surface the
43
- * primary tool name (for metrics). Best-effort: malformed bodies count as zero.
44
- */
45
- export declare function inspectMcpBody(body: Buffer | undefined, contentType: string | undefined): {
46
- toolCalls: number;
47
- primaryTool?: string;
48
- };
49
- /**
50
- * Stream-proxy a request to a local container upstream, preserving method,
51
- * headers, body, and streaming the response (including long-lived SSE).
52
- *
53
- * @param bufferedBody Pre-read request body to forward (empty for GET/DELETE).
54
- */
55
- export declare function proxyToUpstream(req: http.IncomingMessage, res: http.ServerResponse, upstreamPort: number, bufferedBody: Buffer, opts?: {
56
- host?: string;
57
- timeoutMs?: number;
58
- }): Promise<void>;
@@ -1,203 +0,0 @@
1
- /**
2
- * Backend reverse-proxy for served MCP traffic.
3
- *
4
- * Each hosted server is reached at `{slug}.{domain}`. Caddy proxies the
5
- * wildcard subdomain to this backend (port 3001); the backend is the single
6
- * authoritative entry point: it validates the hashed `mf_` bearer token,
7
- * enforces quota, meters usage, and streams the request through to the
8
- * container listening on `127.0.0.1:{port}`.
9
- *
10
- * This resolves the data-path question in the launch plan: Caddy routes the
11
- * wildcard to the backend, the backend authenticates + meters, and the
12
- * container (which also validates MCP_AUTH_TOKEN) is the in-depth backstop.
13
- */
14
- import http from 'node:http';
15
- import { verifyToken } from './security.js';
16
- /** Body buffered for metering must never exceed this (MCP JSON-RPC is small). */
17
- export const MAX_PROXY_BODY = 8 * 1024 * 1024; // 8 MB
18
- /** Methods that carry a request body we need to buffer for metering. */
19
- const BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);
20
- /** Hop-by-hop headers that must not be forwarded through a proxy (RFC 7230 §6.1). */
21
- const HOP_BY_HOP = new Set([
22
- 'connection',
23
- 'keep-alive',
24
- 'proxy-authenticate',
25
- 'proxy-authorization',
26
- 'te',
27
- 'trailers',
28
- 'transfer-encoding',
29
- 'upgrade',
30
- ]);
31
- /**
32
- * Extract the server slug from a Host header given the apex domain.
33
- *
34
- * Returns the slug for `{slug}.{domain}` hosts, or null for the apex domain,
35
- * `www`, multi-label subdomains, or anything that isn't a valid slug.
36
- */
37
- export function extractSlug(host, domain) {
38
- if (!host)
39
- return null;
40
- let h = host.trim().toLowerCase();
41
- if (!h)
42
- return null;
43
- // Strip a trailing :port (ignore IPv6 brackets — server hosts are never IPv6 here)
44
- if (h.startsWith('['))
45
- return null;
46
- const colon = h.lastIndexOf(':');
47
- if (colon !== -1)
48
- h = h.slice(0, colon);
49
- const suffix = '.' + domain.trim().toLowerCase();
50
- if (!h.endsWith(suffix))
51
- return null;
52
- const label = h.slice(0, -suffix.length);
53
- if (!label || label === 'www' || label.includes('.'))
54
- return null;
55
- if (!/^[a-z0-9][a-z0-9-]*$/.test(label))
56
- return null;
57
- return label;
58
- }
59
- /**
60
- * Validate the request's bearer token against a server's stored SHA-256 hash.
61
- */
62
- export function authorizeBearer(req, tokenHash) {
63
- const header = req.headers.authorization;
64
- if (!header || !header.startsWith('Bearer ')) {
65
- return { ok: false, status: 401, error: 'Missing or invalid Authorization header' };
66
- }
67
- const token = header.slice(7).trim();
68
- if (!token || !verifyToken(token, tokenHash)) {
69
- return { ok: false, status: 403, error: 'Invalid bearer token' };
70
- }
71
- return { ok: true };
72
- }
73
- /**
74
- * Read a request body up to MAX_PROXY_BODY. Resolves `null` if the limit is
75
- * exceeded (caller should respond 413). Returns an empty buffer for bodyless
76
- * methods without touching the stream.
77
- */
78
- export function readBoundedBody(req) {
79
- if (!BODY_METHODS.has((req.method ?? 'GET').toUpperCase())) {
80
- return Promise.resolve(Buffer.alloc(0));
81
- }
82
- return new Promise((resolve) => {
83
- const chunks = [];
84
- let total = 0;
85
- let settled = false;
86
- const finish = (value) => {
87
- if (settled)
88
- return;
89
- settled = true;
90
- resolve(value);
91
- };
92
- req.on('data', (chunk) => {
93
- total += chunk.length;
94
- if (total > MAX_PROXY_BODY) {
95
- finish(null);
96
- req.destroy();
97
- return;
98
- }
99
- chunks.push(chunk);
100
- });
101
- req.on('end', () => finish(Buffer.concat(chunks)));
102
- req.on('error', () => finish(null));
103
- req.on('aborted', () => finish(null));
104
- });
105
- }
106
- /**
107
- * Count billable tool calls in an MCP JSON-RPC request body, and surface the
108
- * primary tool name (for metrics). Best-effort: malformed bodies count as zero.
109
- */
110
- export function inspectMcpBody(body, contentType) {
111
- if (!body || body.length === 0)
112
- return { toolCalls: 0 };
113
- if (contentType && !contentType.includes('json'))
114
- return { toolCalls: 0 };
115
- let parsed;
116
- try {
117
- parsed = JSON.parse(body.toString('utf-8'));
118
- }
119
- catch {
120
- return { toolCalls: 0 };
121
- }
122
- const messages = Array.isArray(parsed) ? parsed : [parsed];
123
- let toolCalls = 0;
124
- let primaryTool;
125
- for (const msg of messages) {
126
- if (msg && typeof msg === 'object' && msg.method === 'tools/call') {
127
- toolCalls++;
128
- const params = msg.params;
129
- if (!primaryTool && params && typeof params.name === 'string') {
130
- primaryTool = params.name;
131
- }
132
- }
133
- }
134
- return { toolCalls, primaryTool };
135
- }
136
- /**
137
- * Stream-proxy a request to a local container upstream, preserving method,
138
- * headers, body, and streaming the response (including long-lived SSE).
139
- *
140
- * @param bufferedBody Pre-read request body to forward (empty for GET/DELETE).
141
- */
142
- export function proxyToUpstream(req, res, upstreamPort, bufferedBody, opts = {}) {
143
- const host = opts.host ?? '127.0.0.1';
144
- const timeoutMs = opts.timeoutMs ?? 120_000;
145
- return new Promise((resolve) => {
146
- // Clone headers, overriding hop-by-hop / length headers we re-derive.
147
- const headers = { ...req.headers };
148
- delete headers['content-length'];
149
- delete headers['connection'];
150
- delete headers['keep-alive'];
151
- delete headers['transfer-encoding'];
152
- headers.host = `${host}:${upstreamPort}`;
153
- const hasBody = BODY_METHODS.has((req.method ?? 'GET').toUpperCase());
154
- if (hasBody) {
155
- headers['content-length'] = String(bufferedBody.length);
156
- }
157
- let settled = false;
158
- const done = () => {
159
- if (settled)
160
- return;
161
- settled = true;
162
- resolve();
163
- };
164
- const upstream = http.request({ host, port: upstreamPort, method: req.method, path: req.url, headers, timeout: timeoutMs }, (proxyRes) => {
165
- // Strip hop-by-hop headers from the upstream response (RFC 7230 §6.1);
166
- // Node manages connection framing for our client side independently.
167
- const resHeaders = {};
168
- for (const [k, v] of Object.entries(proxyRes.headers)) {
169
- if (!HOP_BY_HOP.has(k.toLowerCase()) && v !== undefined)
170
- resHeaders[k] = v;
171
- }
172
- res.writeHead(proxyRes.statusCode ?? 502, resHeaders);
173
- proxyRes.pipe(res);
174
- proxyRes.on('end', done);
175
- proxyRes.on('error', () => {
176
- res.destroy();
177
- done();
178
- });
179
- });
180
- upstream.on('timeout', () => {
181
- upstream.destroy(new Error('upstream timeout'));
182
- });
183
- upstream.on('error', () => {
184
- if (!res.headersSent) {
185
- res.writeHead(502, { 'Content-Type': 'application/json' });
186
- res.end(JSON.stringify({ error: 'Bad gateway: server is unreachable' }));
187
- }
188
- else {
189
- res.destroy();
190
- }
191
- done();
192
- });
193
- // If the client disconnects, tear down the upstream request.
194
- res.on('close', () => {
195
- if (!settled)
196
- upstream.destroy();
197
- });
198
- if (hasBody)
199
- upstream.end(bufferedBody);
200
- else
201
- upstream.end();
202
- });
203
- }
@@ -1,43 +0,0 @@
1
- /**
2
- * Durable time-series of host/API metrics for the admin charts.
3
- *
4
- * One row is written per sampler tick (every ~5 min by the ResourceMonitor's
5
- * onSample hook). Backed by the `metric_samples` Postgres table when a database
6
- * is configured; otherwise a bounded in-memory ring (dev / single-process).
7
- *
8
- * `requests`/`errors_*` are PER-INTERVAL deltas (read from the rolling
9
- * FailureTracker window), not cumulative totals.
10
- */
11
- import type { Database } from './db/index.js';
12
- export interface MetricSample {
13
- /** ISO timestamp. */
14
- sampledAt: string;
15
- requests: number;
16
- errors4xx: number;
17
- errors5xx: number;
18
- activeContainers: number;
19
- memUsedPct: number;
20
- diskUsedPct: number;
21
- totalUsers: number;
22
- totalServers: number;
23
- }
24
- export interface MetricSampleStore {
25
- record(sample: MetricSample): Promise<void>;
26
- /** Samples with `sampledAt` within the last `sinceMs`, oldest first. */
27
- recent(sinceMs: number): Promise<MetricSample[]>;
28
- /** Delete samples older than `olderThanMs`. */
29
- prune(olderThanMs: number): Promise<void>;
30
- }
31
- export declare class InMemoryMetricSampleStore implements MetricSampleStore {
32
- private samples;
33
- record(sample: MetricSample): Promise<void>;
34
- recent(sinceMs: number): Promise<MetricSample[]>;
35
- prune(olderThanMs: number): Promise<void>;
36
- }
37
- export declare class PgMetricSampleStore implements MetricSampleStore {
38
- private db;
39
- constructor(db: Database);
40
- record(sample: MetricSample): Promise<void>;
41
- recent(sinceMs: number): Promise<MetricSample[]>;
42
- prune(olderThanMs: number): Promise<void>;
43
- }
@@ -1,85 +0,0 @@
1
- /**
2
- * Durable time-series of host/API metrics for the admin charts.
3
- *
4
- * One row is written per sampler tick (every ~5 min by the ResourceMonitor's
5
- * onSample hook). Backed by the `metric_samples` Postgres table when a database
6
- * is configured; otherwise a bounded in-memory ring (dev / single-process).
7
- *
8
- * `requests`/`errors_*` are PER-INTERVAL deltas (read from the rolling
9
- * FailureTracker window), not cumulative totals.
10
- */
11
- import { randomBytes } from 'node:crypto';
12
- // ---------------------------------------------------------------------------
13
- // In-memory (dev / no database) — bounded ring
14
- // ---------------------------------------------------------------------------
15
- /** 24h at 5-min cadence. */
16
- const MAX_INMEMORY_SAMPLES = 288;
17
- export class InMemoryMetricSampleStore {
18
- samples = [];
19
- async record(sample) {
20
- this.samples.push(sample);
21
- if (this.samples.length > MAX_INMEMORY_SAMPLES) {
22
- this.samples.splice(0, this.samples.length - MAX_INMEMORY_SAMPLES);
23
- }
24
- }
25
- async recent(sinceMs) {
26
- const cutoff = Date.now() - sinceMs;
27
- return this.samples.filter((s) => Date.parse(s.sampledAt) >= cutoff);
28
- }
29
- async prune(olderThanMs) {
30
- const cutoff = Date.now() - olderThanMs;
31
- this.samples = this.samples.filter((s) => Date.parse(s.sampledAt) >= cutoff);
32
- }
33
- }
34
- // ---------------------------------------------------------------------------
35
- // Postgres
36
- // ---------------------------------------------------------------------------
37
- export class PgMetricSampleStore {
38
- db;
39
- constructor(db) {
40
- this.db = db;
41
- }
42
- async record(sample) {
43
- await this.db.query(`INSERT INTO metric_samples
44
- (id, sampled_at, requests, errors_4xx, errors_5xx, active_containers,
45
- mem_used_pct, disk_used_pct, total_users, total_servers)
46
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`, [
47
- randomBytes(16).toString('hex'),
48
- sample.sampledAt,
49
- sample.requests,
50
- sample.errors4xx,
51
- sample.errors5xx,
52
- sample.activeContainers,
53
- sample.memUsedPct,
54
- sample.diskUsedPct,
55
- sample.totalUsers,
56
- sample.totalServers,
57
- ]);
58
- }
59
- async recent(sinceMs) {
60
- const since = new Date(Date.now() - sinceMs).toISOString();
61
- const { rows } = await this.db.query(`SELECT sampled_at, requests, errors_4xx, errors_5xx, active_containers,
62
- mem_used_pct, disk_used_pct, total_users, total_servers
63
- FROM metric_samples WHERE sampled_at >= $1 ORDER BY sampled_at ASC`, [since]);
64
- return rows.map(rowToSample);
65
- }
66
- async prune(olderThanMs) {
67
- const cutoff = new Date(Date.now() - olderThanMs).toISOString();
68
- await this.db.query('DELETE FROM metric_samples WHERE sampled_at < $1', [cutoff]);
69
- }
70
- }
71
- function rowToSample(row) {
72
- const num = (v) => (typeof v === 'number' ? v : Number(v ?? 0));
73
- const sampledAt = row.sampled_at;
74
- return {
75
- sampledAt: typeof sampledAt === 'string' ? sampledAt : new Date(sampledAt).toISOString(),
76
- requests: num(row.requests),
77
- errors4xx: num(row.errors_4xx),
78
- errors5xx: num(row.errors_5xx),
79
- activeContainers: num(row.active_containers),
80
- memUsedPct: num(row.mem_used_pct),
81
- diskUsedPct: num(row.disk_used_pct),
82
- totalUsers: num(row.total_users),
83
- totalServers: num(row.total_servers),
84
- };
85
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * In-memory usage metrics for hosted MCP servers.
3
- * Tracks request counts, tool call breakdowns, and activity timestamps.
4
- */
5
- export interface ServerMetrics {
6
- slug: string;
7
- totalRequests: number;
8
- toolCalls: Record<string, number>;
9
- lastActiveAt: string;
10
- createdAt: string;
11
- }
12
- export declare class MetricsStore {
13
- private metrics;
14
- init(slug: string): void;
15
- recordRequest(slug: string, toolName?: string): void;
16
- get(slug: string): ServerMetrics | undefined;
17
- getAll(): ServerMetrics[];
18
- delete(slug: string): void;
19
- /**
20
- * Get top tools by call count for a given server.
21
- */
22
- getTopTools(slug: string, limit?: number): Array<{
23
- tool: string;
24
- calls: number;
25
- }>;
26
- }
@@ -1,59 +0,0 @@
1
- /**
2
- * In-memory usage metrics for hosted MCP servers.
3
- * Tracks request counts, tool call breakdowns, and activity timestamps.
4
- */
5
- export class MetricsStore {
6
- metrics = new Map();
7
- init(slug) {
8
- if (this.metrics.has(slug))
9
- return;
10
- const now = new Date().toISOString();
11
- this.metrics.set(slug, {
12
- slug,
13
- totalRequests: 0,
14
- toolCalls: {},
15
- lastActiveAt: now,
16
- createdAt: now,
17
- });
18
- }
19
- recordRequest(slug, toolName) {
20
- let entry = this.metrics.get(slug);
21
- if (!entry) {
22
- this.init(slug);
23
- entry = this.metrics.get(slug);
24
- }
25
- entry.totalRequests++;
26
- entry.lastActiveAt = new Date().toISOString();
27
- if (toolName) {
28
- // Only track if the tool is already known or we haven't hit the cap
29
- if (toolName in entry.toolCalls || Object.keys(entry.toolCalls).length < 500) {
30
- entry.toolCalls[toolName] = (entry.toolCalls[toolName] ?? 0) + 1;
31
- }
32
- }
33
- }
34
- get(slug) {
35
- const entry = this.metrics.get(slug);
36
- return entry ? { ...entry, toolCalls: { ...entry.toolCalls } } : undefined;
37
- }
38
- getAll() {
39
- return [...this.metrics.values()].map((e) => ({
40
- ...e,
41
- toolCalls: { ...e.toolCalls },
42
- }));
43
- }
44
- delete(slug) {
45
- this.metrics.delete(slug);
46
- }
47
- /**
48
- * Get top tools by call count for a given server.
49
- */
50
- getTopTools(slug, limit = 10) {
51
- const entry = this.metrics.get(slug);
52
- if (!entry)
53
- return [];
54
- return Object.entries(entry.toolCalls)
55
- .sort(([, a], [, b]) => b - a)
56
- .slice(0, limit)
57
- .map(([tool, calls]) => ({ tool, calls }));
58
- }
59
- }