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,198 @@
1
+ /**
2
+ * Streaming Convert API - Real-time progress updates via Server-Sent Events
3
+ * @copyright 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ import { NextRequest } from 'next/server';
8
+
9
+ export const runtime = 'nodejs';
10
+ export const dynamic = 'force-dynamic';
11
+
12
+ // Progress steps for the streaming response
13
+ const PROGRESS_STEPS = [
14
+ { id: 'validate', label: 'Validating GitHub URL', description: 'Checking repository accessibility' },
15
+ { id: 'fetch', label: 'Fetching repository', description: 'Downloading repository metadata' },
16
+ { id: 'classify', label: 'Classifying repository', description: 'Detecting repo type and structure' },
17
+ { id: 'readme', label: 'Analyzing README', description: 'Extracting documentation and examples' },
18
+ { id: 'openapi', label: 'Scanning for OpenAPI specs', description: 'Looking for API definitions' },
19
+ { id: 'code', label: 'Analyzing code', description: 'Extracting functions and patterns' },
20
+ { id: 'generate-ts', label: 'Generating TypeScript server', description: 'Creating MCP server code' },
21
+ { id: 'generate-py', label: 'Generating Python server', description: 'Creating Python alternative' },
22
+ { id: 'configs', label: 'Creating configurations', description: 'Building platform configs' },
23
+ { id: 'complete', label: 'Conversion complete', description: 'MCP server ready' },
24
+ ];
25
+
26
+ export async function GET(request: NextRequest) {
27
+ const url = request.nextUrl.searchParams.get('url');
28
+
29
+ if (!url) {
30
+ return new Response(JSON.stringify({ error: 'GitHub URL is required' }), {
31
+ status: 400,
32
+ headers: { 'Content-Type': 'application/json' },
33
+ });
34
+ }
35
+
36
+ // Validate GitHub URL
37
+ const githubPattern = /^https?:\/\/(www\.)?github\.com\/[\w-]+\/[\w.-]+/;
38
+ if (!githubPattern.test(url)) {
39
+ return new Response(JSON.stringify({ error: 'Invalid GitHub URL format' }), {
40
+ status: 400,
41
+ headers: { 'Content-Type': 'application/json' },
42
+ });
43
+ }
44
+
45
+ const encoder = new TextEncoder();
46
+
47
+ const stream = new ReadableStream({
48
+ async start(controller) {
49
+ const sendEvent = (event: string, data: unknown) => {
50
+ controller.enqueue(encoder.encode(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`));
51
+ };
52
+
53
+ try {
54
+ // Step 1: Validate URL
55
+ sendEvent('progress', {
56
+ step: 'validate',
57
+ status: 'in-progress',
58
+ message: PROGRESS_STEPS[0].label,
59
+ description: PROGRESS_STEPS[0].description,
60
+ progress: 5,
61
+ });
62
+ await new Promise(resolve => setTimeout(resolve, 300));
63
+ sendEvent('progress', { step: 'validate', status: 'complete', progress: 10 });
64
+
65
+ // Step 2: Fetch repository
66
+ sendEvent('progress', {
67
+ step: 'fetch',
68
+ status: 'in-progress',
69
+ message: PROGRESS_STEPS[1].label,
70
+ description: PROGRESS_STEPS[1].description,
71
+ progress: 15,
72
+ });
73
+
74
+ // Import the generator dynamically
75
+ const { generateFromGithub } = await import('@nirholas/github-to-mcp');
76
+
77
+ // Create a wrapper that will be used for streaming updates
78
+ let currentProgress = 15;
79
+
80
+ // We'll call the actual generation, but simulate progress steps
81
+ const progressUpdates = [
82
+ { step: 'fetch', delay: 500, progress: 20 },
83
+ { step: 'classify', delay: 800, progress: 30 },
84
+ { step: 'readme', delay: 600, progress: 40 },
85
+ { step: 'openapi', delay: 1000, progress: 55 },
86
+ { step: 'code', delay: 1200, progress: 70 },
87
+ { step: 'generate-ts', delay: 800, progress: 80 },
88
+ { step: 'generate-py', delay: 600, progress: 90 },
89
+ { step: 'configs', delay: 400, progress: 95 },
90
+ ];
91
+
92
+ // Start the actual generation in the background
93
+ const generationPromise = generateFromGithub(url, {
94
+ sources: ['readme', 'openapi', 'code'],
95
+ githubToken: process.env.GITHUB_TOKEN,
96
+ });
97
+
98
+ // Send progress updates while generation is happening
99
+ for (const update of progressUpdates) {
100
+ sendEvent('progress', {
101
+ step: update.step,
102
+ status: 'in-progress',
103
+ message: PROGRESS_STEPS.find(s => s.id === update.step)?.label || update.step,
104
+ description: PROGRESS_STEPS.find(s => s.id === update.step)?.description || '',
105
+ progress: update.progress,
106
+ });
107
+ await new Promise(resolve => setTimeout(resolve, update.delay));
108
+ sendEvent('progress', { step: update.step, status: 'complete', progress: update.progress + 5 });
109
+ }
110
+
111
+ // Wait for actual generation to complete
112
+ const result = await generationPromise;
113
+
114
+ // Generate the MCP server code
115
+ const code = result.generate();
116
+ const pythonCode = result.generatePython ? result.generatePython() : '';
117
+
118
+ // Generate config snippets
119
+ const repoName = result.name;
120
+
121
+ const claudeConfig = JSON.stringify({
122
+ mcpServers: {
123
+ [repoName]: {
124
+ command: 'npx',
125
+ args: ['tsx', `${repoName}-mcp/index.ts`],
126
+ },
127
+ },
128
+ }, null, 2);
129
+
130
+ const cursorConfig = JSON.stringify({
131
+ mcpServers: {
132
+ [repoName]: {
133
+ command: 'npx',
134
+ args: ['tsx', `${repoName}-mcp/index.ts`],
135
+ },
136
+ },
137
+ }, null, 2);
138
+
139
+ const claudePythonConfig = JSON.stringify({
140
+ mcpServers: {
141
+ [repoName]: {
142
+ command: 'python',
143
+ args: ['-m', `${repoName.replace(/-/g, '_')}_mcp`],
144
+ },
145
+ },
146
+ }, null, 2);
147
+
148
+ // Send completion
149
+ sendEvent('progress', {
150
+ step: 'complete',
151
+ status: 'complete',
152
+ message: PROGRESS_STEPS[9].label,
153
+ description: `Successfully extracted ${result.tools.length} tools`,
154
+ progress: 100,
155
+ });
156
+
157
+ // Send the final result
158
+ sendEvent('result', {
159
+ name: result.name,
160
+ tools: result.tools.map((t) => ({
161
+ name: t.name,
162
+ description: t.description,
163
+ inputSchema: t.inputSchema,
164
+ source: t.source,
165
+ })),
166
+ sources: result.sources,
167
+ classification: result.classification,
168
+ code,
169
+ pythonCode,
170
+ claudeConfig,
171
+ cursorConfig,
172
+ claudePythonConfig,
173
+ });
174
+
175
+ sendEvent('done', { success: true });
176
+
177
+ } catch (error) {
178
+ const message = error instanceof Error ? error.message : 'Conversion failed';
179
+
180
+ sendEvent('error', {
181
+ error: message,
182
+ code: message.includes('rate limit') ? 'RATE_LIMIT' : 'CONVERSION_ERROR',
183
+ });
184
+ } finally {
185
+ controller.close();
186
+ }
187
+ },
188
+ });
189
+
190
+ return new Response(stream, {
191
+ headers: {
192
+ 'Content-Type': 'text/event-stream',
193
+ 'Cache-Control': 'no-cache, no-transform',
194
+ 'Connection': 'keep-alive',
195
+ 'X-Accel-Buffering': 'no',
196
+ },
197
+ });
198
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Deploy API - Create cloud-hosted MCP servers
3
+ * @copyright 2024-2026 nirholas
4
+ * @license MIT
5
+ *
6
+ * POST /api/deploy - Deploy a new MCP server
7
+ * GET /api/deploy - List user's deployed servers
8
+ * DELETE /api/deploy?id=xxx - Delete a deployed server
9
+ */
10
+
11
+ import { NextRequest, NextResponse } from 'next/server';
12
+ import { nanoid } from 'nanoid';
13
+ import type {
14
+ DeployRequest,
15
+ DeployResponse,
16
+ DeployedServer,
17
+ ServerListResponse
18
+ } from '@/types/deploy';
19
+
20
+ // In production, this would be a database (Vercel KV, Planetscale, etc.)
21
+ // For now, we use in-memory storage with localStorage sync on client
22
+ const STORAGE_KEY = 'github-to-mcp-deployed-servers';
23
+
24
+ // Generate a secure API key
25
+ function generateApiKey(): string {
26
+ return `mcp_${nanoid(32)}`;
27
+ }
28
+
29
+ // Hash API key for storage (simple hash for demo, use bcrypt in production)
30
+ function hashApiKey(key: string): string {
31
+ // In production, use proper hashing
32
+ return Buffer.from(key).toString('base64');
33
+ }
34
+
35
+ // Generate server endpoint URL
36
+ function generateEndpoint(serverId: string): string {
37
+ const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://github-to-mcp.vercel.app';
38
+ return `${baseUrl}/api/mcp/${serverId}`;
39
+ }
40
+
41
+ /**
42
+ * POST /api/deploy - Deploy a new MCP server
43
+ */
44
+ export async function POST(request: NextRequest): Promise<NextResponse<DeployResponse>> {
45
+ try {
46
+ const body = await request.json() as DeployRequest;
47
+
48
+ // Validate request
49
+ if (!body.name || !body.code || !body.tools?.length) {
50
+ return NextResponse.json({
51
+ success: false,
52
+ error: 'Missing required fields: name, code, and tools are required',
53
+ }, { status: 400 });
54
+ }
55
+
56
+ // Generate IDs and keys
57
+ const serverId = nanoid(12);
58
+ const apiKey = generateApiKey();
59
+ const endpoint = generateEndpoint(serverId);
60
+
61
+ // Create deployed server record
62
+ const server: DeployedServer = {
63
+ id: serverId,
64
+ name: body.name,
65
+ description: body.description || `MCP server for ${body.name}`,
66
+
67
+ tools: body.tools.map(t => ({
68
+ name: t.name,
69
+ description: t.description,
70
+ inputSchema: t.inputSchema,
71
+ enabled: true,
72
+ callCount: 0,
73
+ })),
74
+ code: body.code,
75
+ language: 'typescript',
76
+
77
+ endpoint,
78
+ status: 'active',
79
+ region: 'us-east-1',
80
+ createdAt: new Date().toISOString(),
81
+ updatedAt: new Date().toISOString(),
82
+
83
+ sourceRepo: body.sourceRepo,
84
+
85
+ apiKeyHash: hashApiKey(apiKey),
86
+ rateLimit: {
87
+ requestsPerMinute: body.rateLimit?.requestsPerMinute || 60,
88
+ requestsPerDay: body.rateLimit?.requestsPerDay || 10000,
89
+ enabled: true,
90
+ },
91
+
92
+ usage: {
93
+ totalCalls: 0,
94
+ totalCallsToday: 0,
95
+ totalCallsThisMonth: 0,
96
+ successRate: 100,
97
+ avgLatencyMs: 0,
98
+ callsByTool: {},
99
+ callsByDay: [],
100
+ errors: [],
101
+ },
102
+ };
103
+
104
+ // In production: Save to database
105
+ // For demo: Return the server data (client will store in localStorage)
106
+
107
+ return NextResponse.json({
108
+ success: true,
109
+ server,
110
+ endpoint,
111
+ apiKey, // Only returned on creation!
112
+ });
113
+ } catch (error) {
114
+ console.error('Deploy error:', error);
115
+ return NextResponse.json({
116
+ success: false,
117
+ error: error instanceof Error ? error.message : 'Deployment failed',
118
+ }, { status: 500 });
119
+ }
120
+ }
121
+
122
+ /**
123
+ * GET /api/deploy - List deployed servers
124
+ * In production, this would fetch from database based on authenticated user
125
+ */
126
+ export async function GET(request: NextRequest): Promise<NextResponse<ServerListResponse>> {
127
+ // In production: Fetch from database with auth
128
+ // For demo: Client manages storage, this is a placeholder
129
+
130
+ return NextResponse.json({
131
+ servers: [],
132
+ total: 0,
133
+ hasMore: false,
134
+ });
135
+ }
136
+
137
+ /**
138
+ * DELETE /api/deploy?id=xxx - Delete a deployed server
139
+ */
140
+ export async function DELETE(request: NextRequest): Promise<NextResponse> {
141
+ const { searchParams } = new URL(request.url);
142
+ const serverId = searchParams.get('id');
143
+
144
+ if (!serverId) {
145
+ return NextResponse.json({
146
+ success: false,
147
+ error: 'Server ID is required',
148
+ }, { status: 400 });
149
+ }
150
+
151
+ // In production: Delete from database with auth verification
152
+
153
+ return NextResponse.json({
154
+ success: true,
155
+ message: `Server ${serverId} deleted`,
156
+ });
157
+ }
@@ -0,0 +1,308 @@
1
+ /**
2
+ * Edge API Route for github-to-mcp
3
+ *
4
+ * This route runs on Vercel Edge Runtime for fast, globally distributed processing.
5
+ * It provides a lightweight version of the MCP generation that works in edge environments.
6
+ */
7
+
8
+ import { NextRequest, NextResponse } from 'next/server';
9
+
10
+ // Tell Next.js to use edge runtime
11
+ export const runtime = 'edge';
12
+
13
+ // Edge-compatible types
14
+ interface EdgeResult {
15
+ repo: string;
16
+ name: string;
17
+ tools: Array<{
18
+ name: string;
19
+ description: string;
20
+ inputSchema: object;
21
+ source: { type: string; file: string };
22
+ confidence?: number;
23
+ }>;
24
+ classification: {
25
+ type: string;
26
+ confidence: number;
27
+ indicators: string[];
28
+ };
29
+ metadata: {
30
+ stars: number;
31
+ language: string;
32
+ license?: string;
33
+ description?: string;
34
+ };
35
+ typescript?: string;
36
+ python?: string;
37
+ }
38
+
39
+ /**
40
+ * Parse GitHub URL
41
+ */
42
+ function parseGithubUrl(url: string): { owner: string; repo: string; branch?: string } {
43
+ const treeMatch = url.match(/github\.com\/([^\/]+)\/([^\/]+)\/tree\/([^\/]+)/);
44
+ if (treeMatch) {
45
+ return {
46
+ owner: treeMatch[1],
47
+ repo: treeMatch[2].replace('.git', ''),
48
+ branch: treeMatch[3]
49
+ };
50
+ }
51
+
52
+ const simpleMatch = url.match(/github\.com\/([^\/]+)\/([^\/]+)/);
53
+ if (simpleMatch) {
54
+ return {
55
+ owner: simpleMatch[1],
56
+ repo: simpleMatch[2].replace('.git', ''),
57
+ branch: 'main'
58
+ };
59
+ }
60
+
61
+ throw new Error(`Invalid GitHub URL: ${url}`);
62
+ }
63
+
64
+ /**
65
+ * Fetch repository metadata from GitHub API
66
+ */
67
+ async function fetchRepoMetadata(owner: string, repo: string, token?: string) {
68
+ const headers: Record<string, string> = {
69
+ 'Accept': 'application/vnd.github.v3+json',
70
+ 'User-Agent': 'github-to-mcp-edge'
71
+ };
72
+
73
+ if (token) {
74
+ headers['Authorization'] = `Bearer ${token}`;
75
+ }
76
+
77
+ const response = await fetch(`https://api.github.com/repos/${owner}/${repo}`, { headers });
78
+
79
+ if (!response.ok) {
80
+ throw new Error(`GitHub API error: ${response.status}`);
81
+ }
82
+
83
+ const data = await response.json();
84
+
85
+ return {
86
+ stars: data.stargazers_count,
87
+ language: data.language || 'unknown',
88
+ license: data.license?.spdx_id,
89
+ description: data.description,
90
+ defaultBranch: data.default_branch
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Fetch README content
96
+ */
97
+ async function fetchReadme(owner: string, repo: string, branch?: string, token?: string): Promise<string | null> {
98
+ const headers: Record<string, string> = {
99
+ 'Accept': 'application/vnd.github.v3+json',
100
+ 'User-Agent': 'github-to-mcp-edge'
101
+ };
102
+
103
+ if (token) {
104
+ headers['Authorization'] = `Bearer ${token}`;
105
+ }
106
+
107
+ const readmeFiles = ['README.md', 'README.MD', 'readme.md'];
108
+
109
+ for (const filename of readmeFiles) {
110
+ try {
111
+ const url = `https://api.github.com/repos/${owner}/${repo}/contents/${filename}${branch ? `?ref=${branch}` : ''}`;
112
+ const response = await fetch(url, { headers });
113
+
114
+ if (response.ok) {
115
+ const data = await response.json();
116
+ if (data.type === 'file' && data.content) {
117
+ return atob(data.content.replace(/\n/g, ''));
118
+ }
119
+ }
120
+ } catch {
121
+ continue;
122
+ }
123
+ }
124
+
125
+ return null;
126
+ }
127
+
128
+ /**
129
+ * Classify repository type
130
+ */
131
+ function classifyRepo(readme: string | null, language: string) {
132
+ let type = 'unknown';
133
+ let confidence = 0.3;
134
+ const indicators: string[] = [];
135
+
136
+ const readmeLower = readme?.toLowerCase() || '';
137
+
138
+ if (readmeLower.includes('mcp') || readmeLower.includes('model context protocol')) {
139
+ type = 'mcp-server';
140
+ confidence = 0.9;
141
+ indicators.push('Contains MCP references');
142
+ } else if (readmeLower.includes('api') || readmeLower.includes('sdk')) {
143
+ type = 'api-sdk';
144
+ confidence = 0.7;
145
+ indicators.push('Contains API/SDK references');
146
+ } else if (readmeLower.includes('cli') || readmeLower.includes('command line')) {
147
+ type = 'cli-tool';
148
+ confidence = 0.7;
149
+ indicators.push('Contains CLI references');
150
+ } else if (readmeLower.includes('library') || readmeLower.includes('package')) {
151
+ type = 'library';
152
+ confidence = 0.6;
153
+ indicators.push('Contains library references');
154
+ }
155
+
156
+ indicators.push(`Language: ${language}`);
157
+
158
+ return { type, confidence, indicators };
159
+ }
160
+
161
+ /**
162
+ * Extract tools from README
163
+ */
164
+ function extractToolsFromReadme(readme: string): EdgeResult['tools'] {
165
+ const tools: EdgeResult['tools'] = [];
166
+
167
+ // Extract API endpoints
168
+ const endpointRegex = /(?:GET|POST|PUT|DELETE|PATCH)\s+[`']?([\/\w\-\{\}:]+)[`']?/gi;
169
+ let match;
170
+
171
+ while ((match = endpointRegex.exec(readme)) !== null) {
172
+ const endpoint = match[1];
173
+ const method = match[0].split(' ')[0].toUpperCase();
174
+ const name = endpoint
175
+ .replace(/[{}]/g, '')
176
+ .split('/')
177
+ .filter(p => p && !p.startsWith(':'))
178
+ .map(p => p.charAt(0).toUpperCase() + p.slice(1))
179
+ .join('');
180
+
181
+ tools.push({
182
+ name: method.toLowerCase() + name,
183
+ description: `${method} ${endpoint}`,
184
+ inputSchema: { type: 'object', properties: {}, required: [] },
185
+ source: { type: 'readme', file: 'README.md' },
186
+ confidence: 0.6
187
+ });
188
+ }
189
+
190
+ return tools;
191
+ }
192
+
193
+ /**
194
+ * Generate TypeScript code
195
+ */
196
+ function generateTypeScript(tools: EdgeResult['tools'], repoName: string, owner: string): string {
197
+ const safeName = repoName.replace(/[^a-zA-Z0-9]/g, '_');
198
+
199
+ const toolDefs = tools.map(t => ` {
200
+ name: "${t.name}",
201
+ description: "${t.description.replace(/"/g, '\\"')}",
202
+ inputSchema: ${JSON.stringify(t.inputSchema)}
203
+ }`).join(',\n');
204
+
205
+ const handlers = tools.map((t, i) =>
206
+ `${i === 0 ? '' : ' else '}if (name === "${t.name}") {
207
+ return { content: [{ type: "text", text: "Not implemented: ${t.name}" }] };
208
+ }`
209
+ ).join('\n ');
210
+
211
+ return `/**
212
+ * Auto-generated MCP Server for ${repoName}
213
+ * Generated by @nirholas/github-to-mcp (Edge)
214
+ * Repository: https://github.com/${owner}/${repoName}
215
+ */
216
+
217
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
218
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
219
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
220
+
221
+ const server = new Server(
222
+ { name: "${safeName}-mcp", version: "1.0.0" },
223
+ { capabilities: { tools: {} } }
224
+ );
225
+
226
+ const tools = [
227
+ ${toolDefs}
228
+ ];
229
+
230
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
231
+
232
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
233
+ const { name, arguments: args } = request.params;
234
+ ${handlers}
235
+ throw new Error(\`Unknown tool: \${name}\`);
236
+ });
237
+
238
+ const transport = new StdioServerTransport();
239
+ server.connect(transport);
240
+ `;
241
+ }
242
+
243
+ /**
244
+ * POST handler for edge generation
245
+ */
246
+ export async function POST(request: NextRequest) {
247
+ try {
248
+ const body = await request.json();
249
+ const { url, language = 'typescript' } = body;
250
+
251
+ if (!url) {
252
+ return NextResponse.json(
253
+ { error: 'Missing required field: url' },
254
+ { status: 400 }
255
+ );
256
+ }
257
+
258
+ // Get GitHub token from environment or request
259
+ const token = process.env.GITHUB_TOKEN || body.token;
260
+
261
+ // Parse URL
262
+ const { owner, repo, branch } = parseGithubUrl(url);
263
+
264
+ // Fetch data in parallel
265
+ const [metadata, readme] = await Promise.all([
266
+ fetchRepoMetadata(owner, repo, token),
267
+ fetchReadme(owner, repo, branch, token)
268
+ ]);
269
+
270
+ // Classify and extract
271
+ const classification = classifyRepo(readme, metadata.language);
272
+ const tools = readme ? extractToolsFromReadme(readme) : [];
273
+
274
+ // Build result
275
+ const result: EdgeResult = {
276
+ repo: `${owner}/${repo}`,
277
+ name: repo,
278
+ tools,
279
+ classification,
280
+ metadata
281
+ };
282
+
283
+ // Generate code
284
+ if (language === 'typescript' || language === 'both') {
285
+ result.typescript = generateTypeScript(tools, repo, owner);
286
+ }
287
+
288
+ return NextResponse.json(result);
289
+
290
+ } catch (error) {
291
+ const message = error instanceof Error ? error.message : 'Unknown error';
292
+ return NextResponse.json(
293
+ { error: message },
294
+ { status: 500 }
295
+ );
296
+ }
297
+ }
298
+
299
+ /**
300
+ * GET handler for health check
301
+ */
302
+ export async function GET() {
303
+ return NextResponse.json({
304
+ status: 'ok',
305
+ runtime: 'edge',
306
+ timestamp: new Date().toISOString()
307
+ });
308
+ }