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,797 @@
1
+ /**
2
+ * @fileoverview Module exports and initialization
3
+ * @copyright Copyright (c) 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ /**
8
+ * Main Generator
9
+ * Orchestrates the entire GitHub to MCP conversion process
10
+ */
11
+
12
+ import { GithubClient } from './github-client';
13
+ import { ReadmeExtractor } from './readme-extractor';
14
+ import { CodeExtractor } from './code-extractor';
15
+ import { GraphQLExtractor } from './graphql-extractor';
16
+ import { McpIntrospector } from './mcp-introspector';
17
+ import { PythonGenerator } from './python-generator';
18
+ import { GoGenerator } from './go-generator';
19
+ import { convertOpenApiToMcp } from '@github-to-mcp/openapi-parser';
20
+ import {
21
+ GithubToMcpOptions,
22
+ GenerationResult,
23
+ ExtractedTool,
24
+ SourceBreakdown,
25
+ RepoClassification,
26
+ RepoType,
27
+ OutputLanguage
28
+ } from './types';
29
+ import * as fs from 'fs/promises';
30
+ import * as path from 'path';
31
+
32
+ export class GithubToMcpGenerator {
33
+ private github: GithubClient;
34
+ private readmeExtractor: ReadmeExtractor;
35
+ private codeExtractor: CodeExtractor;
36
+ private graphqlExtractor: GraphQLExtractor;
37
+ private mcpIntrospector: McpIntrospector;
38
+ private pythonGenerator: PythonGenerator;
39
+ private goGenerator: GoGenerator;
40
+
41
+ constructor(private options: GithubToMcpOptions = {}) {
42
+ this.github = new GithubClient(options.githubToken);
43
+ this.readmeExtractor = new ReadmeExtractor();
44
+ this.codeExtractor = new CodeExtractor();
45
+ this.graphqlExtractor = new GraphQLExtractor();
46
+ this.mcpIntrospector = new McpIntrospector();
47
+ this.pythonGenerator = new PythonGenerator();
48
+ this.goGenerator = new GoGenerator();
49
+ }
50
+
51
+ /**
52
+ * Generate MCP tools from GitHub repository
53
+ */
54
+ async generate(githubUrl: string): Promise<GenerationResult> {
55
+ // Parse GitHub URL
56
+ const repoMeta = this.github.parseGithubUrl(githubUrl);
57
+
58
+ // Get repository metadata
59
+ const metadata = await this.github.getRepoMetadata(repoMeta.owner, repoMeta.repo);
60
+
61
+ // Get README for classification
62
+ const readme = await this.github.getReadme(repoMeta.owner, repoMeta.repo);
63
+
64
+ // Classify the repository
65
+ const classification = await this.classifyRepo(repoMeta.owner, repoMeta.repo, readme, metadata);
66
+
67
+ // Extract tools from all sources
68
+ const tools: ExtractedTool[] = [];
69
+ const sources: SourceBreakdown[] = [];
70
+
71
+ const enabledSources = this.options.sources || ['readme', 'openapi', 'code'];
72
+
73
+ // 1. Extract from OpenAPI specs
74
+ if (enabledSources.includes('openapi')) {
75
+ const openapiTools = await this.extractFromOpenApi(repoMeta.owner, repoMeta.repo);
76
+ tools.push(...openapiTools);
77
+
78
+ if (openapiTools.length > 0) {
79
+ sources.push({
80
+ type: 'openapi',
81
+ count: openapiTools.length,
82
+ files: openapiTools.map(t => t.source.file)
83
+ });
84
+ }
85
+ }
86
+
87
+ // 2. Extract from README
88
+ if (enabledSources.includes('readme')) {
89
+ const readmeTools = await this.extractFromReadme(repoMeta.owner, repoMeta.repo);
90
+ tools.push(...readmeTools);
91
+
92
+ if (readmeTools.length > 0) {
93
+ sources.push({
94
+ type: 'readme',
95
+ count: readmeTools.length,
96
+ files: ['README.md']
97
+ });
98
+ }
99
+ }
100
+
101
+ // 3. Extract from code
102
+ if (enabledSources.includes('code')) {
103
+ const codeTools = await this.extractFromCode(repoMeta.owner, repoMeta.repo);
104
+ tools.push(...codeTools);
105
+
106
+ if (codeTools.length > 0) {
107
+ sources.push({
108
+ type: 'code',
109
+ count: codeTools.length,
110
+ files: [...new Set(codeTools.map(t => t.source.file))]
111
+ });
112
+ }
113
+ }
114
+
115
+ // 4. Extract from GraphQL schemas
116
+ const graphqlTools = await this.extractFromGraphQL(repoMeta.owner, repoMeta.repo);
117
+ tools.push(...graphqlTools);
118
+ if (graphqlTools.length > 0) {
119
+ sources.push({
120
+ type: 'graphql',
121
+ count: graphqlTools.length,
122
+ files: graphqlTools.map(t => t.source.file).filter((f, i, a) => a.indexOf(f) === i)
123
+ });
124
+ }
125
+
126
+ // 5. Introspect existing MCP servers
127
+ if (classification.type === 'mcp-server') {
128
+ const mcpTools = await this.introspectMcpServer(repoMeta.owner, repoMeta.repo);
129
+ tools.push(...mcpTools);
130
+ if (mcpTools.length > 0) {
131
+ sources.push({
132
+ type: 'mcp-introspect',
133
+ count: mcpTools.length,
134
+ files: mcpTools.map(t => t.source.file).filter((f, i, a) => a.indexOf(f) === i)
135
+ });
136
+ }
137
+ }
138
+
139
+ // 6. Add universal fallback tools (always included)
140
+ const universalTools = this.generateUniversalTools(repoMeta.owner, repoMeta.repo);
141
+ tools.push(...universalTools);
142
+ sources.push({
143
+ type: 'universal',
144
+ count: universalTools.length,
145
+ files: []
146
+ });
147
+
148
+ // Deduplicate tools
149
+ const uniqueTools = this.deduplicateTools(tools);
150
+
151
+ // Determine output language
152
+ const outputLanguage = this.options.outputLanguage || 'typescript';
153
+
154
+ // Build result
155
+ const result: GenerationResult = {
156
+ repo: githubUrl,
157
+ name: repoMeta.repo,
158
+ tools: uniqueTools,
159
+ sources,
160
+ classification,
161
+ metadata,
162
+ generate: () => this.generateCode(uniqueTools, repoMeta.repo, repoMeta.owner, outputLanguage),
163
+ generatePython: () => this.pythonGenerator.generateServer(uniqueTools, repoMeta.repo, repoMeta.owner),
164
+ save: async (outputDir: string) => this.saveToFiles(uniqueTools, repoMeta.repo, repoMeta.owner, outputDir),
165
+ download: () => this.downloadZip(uniqueTools, repoMeta.repo)
166
+ };
167
+
168
+ return result;
169
+ }
170
+
171
+ /**
172
+ * Classify the repository type
173
+ */
174
+ private async classifyRepo(
175
+ owner: string,
176
+ repo: string,
177
+ readme: string | null,
178
+ metadata: any
179
+ ): Promise<RepoClassification> {
180
+ const indicators: string[] = [];
181
+ let type: RepoType = 'unknown';
182
+ let confidence = 0.3;
183
+
184
+ const readmeLower = (readme || '').toLowerCase();
185
+
186
+ // Check for MCP server indicators
187
+ if (
188
+ readmeLower.includes('mcp') ||
189
+ readmeLower.includes('model context protocol') ||
190
+ readmeLower.includes('@modelcontextprotocol')
191
+ ) {
192
+ type = 'mcp-server';
193
+ confidence = 0.9;
194
+ indicators.push('MCP keywords in README');
195
+ }
196
+ // Check for API/SDK indicators
197
+ else if (
198
+ readmeLower.includes('api') ||
199
+ readmeLower.includes('sdk') ||
200
+ readmeLower.includes('client library') ||
201
+ readmeLower.includes('openapi') ||
202
+ readmeLower.includes('swagger')
203
+ ) {
204
+ type = 'api-sdk';
205
+ confidence = 0.8;
206
+ indicators.push('API/SDK keywords in README');
207
+ }
208
+ // Check for CLI indicators
209
+ else if (
210
+ readmeLower.includes('cli') ||
211
+ readmeLower.includes('command line') ||
212
+ readmeLower.includes('usage:') ||
213
+ readmeLower.includes('npx ') ||
214
+ readmeLower.includes('$ ')
215
+ ) {
216
+ type = 'cli-tool';
217
+ confidence = 0.7;
218
+ indicators.push('CLI patterns in README');
219
+ }
220
+ // Check for library indicators
221
+ else if (
222
+ readmeLower.includes('npm install') ||
223
+ readmeLower.includes('yarn add') ||
224
+ readmeLower.includes('pip install') ||
225
+ readmeLower.includes('import ') ||
226
+ readmeLower.includes('require(')
227
+ ) {
228
+ type = 'library';
229
+ confidence = 0.6;
230
+ indicators.push('Package installation patterns');
231
+ }
232
+ // Check for documentation
233
+ else if (
234
+ readmeLower.includes('documentation') ||
235
+ readmeLower.includes('tutorial') ||
236
+ readmeLower.includes('guide') ||
237
+ readmeLower.includes('learn ')
238
+ ) {
239
+ type = 'documentation';
240
+ confidence = 0.5;
241
+ indicators.push('Documentation keywords');
242
+ }
243
+
244
+ // Boost confidence based on language
245
+ if (metadata.language) {
246
+ indicators.push(`Primary language: ${metadata.language}`);
247
+ if (['TypeScript', 'JavaScript', 'Python'].includes(metadata.language)) {
248
+ confidence = Math.min(1, confidence + 0.1);
249
+ }
250
+ }
251
+
252
+ // Boost confidence based on stars
253
+ if (metadata.stars > 1000) {
254
+ indicators.push(`Popular repo (${metadata.stars} stars)`);
255
+ confidence = Math.min(1, confidence + 0.05);
256
+ }
257
+
258
+ return { type, confidence, indicators };
259
+ }
260
+
261
+ /**
262
+ * Generate universal fallback tools that work for any repo
263
+ */
264
+ private generateUniversalTools(owner: string, repo: string): ExtractedTool[] {
265
+ return [
266
+ {
267
+ name: 'get_readme',
268
+ description: `Get the README content from ${owner}/${repo}`,
269
+ inputSchema: {
270
+ type: 'object',
271
+ properties: {},
272
+ required: []
273
+ },
274
+ implementation: `async function get_readme() {
275
+ const response = await fetch('https://api.github.com/repos/${owner}/${repo}/readme', {
276
+ headers: { 'Accept': 'application/vnd.github.raw' }
277
+ });
278
+ if (!response.ok) {
279
+ if (response.status === 404) {
280
+ return { content: [{ type: 'text', text: 'No README found in this repository.' }] };
281
+ }
282
+ throw new Error(\`Failed to fetch README (HTTP \${response.status})\`);
283
+ }
284
+ return { content: [{ type: 'text', text: await response.text() }] };
285
+ }`,
286
+ source: { type: 'universal', file: 'generated' }
287
+ },
288
+ {
289
+ name: 'list_files',
290
+ description: `List files and directories in ${owner}/${repo}`,
291
+ inputSchema: {
292
+ type: 'object',
293
+ properties: {
294
+ path: {
295
+ type: 'string',
296
+ description: 'Directory path (empty for root)',
297
+ default: ''
298
+ }
299
+ },
300
+ required: []
301
+ },
302
+ implementation: `async function list_files(args: { path?: string }) {
303
+ const path = args.path || '';
304
+ const response = await fetch(\`https://api.github.com/repos/${owner}/${repo}/contents/\${path}\`);
305
+ if (!response.ok) {
306
+ if (response.status === 404) {
307
+ return { content: [{ type: 'text', text: \`Directory not found: \${path || '/'}\` }] };
308
+ }
309
+ throw new Error(\`Failed to list files (HTTP \${response.status})\`);
310
+ }
311
+ const data = await response.json();
312
+ const files = Array.isArray(data) ? data.map((f: any) => ({ name: f.name, type: f.type, path: f.path })) : [data];
313
+ return { content: [{ type: 'text', text: JSON.stringify(files, null, 2) }] };
314
+ }`,
315
+ source: { type: 'universal', file: 'generated' }
316
+ },
317
+ {
318
+ name: 'read_file',
319
+ description: `Read a file from ${owner}/${repo}`,
320
+ inputSchema: {
321
+ type: 'object',
322
+ properties: {
323
+ path: {
324
+ type: 'string',
325
+ description: 'File path to read'
326
+ }
327
+ },
328
+ required: ['path']
329
+ },
330
+ implementation: `async function read_file(args: { path: string }) {
331
+ const response = await fetch(\`https://api.github.com/repos/${owner}/${repo}/contents/\${args.path}\`, {
332
+ headers: { 'Accept': 'application/vnd.github.raw' }
333
+ });
334
+ if (!response.ok) {
335
+ if (response.status === 404) {
336
+ return { content: [{ type: 'text', text: \`File not found: \${args.path}. Use list_files to see available files.\` }] };
337
+ }
338
+ throw new Error(\`Failed to read file (HTTP \${response.status}): \${args.path}\`);
339
+ }
340
+ return { content: [{ type: 'text', text: await response.text() }] };
341
+ }`,
342
+ source: { type: 'universal', file: 'generated' }
343
+ },
344
+ {
345
+ name: 'search_code',
346
+ description: `Search for code in ${owner}/${repo}`,
347
+ inputSchema: {
348
+ type: 'object',
349
+ properties: {
350
+ query: {
351
+ type: 'string',
352
+ description: 'Search query'
353
+ }
354
+ },
355
+ required: ['query']
356
+ },
357
+ implementation: `async function search_code(args: { query: string }) {
358
+ const response = await fetch(\`https://api.github.com/search/code?q=\${encodeURIComponent(args.query)}+repo:${owner}/${repo}\`);
359
+ if (!response.ok) {
360
+ if (response.status === 403) {
361
+ return { content: [{ type: 'text', text: 'GitHub API rate limit exceeded. Try again later or use a GitHub token.' }] };
362
+ }
363
+ if (response.status === 422) {
364
+ return { content: [{ type: 'text', text: 'Search query invalid. Try a simpler search term.' }] };
365
+ }
366
+ throw new Error(\`Search failed (HTTP \${response.status})\`);
367
+ }
368
+ const data = await response.json();
369
+ if (!data.items || data.items.length === 0) {
370
+ return { content: [{ type: 'text', text: \`No results found for: \${args.query}\` }] };
371
+ }
372
+ const results = data.items.slice(0, 10).map((item: any) => ({
373
+ file: item.path,
374
+ url: item.html_url
375
+ }));
376
+ return { content: [{ type: 'text', text: JSON.stringify(results, null, 2) }] };
377
+ }`,
378
+ source: { type: 'universal', file: 'generated' }
379
+ }
380
+ ];
381
+ }
382
+
383
+ /**
384
+ * Extract tools from OpenAPI specs
385
+ */
386
+ private async extractFromOpenApi(owner: string, repo: string): Promise<ExtractedTool[]> {
387
+ const tools: ExtractedTool[] = [];
388
+
389
+ const specs = await this.github.findApiSpecs(owner, repo);
390
+
391
+ for (const spec of specs) {
392
+ try {
393
+ // Use OpenAPI converter
394
+ const converted = await convertOpenApiToMcp(spec.spec);
395
+
396
+ // Convert to our format
397
+ for (const tool of converted.tools) {
398
+ tools.push({
399
+ name: tool.name,
400
+ description: tool.description,
401
+ inputSchema: tool.inputSchema,
402
+ source: {
403
+ type: 'openapi',
404
+ file: spec.path
405
+ }
406
+ });
407
+ }
408
+ } catch (error) {
409
+ console.error(`Failed to convert OpenAPI spec: ${spec.path}`);
410
+ }
411
+ }
412
+
413
+ return tools;
414
+ }
415
+
416
+ /**
417
+ * Extract tools from README
418
+ */
419
+ private async extractFromReadme(owner: string, repo: string): Promise<ExtractedTool[]> {
420
+ const readme = await this.github.getReadme(owner, repo);
421
+
422
+ if (!readme) {
423
+ return [];
424
+ }
425
+
426
+ return this.readmeExtractor.extract(readme);
427
+ }
428
+
429
+ /**
430
+ * Extract tools from code
431
+ */
432
+ private async extractFromCode(owner: string, repo: string): Promise<ExtractedTool[]> {
433
+ const tools: ExtractedTool[] = [];
434
+
435
+ // Search for SDK files (TypeScript, JavaScript, and Python)
436
+ const sdkFiles = await this.github.searchFiles(
437
+ owner,
438
+ repo,
439
+ /\.(ts|js|py)$/,
440
+ 2 // Max depth
441
+ );
442
+
443
+ for (const file of sdkFiles) {
444
+ // Skip test files, config files, etc.
445
+ if (this.shouldSkipFile(file.path)) {
446
+ continue;
447
+ }
448
+
449
+ const extracted = await this.codeExtractor.extract(file.content, file.path);
450
+ tools.push(...extracted);
451
+ }
452
+
453
+ return tools;
454
+ }
455
+
456
+ /**
457
+ * Check if file should be skipped
458
+ */
459
+ private shouldSkipFile(filepath: string): boolean {
460
+ const skipPatterns = [
461
+ /test/i,
462
+ /spec/i,
463
+ /\.config\./,
464
+ /\.setup\./,
465
+ /node_modules/,
466
+ /dist/,
467
+ /build/
468
+ ];
469
+
470
+ return skipPatterns.some(pattern => pattern.test(filepath));
471
+ }
472
+
473
+ /**
474
+ * Extract tools from GraphQL schemas
475
+ */
476
+ private async extractFromGraphQL(owner: string, repo: string): Promise<ExtractedTool[]> {
477
+ const tools: ExtractedTool[] = [];
478
+
479
+ try {
480
+ // Search for GraphQL schema files
481
+ const graphqlFiles = await this.github.searchFiles(
482
+ owner,
483
+ repo,
484
+ /\.(graphql|gql)$/,
485
+ 3 // Max depth
486
+ );
487
+
488
+ for (const file of graphqlFiles) {
489
+ if (file.path.includes('node_modules')) continue;
490
+
491
+ try {
492
+ const schema = this.graphqlExtractor.parseSchema(file.content);
493
+
494
+ // Determine GraphQL endpoint (guess based on common patterns)
495
+ const endpoint = `https://api.github.com/repos/${owner}/${repo}/graphql`;
496
+
497
+ const schemaTools = this.graphqlExtractor.schemaToTools(schema, endpoint, owner, repo);
498
+ tools.push(...schemaTools);
499
+ } catch (error) {
500
+ console.error(`Failed to parse GraphQL schema: ${file.path}`);
501
+ }
502
+ }
503
+ } catch (error) {
504
+ // No GraphQL files found
505
+ }
506
+
507
+ return tools;
508
+ }
509
+
510
+ /**
511
+ * Introspect existing MCP server to extract tool definitions
512
+ */
513
+ private async introspectMcpServer(owner: string, repo: string): Promise<ExtractedTool[]> {
514
+ const tools: ExtractedTool[] = [];
515
+
516
+ try {
517
+ // Search for likely MCP server files
518
+ const serverFiles = await this.github.searchFiles(
519
+ owner,
520
+ repo,
521
+ /\.(ts|js|py)$/,
522
+ 3
523
+ );
524
+
525
+ for (const file of serverFiles) {
526
+ // Check if this file looks like an MCP server
527
+ if (!this.mcpIntrospector.isLikelyMcpServer(file.content)) {
528
+ continue;
529
+ }
530
+
531
+ let extracted: ExtractedTool[] = [];
532
+
533
+ if (file.path.endsWith('.py')) {
534
+ extracted = this.mcpIntrospector.extractFromPython(file.content, file.path);
535
+ } else {
536
+ extracted = this.mcpIntrospector.extractFromTypeScript(file.content, file.path);
537
+ }
538
+
539
+ tools.push(...extracted);
540
+ }
541
+ } catch (error) {
542
+ console.error('Failed to introspect MCP server:', error);
543
+ }
544
+
545
+ return tools;
546
+ }
547
+
548
+ /**
549
+ * Deduplicate tools by name
550
+ */
551
+ private deduplicateTools(tools: ExtractedTool[]): ExtractedTool[] {
552
+ const seen = new Map<string, ExtractedTool>();
553
+
554
+ for (const tool of tools) {
555
+ if (!seen.has(tool.name)) {
556
+ seen.set(tool.name, tool);
557
+ } else {
558
+ // Prefer MCP introspect > OpenAPI > GraphQL > Code > README > universal > others
559
+ const existing = seen.get(tool.name)!;
560
+ const priority: Record<string, number> = {
561
+ 'mcp-introspect': 8,
562
+ openapi: 7,
563
+ graphql: 6,
564
+ code: 5,
565
+ tests: 4,
566
+ docs: 3,
567
+ examples: 2,
568
+ readme: 1,
569
+ universal: 0
570
+ };
571
+
572
+ if ((priority[tool.source.type] || 0) > (priority[existing.source.type] || 0)) {
573
+ seen.set(tool.name, tool);
574
+ }
575
+ }
576
+ }
577
+
578
+ return Array.from(seen.values());
579
+ }
580
+
581
+ /**
582
+ * Generate TypeScript MCP server code
583
+ */
584
+ private generateCode(tools: ExtractedTool[], repoName: string, owner?: string, language: OutputLanguage = 'typescript'): string {
585
+ // If Python output requested, use Python generator
586
+ if (language === 'python') {
587
+ return this.pythonGenerator.generateServer(tools, repoName, owner || 'unknown');
588
+ }
589
+
590
+ const toolDefinitions = tools.map(t => ({
591
+ name: t.name,
592
+ description: t.description,
593
+ inputSchema: t.inputSchema
594
+ }));
595
+
596
+ const toolCases = tools.map(t => `
597
+ case '${t.name}':
598
+ return await ${t.name}(args);`
599
+ ).join('\n');
600
+
601
+ const implementations = tools.map(t => t.implementation || '').join('\n\n');
602
+
603
+ return `/**
604
+ * Auto-generated MCP server for ${repoName}
605
+ * Generated by @nirholas/github-to-mcp
606
+ */
607
+
608
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
609
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
610
+ import {
611
+ CallToolRequestSchema,
612
+ ListToolsRequestSchema
613
+ } from '@modelcontextprotocol/sdk/types.js';
614
+
615
+ const server = new Server({
616
+ name: '${repoName}-mcp',
617
+ version: '1.0.0'
618
+ }, {
619
+ capabilities: {
620
+ tools: {}
621
+ }
622
+ });
623
+
624
+ // Tool definitions
625
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
626
+ tools: ${JSON.stringify(toolDefinitions, null, 2)}
627
+ }));
628
+
629
+ // Tool implementations
630
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
631
+ const { name, arguments: args } = request.params;
632
+
633
+ switch (name) {${toolCases}
634
+ default:
635
+ throw new Error(\`Unknown tool: \${name}\`);
636
+ }
637
+ });
638
+
639
+ // Tool functions
640
+ ${implementations}
641
+
642
+ // Start server
643
+ async function main() {
644
+ const transport = new StdioServerTransport();
645
+ await server.connect(transport);
646
+ console.error('${repoName} MCP server running on stdio');
647
+ }
648
+
649
+ main().catch(console.error);
650
+ `;
651
+ }
652
+
653
+ /**
654
+ * Save generated code to files
655
+ */
656
+ private async saveToFiles(tools: ExtractedTool[], repoName: string, owner: string, outputDir: string): Promise<void> {
657
+ await fs.mkdir(outputDir, { recursive: true });
658
+
659
+ // Generate main server file
660
+ const serverCode = this.generateCode(tools, repoName, owner);
661
+ await fs.writeFile(path.join(outputDir, 'index.ts'), serverCode);
662
+
663
+ // Generate package.json
664
+ const packageJson = {
665
+ name: `${repoName}-mcp`,
666
+ version: '1.0.0',
667
+ type: 'module',
668
+ dependencies: {
669
+ '@modelcontextprotocol/sdk': '^1.0.0'
670
+ }
671
+ };
672
+ await fs.writeFile(
673
+ path.join(outputDir, 'package.json'),
674
+ JSON.stringify(packageJson, null, 2)
675
+ );
676
+
677
+ // Generate README
678
+ const readme = this.generateReadme(tools, repoName);
679
+ await fs.writeFile(path.join(outputDir, 'README.md'), readme);
680
+ }
681
+
682
+ /**
683
+ * Generate README for the MCP server
684
+ */
685
+ private generateReadme(tools: ExtractedTool[], repoName: string): string {
686
+ const toolsList = tools.map(t => `- \`${t.name}\`: ${t.description}`).join('\n');
687
+
688
+ return `# ${repoName} MCP Server
689
+
690
+ Auto-generated MCP server with ${tools.length} tools.
691
+
692
+ ## Tools
693
+
694
+ ${toolsList}
695
+
696
+ ## Installation
697
+
698
+ \`\`\`bash
699
+ npm install
700
+ \`\`\`
701
+
702
+ ## Usage
703
+
704
+ \`\`\`bash
705
+ node index.ts
706
+ \`\`\`
707
+ `;
708
+ }
709
+
710
+ /**
711
+ * Download as ZIP (browser only)
712
+ */
713
+ private downloadZip(tools: ExtractedTool[], repoName: string): void {
714
+ // This would require a ZIP library in browser context
715
+ console.log('Download functionality requires browser environment');
716
+ }
717
+ }
718
+
719
+ /**
720
+ * Convenience function for single repo
721
+ */
722
+ export async function generateFromGithub(
723
+ url: string,
724
+ options?: GithubToMcpOptions
725
+ ): Promise<GenerationResult> {
726
+ const generator = new GithubToMcpGenerator(options);
727
+ return generator.generate(url);
728
+ }
729
+
730
+ /**
731
+ * Batch processing
732
+ */
733
+ export async function generateFromGithubBatch(
734
+ urls: string[],
735
+ options?: GithubToMcpOptions
736
+ ): Promise<GenerationResult[]> {
737
+ const generator = new GithubToMcpGenerator(options);
738
+ return Promise.all(urls.map(url => generator.generate(url)));
739
+ }
740
+
741
+ // Export all types
742
+ export * from './types';
743
+
744
+ // Export streaming module
745
+ export {
746
+ StreamingGenerator,
747
+ streamGenerate,
748
+ collectStreamEvents,
749
+ streamToResult,
750
+ type StreamEvent,
751
+ type StreamOptions,
752
+ type StreamEventType,
753
+ type StartEvent,
754
+ type MetadataEvent,
755
+ type ClassifyingEvent,
756
+ type ClassifiedEvent,
757
+ type ExtractingEvent,
758
+ type ToolFoundEvent,
759
+ type SourceCompleteEvent,
760
+ type GeneratingEvent,
761
+ type CompleteEvent,
762
+ type ErrorEvent,
763
+ type ProgressEvent
764
+ } from './streaming';
765
+
766
+ // Export plugin system
767
+ export {
768
+ PluginManager,
769
+ PluginRegistry,
770
+ defaultPluginManager,
771
+ defaultRegistry,
772
+ registerPlugin,
773
+ unregisterPlugin,
774
+ listPlugins,
775
+ loadPlugin,
776
+ loadPluginFromFile,
777
+ type ExtractorPlugin,
778
+ type PluginRepoContext,
779
+ type PluginExtractionResult,
780
+ type PluginDetectionResult,
781
+ type PluginManagerConfig,
782
+ type PluginLoadResult,
783
+ type PluginEvent,
784
+ type PluginEventHandler,
785
+ type PluginMetadata,
786
+ type PluginConfigSchema,
787
+ type PluginHooks
788
+ } from './plugins';
789
+
790
+ // Export language-specific extractors
791
+ export { RustExtractor } from './extractors/rust-extractor';
792
+ export { GoExtractor } from './extractors/go-extractor';
793
+ export { JavaExtractor } from './extractors/java-extractor';
794
+
795
+ // Export language-specific generators
796
+ export { PythonGenerator } from './python-generator';
797
+ export { GoGenerator } from './go-generator';