github-to-mcp-monorepo 1.0.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 (388) hide show
  1. package/.env.example +8 -0
  2. package/.github/CODEOWNERS +6 -0
  3. package/.husky/pre-commit +1 -0
  4. package/.nvmrc +1 -0
  5. package/.prettierignore +5 -0
  6. package/.prettierrc +7 -0
  7. package/.vscode/settings.json +4 -0
  8. package/ARCHITECTURE.md +1429 -0
  9. package/CHANGELOG.md +167 -0
  10. package/CONTRIBUTING.md +327 -0
  11. package/LICENSE +201 -0
  12. package/README.md +1028 -0
  13. package/SECURITY.md +248 -0
  14. package/VISUAL_GUIDE.md +437 -0
  15. package/apps/vscode/IMPLEMENTATION.md +480 -0
  16. package/apps/vscode/README.md +248 -0
  17. package/apps/vscode/package.json +381 -0
  18. package/apps/vscode/resources/icon.png +0 -0
  19. package/apps/vscode/resources/icon.svg +5 -0
  20. package/apps/vscode/src/commands/browseRegistry.ts +211 -0
  21. package/apps/vscode/src/commands/configureClaudeDesktop.ts +332 -0
  22. package/apps/vscode/src/commands/convert.ts +82 -0
  23. package/apps/vscode/src/commands/convertCurrentRepo.ts +109 -0
  24. package/apps/vscode/src/commands/convertFromUrl.ts +138 -0
  25. package/apps/vscode/src/commands/index.ts +121 -0
  26. package/apps/vscode/src/commands/validate.ts +197 -0
  27. package/apps/vscode/src/extension.ts +464 -0
  28. package/apps/vscode/src/global.d.ts +36 -0
  29. package/apps/vscode/src/test/extension.test.ts +73 -0
  30. package/apps/vscode/src/utils/file-generator.ts +529 -0
  31. package/apps/vscode/src/utils/github-api.ts +335 -0
  32. package/apps/vscode/src/utils/index.ts +29 -0
  33. package/apps/vscode/src/utils/mcp-config.ts +334 -0
  34. package/apps/vscode/src/utils/storage.ts +87 -0
  35. package/apps/vscode/src/views/McpServersTreeView.ts +160 -0
  36. package/apps/vscode/src/views/OutputChannelView.ts +195 -0
  37. package/apps/vscode/src/views/StatusBarItem.ts +251 -0
  38. package/apps/vscode/src/views/ToolsExplorerView.ts +314 -0
  39. package/apps/vscode/src/views/historyProvider.ts +75 -0
  40. package/apps/vscode/src/views/index.ts +12 -0
  41. package/apps/vscode/src/views/resultsPanel.ts +330 -0
  42. package/apps/vscode/src/webviews/ConversionPanel.ts +350 -0
  43. package/apps/vscode/src/webviews/ToolDetailsPanel.ts +448 -0
  44. package/apps/vscode/src/webviews/index.ts +9 -0
  45. package/apps/vscode/src/webviews/webview-ui/styles.ts +492 -0
  46. package/apps/vscode/tsconfig.json +20 -0
  47. package/apps/web/PLAYGROUND_GUIDE.md +499 -0
  48. package/apps/web/README.md +505 -0
  49. package/apps/web/app/api/convert/route.ts +100 -0
  50. package/apps/web/app/api/convert/stream/route.ts +198 -0
  51. package/apps/web/app/api/deploy/route.ts +157 -0
  52. package/apps/web/app/api/edge/route.ts +308 -0
  53. package/apps/web/app/api/export-docker/route.ts +284 -0
  54. package/apps/web/app/api/generate-openapi/route.ts +119 -0
  55. package/apps/web/app/api/mcp/[serverId]/route.ts +263 -0
  56. package/apps/web/app/api/playground/connect/route.ts +143 -0
  57. package/apps/web/app/api/playground/disconnect/route.ts +78 -0
  58. package/apps/web/app/api/playground/execute/route.ts +135 -0
  59. package/apps/web/app/api/playground/sessions/route.ts +103 -0
  60. package/apps/web/app/api/playground/tools/route.ts +117 -0
  61. package/apps/web/app/api/playground/v2/connect/route.ts +96 -0
  62. package/apps/web/app/api/playground/v2/disconnect/route.ts +88 -0
  63. package/apps/web/app/api/playground/v2/health/route.ts +80 -0
  64. package/apps/web/app/api/playground/v2/prompts/route.ts +160 -0
  65. package/apps/web/app/api/playground/v2/resources/route.ts +159 -0
  66. package/apps/web/app/api/playground/v2/sessions/route.ts +184 -0
  67. package/apps/web/app/api/playground/v2/tools/route.ts +167 -0
  68. package/apps/web/app/api/stream/route.ts +232 -0
  69. package/apps/web/app/batch/BatchConvertClient.tsx +190 -0
  70. package/apps/web/app/batch/page.tsx +37 -0
  71. package/apps/web/app/convert/page.tsx +269 -0
  72. package/apps/web/app/dashboard/page.tsx +380 -0
  73. package/apps/web/app/globals.css +622 -0
  74. package/apps/web/app/layout.tsx +120 -0
  75. package/apps/web/app/manifest.ts +31 -0
  76. package/apps/web/app/opengraph-image.tsx +112 -0
  77. package/apps/web/app/page.old.tsx +924 -0
  78. package/apps/web/app/page.tsx +77 -0
  79. package/apps/web/app/playground/page.tsx +306 -0
  80. package/apps/web/app/playground/v2/error.tsx +163 -0
  81. package/apps/web/app/playground/v2/layout.tsx +58 -0
  82. package/apps/web/app/playground/v2/loading.tsx +152 -0
  83. package/apps/web/app/playground/v2/page.tsx +644 -0
  84. package/apps/web/app/playground/v2/providers.tsx +214 -0
  85. package/apps/web/app/playground/v2/use-shortcuts.ts +209 -0
  86. package/apps/web/app/playground/v2/use-url-state.ts +296 -0
  87. package/apps/web/app/providers.tsx +22 -0
  88. package/apps/web/app/sitemap.ts +32 -0
  89. package/apps/web/app/twitter-image.tsx +112 -0
  90. package/apps/web/components/BranchSelector.tsx +401 -0
  91. package/apps/web/components/ClaudeConfigExport.tsx +226 -0
  92. package/apps/web/components/Features.tsx +84 -0
  93. package/apps/web/components/Footer.tsx +119 -0
  94. package/apps/web/components/GenerationProgress.tsx +248 -0
  95. package/apps/web/components/GithubUrlInput.tsx +483 -0
  96. package/apps/web/components/Header.tsx +175 -0
  97. package/apps/web/components/Hero.tsx +117 -0
  98. package/apps/web/components/HowItWorks.tsx +119 -0
  99. package/apps/web/components/InstallBanner.tsx +158 -0
  100. package/apps/web/components/Logo.tsx +116 -0
  101. package/apps/web/components/ParticleBackground.tsx +105 -0
  102. package/apps/web/components/Playground.tsx +472 -0
  103. package/apps/web/components/PlaygroundToolTester.tsx +410 -0
  104. package/apps/web/components/ProductCards.tsx +179 -0
  105. package/apps/web/components/SplitView.tsx +194 -0
  106. package/apps/web/components/ToolFilter.tsx +260 -0
  107. package/apps/web/components/ToolList.tsx +325 -0
  108. package/apps/web/components/batch/BatchConvert.tsx +785 -0
  109. package/apps/web/components/batch/index.ts +7 -0
  110. package/apps/web/components/convert/ConfigTabs.tsx +230 -0
  111. package/apps/web/components/convert/ConversionResult.tsx +482 -0
  112. package/apps/web/components/convert/InlinePlayground.tsx +259 -0
  113. package/apps/web/components/convert/LoadingSteps.tsx +311 -0
  114. package/apps/web/components/convert/OneClickInstall.tsx +224 -0
  115. package/apps/web/components/convert/ToolCard.tsx +189 -0
  116. package/apps/web/components/convert/TryInPlayground.tsx +242 -0
  117. package/apps/web/components/convert/index.ts +12 -0
  118. package/apps/web/components/deploy/DeployButton.tsx +369 -0
  119. package/apps/web/components/deploy/index.ts +7 -0
  120. package/apps/web/components/docker/DockerExport.tsx +690 -0
  121. package/apps/web/components/docker/index.ts +7 -0
  122. package/apps/web/components/install/OneClickInstall.tsx +676 -0
  123. package/apps/web/components/install/index.ts +7 -0
  124. package/apps/web/components/playground/CapabilityTabs.tsx +150 -0
  125. package/apps/web/components/playground/ConnectionStatusV2.tsx +322 -0
  126. package/apps/web/components/playground/EmptyStates.tsx +305 -0
  127. package/apps/web/components/playground/ExecutionLog.tsx +260 -0
  128. package/apps/web/components/playground/ExecutionLogV2.tsx +378 -0
  129. package/apps/web/components/playground/JsonViewer.tsx +388 -0
  130. package/apps/web/components/playground/PlaygroundLayout.tsx +244 -0
  131. package/apps/web/components/playground/PromptsPanel.tsx +385 -0
  132. package/apps/web/components/playground/ResourcesPanel.tsx +378 -0
  133. package/apps/web/components/playground/SchemaForm.tsx +477 -0
  134. package/apps/web/components/playground/ServerStatus.tsx +151 -0
  135. package/apps/web/components/playground/ShareButton.tsx +239 -0
  136. package/apps/web/components/playground/ToolsPanel.tsx +309 -0
  137. package/apps/web/components/playground/TransportConfigurator.tsx +563 -0
  138. package/apps/web/components/playground/index.ts +74 -0
  139. package/apps/web/components/playground/types.ts +202 -0
  140. package/apps/web/components/streaming/StreamingProgress.tsx +441 -0
  141. package/apps/web/components/streaming/index.ts +7 -0
  142. package/apps/web/components/ui/badge.tsx +42 -0
  143. package/apps/web/components/ui/button.tsx +88 -0
  144. package/apps/web/components/ui/card.tsx +75 -0
  145. package/apps/web/components/ui/code-block.tsx +122 -0
  146. package/apps/web/components/ui/index.ts +12 -0
  147. package/apps/web/components/ui/input.tsx +55 -0
  148. package/apps/web/components/ui/tabs.tsx +61 -0
  149. package/apps/web/hooks/index.ts +85 -0
  150. package/apps/web/hooks/types.ts +1173 -0
  151. package/apps/web/hooks/use-conversion.ts +133 -0
  152. package/apps/web/hooks/use-execution-history.ts +376 -0
  153. package/apps/web/hooks/use-generation-progress.ts +147 -0
  154. package/apps/web/hooks/use-local-storage.ts +88 -0
  155. package/apps/web/hooks/use-mcp-client.ts +623 -0
  156. package/apps/web/hooks/use-mcp-connection.ts +500 -0
  157. package/apps/web/hooks/use-mcp-execution.ts +282 -0
  158. package/apps/web/hooks/use-mcp-prompts.ts +441 -0
  159. package/apps/web/hooks/use-mcp-resources.ts +430 -0
  160. package/apps/web/hooks/use-mcp-tools.ts +540 -0
  161. package/apps/web/hooks/use-playground-store.ts +299 -0
  162. package/apps/web/hooks/use-playground.ts +184 -0
  163. package/apps/web/hooks/use-streaming-conversion.ts +227 -0
  164. package/apps/web/hooks/useBatchConversion.ts +271 -0
  165. package/apps/web/hooks/useDockerConfig.ts +161 -0
  166. package/apps/web/hooks/usePlatformDetection.ts +80 -0
  167. package/apps/web/hooks/useStreaming.ts +199 -0
  168. package/apps/web/lib/api/errors.ts +386 -0
  169. package/apps/web/lib/api/index.ts +137 -0
  170. package/apps/web/lib/api/logger.ts +187 -0
  171. package/apps/web/lib/api/middleware.ts +364 -0
  172. package/apps/web/lib/api/openapi.ts +977 -0
  173. package/apps/web/lib/api/session-manager.ts +594 -0
  174. package/apps/web/lib/api/types.ts +433 -0
  175. package/apps/web/lib/api/validation.ts +523 -0
  176. package/apps/web/lib/constants.ts +114 -0
  177. package/apps/web/lib/mcp/client.ts +1137 -0
  178. package/apps/web/lib/mcp/events.ts +651 -0
  179. package/apps/web/lib/mcp/index.ts +347 -0
  180. package/apps/web/lib/mcp/logger.ts +428 -0
  181. package/apps/web/lib/mcp/metrics.ts +703 -0
  182. package/apps/web/lib/mcp/retry.ts +616 -0
  183. package/apps/web/lib/mcp/session-manager.ts +779 -0
  184. package/apps/web/lib/mcp/transports.ts +988 -0
  185. package/apps/web/lib/mcp/types.ts +594 -0
  186. package/apps/web/lib/mcp-client-enhanced.ts +871 -0
  187. package/apps/web/lib/mcp-client.ts +778 -0
  188. package/apps/web/lib/mcp-errors.ts +489 -0
  189. package/apps/web/lib/mcp-sandbox.ts +593 -0
  190. package/apps/web/lib/mcp-testing.ts +428 -0
  191. package/apps/web/lib/mcp-types.ts +448 -0
  192. package/apps/web/lib/playground-store.tsx +1147 -0
  193. package/apps/web/lib/utils.ts +439 -0
  194. package/apps/web/next-env.d.ts +5 -0
  195. package/apps/web/next.config.js +23 -0
  196. package/apps/web/package.json +55 -0
  197. package/apps/web/postcss.config.js +6 -0
  198. package/apps/web/public/.well-known/ai-plugin.json +17 -0
  199. package/apps/web/public/logo.svg +6 -0
  200. package/apps/web/public/robots.txt +22 -0
  201. package/apps/web/public/schema.json +27 -0
  202. package/apps/web/tailwind.config.js +26 -0
  203. package/apps/web/tailwind.config.ts +123 -0
  204. package/apps/web/tsconfig.json +20 -0
  205. package/apps/web/types/deploy.ts +139 -0
  206. package/apps/web/types/index.ts +247 -0
  207. package/apps/web/vercel.json +39 -0
  208. package/eslint.config.mjs +23 -0
  209. package/llms.txt +102 -0
  210. package/mkdocs/docs/api/core.md +318 -0
  211. package/mkdocs/docs/api/index.md +128 -0
  212. package/mkdocs/docs/api/mcp-server.md +301 -0
  213. package/mkdocs/docs/api/openapi-parser.md +254 -0
  214. package/mkdocs/docs/assets/logo.svg +7 -0
  215. package/mkdocs/docs/changelog.md +118 -0
  216. package/mkdocs/docs/cli/generate.md +148 -0
  217. package/mkdocs/docs/cli/index.md +52 -0
  218. package/mkdocs/docs/cli/inspect.md +164 -0
  219. package/mkdocs/docs/cli/serve.md +136 -0
  220. package/mkdocs/docs/concepts/classification.md +254 -0
  221. package/mkdocs/docs/concepts/how-it-works.md +299 -0
  222. package/mkdocs/docs/concepts/index.md +77 -0
  223. package/mkdocs/docs/concepts/mcp-protocol.md +362 -0
  224. package/mkdocs/docs/concepts/tool-types.md +382 -0
  225. package/mkdocs/docs/contributing/architecture.md +262 -0
  226. package/mkdocs/docs/contributing/development.md +245 -0
  227. package/mkdocs/docs/contributing/index.md +73 -0
  228. package/mkdocs/docs/contributing/testing.md +320 -0
  229. package/mkdocs/docs/getting-started/configuration.md +235 -0
  230. package/mkdocs/docs/getting-started/index.md +54 -0
  231. package/mkdocs/docs/getting-started/installation.md +145 -0
  232. package/mkdocs/docs/getting-started/quickstart.md +160 -0
  233. package/mkdocs/docs/guides/batch.md +375 -0
  234. package/mkdocs/docs/guides/claude-desktop.md +227 -0
  235. package/mkdocs/docs/guides/cursor.md +188 -0
  236. package/mkdocs/docs/guides/custom-tools.md +367 -0
  237. package/mkdocs/docs/guides/index.md +78 -0
  238. package/mkdocs/docs/guides/private-repos.md +221 -0
  239. package/mkdocs/docs/guides/vscode.md +247 -0
  240. package/mkdocs/docs/index.md +175 -0
  241. package/mkdocs/docs/reference/config.md +223 -0
  242. package/mkdocs/docs/reference/env.md +192 -0
  243. package/mkdocs/docs/reference/index.md +102 -0
  244. package/mkdocs/docs/reference/tools.md +309 -0
  245. package/mkdocs/docs/stylesheets/extra.css +231 -0
  246. package/mkdocs/mkdocs.yml +204 -0
  247. package/mkdocs/overrides/.gitkeep +1 -0
  248. package/mkdocs/overrides/main.html +7 -0
  249. package/mkdocs/python-deps.txt +7 -0
  250. package/mkdocs/vercel.json +11 -0
  251. package/package.json +63 -0
  252. package/packages/core/package.json +61 -0
  253. package/packages/core/src/__tests__/bitbucket-client.test.ts +366 -0
  254. package/packages/core/src/__tests__/cli.test.ts +235 -0
  255. package/packages/core/src/__tests__/code-extractor.test.ts +378 -0
  256. package/packages/core/src/__tests__/docker-generator.test.ts +255 -0
  257. package/packages/core/src/__tests__/github-client.test.ts +390 -0
  258. package/packages/core/src/__tests__/gitlab-client.test.ts +319 -0
  259. package/packages/core/src/__tests__/go-extractor.test.ts +351 -0
  260. package/packages/core/src/__tests__/graphql-extractor.test.ts +330 -0
  261. package/packages/core/src/__tests__/java-extractor.test.ts +497 -0
  262. package/packages/core/src/__tests__/plugins.test.ts +467 -0
  263. package/packages/core/src/__tests__/readme-extractor.test.ts +258 -0
  264. package/packages/core/src/__tests__/redis-cache.test.ts +307 -0
  265. package/packages/core/src/__tests__/rust-extractor.test.ts +252 -0
  266. package/packages/core/src/__tests__/streaming.test.ts +251 -0
  267. package/packages/core/src/additional-extractors.ts +333 -0
  268. package/packages/core/src/cache/cache-interface.ts +179 -0
  269. package/packages/core/src/cache/index.ts +210 -0
  270. package/packages/core/src/cache/redis-cache.ts +291 -0
  271. package/packages/core/src/cache/upstash-cache.ts +379 -0
  272. package/packages/core/src/cache.ts +251 -0
  273. package/packages/core/src/cli.ts +822 -0
  274. package/packages/core/src/code-extractor.ts +696 -0
  275. package/packages/core/src/docker-generator.ts +470 -0
  276. package/packages/core/src/edge-compatible.ts +491 -0
  277. package/packages/core/src/extractors/go-extractor.ts +791 -0
  278. package/packages/core/src/extractors/index.ts +9 -0
  279. package/packages/core/src/extractors/java-extractor.ts +937 -0
  280. package/packages/core/src/extractors/rust-extractor.ts +744 -0
  281. package/packages/core/src/github-client.ts +319 -0
  282. package/packages/core/src/go-generator.ts +356 -0
  283. package/packages/core/src/graphql-extractor.ts +358 -0
  284. package/packages/core/src/index.ts +797 -0
  285. package/packages/core/src/langchain-exporter.ts +617 -0
  286. package/packages/core/src/language-parsers.ts +1114 -0
  287. package/packages/core/src/mcp-introspector.ts +279 -0
  288. package/packages/core/src/monorepo-detector.ts +378 -0
  289. package/packages/core/src/plugins/index.ts +370 -0
  290. package/packages/core/src/plugins/registry.ts +404 -0
  291. package/packages/core/src/plugins/types.ts +215 -0
  292. package/packages/core/src/providers/base-provider.ts +246 -0
  293. package/packages/core/src/providers/bitbucket-client.ts +464 -0
  294. package/packages/core/src/providers/gitlab-client.ts +388 -0
  295. package/packages/core/src/providers/index.ts +176 -0
  296. package/packages/core/src/python-generator.ts +260 -0
  297. package/packages/core/src/queue/index.ts +100 -0
  298. package/packages/core/src/queue/memory-queue.ts +445 -0
  299. package/packages/core/src/queue/redis-queue.ts +578 -0
  300. package/packages/core/src/queue/types.ts +251 -0
  301. package/packages/core/src/readme-extractor.ts +409 -0
  302. package/packages/core/src/schema-generator.ts +638 -0
  303. package/packages/core/src/streaming.ts +999 -0
  304. package/packages/core/src/types.ts +289 -0
  305. package/packages/core/tsconfig.json +9 -0
  306. package/packages/core/tsup.config.ts +25 -0
  307. package/packages/mcp-server/README.md +297 -0
  308. package/packages/mcp-server/package.json +55 -0
  309. package/packages/mcp-server/src/__tests__/mcp-server.test.ts +177 -0
  310. package/packages/mcp-server/src/__tests__/tools.test.ts +217 -0
  311. package/packages/mcp-server/src/index.ts +1206 -0
  312. package/packages/mcp-server/src/prompts/index.ts +601 -0
  313. package/packages/mcp-server/src/tools/export-docker.ts +362 -0
  314. package/packages/mcp-server/src/tools/generate-openapi.ts +162 -0
  315. package/packages/mcp-server/src/tools/monitor-mcp-server.ts +448 -0
  316. package/packages/mcp-server/src/tools/stream-convert.ts +398 -0
  317. package/packages/mcp-server/src/tools/test-mcp-tool.ts +531 -0
  318. package/packages/mcp-server/tsconfig.json +12 -0
  319. package/packages/mcp-server/tsup.config.ts +14 -0
  320. package/packages/openapi-parser/package-lock.json +3028 -0
  321. package/packages/openapi-parser/package.json +41 -0
  322. package/packages/openapi-parser/src/analyzer.ts +700 -0
  323. package/packages/openapi-parser/src/asyncapi-parser.ts +475 -0
  324. package/packages/openapi-parser/src/cli.ts +302 -0
  325. package/packages/openapi-parser/src/generator.ts +570 -0
  326. package/packages/openapi-parser/src/generators/express-analyzer.ts +649 -0
  327. package/packages/openapi-parser/src/generators/fastapi-analyzer.ts +960 -0
  328. package/packages/openapi-parser/src/generators/index.ts +200 -0
  329. package/packages/openapi-parser/src/generators/nextjs-analyzer.ts +768 -0
  330. package/packages/openapi-parser/src/generators/openapi-builder.ts +527 -0
  331. package/packages/openapi-parser/src/generators/types.ts +298 -0
  332. package/packages/openapi-parser/src/graphql-parser.ts +462 -0
  333. package/packages/openapi-parser/src/grpc-parser.ts +649 -0
  334. package/packages/openapi-parser/src/har-parser.ts +723 -0
  335. package/packages/openapi-parser/src/index.ts +635 -0
  336. package/packages/openapi-parser/src/insomnia-parser.ts +614 -0
  337. package/packages/openapi-parser/src/parser.ts +231 -0
  338. package/packages/openapi-parser/src/postman-parser.ts +611 -0
  339. package/packages/openapi-parser/src/ref-resolver.ts +313 -0
  340. package/packages/openapi-parser/src/transformer.ts +459 -0
  341. package/packages/openapi-parser/tests/generators/express.test.ts +209 -0
  342. package/packages/openapi-parser/tests/generators/fastapi.test.ts +236 -0
  343. package/packages/openapi-parser/tests/generators/nextjs.test.ts +273 -0
  344. package/packages/openapi-parser/tests/parsers.test.ts +847 -0
  345. package/packages/openapi-parser/tsconfig.json +9 -0
  346. package/packages/openapi-parser/tsup.config.ts +11 -0
  347. package/packages/registry/package.json +59 -0
  348. package/packages/registry/src/cli.ts +456 -0
  349. package/packages/registry/src/index.ts +44 -0
  350. package/packages/registry/src/popular/github.json +47 -0
  351. package/packages/registry/src/popular/index.ts +55 -0
  352. package/packages/registry/src/popular/linear.json +42 -0
  353. package/packages/registry/src/popular/notion.json +42 -0
  354. package/packages/registry/src/popular/openai.json +40 -0
  355. package/packages/registry/src/popular/resend.json +38 -0
  356. package/packages/registry/src/popular/slack.json +42 -0
  357. package/packages/registry/src/popular/stripe.json +163 -0
  358. package/packages/registry/src/popular/supabase.json +42 -0
  359. package/packages/registry/src/popular/twilio.json +40 -0
  360. package/packages/registry/src/popular/vercel.json +40 -0
  361. package/packages/registry/src/registry.ts +492 -0
  362. package/packages/registry/src/storage.ts +334 -0
  363. package/packages/registry/src/types.ts +275 -0
  364. package/packages/registry/src/updater.ts +208 -0
  365. package/packages/registry/tsconfig.json +10 -0
  366. package/packages/registry/tsup.config.ts +11 -0
  367. package/pnpm-workspace.yaml +3 -0
  368. package/scripts/build-docs.sh +16 -0
  369. package/server.json +9 -0
  370. package/templates/Dockerfile.python.template +60 -0
  371. package/templates/Dockerfile.typescript.template +60 -0
  372. package/templates/docker-compose.template.yml +68 -0
  373. package/tests/fixtures/express-app/index.js +34 -0
  374. package/tests/fixtures/express-app/routes/posts.js +43 -0
  375. package/tests/fixtures/express-app/routes/users.js +58 -0
  376. package/tests/fixtures/fastapi-app/main.py +125 -0
  377. package/tests/fixtures/fastapi-app/routes/admin.py +42 -0
  378. package/tests/fixtures/graphql/simple-schema.graphql +65 -0
  379. package/tests/fixtures/mocks/github-api-responses.json +63 -0
  380. package/tests/fixtures/nextjs-app/app/api/posts/route.ts +55 -0
  381. package/tests/fixtures/nextjs-app/app/api/users/[id]/route.ts +63 -0
  382. package/tests/fixtures/nextjs-app/app/api/users/route.ts +44 -0
  383. package/tests/fixtures/nextjs-app/pages/api/health.ts +28 -0
  384. package/tests/fixtures/openapi/petstore.yaml +179 -0
  385. package/tests/integration/langchain-export.test.ts +405 -0
  386. package/tests/integration/openapi-conversion.test.ts +221 -0
  387. package/tsconfig.json +18 -0
  388. package/vitest.config.ts +32 -0
