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,649 @@
1
+ /**
2
+ * @fileoverview gRPC/Protobuf parser for extracting service methods as MCP tools
3
+ * Parses .proto files to extract service definitions, RPC methods, and messages
4
+ * @copyright Copyright (c) 2024-2026 nirholas
5
+ * @license MIT
6
+ */
7
+
8
+ export interface ProtobufField {
9
+ name: string;
10
+ type: string;
11
+ number: number;
12
+ repeated: boolean;
13
+ optional: boolean;
14
+ mapKeyType?: string;
15
+ mapValueType?: string;
16
+ comment?: string;
17
+ }
18
+
19
+ export interface ProtobufMessage {
20
+ name: string;
21
+ fields: ProtobufField[];
22
+ nestedMessages: ProtobufMessage[];
23
+ enums: ProtobufEnum[];
24
+ comment?: string;
25
+ }
26
+
27
+ export interface ProtobufEnum {
28
+ name: string;
29
+ values: Array<{
30
+ name: string;
31
+ number: number;
32
+ comment?: string;
33
+ }>;
34
+ comment?: string;
35
+ }
36
+
37
+ export interface ProtobufRpcMethod {
38
+ name: string;
39
+ inputType: string;
40
+ outputType: string;
41
+ clientStreaming: boolean;
42
+ serverStreaming: boolean;
43
+ comment?: string;
44
+ options?: Record<string, string>;
45
+ }
46
+
47
+ export interface ProtobufService {
48
+ name: string;
49
+ methods: ProtobufRpcMethod[];
50
+ comment?: string;
51
+ }
52
+
53
+ export interface GrpcToolDefinition {
54
+ name: string;
55
+ description: string;
56
+ inputSchema: {
57
+ type: 'object';
58
+ properties: Record<string, any>;
59
+ required?: string[];
60
+ };
61
+ metadata: {
62
+ service: string;
63
+ method: string;
64
+ inputType: string;
65
+ outputType: string;
66
+ clientStreaming: boolean;
67
+ serverStreaming: boolean;
68
+ httpBinding?: {
69
+ method: string;
70
+ path: string;
71
+ };
72
+ };
73
+ }
74
+
75
+ export interface GrpcParseResult {
76
+ format: 'grpc';
77
+ package: string;
78
+ services: ProtobufService[];
79
+ messages: ProtobufMessage[];
80
+ enums: ProtobufEnum[];
81
+ tools: GrpcToolDefinition[];
82
+ imports: string[];
83
+ options: Record<string, string>;
84
+ }
85
+
86
+ /**
87
+ * Parser for Protocol Buffer (.proto) files
88
+ */
89
+ export class GrpcParser {
90
+ private messages: Map<string, ProtobufMessage> = new Map();
91
+ private enums: Map<string, ProtobufEnum> = new Map();
92
+ private packageName: string = '';
93
+ private imports: string[] = [];
94
+ private options: Record<string, string> = {};
95
+
96
+ /**
97
+ * Parse a .proto file content
98
+ */
99
+ parse(protoContent: string): GrpcParseResult {
100
+ // Reset state
101
+ this.messages.clear();
102
+ this.enums.clear();
103
+ this.packageName = '';
104
+ this.imports = [];
105
+ this.options = {};
106
+
107
+ // Remove comments for easier parsing but keep for documentation
108
+ const commentMap = this.extractComments(protoContent);
109
+ const cleanContent = this.removeComments(protoContent);
110
+
111
+ // Parse package
112
+ this.parsePackage(cleanContent);
113
+
114
+ // Parse imports
115
+ this.parseImports(cleanContent);
116
+
117
+ // Parse options
118
+ this.parseOptions(cleanContent);
119
+
120
+ // Parse enums (need to do before messages)
121
+ const enums = this.parseEnums(cleanContent, commentMap);
122
+ enums.forEach(e => this.enums.set(e.name, e));
123
+
124
+ // Parse messages
125
+ const messages = this.parseMessages(cleanContent, commentMap);
126
+ messages.forEach(m => this.messages.set(m.name, m));
127
+
128
+ // Parse services
129
+ const services = this.parseServices(cleanContent, commentMap);
130
+
131
+ // Generate tool definitions
132
+ const tools = this.generateTools(services);
133
+
134
+ return {
135
+ format: 'grpc',
136
+ package: this.packageName,
137
+ services,
138
+ messages,
139
+ enums,
140
+ tools,
141
+ imports: this.imports,
142
+ options: this.options,
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Extract comments and their positions
148
+ */
149
+ private extractComments(content: string): Map<number, string> {
150
+ const comments = new Map<number, string>();
151
+ const lines = content.split('\n');
152
+ let currentComment = '';
153
+
154
+ for (let i = 0; i < lines.length; i++) {
155
+ const line = lines[i].trim();
156
+
157
+ // Single-line comment
158
+ if (line.startsWith('//')) {
159
+ const comment = line.substring(2).trim();
160
+ currentComment = currentComment ? `${currentComment} ${comment}` : comment;
161
+ continue;
162
+ }
163
+
164
+ // Block comment start
165
+ if (line.includes('/*')) {
166
+ const blockMatch = content.substring(content.indexOf(line)).match(/\/\*[\s\S]*?\*\//);
167
+ if (blockMatch) {
168
+ currentComment = blockMatch[0]
169
+ .replace(/^\/\*\*?/, '')
170
+ .replace(/\*\/$/, '')
171
+ .split('\n')
172
+ .map(l => l.replace(/^\s*\*?\s*/, '').trim())
173
+ .filter(l => l)
174
+ .join(' ');
175
+ }
176
+ continue;
177
+ }
178
+
179
+ // If we have a comment and reach a definition line, attach it
180
+ if (currentComment && (
181
+ line.startsWith('message ') ||
182
+ line.startsWith('enum ') ||
183
+ line.startsWith('service ') ||
184
+ line.startsWith('rpc ') ||
185
+ line.match(/^\w+\s+\w+\s*=/)
186
+ )) {
187
+ comments.set(i, currentComment);
188
+ currentComment = '';
189
+ } else if (!line.startsWith('//') && !line.includes('/*') && line.length > 0) {
190
+ currentComment = '';
191
+ }
192
+ }
193
+
194
+ return comments;
195
+ }
196
+
197
+ /**
198
+ * Remove comments from content
199
+ */
200
+ private removeComments(content: string): string {
201
+ // Remove block comments
202
+ let result = content.replace(/\/\*[\s\S]*?\*\//g, '');
203
+ // Remove line comments
204
+ result = result.replace(/\/\/.*$/gm, '');
205
+ return result;
206
+ }
207
+
208
+ /**
209
+ * Parse package declaration
210
+ */
211
+ private parsePackage(content: string): void {
212
+ const match = content.match(/package\s+([\w.]+)\s*;/);
213
+ if (match) {
214
+ this.packageName = match[1];
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Parse import statements
220
+ */
221
+ private parseImports(content: string): void {
222
+ const importPattern = /import\s+(?:public\s+)?"([^"]+)"\s*;/g;
223
+ let match;
224
+ while ((match = importPattern.exec(content)) !== null) {
225
+ this.imports.push(match[1]);
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Parse option statements
231
+ */
232
+ private parseOptions(content: string): void {
233
+ const optionPattern = /option\s+([\w.]+)\s*=\s*"?([^";\n]+)"?\s*;/g;
234
+ let match;
235
+ while ((match = optionPattern.exec(content)) !== null) {
236
+ this.options[match[1]] = match[2];
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Parse enum definitions
242
+ */
243
+ private parseEnums(content: string, commentMap: Map<number, string>): ProtobufEnum[] {
244
+ const enums: ProtobufEnum[] = [];
245
+ const enumPattern = /enum\s+(\w+)\s*\{([^}]+)\}/g;
246
+
247
+ let match;
248
+ while ((match = enumPattern.exec(content)) !== null) {
249
+ const name = match[1];
250
+ const body = match[2];
251
+ const values: ProtobufEnum['values'] = [];
252
+
253
+ const valuePattern = /(\w+)\s*=\s*(\d+)/g;
254
+ let valueMatch;
255
+ while ((valueMatch = valuePattern.exec(body)) !== null) {
256
+ values.push({
257
+ name: valueMatch[1],
258
+ number: parseInt(valueMatch[2], 10),
259
+ });
260
+ }
261
+
262
+ enums.push({ name, values });
263
+ }
264
+
265
+ return enums;
266
+ }
267
+
268
+ /**
269
+ * Parse message definitions
270
+ */
271
+ private parseMessages(content: string, commentMap: Map<number, string>): ProtobufMessage[] {
272
+ const messages: ProtobufMessage[] = [];
273
+ const messagePattern = /message\s+(\w+)\s*\{/g;
274
+
275
+ let match;
276
+ while ((match = messagePattern.exec(content)) !== null) {
277
+ const name = match[1];
278
+ const startIndex = match.index + match[0].length;
279
+ const body = this.extractBracedContent(content, startIndex - 1);
280
+
281
+ if (body) {
282
+ const fields = this.parseFields(body);
283
+ const nestedMessages = this.parseMessages(body, commentMap);
284
+ const nestedEnums = this.parseEnums(body, commentMap);
285
+
286
+ messages.push({
287
+ name,
288
+ fields,
289
+ nestedMessages,
290
+ enums: nestedEnums,
291
+ });
292
+ }
293
+ }
294
+
295
+ return messages;
296
+ }
297
+
298
+ /**
299
+ * Parse message fields
300
+ */
301
+ private parseFields(body: string): ProtobufField[] {
302
+ const fields: ProtobufField[] = [];
303
+
304
+ // Standard field pattern: [optional|repeated] type name = number;
305
+ const fieldPattern = /(optional\s+|repeated\s+)?(\w+(?:\.\w+)*)\s+(\w+)\s*=\s*(\d+)/g;
306
+
307
+ // Map field pattern: map<keyType, valueType> name = number;
308
+ const mapPattern = /map\s*<\s*(\w+)\s*,\s*(\w+(?:\.\w+)*)\s*>\s+(\w+)\s*=\s*(\d+)/g;
309
+
310
+ let match;
311
+
312
+ // Parse map fields first
313
+ while ((match = mapPattern.exec(body)) !== null) {
314
+ fields.push({
315
+ name: match[3],
316
+ type: 'map',
317
+ number: parseInt(match[4], 10),
318
+ repeated: false,
319
+ optional: false,
320
+ mapKeyType: match[1],
321
+ mapValueType: match[2],
322
+ });
323
+ }
324
+
325
+ // Parse regular fields
326
+ while ((match = fieldPattern.exec(body)) !== null) {
327
+ const modifier = match[1]?.trim() || '';
328
+ fields.push({
329
+ name: match[3],
330
+ type: match[2],
331
+ number: parseInt(match[4], 10),
332
+ repeated: modifier === 'repeated',
333
+ optional: modifier === 'optional',
334
+ });
335
+ }
336
+
337
+ return fields.sort((a, b) => a.number - b.number);
338
+ }
339
+
340
+ /**
341
+ * Parse service definitions
342
+ */
343
+ private parseServices(content: string, commentMap: Map<number, string>): ProtobufService[] {
344
+ const services: ProtobufService[] = [];
345
+ const servicePattern = /service\s+(\w+)\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}/g;
346
+
347
+ let match;
348
+ while ((match = servicePattern.exec(content)) !== null) {
349
+ const name = match[1];
350
+ const body = match[2];
351
+ const methods = this.parseRpcMethods(body);
352
+
353
+ services.push({ name, methods });
354
+ }
355
+
356
+ return services;
357
+ }
358
+
359
+ /**
360
+ * Parse RPC method definitions
361
+ */
362
+ private parseRpcMethods(body: string): ProtobufRpcMethod[] {
363
+ const methods: ProtobufRpcMethod[] = [];
364
+
365
+ // RPC pattern: rpc MethodName (stream? RequestType) returns (stream? ResponseType) { options }
366
+ const rpcPattern = /rpc\s+(\w+)\s*\(\s*(stream\s+)?(\w+(?:\.\w+)*)\s*\)\s*returns\s*\(\s*(stream\s+)?(\w+(?:\.\w+)*)\s*\)(?:\s*\{([^}]*)\})?/g;
367
+
368
+ let match;
369
+ while ((match = rpcPattern.exec(body)) !== null) {
370
+ const options: Record<string, string> = {};
371
+
372
+ // Parse HTTP bindings if present (google.api.http)
373
+ if (match[6]) {
374
+ const httpMatch = match[6].match(/option\s*\(google\.api\.http\)\s*=\s*\{([^}]+)\}/);
375
+ if (httpMatch) {
376
+ const httpBody = httpMatch[1];
377
+ const methodMatch = httpBody.match(/(get|post|put|delete|patch):\s*"([^"]+)"/i);
378
+ if (methodMatch) {
379
+ options['http.method'] = methodMatch[1].toUpperCase();
380
+ options['http.path'] = methodMatch[2];
381
+ }
382
+ const bodyMatch = httpBody.match(/body:\s*"([^"]+)"/);
383
+ if (bodyMatch) {
384
+ options['http.body'] = bodyMatch[1];
385
+ }
386
+ }
387
+ }
388
+
389
+ methods.push({
390
+ name: match[1],
391
+ inputType: match[3],
392
+ outputType: match[5],
393
+ clientStreaming: !!match[2],
394
+ serverStreaming: !!match[4],
395
+ options: Object.keys(options).length > 0 ? options : undefined,
396
+ });
397
+ }
398
+
399
+ return methods;
400
+ }
401
+
402
+ /**
403
+ * Extract content between matching braces
404
+ */
405
+ private extractBracedContent(content: string, startIndex: number): string | null {
406
+ let depth = 0;
407
+ let start = -1;
408
+
409
+ for (let i = startIndex; i < content.length; i++) {
410
+ if (content[i] === '{') {
411
+ if (start === -1) start = i;
412
+ depth++;
413
+ } else if (content[i] === '}') {
414
+ depth--;
415
+ if (depth === 0) {
416
+ return content.substring(start + 1, i);
417
+ }
418
+ }
419
+ }
420
+
421
+ return null;
422
+ }
423
+
424
+ /**
425
+ * Generate MCP tool definitions from services
426
+ */
427
+ private generateTools(services: ProtobufService[]): GrpcToolDefinition[] {
428
+ const tools: GrpcToolDefinition[] = [];
429
+
430
+ for (const service of services) {
431
+ for (const method of service.methods) {
432
+ const inputMessage = this.messages.get(method.inputType);
433
+ const inputSchema = this.messageToJsonSchema(inputMessage);
434
+
435
+ const toolName = this.generateToolName(service.name, method.name);
436
+ const description = this.generateDescription(service, method);
437
+
438
+ tools.push({
439
+ name: toolName,
440
+ description,
441
+ inputSchema,
442
+ metadata: {
443
+ service: service.name,
444
+ method: method.name,
445
+ inputType: method.inputType,
446
+ outputType: method.outputType,
447
+ clientStreaming: method.clientStreaming,
448
+ serverStreaming: method.serverStreaming,
449
+ httpBinding: method.options?.['http.method'] ? {
450
+ method: method.options['http.method'],
451
+ path: method.options['http.path'],
452
+ } : undefined,
453
+ },
454
+ });
455
+ }
456
+ }
457
+
458
+ return tools;
459
+ }
460
+
461
+ /**
462
+ * Convert a protobuf message to JSON Schema
463
+ */
464
+ private messageToJsonSchema(message?: ProtobufMessage): GrpcToolDefinition['inputSchema'] {
465
+ if (!message) {
466
+ return { type: 'object', properties: {}, required: [] };
467
+ }
468
+
469
+ const properties: Record<string, any> = {};
470
+ const required: string[] = [];
471
+
472
+ for (const field of message.fields) {
473
+ const schema = this.fieldToJsonSchema(field);
474
+ properties[field.name] = schema;
475
+
476
+ // In proto3, fields are optional by default unless explicitly required
477
+ if (!field.optional && !field.repeated) {
478
+ required.push(field.name);
479
+ }
480
+ }
481
+
482
+ return {
483
+ type: 'object',
484
+ properties,
485
+ required: required.length > 0 ? required : undefined,
486
+ };
487
+ }
488
+
489
+ /**
490
+ * Convert a protobuf field to JSON Schema
491
+ */
492
+ private fieldToJsonSchema(field: ProtobufField): Record<string, any> {
493
+ let schema: Record<string, any>;
494
+
495
+ if (field.type === 'map') {
496
+ schema = {
497
+ type: 'object',
498
+ additionalProperties: this.protoTypeToJsonSchema(field.mapValueType || 'string'),
499
+ };
500
+ } else {
501
+ schema = this.protoTypeToJsonSchema(field.type);
502
+ }
503
+
504
+ if (field.repeated) {
505
+ return {
506
+ type: 'array',
507
+ items: schema,
508
+ };
509
+ }
510
+
511
+ if (field.comment) {
512
+ schema.description = field.comment;
513
+ }
514
+
515
+ return schema;
516
+ }
517
+
518
+ /**
519
+ * Convert protobuf type to JSON Schema type
520
+ */
521
+ private protoTypeToJsonSchema(protoType: string): Record<string, any> {
522
+ // Scalar types
523
+ const scalarMap: Record<string, any> = {
524
+ 'double': { type: 'number' },
525
+ 'float': { type: 'number' },
526
+ 'int32': { type: 'integer' },
527
+ 'int64': { type: 'integer' },
528
+ 'uint32': { type: 'integer', minimum: 0 },
529
+ 'uint64': { type: 'integer', minimum: 0 },
530
+ 'sint32': { type: 'integer' },
531
+ 'sint64': { type: 'integer' },
532
+ 'fixed32': { type: 'integer', minimum: 0 },
533
+ 'fixed64': { type: 'integer', minimum: 0 },
534
+ 'sfixed32': { type: 'integer' },
535
+ 'sfixed64': { type: 'integer' },
536
+ 'bool': { type: 'boolean' },
537
+ 'string': { type: 'string' },
538
+ 'bytes': { type: 'string', contentEncoding: 'base64' },
539
+ };
540
+
541
+ if (scalarMap[protoType]) {
542
+ return scalarMap[protoType];
543
+ }
544
+
545
+ // Well-known types
546
+ const wellKnownMap: Record<string, any> = {
547
+ 'google.protobuf.Timestamp': { type: 'string', format: 'date-time' },
548
+ 'google.protobuf.Duration': { type: 'string' },
549
+ 'google.protobuf.Empty': { type: 'object', properties: {} },
550
+ 'google.protobuf.Any': { type: 'object' },
551
+ 'google.protobuf.Struct': { type: 'object' },
552
+ 'google.protobuf.Value': {},
553
+ 'google.protobuf.NullValue': { type: 'null' },
554
+ 'google.protobuf.BoolValue': { type: 'boolean' },
555
+ 'google.protobuf.StringValue': { type: 'string' },
556
+ 'google.protobuf.Int32Value': { type: 'integer' },
557
+ 'google.protobuf.Int64Value': { type: 'integer' },
558
+ 'google.protobuf.UInt32Value': { type: 'integer', minimum: 0 },
559
+ 'google.protobuf.UInt64Value': { type: 'integer', minimum: 0 },
560
+ 'google.protobuf.FloatValue': { type: 'number' },
561
+ 'google.protobuf.DoubleValue': { type: 'number' },
562
+ 'google.protobuf.BytesValue': { type: 'string', contentEncoding: 'base64' },
563
+ };
564
+
565
+ if (wellKnownMap[protoType]) {
566
+ return wellKnownMap[protoType];
567
+ }
568
+
569
+ // Check for enum
570
+ const enumDef = this.enums.get(protoType);
571
+ if (enumDef) {
572
+ return {
573
+ type: 'string',
574
+ enum: enumDef.values.map(v => v.name),
575
+ };
576
+ }
577
+
578
+ // Check for message (nested object)
579
+ const messageDef = this.messages.get(protoType);
580
+ if (messageDef) {
581
+ return this.messageToJsonSchema(messageDef);
582
+ }
583
+
584
+ // Unknown type - assume object
585
+ return { type: 'object', description: `Custom type: ${protoType}` };
586
+ }
587
+
588
+ /**
589
+ * Generate tool name from service and method
590
+ */
591
+ private generateToolName(serviceName: string, methodName: string): string {
592
+ // Convert CamelCase to snake_case
593
+ const snakeCase = (str: string) => str
594
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
595
+ .toLowerCase();
596
+
597
+ return `${snakeCase(serviceName)}_${snakeCase(methodName)}`;
598
+ }
599
+
600
+ /**
601
+ * Generate description for a tool
602
+ */
603
+ private generateDescription(service: ProtobufService, method: ProtobufRpcMethod): string {
604
+ const parts: string[] = [];
605
+
606
+ if (method.comment) {
607
+ parts.push(method.comment);
608
+ } else {
609
+ parts.push(`${method.name} RPC method from ${service.name} service`);
610
+ }
611
+
612
+ if (method.clientStreaming || method.serverStreaming) {
613
+ const streaming = [];
614
+ if (method.clientStreaming) streaming.push('client');
615
+ if (method.serverStreaming) streaming.push('server');
616
+ parts.push(`(${streaming.join(' and ')} streaming)`);
617
+ }
618
+
619
+ if (method.options?.['http.method']) {
620
+ parts.push(`HTTP: ${method.options['http.method']} ${method.options['http.path']}`);
621
+ }
622
+
623
+ return parts.join(' ');
624
+ }
625
+
626
+ /**
627
+ * Check if content appears to be a proto file
628
+ */
629
+ static isProtoFile(content: string): boolean {
630
+ const trimmed = content.trim();
631
+ return (
632
+ trimmed.includes('syntax = "proto') ||
633
+ trimmed.includes('message ') ||
634
+ trimmed.includes('service ') ||
635
+ trimmed.includes('rpc ')
636
+ );
637
+ }
638
+
639
+ /**
640
+ * Get proto syntax version
641
+ */
642
+ getProtoVersion(content: string): 'proto2' | 'proto3' | 'unknown' {
643
+ const match = content.match(/syntax\s*=\s*"(proto\d)"/);
644
+ if (match) {
645
+ return match[1] as 'proto2' | 'proto3';
646
+ }
647
+ return 'unknown';
648
+ }
649
+ }