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.
Files changed (344) hide show
  1. package/README.md +691 -0
  2. package/bin/mcpmake.mjs +2 -0
  3. package/dist/analyzer/auth-detector.d.ts +12 -0
  4. package/dist/analyzer/auth-detector.js +142 -0
  5. package/dist/analyzer/dom-parser.d.ts +10 -0
  6. package/dist/analyzer/dom-parser.js +259 -0
  7. package/dist/analyzer/goal-crawler.d.ts +25 -0
  8. package/dist/analyzer/goal-crawler.js +177 -0
  9. package/dist/analyzer/hybrid-detector.d.ts +28 -0
  10. package/dist/analyzer/hybrid-detector.js +96 -0
  11. package/dist/analyzer/index.d.ts +12 -0
  12. package/dist/analyzer/index.js +8 -0
  13. package/dist/analyzer/screenshot-capture.d.ts +29 -0
  14. package/dist/analyzer/screenshot-capture.js +42 -0
  15. package/dist/analyzer/selector-builder.d.ts +19 -0
  16. package/dist/analyzer/selector-builder.js +199 -0
  17. package/dist/analyzer/semantic-analyzer.d.ts +13 -0
  18. package/dist/analyzer/semantic-analyzer.js +145 -0
  19. package/dist/analyzer/site-crawler.d.ts +38 -0
  20. package/dist/analyzer/site-crawler.js +235 -0
  21. package/dist/cloud/billing/billing-engine.d.ts +44 -0
  22. package/dist/cloud/billing/billing-engine.js +81 -0
  23. package/dist/cloud/billing/credit-store.d.ts +64 -0
  24. package/dist/cloud/billing/credit-store.js +168 -0
  25. package/dist/cloud/billing/index.d.ts +4 -0
  26. package/dist/cloud/billing/index.js +2 -0
  27. package/dist/cloud/billing/usage-store.d.ts +42 -0
  28. package/dist/cloud/billing/usage-store.js +85 -0
  29. package/dist/cloud/billing/usage-tracker.d.ts +38 -0
  30. package/dist/cloud/billing/usage-tracker.js +95 -0
  31. package/dist/cloud/build-pipeline.d.ts +39 -0
  32. package/dist/cloud/build-pipeline.js +310 -0
  33. package/dist/cloud/build-queue.d.ts +30 -0
  34. package/dist/cloud/build-queue.js +70 -0
  35. package/dist/cloud/caddy-manager.d.ts +18 -0
  36. package/dist/cloud/caddy-manager.js +97 -0
  37. package/dist/cloud/container-backend.d.ts +62 -0
  38. package/dist/cloud/container-backend.js +59 -0
  39. package/dist/cloud/container-manager.d.ts +64 -0
  40. package/dist/cloud/container-manager.js +301 -0
  41. package/dist/cloud/crypto.d.ts +27 -0
  42. package/dist/cloud/crypto.js +63 -0
  43. package/dist/cloud/db/index.d.ts +27 -0
  44. package/dist/cloud/db/index.js +53 -0
  45. package/dist/cloud/db/migrations.d.ts +12 -0
  46. package/dist/cloud/db/migrations.js +329 -0
  47. package/dist/cloud/db/pg-store.d.ts +45 -0
  48. package/dist/cloud/db/pg-store.js +336 -0
  49. package/dist/cloud/failure-tracker.d.ts +51 -0
  50. package/dist/cloud/failure-tracker.js +102 -0
  51. package/dist/cloud/idle-monitor.d.ts +30 -0
  52. package/dist/cloud/idle-monitor.js +70 -0
  53. package/dist/cloud/mailer.d.ts +21 -0
  54. package/dist/cloud/mailer.js +193 -0
  55. package/dist/cloud/mcp-proxy.d.ts +58 -0
  56. package/dist/cloud/mcp-proxy.js +203 -0
  57. package/dist/cloud/metric-samples.d.ts +43 -0
  58. package/dist/cloud/metric-samples.js +85 -0
  59. package/dist/cloud/metrics.d.ts +26 -0
  60. package/dist/cloud/metrics.js +59 -0
  61. package/dist/cloud/multipart.d.ts +26 -0
  62. package/dist/cloud/multipart.js +132 -0
  63. package/dist/cloud/observability.d.ts +27 -0
  64. package/dist/cloud/observability.js +98 -0
  65. package/dist/cloud/rate-limiter.d.ts +31 -0
  66. package/dist/cloud/rate-limiter.js +58 -0
  67. package/dist/cloud/request-security.d.ts +5 -0
  68. package/dist/cloud/request-security.js +74 -0
  69. package/dist/cloud/resource-monitor.d.ts +69 -0
  70. package/dist/cloud/resource-monitor.js +130 -0
  71. package/dist/cloud/secret-store.d.ts +38 -0
  72. package/dist/cloud/secret-store.js +103 -0
  73. package/dist/cloud/security.d.ts +26 -0
  74. package/dist/cloud/security.js +142 -0
  75. package/dist/cloud/server.d.ts +21 -0
  76. package/dist/cloud/server.js +1079 -0
  77. package/dist/cloud/shared-state.d.ts +72 -0
  78. package/dist/cloud/shared-state.js +159 -0
  79. package/dist/cloud/ssrf.d.ts +43 -0
  80. package/dist/cloud/ssrf.js +150 -0
  81. package/dist/cloud/store.d.ts +41 -0
  82. package/dist/cloud/store.js +75 -0
  83. package/dist/cloud/stripe.d.ts +78 -0
  84. package/dist/cloud/stripe.js +317 -0
  85. package/dist/cloud/telemetry-store.d.ts +53 -0
  86. package/dist/cloud/telemetry-store.js +108 -0
  87. package/dist/cloud/web/auth.d.ts +225 -0
  88. package/dist/cloud/web/auth.js +555 -0
  89. package/dist/cloud/web/charts.d.ts +70 -0
  90. package/dist/cloud/web/charts.js +178 -0
  91. package/dist/cloud/web/csrf.d.ts +14 -0
  92. package/dist/cloud/web/csrf.js +22 -0
  93. package/dist/cloud/web/docs.d.ts +40 -0
  94. package/dist/cloud/web/docs.js +174 -0
  95. package/dist/cloud/web/router.d.ts +25 -0
  96. package/dist/cloud/web/router.js +1921 -0
  97. package/dist/cloud/web/static/alpine.min.js +5 -0
  98. package/dist/cloud/web/static/favicon.svg +4 -0
  99. package/dist/cloud/web/static/htmx-sse.js +290 -0
  100. package/dist/cloud/web/static/htmx.min.js +1 -0
  101. package/dist/cloud/web/static/style.css +2683 -0
  102. package/dist/cloud/web/static-server.d.ts +13 -0
  103. package/dist/cloud/web/static-server.js +73 -0
  104. package/dist/cloud/web/template-engine.d.ts +27 -0
  105. package/dist/cloud/web/template-engine.js +146 -0
  106. package/dist/cloud/web/templates/layouts/admin.hbs +57 -0
  107. package/dist/cloud/web/templates/layouts/auth.hbs +138 -0
  108. package/dist/cloud/web/templates/layouts/base.hbs +16 -0
  109. package/dist/cloud/web/templates/layouts/dashboard.hbs +39 -0
  110. package/dist/cloud/web/templates/layouts/landing.hbs +82 -0
  111. package/dist/cloud/web/templates/pages/admin/overview.hbs +123 -0
  112. package/dist/cloud/web/templates/pages/admin/servers.hbs +129 -0
  113. package/dist/cloud/web/templates/pages/admin/telemetry.hbs +39 -0
  114. package/dist/cloud/web/templates/pages/admin/user-edit.hbs +91 -0
  115. package/dist/cloud/web/templates/pages/admin/users.hbs +179 -0
  116. package/dist/cloud/web/templates/pages/auth/forgot-password.hbs +25 -0
  117. package/dist/cloud/web/templates/pages/auth/login.hbs +33 -0
  118. package/dist/cloud/web/templates/pages/auth/register.hbs +32 -0
  119. package/dist/cloud/web/templates/pages/auth/reset-password.hbs +34 -0
  120. package/dist/cloud/web/templates/pages/dashboard/billing.hbs +140 -0
  121. package/dist/cloud/web/templates/pages/dashboard/create.hbs +173 -0
  122. package/dist/cloud/web/templates/pages/dashboard/index.hbs +8 -0
  123. package/dist/cloud/web/templates/pages/dashboard/server-detail.hbs +280 -0
  124. package/dist/cloud/web/templates/pages/dashboard/server-logs.hbs +35 -0
  125. package/dist/cloud/web/templates/pages/dashboard/server-metrics.hbs +63 -0
  126. package/dist/cloud/web/templates/pages/dashboard/servers-partial.hbs +21 -0
  127. package/dist/cloud/web/templates/pages/dashboard/servers.hbs +44 -0
  128. package/dist/cloud/web/templates/pages/docs/show.hbs +16 -0
  129. package/dist/cloud/web/templates/pages/errors/404.hbs +9 -0
  130. package/dist/cloud/web/templates/pages/errors/500.hbs +8 -0
  131. package/dist/cloud/web/templates/pages/landing/index.hbs +223 -0
  132. package/dist/cloud/web/templates/pages/legal/privacy.hbs +71 -0
  133. package/dist/cloud/web/templates/pages/legal/terms.hbs +73 -0
  134. package/dist/cloud/web/templates/partials/admin-stats.hbs +52 -0
  135. package/dist/cloud/web/templates/partials/flash-message.hbs +6 -0
  136. package/dist/cloud/web/templates/partials/pricing-table.hbs +103 -0
  137. package/dist/cloud/web/templates/partials/server-card.hbs +19 -0
  138. package/dist/cloud/web/templates/partials/status-badge.hbs +1 -0
  139. package/dist/commands/bundle.d.ts +18 -0
  140. package/dist/commands/bundle.js +82 -0
  141. package/dist/commands/ci.d.ts +25 -0
  142. package/dist/commands/ci.js +149 -0
  143. package/dist/commands/deploy.d.ts +24 -0
  144. package/dist/commands/deploy.js +145 -0
  145. package/dist/commands/diff.d.ts +18 -0
  146. package/dist/commands/diff.js +185 -0
  147. package/dist/commands/from/describe.d.ts +65 -0
  148. package/dist/commands/from/describe.js +173 -0
  149. package/dist/commands/from/har.d.ts +81 -0
  150. package/dist/commands/from/har.js +255 -0
  151. package/dist/commands/from/openapi.d.ts +105 -0
  152. package/dist/commands/from/openapi.js +302 -0
  153. package/dist/commands/from/postman.d.ts +51 -0
  154. package/dist/commands/from/postman.js +146 -0
  155. package/dist/commands/from/target-support.d.ts +11 -0
  156. package/dist/commands/from/target-support.js +33 -0
  157. package/dist/commands/from/url.d.ts +75 -0
  158. package/dist/commands/from/url.js +244 -0
  159. package/dist/commands/from/website.d.ts +75 -0
  160. package/dist/commands/from/website.js +284 -0
  161. package/dist/commands/lint.d.ts +24 -0
  162. package/dist/commands/lint.js +184 -0
  163. package/dist/commands/merge.d.ts +18 -0
  164. package/dist/commands/merge.js +161 -0
  165. package/dist/commands/publish.d.ts +27 -0
  166. package/dist/commands/publish.js +334 -0
  167. package/dist/commands/rescan.d.ts +40 -0
  168. package/dist/commands/rescan.js +255 -0
  169. package/dist/commands/update.d.ts +14 -0
  170. package/dist/commands/update.js +87 -0
  171. package/dist/commands/verify.d.ts +14 -0
  172. package/dist/commands/verify.js +71 -0
  173. package/dist/config/configurable-command.d.ts +13 -0
  174. package/dist/config/configurable-command.js +70 -0
  175. package/dist/config/mcpmake-config.d.ts +68 -0
  176. package/dist/config/mcpmake-config.js +207 -0
  177. package/dist/docs/cli.md +400 -0
  178. package/dist/docs/mcp-2026-07-28-migration.md +78 -0
  179. package/dist/docs/migrate-from-stainless.md +94 -0
  180. package/dist/docs/quickstart.md +166 -0
  181. package/dist/docs/show-hn.md +26 -0
  182. package/dist/docs/website-servers.md +169 -0
  183. package/dist/emitter/code-writer.d.ts +8 -0
  184. package/dist/emitter/code-writer.js +25 -0
  185. package/dist/emitter/index.d.ts +32 -0
  186. package/dist/emitter/index.js +280 -0
  187. package/dist/emitter/mcpb-bundler.d.ts +31 -0
  188. package/dist/emitter/mcpb-bundler.js +172 -0
  189. package/dist/emitter/project-scaffolder.d.ts +4 -0
  190. package/dist/emitter/project-scaffolder.js +89 -0
  191. package/dist/emitter/python-template-loader.d.ts +4 -0
  192. package/dist/emitter/python-template-loader.js +30 -0
  193. package/dist/emitter/python-templates/dockerfile.hbs +14 -0
  194. package/dist/emitter/python-templates/env.example.hbs +6 -0
  195. package/dist/emitter/python-templates/requirements.txt.hbs +4 -0
  196. package/dist/emitter/python-templates/server.py.hbs +77 -0
  197. package/dist/emitter/site-scaffolder.d.ts +13 -0
  198. package/dist/emitter/site-scaffolder.js +70 -0
  199. package/dist/emitter/site-template-loader.d.ts +5 -0
  200. package/dist/emitter/site-template-loader.js +47 -0
  201. package/dist/emitter/site-templates/browser-manager.ts.hbs +233 -0
  202. package/dist/emitter/site-templates/config.ts.hbs +28 -0
  203. package/dist/emitter/site-templates/dockerfile.hbs +31 -0
  204. package/dist/emitter/site-templates/env.example.hbs +19 -0
  205. package/dist/emitter/site-templates/package.json.hbs +26 -0
  206. package/dist/emitter/site-templates/server-main-http.ts.hbs +108 -0
  207. package/dist/emitter/site-templates/server-main.ts.hbs +23 -0
  208. package/dist/emitter/site-templates/tool-handler-action.ts.hbs +86 -0
  209. package/dist/emitter/site-templates/tool-handler-form.ts.hbs +116 -0
  210. package/dist/emitter/site-templates/tool-handler-lifecycle.ts.hbs +146 -0
  211. package/dist/emitter/site-templates/tool-index.ts.hbs +11 -0
  212. package/dist/emitter/template-loader.d.ts +1 -0
  213. package/dist/emitter/template-loader.js +27 -0
  214. package/dist/emitter/templates/auth-provider.ts.hbs +57 -0
  215. package/dist/emitter/templates/config.ts.hbs +63 -0
  216. package/dist/emitter/templates/discovery.ts.hbs +301 -0
  217. package/dist/emitter/templates/dockerfile.hbs +34 -0
  218. package/dist/emitter/templates/env.example.hbs +28 -0
  219. package/dist/emitter/templates/gitignore.hbs +5 -0
  220. package/dist/emitter/templates/http-executor.ts.hbs +117 -0
  221. package/dist/emitter/templates/oauth.ts.hbs +188 -0
  222. package/dist/emitter/templates/package.json.hbs +25 -0
  223. package/dist/emitter/templates/prompts.ts.hbs +22 -0
  224. package/dist/emitter/templates/readme.md.hbs +123 -0
  225. package/dist/emitter/templates/resources.ts.hbs +63 -0
  226. package/dist/emitter/templates/server-main-http.ts.hbs +407 -0
  227. package/dist/emitter/templates/server-main.ts.hbs +40 -0
  228. package/dist/emitter/templates/task-handlers.ts.hbs +189 -0
  229. package/dist/emitter/templates/task-manager.ts.hbs +139 -0
  230. package/dist/emitter/templates/task-sse.ts.hbs +105 -0
  231. package/dist/emitter/templates/tool-handler.ts.hbs +124 -0
  232. package/dist/emitter/templates/tool-index.ts.hbs +11 -0
  233. package/dist/emitter/templates/tool-test.ts.hbs +57 -0
  234. package/dist/emitter/templates/trace.ts.hbs +79 -0
  235. package/dist/emitter/templates/tsconfig.json.hbs +16 -0
  236. package/dist/emitter/templates/types.ts.hbs +5 -0
  237. package/dist/emitter/worker-template-loader.d.ts +5 -0
  238. package/dist/emitter/worker-template-loader.js +33 -0
  239. package/dist/emitter/worker-templates/config.ts.hbs +54 -0
  240. package/dist/emitter/worker-templates/dev-vars.example.hbs +10 -0
  241. package/dist/emitter/worker-templates/gitignore.hbs +6 -0
  242. package/dist/emitter/worker-templates/package.json.hbs +24 -0
  243. package/dist/emitter/worker-templates/readme.md.hbs +53 -0
  244. package/dist/emitter/worker-templates/server.test.ts.hbs +20 -0
  245. package/dist/emitter/worker-templates/tool-handler.ts.hbs +85 -0
  246. package/dist/emitter/worker-templates/tool-index.ts.hbs +28 -0
  247. package/dist/emitter/worker-templates/tsconfig.json.hbs +17 -0
  248. package/dist/emitter/worker-templates/worker.ts.hbs +242 -0
  249. package/dist/emitter/worker-templates/wrangler.toml.hbs +19 -0
  250. package/dist/generator/spec-generator.d.ts +6 -0
  251. package/dist/generator/spec-generator.js +50 -0
  252. package/dist/index.d.ts +1 -0
  253. package/dist/index.js +64 -0
  254. package/dist/parser/har-filter.d.ts +8 -0
  255. package/dist/parser/har-filter.js +71 -0
  256. package/dist/parser/har-loader.d.ts +2 -0
  257. package/dist/parser/har-loader.js +14 -0
  258. package/dist/parser/har-normalizer.d.ts +20 -0
  259. package/dist/parser/har-normalizer.js +78 -0
  260. package/dist/parser/index.d.ts +10 -0
  261. package/dist/parser/index.js +6 -0
  262. package/dist/parser/openapi-loader.d.ts +6 -0
  263. package/dist/parser/openapi-loader.js +308 -0
  264. package/dist/parser/operation-extractor.d.ts +13 -0
  265. package/dist/parser/operation-extractor.js +155 -0
  266. package/dist/parser/overlay-loader.d.ts +10 -0
  267. package/dist/parser/overlay-loader.js +184 -0
  268. package/dist/parser/postman-loader.d.ts +9 -0
  269. package/dist/parser/postman-loader.js +106 -0
  270. package/dist/parser/schema-converter.d.ts +12 -0
  271. package/dist/parser/schema-converter.js +117 -0
  272. package/dist/plugins/adapter.d.ts +40 -0
  273. package/dist/plugins/adapter.js +15 -0
  274. package/dist/plugins/loader.d.ts +25 -0
  275. package/dist/plugins/loader.js +58 -0
  276. package/dist/pricing.d.ts +55 -0
  277. package/dist/pricing.js +133 -0
  278. package/dist/providers/index.d.ts +15 -0
  279. package/dist/providers/index.js +56 -0
  280. package/dist/recorder/browser-recorder.d.ts +22 -0
  281. package/dist/recorder/browser-recorder.js +205 -0
  282. package/dist/registry/official-registry.d.ts +90 -0
  283. package/dist/registry/official-registry.js +129 -0
  284. package/dist/rescan/diff-engine.d.ts +5 -0
  285. package/dist/rescan/diff-engine.js +312 -0
  286. package/dist/rescan/index.d.ts +3 -0
  287. package/dist/rescan/index.js +2 -0
  288. package/dist/rescan/rescan-runner.d.ts +42 -0
  289. package/dist/rescan/rescan-runner.js +69 -0
  290. package/dist/rescan/rescan-scheduler.d.ts +41 -0
  291. package/dist/rescan/rescan-scheduler.js +179 -0
  292. package/dist/site-transformer/browser-tools.d.ts +10 -0
  293. package/dist/site-transformer/browser-tools.js +59 -0
  294. package/dist/site-transformer/index.d.ts +2 -0
  295. package/dist/site-transformer/index.js +2 -0
  296. package/dist/site-transformer/selector-healer.d.ts +8 -0
  297. package/dist/site-transformer/selector-healer.js +106 -0
  298. package/dist/site-transformer/tool-generator.d.ts +13 -0
  299. package/dist/site-transformer/tool-generator.js +245 -0
  300. package/dist/transformer/auth-detector.d.ts +13 -0
  301. package/dist/transformer/auth-detector.js +90 -0
  302. package/dist/transformer/catalog-builder.d.ts +18 -0
  303. package/dist/transformer/catalog-builder.js +56 -0
  304. package/dist/transformer/client-compat.d.ts +6 -0
  305. package/dist/transformer/client-compat.js +44 -0
  306. package/dist/transformer/har-clusterer.d.ts +9 -0
  307. package/dist/transformer/har-clusterer.js +27 -0
  308. package/dist/transformer/har-dedup.d.ts +10 -0
  309. package/dist/transformer/har-dedup.js +81 -0
  310. package/dist/transformer/har-schema-inferrer.d.ts +15 -0
  311. package/dist/transformer/har-schema-inferrer.js +90 -0
  312. package/dist/transformer/har-to-operations.d.ts +13 -0
  313. package/dist/transformer/har-to-operations.js +192 -0
  314. package/dist/transformer/index.d.ts +8 -0
  315. package/dist/transformer/index.js +6 -0
  316. package/dist/transformer/llm-namer.d.ts +6 -0
  317. package/dist/transformer/llm-namer.js +59 -0
  318. package/dist/transformer/naming.d.ts +4 -0
  319. package/dist/transformer/naming.js +30 -0
  320. package/dist/transformer/operation-filter.d.ts +13 -0
  321. package/dist/transformer/operation-filter.js +52 -0
  322. package/dist/transformer/resource-builder.d.ts +12 -0
  323. package/dist/transformer/resource-builder.js +80 -0
  324. package/dist/transformer/schema-merger.d.ts +14 -0
  325. package/dist/transformer/schema-merger.js +65 -0
  326. package/dist/transformer/tool-builder.d.ts +3 -0
  327. package/dist/transformer/tool-builder.js +114 -0
  328. package/dist/types/index.d.ts +131 -0
  329. package/dist/types/index.js +1 -0
  330. package/dist/types/site.d.ts +284 -0
  331. package/dist/types/site.js +8 -0
  332. package/dist/utils/fail.d.ts +48 -0
  333. package/dist/utils/fail.js +204 -0
  334. package/dist/utils/fs.d.ts +5 -0
  335. package/dist/utils/fs.js +28 -0
  336. package/dist/utils/interactive.d.ts +6 -0
  337. package/dist/utils/interactive.js +30 -0
  338. package/dist/utils/logger.d.ts +1 -0
  339. package/dist/utils/logger.js +2 -0
  340. package/dist/utils/sanitize.d.ts +28 -0
  341. package/dist/utils/sanitize.js +44 -0
  342. package/dist/utils/watcher.d.ts +11 -0
  343. package/dist/utils/watcher.js +36 -0
  344. package/package.json +65 -0
