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,593 @@
1
+ /**
2
+ * MCP Sandbox Runtime - Spawn and manage MCP server processes
3
+ * @copyright 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ import { spawn, ChildProcess } from 'child_process';
8
+ import { randomUUID } from 'crypto';
9
+ import * as fs from 'fs/promises';
10
+ import * as path from 'path';
11
+ import * as os from 'os';
12
+
13
+ // ============================================================================
14
+ // Types
15
+ // ============================================================================
16
+
17
+ export interface McpSession {
18
+ id: string;
19
+ process: ChildProcess;
20
+ tempFile: string;
21
+ createdAt: Date;
22
+ lastUsed: Date;
23
+ cleanupTimer: NodeJS.Timeout;
24
+ requestId: number;
25
+ pendingRequests: Map<number, {
26
+ resolve: (value: unknown) => void;
27
+ reject: (error: Error) => void;
28
+ timeout: NodeJS.Timeout;
29
+ }>;
30
+ buffer: string;
31
+ initialized: boolean;
32
+ }
33
+
34
+ export interface ExecuteToolRequest {
35
+ generatedCode: string;
36
+ toolName: string;
37
+ toolParams: Record<string, unknown>;
38
+ sessionId?: string;
39
+ }
40
+
41
+ export interface ExecuteToolResponse {
42
+ success: boolean;
43
+ result?: unknown;
44
+ error?: string;
45
+ errorDetails?: {
46
+ code?: number;
47
+ stack?: string;
48
+ data?: unknown;
49
+ };
50
+ sessionId: string;
51
+ executionTime: number;
52
+ logs?: string[];
53
+ }
54
+
55
+ export interface McpTool {
56
+ name: string;
57
+ description?: string;
58
+ inputSchema?: {
59
+ type: string;
60
+ properties?: Record<string, unknown>;
61
+ required?: string[];
62
+ };
63
+ }
64
+
65
+ export interface ListToolsResponse {
66
+ success: boolean;
67
+ tools?: McpTool[];
68
+ error?: string;
69
+ sessionId: string;
70
+ }
71
+
72
+ // MCP JSON-RPC Types
73
+ interface JsonRpcRequest {
74
+ jsonrpc: '2.0';
75
+ id: number;
76
+ method: string;
77
+ params?: Record<string, unknown>;
78
+ }
79
+
80
+ interface JsonRpcResponse {
81
+ jsonrpc: '2.0';
82
+ id: number;
83
+ result?: unknown;
84
+ error?: {
85
+ code: number;
86
+ message: string;
87
+ data?: unknown;
88
+ };
89
+ }
90
+
91
+ // ============================================================================
92
+ // Configuration
93
+ // ============================================================================
94
+
95
+ const SESSION_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
96
+ const REQUEST_TIMEOUT_MS = 30 * 1000; // 30 seconds
97
+ const INIT_TIMEOUT_MS = 10 * 1000; // 10 seconds for initialization
98
+ const MAX_SESSIONS = 100;
99
+
100
+ // ============================================================================
101
+ // Session Store
102
+ // ============================================================================
103
+
104
+ const sessions = new Map<string, McpSession>();
105
+
106
+ /**
107
+ * Clean up expired sessions
108
+ */
109
+ function cleanupSession(sessionId: string): void {
110
+ const session = sessions.get(sessionId);
111
+ if (session) {
112
+ clearTimeout(session.cleanupTimer);
113
+
114
+ // Reject all pending requests
115
+ Array.from(session.pendingRequests.values()).forEach(pending => {
116
+ clearTimeout(pending.timeout);
117
+ pending.reject(new Error('Session closed'));
118
+ });
119
+
120
+ // Kill the process
121
+ if (!session.process.killed) {
122
+ session.process.kill('SIGTERM');
123
+ setTimeout(() => {
124
+ if (!session.process.killed) {
125
+ session.process.kill('SIGKILL');
126
+ }
127
+ }, 1000);
128
+ }
129
+
130
+ // Remove temp file
131
+ fs.unlink(session.tempFile).catch(() => {
132
+ // Ignore errors - file may already be deleted
133
+ });
134
+
135
+ sessions.delete(sessionId);
136
+ console.log(`[MCP Sandbox] Session ${sessionId} cleaned up`);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Reset session timeout
142
+ */
143
+ function resetSessionTimeout(session: McpSession): void {
144
+ clearTimeout(session.cleanupTimer);
145
+ session.lastUsed = new Date();
146
+ session.cleanupTimer = setTimeout(() => {
147
+ cleanupSession(session.id);
148
+ }, SESSION_TIMEOUT_MS);
149
+ }
150
+
151
+ // ============================================================================
152
+ // MCP Sandbox Class
153
+ // ============================================================================
154
+
155
+ export class McpSandbox {
156
+ private logs: string[] = [];
157
+
158
+ /**
159
+ * Get or create a session for the given code
160
+ */
161
+ async getOrCreateSession(generatedCode: string, sessionId?: string): Promise<McpSession> {
162
+ // If sessionId provided, try to get existing session
163
+ if (sessionId && sessions.has(sessionId)) {
164
+ const session = sessions.get(sessionId)!;
165
+ resetSessionTimeout(session);
166
+ return session;
167
+ }
168
+
169
+ // Check max sessions limit
170
+ if (sessions.size >= MAX_SESSIONS) {
171
+ // Clean up oldest session
172
+ const allSessions = Array.from(sessions.values());
173
+ let oldestSession: McpSession | null = null;
174
+ for (let i = 0; i < allSessions.length; i++) {
175
+ const session = allSessions[i];
176
+ if (!oldestSession || session.lastUsed < oldestSession.lastUsed) {
177
+ oldestSession = session;
178
+ }
179
+ }
180
+ if (oldestSession) {
181
+ cleanupSession(oldestSession.id);
182
+ }
183
+ }
184
+
185
+ // Create new session
186
+ return this.createSession(generatedCode);
187
+ }
188
+
189
+ /**
190
+ * Create a new MCP server session
191
+ */
192
+ private async createSession(generatedCode: string): Promise<McpSession> {
193
+ const sessionId = randomUUID();
194
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mcp-sandbox-'));
195
+ const tempFile = path.join(tempDir, 'server.ts');
196
+
197
+ // Write the generated code to temp file
198
+ await fs.writeFile(tempFile, generatedCode, 'utf-8');
199
+ this.logs.push(`[${new Date().toISOString()}] Created temp file: ${tempFile}`);
200
+
201
+ // Spawn the MCP server process using tsx
202
+ const process = spawn('npx', ['tsx', tempFile], {
203
+ stdio: ['pipe', 'pipe', 'pipe'],
204
+ env: {
205
+ ...globalThis.process.env,
206
+ NODE_ENV: 'production',
207
+ // Limit resources
208
+ NODE_OPTIONS: '--max-old-space-size=256',
209
+ },
210
+ cwd: tempDir,
211
+ });
212
+
213
+ const session: McpSession = {
214
+ id: sessionId,
215
+ process,
216
+ tempFile,
217
+ createdAt: new Date(),
218
+ lastUsed: new Date(),
219
+ cleanupTimer: setTimeout(() => cleanupSession(sessionId), SESSION_TIMEOUT_MS),
220
+ requestId: 0,
221
+ pendingRequests: new Map(),
222
+ buffer: '',
223
+ initialized: false,
224
+ };
225
+
226
+ // Handle stdout - parse JSON-RPC responses
227
+ process.stdout?.on('data', (data: Buffer) => {
228
+ const chunk = data.toString();
229
+ session.buffer += chunk;
230
+ this.logs.push(`[${new Date().toISOString()}] stdout: ${chunk}`);
231
+
232
+ // Try to parse complete JSON-RPC messages
233
+ this.processBuffer(session);
234
+ });
235
+
236
+ // Handle stderr
237
+ process.stderr?.on('data', (data: Buffer) => {
238
+ const message = data.toString();
239
+ this.logs.push(`[${new Date().toISOString()}] stderr: ${message}`);
240
+ });
241
+
242
+ // Handle process exit
243
+ process.on('exit', (code, signal) => {
244
+ this.logs.push(`[${new Date().toISOString()}] Process exited with code ${code}, signal ${signal}`);
245
+
246
+ // Reject all pending requests
247
+ Array.from(session.pendingRequests.values()).forEach(pending => {
248
+ clearTimeout(pending.timeout);
249
+ pending.reject(new Error(`Process exited with code ${code}`));
250
+ });
251
+ session.pendingRequests.clear();
252
+ });
253
+
254
+ process.on('error', (error) => {
255
+ this.logs.push(`[${new Date().toISOString()}] Process error: ${error.message}`);
256
+ });
257
+
258
+ sessions.set(sessionId, session);
259
+
260
+ // Initialize the MCP connection
261
+ await this.initializeSession(session);
262
+
263
+ return session;
264
+ }
265
+
266
+ /**
267
+ * Process the buffer for complete JSON-RPC messages
268
+ */
269
+ private processBuffer(session: McpSession): void {
270
+ // MCP uses newline-delimited JSON
271
+ const lines = session.buffer.split('\n');
272
+
273
+ // Keep the last incomplete line in the buffer
274
+ session.buffer = lines.pop() || '';
275
+
276
+ for (const line of lines) {
277
+ const trimmed = line.trim();
278
+ if (!trimmed) continue;
279
+
280
+ try {
281
+ const response = JSON.parse(trimmed) as JsonRpcResponse;
282
+
283
+ if (response.id !== undefined) {
284
+ const pending = session.pendingRequests.get(response.id);
285
+ if (pending) {
286
+ clearTimeout(pending.timeout);
287
+ session.pendingRequests.delete(response.id);
288
+
289
+ if (response.error) {
290
+ pending.reject(new McpRpcError(
291
+ response.error.message,
292
+ response.error.code,
293
+ response.error.data
294
+ ));
295
+ } else {
296
+ pending.resolve(response.result);
297
+ }
298
+ }
299
+ }
300
+ } catch {
301
+ // Not valid JSON, might be regular log output
302
+ this.logs.push(`[${new Date().toISOString()}] Non-JSON output: ${trimmed}`);
303
+ }
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Initialize MCP session with initialize/initialized handshake
309
+ */
310
+ private async initializeSession(session: McpSession): Promise<void> {
311
+ // Send initialize request
312
+ const initResult = await this.sendRequest<{ capabilities: unknown }>(session, 'initialize', {
313
+ protocolVersion: '2024-11-05',
314
+ capabilities: {
315
+ roots: { listChanged: false },
316
+ sampling: {},
317
+ },
318
+ clientInfo: {
319
+ name: 'github-to-mcp-playground',
320
+ version: '1.0.0',
321
+ },
322
+ }, INIT_TIMEOUT_MS);
323
+
324
+ this.logs.push(`[${new Date().toISOString()}] Initialize response: ${JSON.stringify(initResult)}`);
325
+
326
+ // Send initialized notification
327
+ this.sendNotification(session, 'notifications/initialized', {});
328
+
329
+ session.initialized = true;
330
+ this.logs.push(`[${new Date().toISOString()}] Session initialized successfully`);
331
+ }
332
+
333
+ /**
334
+ * Send a JSON-RPC request and wait for response
335
+ */
336
+ private sendRequest<T>(
337
+ session: McpSession,
338
+ method: string,
339
+ params?: Record<string, unknown>,
340
+ timeout: number = REQUEST_TIMEOUT_MS
341
+ ): Promise<T> {
342
+ return new Promise((resolve, reject) => {
343
+ const id = ++session.requestId;
344
+
345
+ const request: JsonRpcRequest = {
346
+ jsonrpc: '2.0',
347
+ id,
348
+ method,
349
+ params,
350
+ };
351
+
352
+ const timeoutHandle = setTimeout(() => {
353
+ session.pendingRequests.delete(id);
354
+ reject(new Error(`Request timed out after ${timeout}ms`));
355
+ }, timeout);
356
+
357
+ session.pendingRequests.set(id, {
358
+ resolve: resolve as (value: unknown) => void,
359
+ reject,
360
+ timeout: timeoutHandle,
361
+ });
362
+
363
+ const message = JSON.stringify(request) + '\n';
364
+ this.logs.push(`[${new Date().toISOString()}] Sending: ${message.trim()}`);
365
+
366
+ session.process.stdin?.write(message, (error) => {
367
+ if (error) {
368
+ session.pendingRequests.delete(id);
369
+ clearTimeout(timeoutHandle);
370
+ reject(new Error(`Failed to send request: ${error.message}`));
371
+ }
372
+ });
373
+ });
374
+ }
375
+
376
+ /**
377
+ * Send a JSON-RPC notification (no response expected)
378
+ */
379
+ private sendNotification(
380
+ session: McpSession,
381
+ method: string,
382
+ params?: Record<string, unknown>
383
+ ): void {
384
+ const notification = {
385
+ jsonrpc: '2.0',
386
+ method,
387
+ params,
388
+ };
389
+
390
+ const message = JSON.stringify(notification) + '\n';
391
+ this.logs.push(`[${new Date().toISOString()}] Sending notification: ${message.trim()}`);
392
+ session.process.stdin?.write(message);
393
+ }
394
+
395
+ /**
396
+ * Connect to MCP server and return session with tools
397
+ * This creates a persistent session that can be reused for tool execution
398
+ */
399
+ async connect(generatedCode: string): Promise<{
400
+ success: boolean;
401
+ sessionId: string;
402
+ tools?: McpTool[];
403
+ error?: string;
404
+ }> {
405
+ try {
406
+ const session = await this.getOrCreateSession(generatedCode);
407
+ resetSessionTimeout(session);
408
+
409
+ // List available tools
410
+ const result = await this.sendRequest<{ tools: McpTool[] }>(
411
+ session,
412
+ 'tools/list',
413
+ {}
414
+ );
415
+
416
+ return {
417
+ success: true,
418
+ sessionId: session.id,
419
+ tools: result.tools || [],
420
+ };
421
+ } catch (error) {
422
+ const message = error instanceof Error ? error.message : 'Failed to connect';
423
+ return {
424
+ success: false,
425
+ sessionId: '',
426
+ error: message,
427
+ };
428
+ }
429
+ }
430
+
431
+ /**
432
+ * List tools available in the MCP server
433
+ */
434
+ async listTools(generatedCode: string, sessionId?: string): Promise<ListToolsResponse> {
435
+ const startTime = Date.now();
436
+
437
+ try {
438
+ const session = await this.getOrCreateSession(generatedCode, sessionId);
439
+ resetSessionTimeout(session);
440
+
441
+ const result = await this.sendRequest<{ tools: McpTool[] }>(
442
+ session,
443
+ 'tools/list',
444
+ {}
445
+ );
446
+
447
+ return {
448
+ success: true,
449
+ tools: result.tools || [],
450
+ sessionId: session.id,
451
+ };
452
+ } catch (error) {
453
+ const message = error instanceof Error ? error.message : 'Unknown error';
454
+ return {
455
+ success: false,
456
+ error: message,
457
+ sessionId: sessionId || '',
458
+ };
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Execute a tool in the MCP server
464
+ */
465
+ async executeTool(request: ExecuteToolRequest): Promise<ExecuteToolResponse> {
466
+ const startTime = Date.now();
467
+ this.logs = []; // Reset logs for this execution
468
+
469
+ try {
470
+ const session = await this.getOrCreateSession(request.generatedCode, request.sessionId);
471
+ resetSessionTimeout(session);
472
+
473
+ const result = await this.sendRequest<{ content: unknown[] }>(
474
+ session,
475
+ 'tools/call',
476
+ {
477
+ name: request.toolName,
478
+ arguments: request.toolParams,
479
+ }
480
+ );
481
+
482
+ return {
483
+ success: true,
484
+ result: result.content,
485
+ sessionId: session.id,
486
+ executionTime: Date.now() - startTime,
487
+ logs: this.logs,
488
+ };
489
+ } catch (error) {
490
+ const executionTime = Date.now() - startTime;
491
+
492
+ if (error instanceof McpRpcError) {
493
+ return {
494
+ success: false,
495
+ error: error.message,
496
+ errorDetails: {
497
+ code: error.code,
498
+ data: error.data,
499
+ },
500
+ sessionId: request.sessionId || '',
501
+ executionTime,
502
+ logs: this.logs,
503
+ };
504
+ }
505
+
506
+ const message = error instanceof Error ? error.message : 'Unknown error';
507
+ const stack = error instanceof Error ? error.stack : undefined;
508
+
509
+ return {
510
+ success: false,
511
+ error: message,
512
+ errorDetails: { stack },
513
+ sessionId: request.sessionId || '',
514
+ executionTime,
515
+ logs: this.logs,
516
+ };
517
+ }
518
+ }
519
+
520
+ /**
521
+ * Get all active sessions
522
+ */
523
+ static getAllSessions(): Array<{
524
+ id: string;
525
+ createdAt: Date;
526
+ lastUsed: Date;
527
+ initialized: boolean;
528
+ }> {
529
+ return Array.from(sessions.values()).map(session => ({
530
+ id: session.id,
531
+ createdAt: session.createdAt,
532
+ lastUsed: session.lastUsed,
533
+ initialized: session.initialized,
534
+ }));
535
+ }
536
+
537
+ /**
538
+ * Delete a specific session
539
+ */
540
+ static deleteSession(sessionId: string): boolean {
541
+ if (sessions.has(sessionId)) {
542
+ cleanupSession(sessionId);
543
+ return true;
544
+ }
545
+ return false;
546
+ }
547
+
548
+ /**
549
+ * Delete all sessions
550
+ */
551
+ static deleteAllSessions(): number {
552
+ const count = sessions.size;
553
+ Array.from(sessions.keys()).forEach(sessionId => {
554
+ cleanupSession(sessionId);
555
+ });
556
+ return count;
557
+ }
558
+ }
559
+
560
+ // ============================================================================
561
+ // Custom Error Classes
562
+ // ============================================================================
563
+
564
+ export class McpRpcError extends Error {
565
+ code: number;
566
+ data?: unknown;
567
+
568
+ constructor(message: string, code: number, data?: unknown) {
569
+ super(message);
570
+ this.name = 'McpRpcError';
571
+ this.code = code;
572
+ this.data = data;
573
+ }
574
+ }
575
+
576
+ export class McpTimeoutError extends Error {
577
+ constructor(message: string = 'MCP request timed out') {
578
+ super(message);
579
+ this.name = 'McpTimeoutError';
580
+ }
581
+ }
582
+
583
+ export class McpProcessError extends Error {
584
+ exitCode?: number;
585
+ signal?: string;
586
+
587
+ constructor(message: string, exitCode?: number, signal?: string) {
588
+ super(message);
589
+ this.name = 'McpProcessError';
590
+ this.exitCode = exitCode;
591
+ this.signal = signal;
592
+ }
593
+ }