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,779 @@
1
+ /**
2
+ * MCP Session Manager - Manages multiple concurrent MCP sessions
3
+ * @copyright 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ import { randomUUID } from 'crypto';
8
+
9
+ import { McpClient } from './client.js';
10
+ import type { EnhancedClientOptions } from './client.js';
11
+ import { createTransport } from './transports.js';
12
+ import type {
13
+ TransportConfig,
14
+ McpSession,
15
+ SessionManagerOptions,
16
+ McpClientOptions,
17
+ ConnectionState,
18
+ } from './types.js';
19
+ import {
20
+ McpSessionError,
21
+ McpErrorCode,
22
+ DEFAULT_SESSION_MANAGER_OPTIONS,
23
+ } from './types.js';
24
+ import type { Logger } from './logger.js';
25
+ import { createNoopLogger } from './logger.js';
26
+ import type { McpEventEmitter, McpEvent } from './events.js';
27
+ import { createEventEmitter } from './events.js';
28
+ import type { SessionManagerMetrics } from './metrics.js';
29
+ import { createSessionManagerMetrics } from './metrics.js';
30
+
31
+ // ============================================================================
32
+ // Enhanced Session Manager Types
33
+ // ============================================================================
34
+
35
+ /**
36
+ * Session health status
37
+ */
38
+ export interface SessionHealthStatus {
39
+ readonly sessionId: string;
40
+ readonly state: ConnectionState;
41
+ readonly healthy: boolean;
42
+ readonly lastUsedAt: Date;
43
+ readonly createdAt: Date;
44
+ readonly ageMs: number;
45
+ readonly idleMs: number;
46
+ }
47
+
48
+ /**
49
+ * Enhanced session manager options
50
+ */
51
+ export interface EnhancedSessionManagerOptions extends SessionManagerOptions {
52
+ readonly logger?: Logger;
53
+ readonly events?: McpEventEmitter;
54
+ readonly enableMetrics?: boolean;
55
+ readonly healthCheckIntervalMs?: number;
56
+ readonly clientOptions?: Partial<EnhancedClientOptions>;
57
+ }
58
+
59
+ // ============================================================================
60
+ // Session Manager Class
61
+ // ============================================================================
62
+
63
+ /**
64
+ * Manages multiple concurrent MCP client sessions with automatic cleanup.
65
+ *
66
+ * Features:
67
+ * - Session creation with configurable transports
68
+ * - Automatic session expiration (default: 5 minutes)
69
+ * - Maximum session limit (default: 100)
70
+ * - Session retrieval and cleanup
71
+ * - Event emission for session lifecycle
72
+ * - Metrics tracking (optional)
73
+ * - Health monitoring
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const manager = SessionManager.getInstance({
78
+ * logger: createConsoleLogger(),
79
+ * enableMetrics: true,
80
+ * });
81
+ *
82
+ * // Subscribe to session events
83
+ * manager.events.on('session:created', (event) => {
84
+ * console.log(`Session created: ${event.sessionId}`);
85
+ * });
86
+ *
87
+ * const session = await manager.createSession({
88
+ * type: 'stdio',
89
+ * command: 'npx',
90
+ * args: ['tsx', 'server.ts'],
91
+ * });
92
+ *
93
+ * // Use the session
94
+ * const client = manager.getClient(session.id);
95
+ * const tools = await client?.listTools();
96
+ *
97
+ * // Check health
98
+ * const health = manager.getSessionHealth(session.id);
99
+ * console.log('Session healthy:', health?.healthy);
100
+ *
101
+ * // Sessions are automatically cleaned up after timeout
102
+ * // Or manually cleanup:
103
+ * await manager.destroySession(session.id);
104
+ * ```
105
+ */
106
+ export class SessionManager {
107
+ private static _instance: SessionManager | null = null;
108
+
109
+ private readonly _options: Required<SessionManagerOptions>;
110
+ private readonly _logger: Logger;
111
+ private readonly _events: McpEventEmitter;
112
+ private readonly _metrics: SessionManagerMetrics | null;
113
+ private readonly _sessions: Map<string, SessionContext> = new Map();
114
+ private readonly _clientOptions: Partial<EnhancedClientOptions>;
115
+ private _healthCheckInterval: ReturnType<typeof setInterval> | null = null;
116
+ private _isShuttingDown = false;
117
+
118
+ /**
119
+ * Creates a new SessionManager instance.
120
+ * Use getInstance() to get the singleton instance.
121
+ *
122
+ * @param options - Session manager configuration options
123
+ */
124
+ private constructor(options: EnhancedSessionManagerOptions = {}) {
125
+ this._options = {
126
+ ...DEFAULT_SESSION_MANAGER_OPTIONS,
127
+ ...options,
128
+ };
129
+
130
+ this._logger = options.logger ?? createNoopLogger();
131
+ this._events = options.events ?? createEventEmitter();
132
+ this._metrics = options.enableMetrics ? createSessionManagerMetrics() : null;
133
+ this._clientOptions = options.clientOptions ?? {};
134
+
135
+ // Start health check if configured
136
+ if (options.healthCheckIntervalMs && options.healthCheckIntervalMs > 0) {
137
+ this._startHealthCheck(options.healthCheckIntervalMs);
138
+ }
139
+
140
+ this._logger.info('SessionManager initialized', {
141
+ data: {
142
+ maxSessions: this._options.maxSessions,
143
+ sessionTimeoutMs: this._options.sessionTimeoutMs,
144
+ },
145
+ });
146
+ }
147
+
148
+ // ============================================================================
149
+ // Singleton Access
150
+ // ============================================================================
151
+
152
+ /**
153
+ * Gets the singleton SessionManager instance.
154
+ *
155
+ * @param options - Optional configuration (only used on first call)
156
+ * @returns The singleton SessionManager instance
157
+ */
158
+ static getInstance(options?: EnhancedSessionManagerOptions): SessionManager {
159
+ if (!SessionManager._instance) {
160
+ SessionManager._instance = new SessionManager(options);
161
+ }
162
+ return SessionManager._instance;
163
+ }
164
+
165
+ /**
166
+ * Resets the singleton instance (useful for testing).
167
+ * WARNING: This will destroy all active sessions.
168
+ */
169
+ static async resetInstance(): Promise<void> {
170
+ if (SessionManager._instance) {
171
+ await SessionManager._instance.shutdown();
172
+ SessionManager._instance = null;
173
+ }
174
+ }
175
+
176
+ // ============================================================================
177
+ // Public Properties
178
+ // ============================================================================
179
+
180
+ /**
181
+ * Number of active sessions.
182
+ */
183
+ get sessionCount(): number {
184
+ return this._sessions.size;
185
+ }
186
+
187
+ /**
188
+ * Maximum allowed sessions.
189
+ */
190
+ get maxSessions(): number {
191
+ return this._options.maxSessions;
192
+ }
193
+
194
+ /**
195
+ * Session timeout in milliseconds.
196
+ */
197
+ get sessionTimeoutMs(): number {
198
+ return this._options.sessionTimeoutMs;
199
+ }
200
+
201
+ /**
202
+ * Whether the manager is shutting down.
203
+ */
204
+ get isShuttingDown(): boolean {
205
+ return this._isShuttingDown;
206
+ }
207
+
208
+ /**
209
+ * Event emitter for subscribing to session events.
210
+ */
211
+ get events(): McpEventEmitter {
212
+ return this._events;
213
+ }
214
+
215
+ /**
216
+ * Session metrics (if enabled).
217
+ */
218
+ get metrics(): SessionManagerMetrics | null {
219
+ return this._metrics;
220
+ }
221
+
222
+ // ============================================================================
223
+ // Session Management
224
+ // ============================================================================
225
+
226
+ /**
227
+ * Creates a new MCP session with the specified transport configuration.
228
+ *
229
+ * @param transportConfig - Transport configuration for the session
230
+ * @param clientOptions - Optional client configuration
231
+ * @returns The created session information
232
+ * @throws {McpSessionError} If max sessions reached or creation fails
233
+ */
234
+ async createSession(
235
+ transportConfig: TransportConfig,
236
+ clientOptions?: Partial<EnhancedClientOptions>
237
+ ): Promise<McpSession> {
238
+ if (this._isShuttingDown) {
239
+ throw new McpSessionError(
240
+ McpErrorCode.InternalError,
241
+ 'SessionManager is shutting down'
242
+ );
243
+ }
244
+
245
+ const timer = this._metrics?.sessionCreationDuration.start();
246
+
247
+ // Check session limit
248
+ if (this._sessions.size >= this._options.maxSessions) {
249
+ // Try to clean up expired sessions first
250
+ this._cleanupExpiredSessions();
251
+
252
+ if (this._sessions.size >= this._options.maxSessions) {
253
+ // Still at limit - evict the oldest session
254
+ const oldestSession = this._findOldestSession();
255
+ if (oldestSession) {
256
+ this._logger.info('Evicting oldest session', { data: { sessionId: oldestSession.session.id } });
257
+ this._metrics?.sessionsEvicted.increment();
258
+ await this._destroySessionContext(oldestSession, 'evicted');
259
+ }
260
+ }
261
+
262
+ // Check again after cleanup
263
+ if (this._sessions.size >= this._options.maxSessions) {
264
+ timer?.cancel();
265
+ throw new McpSessionError(
266
+ McpErrorCode.MaxSessionsReached,
267
+ `Maximum sessions (${this._options.maxSessions}) reached`
268
+ );
269
+ }
270
+ }
271
+
272
+ const sessionId = randomUUID();
273
+ const now = new Date();
274
+
275
+ this._logger.info('Creating session', { sessionId, data: { transportType: transportConfig.type } });
276
+
277
+ try {
278
+ // Create client with merged options
279
+ const mergedClientOptions: EnhancedClientOptions = {
280
+ name: 'mcp-session',
281
+ version: '1.0.0',
282
+ ...this._clientOptions,
283
+ ...clientOptions,
284
+ // Share events and logger with the client
285
+ logger: clientOptions?.logger ?? this._logger,
286
+ events: clientOptions?.events ?? this._events,
287
+ };
288
+
289
+ const client = new McpClient(mergedClientOptions);
290
+
291
+ // Connect the client
292
+ await client.connect(transportConfig);
293
+
294
+ // Create session object
295
+ const session: McpSession = {
296
+ id: sessionId,
297
+ transportConfig,
298
+ state: 'connected',
299
+ capabilities: client.capabilities,
300
+ serverInfo: client.serverInfo,
301
+ createdAt: now,
302
+ lastUsedAt: now,
303
+ };
304
+
305
+ // Set up cleanup timer
306
+ const cleanupTimer = setTimeout(() => {
307
+ this._onSessionTimeout(sessionId);
308
+ }, this._options.sessionTimeoutMs);
309
+
310
+ // Store session context
311
+ const context: SessionContext = {
312
+ session,
313
+ client,
314
+ cleanupTimer,
315
+ };
316
+
317
+ this._sessions.set(sessionId, context);
318
+
319
+ // Update metrics
320
+ this._metrics?.sessionsCreated.increment();
321
+ this._metrics?.sessionsActive.set(this._sessions.size);
322
+ timer?.end();
323
+
324
+ // Emit event
325
+ this._events.emit({
326
+ type: 'session:created',
327
+ sessionId,
328
+ timestamp: now,
329
+ });
330
+
331
+ this._logger.info('Session created', {
332
+ sessionId,
333
+ data: {
334
+ serverName: client.serverInfo?.name,
335
+ serverVersion: client.serverInfo?.version,
336
+ },
337
+ });
338
+
339
+ return { ...session };
340
+ } catch (error) {
341
+ timer?.cancel();
342
+ this._logger.error('Failed to create session', {
343
+ data: { errorMessage: error instanceof Error ? error.message : String(error) },
344
+ });
345
+ throw new McpSessionError(
346
+ McpErrorCode.ConnectionFailed,
347
+ `Failed to create session: ${error instanceof Error ? error.message : String(error)}`,
348
+ error
349
+ );
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Gets a session by ID.
355
+ *
356
+ * @param sessionId - The session ID to retrieve
357
+ * @returns The session if found, undefined otherwise
358
+ */
359
+ getSession(sessionId: string): McpSession | undefined {
360
+ const context = this._sessions.get(sessionId);
361
+ if (!context) {
362
+ return undefined;
363
+ }
364
+
365
+ // Update last used time and reset timer
366
+ this._touchSession(context);
367
+
368
+ return { ...context.session };
369
+ }
370
+
371
+ /**
372
+ * Gets the MCP client for a session.
373
+ *
374
+ * @param sessionId - The session ID
375
+ * @returns The McpClient if session exists and is connected, undefined otherwise
376
+ */
377
+ getClient(sessionId: string): McpClient | undefined {
378
+ const context = this._sessions.get(sessionId);
379
+ if (!context || !context.client.isConnected) {
380
+ return undefined;
381
+ }
382
+
383
+ // Update last used time and reset timer
384
+ this._touchSession(context);
385
+
386
+ return context.client;
387
+ }
388
+
389
+ /**
390
+ * Gets all active session IDs.
391
+ *
392
+ * @returns Array of active session IDs
393
+ */
394
+ getSessionIds(): readonly string[] {
395
+ return Array.from(this._sessions.keys());
396
+ }
397
+
398
+ /**
399
+ * Gets all active sessions.
400
+ *
401
+ * @returns Array of active sessions
402
+ */
403
+ getAllSessions(): readonly McpSession[] {
404
+ return Array.from(this._sessions.values()).map((ctx) => ({ ...ctx.session }));
405
+ }
406
+
407
+ /**
408
+ * Destroys a session and releases its resources.
409
+ *
410
+ * @param sessionId - The session ID to destroy
411
+ * @returns True if the session was destroyed, false if not found
412
+ */
413
+ async destroySession(sessionId: string): Promise<boolean> {
414
+ const context = this._sessions.get(sessionId);
415
+ if (!context) {
416
+ return false;
417
+ }
418
+
419
+ await this._destroySessionContext(context);
420
+ return true;
421
+ }
422
+
423
+ /**
424
+ * Shuts down the session manager and destroys all sessions.
425
+ */
426
+ async shutdown(): Promise<void> {
427
+ if (this._isShuttingDown) {
428
+ return;
429
+ }
430
+
431
+ this._isShuttingDown = true;
432
+ this._stopHealthCheck();
433
+ this._logger.info('Shutting down SessionManager...', { data: { sessionCount: this._sessions.size } });
434
+
435
+ const destroyPromises = Array.from(this._sessions.values()).map((context) =>
436
+ this._destroySessionContext(context, 'shutdown').catch((error) => {
437
+ this._logger.error('Error destroying session during shutdown', {
438
+ sessionId: context.session.id,
439
+ data: { errorMessage: error instanceof Error ? error.message : String(error) },
440
+ });
441
+ })
442
+ );
443
+
444
+ await Promise.all(destroyPromises);
445
+
446
+ this._sessions.clear();
447
+ this._isShuttingDown = false;
448
+ this._logger.info('SessionManager shut down');
449
+ }
450
+
451
+ // ============================================================================
452
+ // Session Queries
453
+ // ============================================================================
454
+
455
+ /**
456
+ * Checks if a session exists.
457
+ *
458
+ * @param sessionId - The session ID to check
459
+ * @returns True if the session exists
460
+ */
461
+ hasSession(sessionId: string): boolean {
462
+ return this._sessions.has(sessionId);
463
+ }
464
+
465
+ /**
466
+ * Gets the state of a session.
467
+ *
468
+ * @param sessionId - The session ID
469
+ * @returns The session state, or undefined if not found
470
+ */
471
+ getSessionState(sessionId: string): ConnectionState | undefined {
472
+ const context = this._sessions.get(sessionId);
473
+ return context?.client.state;
474
+ }
475
+
476
+ /**
477
+ * Refreshes a session's timeout, keeping it alive.
478
+ *
479
+ * @param sessionId - The session ID to refresh
480
+ * @returns True if the session was refreshed, false if not found
481
+ */
482
+ refreshSession(sessionId: string): boolean {
483
+ const context = this._sessions.get(sessionId);
484
+ if (!context) {
485
+ return false;
486
+ }
487
+
488
+ this._touchSession(context);
489
+ return true;
490
+ }
491
+
492
+ /**
493
+ * Gets the health status of a session.
494
+ *
495
+ * @param sessionId - The session ID
496
+ * @returns Session health status, or undefined if not found
497
+ */
498
+ getSessionHealth(sessionId: string): SessionHealthStatus | undefined {
499
+ const context = this._sessions.get(sessionId);
500
+ if (!context) {
501
+ return undefined;
502
+ }
503
+
504
+ const now = Date.now();
505
+
506
+ return {
507
+ sessionId,
508
+ state: context.client.state,
509
+ healthy: context.client.isConnected && context.client.state !== 'error',
510
+ lastUsedAt: context.session.lastUsedAt,
511
+ createdAt: context.session.createdAt,
512
+ ageMs: now - context.session.createdAt.getTime(),
513
+ idleMs: now - context.session.lastUsedAt.getTime(),
514
+ };
515
+ }
516
+
517
+ /**
518
+ * Gets health status for all sessions.
519
+ *
520
+ * @returns Array of session health statuses
521
+ */
522
+ getAllSessionHealth(): readonly SessionHealthStatus[] {
523
+ return Array.from(this._sessions.keys()).map(
524
+ (sessionId) => this.getSessionHealth(sessionId)!
525
+ );
526
+ }
527
+
528
+ // ============================================================================
529
+ // Private Methods
530
+ // ============================================================================
531
+
532
+ /**
533
+ * Updates a session's last used time and resets its cleanup timer.
534
+ */
535
+ private _touchSession(context: SessionContext): void {
536
+ context.session.lastUsedAt = new Date();
537
+
538
+ // Reset cleanup timer
539
+ clearTimeout(context.cleanupTimer);
540
+ context.cleanupTimer = setTimeout(() => {
541
+ this._onSessionTimeout(context.session.id);
542
+ }, this._options.sessionTimeoutMs);
543
+ }
544
+
545
+ /**
546
+ * Handles session timeout expiration.
547
+ */
548
+ private _onSessionTimeout(sessionId: string): void {
549
+ const context = this._sessions.get(sessionId);
550
+ if (context) {
551
+ this._logger.info('Session timed out', { sessionId });
552
+ this._metrics?.sessionsTimedOut.increment();
553
+ this._destroySessionContext(context, 'timeout').catch((error) => {
554
+ this._logger.error('Error destroying timed out session', {
555
+ sessionId,
556
+ data: { errorMessage: error instanceof Error ? error.message : String(error) },
557
+ });
558
+ });
559
+ }
560
+ }
561
+
562
+ /**
563
+ * Destroys a session context and cleans up resources.
564
+ */
565
+ private async _destroySessionContext(
566
+ context: SessionContext,
567
+ reason: 'timeout' | 'manual' | 'evicted' | 'error' | 'shutdown' = 'manual'
568
+ ): Promise<void> {
569
+ const sessionId = context.session.id;
570
+ const timer = this._metrics?.sessionDuration.start();
571
+
572
+ this._logger.info('Destroying session', { sessionId, data: { reason } });
573
+
574
+ // Clear timeout
575
+ clearTimeout(context.cleanupTimer);
576
+
577
+ // Remove from map first to prevent re-entry
578
+ this._sessions.delete(sessionId);
579
+
580
+ // Disconnect client
581
+ try {
582
+ await context.client.disconnect();
583
+ } catch (error) {
584
+ this._logger.warn('Error disconnecting client', {
585
+ sessionId,
586
+ data: { errorMessage: error instanceof Error ? error.message : String(error) },
587
+ });
588
+ }
589
+
590
+ // Update metrics
591
+ this._metrics?.sessionsDestroyed.increment();
592
+ this._metrics?.sessionsActive.set(this._sessions.size);
593
+ timer?.end();
594
+
595
+ // Emit event
596
+ this._events.emit({
597
+ type: 'session:destroyed',
598
+ sessionId,
599
+ reason,
600
+ timestamp: new Date(),
601
+ });
602
+
603
+ this._logger.info('Session destroyed', { sessionId });
604
+ }
605
+
606
+ /**
607
+ * Finds the oldest session based on last used time.
608
+ */
609
+ private _findOldestSession(): SessionContext | undefined {
610
+ let oldest: SessionContext | undefined;
611
+
612
+ for (const context of this._sessions.values()) {
613
+ if (!oldest || context.session.lastUsedAt < oldest.session.lastUsedAt) {
614
+ oldest = context;
615
+ }
616
+ }
617
+
618
+ return oldest;
619
+ }
620
+
621
+ /**
622
+ * Cleans up expired sessions.
623
+ */
624
+ private _cleanupExpiredSessions(): void {
625
+ const now = Date.now();
626
+ const expiredSessions: SessionContext[] = [];
627
+
628
+ for (const context of this._sessions.values()) {
629
+ const age = now - context.session.lastUsedAt.getTime();
630
+ if (age >= this._options.sessionTimeoutMs) {
631
+ expiredSessions.push(context);
632
+ }
633
+ }
634
+
635
+ for (const context of expiredSessions) {
636
+ this._destroySessionContext(context, 'timeout').catch((error) => {
637
+ this._logger.error('Error cleaning up expired session', {
638
+ sessionId: context.session.id,
639
+ data: { errorMessage: error instanceof Error ? error.message : String(error) },
640
+ });
641
+ });
642
+ }
643
+
644
+ if (expiredSessions.length > 0) {
645
+ this._logger.info('Cleaned up expired sessions', { data: { count: expiredSessions.length } });
646
+ }
647
+ }
648
+
649
+ /**
650
+ * Start health check interval.
651
+ */
652
+ private _startHealthCheck(intervalMs: number): void {
653
+ this._stopHealthCheck();
654
+
655
+ this._healthCheckInterval = setInterval(() => {
656
+ if (this._isShuttingDown) return;
657
+
658
+ this._performHealthCheck();
659
+ }, intervalMs);
660
+ }
661
+
662
+ /**
663
+ * Stop health check interval.
664
+ */
665
+ private _stopHealthCheck(): void {
666
+ if (this._healthCheckInterval) {
667
+ clearInterval(this._healthCheckInterval);
668
+ this._healthCheckInterval = null;
669
+ }
670
+ }
671
+
672
+ /**
673
+ * Perform health check on all sessions.
674
+ */
675
+ private _performHealthCheck(): void {
676
+ const unhealthySessions: SessionContext[] = [];
677
+
678
+ for (const context of this._sessions.values()) {
679
+ if (!context.client.isConnected || context.client.state === 'error') {
680
+ unhealthySessions.push(context);
681
+ }
682
+ }
683
+
684
+ for (const context of unhealthySessions) {
685
+ this._logger.warn('Unhealthy session detected', {
686
+ sessionId: context.session.id,
687
+ data: { state: context.client.state },
688
+ });
689
+
690
+ this._destroySessionContext(context, 'error').catch((error) => {
691
+ this._logger.error('Error destroying unhealthy session', {
692
+ sessionId: context.session.id,
693
+ data: { errorMessage: error instanceof Error ? error.message : String(error) },
694
+ });
695
+ });
696
+ }
697
+ }
698
+
699
+ /**
700
+ * Logs a message if debug mode is enabled.
701
+ * @deprecated Use this._logger instead
702
+ */
703
+ private _log(message: string): void {
704
+ if (this._options.debug) {
705
+ console.log(`[SessionManager] ${message}`);
706
+ }
707
+ }
708
+ }
709
+
710
+ // ============================================================================
711
+ // Internal Types
712
+ // ============================================================================
713
+
714
+ /**
715
+ * Internal session context with client and cleanup timer
716
+ */
717
+ interface SessionContext {
718
+ session: McpSession;
719
+ client: McpClient;
720
+ cleanupTimer: ReturnType<typeof setTimeout>;
721
+ }
722
+
723
+ // ============================================================================
724
+ // Convenience Functions
725
+ // ============================================================================
726
+
727
+ /**
728
+ * Gets the singleton SessionManager instance.
729
+ *
730
+ * @param options - Optional configuration (only used on first call)
731
+ * @returns The singleton SessionManager instance
732
+ */
733
+ export function getSessionManager(options?: EnhancedSessionManagerOptions): SessionManager {
734
+ return SessionManager.getInstance(options);
735
+ }
736
+
737
+ /**
738
+ * Creates a new session using the default SessionManager.
739
+ *
740
+ * @param transportConfig - Transport configuration
741
+ * @param clientOptions - Optional client options
742
+ * @returns The created session
743
+ */
744
+ export async function createSession(
745
+ transportConfig: TransportConfig,
746
+ clientOptions?: Partial<EnhancedClientOptions>
747
+ ): Promise<McpSession> {
748
+ return SessionManager.getInstance().createSession(transportConfig, clientOptions);
749
+ }
750
+
751
+ /**
752
+ * Gets a client from the default SessionManager.
753
+ *
754
+ * @param sessionId - Session ID
755
+ * @returns The client if found
756
+ */
757
+ export function getClient(sessionId: string): McpClient | undefined {
758
+ return SessionManager.getInstance().getClient(sessionId);
759
+ }
760
+
761
+ /**
762
+ * Destroys a session in the default SessionManager.
763
+ *
764
+ * @param sessionId - Session ID
765
+ * @returns True if destroyed
766
+ */
767
+ export async function destroySession(sessionId: string): Promise<boolean> {
768
+ return SessionManager.getInstance().destroySession(sessionId);
769
+ }
770
+
771
+ /**
772
+ * Gets session health from the default SessionManager.
773
+ *
774
+ * @param sessionId - Session ID
775
+ * @returns Session health status if found
776
+ */
777
+ export function getSessionHealth(sessionId: string): SessionHealthStatus | undefined {
778
+ return SessionManager.getInstance().getSessionHealth(sessionId);
779
+ }