@@ -0,0 +1,6 @@
1
+ import type { OperationDescriptor } from '../types/index.js';
2
+ /**
3
+ * Use Claude to generate better tool names and descriptions
4
+ * from HAR-captured request/response patterns.
5
+ */
6
+ export declare function improveToolNames(operations: OperationDescriptor[], model?: string): Promise<OperationDescriptor[]>;
@@ -0,0 +1,59 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import { logger } from '../utils/logger.js';
3
+ /**
4
+ * Use Claude to generate better tool names and descriptions
5
+ * from HAR-captured request/response patterns.
6
+ */
7
+ export async function improveToolNames(operations, model) {
8
+ const apiKey = process.env.ANTHROPIC_API_KEY;
9
+ if (!apiKey) {
10
+ logger.warn('ANTHROPIC_API_KEY not set — skipping LLM tool naming');
11
+ return operations;
12
+ }
13
+ const client = new Anthropic({ apiKey });
14
+ const operationSummaries = operations.map((op) => ({
15
+ method: op.method,
16
+ path: op.path,
17
+ currentId: op.operationId,
18
+ summary: op.summary,
19
+ paramNames: op.parameters.map((p) => p.name),
20
+ hasBody: !!op.requestBody,
21
+ tags: op.tags,
22
+ }));
23
+ const prompt = `Given these API operations captured from network traffic, suggest better operationId names and descriptions. Return a JSON array with one object per operation: { "index": number, "operationId": "camelCase name", "summary": "one-line description" }. Keep names concise (camelCase, under 40 chars). Only output JSON, no explanation.
24
+
25
+ Operations:
26
+ ${JSON.stringify(operationSummaries, null, 2)}`;
27
+ try {
28
+ logger.info('Improving tool names with Claude...');
29
+ const message = await client.messages.create({
30
+ model: model ?? 'claude-sonnet-4-20250514',
31
+ max_tokens: 2048,
32
+ messages: [{ role: 'user', content: prompt }],
33
+ });
34
+ const content = message.content[0];
35
+ if (content.type !== 'text')
36
+ return operations;
37
+ let json = content.text.trim();
38
+ if (json.startsWith('```')) {
39
+ json = json.replace(/^```(?:json)?\n?/, '').replace(/\n?```$/, '');
40
+ }
41
+ const improvements = JSON.parse(json);
42
+ const result = operations.map((op, i) => {
43
+ const improvement = improvements.find((imp) => imp.index === i);
44
+ if (!improvement)
45
+ return op;
46
+ return {
47
+ ...op,
48
+ operationId: improvement.operationId || op.operationId,
49
+ summary: improvement.summary || op.summary,
50
+ };
51
+ });
52
+ logger.info(`Improved ${improvements.length} tool names`);
53
+ return result;
54
+ }
55
+ catch (err) {
56
+ logger.warn(`LLM naming failed, using defaults: ${err instanceof Error ? err.message : err}`);
57
+ return operations;
58
+ }
59
+ }
@@ -0,0 +1,4 @@
1
+ export declare function toToolName(operationId: string): string;
2
+ export declare function toToolTitle(operationId: string): string;
3
+ export declare function toFileName(operationId: string): string;
4
+ export declare function toFunctionName(operationId: string): string;
@@ -0,0 +1,30 @@
1
+ export function toToolName(operationId) {
2
+ return toSnakeCase(operationId);
3
+ }
4
+ export function toToolTitle(operationId) {
5
+ const snake = toSnakeCase(operationId);
6
+ return snake
7
+ .split('_')
8
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
9
+ .join(' ');
10
+ }
11
+ export function toFileName(operationId) {
12
+ return toSnakeCase(operationId)
13
+ .replace(/_/g, '-')
14
+ .replace(/\.\./g, '')
15
+ .replace(/[/\\]/g, '')
16
+ .replace(/[^a-z0-9\-]/g, '');
17
+ }
18
+ export function toFunctionName(operationId) {
19
+ const snake = toSnakeCase(operationId);
20
+ return snake.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
21
+ }
22
+ function toSnakeCase(str) {
23
+ return str
24
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
25
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
26
+ .replace(/[\s\-]+/g, '_')
27
+ .toLowerCase()
28
+ .replace(/^_+|_+$/g, '')
29
+ .replace(/_+/g, '_');
30
+ }
@@ -0,0 +1,13 @@
1
+ import type { OperationDescriptor } from '../types/index.js';
2
+ export interface FilterOptions {
3
+ include?: string[];
4
+ exclude?: string[];
5
+ }
6
+ /**
7
+ * Filter operations by tag or path pattern.
8
+ * Patterns can be:
9
+ * - A tag name: "pets" matches operations tagged with "pets"
10
+ * - A path prefix: "/users*" matches /users, /users/{id}, etc.
11
+ * - A glob-like pattern: "*admin*" matches any operation with "admin" in path or tags
12
+ */
13
+ export declare function filterOperations(operations: OperationDescriptor[], options: FilterOptions): OperationDescriptor[];
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Filter operations by tag or path pattern.
3
+ * Patterns can be:
4
+ * - A tag name: "pets" matches operations tagged with "pets"
5
+ * - A path prefix: "/users*" matches /users, /users/{id}, etc.
6
+ * - A glob-like pattern: "*admin*" matches any operation with "admin" in path or tags
7
+ */
8
+ export function filterOperations(operations, options) {
9
+ let result = operations;
10
+ if (options.include?.length) {
11
+ result = result.filter((op) => options.include.some((pattern) => matchesOperation(op, pattern)));
12
+ }
13
+ if (options.exclude?.length) {
14
+ result = result.filter((op) => !options.exclude.some((pattern) => matchesOperation(op, pattern)));
15
+ }
16
+ return result;
17
+ }
18
+ function matchesOperation(op, pattern) {
19
+ const lowerPattern = pattern.toLowerCase();
20
+ // Check tag match
21
+ if (op.tags.some((t) => t.toLowerCase() === lowerPattern))
22
+ return true;
23
+ // Check path match with simple glob support
24
+ if (matchGlob(op.path.toLowerCase(), lowerPattern))
25
+ return true;
26
+ // Check operationId match
27
+ if (op.operationId.toLowerCase().includes(lowerPattern))
28
+ return true;
29
+ return false;
30
+ }
31
+ function matchGlob(str, pattern) {
32
+ // Simple glob matching without regex to avoid ReDoS.
33
+ // Split pattern by '*' and check that all parts appear in order.
34
+ const parts = pattern.split('*');
35
+ let pos = 0;
36
+ for (let i = 0; i < parts.length; i++) {
37
+ const part = parts[i];
38
+ if (part === '')
39
+ continue;
40
+ const idx = str.indexOf(part, pos);
41
+ if (idx === -1)
42
+ return false;
43
+ // First segment must match at start, last at end
44
+ if (i === 0 && idx !== 0)
45
+ return false;
46
+ pos = idx + part.length;
47
+ }
48
+ // If pattern doesn't end with *, the string must end at pos
49
+ if (!pattern.endsWith('*') && pos !== str.length)
50
+ return false;
51
+ return true;
52
+ }
@@ -0,0 +1,12 @@
1
+ import type { OperationDescriptor } from '../types/index.js';
2
+ import type { ResourceDefinition, PromptDefinition } from '../types/index.js';
3
+ /**
4
+ * Generate MCP resources from GET operations.
5
+ * - List endpoints (no path params) → static resources
6
+ * - Detail endpoints (with path params) → URI template resources
7
+ */
8
+ export declare function buildResources(operations: OperationDescriptor[]): ResourceDefinition[];
9
+ /**
10
+ * Generate MCP prompts — one per tag as a "workflow" prompt.
11
+ */
12
+ export declare function buildPrompts(operations: OperationDescriptor[]): PromptDefinition[];
@@ -0,0 +1,80 @@
1
+ import { escapeTemplateLiteral, escapeStringLiteral, sanitizeIdentifier, } from '../utils/sanitize.js';
2
+ import { toToolName } from './naming.js';
3
+ /**
4
+ * Generate MCP resources from GET operations.
5
+ * - List endpoints (no path params) → static resources
6
+ * - Detail endpoints (with path params) → URI template resources
7
+ */
8
+ export function buildResources(operations) {
9
+ const resources = [];
10
+ for (const op of operations) {
11
+ if (op.method !== 'get')
12
+ continue;
13
+ const name = toToolName(op.operationId);
14
+ const description = escapeTemplateLiteral(op.summary ?? `${op.method.toUpperCase()} ${op.path}`);
15
+ if (!op.path.includes('{')) {
16
+ // Static resource — list endpoint
17
+ resources.push({
18
+ name,
19
+ uri: `api://${name}`,
20
+ path: op.path,
21
+ description,
22
+ });
23
+ }
24
+ else {
25
+ // Template resource — detail endpoint with path params
26
+ const pathParams = op.parameters.filter((p) => p.in === 'path').map((p) => p.name);
27
+ const uriTemplate = `api://${name}/${pathParams.map((p) => `{${p}}`).join('/')}`;
28
+ // Pre-compute URL body to avoid Handlebars/curly-brace conflicts.
29
+ // Resource handler receives (uri: URL, extra) — extract params from uri.pathname.
30
+ const urlLines = [];
31
+ urlLines.push(` const pathParts = uri.pathname.split('/').filter(Boolean);`);
32
+ urlLines.push(` let url = \`\${config.baseUrl}${escapeStringLiteral(op.path)}\`;`);
33
+ // Replace path params using positional extraction from the URI
34
+ const pathSegments = op.path.split('/').filter(Boolean);
35
+ for (let i = 0; i < pathSegments.length; i++) {
36
+ const seg = pathSegments[i];
37
+ if (seg.startsWith('{') && seg.endsWith('}')) {
38
+ const safe = sanitizeIdentifier(seg.slice(1, -1));
39
+ urlLines.push(` if (pathParts[${i}]) url = url.replace('${escapeStringLiteral(seg)}', encodeURIComponent(pathParts[${i}]));`);
40
+ }
41
+ }
42
+ resources.push({
43
+ name,
44
+ uri: uriTemplate,
45
+ path: op.path,
46
+ description,
47
+ isTemplate: true,
48
+ templateParams: pathParams,
49
+ urlBody: urlLines.join('\n'),
50
+ });
51
+ }
52
+ }
53
+ return resources;
54
+ }
55
+ /**
56
+ * Generate MCP prompts — one per tag as a "workflow" prompt.
57
+ */
58
+ export function buildPrompts(operations) {
59
+ const tagGroups = new Map();
60
+ for (const op of operations) {
61
+ const tag = op.tags[0] ?? 'default';
62
+ const existing = tagGroups.get(tag);
63
+ if (existing)
64
+ existing.push(op);
65
+ else
66
+ tagGroups.set(tag, [op]);
67
+ }
68
+ const prompts = [];
69
+ for (const [tag, ops] of tagGroups) {
70
+ const toolList = ops
71
+ .map((op) => `- ${toToolName(op.operationId)}: ${op.summary ?? op.path}`)
72
+ .join('\\n');
73
+ prompts.push({
74
+ name: `${tag}_workflow`,
75
+ description: escapeTemplateLiteral(`Work with ${tag} — available operations`),
76
+ template: escapeTemplateLiteral(`You have the following ${tag} tools available:\\n${toolList}\\n\\nWhat would you like to do?`),
77
+ });
78
+ }
79
+ return prompts;
80
+ }
@@ -0,0 +1,14 @@
1
+ import type { JsonSchema } from '../types/index.js';
2
+ /**
3
+ * Merge multiple JSON schemas into one that covers all observed fields.
4
+ * Uses a union approach: if a field appears in any sample, it's included
5
+ * (marked optional if not present in all samples).
6
+ */
7
+ export declare function mergeSchemas(schemas: JsonSchema[]): JsonSchema;
8
+ /**
9
+ * Merge request body schemas from multiple HAR entries in a cluster.
10
+ */
11
+ export declare function mergeRequestBodySchemas(bodies: Array<{
12
+ text: string;
13
+ mimeType: string;
14
+ }>): JsonSchema | undefined;
@@ -0,0 +1,65 @@
1
+ import { inferJsonSchema } from './har-schema-inferrer.js';
2
+ /**
3
+ * Merge multiple JSON schemas into one that covers all observed fields.
4
+ * Uses a union approach: if a field appears in any sample, it's included
5
+ * (marked optional if not present in all samples).
6
+ */
7
+ export function mergeSchemas(schemas) {
8
+ if (schemas.length === 0)
9
+ return { type: 'object' };
10
+ if (schemas.length === 1)
11
+ return schemas[0];
12
+ // Only merge object schemas
13
+ if (!schemas.every((s) => s.type === 'object'))
14
+ return schemas[0];
15
+ const allProperties = new Map();
16
+ const requiredCounts = new Map();
17
+ for (const schema of schemas) {
18
+ const props = (schema.properties ?? {});
19
+ const required = new Set(schema.required ?? []);
20
+ for (const [key, propSchema] of Object.entries(props)) {
21
+ const existing = allProperties.get(key);
22
+ if (existing)
23
+ existing.push(propSchema);
24
+ else
25
+ allProperties.set(key, [propSchema]);
26
+ if (required.has(key)) {
27
+ requiredCounts.set(key, (requiredCounts.get(key) ?? 0) + 1);
28
+ }
29
+ }
30
+ }
31
+ const mergedProperties = {};
32
+ const mergedRequired = [];
33
+ for (const [key, propSchemas] of allProperties) {
34
+ // Use the most common type
35
+ mergedProperties[key] = propSchemas[0];
36
+ // Only required if present in ALL samples
37
+ if ((requiredCounts.get(key) ?? 0) === schemas.length) {
38
+ mergedRequired.push(key);
39
+ }
40
+ }
41
+ return {
42
+ type: 'object',
43
+ properties: mergedProperties,
44
+ ...(mergedRequired.length > 0 ? { required: mergedRequired } : {}),
45
+ };
46
+ }
47
+ /**
48
+ * Merge request body schemas from multiple HAR entries in a cluster.
49
+ */
50
+ export function mergeRequestBodySchemas(bodies) {
51
+ const schemas = [];
52
+ for (const body of bodies) {
53
+ if (!body.text || !body.mimeType.includes('json'))
54
+ continue;
55
+ try {
56
+ schemas.push(inferJsonSchema(JSON.parse(body.text)));
57
+ }
58
+ catch {
59
+ continue;
60
+ }
61
+ }
62
+ if (schemas.length === 0)
63
+ return undefined;
64
+ return mergeSchemas(schemas);
65
+ }
@@ -0,0 +1,3 @@
1
+ import type { OperationDescriptor, ToolDefinition } from '../types/index.js';
2
+ export declare function buildToolDefinition(op: OperationDescriptor): ToolDefinition;
3
+ export declare function buildAllTools(operations: OperationDescriptor[]): ToolDefinition[];
@@ -0,0 +1,114 @@
1
+ import { buildOperationInputSchema, jsonSchemaToOutputZodCode, } from '../parser/schema-converter.js';
2
+ import { toToolName, toToolTitle, toFileName, toFunctionName } from './naming.js';
3
+ import { escapeTemplateLiteral, escapeStringLiteral, sanitizeIdentifier, sanitizePathTemplate, } from '../utils/sanitize.js';
4
+ export function buildToolDefinition(op) {
5
+ const inputSchemaCode = buildOperationInputSchema(op);
6
+ const descParts = [];
7
+ if (op.summary)
8
+ descParts.push(op.summary);
9
+ if (op.description && op.description !== op.summary)
10
+ descParts.push(op.description);
11
+ if (op.deprecated)
12
+ descParts.push('[DEPRECATED]');
13
+ if (op.mcpExtensions?.deprecationMessage) {
14
+ descParts.push(`[DEPRECATED: ${op.mcpExtensions.deprecationMessage}]`);
15
+ }
16
+ if (op.mcpExtensions?.deprecationReplacement) {
17
+ descParts.push(`Use ${op.mcpExtensions.deprecationReplacement} instead.`);
18
+ }
19
+ const description = escapeTemplateLiteral(descParts.join(' — ') || `${op.method.toUpperCase()} ${op.path}`);
20
+ const pathParams = op.parameters.filter((p) => p.in === 'path').map((p) => p.name);
21
+ const queryParams = op.parameters.filter((p) => p.in === 'query').map((p) => p.name);
22
+ // Apply x-mcp-* extension overrides
23
+ const mcpName = op.mcpExtensions?.name;
24
+ const mcpDesc = op.mcpExtensions?.description;
25
+ // Output schema from 200 response
26
+ const successResponse = op.responses.find((r) => r.statusCode === '200' || r.statusCode === '201');
27
+ const outputSchemaCode = successResponse?.schema
28
+ ? jsonSchemaToOutputZodCode(successResponse.schema)
29
+ : undefined;
30
+ // Annotations from HTTP method semantics
31
+ const annotations = buildAnnotations(op.method);
32
+ return {
33
+ name: mcpName ? sanitizeIdentifier(mcpName) : toToolName(op.operationId),
34
+ title: mcpName ? mcpName : toToolTitle(op.operationId),
35
+ description: mcpDesc ? escapeTemplateLiteral(mcpDesc) : description,
36
+ inputSchemaCode,
37
+ outputSchemaCode,
38
+ operationId: op.operationId,
39
+ method: op.method,
40
+ pathTemplate: op.path,
41
+ pathParams,
42
+ queryParams,
43
+ headerParams: op.parameters.filter((p) => p.in === 'header').map((p) => p.name),
44
+ hasRequestBody: !!op.requestBody,
45
+ requestBodyContentType: op.requestBody?.contentType ?? 'application/json',
46
+ fileName: toFileName(op.operationId),
47
+ functionName: toFunctionName(op.operationId),
48
+ buildUrlBody: generateBuildUrlBody(op.path, pathParams, queryParams),
49
+ annotations,
50
+ isAsync: op.responses.some((r) => r.statusCode === '202'),
51
+ isDestructive: op.method === 'delete',
52
+ jqFilter: op.mcpExtensions?.jqFilter,
53
+ };
54
+ }
55
+ function buildAnnotations(method) {
56
+ switch (method) {
57
+ case 'get':
58
+ case 'head':
59
+ case 'options':
60
+ return { readOnlyHint: true };
61
+ case 'delete':
62
+ return { destructiveHint: true };
63
+ case 'put':
64
+ return { idempotentHint: true };
65
+ default:
66
+ return undefined;
67
+ }
68
+ }
69
+ function generateBuildUrlBody(pathTemplate, pathParams, queryParams) {
70
+ const safePath = sanitizePathTemplate(pathTemplate);
71
+ const lines = [];
72
+ lines.push(` let url = baseUrl + '${escapeStringLiteral(safePath)}';`);
73
+ for (const p of pathParams) {
74
+ const safeP = sanitizeIdentifier(p);
75
+ lines.push(` url = url.replace('${escapeStringLiteral(`{${safeP}}`)}', encodeURIComponent(String(params['${escapeStringLiteral(safeP)}'])));`);
76
+ }
77
+ if (queryParams.length > 0) {
78
+ lines.push(' const query = new URLSearchParams();');
79
+ for (const q of queryParams) {
80
+ const safeQ = sanitizeIdentifier(q);
81
+ lines.push(` if (params['${escapeStringLiteral(safeQ)}'] !== undefined) query.set('${escapeStringLiteral(safeQ)}', String(params['${escapeStringLiteral(safeQ)}']));`);
82
+ }
83
+ lines.push(' const qs = query.toString();');
84
+ lines.push(' return qs ? `${url}?${qs}` : url;');
85
+ }
86
+ else {
87
+ lines.push(' return url;');
88
+ }
89
+ return lines.join('\n');
90
+ }
91
+ export function buildAllTools(operations) {
92
+ // Filter out operations marked with x-mcp-emit: skip
93
+ const filtered = operations.filter((op) => op.mcpExtensions?.emit !== 'skip');
94
+ const tools = filtered.map(buildToolDefinition);
95
+ // Handle name collisions by appending method
96
+ const nameCount = new Map();
97
+ for (const t of tools) {
98
+ nameCount.set(t.name, (nameCount.get(t.name) ?? 0) + 1);
99
+ }
100
+ for (const tool of tools) {
101
+ if ((nameCount.get(tool.name) ?? 0) > 1) {
102
+ tool.name = `${tool.name}_${tool.method}`;
103
+ tool.fileName = `${tool.fileName}-${tool.method}`;
104
+ tool.functionName = `${tool.functionName}${tool.method.charAt(0).toUpperCase() + tool.method.slice(1)}`;
105
+ }
106
+ }
107
+ // Enforce MCP spec name length limit (128 chars)
108
+ for (const tool of tools) {
109
+ if (tool.name.length > 128) {
110
+ tool.name = tool.name.slice(0, 128);
111
+ }
112
+ }
113
+ return tools;
114
+ }
@@ -0,0 +1,131 @@
1
+ export type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options';
2
+ export interface ParameterDescriptor {
3
+ name: string;
4
+ in: 'path' | 'query' | 'header' | 'cookie';
5
+ required: boolean;
6
+ description?: string;
7
+ schema: JsonSchema;
8
+ }
9
+ export interface RequestBodyDescriptor {
10
+ required: boolean;
11
+ description?: string;
12
+ contentType: string;
13
+ schema: JsonSchema;
14
+ }
15
+ export interface ResponseDescriptor {
16
+ statusCode: string;
17
+ description?: string;
18
+ contentType?: string;
19
+ schema?: JsonSchema;
20
+ }
21
+ export interface SecurityRequirement {
22
+ schemeName: string;
23
+ scopes: string[];
24
+ }
25
+ export interface McpExtensions {
26
+ name?: string;
27
+ description?: string;
28
+ emit?: 'tool' | 'resource' | 'prompt' | 'skip';
29
+ scope?: 'read' | 'write' | 'destructive';
30
+ /** Deprecation message surfaced in tool description */
31
+ deprecationMessage?: string;
32
+ /** Replacement tool name for deprecated operations */
33
+ deprecationReplacement?: string;
34
+ /** JQ filter expression to trim API responses before returning to agent */
35
+ jqFilter?: string;
36
+ /** Allow unknown enum values for forward compatibility */
37
+ unknownValues?: 'allow' | 'reject';
38
+ }
39
+ export interface OperationDescriptor {
40
+ operationId: string;
41
+ method: HttpMethod;
42
+ path: string;
43
+ summary?: string;
44
+ description?: string;
45
+ tags: string[];
46
+ parameters: ParameterDescriptor[];
47
+ requestBody?: RequestBodyDescriptor;
48
+ responses: ResponseDescriptor[];
49
+ security: SecurityRequirement[];
50
+ deprecated: boolean;
51
+ mcpExtensions?: McpExtensions;
52
+ }
53
+ export interface ToolAnnotations {
54
+ readOnlyHint?: boolean;
55
+ destructiveHint?: boolean;
56
+ idempotentHint?: boolean;
57
+ }
58
+ export interface ToolDefinition {
59
+ name: string;
60
+ title: string;
61
+ description: string;
62
+ inputSchemaCode: string;
63
+ outputSchemaCode?: string;
64
+ operationId: string;
65
+ method: HttpMethod;
66
+ pathTemplate: string;
67
+ pathParams: string[];
68
+ queryParams: string[];
69
+ headerParams: string[];
70
+ hasRequestBody: boolean;
71
+ requestBodyContentType: string;
72
+ fileName: string;
73
+ functionName: string;
74
+ buildUrlBody: string;
75
+ annotations?: ToolAnnotations;
76
+ isAsync?: boolean;
77
+ isDestructive?: boolean;
78
+ /** JQ filter to apply to API response before returning to agent */
79
+ jqFilter?: string;
80
+ }
81
+ export type AuthType = 'apiKey' | 'http-bearer' | 'http-basic' | 'oauth2';
82
+ export interface AuthScheme {
83
+ type: AuthType;
84
+ envVarName: string;
85
+ headerName?: string;
86
+ in?: 'header' | 'query' | 'cookie';
87
+ description?: string;
88
+ }
89
+ export interface EnvVarDescriptor {
90
+ name: string;
91
+ description: string;
92
+ required: boolean;
93
+ example?: string;
94
+ }
95
+ export type TransportMode = 'stdio' | 'http';
96
+ /**
97
+ * Deployment target for the generated TypeScript server.
98
+ * `node` (default) emits a Node.js server (stdio or node:http); `cloudflare`
99
+ * emits a stateless Cloudflare Workers Fetch handler.
100
+ */
101
+ export type EmitTarget = 'node' | 'cloudflare';
102
+ export interface ResourceDefinition {
103
+ name: string;
104
+ uri: string;
105
+ path: string;
106
+ description: string;
107
+ isTemplate?: boolean;
108
+ templateParams?: string[];
109
+ urlBody?: string;
110
+ }
111
+ export interface PromptDefinition {
112
+ name: string;
113
+ description: string;
114
+ template: string;
115
+ }
116
+ export interface ProjectManifest {
117
+ serverName: string;
118
+ serverVersion: string;
119
+ baseUrl: string;
120
+ transport: TransportMode;
121
+ tools: ToolDefinition[];
122
+ resources?: ResourceDefinition[];
123
+ prompts?: PromptDefinition[];
124
+ authSchemes: AuthScheme[];
125
+ envVars: EnvVarDescriptor[];
126
+ dynamicDiscovery?: boolean;
127
+ staticToolCount?: number;
128
+ /** Deployment target (default `node`). `cloudflare` emits a Workers project. */
129
+ target?: EmitTarget;
130
+ }
131
+ export type JsonSchema = Record<string, unknown>;
@@ -0,0 +1 @@
1
+ export {};