@@ -0,0 +1,635 @@
1
+ /**
2
+ * @fileoverview Module exports and initialization
3
+ * Multi-format API specification parser with unified interface
4
+ * Supports: OpenAPI, AsyncAPI, GraphQL, gRPC/Protobuf, Postman, Insomnia, HAR
5
+ * @copyright Copyright (c) 2024-2026 nirholas
6
+ * @license MIT
7
+ */
8
+
9
+ import { OpenAPIV3 } from 'openapi-types';
10
+ import { OpenApiParser } from './parser.js';
11
+ import { OpenApiAnalyzer, type EndpointInfo } from './analyzer.js';
12
+ import { OpenApiTransformer, type TransformOptions, type McpToolDefinition } from './transformer.js';
13
+ import { CodeGenerator, type GeneratorOptions } from './generator.js';
14
+ import { parseAsyncAPI, type AsyncAPIParseResult, type AsyncAPIToolDefinition } from './asyncapi-parser.js';
15
+ import { parseGraphQL, type GraphQLParseResult, type GraphQLToolDefinition } from './graphql-parser.js';
16
+ import { GrpcParser, type GrpcParseResult, type GrpcToolDefinition, type ProtobufService, type ProtobufMessage, type ProtobufEnum, type ProtobufRpcMethod } from './grpc-parser.js';
17
+ import { parsePostman, type PostmanParseResult, type PostmanToolDefinition } from './postman-parser.js';
18
+ import { parseInsomnia, type InsomniaParseResult, type InsomniaToolDefinition } from './insomnia-parser.js';
19
+ import { parseHAR, type HarParseResult, type HarToolDefinition } from './har-parser.js';
20
+ import { RefResolver, resolveRefs, type RefResolverOptions, type ResolvedSpec } from './ref-resolver.js';
21
+ import { promises as fs } from 'fs';
22
+ import path from 'path';
23
+ import yaml from 'js-yaml';
24
+
25
+ // Export generators module
26
+ export * from './generators/index.js';
27
+ export {
28
+ ExpressAnalyzer,
29
+ FastAPIAnalyzer,
30
+ NextJSAnalyzer,
31
+ OpenApiBuilder,
32
+ generateOpenApiFromCode,
33
+ generateOpenApiFromCodeWithDetails,
34
+ analyzeFiles,
35
+ detectFramework,
36
+ analyzeWithFramework,
37
+ } from './generators/index.js';
38
+
39
+ // Export gRPC parser
40
+ export { GrpcParser, type GrpcParseResult, type GrpcToolDefinition, type ProtobufService, type ProtobufMessage, type ProtobufEnum, type ProtobufRpcMethod };
41
+
42
+ export interface ConverterConfig {
43
+ /** OpenAPI spec source (file path or URL) */
44
+ spec: string;
45
+
46
+ /** Output directory */
47
+ outputDir: string;
48
+
49
+ /** Base URL for API (overrides spec) */
50
+ baseUrl?: string;
51
+
52
+ /** Filter options */
53
+ filters?: {
54
+ tags?: string[];
55
+ paths?: string[];
56
+ methods?: string[];
57
+ include?: string[];
58
+ exclude?: string[];
59
+ };
60
+
61
+ /** Transformation options */
62
+ transform?: TransformOptions;
63
+
64
+ /** Generation options */
65
+ generation?: Partial<GeneratorOptions>;
66
+ }
67
+
68
+ export interface ConversionStats {
69
+ spec: {
70
+ title: string;
71
+ version: string;
72
+ endpoints: number;
73
+ };
74
+ conversion: {
75
+ toolsGenerated: number;
76
+ filesCreated: number;
77
+ duration: number;
78
+ };
79
+ breakdown: {
80
+ byMethod: Record<string, number>;
81
+ byTag: Record<string, number>;
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Main converter class - orchestrates the conversion pipeline
87
+ */
88
+ export class OpenApiToMcp {
89
+ private parser: OpenApiParser;
90
+ private analyzer: OpenApiAnalyzer | null = null;
91
+ private transformer: OpenApiTransformer | null = null;
92
+ private generator: CodeGenerator | null = null;
93
+
94
+ private tools: McpToolDefinition[] = [];
95
+ private stats: ConversionStats | null = null;
96
+
97
+ constructor(private config: ConverterConfig) {
98
+ this.parser = new OpenApiParser();
99
+ }
100
+
101
+ /**
102
+ * Run the complete conversion pipeline
103
+ */
104
+ async convert(): Promise<ConversionStats> {
105
+ const startTime = Date.now();
106
+
107
+ console.log('🔍 Parsing OpenAPI specification...');
108
+ const spec = await this.parser.parse(this.config.spec);
109
+ const specInfo = this.parser.getInfo();
110
+
111
+ console.log(`✅ Parsed: ${specInfo.title} v${specInfo.version}`);
112
+
113
+ console.log('📊 Analyzing endpoints...');
114
+ // Cast to OpenAPIV3.Document - OpenAPI 3.1 is mostly compatible for our analysis
115
+ const v3Spec = spec as OpenAPIV3.Document;
116
+ this.analyzer = new OpenApiAnalyzer(v3Spec);
117
+ let endpoints = this.analyzer.extractEndpoints(this.config.filters);
118
+
119
+ // Apply include/exclude filters
120
+ if (this.config.filters?.include) {
121
+ endpoints = endpoints.filter(e =>
122
+ this.config.filters!.include!.includes(e.operationId || '')
123
+ );
124
+ }
125
+ if (this.config.filters?.exclude) {
126
+ endpoints = endpoints.filter(e =>
127
+ !this.config.filters!.exclude!.includes(e.operationId || '')
128
+ );
129
+ }
130
+
131
+ console.log(`✅ Found ${endpoints.length} endpoints`);
132
+
133
+ console.log('🔄 Transforming to MCP tools...');
134
+ this.transformer = new OpenApiTransformer(v3Spec, this.config.transform);
135
+
136
+ // Detect pagination for endpoints
137
+ const paginationMap = new Map();
138
+ for (const endpoint of endpoints) {
139
+ const pagination = this.analyzer.detectPagination(endpoint);
140
+ if (pagination) {
141
+ const key = `${endpoint.method}:${endpoint.path}`;
142
+ paginationMap.set(key, pagination);
143
+ }
144
+ }
145
+
146
+ this.tools = this.transformer.transformEndpoints(endpoints, paginationMap);
147
+ console.log(`✅ Generated ${this.tools.length} MCP tools`);
148
+
149
+ console.log('💻 Generating code...');
150
+ const baseUrl = this.config.baseUrl || this.parser.getBaseUrl();
151
+ const generatorOptions: GeneratorOptions = {
152
+ format: 'typescript',
153
+ serverName: specInfo.title,
154
+ serverVersion: specInfo.version,
155
+ baseUrl,
156
+ ...this.config.generation,
157
+ };
158
+
159
+ this.generator = new CodeGenerator(generatorOptions);
160
+
161
+ // Group tools by tag
162
+ const toolGroups = new Map<string, McpToolDefinition[]>();
163
+ for (const tool of this.tools) {
164
+ const group = tool.metadata.tags?.[0] || 'default';
165
+ if (!toolGroups.has(group)) {
166
+ toolGroups.set(group, []);
167
+ }
168
+ toolGroups.get(group)!.push(tool);
169
+ }
170
+
171
+ const files = this.generator.generateServer(this.tools, toolGroups);
172
+
173
+ console.log('📝 Writing files...');
174
+ await this.writeFiles(files);
175
+ console.log(`✅ Created ${files.size} files`);
176
+
177
+ const duration = Date.now() - startTime;
178
+
179
+ this.stats = {
180
+ spec: {
181
+ title: specInfo.title,
182
+ version: specInfo.version,
183
+ endpoints: endpoints.length,
184
+ },
185
+ conversion: {
186
+ toolsGenerated: this.tools.length,
187
+ filesCreated: files.size,
188
+ duration,
189
+ },
190
+ breakdown: this.analyzer.getEndpointStats(endpoints) as any,
191
+ };
192
+
193
+ console.log('\n✨ Conversion complete!');
194
+ console.log(`⏱️ Duration: ${(duration / 1000).toFixed(2)}s`);
195
+ console.log(`📁 Output: ${this.config.outputDir}`);
196
+
197
+ return this.stats;
198
+ }
199
+
200
+ /**
201
+ * Write generated files to disk
202
+ */
203
+ private async writeFiles(files: Map<string, string>): Promise<void> {
204
+ // Create output directory
205
+ await fs.mkdir(this.config.outputDir, { recursive: true });
206
+
207
+ // Write each file
208
+ for (const [relativePath, content] of files.entries()) {
209
+ const fullPath = path.join(this.config.outputDir, relativePath);
210
+ const dir = path.dirname(fullPath);
211
+
212
+ // Ensure directory exists
213
+ await fs.mkdir(dir, { recursive: true });
214
+
215
+ // Write file
216
+ await fs.writeFile(fullPath, content, 'utf-8');
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Get generated tools
222
+ */
223
+ getTools(): McpToolDefinition[] {
224
+ return this.tools;
225
+ }
226
+
227
+ /**
228
+ * Get conversion statistics
229
+ */
230
+ getStats(): ConversionStats | null {
231
+ return this.stats;
232
+ }
233
+
234
+ /**
235
+ * Preview conversion (don't write files)
236
+ */
237
+ async preview(): Promise<{
238
+ tools: McpToolDefinition[];
239
+ stats: any;
240
+ }> {
241
+ const spec = await this.parser.parse(this.config.spec);
242
+ // Cast to OpenAPIV3.Document - OpenAPI 3.1 is mostly compatible
243
+ const v3Spec = spec as OpenAPIV3.Document;
244
+ this.analyzer = new OpenApiAnalyzer(v3Spec);
245
+
246
+ let endpoints = this.analyzer.extractEndpoints(this.config.filters);
247
+
248
+ if (this.config.filters?.include) {
249
+ endpoints = endpoints.filter(e =>
250
+ this.config.filters!.include!.includes(e.operationId || '')
251
+ );
252
+ }
253
+ if (this.config.filters?.exclude) {
254
+ endpoints = endpoints.filter(e =>
255
+ !this.config.filters!.exclude!.includes(e.operationId || '')
256
+ );
257
+ }
258
+
259
+ this.transformer = new OpenApiTransformer(v3Spec, this.config.transform);
260
+ const tools = this.transformer.transformEndpoints(endpoints);
261
+ const stats = this.analyzer.getEndpointStats(endpoints);
262
+
263
+ return { tools, stats };
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Convenience function to convert OpenAPI spec to MCP tools
269
+ */
270
+ export async function convertOpenApiToMcp(spec: any): Promise<{
271
+ tools: McpToolDefinition[];
272
+ stats: any;
273
+ }> {
274
+ const parser = new OpenApiParser();
275
+ const parsedSpec = parser.parseObject(spec);
276
+ const v3Spec = parsedSpec as OpenAPIV3.Document;
277
+
278
+ const analyzer = new OpenApiAnalyzer(v3Spec);
279
+ const endpoints = analyzer.extractEndpoints();
280
+
281
+ const transformer = new OpenApiTransformer(v3Spec);
282
+ const tools = transformer.transformEndpoints(endpoints);
283
+ const stats = analyzer.getEndpointStats(endpoints);
284
+
285
+ return { tools, stats };
286
+ }
287
+
288
+ // Export all types (excluding duplicates)
289
+ export * from './parser.js';
290
+ export * from './analyzer.js';
291
+ export * from './transformer.js';
292
+ // Note: GeneratorOptions is exported from generators/types.js, not generator.js to avoid conflicts
293
+ export { CodeGenerator } from './generator.js';
294
+ export * from './asyncapi-parser.js';
295
+ export * from './graphql-parser.js';
296
+ export * from './postman-parser.js';
297
+ export * from './insomnia-parser.js';
298
+ export * from './har-parser.js';
299
+ export * from './ref-resolver.js';
300
+
301
+ // ============================================================================
302
+ // Unified Parser Interface
303
+ // ============================================================================
304
+
305
+ /** Supported API specification formats */
306
+ export type SpecFormat = 'openapi' | 'asyncapi' | 'graphql' | 'postman' | 'insomnia' | 'har';
307
+
308
+ /** Unified tool definition */
309
+ export interface UnifiedToolDefinition {
310
+ name: string;
311
+ description: string;
312
+ inputSchema: {
313
+ type: 'object';
314
+ properties: Record<string, any>;
315
+ required?: string[];
316
+ };
317
+ metadata: {
318
+ format: SpecFormat;
319
+ endpoint?: {
320
+ path: string;
321
+ method: string;
322
+ };
323
+ channel?: string;
324
+ operationType?: 'query' | 'mutation' | 'subscription';
325
+ auth?: {
326
+ type: string;
327
+ envVar?: string;
328
+ };
329
+ tags?: string[];
330
+ deprecated?: boolean;
331
+ confidence?: 'high' | 'medium' | 'low';
332
+ };
333
+ examples?: Array<{ input?: any; output?: any }>;
334
+ }
335
+
336
+ /** Unified parse options */
337
+ export interface ParseOptions {
338
+ /** Specify format or auto-detect if not specified */
339
+ format?: SpecFormat;
340
+ /** How to group operations */
341
+ groupBy?: 'tags' | 'paths' | 'none';
342
+ /** Include examples in output */
343
+ includeExamples?: boolean;
344
+ /** Resolve external $ref references */
345
+ resolveRefs?: boolean;
346
+ /** Include deprecated operations */
347
+ includeDeprecated?: boolean;
348
+ /** Custom operation filter */
349
+ operationFilter?: (op: any) => boolean;
350
+ }
351
+
352
+ /** Unified parse result */
353
+ export interface UnifiedParseResult {
354
+ format: SpecFormat;
355
+ info: {
356
+ title?: string;
357
+ version?: string;
358
+ description?: string;
359
+ };
360
+ tools: UnifiedToolDefinition[];
361
+ auth?: {
362
+ type: string;
363
+ schemes?: Array<{ name: string; type: string }>;
364
+ };
365
+ errors?: Array<{ message: string; location?: string }>;
366
+ }
367
+
368
+ /**
369
+ * Detect the format of an API specification
370
+ */
371
+ export function detectFormat(input: string | object): SpecFormat {
372
+ let obj: any;
373
+
374
+ if (typeof input === 'string') {
375
+ const trimmed = input.trim();
376
+
377
+ // Check for GraphQL SDL patterns first (before YAML parsing which can succeed on SDL)
378
+ if (trimmed.includes('type Query') ||
379
+ trimmed.includes('type Mutation') ||
380
+ trimmed.includes('type Subscription') ||
381
+ trimmed.includes('schema {') ||
382
+ /^\s*type\s+\w+\s*\{/.test(trimmed)) {
383
+ return 'graphql';
384
+ }
385
+
386
+ // Try JSON first
387
+ if (trimmed.startsWith('{')) {
388
+ try {
389
+ obj = JSON.parse(trimmed);
390
+ } catch {
391
+ // Try YAML
392
+ try {
393
+ obj = yaml.load(trimmed);
394
+ } catch {
395
+ throw new Error('Unable to parse input as JSON, YAML, or GraphQL SDL');
396
+ }
397
+ }
398
+ } else {
399
+ // Likely YAML
400
+ try {
401
+ obj = yaml.load(trimmed);
402
+ } catch {
403
+ throw new Error('Unable to parse input as JSON, YAML, or GraphQL SDL');
404
+ }
405
+ }
406
+ } else {
407
+ obj = input;
408
+ }
409
+
410
+ if (!obj || typeof obj !== 'object') {
411
+ throw new Error('Invalid input: expected an object');
412
+ }
413
+
414
+ // OpenAPI detection
415
+ if ('openapi' in obj || 'swagger' in obj) {
416
+ return 'openapi';
417
+ }
418
+
419
+ // AsyncAPI detection
420
+ if ('asyncapi' in obj) {
421
+ return 'asyncapi';
422
+ }
423
+
424
+ // Postman Collection detection
425
+ // Check for Postman collection schema URL (should be at the start of the schema property)
426
+ if ('info' in obj && typeof obj.info?.schema === 'string') {
427
+ const schema = obj.info.schema;
428
+ // Postman collection schemas follow the pattern: https://schema.getpostman.com/...
429
+ if (schema.startsWith('https://schema.getpostman.com/') ||
430
+ schema.startsWith('http://schema.getpostman.com/')) {
431
+ return 'postman';
432
+ }
433
+ }
434
+ // Fallback detection for Postman collections without schema field
435
+ if ('info' in obj && 'item' in obj && Array.isArray(obj.item)) {
436
+ return 'postman';
437
+ }
438
+
439
+ // Insomnia export detection
440
+ if (obj._type === 'export' && '__export_format' in obj) {
441
+ return 'insomnia';
442
+ }
443
+
444
+ // HAR file detection
445
+ if ('log' in obj && obj.log?.version && Array.isArray(obj.log?.entries)) {
446
+ return 'har';
447
+ }
448
+
449
+ // GraphQL introspection result detection
450
+ if ('__schema' in obj || (obj.data && '__schema' in obj.data)) {
451
+ return 'graphql';
452
+ }
453
+
454
+ throw new Error('Unable to detect specification format');
455
+ }
456
+
457
+ /**
458
+ * Convert format-specific tools to unified format
459
+ */
460
+ function toUnifiedTools(
461
+ tools: any[],
462
+ format: SpecFormat
463
+ ): UnifiedToolDefinition[] {
464
+ return tools.map(tool => ({
465
+ name: tool.name,
466
+ description: tool.description,
467
+ inputSchema: tool.inputSchema,
468
+ metadata: {
469
+ format,
470
+ endpoint: tool.metadata?.endpoint,
471
+ channel: tool.metadata?.channel,
472
+ operationType: tool.metadata?.operationType,
473
+ auth: tool.metadata?.auth,
474
+ tags: tool.metadata?.tags,
475
+ deprecated: tool.metadata?.deprecated,
476
+ confidence: tool.metadata?.confidence,
477
+ },
478
+ examples: tool.examples,
479
+ }));
480
+ }
481
+
482
+ /**
483
+ * Unified parser entry point - parses any supported specification format
484
+ */
485
+ export async function parseSpec(
486
+ input: string | object,
487
+ options: ParseOptions = {}
488
+ ): Promise<UnifiedParseResult> {
489
+ const format = options.format || detectFormat(input);
490
+
491
+ switch (format) {
492
+ case 'openapi': {
493
+ const parser = new OpenApiParser();
494
+ let spec: any;
495
+
496
+ if (typeof input === 'string') {
497
+ // Check if it's a file path or content
498
+ if (input.trim().startsWith('{') || input.trim().startsWith('openapi:') || input.trim().startsWith('swagger:')) {
499
+ // It's content, parse it
500
+ try {
501
+ spec = JSON.parse(input);
502
+ } catch {
503
+ spec = yaml.load(input);
504
+ }
505
+ parser.parseObject(spec);
506
+ } else {
507
+ // It's a file path
508
+ spec = await parser.parse(input);
509
+ }
510
+ } else {
511
+ spec = parser.parseObject(input as any);
512
+ }
513
+
514
+ // Optionally resolve refs
515
+ if (options.resolveRefs) {
516
+ const resolved = await resolveRefs(spec);
517
+ spec = resolved.spec;
518
+ }
519
+
520
+ const v3Spec = spec as OpenAPIV3.Document;
521
+ const analyzer = new OpenApiAnalyzer(v3Spec);
522
+ let endpoints = analyzer.extractEndpoints();
523
+
524
+ // Apply filters
525
+ if (!options.includeDeprecated) {
526
+ endpoints = endpoints.filter(e => !e.deprecated);
527
+ }
528
+ if (options.operationFilter) {
529
+ endpoints = endpoints.filter(options.operationFilter);
530
+ }
531
+
532
+ const transformer = new OpenApiTransformer(v3Spec);
533
+ const tools = transformer.transformEndpoints(endpoints);
534
+
535
+ // Extract auth info
536
+ const authInfo = analyzer.getAuthenticationInfo();
537
+
538
+ return {
539
+ format: 'openapi',
540
+ info: {
541
+ title: spec.info?.title,
542
+ version: spec.info?.version,
543
+ description: spec.info?.description,
544
+ },
545
+ tools: toUnifiedTools(tools, 'openapi'),
546
+ auth: authInfo.length > 0 ? {
547
+ type: authInfo[0].type,
548
+ schemes: authInfo.map(a => ({ name: a.name || 'default', type: a.type })),
549
+ } : undefined,
550
+ };
551
+ }
552
+
553
+ case 'asyncapi': {
554
+ const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
555
+ const result = parseAsyncAPI(inputStr);
556
+
557
+ return {
558
+ format: 'asyncapi',
559
+ info: {
560
+ title: result.info.title,
561
+ version: result.info.version,
562
+ description: result.info.description,
563
+ },
564
+ tools: toUnifiedTools(result.tools, 'asyncapi'),
565
+ auth: Object.keys(result.securitySchemes).length > 0 ? {
566
+ type: 'multiple',
567
+ schemes: Object.entries(result.securitySchemes).map(([name, scheme]) => ({
568
+ name,
569
+ type: (scheme as any).type,
570
+ })),
571
+ } : undefined,
572
+ };
573
+ }
574
+
575
+ case 'graphql': {
576
+ const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
577
+ const result = parseGraphQL(inputStr);
578
+
579
+ return {
580
+ format: 'graphql',
581
+ info: {
582
+ title: 'GraphQL API',
583
+ description: `${result.types.queries.length} queries, ${result.types.mutations.length} mutations, ${result.types.subscriptions.length} subscriptions`,
584
+ },
585
+ tools: toUnifiedTools(result.tools, 'graphql'),
586
+ };
587
+ }
588
+
589
+ case 'postman': {
590
+ const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
591
+ const result = parsePostman(inputStr);
592
+
593
+ return {
594
+ format: 'postman',
595
+ info: {
596
+ title: result.info.name,
597
+ description: result.info.description,
598
+ },
599
+ tools: toUnifiedTools(result.tools, 'postman'),
600
+ auth: result.auth ? { type: result.auth.type } : undefined,
601
+ };
602
+ }
603
+
604
+ case 'insomnia': {
605
+ const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
606
+ const result = parseInsomnia(inputStr);
607
+
608
+ return {
609
+ format: 'insomnia',
610
+ info: {
611
+ title: result.workspaces[0]?.name || 'Insomnia Collection',
612
+ description: result.workspaces[0]?.description,
613
+ },
614
+ tools: toUnifiedTools(result.tools, 'insomnia'),
615
+ };
616
+ }
617
+
618
+ case 'har': {
619
+ const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
620
+ const result = parseHAR(inputStr);
621
+
622
+ return {
623
+ format: 'har',
624
+ info: {
625
+ title: 'API from HAR',
626
+ description: `Inferred from ${result.info.entryCount} captured requests (${result.info.endpointCount} unique endpoints)`,
627
+ },
628
+ tools: toUnifiedTools(result.tools, 'har'),
629
+ };
630
+ }
631
+
632
+ default:
633
+ throw new Error(`Unsupported format: ${format}`);
634
+ }
635
+ }