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,88 @@
1
+ /**
2
+ * Local Storage Hook with SSR Safety
3
+ * @copyright 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ 'use client';
8
+
9
+ import { useState, useEffect, useCallback } from 'react';
10
+ import { safeJsonParse } from '@/lib/utils';
11
+
12
+ export function useLocalStorage<T>(
13
+ key: string,
14
+ initialValue: T
15
+ ): [T, (value: T | ((prev: T) => T)) => void, () => void] {
16
+ // State to store our value
17
+ const [storedValue, setStoredValue] = useState<T>(initialValue);
18
+ const [isInitialized, setIsInitialized] = useState(false);
19
+
20
+ // Read from localStorage on mount
21
+ useEffect(() => {
22
+ if (typeof window === 'undefined') return;
23
+
24
+ try {
25
+ const item = window.localStorage.getItem(key);
26
+ if (item !== null) {
27
+ setStoredValue(safeJsonParse<T>(item, initialValue));
28
+ }
29
+ } catch (error) {
30
+ console.warn(`Error reading localStorage key "${key}":`, error);
31
+ }
32
+ setIsInitialized(true);
33
+ }, [key, initialValue]);
34
+
35
+ // Return a wrapped version of useState's setter function that persists to localStorage
36
+ const setValue = useCallback(
37
+ (value: T | ((prev: T) => T)) => {
38
+ try {
39
+ // Allow value to be a function so we have same API as useState
40
+ const valueToStore = value instanceof Function ? value(storedValue) : value;
41
+ setStoredValue(valueToStore);
42
+
43
+ if (typeof window !== 'undefined') {
44
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
45
+
46
+ // Dispatch storage event for other tabs
47
+ window.dispatchEvent(
48
+ new StorageEvent('storage', {
49
+ key,
50
+ newValue: JSON.stringify(valueToStore),
51
+ })
52
+ );
53
+ }
54
+ } catch (error) {
55
+ console.warn(`Error setting localStorage key "${key}":`, error);
56
+ }
57
+ },
58
+ [key, storedValue]
59
+ );
60
+
61
+ // Remove from localStorage
62
+ const removeValue = useCallback(() => {
63
+ try {
64
+ setStoredValue(initialValue);
65
+ if (typeof window !== 'undefined') {
66
+ window.localStorage.removeItem(key);
67
+ }
68
+ } catch (error) {
69
+ console.warn(`Error removing localStorage key "${key}":`, error);
70
+ }
71
+ }, [key, initialValue]);
72
+
73
+ // Listen for storage changes from other tabs
74
+ useEffect(() => {
75
+ if (typeof window === 'undefined') return;
76
+
77
+ const handleStorageChange = (e: StorageEvent) => {
78
+ if (e.key === key && e.newValue !== null) {
79
+ setStoredValue(safeJsonParse<T>(e.newValue, initialValue));
80
+ }
81
+ };
82
+
83
+ window.addEventListener('storage', handleStorageChange);
84
+ return () => window.removeEventListener('storage', handleStorageChange);
85
+ }, [key, initialValue]);
86
+
87
+ return [isInitialized ? storedValue : initialValue, setValue, removeValue];
88
+ }
@@ -0,0 +1,623 @@
1
+ /**
2
+ * useMcpClient Hook
3
+ *
4
+ * React hook that provides a clean interface to the MCP client
5
+ * with automatic lifecycle management and React state integration.
6
+ *
7
+ * @author nich (x.com/nichxbt | github.com/nirholas)
8
+ * @copyright 2024-2026 nich (nirholas)
9
+ * @license MIT
10
+ */
11
+
12
+ 'use client';
13
+
14
+ import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
15
+ import {
16
+ EnhancedMcpClient,
17
+ EnhancedMcpClientOptions,
18
+ McpClientEvents,
19
+ WebSocketTransport,
20
+ WebSocketTransportOptions,
21
+ } from '@/lib/mcp-client-enhanced';
22
+ import {
23
+ McpClient,
24
+ HttpTransport,
25
+ McpClientOptions,
26
+ McpClientState,
27
+ } from '@/lib/mcp-client';
28
+ import { McpTool, CallToolResult, ServerCapabilities, ServerInfo } from '@/lib/mcp-types';
29
+ import { McpError, formatMcpError } from '@/lib/mcp-errors';
30
+
31
+ // ============================================================================
32
+ // Types
33
+ // ============================================================================
34
+
35
+ /** MCP React Hooks - nich (x.com/nichxbt | github.com/nirholas) */
36
+ const _HOOKS_META = { author: 'nich', twitter: 'nichxbt', github: 'nirholas' } as const;
37
+
38
+ export interface UseMcpClientOptions {
39
+ /** Transport type */
40
+ transport: 'http' | 'websocket';
41
+ /** Endpoint URL */
42
+ endpoint: string;
43
+ /** Additional headers for HTTP transport */
44
+ headers?: Record<string, string>;
45
+ /** Client options */
46
+ clientOptions?: Partial<McpClientOptions | EnhancedMcpClientOptions>;
47
+ /** Auto-connect on mount */
48
+ autoConnect?: boolean;
49
+ /** Reconnect on error */
50
+ autoReconnect?: boolean;
51
+ /** Log events to console */
52
+ debug?: boolean;
53
+ }
54
+
55
+ export interface McpClientHookState {
56
+ /** Current connection state */
57
+ state: McpClientState;
58
+ /** Whether client is connected and ready */
59
+ isReady: boolean;
60
+ /** Whether client is connecting */
61
+ isConnecting: boolean;
62
+ /** Whether a tool call is in progress */
63
+ isExecuting: boolean;
64
+ /** Available tools */
65
+ tools: McpTool[];
66
+ /** Server capabilities */
67
+ capabilities: ServerCapabilities | null;
68
+ /** Server info */
69
+ serverInfo: ServerInfo | null;
70
+ /** Last error */
71
+ error: string | null;
72
+ /** Execution logs */
73
+ logs: McpClientLog[];
74
+ }
75
+
76
+ export interface McpClientLog {
77
+ id: string;
78
+ timestamp: Date;
79
+ type: 'info' | 'success' | 'error' | 'debug';
80
+ message: string;
81
+ data?: unknown;
82
+ }
83
+
84
+ export interface UseMcpClientReturn extends McpClientHookState {
85
+ /** Connect to the MCP server */
86
+ connect: () => Promise<void>;
87
+ /** Disconnect from the MCP server */
88
+ disconnect: () => Promise<void>;
89
+ /** Refresh the tools list */
90
+ refreshTools: () => Promise<McpTool[]>;
91
+ /** Execute a tool */
92
+ executeTool: (name: string, params?: Record<string, unknown>) => Promise<CallToolResult>;
93
+ /** Clear logs */
94
+ clearLogs: () => void;
95
+ /** Clear error */
96
+ clearError: () => void;
97
+ }
98
+
99
+ // ============================================================================
100
+ // Hook Implementation
101
+ // ============================================================================
102
+
103
+ function generateLogId(): string {
104
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
105
+ }
106
+
107
+ export function useMcpClient(options: UseMcpClientOptions): UseMcpClientReturn {
108
+ const {
109
+ transport: transportType,
110
+ endpoint,
111
+ headers,
112
+ clientOptions,
113
+ autoConnect = false,
114
+ autoReconnect = true,
115
+ debug = false,
116
+ } = options;
117
+
118
+ // State
119
+ const [state, setState] = useState<McpClientState>('disconnected');
120
+ const [tools, setTools] = useState<McpTool[]>([]);
121
+ const [capabilities, setCapabilities] = useState<ServerCapabilities | null>(null);
122
+ const [serverInfo, setServerInfo] = useState<ServerInfo | null>(null);
123
+ const [error, setError] = useState<string | null>(null);
124
+ const [isExecuting, setIsExecuting] = useState(false);
125
+ const [logs, setLogs] = useState<McpClientLog[]>([]);
126
+
127
+ // Refs
128
+ const clientRef = useRef<McpClient | EnhancedMcpClient | null>(null);
129
+ const mountedRef = useRef(true);
130
+
131
+ // Derived state
132
+ const isReady = state === 'ready';
133
+ const isConnecting = state === 'connecting' || state === 'initializing';
134
+
135
+ // Logging
136
+ const addLog = useCallback((
137
+ type: McpClientLog['type'],
138
+ message: string,
139
+ data?: unknown
140
+ ) => {
141
+ if (!mountedRef.current) return;
142
+
143
+ const log: McpClientLog = {
144
+ id: generateLogId(),
145
+ timestamp: new Date(),
146
+ type,
147
+ message,
148
+ data,
149
+ };
150
+
151
+ setLogs(prev => [...prev.slice(-99), log]); // Keep last 100 logs
152
+
153
+ if (debug) {
154
+ const prefix = type === 'error' ? '❌' : type === 'success' ? '✅' : type === 'debug' ? '🔍' : 'ℹ️';
155
+ console.log(`[MCP Client] ${prefix} ${message}`, data ?? '');
156
+ }
157
+ }, [debug]);
158
+
159
+ // Create client
160
+ const createClient = useCallback(() => {
161
+ if (transportType === 'websocket') {
162
+ const wsTransport = new WebSocketTransport({
163
+ url: endpoint,
164
+ autoReconnect,
165
+ });
166
+
167
+ const client = new EnhancedMcpClient(wsTransport, {
168
+ ...clientOptions,
169
+ autoReconnect,
170
+ });
171
+
172
+ // Set up event listeners for enhanced client
173
+ client.on<McpClientEvents['state:change']>('state:change', ({ current }) => {
174
+ if (mountedRef.current) {
175
+ setState(current);
176
+ addLog('debug', `State changed to: ${current}`);
177
+ }
178
+ });
179
+
180
+ client.on<McpClientEvents['connected']>('connected', ({ serverInfo: info, capabilities: caps }) => {
181
+ if (mountedRef.current) {
182
+ setServerInfo(info);
183
+ setCapabilities(caps);
184
+ addLog('success', `Connected to ${info.name} v${info.version}`);
185
+ }
186
+ });
187
+
188
+ client.on<McpClientEvents['disconnected']>('disconnected', ({ reason }) => {
189
+ if (mountedRef.current) {
190
+ addLog('info', `Disconnected: ${reason}`);
191
+ }
192
+ });
193
+
194
+ client.on<McpClientEvents['error']>('error', ({ error: err }) => {
195
+ if (mountedRef.current) {
196
+ setError(formatMcpError(err));
197
+ addLog('error', formatMcpError(err));
198
+ }
199
+ });
200
+
201
+ client.on<McpClientEvents['tools:changed']>('tools:changed', ({ tools: newTools }) => {
202
+ if (mountedRef.current) {
203
+ setTools(newTools);
204
+ addLog('info', `Tools updated: ${newTools.length} tools available`);
205
+ }
206
+ });
207
+
208
+ return client;
209
+ } else {
210
+ const httpTransport = new HttpTransport({
211
+ endpoint,
212
+ headers,
213
+ timeout: clientOptions?.timeout,
214
+ });
215
+
216
+ return new McpClient(httpTransport, {
217
+ ...clientOptions,
218
+ onOutput: (data) => addLog('info', data),
219
+ onError: (err) => {
220
+ setError(err);
221
+ addLog('error', err);
222
+ },
223
+ onNotification: (method, params) => {
224
+ addLog('debug', `Notification: ${method}`, params);
225
+ },
226
+ });
227
+ }
228
+ }, [transportType, endpoint, headers, clientOptions, autoReconnect, addLog]);
229
+
230
+ // Connect
231
+ const connect = useCallback(async () => {
232
+ if (clientRef.current && (state === 'ready' || state === 'connecting')) {
233
+ return;
234
+ }
235
+
236
+ try {
237
+ setError(null);
238
+ addLog('info', 'Connecting...');
239
+
240
+ if (!clientRef.current) {
241
+ clientRef.current = createClient();
242
+ }
243
+
244
+ // For non-enhanced client, manually track state
245
+ if (!(clientRef.current instanceof EnhancedMcpClient)) {
246
+ setState('connecting');
247
+ }
248
+
249
+ await clientRef.current.connect();
250
+
251
+ if (mountedRef.current) {
252
+ // For non-enhanced client, manually update state
253
+ if (!(clientRef.current instanceof EnhancedMcpClient)) {
254
+ setState('ready');
255
+ if (clientRef.current.capabilities) {
256
+ setCapabilities(clientRef.current.capabilities);
257
+ }
258
+ }
259
+
260
+ // Fetch tools
261
+ const fetchedTools = await clientRef.current.listTools();
262
+ if (mountedRef.current) {
263
+ setTools(fetchedTools);
264
+ addLog('success', `Loaded ${fetchedTools.length} tools`);
265
+ }
266
+ }
267
+ } catch (err) {
268
+ if (mountedRef.current) {
269
+ const errorMessage = err instanceof McpError ? formatMcpError(err) : String(err);
270
+ setError(errorMessage);
271
+ setState('error');
272
+ addLog('error', `Connection failed: ${errorMessage}`);
273
+ }
274
+ throw err;
275
+ }
276
+ }, [state, createClient, addLog]);
277
+
278
+ // Disconnect
279
+ const disconnect = useCallback(async () => {
280
+ if (!clientRef.current) return;
281
+
282
+ try {
283
+ addLog('info', 'Disconnecting...');
284
+ await clientRef.current.disconnect();
285
+
286
+ if (mountedRef.current) {
287
+ setState('disconnected');
288
+ setTools([]);
289
+ setCapabilities(null);
290
+ setServerInfo(null);
291
+ addLog('success', 'Disconnected');
292
+ }
293
+ } catch (err) {
294
+ addLog('error', `Disconnect error: ${err}`);
295
+ }
296
+ }, [addLog]);
297
+
298
+ // Refresh tools
299
+ const refreshTools = useCallback(async (): Promise<McpTool[]> => {
300
+ if (!clientRef.current || state !== 'ready') {
301
+ throw new Error('Client not connected');
302
+ }
303
+
304
+ addLog('info', 'Refreshing tools...');
305
+
306
+ // For enhanced client, force refresh
307
+ const fetchedTools = clientRef.current instanceof EnhancedMcpClient
308
+ ? await clientRef.current.listTools(true)
309
+ : await clientRef.current.listTools();
310
+
311
+ if (mountedRef.current) {
312
+ setTools(fetchedTools);
313
+ addLog('success', `Refreshed: ${fetchedTools.length} tools`);
314
+ }
315
+
316
+ return fetchedTools;
317
+ }, [state, addLog]);
318
+
319
+ // Execute tool
320
+ const executeTool = useCallback(async (
321
+ name: string,
322
+ params?: Record<string, unknown>
323
+ ): Promise<CallToolResult> => {
324
+ if (!clientRef.current || state !== 'ready') {
325
+ throw new Error('Client not connected');
326
+ }
327
+
328
+ setIsExecuting(true);
329
+ addLog('info', `Executing: ${name}`, params);
330
+ const startTime = Date.now();
331
+
332
+ try {
333
+ const result = await clientRef.current.callTool(name, params);
334
+ const duration = Date.now() - startTime;
335
+
336
+ if (mountedRef.current) {
337
+ if (result.isError) {
338
+ addLog('error', `Tool error: ${name} (${duration}ms)`, result);
339
+ } else {
340
+ addLog('success', `Completed: ${name} (${duration}ms)`, result);
341
+ }
342
+ }
343
+
344
+ return result;
345
+ } catch (err) {
346
+ const errorMessage = err instanceof McpError ? formatMcpError(err) : String(err);
347
+ addLog('error', `Execution failed: ${name} - ${errorMessage}`);
348
+ throw err;
349
+ } finally {
350
+ if (mountedRef.current) {
351
+ setIsExecuting(false);
352
+ }
353
+ }
354
+ }, [state, addLog]);
355
+
356
+ // Clear logs
357
+ const clearLogs = useCallback(() => {
358
+ setLogs([]);
359
+ }, []);
360
+
361
+ // Clear error
362
+ const clearError = useCallback(() => {
363
+ setError(null);
364
+ }, []);
365
+
366
+ // Auto-connect on mount
367
+ useEffect(() => {
368
+ if (autoConnect) {
369
+ connect().catch(() => {
370
+ // Error already handled in connect()
371
+ });
372
+ }
373
+
374
+ return () => {
375
+ mountedRef.current = false;
376
+ if (clientRef.current) {
377
+ clientRef.current.disconnect().catch(() => {});
378
+ }
379
+ };
380
+ }, [autoConnect]); // Only run on mount, not when connect changes
381
+
382
+ return {
383
+ state,
384
+ isReady,
385
+ isConnecting,
386
+ isExecuting,
387
+ tools,
388
+ capabilities,
389
+ serverInfo,
390
+ error,
391
+ logs,
392
+ connect,
393
+ disconnect,
394
+ refreshTools,
395
+ executeTool,
396
+ clearLogs,
397
+ clearError,
398
+ };
399
+ }
400
+
401
+ // ============================================================================
402
+ // Convenience Hooks
403
+ // ============================================================================
404
+
405
+ /**
406
+ * Hook for connecting to an MCP server via HTTP
407
+ */
408
+ export function useHttpMcpClient(
409
+ endpoint: string,
410
+ options?: Omit<UseMcpClientOptions, 'transport' | 'endpoint'>
411
+ ): UseMcpClientReturn {
412
+ return useMcpClient({
413
+ transport: 'http',
414
+ endpoint,
415
+ ...options,
416
+ });
417
+ }
418
+
419
+ /**
420
+ * Hook for connecting to an MCP server via WebSocket
421
+ */
422
+ export function useWebSocketMcpClient(
423
+ endpoint: string,
424
+ options?: Omit<UseMcpClientOptions, 'transport' | 'endpoint'>
425
+ ): UseMcpClientReturn {
426
+ return useMcpClient({
427
+ transport: 'websocket',
428
+ endpoint,
429
+ ...options,
430
+ });
431
+ }
432
+
433
+ /**
434
+ * Hook for the playground API-based MCP execution
435
+ */
436
+ export function usePlaygroundMcpClient(
437
+ generatedCode: string | null,
438
+ options?: { autoConnect?: boolean; debug?: boolean }
439
+ ): UseMcpClientReturn & { sessionId: string | null } {
440
+ const [sessionId, setSessionId] = useState<string | null>(null);
441
+ const [state, setState] = useState<McpClientState>('disconnected');
442
+ const [tools, setTools] = useState<McpTool[]>([]);
443
+ const [error, setError] = useState<string | null>(null);
444
+ const [isExecuting, setIsExecuting] = useState(false);
445
+ const [logs, setLogs] = useState<McpClientLog[]>([]);
446
+
447
+ const mountedRef = useRef(true);
448
+
449
+ const addLog = useCallback((
450
+ type: McpClientLog['type'],
451
+ message: string,
452
+ data?: unknown
453
+ ) => {
454
+ if (!mountedRef.current) return;
455
+ setLogs(prev => [...prev.slice(-99), {
456
+ id: generateLogId(),
457
+ timestamp: new Date(),
458
+ type,
459
+ message,
460
+ data,
461
+ }]);
462
+ }, []);
463
+
464
+ const connect = useCallback(async () => {
465
+ if (!generatedCode) {
466
+ setError('No generated code provided');
467
+ return;
468
+ }
469
+
470
+ setState('connecting');
471
+ setError(null);
472
+ addLog('info', 'Connecting to playground server...');
473
+
474
+ try {
475
+ const response = await fetch('/api/playground/connect', {
476
+ method: 'POST',
477
+ headers: { 'Content-Type': 'application/json' },
478
+ body: JSON.stringify({ generatedCode }),
479
+ });
480
+
481
+ if (!response.ok) {
482
+ const data = await response.json().catch(() => ({}));
483
+ throw new Error(data.error || 'Connection failed');
484
+ }
485
+
486
+ const data = await response.json();
487
+
488
+ if (mountedRef.current) {
489
+ setSessionId(data.sessionId);
490
+ setTools(data.tools || []);
491
+ setState('ready');
492
+ addLog('success', `Connected! Session: ${data.sessionId}`);
493
+ }
494
+ } catch (err) {
495
+ if (mountedRef.current) {
496
+ const msg = err instanceof Error ? err.message : 'Connection failed';
497
+ setError(msg);
498
+ setState('error');
499
+ addLog('error', msg);
500
+ }
501
+ }
502
+ }, [generatedCode, addLog]);
503
+
504
+ const disconnect = useCallback(async () => {
505
+ if (!sessionId) return;
506
+
507
+ addLog('info', 'Disconnecting...');
508
+
509
+ try {
510
+ await fetch('/api/playground/disconnect', {
511
+ method: 'POST',
512
+ headers: { 'Content-Type': 'application/json' },
513
+ body: JSON.stringify({ sessionId }),
514
+ });
515
+ } catch {
516
+ // Best effort
517
+ }
518
+
519
+ if (mountedRef.current) {
520
+ setSessionId(null);
521
+ setTools([]);
522
+ setState('disconnected');
523
+ addLog('success', 'Disconnected');
524
+ }
525
+ }, [sessionId, addLog]);
526
+
527
+ const executeTool = useCallback(async (
528
+ name: string,
529
+ params?: Record<string, unknown>
530
+ ): Promise<CallToolResult> => {
531
+ if (!sessionId) {
532
+ throw new Error('Not connected');
533
+ }
534
+
535
+ setIsExecuting(true);
536
+ addLog('info', `Executing: ${name}`, params);
537
+ const startTime = Date.now();
538
+
539
+ try {
540
+ const response = await fetch('/api/playground/execute', {
541
+ method: 'POST',
542
+ headers: { 'Content-Type': 'application/json' },
543
+ body: JSON.stringify({
544
+ sessionId,
545
+ toolName: name,
546
+ toolParams: params || {},
547
+ }),
548
+ });
549
+
550
+ const data = await response.json();
551
+ const duration = Date.now() - startTime;
552
+
553
+ if (!response.ok || !data.success) {
554
+ addLog('error', `Failed: ${name} - ${data.error}`, data);
555
+ return {
556
+ content: [{ type: 'text', text: data.error || 'Execution failed' }],
557
+ isError: true,
558
+ };
559
+ }
560
+
561
+ addLog('success', `Completed: ${name} (${duration}ms)`, data.result);
562
+
563
+ return {
564
+ content: [{
565
+ type: 'text',
566
+ text: typeof data.result === 'string'
567
+ ? data.result
568
+ : JSON.stringify(data.result, null, 2)
569
+ }],
570
+ isError: false,
571
+ };
572
+ } catch (err) {
573
+ const msg = err instanceof Error ? err.message : 'Execution failed';
574
+ addLog('error', `Error: ${name} - ${msg}`);
575
+ throw err;
576
+ } finally {
577
+ if (mountedRef.current) {
578
+ setIsExecuting(false);
579
+ }
580
+ }
581
+ }, [sessionId, addLog]);
582
+
583
+ const refreshTools = useCallback(async (): Promise<McpTool[]> => {
584
+ if (!sessionId) throw new Error('Not connected');
585
+
586
+ const response = await fetch(`/api/playground/tools?sessionId=${sessionId}`);
587
+ const data = await response.json();
588
+
589
+ if (mountedRef.current && data.tools) {
590
+ setTools(data.tools);
591
+ }
592
+
593
+ return data.tools || [];
594
+ }, [sessionId]);
595
+
596
+ useEffect(() => {
597
+ if (options?.autoConnect && generatedCode) {
598
+ connect();
599
+ }
600
+ return () => {
601
+ mountedRef.current = false;
602
+ };
603
+ }, []);
604
+
605
+ return {
606
+ state,
607
+ isReady: state === 'ready',
608
+ isConnecting: state === 'connecting',
609
+ isExecuting,
610
+ tools,
611
+ capabilities: null,
612
+ serverInfo: null,
613
+ error,
614
+ logs,
615
+ sessionId,
616
+ connect,
617
+ disconnect,
618
+ refreshTools,
619
+ executeTool,
620
+ clearLogs: () => setLogs([]),
621
+ clearError: () => setError(null),
622
+ };
623
+ }