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,401 @@
1
+ /**
2
+ * BranchSelector Component - Select branch, tag, or commit SHA
3
+ * @copyright 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ 'use client';
8
+
9
+ import { useState, useEffect, useCallback, useRef } from 'react';
10
+ import { motion, AnimatePresence } from 'framer-motion';
11
+ import { GitBranch, Tag, Hash, ChevronDown, Loader2, Check, RefreshCw, X } from 'lucide-react';
12
+ import { Input } from '@/components/ui/input';
13
+ import { Button } from '@/components/ui/button';
14
+
15
+ export type RefType = 'branch' | 'tag' | 'commit';
16
+
17
+ export interface GitRef {
18
+ name: string;
19
+ type: RefType;
20
+ sha?: string;
21
+ isDefault?: boolean;
22
+ }
23
+
24
+ interface BranchSelectorProps {
25
+ owner: string;
26
+ repo: string;
27
+ selectedRef: GitRef | null;
28
+ onRefChange: (ref: GitRef | null) => void;
29
+ className?: string;
30
+ disabled?: boolean;
31
+ }
32
+
33
+ const REF_TYPE_ICONS: Record<RefType, typeof GitBranch> = {
34
+ branch: GitBranch,
35
+ tag: Tag,
36
+ commit: Hash,
37
+ };
38
+
39
+ const REF_TYPE_COLORS: Record<RefType, string> = {
40
+ branch: 'text-green-400',
41
+ tag: 'text-blue-400',
42
+ commit: 'text-orange-400',
43
+ };
44
+
45
+ export default function BranchSelector({
46
+ owner,
47
+ repo,
48
+ selectedRef,
49
+ onRefChange,
50
+ className = '',
51
+ disabled = false,
52
+ }: BranchSelectorProps) {
53
+ const [isOpen, setIsOpen] = useState(false);
54
+ const [activeTab, setActiveTab] = useState<RefType>('branch');
55
+ const [branches, setBranches] = useState<GitRef[]>([]);
56
+ const [tags, setTags] = useState<GitRef[]>([]);
57
+ const [isLoading, setIsLoading] = useState(false);
58
+ const [error, setError] = useState<string | null>(null);
59
+ const [searchQuery, setSearchQuery] = useState('');
60
+ const [commitSha, setCommitSha] = useState('');
61
+ const dropdownRef = useRef<HTMLDivElement>(null);
62
+
63
+ // Fetch branches and tags from GitHub API
64
+ const fetchRefs = useCallback(async () => {
65
+ if (!owner || !repo) return;
66
+
67
+ setIsLoading(true);
68
+ setError(null);
69
+
70
+ try {
71
+ // Fetch branches
72
+ const branchesRes = await fetch(
73
+ `https://api.github.com/repos/${owner}/${repo}/branches?per_page=100`
74
+ );
75
+
76
+ if (!branchesRes.ok) {
77
+ throw new Error('Failed to fetch branches');
78
+ }
79
+
80
+ const branchesData = await branchesRes.json();
81
+
82
+ // Fetch default branch info
83
+ const repoRes = await fetch(`https://api.github.com/repos/${owner}/${repo}`);
84
+ const repoData = repoRes.ok ? await repoRes.json() : { default_branch: 'main' };
85
+ const defaultBranch = repoData.default_branch;
86
+
87
+ const branchRefs: GitRef[] = branchesData.map((b: { name: string; commit: { sha: string } }) => ({
88
+ name: b.name,
89
+ type: 'branch' as RefType,
90
+ sha: b.commit.sha,
91
+ isDefault: b.name === defaultBranch,
92
+ }));
93
+
94
+ // Sort to put default branch first
95
+ branchRefs.sort((a, b) => {
96
+ if (a.isDefault) return -1;
97
+ if (b.isDefault) return 1;
98
+ return a.name.localeCompare(b.name);
99
+ });
100
+
101
+ setBranches(branchRefs);
102
+
103
+ // Set default branch as selected if nothing selected
104
+ if (!selectedRef) {
105
+ const defaultRef = branchRefs.find(b => b.isDefault) || branchRefs[0];
106
+ if (defaultRef) {
107
+ onRefChange(defaultRef);
108
+ }
109
+ }
110
+
111
+ // Fetch tags
112
+ const tagsRes = await fetch(
113
+ `https://api.github.com/repos/${owner}/${repo}/tags?per_page=100`
114
+ );
115
+
116
+ if (tagsRes.ok) {
117
+ const tagsData = await tagsRes.json();
118
+ const tagRefs: GitRef[] = tagsData.map((t: { name: string; commit: { sha: string } }) => ({
119
+ name: t.name,
120
+ type: 'tag' as RefType,
121
+ sha: t.commit.sha,
122
+ }));
123
+ setTags(tagRefs);
124
+ }
125
+ } catch (err) {
126
+ setError(err instanceof Error ? err.message : 'Failed to fetch refs');
127
+ } finally {
128
+ setIsLoading(false);
129
+ }
130
+ }, [owner, repo, selectedRef, onRefChange]);
131
+
132
+ // Fetch refs when owner/repo changes
133
+ useEffect(() => {
134
+ if (owner && repo) {
135
+ fetchRefs();
136
+ }
137
+ }, [owner, repo, fetchRefs]);
138
+
139
+ // Close dropdown on outside click
140
+ useEffect(() => {
141
+ function handleClickOutside(event: MouseEvent) {
142
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
143
+ setIsOpen(false);
144
+ }
145
+ }
146
+
147
+ document.addEventListener('mousedown', handleClickOutside);
148
+ return () => document.removeEventListener('mousedown', handleClickOutside);
149
+ }, []);
150
+
151
+ const handleRefSelect = useCallback((ref: GitRef) => {
152
+ onRefChange(ref);
153
+ setIsOpen(false);
154
+ setSearchQuery('');
155
+ }, [onRefChange]);
156
+
157
+ const handleCommitSubmit = useCallback(() => {
158
+ if (commitSha.trim()) {
159
+ onRefChange({
160
+ name: commitSha.trim().substring(0, 7),
161
+ type: 'commit',
162
+ sha: commitSha.trim(),
163
+ });
164
+ setIsOpen(false);
165
+ setCommitSha('');
166
+ }
167
+ }, [commitSha, onRefChange]);
168
+
169
+ const handleClear = useCallback(() => {
170
+ onRefChange(null);
171
+ const defaultBranch = branches.find(b => b.isDefault);
172
+ if (defaultBranch) {
173
+ onRefChange(defaultBranch);
174
+ }
175
+ }, [branches, onRefChange]);
176
+
177
+ // Filter refs based on search
178
+ const filteredBranches = branches.filter(b =>
179
+ b.name.toLowerCase().includes(searchQuery.toLowerCase())
180
+ );
181
+ const filteredTags = tags.filter(t =>
182
+ t.name.toLowerCase().includes(searchQuery.toLowerCase())
183
+ );
184
+
185
+ const tabs = [
186
+ { id: 'branch' as RefType, label: 'Branches', count: branches.length },
187
+ { id: 'tag' as RefType, label: 'Tags', count: tags.length },
188
+ { id: 'commit' as RefType, label: 'Commit' },
189
+ ];
190
+
191
+ if (!owner || !repo) {
192
+ return null;
193
+ }
194
+
195
+ return (
196
+ <div className={`relative ${className}`} ref={dropdownRef}>
197
+ {/* Trigger button */}
198
+ <button
199
+ onClick={() => setIsOpen(!isOpen)}
200
+ disabled={disabled || isLoading}
201
+ className={`flex items-center gap-2 px-3 py-2 text-sm rounded-lg border transition-all ${
202
+ isOpen
203
+ ? 'border-neutral-600 bg-white/10 text-white'
204
+ : 'border-neutral-700 bg-black/50 text-neutral-300 hover:border-neutral-600 hover:text-white'
205
+ } ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
206
+ >
207
+ {isLoading ? (
208
+ <Loader2 className="w-4 h-4 animate-spin" />
209
+ ) : selectedRef ? (
210
+ <>
211
+ {(() => {
212
+ const Icon = REF_TYPE_ICONS[selectedRef.type];
213
+ return <Icon className={`w-4 h-4 ${REF_TYPE_COLORS[selectedRef.type]}`} />;
214
+ })()}
215
+ <span className="max-w-[120px] truncate">{selectedRef.name}</span>
216
+ {selectedRef.isDefault && (
217
+ <span className="text-xs text-neutral-500">(default)</span>
218
+ )}
219
+ </>
220
+ ) : (
221
+ <>
222
+ <GitBranch className="w-4 h-4" />
223
+ <span>Select ref</span>
224
+ </>
225
+ )}
226
+ <ChevronDown className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} />
227
+ </button>
228
+
229
+ {/* Dropdown */}
230
+ <AnimatePresence>
231
+ {isOpen && (
232
+ <motion.div
233
+ initial={{ opacity: 0, y: -10, scale: 0.95 }}
234
+ animate={{ opacity: 1, y: 0, scale: 1 }}
235
+ exit={{ opacity: 0, y: -10, scale: 0.95 }}
236
+ transition={{ duration: 0.15 }}
237
+ className="absolute z-50 top-full left-0 mt-2 w-72 rounded-xl border border-neutral-800 bg-neutral-900 shadow-xl overflow-hidden"
238
+ >
239
+ {/* Tabs */}
240
+ <div className="flex border-b border-neutral-800">
241
+ {tabs.map((tab) => (
242
+ <button
243
+ key={tab.id}
244
+ onClick={() => setActiveTab(tab.id)}
245
+ className={`flex-1 px-3 py-2.5 text-xs font-medium transition-colors ${
246
+ activeTab === tab.id
247
+ ? 'text-white bg-white/5 border-b-2 border-white'
248
+ : 'text-neutral-400 hover:text-white hover:bg-white/5'
249
+ }`}
250
+ >
251
+ {tab.label}
252
+ {tab.count !== undefined && (
253
+ <span className="ml-1 text-neutral-500">({tab.count})</span>
254
+ )}
255
+ </button>
256
+ ))}
257
+ </div>
258
+
259
+ {/* Search */}
260
+ {activeTab !== 'commit' && (
261
+ <div className="p-2 border-b border-neutral-800">
262
+ <Input
263
+ type="text"
264
+ placeholder={`Search ${activeTab}s...`}
265
+ value={searchQuery}
266
+ onChange={(e) => setSearchQuery(e.target.value)}
267
+ className="h-8 text-sm"
268
+ />
269
+ </div>
270
+ )}
271
+
272
+ {/* Content */}
273
+ <div className="max-h-64 overflow-y-auto">
274
+ {activeTab === 'branch' && (
275
+ <div className="py-1">
276
+ {filteredBranches.length === 0 ? (
277
+ <div className="px-3 py-4 text-center text-sm text-neutral-500">
278
+ {searchQuery ? 'No matching branches' : 'No branches found'}
279
+ </div>
280
+ ) : (
281
+ filteredBranches.map((branch) => (
282
+ <RefItem
283
+ key={branch.name}
284
+ ref={branch}
285
+ isSelected={selectedRef?.name === branch.name && selectedRef?.type === 'branch'}
286
+ onSelect={() => handleRefSelect(branch)}
287
+ />
288
+ ))
289
+ )}
290
+ </div>
291
+ )}
292
+
293
+ {activeTab === 'tag' && (
294
+ <div className="py-1">
295
+ {filteredTags.length === 0 ? (
296
+ <div className="px-3 py-4 text-center text-sm text-neutral-500">
297
+ {searchQuery ? 'No matching tags' : 'No tags found'}
298
+ </div>
299
+ ) : (
300
+ filteredTags.map((tag) => (
301
+ <RefItem
302
+ key={tag.name}
303
+ ref={tag}
304
+ isSelected={selectedRef?.name === tag.name && selectedRef?.type === 'tag'}
305
+ onSelect={() => handleRefSelect(tag)}
306
+ />
307
+ ))
308
+ )}
309
+ </div>
310
+ )}
311
+
312
+ {activeTab === 'commit' && (
313
+ <div className="p-3 space-y-3">
314
+ <p className="text-xs text-neutral-400">
315
+ Enter a specific commit SHA to use
316
+ </p>
317
+ <div className="flex gap-2">
318
+ <Input
319
+ type="text"
320
+ placeholder="Enter commit SHA..."
321
+ value={commitSha}
322
+ onChange={(e) => setCommitSha(e.target.value)}
323
+ className="h-9 text-sm font-mono"
324
+ maxLength={40}
325
+ />
326
+ <Button
327
+ size="sm"
328
+ onClick={handleCommitSubmit}
329
+ disabled={!commitSha.trim()}
330
+ >
331
+ Use
332
+ </Button>
333
+ </div>
334
+ </div>
335
+ )}
336
+ </div>
337
+
338
+ {/* Footer */}
339
+ {error && (
340
+ <div className="px-3 py-2 border-t border-neutral-800 bg-red-500/10">
341
+ <p className="text-xs text-red-400 flex items-center gap-2">
342
+ <X className="w-3 h-3" />
343
+ {error}
344
+ </p>
345
+ </div>
346
+ )}
347
+
348
+ <div className="px-3 py-2 border-t border-neutral-800 flex items-center justify-between">
349
+ <button
350
+ onClick={fetchRefs}
351
+ className="text-xs text-neutral-500 hover:text-white transition-colors flex items-center gap-1"
352
+ >
353
+ <RefreshCw className="w-3 h-3" />
354
+ Refresh
355
+ </button>
356
+ {selectedRef && !selectedRef.isDefault && (
357
+ <button
358
+ onClick={handleClear}
359
+ className="text-xs text-neutral-500 hover:text-white transition-colors"
360
+ >
361
+ Reset to default
362
+ </button>
363
+ )}
364
+ </div>
365
+ </motion.div>
366
+ )}
367
+ </AnimatePresence>
368
+ </div>
369
+ );
370
+ }
371
+
372
+ // Individual ref item component
373
+ interface RefItemProps {
374
+ ref: GitRef;
375
+ isSelected: boolean;
376
+ onSelect: () => void;
377
+ }
378
+
379
+ function RefItem({ ref, isSelected, onSelect }: RefItemProps) {
380
+ const Icon = REF_TYPE_ICONS[ref.type];
381
+
382
+ return (
383
+ <button
384
+ onClick={onSelect}
385
+ className={`w-full flex items-center gap-2 px-3 py-2 text-sm transition-colors ${
386
+ isSelected
387
+ ? 'bg-white/10 text-white'
388
+ : 'text-neutral-300 hover:bg-white/5 hover:text-white'
389
+ }`}
390
+ >
391
+ <Icon className={`w-4 h-4 flex-shrink-0 ${REF_TYPE_COLORS[ref.type]}`} />
392
+ <span className="flex-1 text-left truncate">{ref.name}</span>
393
+ {ref.isDefault && (
394
+ <span className="text-xs px-1.5 py-0.5 rounded bg-green-500/20 text-green-400">
395
+ default
396
+ </span>
397
+ )}
398
+ {isSelected && <Check className="w-4 h-4 text-green-400 flex-shrink-0" />}
399
+ </button>
400
+ );
401
+ }
@@ -0,0 +1,226 @@
1
+ /**
2
+ * ClaudeConfigExport Component - Generate and copy Claude desktop config
3
+ * @copyright 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ 'use client';
8
+
9
+ import { useState, useCallback, useMemo } from 'react';
10
+ import { motion, AnimatePresence } from 'framer-motion';
11
+ import { Copy, Check, Terminal, FileJson, Download } from 'lucide-react';
12
+ import { Button } from '@/components/ui/button';
13
+ import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
14
+ import { copyToClipboard, downloadAsFile } from '@/lib/utils';
15
+
16
+ interface ClaudeConfigExportProps {
17
+ serverName: string;
18
+ serverDescription: string;
19
+ generatedFilePath?: string;
20
+ className?: string;
21
+ }
22
+
23
+ type ConfigType = 'npx' | 'local' | 'python';
24
+
25
+ export default function ClaudeConfigExport({
26
+ serverName,
27
+ serverDescription,
28
+ generatedFilePath,
29
+ className = '',
30
+ }: ClaudeConfigExportProps) {
31
+ const [copiedConfig, setCopiedConfig] = useState<ConfigType | null>(null);
32
+ const [activeTab, setActiveTab] = useState<ConfigType>('npx');
33
+
34
+ // Generate the different config formats
35
+ const configs = useMemo(() => {
36
+ const safeName = serverName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
37
+
38
+ const npxConfig = {
39
+ mcpServers: {
40
+ [safeName]: {
41
+ command: 'npx',
42
+ args: ['-y', `@github-to-mcp/${safeName}`],
43
+ env: {},
44
+ },
45
+ },
46
+ };
47
+
48
+ const localConfig = {
49
+ mcpServers: {
50
+ [safeName]: {
51
+ command: 'node',
52
+ args: [generatedFilePath || `./path/to/${safeName}-mcp-server.js`],
53
+ env: {},
54
+ },
55
+ },
56
+ };
57
+
58
+ const pythonConfig = {
59
+ mcpServers: {
60
+ [safeName]: {
61
+ command: 'python',
62
+ args: ['-m', safeName.replace(/-/g, '_')],
63
+ env: {},
64
+ },
65
+ },
66
+ };
67
+
68
+ return {
69
+ npx: JSON.stringify(npxConfig, null, 2),
70
+ local: JSON.stringify(localConfig, null, 2),
71
+ python: JSON.stringify(pythonConfig, null, 2),
72
+ };
73
+ }, [serverName, generatedFilePath]);
74
+
75
+ const configDescriptions: Record<ConfigType, { title: string; description: string; icon: typeof Terminal }> = {
76
+ npx: {
77
+ title: 'NPX (Recommended)',
78
+ description: 'Run directly without installation using npx',
79
+ icon: Terminal,
80
+ },
81
+ local: {
82
+ title: 'Local File',
83
+ description: 'Run from a local file path',
84
+ icon: FileJson,
85
+ },
86
+ python: {
87
+ title: 'Python',
88
+ description: 'Run using Python module',
89
+ icon: Terminal,
90
+ },
91
+ };
92
+
93
+ const handleCopy = useCallback(async (configType: ConfigType) => {
94
+ const success = await copyToClipboard(configs[configType]);
95
+ if (success) {
96
+ setCopiedConfig(configType);
97
+ setTimeout(() => setCopiedConfig(null), 2000);
98
+ }
99
+ }, [configs]);
100
+
101
+ const handleDownload = useCallback(() => {
102
+ const fullConfig = {
103
+ mcpServers: JSON.parse(configs[activeTab]).mcpServers,
104
+ };
105
+ downloadAsFile(
106
+ JSON.stringify(fullConfig, null, 2),
107
+ 'claude_desktop_config.json',
108
+ 'application/json'
109
+ );
110
+ }, [configs, activeTab]);
111
+
112
+ return (
113
+ <div className={`rounded-xl border border-neutral-800 bg-neutral-900/50 backdrop-blur-xl overflow-hidden ${className}`}>
114
+ <div className="p-4 border-b border-neutral-800">
115
+ <div className="flex items-center justify-between">
116
+ <div>
117
+ <h3 className="font-semibold text-white">Claude Desktop Configuration</h3>
118
+ <p className="text-sm text-neutral-400 mt-1">
119
+ Add this to your <code className="text-xs bg-white/10 px-1.5 py-0.5 rounded">claude_desktop_config.json</code>
120
+ </p>
121
+ </div>
122
+ <Button
123
+ variant="outline"
124
+ size="sm"
125
+ onClick={handleDownload}
126
+ leftIcon={<Download className="w-4 h-4" />}
127
+ >
128
+ Download
129
+ </Button>
130
+ </div>
131
+ </div>
132
+
133
+ <Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as ConfigType)} className="p-4">
134
+ <TabsList className="w-full grid grid-cols-3 mb-4">
135
+ {(Object.keys(configs) as ConfigType[]).map((type) => {
136
+ const config = configDescriptions[type];
137
+ const Icon = config.icon;
138
+ return (
139
+ <TabsTrigger key={type} value={type} className="gap-2">
140
+ <Icon className="w-3.5 h-3.5" />
141
+ {type === 'npx' ? 'NPX' : type === 'local' ? 'Local' : 'Python'}
142
+ </TabsTrigger>
143
+ );
144
+ })}
145
+ </TabsList>
146
+
147
+ {(Object.keys(configs) as ConfigType[]).map((type) => {
148
+ const config = configDescriptions[type];
149
+ const isCopied = copiedConfig === type;
150
+
151
+ return (
152
+ <TabsContent key={type} value={type}>
153
+ <div className="space-y-3">
154
+ <p className="text-sm text-neutral-400">{config.description}</p>
155
+
156
+ <div className="relative group">
157
+ <pre className="p-4 bg-black/50 rounded-lg border border-neutral-800 overflow-x-auto text-sm text-neutral-300 font-mono">
158
+ {configs[type]}
159
+ </pre>
160
+
161
+ {/* Copy button */}
162
+ <Button
163
+ variant="secondary"
164
+ size="sm"
165
+ onClick={() => handleCopy(type)}
166
+ className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity"
167
+ leftIcon={
168
+ <AnimatePresence mode="wait">
169
+ <motion.div
170
+ key={isCopied ? 'check' : 'copy'}
171
+ initial={{ scale: 0.5, opacity: 0 }}
172
+ animate={{ scale: 1, opacity: 1 }}
173
+ exit={{ scale: 0.5, opacity: 0 }}
174
+ transition={{ duration: 0.15 }}
175
+ >
176
+ {isCopied ? (
177
+ <Check className="w-4 h-4 text-green-400" />
178
+ ) : (
179
+ <Copy className="w-4 h-4" />
180
+ )}
181
+ </motion.div>
182
+ </AnimatePresence>
183
+ }
184
+ >
185
+ {isCopied ? 'Copied!' : 'Copy'}
186
+ </Button>
187
+ </div>
188
+
189
+ {/* Instructions */}
190
+ <div className="p-3 bg-white/5 rounded-lg border border-neutral-800">
191
+ <h4 className="text-xs font-medium text-neutral-300 mb-2">How to use:</h4>
192
+ <ol className="text-xs text-neutral-500 space-y-1 list-decimal list-inside">
193
+ {type === 'npx' && (
194
+ <>
195
+ <li>Open Claude Desktop settings</li>
196
+ <li>Navigate to MCP Servers configuration</li>
197
+ <li>Paste the config above into your configuration file</li>
198
+ <li>Restart Claude Desktop</li>
199
+ </>
200
+ )}
201
+ {type === 'local' && (
202
+ <>
203
+ <li>Download the generated server file</li>
204
+ <li>Update the path in the config to match your file location</li>
205
+ <li>Paste into your Claude Desktop config</li>
206
+ <li>Restart Claude Desktop</li>
207
+ </>
208
+ )}
209
+ {type === 'python' && (
210
+ <>
211
+ <li>Download the Python server file</li>
212
+ <li>Install dependencies: <code className="bg-white/10 px-1 rounded">pip install mcp</code></li>
213
+ <li>Paste the config into your Claude Desktop config</li>
214
+ <li>Restart Claude Desktop</li>
215
+ </>
216
+ )}
217
+ </ol>
218
+ </div>
219
+ </div>
220
+ </TabsContent>
221
+ );
222
+ })}
223
+ </Tabs>
224
+ </div>
225
+ );
226
+ }