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,1206 @@
1
+ /**
2
+ * @fileoverview MCP Server for github-to-mcp
3
+ * Exposes the github-to-mcp conversion functionality as MCP tools
4
+ * @copyright Copyright (c) 2024-2026 nirholas
5
+ * @license MIT
6
+ */
7
+
8
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
9
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
+ import {
11
+ CallToolRequestSchema,
12
+ ListToolsRequestSchema,
13
+ ListResourcesRequestSchema,
14
+ ReadResourceRequestSchema,
15
+ ListPromptsRequestSchema,
16
+ GetPromptRequestSchema,
17
+ Tool,
18
+ TextContent,
19
+ } from '@modelcontextprotocol/sdk/types.js';
20
+ import { GithubToMcpGenerator, ExtractedTool, GenerationResult } from '@nirholas/github-to-mcp';
21
+ import { z } from 'zod';
22
+
23
+ // Import new tools
24
+ import {
25
+ generateOpenApiTool,
26
+ handleGenerateOpenApi,
27
+ } from './tools/generate-openapi.js';
28
+ import {
29
+ exportDockerTool,
30
+ handleExportDocker,
31
+ } from './tools/export-docker.js';
32
+ import {
33
+ streamConvertTool,
34
+ listProvidersTool,
35
+ handleStreamConvert,
36
+ handleListProviders,
37
+ } from './tools/stream-convert.js';
38
+ import {
39
+ testMcpToolTool,
40
+ handleTestMcpTool,
41
+ } from './tools/test-mcp-tool.js';
42
+ import {
43
+ monitorMcpServerTool,
44
+ handleMonitorMcpServer,
45
+ } from './tools/monitor-mcp-server.js';
46
+
47
+ // Import prompts
48
+ import {
49
+ PROMPTS,
50
+ getPromptMessages,
51
+ } from './prompts/index.js';
52
+
53
+ // ============================================================================
54
+ // Tool Definitions
55
+ // ============================================================================
56
+
57
+ const TOOLS: Tool[] = [
58
+ {
59
+ name: 'convert_repo',
60
+ description: `Convert a GitHub repository into an MCP server implementation.
61
+
62
+ This tool analyzes a GitHub repository and generates a complete MCP server that exposes the repository's functionality as AI-usable tools.
63
+
64
+ Supported extraction sources:
65
+ - OpenAPI/Swagger specifications
66
+ - README documentation
67
+ - Source code (Python functions, TypeScript functions)
68
+ - GraphQL schemas
69
+ - Existing MCP server introspection
70
+
71
+ Returns the generated MCP server code with full type annotations and documentation.`,
72
+ inputSchema: {
73
+ type: 'object',
74
+ properties: {
75
+ github_url: {
76
+ type: 'string',
77
+ description: 'The GitHub repository URL (e.g., https://github.com/owner/repo)',
78
+ },
79
+ output_language: {
80
+ type: 'string',
81
+ enum: ['typescript', 'python'],
82
+ default: 'typescript',
83
+ description: 'The output language for the generated MCP server',
84
+ },
85
+ sources: {
86
+ type: 'array',
87
+ items: {
88
+ type: 'string',
89
+ enum: ['readme', 'openapi', 'code', 'graphql'],
90
+ },
91
+ description: 'Which extraction sources to use (default: all)',
92
+ },
93
+ github_token: {
94
+ type: 'string',
95
+ description: 'GitHub personal access token for private repos or higher rate limits (optional)',
96
+ },
97
+ },
98
+ required: ['github_url'],
99
+ },
100
+ },
101
+ {
102
+ name: 'list_extracted_tools',
103
+ description: `Preview the tools that would be extracted from a GitHub repository without generating the full MCP server.
104
+
105
+ Useful for understanding what capabilities will be available before committing to a full conversion.
106
+
107
+ Returns a structured list of all detected tools with their names, descriptions, parameters, and source locations.`,
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ github_url: {
112
+ type: 'string',
113
+ description: 'The GitHub repository URL to analyze',
114
+ },
115
+ sources: {
116
+ type: 'array',
117
+ items: {
118
+ type: 'string',
119
+ enum: ['readme', 'openapi', 'code', 'graphql'],
120
+ },
121
+ description: 'Which extraction sources to scan',
122
+ },
123
+ github_token: {
124
+ type: 'string',
125
+ description: 'GitHub personal access token (optional)',
126
+ },
127
+ },
128
+ required: ['github_url'],
129
+ },
130
+ },
131
+ {
132
+ name: 'validate_mcp_server',
133
+ description: `Validate MCP server code for correctness and best practices.
134
+
135
+ Checks:
136
+ - Tool definitions are well-formed
137
+ - Input schemas are valid JSON Schema
138
+ - Type annotations are consistent
139
+ - Required fields are present
140
+ - Description quality
141
+
142
+ Returns validation results with any warnings or errors found.`,
143
+ inputSchema: {
144
+ type: 'object',
145
+ properties: {
146
+ code: {
147
+ type: 'string',
148
+ description: 'The MCP server code to validate',
149
+ },
150
+ language: {
151
+ type: 'string',
152
+ enum: ['typescript', 'python'],
153
+ description: 'The language of the code',
154
+ },
155
+ },
156
+ required: ['code', 'language'],
157
+ },
158
+ },
159
+ {
160
+ name: 'generate_claude_config',
161
+ description: `Generate a Claude Desktop configuration snippet for an MCP server.
162
+
163
+ Creates the JSON configuration that can be added to Claude Desktop's config file to register the generated MCP server.`,
164
+ inputSchema: {
165
+ type: 'object',
166
+ properties: {
167
+ server_name: {
168
+ type: 'string',
169
+ description: 'Name for the MCP server in the config',
170
+ },
171
+ server_path: {
172
+ type: 'string',
173
+ description: 'Path to the generated MCP server file',
174
+ },
175
+ language: {
176
+ type: 'string',
177
+ enum: ['typescript', 'python'],
178
+ description: 'The language of the MCP server',
179
+ },
180
+ env_vars: {
181
+ type: 'object',
182
+ additionalProperties: { type: 'string' },
183
+ description: 'Environment variables to pass to the server',
184
+ },
185
+ },
186
+ required: ['server_name', 'server_path', 'language'],
187
+ },
188
+ },
189
+ {
190
+ name: 'generate_cursor_config',
191
+ description: `Generate a Cursor IDE configuration for an MCP server.
192
+
193
+ Creates the configuration format used by Cursor to integrate MCP servers.`,
194
+ inputSchema: {
195
+ type: 'object',
196
+ properties: {
197
+ server_name: {
198
+ type: 'string',
199
+ description: 'Name for the MCP server',
200
+ },
201
+ server_path: {
202
+ type: 'string',
203
+ description: 'Path to the generated MCP server file',
204
+ },
205
+ language: {
206
+ type: 'string',
207
+ enum: ['typescript', 'python'],
208
+ description: 'The language of the MCP server',
209
+ },
210
+ },
211
+ required: ['server_name', 'server_path', 'language'],
212
+ },
213
+ },
214
+ {
215
+ name: 'analyze_repo_structure',
216
+ description: `Analyze a GitHub repository's structure to identify what extraction sources are available.
217
+
218
+ Scans for:
219
+ - OpenAPI/Swagger specs
220
+ - GraphQL schemas
221
+ - README files
222
+ - Python and TypeScript source files
223
+ - Existing MCP server implementations
224
+
225
+ Returns a detailed breakdown of the repository structure with recommendations for extraction.`,
226
+ inputSchema: {
227
+ type: 'object',
228
+ properties: {
229
+ github_url: {
230
+ type: 'string',
231
+ description: 'The GitHub repository URL to analyze',
232
+ },
233
+ github_token: {
234
+ type: 'string',
235
+ description: 'GitHub personal access token (optional)',
236
+ },
237
+ },
238
+ required: ['github_url'],
239
+ },
240
+ },
241
+ {
242
+ name: 'convert_openapi_to_mcp',
243
+ description: `Convert an OpenAPI specification directly to MCP tools.
244
+
245
+ Supports OpenAPI 3.x and Swagger 2.0 specifications. Can also handle:
246
+ - Postman collections
247
+ - Insomnia exports
248
+ - HAR files
249
+ - AsyncAPI specs
250
+ - GraphQL schemas
251
+
252
+ Returns MCP tool definitions extracted from the API specification.`,
253
+ inputSchema: {
254
+ type: 'object',
255
+ properties: {
256
+ spec: {
257
+ type: 'string',
258
+ description: 'The OpenAPI specification content (JSON or YAML)',
259
+ },
260
+ format: {
261
+ type: 'string',
262
+ enum: ['openapi', 'swagger', 'postman', 'insomnia', 'har', 'asyncapi', 'graphql'],
263
+ default: 'openapi',
264
+ description: 'The format of the specification',
265
+ },
266
+ base_url: {
267
+ type: 'string',
268
+ description: 'Override the base URL for API calls',
269
+ },
270
+ },
271
+ required: ['spec'],
272
+ },
273
+ },
274
+ {
275
+ name: 'get_tool_template',
276
+ description: `Get a template for creating a new MCP tool definition.
277
+
278
+ Returns a starter template in the requested language with best practices and documentation.`,
279
+ inputSchema: {
280
+ type: 'object',
281
+ properties: {
282
+ tool_name: {
283
+ type: 'string',
284
+ description: 'Name for the tool',
285
+ },
286
+ description: {
287
+ type: 'string',
288
+ description: 'Description of what the tool does',
289
+ },
290
+ parameters: {
291
+ type: 'array',
292
+ items: {
293
+ type: 'object',
294
+ properties: {
295
+ name: { type: 'string' },
296
+ type: { type: 'string' },
297
+ description: { type: 'string' },
298
+ required: { type: 'boolean' },
299
+ },
300
+ },
301
+ description: 'List of parameters for the tool',
302
+ },
303
+ language: {
304
+ type: 'string',
305
+ enum: ['typescript', 'python'],
306
+ default: 'typescript',
307
+ description: 'Target language for the template',
308
+ },
309
+ },
310
+ required: ['tool_name', 'description'],
311
+ },
312
+ },
313
+ // New tools added
314
+ generateOpenApiTool,
315
+ exportDockerTool,
316
+ streamConvertTool,
317
+ listProvidersTool,
318
+ testMcpToolTool,
319
+ monitorMcpServerTool,
320
+ ];
321
+
322
+ // ============================================================================
323
+ // Tool Implementations
324
+ // ============================================================================
325
+
326
+ async function convertRepo(args: {
327
+ github_url: string;
328
+ output_language?: 'typescript' | 'python';
329
+ sources?: string[];
330
+ github_token?: string;
331
+ }): Promise<TextContent> {
332
+ const generator = new GithubToMcpGenerator({
333
+ githubToken: args.github_token,
334
+ sources: args.sources as any,
335
+ outputLanguage: args.output_language || 'typescript',
336
+ });
337
+
338
+ try {
339
+ const result = await generator.generate(args.github_url);
340
+
341
+ let code: string;
342
+ if (args.output_language === 'python') {
343
+ code = result.generatePython();
344
+ } else {
345
+ code = result.generate();
346
+ }
347
+
348
+ const summary = formatResultSummary(result);
349
+
350
+ return {
351
+ type: 'text',
352
+ text: `# MCP Server Generated Successfully
353
+
354
+ ${summary}
355
+
356
+ ## Generated Code
357
+
358
+ \`\`\`${args.output_language || 'typescript'}
359
+ ${code}
360
+ \`\`\`
361
+ `,
362
+ };
363
+ } catch (error) {
364
+ return {
365
+ type: 'text',
366
+ text: `Error generating MCP server: ${error instanceof Error ? error.message : String(error)}`,
367
+ };
368
+ }
369
+ }
370
+
371
+ async function listExtractedTools(args: {
372
+ github_url: string;
373
+ sources?: string[];
374
+ github_token?: string;
375
+ }): Promise<TextContent> {
376
+ const generator = new GithubToMcpGenerator({
377
+ githubToken: args.github_token,
378
+ sources: args.sources as any,
379
+ });
380
+
381
+ try {
382
+ const result = await generator.generate(args.github_url);
383
+
384
+ const toolsList = result.tools.map((tool: ExtractedTool, index: number) => {
385
+ const params = Object.entries(tool.parameters || {})
386
+ .map(([name, schema]) => {
387
+ const s = schema as any;
388
+ return ` - \`${name}\` (${s.type}${tool.required?.includes(name) ? ', required' : ''}): ${s.description || 'No description'}`;
389
+ })
390
+ .join('\n');
391
+
392
+ return `### ${index + 1}. ${tool.name}
393
+
394
+ **Source:** ${tool.source.type} (${tool.source.file})
395
+ **Description:** ${tool.description}
396
+
397
+ **Parameters:**
398
+ ${params || ' None'}
399
+ `;
400
+ }).join('\n---\n\n');
401
+
402
+ return {
403
+ type: 'text',
404
+ text: `# Extracted Tools from ${args.github_url}
405
+
406
+ **Total Tools:** ${result.tools.length}
407
+ **Sources Used:** ${result.sources.map(s => `${s.type} (${s.count} tools)`).join(', ')}
408
+
409
+ ---
410
+
411
+ ${toolsList}`,
412
+ };
413
+ } catch (error) {
414
+ return {
415
+ type: 'text',
416
+ text: `Error analyzing repository: ${error instanceof Error ? error.message : String(error)}`,
417
+ };
418
+ }
419
+ }
420
+
421
+ function validateMcpServer(args: { code: string; language: string }): TextContent {
422
+ const issues: string[] = [];
423
+ const warnings: string[] = [];
424
+ const code = args.code;
425
+
426
+ // Check for tool definitions
427
+ if (args.language === 'typescript') {
428
+ if (!code.includes('ListToolsRequestSchema') && !code.includes('tools:')) {
429
+ issues.push('Missing tool definitions - no ListToolsRequestSchema handler or tools array found');
430
+ }
431
+ if (!code.includes('CallToolRequestSchema')) {
432
+ issues.push('Missing CallToolRequestSchema handler - tools cannot be executed');
433
+ }
434
+ if (!code.includes('@modelcontextprotocol/sdk')) {
435
+ warnings.push('Not using official MCP SDK - consider using @modelcontextprotocol/sdk');
436
+ }
437
+ if (!code.includes('inputSchema')) {
438
+ warnings.push('No inputSchema definitions found - tools may not have proper parameter validation');
439
+ }
440
+ if (!code.includes('description')) {
441
+ warnings.push('Missing tool descriptions - AI assistants need descriptions to understand tool purpose');
442
+ }
443
+ } else if (args.language === 'python') {
444
+ if (!code.includes('@mcp.tool') && !code.includes('list_tools')) {
445
+ issues.push('Missing tool definitions');
446
+ }
447
+ if (!code.includes('description=')) {
448
+ warnings.push('Missing tool descriptions');
449
+ }
450
+ if (!code.includes('def ') && !code.includes('async def ')) {
451
+ issues.push('No function definitions found');
452
+ }
453
+ }
454
+
455
+ // Check for common issues
456
+ if (code.length < 100) {
457
+ issues.push('Code appears too short to be a complete MCP server');
458
+ }
459
+
460
+ const status = issues.length === 0 ? '✅ Valid' : '❌ Invalid';
461
+
462
+ return {
463
+ type: 'text',
464
+ text: `# MCP Server Validation
465
+
466
+ **Status:** ${status}
467
+
468
+ ${issues.length > 0 ? `## Errors
469
+ ${issues.map(i => `- ❌ ${i}`).join('\n')}
470
+ ` : ''}
471
+
472
+ ${warnings.length > 0 ? `## Warnings
473
+ ${warnings.map(w => `- ⚠️ ${w}`).join('\n')}
474
+ ` : ''}
475
+
476
+ ${issues.length === 0 && warnings.length === 0 ? '✅ No issues found!' : ''}`,
477
+ };
478
+ }
479
+
480
+ function generateClaudeConfig(args: {
481
+ server_name: string;
482
+ server_path: string;
483
+ language: string;
484
+ env_vars?: Record<string, string>;
485
+ }): TextContent {
486
+ const command = args.language === 'python' ? 'python' : 'node';
487
+ const config = {
488
+ mcpServers: {
489
+ [args.server_name]: {
490
+ command,
491
+ args: [args.server_path],
492
+ ...(args.env_vars && { env: args.env_vars }),
493
+ },
494
+ },
495
+ };
496
+
497
+ return {
498
+ type: 'text',
499
+ text: `# Claude Desktop Configuration
500
+
501
+ Add the following to your Claude Desktop config file:
502
+
503
+ **macOS:** \`~/Library/Application Support/Claude/claude_desktop_config.json\`
504
+ **Windows:** \`%APPDATA%\\Claude\\claude_desktop_config.json\`
505
+ **Linux:** \`~/.config/Claude/claude_desktop_config.json\`
506
+
507
+ \`\`\`json
508
+ ${JSON.stringify(config, null, 2)}
509
+ \`\`\`
510
+
511
+ ## Full Config Example
512
+
513
+ If you have multiple servers, merge them like this:
514
+
515
+ \`\`\`json
516
+ {
517
+ "mcpServers": {
518
+ "${args.server_name}": ${JSON.stringify(config.mcpServers[args.server_name], null, 4).split('\n').join('\n ')},
519
+ "other-server": {
520
+ "command": "...",
521
+ "args": ["..."]
522
+ }
523
+ }
524
+ }
525
+ \`\`\`
526
+ `,
527
+ };
528
+ }
529
+
530
+ function generateCursorConfig(args: {
531
+ server_name: string;
532
+ server_path: string;
533
+ language: string;
534
+ }): TextContent {
535
+ const command = args.language === 'python' ? 'python' : 'node';
536
+
537
+ return {
538
+ type: 'text',
539
+ text: `# Cursor IDE Configuration
540
+
541
+ Add to your Cursor settings or \`.cursor/mcp.json\`:
542
+
543
+ \`\`\`json
544
+ {
545
+ "mcpServers": {
546
+ "${args.server_name}": {
547
+ "command": "${command}",
548
+ "args": ["${args.server_path}"]
549
+ }
550
+ }
551
+ }
552
+ \`\`\`
553
+
554
+ ## Alternative: Using npx
555
+
556
+ If your MCP server is published to npm:
557
+
558
+ \`\`\`json
559
+ {
560
+ "mcpServers": {
561
+ "${args.server_name}": {
562
+ "command": "npx",
563
+ "args": ["-y", "${args.server_name}"]
564
+ }
565
+ }
566
+ }
567
+ \`\`\`
568
+ `,
569
+ };
570
+ }
571
+
572
+ async function analyzeRepoStructure(args: {
573
+ github_url: string;
574
+ github_token?: string;
575
+ }): Promise<TextContent> {
576
+ const generator = new GithubToMcpGenerator({
577
+ githubToken: args.github_token,
578
+ });
579
+
580
+ try {
581
+ const result = await generator.generate(args.github_url);
582
+
583
+ const analysis = {
584
+ classification: result.classification,
585
+ sources: result.sources,
586
+ metadata: {
587
+ name: result.metadata.name,
588
+ description: result.metadata.description,
589
+ language: result.metadata.language,
590
+ stars: result.metadata.stargazers_count,
591
+ topics: result.metadata.topics,
592
+ },
593
+ };
594
+
595
+ const recommendations: string[] = [];
596
+
597
+ if (result.classification.type === 'api-sdk') {
598
+ recommendations.push('This appears to be an API SDK - OpenAPI extraction will likely work well');
599
+ }
600
+ if (result.classification.type === 'mcp-server') {
601
+ recommendations.push('This is already an MCP server - introspection mode recommended');
602
+ }
603
+ if (result.sources.some(s => s.type === 'openapi')) {
604
+ recommendations.push('OpenAPI specs detected - these provide the most accurate tool definitions');
605
+ }
606
+ if (result.sources.some(s => s.type === 'code')) {
607
+ recommendations.push('Source code parsed - consider reviewing auto-generated descriptions');
608
+ }
609
+
610
+ return {
611
+ type: 'text',
612
+ text: `# Repository Analysis: ${args.github_url}
613
+
614
+ ## Classification
615
+ - **Type:** ${result.classification.type}
616
+ - **Confidence:** ${(result.classification.confidence * 100).toFixed(0)}%
617
+ - **Indicators:** ${result.classification.indicators.join(', ')}
618
+
619
+ ## Repository Info
620
+ - **Language:** ${analysis.metadata.language || 'Unknown'}
621
+ - **Stars:** ${analysis.metadata.stars || 0}
622
+ - **Topics:** ${analysis.metadata.topics?.join(', ') || 'None'}
623
+
624
+ ## Detected Sources
625
+ ${result.sources.map(s => `- **${s.type}:** ${s.count} tools from ${s.files.length} files`).join('\n')}
626
+
627
+ ## Files by Source
628
+ ${result.sources.map(s => `### ${s.type}
629
+ ${s.files.map(f => `- ${f}`).join('\n') || 'N/A'}`).join('\n\n')}
630
+
631
+ ## Recommendations
632
+ ${recommendations.map(r => `- ${r}`).join('\n')}
633
+
634
+ ## Total Tools Available: ${result.tools.length}
635
+ `,
636
+ };
637
+ } catch (error) {
638
+ return {
639
+ type: 'text',
640
+ text: `Error analyzing repository: ${error instanceof Error ? error.message : String(error)}`,
641
+ };
642
+ }
643
+ }
644
+
645
+ async function convertOpenApiToMcpTool(args: {
646
+ spec: string;
647
+ format?: string;
648
+ base_url?: string;
649
+ }): Promise<TextContent> {
650
+ try {
651
+ const { convertOpenApiToMcp } = await import('@github-to-mcp/openapi-parser');
652
+
653
+ const result = await convertOpenApiToMcp(args.spec, {
654
+ format: args.format as any,
655
+ baseUrl: args.base_url,
656
+ });
657
+
658
+ return {
659
+ type: 'text',
660
+ text: `# OpenAPI to MCP Conversion
661
+
662
+ **Tools Extracted:** ${result.tools.length}
663
+ **API Title:** ${result.info?.title || 'Unknown'}
664
+ **Version:** ${result.info?.version || 'Unknown'}
665
+
666
+ ## Tools
667
+
668
+ ${result.tools.map((tool: any, i: number) => `### ${i + 1}. ${tool.name}
669
+ ${tool.description}
670
+
671
+ **Parameters:**
672
+ ${Object.entries(tool.inputSchema?.properties || {}).map(([name, schema]: [string, any]) =>
673
+ `- \`${name}\` (${schema.type}): ${schema.description || 'No description'}`
674
+ ).join('\n') || 'None'}
675
+ `).join('\n---\n')}`,
676
+ };
677
+ } catch (error) {
678
+ return {
679
+ type: 'text',
680
+ text: `Error converting specification: ${error instanceof Error ? error.message : String(error)}`,
681
+ };
682
+ }
683
+ }
684
+
685
+ function getToolTemplate(args: {
686
+ tool_name: string;
687
+ description: string;
688
+ parameters?: Array<{ name: string; type: string; description?: string; required?: boolean }>;
689
+ language?: string;
690
+ }): TextContent {
691
+ const params = args.parameters || [];
692
+
693
+ if (args.language === 'python') {
694
+ const pythonParams = params.map(p => {
695
+ const pythonType = {
696
+ string: 'str',
697
+ number: 'float',
698
+ integer: 'int',
699
+ boolean: 'bool',
700
+ array: 'list',
701
+ object: 'dict',
702
+ }[p.type] || 'Any';
703
+ return ` ${p.name}: ${pythonType}${p.required ? '' : ' = None'}`;
704
+ }).join('\n');
705
+
706
+ const docParams = params.map(p =>
707
+ ` ${p.name}: ${p.description || 'No description'}`
708
+ ).join('\n');
709
+
710
+ return {
711
+ type: 'text',
712
+ text: `# Python MCP Tool Template
713
+
714
+ \`\`\`python
715
+ from mcp.server import Server
716
+ from mcp.types import Tool, TextContent
717
+ import mcp.server.stdio
718
+
719
+ server = Server("${args.tool_name}-server")
720
+
721
+ @server.list_tools()
722
+ async def list_tools() -> list[Tool]:
723
+ return [
724
+ Tool(
725
+ name="${args.tool_name}",
726
+ description="""${args.description}""",
727
+ inputSchema={
728
+ "type": "object",
729
+ "properties": {
730
+ ${params.map(p => ` "${p.name}": {
731
+ "type": "${p.type}",
732
+ "description": "${p.description || ''}"
733
+ }`).join(',\n')}
734
+ },
735
+ "required": [${params.filter(p => p.required).map(p => `"${p.name}"`).join(', ')}]
736
+ }
737
+ )
738
+ ]
739
+
740
+ @server.call_tool()
741
+ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
742
+ if name == "${args.tool_name}":
743
+ return await ${args.tool_name.replace(/-/g, '_')}(**arguments)
744
+ raise ValueError(f"Unknown tool: {name}")
745
+
746
+ async def ${args.tool_name.replace(/-/g, '_')}(
747
+ ${pythonParams || ' # No parameters'}
748
+ ) -> list[TextContent]:
749
+ """
750
+ ${args.description}
751
+
752
+ Args:
753
+ ${docParams || ' None'}
754
+
755
+ Returns:
756
+ Tool execution result
757
+ """
758
+ # TODO: Implement tool logic
759
+ result = f"Executed ${args.tool_name}"
760
+
761
+ return [TextContent(type="text", text=result)]
762
+
763
+ async def main():
764
+ async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
765
+ await server.run(read_stream, write_stream)
766
+
767
+ if __name__ == "__main__":
768
+ import asyncio
769
+ asyncio.run(main())
770
+ \`\`\`
771
+ `,
772
+ };
773
+ }
774
+
775
+ // TypeScript template (default)
776
+ const tsParams = params.map(p =>
777
+ `${p.name}${p.required ? '' : '?'}: ${p.type === 'integer' ? 'number' : p.type}`
778
+ ).join('; ');
779
+
780
+ return {
781
+ type: 'text',
782
+ text: `# TypeScript MCP Tool Template
783
+
784
+ \`\`\`typescript
785
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
786
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
787
+ import {
788
+ CallToolRequestSchema,
789
+ ListToolsRequestSchema,
790
+ } from '@modelcontextprotocol/sdk/types.js';
791
+
792
+ const server = new Server(
793
+ { name: '${args.tool_name}-server', version: '1.0.0' },
794
+ { capabilities: { tools: {} } }
795
+ );
796
+
797
+ // Tool definitions
798
+ const TOOLS = [
799
+ {
800
+ name: '${args.tool_name}',
801
+ description: \`${args.description}\`,
802
+ inputSchema: {
803
+ type: 'object',
804
+ properties: {
805
+ ${params.map(p => ` ${p.name}: {
806
+ type: '${p.type}',
807
+ description: '${p.description || ''}',
808
+ }`).join(',\n')}
809
+ },
810
+ required: [${params.filter(p => p.required).map(p => `'${p.name}'`).join(', ')}],
811
+ },
812
+ },
813
+ ];
814
+
815
+ // List tools handler
816
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
817
+ tools: TOOLS,
818
+ }));
819
+
820
+ // Call tool handler
821
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
822
+ const { name, arguments: args } = request.params;
823
+
824
+ if (name === '${args.tool_name}') {
825
+ const { ${params.map(p => p.name).join(', ')} } = args as { ${tsParams || 'never?: never' } };
826
+
827
+ // TODO: Implement tool logic
828
+ const result = \`Executed ${args.tool_name}\`;
829
+
830
+ return {
831
+ content: [{ type: 'text', text: result }],
832
+ };
833
+ }
834
+
835
+ throw new Error(\`Unknown tool: \${name}\`);
836
+ });
837
+
838
+ // Start server
839
+ async function main() {
840
+ const transport = new StdioServerTransport();
841
+ await server.connect(transport);
842
+ console.error('MCP Server running on stdio');
843
+ }
844
+
845
+ main().catch(console.error);
846
+ \`\`\`
847
+ `,
848
+ };
849
+ }
850
+
851
+ // ============================================================================
852
+ // Helper Functions
853
+ // ============================================================================
854
+
855
+ function formatResultSummary(result: GenerationResult): string {
856
+ return `## Conversion Summary
857
+
858
+ - **Repository:** ${result.repo}
859
+ - **Classification:** ${result.classification.type} (${(result.classification.confidence * 100).toFixed(0)}% confidence)
860
+ - **Total Tools:** ${result.tools.length}
861
+
862
+ ### Sources Breakdown
863
+ ${result.sources.map(s => `- **${s.type}:** ${s.count} tools`).join('\n')}
864
+
865
+ ### Extracted Tools
866
+ ${result.tools.slice(0, 10).map((t: ExtractedTool, i: number) => `${i + 1}. \`${t.name}\` - ${t.description?.slice(0, 60)}${(t.description?.length || 0) > 60 ? '...' : ''}`).join('\n')}
867
+ ${result.tools.length > 10 ? `\n... and ${result.tools.length - 10} more tools` : ''}`;
868
+ }
869
+
870
+ // ============================================================================
871
+ // Server Setup
872
+ // ============================================================================
873
+
874
+ const server = new Server(
875
+ {
876
+ name: 'github-to-mcp',
877
+ version: '1.0.0',
878
+ },
879
+ {
880
+ capabilities: {
881
+ tools: {},
882
+ resources: {},
883
+ prompts: {},
884
+ },
885
+ }
886
+ );
887
+
888
+ // List available tools
889
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
890
+ return { tools: TOOLS };
891
+ });
892
+
893
+ // Handle tool calls
894
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
895
+ const { name, arguments: args } = request.params;
896
+
897
+ try {
898
+ let result: TextContent;
899
+
900
+ switch (name) {
901
+ case 'convert_repo':
902
+ result = await convertRepo(args as any);
903
+ break;
904
+ case 'list_extracted_tools':
905
+ result = await listExtractedTools(args as any);
906
+ break;
907
+ case 'validate_mcp_server':
908
+ result = validateMcpServer(args as any);
909
+ break;
910
+ case 'generate_claude_config':
911
+ result = generateClaudeConfig(args as any);
912
+ break;
913
+ case 'generate_cursor_config':
914
+ result = generateCursorConfig(args as any);
915
+ break;
916
+ case 'analyze_repo_structure':
917
+ result = await analyzeRepoStructure(args as any);
918
+ break;
919
+ case 'convert_openapi_to_mcp':
920
+ result = await convertOpenApiToMcpTool(args as any);
921
+ break;
922
+ case 'get_tool_template':
923
+ result = getToolTemplate(args as any);
924
+ break;
925
+ // New tool handlers
926
+ case 'generate_openapi_spec':
927
+ result = await handleGenerateOpenApi(args as any);
928
+ break;
929
+ case 'export_docker':
930
+ result = await handleExportDocker(args as any);
931
+ break;
932
+ case 'stream_convert':
933
+ result = await handleStreamConvert(args as any);
934
+ break;
935
+ case 'list_providers':
936
+ result = await handleListProviders(args as any);
937
+ break;
938
+ case 'test_mcp_tool':
939
+ result = await handleTestMcpTool(args as any);
940
+ break;
941
+ case 'monitor_mcp_server':
942
+ result = await handleMonitorMcpServer(args as any);
943
+ break;
944
+ default:
945
+ throw new Error(`Unknown tool: ${name}`);
946
+ }
947
+
948
+ return {
949
+ content: [result],
950
+ };
951
+ } catch (error) {
952
+ return {
953
+ content: [
954
+ {
955
+ type: 'text',
956
+ text: `Error executing tool ${name}: ${error instanceof Error ? error.message : String(error)}`,
957
+ },
958
+ ],
959
+ isError: true,
960
+ };
961
+ }
962
+ });
963
+
964
+ // List resources (documentation, examples)
965
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
966
+ return {
967
+ resources: [
968
+ {
969
+ uri: 'github-to-mcp://docs/quick-start',
970
+ name: 'Quick Start Guide',
971
+ description: 'Get started with github-to-mcp in 5 minutes',
972
+ mimeType: 'text/markdown',
973
+ },
974
+ {
975
+ uri: 'github-to-mcp://docs/extraction-sources',
976
+ name: 'Extraction Sources',
977
+ description: 'Learn about different extraction sources and their capabilities',
978
+ mimeType: 'text/markdown',
979
+ },
980
+ {
981
+ uri: 'github-to-mcp://examples/typescript',
982
+ name: 'TypeScript MCP Server Example',
983
+ description: 'Complete TypeScript MCP server example',
984
+ mimeType: 'text/markdown',
985
+ },
986
+ {
987
+ uri: 'github-to-mcp://examples/python',
988
+ name: 'Python MCP Server Example',
989
+ description: 'Complete Python MCP server example',
990
+ mimeType: 'text/markdown',
991
+ },
992
+ ],
993
+ };
994
+ });
995
+
996
+ // Read resources
997
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
998
+ const { uri } = request.params;
999
+
1000
+ const resources: Record<string, string> = {
1001
+ 'github-to-mcp://docs/quick-start': `# Quick Start Guide
1002
+
1003
+ ## Installation
1004
+
1005
+ \`\`\`bash
1006
+ npm install -g @nirholas/github-to-mcp
1007
+ \`\`\`
1008
+
1009
+ ## Basic Usage
1010
+
1011
+ \`\`\`bash
1012
+ # Convert a GitHub repository to an MCP server
1013
+ github-to-mcp https://github.com/owner/repo
1014
+
1015
+ # Save to a file
1016
+ github-to-mcp https://github.com/owner/repo --output ./mcp-server.ts
1017
+
1018
+ # Generate Python output
1019
+ github-to-mcp https://github.com/owner/repo --language python
1020
+ \`\`\`
1021
+
1022
+ ## Using with Claude Desktop
1023
+
1024
+ 1. Generate your MCP server
1025
+ 2. Add to Claude Desktop config:
1026
+
1027
+ \`\`\`json
1028
+ {
1029
+ "mcpServers": {
1030
+ "my-server": {
1031
+ "command": "node",
1032
+ "args": ["./mcp-server.js"]
1033
+ }
1034
+ }
1035
+ }
1036
+ \`\`\`
1037
+
1038
+ 3. Restart Claude Desktop
1039
+ `,
1040
+
1041
+ 'github-to-mcp://docs/extraction-sources': `# Extraction Sources
1042
+
1043
+ github-to-mcp can extract tools from multiple sources:
1044
+
1045
+ ## 1. OpenAPI Specifications
1046
+ - Swagger 2.0 and OpenAPI 3.x
1047
+ - Automatic endpoint to tool conversion
1048
+ - Full parameter validation
1049
+
1050
+ ## 2. README Documentation
1051
+ - Parses code examples
1052
+ - Extracts API descriptions
1053
+ - Identifies endpoints and methods
1054
+
1055
+ ## 3. Source Code
1056
+ - Python function analysis
1057
+ - TypeScript function analysis
1058
+ - Docstring extraction
1059
+ - Type annotation parsing
1060
+
1061
+ ## 4. GraphQL Schemas
1062
+ - Query and mutation extraction
1063
+ - Type-safe parameter generation
1064
+
1065
+ ## 5. MCP Server Introspection
1066
+ - Analyzes existing MCP servers
1067
+ - Extracts tool definitions
1068
+ `,
1069
+
1070
+ 'github-to-mcp://examples/typescript': `# TypeScript MCP Server Example
1071
+
1072
+ \`\`\`typescript
1073
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
1074
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
1075
+
1076
+ const server = new Server(
1077
+ { name: 'example-server', version: '1.0.0' },
1078
+ { capabilities: { tools: {} } }
1079
+ );
1080
+
1081
+ // Define tools
1082
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
1083
+ tools: [
1084
+ {
1085
+ name: 'hello',
1086
+ description: 'Say hello',
1087
+ inputSchema: {
1088
+ type: 'object',
1089
+ properties: {
1090
+ name: { type: 'string', description: 'Name to greet' }
1091
+ },
1092
+ required: ['name']
1093
+ }
1094
+ }
1095
+ ]
1096
+ }));
1097
+
1098
+ // Handle calls
1099
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1100
+ if (request.params.name === 'hello') {
1101
+ return {
1102
+ content: [{
1103
+ type: 'text',
1104
+ text: \`Hello, \${request.params.arguments.name}!\`
1105
+ }]
1106
+ };
1107
+ }
1108
+ });
1109
+
1110
+ // Start
1111
+ const transport = new StdioServerTransport();
1112
+ await server.connect(transport);
1113
+ \`\`\`
1114
+ `,
1115
+
1116
+ 'github-to-mcp://examples/python': `# Python MCP Server Example
1117
+
1118
+ \`\`\`python
1119
+ from mcp.server import Server
1120
+ from mcp.types import Tool, TextContent
1121
+ import mcp.server.stdio
1122
+
1123
+ server = Server("example-server")
1124
+
1125
+ @server.list_tools()
1126
+ async def list_tools():
1127
+ return [
1128
+ Tool(
1129
+ name="hello",
1130
+ description="Say hello",
1131
+ inputSchema={
1132
+ "type": "object",
1133
+ "properties": {
1134
+ "name": {"type": "string", "description": "Name to greet"}
1135
+ },
1136
+ "required": ["name"]
1137
+ }
1138
+ )
1139
+ ]
1140
+
1141
+ @server.call_tool()
1142
+ async def call_tool(name: str, arguments: dict):
1143
+ if name == "hello":
1144
+ return [TextContent(type="text", text=f"Hello, {arguments['name']}!")]
1145
+
1146
+ async def main():
1147
+ async with mcp.server.stdio.stdio_server() as (read, write):
1148
+ await server.run(read, write)
1149
+
1150
+ if __name__ == "__main__":
1151
+ import asyncio
1152
+ asyncio.run(main())
1153
+ \`\`\`
1154
+ `,
1155
+ };
1156
+
1157
+ const content = resources[uri];
1158
+ if (!content) {
1159
+ throw new Error(`Resource not found: ${uri}`);
1160
+ }
1161
+
1162
+ return {
1163
+ contents: [
1164
+ {
1165
+ uri,
1166
+ mimeType: 'text/markdown',
1167
+ text: content,
1168
+ },
1169
+ ],
1170
+ };
1171
+ });
1172
+
1173
+ // List available prompts
1174
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
1175
+ return { prompts: PROMPTS };
1176
+ });
1177
+
1178
+ // Get prompt messages
1179
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
1180
+ const { name, arguments: args } = request.params;
1181
+
1182
+ try {
1183
+ const messages = getPromptMessages(name, args || {});
1184
+ return {
1185
+ description: PROMPTS.find(p => p.name === name)?.description || '',
1186
+ messages,
1187
+ };
1188
+ } catch (error) {
1189
+ throw new Error(`Error getting prompt: ${error instanceof Error ? error.message : String(error)}`);
1190
+ }
1191
+ });
1192
+
1193
+ // ============================================================================
1194
+ // Main Entry Point
1195
+ // ============================================================================
1196
+
1197
+ async function main() {
1198
+ const transport = new StdioServerTransport();
1199
+ await server.connect(transport);
1200
+ console.error('github-to-mcp MCP Server running on stdio');
1201
+ }
1202
+
1203
+ main().catch((error) => {
1204
+ console.error('Fatal error:', error);
1205
+ process.exit(1);
1206
+ });