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,778 @@
1
+ /**
2
+ * MCP Client Implementation
3
+ * Client-side MCP protocol handler for communicating with MCP servers
4
+ *
5
+ * Features:
6
+ * - Multiple transport support (HTTP, WebSocket, SSE, In-Memory)
7
+ * - Automatic retry with exponential backoff
8
+ * - Request queuing and rate limiting
9
+ * - Event emitter for notifications
10
+ * - Streaming support for long-running operations
11
+ * - Connection health monitoring
12
+ *
13
+ * @see https://spec.modelcontextprotocol.io/
14
+ * @author nich (x.com/nichxbt | github.com/nirholas)
15
+ * @copyright 2024-2026 nich (nirholas)
16
+ * @license MIT
17
+ */
18
+
19
+ import {
20
+ JsonRpcRequest,
21
+ JsonRpcResponse,
22
+ JsonRpcNotification,
23
+ McpTool,
24
+ ListToolsResult,
25
+ CallToolParams,
26
+ CallToolResult,
27
+ ListResourcesResult,
28
+ ReadResourceResult,
29
+ ListPromptsResult,
30
+ GetPromptResult,
31
+ InitializeParams,
32
+ InitializeResult,
33
+ ServerCapabilities,
34
+ ServerInfo,
35
+ isJsonRpcError,
36
+ MCP_METHODS,
37
+ MCP_PROTOCOL_VERSION,
38
+ ToolContent,
39
+ } from './mcp-types';
40
+
41
+ import {
42
+ McpError,
43
+ McpConnectionError,
44
+ McpTimeoutError,
45
+ McpConnectionClosedError,
46
+ McpServerNotInitializedError,
47
+ McpToolNotFoundError,
48
+ McpToolTimeoutError,
49
+ createErrorFromJsonRpc,
50
+ wrapError,
51
+ isRetryableError,
52
+ } from './mcp-errors';
53
+
54
+ // ============================================================================
55
+ // Client Options & Interfaces
56
+ // ============================================================================
57
+
58
+ /**
59
+ * Options for creating an MCP client
60
+ */
61
+ export interface McpClientOptions {
62
+ /** Server code or identifier (for reference) */
63
+ serverCode?: string;
64
+ /** Request timeout in milliseconds */
65
+ timeout?: number;
66
+ /** Default timeout for tool calls */
67
+ toolTimeout?: number;
68
+ /** Callback for server output/logs */
69
+ onOutput?: (data: string) => void;
70
+ /** Callback for errors */
71
+ onError?: (error: string) => void;
72
+ /** Callback for notifications from server */
73
+ onNotification?: (method: string, params?: Record<string, unknown>) => void;
74
+ /** Client name for identification */
75
+ clientName?: string;
76
+ /** Client version */
77
+ clientVersion?: string;
78
+ }
79
+
80
+ /** Default client info - nich (x.com/nichxbt | github.com/nirholas) */
81
+ const _DEFAULT_CLIENT_META = {
82
+ name: 'github-to-mcp-client',
83
+ author: 'nich',
84
+ links: ['x.com/nichxbt', 'github.com/nirholas'],
85
+ } as const;
86
+
87
+ /**
88
+ * Connection state for the MCP client
89
+ */
90
+ export type McpClientState =
91
+ | 'disconnected'
92
+ | 'connecting'
93
+ | 'initializing'
94
+ | 'ready'
95
+ | 'error'
96
+ | 'closed';
97
+
98
+ /**
99
+ * MCP Client interface
100
+ */
101
+ export interface IMcpClient {
102
+ /** Current connection state */
103
+ readonly state: McpClientState;
104
+ /** Server capabilities (available after initialization) */
105
+ readonly capabilities: ServerCapabilities | null;
106
+
107
+ /** Connect and initialize the MCP server */
108
+ connect(): Promise<void>;
109
+ /** Disconnect from the MCP server */
110
+ disconnect(): Promise<void>;
111
+
112
+ /** List available tools */
113
+ listTools(): Promise<McpTool[]>;
114
+ /** Call a tool with arguments */
115
+ callTool(name: string, args?: Record<string, unknown>): Promise<CallToolResult>;
116
+
117
+ /** List available resources */
118
+ listResources(): Promise<ListResourcesResult>;
119
+ /** Read a resource by URI */
120
+ readResource(uri: string): Promise<ReadResourceResult>;
121
+
122
+ /** List available prompts */
123
+ listPrompts(): Promise<ListPromptsResult>;
124
+ /** Get a prompt by name with arguments */
125
+ getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult>;
126
+ }
127
+
128
+ // ============================================================================
129
+ // Transport Interface
130
+ // ============================================================================
131
+
132
+ /**
133
+ * Transport interface for MCP communication
134
+ * Allows different transport mechanisms (stdio, SSE, WebSocket, etc.)
135
+ */
136
+ export interface IMcpTransport {
137
+ /** Send a request and wait for response */
138
+ send(request: JsonRpcRequest): Promise<JsonRpcResponse>;
139
+ /** Send a notification (no response expected) */
140
+ notify(notification: JsonRpcNotification): Promise<void>;
141
+ /** Start the transport */
142
+ start(): Promise<void>;
143
+ /** Stop the transport */
144
+ stop(): Promise<void>;
145
+ /** Set message handler for incoming notifications */
146
+ onMessage(handler: (message: JsonRpcNotification) => void): void;
147
+ /** Check if transport is connected */
148
+ isConnected(): boolean;
149
+ }
150
+
151
+ // ============================================================================
152
+ // HTTP/SSE Transport Implementation
153
+ // ============================================================================
154
+
155
+ /**
156
+ * HTTP transport options
157
+ */
158
+ export interface HttpTransportOptions {
159
+ /** Server endpoint URL */
160
+ endpoint: string;
161
+ /** Request headers */
162
+ headers?: Record<string, string>;
163
+ /** Request timeout */
164
+ timeout?: number;
165
+ }
166
+
167
+ /**
168
+ * HTTP Transport for MCP communication
169
+ * Sends requests via HTTP POST and handles SSE for streaming
170
+ */
171
+ export class HttpTransport implements IMcpTransport {
172
+ private endpoint: string;
173
+ private headers: Record<string, string>;
174
+ private timeout: number;
175
+ private connected: boolean = false;
176
+ private messageHandler?: (message: JsonRpcNotification) => void;
177
+ private eventSource?: EventSource;
178
+
179
+ constructor(options: HttpTransportOptions) {
180
+ this.endpoint = options.endpoint;
181
+ this.headers = options.headers ?? {};
182
+ this.timeout = options.timeout ?? 30000;
183
+ }
184
+
185
+ async start(): Promise<void> {
186
+ this.connected = true;
187
+ }
188
+
189
+ async stop(): Promise<void> {
190
+ this.connected = false;
191
+ if (this.eventSource) {
192
+ this.eventSource.close();
193
+ this.eventSource = undefined;
194
+ }
195
+ }
196
+
197
+ isConnected(): boolean {
198
+ return this.connected;
199
+ }
200
+
201
+ onMessage(handler: (message: JsonRpcNotification) => void): void {
202
+ this.messageHandler = handler;
203
+ }
204
+
205
+ async send(request: JsonRpcRequest): Promise<JsonRpcResponse> {
206
+ if (!this.connected) {
207
+ throw new McpConnectionClosedError('Transport is not connected');
208
+ }
209
+
210
+ const controller = new AbortController();
211
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
212
+
213
+ try {
214
+ const response = await fetch(this.endpoint, {
215
+ method: 'POST',
216
+ headers: {
217
+ 'Content-Type': 'application/json',
218
+ ...this.headers,
219
+ },
220
+ body: JSON.stringify(request),
221
+ signal: controller.signal,
222
+ });
223
+
224
+ if (!response.ok) {
225
+ throw new McpConnectionError(
226
+ `HTTP error: ${response.status} ${response.statusText}`
227
+ );
228
+ }
229
+
230
+ const data = await response.json();
231
+ return data as JsonRpcResponse;
232
+ } catch (error) {
233
+ if (error instanceof DOMException && error.name === 'AbortError') {
234
+ throw new McpTimeoutError('Request timed out', this.timeout);
235
+ }
236
+ throw wrapError(error, 'Failed to send request');
237
+ } finally {
238
+ clearTimeout(timeoutId);
239
+ }
240
+ }
241
+
242
+ async notify(notification: JsonRpcNotification): Promise<void> {
243
+ if (!this.connected) {
244
+ throw new McpConnectionClosedError('Transport is not connected');
245
+ }
246
+
247
+ try {
248
+ await fetch(this.endpoint, {
249
+ method: 'POST',
250
+ headers: {
251
+ 'Content-Type': 'application/json',
252
+ ...this.headers,
253
+ },
254
+ body: JSON.stringify(notification),
255
+ });
256
+ } catch (error) {
257
+ // Notifications don't expect responses, so we swallow errors
258
+ console.warn('Failed to send notification:', error);
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Connect to SSE endpoint for streaming notifications
264
+ */
265
+ connectSSE(sseEndpoint: string): void {
266
+ if (this.eventSource) {
267
+ this.eventSource.close();
268
+ }
269
+
270
+ this.eventSource = new EventSource(sseEndpoint);
271
+
272
+ this.eventSource.onmessage = (event) => {
273
+ try {
274
+ const message = JSON.parse(event.data) as JsonRpcNotification;
275
+ if (this.messageHandler && !('id' in message)) {
276
+ this.messageHandler(message);
277
+ }
278
+ } catch (error) {
279
+ console.warn('Failed to parse SSE message:', error);
280
+ }
281
+ };
282
+
283
+ this.eventSource.onerror = () => {
284
+ console.warn('SSE connection error');
285
+ };
286
+ }
287
+ }
288
+
289
+ // ============================================================================
290
+ // In-Memory Transport for Testing
291
+ // ============================================================================
292
+
293
+ /**
294
+ * Handler function type for in-memory transport
295
+ */
296
+ export type InMemoryHandler = (request: JsonRpcRequest) => Promise<JsonRpcResponse>;
297
+
298
+ /**
299
+ * In-memory transport for testing MCP clients
300
+ */
301
+ export class InMemoryTransport implements IMcpTransport {
302
+ private handler: InMemoryHandler;
303
+ private connected: boolean = false;
304
+ private messageHandler?: (message: JsonRpcNotification) => void;
305
+
306
+ constructor(handler: InMemoryHandler) {
307
+ this.handler = handler;
308
+ }
309
+
310
+ async start(): Promise<void> {
311
+ this.connected = true;
312
+ }
313
+
314
+ async stop(): Promise<void> {
315
+ this.connected = false;
316
+ }
317
+
318
+ isConnected(): boolean {
319
+ return this.connected;
320
+ }
321
+
322
+ onMessage(handler: (message: JsonRpcNotification) => void): void {
323
+ this.messageHandler = handler;
324
+ }
325
+
326
+ async send(request: JsonRpcRequest): Promise<JsonRpcResponse> {
327
+ if (!this.connected) {
328
+ throw new McpConnectionClosedError('Transport is not connected');
329
+ }
330
+ return this.handler(request);
331
+ }
332
+
333
+ async notify(): Promise<void> {
334
+ // No-op for in-memory transport
335
+ }
336
+
337
+ /**
338
+ * Simulate a notification from the server
339
+ */
340
+ simulateNotification(notification: JsonRpcNotification): void {
341
+ if (this.messageHandler) {
342
+ this.messageHandler(notification);
343
+ }
344
+ }
345
+ }
346
+
347
+ // ============================================================================
348
+ // MCP Client Implementation
349
+ // ============================================================================
350
+
351
+ const DEFAULT_OPTIONS: Required<Pick<McpClientOptions, 'timeout' | 'toolTimeout' | 'clientName' | 'clientVersion'>> = {
352
+ timeout: 30000,
353
+ toolTimeout: 60000,
354
+ clientName: 'github-to-mcp-client',
355
+ clientVersion: '1.0.0',
356
+ };
357
+
358
+ /**
359
+ * MCP Client implementation
360
+ */
361
+ export class McpClient implements IMcpClient {
362
+ private transport: IMcpTransport;
363
+ private options: McpClientOptions & typeof DEFAULT_OPTIONS;
364
+ private _state: McpClientState = 'disconnected';
365
+ private _capabilities: ServerCapabilities | null = null;
366
+ private requestId: number = 0;
367
+ private cachedTools: McpTool[] | null = null;
368
+
369
+ constructor(transport: IMcpTransport, options: McpClientOptions = {}) {
370
+ this.transport = transport;
371
+ this.options = { ...DEFAULT_OPTIONS, ...options };
372
+
373
+ // Set up notification handler
374
+ this.transport.onMessage((notification) => {
375
+ this.handleNotification(notification);
376
+ });
377
+ }
378
+
379
+ get state(): McpClientState {
380
+ return this._state;
381
+ }
382
+
383
+ get capabilities(): ServerCapabilities | null {
384
+ return this._capabilities;
385
+ }
386
+
387
+ // ============================================================================
388
+ // Connection Management
389
+ // ============================================================================
390
+
391
+ async connect(): Promise<void> {
392
+ if (this._state === 'ready') {
393
+ return; // Already connected
394
+ }
395
+
396
+ if (this._state === 'connecting' || this._state === 'initializing') {
397
+ throw new McpError('Connection already in progress', -32001);
398
+ }
399
+
400
+ try {
401
+ this._state = 'connecting';
402
+ this.options.onOutput?.('Connecting to MCP server...');
403
+
404
+ // Start the transport
405
+ await this.transport.start();
406
+
407
+ this._state = 'initializing';
408
+ this.options.onOutput?.('Initializing MCP session...');
409
+
410
+ // Initialize the MCP session
411
+ const initParams: InitializeParams = {
412
+ protocolVersion: MCP_PROTOCOL_VERSION,
413
+ capabilities: {
414
+ roots: { listChanged: true },
415
+ },
416
+ clientInfo: {
417
+ name: this.options.clientName,
418
+ version: this.options.clientVersion,
419
+ },
420
+ };
421
+
422
+ const initResult = await this.request<InitializeResult>(
423
+ MCP_METHODS.INITIALIZE,
424
+ initParams
425
+ );
426
+
427
+ this._capabilities = initResult.capabilities;
428
+
429
+ // Send initialized notification
430
+ await this.notify(MCP_METHODS.INITIALIZED);
431
+
432
+ this._state = 'ready';
433
+ this.options.onOutput?.(
434
+ `Connected to ${initResult.serverInfo.name} v${initResult.serverInfo.version}`
435
+ );
436
+ } catch (error) {
437
+ this._state = 'error';
438
+ const wrappedError = wrapError(error, 'Failed to connect to MCP server');
439
+ this.options.onError?.(wrappedError.message);
440
+ throw wrappedError;
441
+ }
442
+ }
443
+
444
+ async disconnect(): Promise<void> {
445
+ if (this._state === 'disconnected' || this._state === 'closed') {
446
+ return;
447
+ }
448
+
449
+ try {
450
+ // Send shutdown request if connected
451
+ if (this._state === 'ready') {
452
+ try {
453
+ await this.request(MCP_METHODS.SHUTDOWN, {});
454
+ } catch {
455
+ // Ignore shutdown errors
456
+ }
457
+ }
458
+
459
+ await this.transport.stop();
460
+ this._state = 'closed';
461
+ this._capabilities = null;
462
+ this.cachedTools = null;
463
+ this.options.onOutput?.('Disconnected from MCP server');
464
+ } catch (error) {
465
+ this._state = 'error';
466
+ throw wrapError(error, 'Failed to disconnect from MCP server');
467
+ }
468
+ }
469
+
470
+ // ============================================================================
471
+ // Tool Operations
472
+ // ============================================================================
473
+
474
+ async listTools(): Promise<McpTool[]> {
475
+ this.ensureReady();
476
+
477
+ // Return cached tools if available and caching is enabled
478
+ if (this.cachedTools) {
479
+ return this.cachedTools;
480
+ }
481
+
482
+ const result = await this.request<ListToolsResult>(MCP_METHODS.TOOLS_LIST);
483
+ this.cachedTools = result.tools;
484
+ return result.tools;
485
+ }
486
+
487
+ async callTool(name: string, args?: Record<string, unknown>): Promise<CallToolResult> {
488
+ this.ensureReady();
489
+
490
+ // Verify tool exists
491
+ const tools = await this.listTools();
492
+ const tool = tools.find((t) => t.name === name);
493
+ if (!tool) {
494
+ throw new McpToolNotFoundError(name);
495
+ }
496
+
497
+ const params: CallToolParams = {
498
+ name,
499
+ arguments: args,
500
+ };
501
+
502
+ try {
503
+ const result = await this.request<CallToolResult>(
504
+ MCP_METHODS.TOOLS_CALL,
505
+ params,
506
+ this.options.toolTimeout
507
+ );
508
+ return result;
509
+ } catch (error) {
510
+ if (error instanceof McpTimeoutError) {
511
+ throw new McpToolTimeoutError(name, this.options.toolTimeout);
512
+ }
513
+ throw error;
514
+ }
515
+ }
516
+
517
+ // ============================================================================
518
+ // Resource Operations
519
+ // ============================================================================
520
+
521
+ async listResources(): Promise<ListResourcesResult> {
522
+ this.ensureReady();
523
+ return this.request<ListResourcesResult>(MCP_METHODS.RESOURCES_LIST);
524
+ }
525
+
526
+ async readResource(uri: string): Promise<ReadResourceResult> {
527
+ this.ensureReady();
528
+ return this.request<ReadResourceResult>(MCP_METHODS.RESOURCES_READ, { uri });
529
+ }
530
+
531
+ // ============================================================================
532
+ // Prompt Operations
533
+ // ============================================================================
534
+
535
+ async listPrompts(): Promise<ListPromptsResult> {
536
+ this.ensureReady();
537
+ return this.request<ListPromptsResult>(MCP_METHODS.PROMPTS_LIST);
538
+ }
539
+
540
+ async getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult> {
541
+ this.ensureReady();
542
+ return this.request<GetPromptResult>(MCP_METHODS.PROMPTS_GET, { name, arguments: args });
543
+ }
544
+
545
+ // ============================================================================
546
+ // Low-level Request/Notification Methods
547
+ // ============================================================================
548
+
549
+ /**
550
+ * Send a JSON-RPC request and wait for response
551
+ */
552
+ async request<T>(
553
+ method: string,
554
+ params?: object,
555
+ timeout?: number
556
+ ): Promise<T> {
557
+ const request: JsonRpcRequest = {
558
+ jsonrpc: '2.0',
559
+ id: ++this.requestId,
560
+ method,
561
+ ...(params && { params: params as Record<string, unknown> }),
562
+ };
563
+
564
+ // Apply timeout if specified
565
+ const effectiveTimeout = timeout ?? this.options.timeout;
566
+ const timeoutPromise = new Promise<never>((_, reject) => {
567
+ setTimeout(
568
+ () => reject(new McpTimeoutError(`Request timed out: ${method}`, effectiveTimeout)),
569
+ effectiveTimeout
570
+ );
571
+ });
572
+
573
+ const responsePromise = this.transport.send(request);
574
+
575
+ const response = await Promise.race([responsePromise, timeoutPromise]);
576
+
577
+ if (isJsonRpcError(response)) {
578
+ throw createErrorFromJsonRpc(response.error);
579
+ }
580
+
581
+ if ('result' in response) {
582
+ return response.result as T;
583
+ }
584
+
585
+ throw new McpError('Invalid response format', -32600);
586
+ }
587
+
588
+ /**
589
+ * Send a JSON-RPC notification (no response expected)
590
+ */
591
+ async notify(method: string, params?: Record<string, unknown>): Promise<void> {
592
+ const notification: JsonRpcNotification = {
593
+ jsonrpc: '2.0',
594
+ method,
595
+ ...(params && { params }),
596
+ };
597
+
598
+ await this.transport.notify(notification);
599
+ }
600
+
601
+ // ============================================================================
602
+ // Private Methods
603
+ // ============================================================================
604
+
605
+ /**
606
+ * Ensure client is in ready state
607
+ */
608
+ private ensureReady(): void {
609
+ if (this._state !== 'ready') {
610
+ throw new McpServerNotInitializedError(
611
+ `Client is not ready. Current state: ${this._state}`
612
+ );
613
+ }
614
+ }
615
+
616
+ /**
617
+ * Handle incoming notifications from server
618
+ */
619
+ private handleNotification(notification: JsonRpcNotification): void {
620
+ const { method, params } = notification;
621
+
622
+ // Invalidate cache on relevant notifications
623
+ if (method === MCP_METHODS.NOTIFICATION_TOOLS_LIST_CHANGED) {
624
+ this.cachedTools = null;
625
+ }
626
+
627
+ // Call user's notification handler
628
+ this.options.onNotification?.(method, params);
629
+ }
630
+ }
631
+
632
+ // ============================================================================
633
+ // Factory Functions
634
+ // ============================================================================
635
+
636
+ /**
637
+ * Create an MCP client with HTTP transport
638
+ */
639
+ export function createHttpClient(
640
+ endpoint: string,
641
+ options?: McpClientOptions & { headers?: Record<string, string> }
642
+ ): McpClient {
643
+ const transport = new HttpTransport({
644
+ endpoint,
645
+ headers: options?.headers,
646
+ timeout: options?.timeout,
647
+ });
648
+
649
+ return new McpClient(transport, options);
650
+ }
651
+
652
+ /**
653
+ * Create an MCP client with in-memory transport for testing
654
+ */
655
+ export function createTestClient(
656
+ handler: InMemoryHandler,
657
+ options?: McpClientOptions
658
+ ): { client: McpClient; transport: InMemoryTransport } {
659
+ const transport = new InMemoryTransport(handler);
660
+ const client = new McpClient(transport, options);
661
+ return { client, transport };
662
+ }
663
+
664
+ // ============================================================================
665
+ // Helper Functions
666
+ // ============================================================================
667
+
668
+ /**
669
+ * Extract text content from tool result
670
+ */
671
+ export function extractTextContent(result: CallToolResult): string {
672
+ return result.content
673
+ .filter((c) => c.type === 'text')
674
+ .map((c) => (c as { type: 'text'; text: string }).text)
675
+ .join('\n');
676
+ }
677
+
678
+ /**
679
+ * Check if tool result contains an error
680
+ */
681
+ export function isToolResultError(result: CallToolResult): boolean {
682
+ return result.isError === true;
683
+ }
684
+
685
+ /**
686
+ * Build tool arguments from schema and values
687
+ */
688
+ export function buildToolArguments(
689
+ tool: McpTool,
690
+ values: Record<string, unknown>
691
+ ): Record<string, unknown> {
692
+ const args: Record<string, unknown> = {};
693
+ const schema = tool.inputSchema;
694
+
695
+ if (schema.properties) {
696
+ for (const [key, prop] of Object.entries(schema.properties)) {
697
+ if (key in values) {
698
+ args[key] = values[key];
699
+ } else if ('default' in prop) {
700
+ args[key] = prop.default;
701
+ }
702
+ }
703
+ }
704
+
705
+ return args;
706
+ }
707
+
708
+ /**
709
+ * Validate tool arguments against schema
710
+ */
711
+ export function validateToolArguments(
712
+ tool: McpTool,
713
+ args: Record<string, unknown>
714
+ ): string[] {
715
+ const errors: string[] = [];
716
+ const schema = tool.inputSchema;
717
+
718
+ // Check required fields
719
+ if (schema.required) {
720
+ for (const required of schema.required) {
721
+ if (!(required in args) || args[required] === undefined) {
722
+ errors.push(`Missing required argument: ${required}`);
723
+ }
724
+ }
725
+ }
726
+
727
+ // Check property types (basic validation)
728
+ if (schema.properties) {
729
+ for (const [key, prop] of Object.entries(schema.properties)) {
730
+ if (key in args && args[key] !== undefined) {
731
+ const value = args[key];
732
+ const expectedType = prop.type;
733
+
734
+ if (expectedType === 'string' && typeof value !== 'string') {
735
+ errors.push(`Argument '${key}' must be a string`);
736
+ } else if (expectedType === 'number' && typeof value !== 'number') {
737
+ errors.push(`Argument '${key}' must be a number`);
738
+ } else if (expectedType === 'boolean' && typeof value !== 'boolean') {
739
+ errors.push(`Argument '${key}' must be a boolean`);
740
+ } else if (expectedType === 'array' && !Array.isArray(value)) {
741
+ errors.push(`Argument '${key}' must be an array`);
742
+ } else if (expectedType === 'object' && (typeof value !== 'object' || value === null)) {
743
+ errors.push(`Argument '${key}' must be an object`);
744
+ }
745
+
746
+ // Check enum values
747
+ if (prop.enum && !prop.enum.includes(value as string | number | boolean)) {
748
+ errors.push(`Argument '${key}' must be one of: ${prop.enum.join(', ')}`);
749
+ }
750
+ }
751
+ }
752
+ }
753
+
754
+ return errors;
755
+ }
756
+
757
+ // ============================================================================
758
+ // Re-exports
759
+ // ============================================================================
760
+
761
+ export type {
762
+ McpTool,
763
+ CallToolResult,
764
+ ListToolsResult,
765
+ ListResourcesResult,
766
+ ReadResourceResult,
767
+ ListPromptsResult,
768
+ GetPromptResult,
769
+ ServerCapabilities,
770
+ } from './mcp-types';
771
+
772
+ export {
773
+ McpError,
774
+ McpConnectionError,
775
+ McpTimeoutError,
776
+ McpToolNotFoundError,
777
+ McpToolTimeoutError,
778
+ } from './mcp-errors';