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,1173 @@
1
+ /**
2
+ * Playground Hooks Type Definitions
3
+ * Shared types for MCP playground React hooks
4
+ * @copyright 2024-2026 nirholas
5
+ * @license MIT
6
+ */
7
+
8
+ // ============================================================================
9
+ // Constants
10
+ // ============================================================================
11
+
12
+ /** Default request timeout in milliseconds */
13
+ export const DEFAULT_TIMEOUT = 30000;
14
+
15
+ /** Default heartbeat interval in milliseconds */
16
+ export const DEFAULT_HEARTBEAT_INTERVAL = 30000;
17
+
18
+ /** Default debounce delay for reconnection */
19
+ export const DEFAULT_RECONNECT_DEBOUNCE = 1000;
20
+
21
+ /** Default cache TTL in milliseconds */
22
+ export const DEFAULT_CACHE_TTL = 60000;
23
+
24
+ // ============================================================================
25
+ // Transport Configuration Types
26
+ // ============================================================================
27
+
28
+ /**
29
+ * Supported transport types for MCP connections
30
+ */
31
+ export type TransportType = 'stdio' | 'http' | 'websocket' | 'sse';
32
+
33
+ /**
34
+ * Base transport configuration
35
+ */
36
+ export interface BaseTransportConfig {
37
+ type: TransportType;
38
+ }
39
+
40
+ /**
41
+ * HTTP/SSE transport configuration
42
+ */
43
+ export interface HttpTransportConfig extends BaseTransportConfig {
44
+ type: 'http' | 'sse';
45
+ url: string;
46
+ headers?: Record<string, string>;
47
+ timeout?: number;
48
+ }
49
+
50
+ /**
51
+ * WebSocket transport configuration
52
+ */
53
+ export interface WebSocketTransportConfig extends BaseTransportConfig {
54
+ type: 'websocket';
55
+ url: string;
56
+ protocols?: string[];
57
+ headers?: Record<string, string>;
58
+ }
59
+
60
+ /**
61
+ * Stdio transport configuration (for server-side execution)
62
+ */
63
+ export interface StdioTransportConfig extends BaseTransportConfig {
64
+ type: 'stdio';
65
+ command: string;
66
+ args?: string[];
67
+ env?: Record<string, string>;
68
+ cwd?: string;
69
+ }
70
+
71
+ /**
72
+ * Union of all transport configurations
73
+ */
74
+ export type TransportConfig =
75
+ | HttpTransportConfig
76
+ | WebSocketTransportConfig
77
+ | StdioTransportConfig;
78
+
79
+ // ============================================================================
80
+ // Connection Types
81
+ // ============================================================================
82
+
83
+ /**
84
+ * Connection status states
85
+ */
86
+ export type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
87
+
88
+ /**
89
+ * MCP Server capabilities
90
+ */
91
+ export interface McpCapabilities {
92
+ tools?: {
93
+ listChanged?: boolean;
94
+ };
95
+ resources?: {
96
+ subscribe?: boolean;
97
+ listChanged?: boolean;
98
+ };
99
+ prompts?: {
100
+ listChanged?: boolean;
101
+ };
102
+ logging?: Record<string, unknown>;
103
+ experimental?: Record<string, unknown>;
104
+ }
105
+
106
+ /**
107
+ * MCP Server information
108
+ */
109
+ export interface ServerInfo {
110
+ name: string;
111
+ version: string;
112
+ protocolVersion?: string;
113
+ instructions?: string;
114
+ }
115
+
116
+ /**
117
+ * Session information after successful connection
118
+ */
119
+ export interface SessionInfo {
120
+ sessionId: string;
121
+ serverInfo: ServerInfo;
122
+ capabilities: McpCapabilities;
123
+ connectedAt: Date;
124
+ }
125
+
126
+ // ============================================================================
127
+ // Tool Types
128
+ // ============================================================================
129
+
130
+ /**
131
+ * JSON Schema property for tool input validation
132
+ */
133
+ export interface JsonSchemaProperty {
134
+ type: string;
135
+ description?: string;
136
+ enum?: (string | number | boolean)[];
137
+ default?: unknown;
138
+ items?: JsonSchemaProperty;
139
+ properties?: Record<string, JsonSchemaProperty>;
140
+ required?: string[];
141
+ minimum?: number;
142
+ maximum?: number;
143
+ minLength?: number;
144
+ maxLength?: number;
145
+ pattern?: string;
146
+ format?: string;
147
+ }
148
+
149
+ /**
150
+ * Tool input schema
151
+ */
152
+ export interface ToolInputSchema {
153
+ type: 'object';
154
+ properties?: Record<string, JsonSchemaProperty>;
155
+ required?: string[];
156
+ additionalProperties?: boolean;
157
+ }
158
+
159
+ /**
160
+ * MCP Tool definition
161
+ */
162
+ export interface McpTool {
163
+ name: string;
164
+ description?: string;
165
+ inputSchema: ToolInputSchema;
166
+ }
167
+
168
+ /**
169
+ * Text content in tool response
170
+ */
171
+ export interface TextContent {
172
+ type: 'text';
173
+ text: string;
174
+ }
175
+
176
+ /**
177
+ * Image content in tool response
178
+ */
179
+ export interface ImageContent {
180
+ type: 'image';
181
+ data: string;
182
+ mimeType: string;
183
+ }
184
+
185
+ /**
186
+ * Resource content embedded in tool response
187
+ */
188
+ export interface EmbeddedResourceContent {
189
+ type: 'resource';
190
+ resource: {
191
+ uri: string;
192
+ mimeType?: string;
193
+ text?: string;
194
+ blob?: string;
195
+ };
196
+ }
197
+
198
+ /**
199
+ * Tool content types
200
+ */
201
+ export type ToolContent = TextContent | ImageContent | EmbeddedResourceContent;
202
+
203
+ /**
204
+ * Result from calling a tool
205
+ */
206
+ export interface ToolCallResult {
207
+ content: ToolContent[];
208
+ isError?: boolean;
209
+ }
210
+
211
+ /**
212
+ * Execution status for async operations
213
+ */
214
+ export type ExecutionStatus = 'pending' | 'running' | 'success' | 'error';
215
+
216
+ /**
217
+ * Tool execution record
218
+ */
219
+ export interface ToolExecution {
220
+ id: string;
221
+ toolName: string;
222
+ params: Record<string, unknown>;
223
+ status: ExecutionStatus;
224
+ result?: ToolCallResult;
225
+ error?: string;
226
+ startedAt: Date;
227
+ completedAt?: Date;
228
+ executionTime?: number;
229
+ logs: string[];
230
+ }
231
+
232
+ // ============================================================================
233
+ // Resource Types
234
+ // ============================================================================
235
+
236
+ /**
237
+ * MCP Resource definition
238
+ */
239
+ export interface McpResource {
240
+ uri: string;
241
+ name: string;
242
+ description?: string;
243
+ mimeType?: string;
244
+ }
245
+
246
+ /**
247
+ * Resource content
248
+ */
249
+ export interface ResourceContent {
250
+ uri: string;
251
+ mimeType?: string;
252
+ text?: string;
253
+ blob?: string;
254
+ }
255
+
256
+ /**
257
+ * Resource contents wrapper
258
+ */
259
+ export interface ResourceContents {
260
+ contents: ResourceContent[];
261
+ }
262
+
263
+ /**
264
+ * Resource read status
265
+ */
266
+ export type ResourceReadStatus = 'pending' | 'loading' | 'success' | 'error';
267
+
268
+ /**
269
+ * Resource read record
270
+ */
271
+ export interface ResourceRead {
272
+ id: string;
273
+ uri: string;
274
+ status: ResourceReadStatus;
275
+ contents?: ResourceContents;
276
+ error?: string;
277
+ readAt?: Date;
278
+ }
279
+
280
+ // ============================================================================
281
+ // Prompt Types
282
+ // ============================================================================
283
+
284
+ /**
285
+ * Prompt argument definition
286
+ */
287
+ export interface PromptArgument {
288
+ name: string;
289
+ description?: string;
290
+ required?: boolean;
291
+ }
292
+
293
+ /**
294
+ * MCP Prompt definition
295
+ */
296
+ export interface McpPrompt {
297
+ name: string;
298
+ description?: string;
299
+ arguments?: PromptArgument[];
300
+ }
301
+
302
+ /**
303
+ * Prompt message role
304
+ */
305
+ export type PromptMessageRole = 'user' | 'assistant';
306
+
307
+ /**
308
+ * Prompt message
309
+ */
310
+ export interface PromptMessage {
311
+ role: PromptMessageRole;
312
+ content: TextContent | ImageContent | EmbeddedResourceContent;
313
+ }
314
+
315
+ /**
316
+ * Prompt execution status
317
+ */
318
+ export type PromptExecutionStatus = 'pending' | 'loading' | 'executing' | 'success' | 'error';
319
+
320
+ /**
321
+ * Prompt execution record
322
+ */
323
+ export interface PromptExecution {
324
+ id: string;
325
+ name: string;
326
+ /** Alias for name (for backwards compatibility) */
327
+ promptName?: string;
328
+ args?: Record<string, string>;
329
+ /** Alias for args (for backwards compatibility) */
330
+ arguments?: Record<string, string>;
331
+ status: PromptExecutionStatus;
332
+ messages?: PromptMessage[];
333
+ description?: string;
334
+ error?: string;
335
+ executedAt?: Date;
336
+ /** When execution started */
337
+ startedAt?: Date;
338
+ /** When execution completed */
339
+ completedAt?: Date;
340
+ }
341
+
342
+ // ============================================================================
343
+ // Execution History Types
344
+ // ============================================================================
345
+
346
+ /**
347
+ * Type of execution entry
348
+ */
349
+ export type ExecutionType = 'tool' | 'resource' | 'prompt';
350
+
351
+ /**
352
+ * Execution history entry
353
+ */
354
+ export interface ExecutionHistoryEntry {
355
+ id: string;
356
+ type: ExecutionType;
357
+ name: string;
358
+ params?: unknown;
359
+ result?: unknown;
360
+ error?: string;
361
+ success: boolean;
362
+ timestamp: Date;
363
+ executionTime?: number;
364
+ }
365
+
366
+ // ============================================================================
367
+ // API Response Types
368
+ // ============================================================================
369
+
370
+ /**
371
+ * Standard API response wrapper
372
+ */
373
+ export interface ApiResponse<T> {
374
+ success: boolean;
375
+ data?: T;
376
+ error?: string;
377
+ message?: string;
378
+ }
379
+
380
+ /**
381
+ * Connect API response
382
+ */
383
+ export interface ConnectResponse {
384
+ sessionId: string;
385
+ serverInfo: ServerInfo;
386
+ capabilities: McpCapabilities;
387
+ }
388
+
389
+ /**
390
+ * List tools API response
391
+ */
392
+ export interface ListToolsResponse {
393
+ tools: McpTool[];
394
+ }
395
+
396
+ /**
397
+ * Execute tool API response
398
+ */
399
+ export interface ExecuteToolResponse {
400
+ result: ToolCallResult;
401
+ executionTime: number;
402
+ logs?: string[];
403
+ }
404
+
405
+ /**
406
+ * List resources API response
407
+ */
408
+ export interface ListResourcesResponse {
409
+ resources: McpResource[];
410
+ }
411
+
412
+ /**
413
+ * Read resource API response
414
+ */
415
+ export interface ReadResourceResponse {
416
+ contents: ResourceContents;
417
+ }
418
+
419
+ /**
420
+ * List prompts API response
421
+ */
422
+ export interface ListPromptsResponse {
423
+ prompts: McpPrompt[];
424
+ }
425
+
426
+ /**
427
+ * Get prompt API response
428
+ */
429
+ export interface GetPromptResponse {
430
+ messages: PromptMessage[];
431
+ description?: string;
432
+ }
433
+
434
+ // ============================================================================
435
+ // Hook Return Types
436
+ // ============================================================================
437
+
438
+ /**
439
+ * Common hook options shared across all hooks
440
+ */
441
+ export interface CommonHookOptions {
442
+ /** Enable debug logging */
443
+ debug?: boolean;
444
+ /** Request timeout in ms */
445
+ timeout?: number;
446
+ /** Event emitter for subscribing to events outside React */
447
+ eventEmitter?: McpEventEmitter;
448
+ }
449
+
450
+ /**
451
+ * Options for useMcpConnection hook
452
+ */
453
+ export interface UseMcpConnectionOptions extends CommonHookOptions {
454
+ autoConnect?: boolean;
455
+ onConnect?: (session: SessionInfo) => void;
456
+ onDisconnect?: () => void;
457
+ onError?: (error: Error) => void;
458
+ /** Heartbeat interval in ms (0 to disable) */
459
+ heartbeatInterval?: number;
460
+ /** Debounce delay for reconnection in ms */
461
+ reconnectDebounce?: number;
462
+ }
463
+
464
+ /**
465
+ * Return type for useMcpConnection hook
466
+ */
467
+ export interface UseMcpConnectionReturn {
468
+ // State
469
+ status: ConnectionStatus;
470
+ sessionId: string | null;
471
+ capabilities: McpCapabilities | null;
472
+ serverInfo: ServerInfo | null;
473
+ error: string | null;
474
+ /** Last successful heartbeat timestamp */
475
+ lastHeartbeat: Date | null;
476
+ /** Server URL (for HTTP/SSE transports) */
477
+ serverUrl: string | null;
478
+
479
+ // Actions
480
+ connect: (config: TransportConfig) => Promise<void>;
481
+ disconnect: () => Promise<void>;
482
+ reconnect: () => Promise<void>;
483
+ clearError: () => void;
484
+ /** Manually trigger a heartbeat */
485
+ heartbeat: () => Promise<boolean>;
486
+ }
487
+
488
+ /**
489
+ * Options for useMcpTools hook
490
+ */
491
+ export interface UseMcpToolsOptions extends CommonHookOptions {
492
+ sessionId: string | null;
493
+ autoLoad?: boolean;
494
+ /** Cache TTL in ms (0 to disable caching) */
495
+ cacheTtl?: number;
496
+ }
497
+
498
+ /**
499
+ * Return type for useMcpTools hook
500
+ */
501
+ export interface UseMcpToolsReturn {
502
+ // State
503
+ tools: McpTool[];
504
+ isLoading: boolean;
505
+ error: string | null;
506
+ executions: ToolExecution[];
507
+ currentExecution: ToolExecution | null;
508
+ /** Whether data is from cache */
509
+ isStale: boolean;
510
+
511
+ // Actions
512
+ loadTools: () => Promise<void>;
513
+ /** Force refresh, bypassing cache */
514
+ refreshTools: () => Promise<void>;
515
+ executeTool: (name: string, params: Record<string, unknown>) => Promise<ToolExecution>;
516
+ /** Execute multiple tools in parallel */
517
+ executeBatch: (requests: BatchToolRequest[], options?: BatchExecutionOptions) => Promise<BatchToolResult[]>;
518
+ cancelExecution: (id: string) => void;
519
+ clearExecutions: () => void;
520
+ clearError: () => void;
521
+ }
522
+
523
+ /**
524
+ * Options for useMcpResources hook
525
+ */
526
+ export interface UseMcpResourcesOptions extends CommonHookOptions {
527
+ sessionId: string | null;
528
+ autoLoad?: boolean;
529
+ /** Cache TTL in ms (0 to disable caching) */
530
+ cacheTtl?: number;
531
+ }
532
+
533
+ /**
534
+ * Return type for useMcpResources hook
535
+ */
536
+ export interface UseMcpResourcesReturn {
537
+ // State
538
+ resources: McpResource[];
539
+ isLoading: boolean;
540
+ error: string | null;
541
+ reads: ResourceRead[];
542
+ /** Whether data is from cache */
543
+ isStale: boolean;
544
+
545
+ // Actions
546
+ loadResources: () => Promise<void>;
547
+ /** Force refresh, bypassing cache */
548
+ refreshResources: () => Promise<void>;
549
+ readResource: (uri: string) => Promise<ResourceRead>;
550
+ clearReads: () => void;
551
+ clearError: () => void;
552
+ }
553
+
554
+ /**
555
+ * Options for useMcpPrompts hook
556
+ */
557
+ export interface UseMcpPromptsOptions extends CommonHookOptions {
558
+ sessionId: string | null;
559
+ autoLoad?: boolean;
560
+ /** Cache TTL in ms (0 to disable caching) */
561
+ cacheTtl?: number;
562
+ }
563
+
564
+ /**
565
+ * Return type for useMcpPrompts hook
566
+ */
567
+ export interface UseMcpPromptsReturn {
568
+ // State
569
+ prompts: McpPrompt[];
570
+ isLoading: boolean;
571
+ error: string | null;
572
+ executions: PromptExecution[];
573
+ /** Whether data is from cache */
574
+ isStale: boolean;
575
+
576
+ // Actions
577
+ loadPrompts: () => Promise<void>;
578
+ /** Force refresh, bypassing cache */
579
+ refreshPrompts: () => Promise<void>;
580
+ getPrompt: (name: string, args?: Record<string, string>) => Promise<PromptExecution>;
581
+ /** Execute a prompt (alias for getPrompt) */
582
+ executePrompt: (name: string, args?: Record<string, string>) => Promise<PromptExecution>;
583
+ clearExecutions: () => void;
584
+ clearError: () => void;
585
+ /** Get messages from last successful execution */
586
+ getLastMessages: () => PromptMessage[] | null;
587
+ }
588
+
589
+ /**
590
+ * Return type for useExecutionHistory hook
591
+ */
592
+ export interface UseExecutionHistoryReturn {
593
+ history: ExecutionHistoryEntry[];
594
+ add: (entry: Omit<ExecutionHistoryEntry, 'id' | 'timestamp'>) => void;
595
+ addExecution: (execution: ToolExecution) => void;
596
+ addResourceRead: (read: ResourceRead) => void;
597
+ addPromptExecution: (execution: PromptExecution) => void;
598
+ clear: () => void;
599
+ clearHistory: () => void;
600
+ getByType: (type: ExecutionType) => ExecutionHistoryEntry[];
601
+ getByStatus: (success: boolean) => ExecutionHistoryEntry[];
602
+ export: () => string;
603
+ exportHistory: () => string;
604
+ import: (json: string) => void;
605
+ importHistory: (json: string) => void;
606
+ }
607
+
608
+ /**
609
+ * Options for usePlayground hook
610
+ */
611
+ export interface UsePlaygroundOptions extends CommonHookOptions {
612
+ initialCode?: string;
613
+ initialTransport?: TransportConfig;
614
+ /** Auto connect on mount */
615
+ autoConnect?: boolean;
616
+ /** Persist history to localStorage */
617
+ persistHistory?: boolean;
618
+ /** Custom storage key for history */
619
+ historyKey?: string;
620
+ /** Cache TTL in ms */
621
+ cacheTtl?: number;
622
+ /** Heartbeat interval in ms */
623
+ heartbeatInterval?: number;
624
+ /** Callback when connected */
625
+ onConnect?: (sessionId: string) => void;
626
+ /** Callback when disconnected */
627
+ onDisconnect?: () => void;
628
+ /** Callback on error */
629
+ onError?: (error: Error) => void;
630
+ }
631
+
632
+ /**
633
+ * Options for useExecutionHistory hook
634
+ */
635
+ export interface UseExecutionHistoryOptions {
636
+ /** Maximum history items to keep */
637
+ maxItems?: number;
638
+ /** Persist to localStorage */
639
+ persistToStorage?: boolean;
640
+ /** Custom storage key */
641
+ storageKey?: string;
642
+ }
643
+
644
+ /**
645
+ * Active tab type in playground
646
+ */
647
+ export type PlaygroundTab = 'tools' | 'resources' | 'prompts';
648
+
649
+ /**
650
+ * Return type for usePlayground hook
651
+ */
652
+ export interface UsePlaygroundReturn {
653
+ // Connection
654
+ connection: UseMcpConnectionReturn;
655
+
656
+ // Data
657
+ tools: UseMcpToolsReturn;
658
+ resources: UseMcpResourcesReturn;
659
+ prompts: UseMcpPromptsReturn;
660
+
661
+ // UI State
662
+ activeTab: PlaygroundTab;
663
+ setActiveTab: (tab: PlaygroundTab) => void;
664
+ selectedTool: McpTool | null;
665
+ setSelectedTool: (tool: McpTool | null) => void;
666
+ selectedResource: McpResource | null;
667
+ setSelectedResource: (resource: McpResource | null) => void;
668
+ selectedPrompt: McpPrompt | null;
669
+ setSelectedPrompt: (prompt: McpPrompt | null) => void;
670
+
671
+ // Transport Config
672
+ transportConfig: TransportConfig | null;
673
+ setTransportConfig: (config: TransportConfig) => void;
674
+
675
+ // Convenience
676
+ isReady: boolean;
677
+ hasCapability: (cap: keyof McpCapabilities) => boolean;
678
+ }
679
+
680
+ // ============================================================================
681
+ // Utility Types
682
+ // ============================================================================
683
+
684
+ /**
685
+ * Generate a unique ID
686
+ */
687
+ export function generateId(): string {
688
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
689
+ }
690
+
691
+ /**
692
+ * Exponential backoff configuration
693
+ */
694
+ export interface RetryConfig {
695
+ maxRetries: number;
696
+ baseDelay: number;
697
+ maxDelay: number;
698
+ factor: number;
699
+ }
700
+
701
+ /**
702
+ * Default retry configuration
703
+ */
704
+ export const DEFAULT_RETRY_CONFIG: RetryConfig = {
705
+ maxRetries: 3,
706
+ baseDelay: 1000,
707
+ maxDelay: 30000,
708
+ factor: 2,
709
+ };
710
+
711
+ /**
712
+ * Calculate delay for exponential backoff
713
+ */
714
+ export function calculateBackoff(attempt: number, config: RetryConfig = DEFAULT_RETRY_CONFIG): number {
715
+ const delay = Math.min(
716
+ config.baseDelay * Math.pow(config.factor, attempt),
717
+ config.maxDelay
718
+ );
719
+ // Add jitter to prevent thundering herd
720
+ return delay + Math.random() * delay * 0.1;
721
+ }
722
+
723
+ // ============================================================================
724
+ // Debug & Logging Types
725
+ // ============================================================================
726
+
727
+ /**
728
+ * Log levels for debug mode
729
+ */
730
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
731
+
732
+ /**
733
+ * Debug log entry
734
+ */
735
+ export interface DebugLogEntry {
736
+ timestamp: Date;
737
+ level: LogLevel;
738
+ source: string;
739
+ message: string;
740
+ data?: unknown;
741
+ }
742
+
743
+ /**
744
+ * Debug options for hooks
745
+ */
746
+ export interface DebugOptions {
747
+ enabled: boolean;
748
+ logLevel?: LogLevel;
749
+ onLog?: (entry: DebugLogEntry) => void;
750
+ }
751
+
752
+ /**
753
+ * Create a debug logger
754
+ */
755
+ export function createDebugLogger(source: string, options?: DebugOptions) {
756
+ const logLevels: Record<LogLevel, number> = {
757
+ debug: 0,
758
+ info: 1,
759
+ warn: 2,
760
+ error: 3,
761
+ };
762
+
763
+ const minLevel = logLevels[options?.logLevel ?? 'debug'];
764
+
765
+ return {
766
+ debug: (message: string, data?: unknown) => {
767
+ if (!options?.enabled || logLevels.debug < minLevel) return;
768
+ const entry: DebugLogEntry = { timestamp: new Date(), level: 'debug', source, message, data };
769
+ options.onLog?.(entry);
770
+ console.debug(`[${source}]`, message, data ?? '');
771
+ },
772
+ info: (message: string, data?: unknown) => {
773
+ if (!options?.enabled || logLevels.info < minLevel) return;
774
+ const entry: DebugLogEntry = { timestamp: new Date(), level: 'info', source, message, data };
775
+ options.onLog?.(entry);
776
+ console.info(`[${source}]`, message, data ?? '');
777
+ },
778
+ warn: (message: string, data?: unknown) => {
779
+ if (!options?.enabled || logLevels.warn < minLevel) return;
780
+ const entry: DebugLogEntry = { timestamp: new Date(), level: 'warn', source, message, data };
781
+ options.onLog?.(entry);
782
+ console.warn(`[${source}]`, message, data ?? '');
783
+ },
784
+ error: (message: string, data?: unknown) => {
785
+ if (!options?.enabled || logLevels.error < minLevel) return;
786
+ const entry: DebugLogEntry = { timestamp: new Date(), level: 'error', source, message, data };
787
+ options.onLog?.(entry);
788
+ console.error(`[${source}]`, message, data ?? '');
789
+ },
790
+ };
791
+ }
792
+
793
+ // ============================================================================
794
+ // Event Emitter Types
795
+ // ============================================================================
796
+
797
+ /**
798
+ * Event types for MCP hooks
799
+ */
800
+ export type McpEventType =
801
+ | 'connection:connecting'
802
+ | 'connection:connected'
803
+ | 'connection:disconnected'
804
+ | 'connection:error'
805
+ | 'connection:heartbeat'
806
+ | 'tools:loading'
807
+ | 'tools:loaded'
808
+ | 'tools:error'
809
+ | 'tool:executing'
810
+ | 'tool:executed'
811
+ | 'tool:error'
812
+ | 'tool:cancelled'
813
+ | 'resources:loading'
814
+ | 'resources:loaded'
815
+ | 'resources:error'
816
+ | 'resource:reading'
817
+ | 'resource:read'
818
+ | 'resource:error'
819
+ | 'prompts:loading'
820
+ | 'prompts:loaded'
821
+ | 'prompts:error'
822
+ | 'prompt:getting'
823
+ | 'prompt:got'
824
+ | 'prompt:error'
825
+ | 'prompt:executing'
826
+ | 'prompt:executed';
827
+
828
+ /**
829
+ * Event payload base
830
+ */
831
+ export interface McpEventBase {
832
+ type: McpEventType;
833
+ timestamp: Date;
834
+ sessionId?: string | null;
835
+ }
836
+
837
+ /**
838
+ * Connection event payload
839
+ */
840
+ export interface ConnectionEvent extends McpEventBase {
841
+ type: 'connection:connecting' | 'connection:connected' | 'connection:disconnected' | 'connection:error' | 'connection:heartbeat';
842
+ data?: {
843
+ serverInfo?: ServerInfo;
844
+ capabilities?: McpCapabilities;
845
+ error?: string;
846
+ };
847
+ }
848
+
849
+ /**
850
+ * Tool event payload
851
+ */
852
+ export interface ToolEvent extends McpEventBase {
853
+ type: 'tools:loading' | 'tools:loaded' | 'tools:error' | 'tool:executing' | 'tool:executed' | 'tool:error' | 'tool:cancelled';
854
+ data?: {
855
+ tools?: McpTool[];
856
+ toolName?: string;
857
+ params?: Record<string, unknown>;
858
+ result?: ToolCallResult;
859
+ error?: string;
860
+ executionTime?: number;
861
+ };
862
+ }
863
+
864
+ /**
865
+ * Resource event payload
866
+ */
867
+ export interface ResourceEvent extends McpEventBase {
868
+ type: 'resources:loading' | 'resources:loaded' | 'resources:error' | 'resource:reading' | 'resource:read' | 'resource:error';
869
+ data?: {
870
+ resources?: McpResource[];
871
+ uri?: string;
872
+ contents?: ResourceContents;
873
+ error?: string;
874
+ };
875
+ }
876
+
877
+ /**
878
+ * Prompt event payload
879
+ */
880
+ export interface PromptEvent extends McpEventBase {
881
+ type: 'prompts:loading' | 'prompts:loaded' | 'prompts:error' | 'prompt:getting' | 'prompt:got' | 'prompt:error' | 'prompt:executing' | 'prompt:executed';
882
+ data?: {
883
+ prompts?: McpPrompt[];
884
+ name?: string;
885
+ args?: Record<string, string>;
886
+ arguments?: Record<string, string>;
887
+ messages?: PromptMessage[];
888
+ error?: string;
889
+ };
890
+ }
891
+
892
+ /**
893
+ * Union of all event types
894
+ */
895
+ export type McpEvent = ConnectionEvent | ToolEvent | ResourceEvent | PromptEvent;
896
+
897
+ /**
898
+ * Event listener function
899
+ */
900
+ export type McpEventListener<T extends McpEvent = McpEvent> = (event: T) => void;
901
+
902
+ /**
903
+ * Simple event emitter for MCP events
904
+ */
905
+ export class McpEventEmitter {
906
+ private listeners = new Map<McpEventType | '*', Set<McpEventListener>>();
907
+
908
+ on<T extends McpEvent>(type: T['type'] | '*', listener: McpEventListener<T>): () => void {
909
+ if (!this.listeners.has(type)) {
910
+ this.listeners.set(type, new Set());
911
+ }
912
+ this.listeners.get(type)!.add(listener as McpEventListener);
913
+
914
+ // Return unsubscribe function
915
+ return () => this.off(type, listener);
916
+ }
917
+
918
+ off<T extends McpEvent>(type: T['type'] | '*', listener: McpEventListener<T>): void {
919
+ this.listeners.get(type)?.delete(listener as McpEventListener);
920
+ }
921
+
922
+ /**
923
+ * Subscribe to all events (alias for on('*', ...))
924
+ */
925
+ subscribe(listener: McpEventListener): () => void {
926
+ return this.on('*', listener);
927
+ }
928
+
929
+ emit<T extends McpEvent>(event: T): void {
930
+ // Emit to specific listeners
931
+ this.listeners.get(event.type)?.forEach(listener => {
932
+ try {
933
+ listener(event);
934
+ } catch (err) {
935
+ console.error('[McpEventEmitter] Error in listener:', err);
936
+ }
937
+ });
938
+
939
+ // Emit to wildcard listeners
940
+ this.listeners.get('*')?.forEach(listener => {
941
+ try {
942
+ listener(event);
943
+ } catch (err) {
944
+ console.error('[McpEventEmitter] Error in wildcard listener:', err);
945
+ }
946
+ });
947
+ }
948
+
949
+ clear(): void {
950
+ this.listeners.clear();
951
+ }
952
+ }
953
+
954
+ /**
955
+ * Create an MCP event emitter instance
956
+ */
957
+ export function createMcpEventEmitter(): McpEventEmitter {
958
+ return new McpEventEmitter();
959
+ }
960
+
961
+ // ============================================================================
962
+ // Cache Types
963
+ // ============================================================================
964
+
965
+ /**
966
+ * Cache entry with TTL
967
+ */
968
+ export interface CacheEntry<T> {
969
+ data: T;
970
+ timestamp: number;
971
+ ttl: number;
972
+ }
973
+
974
+ /**
975
+ * Simple cache implementation
976
+ */
977
+ export class SimpleCache<T> {
978
+ private cache = new Map<string, CacheEntry<T>>();
979
+
980
+ set(key: string, data: T, ttl: number = DEFAULT_CACHE_TTL): void {
981
+ this.cache.set(key, {
982
+ data,
983
+ timestamp: Date.now(),
984
+ ttl,
985
+ });
986
+ }
987
+
988
+ get(key: string): T | null {
989
+ const entry = this.cache.get(key);
990
+ if (!entry) return null;
991
+
992
+ if (Date.now() - entry.timestamp > entry.ttl) {
993
+ this.cache.delete(key);
994
+ return null;
995
+ }
996
+
997
+ return entry.data;
998
+ }
999
+
1000
+ has(key: string): boolean {
1001
+ return this.get(key) !== null;
1002
+ }
1003
+
1004
+ delete(key: string): void {
1005
+ this.cache.delete(key);
1006
+ }
1007
+
1008
+ clear(): void {
1009
+ this.cache.clear();
1010
+ }
1011
+
1012
+ isStale(key: string): boolean {
1013
+ const entry = this.cache.get(key);
1014
+ if (!entry) return true;
1015
+ return Date.now() - entry.timestamp > entry.ttl;
1016
+ }
1017
+
1018
+ getStale(key: string): T | null {
1019
+ const entry = this.cache.get(key);
1020
+ return entry?.data ?? null;
1021
+ }
1022
+ }
1023
+
1024
+ // ============================================================================
1025
+ // Batch Execution Types
1026
+ // ============================================================================
1027
+
1028
+ /**
1029
+ * Batch tool execution request
1030
+ */
1031
+ export interface BatchToolRequest {
1032
+ name: string;
1033
+ params: Record<string, unknown>;
1034
+ }
1035
+
1036
+ /**
1037
+ * Batch tool execution result
1038
+ */
1039
+ export interface BatchToolResult {
1040
+ request: BatchToolRequest;
1041
+ execution: ToolExecution;
1042
+ }
1043
+
1044
+ /**
1045
+ * Batch execution options
1046
+ */
1047
+ export interface BatchExecutionOptions {
1048
+ /** Maximum concurrent executions */
1049
+ concurrency?: number;
1050
+ /** Stop on first error */
1051
+ stopOnError?: boolean;
1052
+ /** Timeout per execution in ms */
1053
+ timeout?: number;
1054
+ }
1055
+
1056
+ // ============================================================================
1057
+ // Request Deduplication Types
1058
+ // ============================================================================
1059
+
1060
+ /**
1061
+ * Pending request tracker
1062
+ */
1063
+ export class RequestDeduplicator {
1064
+ private pending = new Map<string, Promise<unknown>>();
1065
+
1066
+ /**
1067
+ * Execute a request with deduplication
1068
+ * If the same key is already in flight, return the existing promise
1069
+ */
1070
+ async execute<T>(key: string, fn: () => Promise<T>): Promise<T> {
1071
+ const existing = this.pending.get(key);
1072
+ if (existing) {
1073
+ return existing as Promise<T>;
1074
+ }
1075
+
1076
+ const promise = fn().finally(() => {
1077
+ this.pending.delete(key);
1078
+ });
1079
+
1080
+ this.pending.set(key, promise);
1081
+ return promise;
1082
+ }
1083
+
1084
+ has(key: string): boolean {
1085
+ return this.pending.has(key);
1086
+ }
1087
+
1088
+ clear(): void {
1089
+ this.pending.clear();
1090
+ }
1091
+ }
1092
+
1093
+ // ============================================================================
1094
+ // Fetch with Timeout
1095
+ // ============================================================================
1096
+
1097
+ /**
1098
+ * Fetch with timeout support
1099
+ */
1100
+ export async function fetchWithTimeout(
1101
+ url: string,
1102
+ options: RequestInit & { timeout?: number } = {}
1103
+ ): Promise<Response> {
1104
+ const { timeout = DEFAULT_TIMEOUT, ...fetchOptions } = options;
1105
+
1106
+ const controller = new AbortController();
1107
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
1108
+
1109
+ // Combine with existing signal if present
1110
+ const signal = options.signal
1111
+ ? anySignal([options.signal, controller.signal])
1112
+ : controller.signal;
1113
+
1114
+ try {
1115
+ const response = await fetch(url, {
1116
+ ...fetchOptions,
1117
+ signal,
1118
+ });
1119
+ return response;
1120
+ } finally {
1121
+ clearTimeout(timeoutId);
1122
+ }
1123
+ }
1124
+
1125
+ /**
1126
+ * Combine multiple AbortSignals into one
1127
+ */
1128
+ function anySignal(signals: AbortSignal[]): AbortSignal {
1129
+ const controller = new AbortController();
1130
+
1131
+ for (const signal of signals) {
1132
+ if (signal.aborted) {
1133
+ controller.abort(signal.reason);
1134
+ return controller.signal;
1135
+ }
1136
+ signal.addEventListener('abort', () => controller.abort(signal.reason), { once: true });
1137
+ }
1138
+
1139
+ return controller.signal;
1140
+ }
1141
+
1142
+ // ============================================================================
1143
+ // Debounce Utility
1144
+ // ============================================================================
1145
+
1146
+ /**
1147
+ * Create a debounced function
1148
+ */
1149
+ export function debounce<T extends (...args: Parameters<T>) => void>(
1150
+ fn: T,
1151
+ delay: number
1152
+ ): T & { cancel: () => void } {
1153
+ let timeoutId: NodeJS.Timeout | null = null;
1154
+
1155
+ const debounced = ((...args: Parameters<T>) => {
1156
+ if (timeoutId) {
1157
+ clearTimeout(timeoutId);
1158
+ }
1159
+ timeoutId = setTimeout(() => {
1160
+ fn(...args);
1161
+ timeoutId = null;
1162
+ }, delay);
1163
+ }) as T & { cancel: () => void };
1164
+
1165
+ debounced.cancel = () => {
1166
+ if (timeoutId) {
1167
+ clearTimeout(timeoutId);
1168
+ timeoutId = null;
1169
+ }
1170
+ };
1171
+
1172
+ return debounced;
1173
+ }