@dotsetlabs/bellwether 0.10.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 (403) hide show
  1. package/CHANGELOG.md +291 -0
  2. package/LICENSE +21 -0
  3. package/README.md +739 -0
  4. package/dist/auth/credentials.d.ts +64 -0
  5. package/dist/auth/credentials.js +218 -0
  6. package/dist/auth/index.d.ts +6 -0
  7. package/dist/auth/index.js +6 -0
  8. package/dist/auth/keychain.d.ts +64 -0
  9. package/dist/auth/keychain.js +268 -0
  10. package/dist/baseline/ab-testing.d.ts +80 -0
  11. package/dist/baseline/ab-testing.js +236 -0
  12. package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
  13. package/dist/baseline/ai-compatibility-scorer.js +606 -0
  14. package/dist/baseline/calibration.d.ts +77 -0
  15. package/dist/baseline/calibration.js +136 -0
  16. package/dist/baseline/category-matching.d.ts +85 -0
  17. package/dist/baseline/category-matching.js +289 -0
  18. package/dist/baseline/change-impact-analyzer.d.ts +98 -0
  19. package/dist/baseline/change-impact-analyzer.js +592 -0
  20. package/dist/baseline/comparator.d.ts +64 -0
  21. package/dist/baseline/comparator.js +916 -0
  22. package/dist/baseline/confidence.d.ts +55 -0
  23. package/dist/baseline/confidence.js +122 -0
  24. package/dist/baseline/converter.d.ts +61 -0
  25. package/dist/baseline/converter.js +585 -0
  26. package/dist/baseline/dependency-analyzer.d.ts +89 -0
  27. package/dist/baseline/dependency-analyzer.js +567 -0
  28. package/dist/baseline/deprecation-tracker.d.ts +133 -0
  29. package/dist/baseline/deprecation-tracker.js +322 -0
  30. package/dist/baseline/diff.d.ts +55 -0
  31. package/dist/baseline/diff.js +1584 -0
  32. package/dist/baseline/documentation-scorer.d.ts +205 -0
  33. package/dist/baseline/documentation-scorer.js +466 -0
  34. package/dist/baseline/embeddings.d.ts +118 -0
  35. package/dist/baseline/embeddings.js +251 -0
  36. package/dist/baseline/error-analyzer.d.ts +198 -0
  37. package/dist/baseline/error-analyzer.js +721 -0
  38. package/dist/baseline/evaluation/evaluator.d.ts +42 -0
  39. package/dist/baseline/evaluation/evaluator.js +323 -0
  40. package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
  41. package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
  42. package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
  43. package/dist/baseline/evaluation/golden-dataset.js +717 -0
  44. package/dist/baseline/evaluation/index.d.ts +15 -0
  45. package/dist/baseline/evaluation/index.js +15 -0
  46. package/dist/baseline/evaluation/types.d.ts +186 -0
  47. package/dist/baseline/evaluation/types.js +8 -0
  48. package/dist/baseline/external-dependency-detector.d.ts +181 -0
  49. package/dist/baseline/external-dependency-detector.js +524 -0
  50. package/dist/baseline/golden-output.d.ts +162 -0
  51. package/dist/baseline/golden-output.js +636 -0
  52. package/dist/baseline/health-scorer.d.ts +174 -0
  53. package/dist/baseline/health-scorer.js +451 -0
  54. package/dist/baseline/incremental-checker.d.ts +97 -0
  55. package/dist/baseline/incremental-checker.js +174 -0
  56. package/dist/baseline/index.d.ts +31 -0
  57. package/dist/baseline/index.js +42 -0
  58. package/dist/baseline/migration-generator.d.ts +137 -0
  59. package/dist/baseline/migration-generator.js +554 -0
  60. package/dist/baseline/migrations.d.ts +60 -0
  61. package/dist/baseline/migrations.js +197 -0
  62. package/dist/baseline/performance-tracker.d.ts +214 -0
  63. package/dist/baseline/performance-tracker.js +577 -0
  64. package/dist/baseline/pr-comment-generator.d.ts +117 -0
  65. package/dist/baseline/pr-comment-generator.js +546 -0
  66. package/dist/baseline/response-fingerprint.d.ts +127 -0
  67. package/dist/baseline/response-fingerprint.js +728 -0
  68. package/dist/baseline/response-schema-tracker.d.ts +129 -0
  69. package/dist/baseline/response-schema-tracker.js +420 -0
  70. package/dist/baseline/risk-scorer.d.ts +54 -0
  71. package/dist/baseline/risk-scorer.js +434 -0
  72. package/dist/baseline/saver.d.ts +89 -0
  73. package/dist/baseline/saver.js +554 -0
  74. package/dist/baseline/scenario-generator.d.ts +151 -0
  75. package/dist/baseline/scenario-generator.js +905 -0
  76. package/dist/baseline/schema-compare.d.ts +86 -0
  77. package/dist/baseline/schema-compare.js +557 -0
  78. package/dist/baseline/schema-evolution.d.ts +189 -0
  79. package/dist/baseline/schema-evolution.js +467 -0
  80. package/dist/baseline/semantic.d.ts +203 -0
  81. package/dist/baseline/semantic.js +908 -0
  82. package/dist/baseline/synonyms.d.ts +60 -0
  83. package/dist/baseline/synonyms.js +386 -0
  84. package/dist/baseline/telemetry.d.ts +165 -0
  85. package/dist/baseline/telemetry.js +294 -0
  86. package/dist/baseline/test-pruner.d.ts +120 -0
  87. package/dist/baseline/test-pruner.js +387 -0
  88. package/dist/baseline/types.d.ts +449 -0
  89. package/dist/baseline/types.js +5 -0
  90. package/dist/baseline/version.d.ts +138 -0
  91. package/dist/baseline/version.js +206 -0
  92. package/dist/cache/index.d.ts +5 -0
  93. package/dist/cache/index.js +5 -0
  94. package/dist/cache/response-cache.d.ts +151 -0
  95. package/dist/cache/response-cache.js +287 -0
  96. package/dist/ci/index.d.ts +60 -0
  97. package/dist/ci/index.js +342 -0
  98. package/dist/cli/commands/auth.d.ts +12 -0
  99. package/dist/cli/commands/auth.js +352 -0
  100. package/dist/cli/commands/badge.d.ts +3 -0
  101. package/dist/cli/commands/badge.js +74 -0
  102. package/dist/cli/commands/baseline-accept.d.ts +15 -0
  103. package/dist/cli/commands/baseline-accept.js +178 -0
  104. package/dist/cli/commands/baseline-migrate.d.ts +12 -0
  105. package/dist/cli/commands/baseline-migrate.js +164 -0
  106. package/dist/cli/commands/baseline.d.ts +14 -0
  107. package/dist/cli/commands/baseline.js +449 -0
  108. package/dist/cli/commands/beta.d.ts +10 -0
  109. package/dist/cli/commands/beta.js +231 -0
  110. package/dist/cli/commands/check.d.ts +11 -0
  111. package/dist/cli/commands/check.js +820 -0
  112. package/dist/cli/commands/cloud/badge.d.ts +3 -0
  113. package/dist/cli/commands/cloud/badge.js +74 -0
  114. package/dist/cli/commands/cloud/diff.d.ts +6 -0
  115. package/dist/cli/commands/cloud/diff.js +79 -0
  116. package/dist/cli/commands/cloud/history.d.ts +6 -0
  117. package/dist/cli/commands/cloud/history.js +102 -0
  118. package/dist/cli/commands/cloud/link.d.ts +9 -0
  119. package/dist/cli/commands/cloud/link.js +119 -0
  120. package/dist/cli/commands/cloud/login.d.ts +7 -0
  121. package/dist/cli/commands/cloud/login.js +499 -0
  122. package/dist/cli/commands/cloud/projects.d.ts +6 -0
  123. package/dist/cli/commands/cloud/projects.js +44 -0
  124. package/dist/cli/commands/cloud/shared.d.ts +7 -0
  125. package/dist/cli/commands/cloud/shared.js +42 -0
  126. package/dist/cli/commands/cloud/teams.d.ts +8 -0
  127. package/dist/cli/commands/cloud/teams.js +169 -0
  128. package/dist/cli/commands/cloud/upload.d.ts +8 -0
  129. package/dist/cli/commands/cloud/upload.js +181 -0
  130. package/dist/cli/commands/contract.d.ts +11 -0
  131. package/dist/cli/commands/contract.js +280 -0
  132. package/dist/cli/commands/discover.d.ts +3 -0
  133. package/dist/cli/commands/discover.js +82 -0
  134. package/dist/cli/commands/eval.d.ts +9 -0
  135. package/dist/cli/commands/eval.js +187 -0
  136. package/dist/cli/commands/explore.d.ts +11 -0
  137. package/dist/cli/commands/explore.js +437 -0
  138. package/dist/cli/commands/feedback.d.ts +9 -0
  139. package/dist/cli/commands/feedback.js +174 -0
  140. package/dist/cli/commands/golden.d.ts +12 -0
  141. package/dist/cli/commands/golden.js +407 -0
  142. package/dist/cli/commands/history.d.ts +10 -0
  143. package/dist/cli/commands/history.js +202 -0
  144. package/dist/cli/commands/init.d.ts +9 -0
  145. package/dist/cli/commands/init.js +219 -0
  146. package/dist/cli/commands/interview.d.ts +3 -0
  147. package/dist/cli/commands/interview.js +903 -0
  148. package/dist/cli/commands/link.d.ts +10 -0
  149. package/dist/cli/commands/link.js +169 -0
  150. package/dist/cli/commands/login.d.ts +7 -0
  151. package/dist/cli/commands/login.js +499 -0
  152. package/dist/cli/commands/preset.d.ts +33 -0
  153. package/dist/cli/commands/preset.js +297 -0
  154. package/dist/cli/commands/profile.d.ts +33 -0
  155. package/dist/cli/commands/profile.js +286 -0
  156. package/dist/cli/commands/registry.d.ts +11 -0
  157. package/dist/cli/commands/registry.js +146 -0
  158. package/dist/cli/commands/shared.d.ts +79 -0
  159. package/dist/cli/commands/shared.js +196 -0
  160. package/dist/cli/commands/teams.d.ts +8 -0
  161. package/dist/cli/commands/teams.js +169 -0
  162. package/dist/cli/commands/test.d.ts +9 -0
  163. package/dist/cli/commands/test.js +500 -0
  164. package/dist/cli/commands/upload.d.ts +8 -0
  165. package/dist/cli/commands/upload.js +223 -0
  166. package/dist/cli/commands/validate-config.d.ts +6 -0
  167. package/dist/cli/commands/validate-config.js +35 -0
  168. package/dist/cli/commands/verify.d.ts +11 -0
  169. package/dist/cli/commands/verify.js +283 -0
  170. package/dist/cli/commands/watch.d.ts +12 -0
  171. package/dist/cli/commands/watch.js +253 -0
  172. package/dist/cli/index.d.ts +3 -0
  173. package/dist/cli/index.js +178 -0
  174. package/dist/cli/interactive.d.ts +47 -0
  175. package/dist/cli/interactive.js +216 -0
  176. package/dist/cli/output/terminal-reporter.d.ts +19 -0
  177. package/dist/cli/output/terminal-reporter.js +104 -0
  178. package/dist/cli/output.d.ts +226 -0
  179. package/dist/cli/output.js +438 -0
  180. package/dist/cli/utils/env.d.ts +5 -0
  181. package/dist/cli/utils/env.js +14 -0
  182. package/dist/cli/utils/progress.d.ts +59 -0
  183. package/dist/cli/utils/progress.js +206 -0
  184. package/dist/cli/utils/server-context.d.ts +10 -0
  185. package/dist/cli/utils/server-context.js +36 -0
  186. package/dist/cloud/auth.d.ts +144 -0
  187. package/dist/cloud/auth.js +374 -0
  188. package/dist/cloud/client.d.ts +24 -0
  189. package/dist/cloud/client.js +65 -0
  190. package/dist/cloud/http-client.d.ts +38 -0
  191. package/dist/cloud/http-client.js +215 -0
  192. package/dist/cloud/index.d.ts +23 -0
  193. package/dist/cloud/index.js +25 -0
  194. package/dist/cloud/mock-client.d.ts +107 -0
  195. package/dist/cloud/mock-client.js +545 -0
  196. package/dist/cloud/types.d.ts +515 -0
  197. package/dist/cloud/types.js +15 -0
  198. package/dist/config/defaults.d.ts +160 -0
  199. package/dist/config/defaults.js +169 -0
  200. package/dist/config/loader.d.ts +24 -0
  201. package/dist/config/loader.js +122 -0
  202. package/dist/config/template.d.ts +42 -0
  203. package/dist/config/template.js +647 -0
  204. package/dist/config/validator.d.ts +2112 -0
  205. package/dist/config/validator.js +658 -0
  206. package/dist/constants/cloud.d.ts +107 -0
  207. package/dist/constants/cloud.js +110 -0
  208. package/dist/constants/core.d.ts +521 -0
  209. package/dist/constants/core.js +556 -0
  210. package/dist/constants/testing.d.ts +1283 -0
  211. package/dist/constants/testing.js +1568 -0
  212. package/dist/constants.d.ts +10 -0
  213. package/dist/constants.js +10 -0
  214. package/dist/contract/index.d.ts +6 -0
  215. package/dist/contract/index.js +5 -0
  216. package/dist/contract/validator.d.ts +177 -0
  217. package/dist/contract/validator.js +574 -0
  218. package/dist/cost/index.d.ts +6 -0
  219. package/dist/cost/index.js +5 -0
  220. package/dist/cost/tracker.d.ts +134 -0
  221. package/dist/cost/tracker.js +313 -0
  222. package/dist/discovery/discovery.d.ts +16 -0
  223. package/dist/discovery/discovery.js +173 -0
  224. package/dist/discovery/types.d.ts +51 -0
  225. package/dist/discovery/types.js +2 -0
  226. package/dist/docs/agents.d.ts +3 -0
  227. package/dist/docs/agents.js +995 -0
  228. package/dist/docs/contract.d.ts +51 -0
  229. package/dist/docs/contract.js +1681 -0
  230. package/dist/docs/generator.d.ts +4 -0
  231. package/dist/docs/generator.js +4 -0
  232. package/dist/docs/html-reporter.d.ts +9 -0
  233. package/dist/docs/html-reporter.js +757 -0
  234. package/dist/docs/index.d.ts +10 -0
  235. package/dist/docs/index.js +11 -0
  236. package/dist/docs/junit-reporter.d.ts +18 -0
  237. package/dist/docs/junit-reporter.js +210 -0
  238. package/dist/docs/report.d.ts +14 -0
  239. package/dist/docs/report.js +44 -0
  240. package/dist/docs/sarif-reporter.d.ts +19 -0
  241. package/dist/docs/sarif-reporter.js +335 -0
  242. package/dist/docs/shared.d.ts +35 -0
  243. package/dist/docs/shared.js +162 -0
  244. package/dist/docs/templates.d.ts +12 -0
  245. package/dist/docs/templates.js +76 -0
  246. package/dist/errors/index.d.ts +6 -0
  247. package/dist/errors/index.js +6 -0
  248. package/dist/errors/retry.d.ts +92 -0
  249. package/dist/errors/retry.js +323 -0
  250. package/dist/errors/types.d.ts +321 -0
  251. package/dist/errors/types.js +584 -0
  252. package/dist/index.d.ts +32 -0
  253. package/dist/index.js +32 -0
  254. package/dist/interview/dependency-resolver.d.ts +11 -0
  255. package/dist/interview/dependency-resolver.js +32 -0
  256. package/dist/interview/interviewer.d.ts +232 -0
  257. package/dist/interview/interviewer.js +1939 -0
  258. package/dist/interview/mock-response-generator.d.ts +7 -0
  259. package/dist/interview/mock-response-generator.js +102 -0
  260. package/dist/interview/orchestrator.d.ts +237 -0
  261. package/dist/interview/orchestrator.js +1296 -0
  262. package/dist/interview/rate-limiter.d.ts +15 -0
  263. package/dist/interview/rate-limiter.js +55 -0
  264. package/dist/interview/response-validator.d.ts +10 -0
  265. package/dist/interview/response-validator.js +132 -0
  266. package/dist/interview/schema-inferrer.d.ts +8 -0
  267. package/dist/interview/schema-inferrer.js +71 -0
  268. package/dist/interview/schema-test-generator.d.ts +71 -0
  269. package/dist/interview/schema-test-generator.js +834 -0
  270. package/dist/interview/smart-value-generator.d.ts +155 -0
  271. package/dist/interview/smart-value-generator.js +554 -0
  272. package/dist/interview/stateful-test-runner.d.ts +19 -0
  273. package/dist/interview/stateful-test-runner.js +106 -0
  274. package/dist/interview/types.d.ts +561 -0
  275. package/dist/interview/types.js +2 -0
  276. package/dist/llm/anthropic.d.ts +41 -0
  277. package/dist/llm/anthropic.js +355 -0
  278. package/dist/llm/client.d.ts +123 -0
  279. package/dist/llm/client.js +42 -0
  280. package/dist/llm/factory.d.ts +38 -0
  281. package/dist/llm/factory.js +145 -0
  282. package/dist/llm/fallback.d.ts +140 -0
  283. package/dist/llm/fallback.js +379 -0
  284. package/dist/llm/index.d.ts +18 -0
  285. package/dist/llm/index.js +15 -0
  286. package/dist/llm/ollama.d.ts +37 -0
  287. package/dist/llm/ollama.js +330 -0
  288. package/dist/llm/openai.d.ts +25 -0
  289. package/dist/llm/openai.js +320 -0
  290. package/dist/llm/token-budget.d.ts +161 -0
  291. package/dist/llm/token-budget.js +395 -0
  292. package/dist/logging/logger.d.ts +70 -0
  293. package/dist/logging/logger.js +130 -0
  294. package/dist/metrics/collector.d.ts +106 -0
  295. package/dist/metrics/collector.js +547 -0
  296. package/dist/metrics/index.d.ts +7 -0
  297. package/dist/metrics/index.js +7 -0
  298. package/dist/metrics/prometheus.d.ts +20 -0
  299. package/dist/metrics/prometheus.js +241 -0
  300. package/dist/metrics/types.d.ts +209 -0
  301. package/dist/metrics/types.js +5 -0
  302. package/dist/persona/builtins.d.ts +54 -0
  303. package/dist/persona/builtins.js +219 -0
  304. package/dist/persona/index.d.ts +8 -0
  305. package/dist/persona/index.js +8 -0
  306. package/dist/persona/loader.d.ts +30 -0
  307. package/dist/persona/loader.js +190 -0
  308. package/dist/persona/types.d.ts +144 -0
  309. package/dist/persona/types.js +5 -0
  310. package/dist/persona/validation.d.ts +94 -0
  311. package/dist/persona/validation.js +332 -0
  312. package/dist/prompts/index.d.ts +5 -0
  313. package/dist/prompts/index.js +5 -0
  314. package/dist/prompts/templates.d.ts +180 -0
  315. package/dist/prompts/templates.js +431 -0
  316. package/dist/registry/client.d.ts +49 -0
  317. package/dist/registry/client.js +191 -0
  318. package/dist/registry/index.d.ts +7 -0
  319. package/dist/registry/index.js +6 -0
  320. package/dist/registry/types.d.ts +140 -0
  321. package/dist/registry/types.js +6 -0
  322. package/dist/scenarios/evaluator.d.ts +43 -0
  323. package/dist/scenarios/evaluator.js +206 -0
  324. package/dist/scenarios/index.d.ts +10 -0
  325. package/dist/scenarios/index.js +9 -0
  326. package/dist/scenarios/loader.d.ts +20 -0
  327. package/dist/scenarios/loader.js +285 -0
  328. package/dist/scenarios/types.d.ts +153 -0
  329. package/dist/scenarios/types.js +8 -0
  330. package/dist/security/index.d.ts +17 -0
  331. package/dist/security/index.js +18 -0
  332. package/dist/security/payloads.d.ts +61 -0
  333. package/dist/security/payloads.js +268 -0
  334. package/dist/security/security-tester.d.ts +42 -0
  335. package/dist/security/security-tester.js +582 -0
  336. package/dist/security/types.d.ts +166 -0
  337. package/dist/security/types.js +8 -0
  338. package/dist/transport/base-transport.d.ts +59 -0
  339. package/dist/transport/base-transport.js +38 -0
  340. package/dist/transport/http-transport.d.ts +67 -0
  341. package/dist/transport/http-transport.js +238 -0
  342. package/dist/transport/mcp-client.d.ts +141 -0
  343. package/dist/transport/mcp-client.js +496 -0
  344. package/dist/transport/sse-transport.d.ts +88 -0
  345. package/dist/transport/sse-transport.js +316 -0
  346. package/dist/transport/stdio-transport.d.ts +43 -0
  347. package/dist/transport/stdio-transport.js +238 -0
  348. package/dist/transport/types.d.ts +125 -0
  349. package/dist/transport/types.js +16 -0
  350. package/dist/utils/concurrency.d.ts +123 -0
  351. package/dist/utils/concurrency.js +213 -0
  352. package/dist/utils/formatters.d.ts +16 -0
  353. package/dist/utils/formatters.js +37 -0
  354. package/dist/utils/index.d.ts +8 -0
  355. package/dist/utils/index.js +8 -0
  356. package/dist/utils/jsonpath.d.ts +87 -0
  357. package/dist/utils/jsonpath.js +326 -0
  358. package/dist/utils/markdown.d.ts +113 -0
  359. package/dist/utils/markdown.js +265 -0
  360. package/dist/utils/network.d.ts +14 -0
  361. package/dist/utils/network.js +17 -0
  362. package/dist/utils/sanitize.d.ts +92 -0
  363. package/dist/utils/sanitize.js +191 -0
  364. package/dist/utils/semantic.d.ts +194 -0
  365. package/dist/utils/semantic.js +1051 -0
  366. package/dist/utils/smart-truncate.d.ts +94 -0
  367. package/dist/utils/smart-truncate.js +361 -0
  368. package/dist/utils/timeout.d.ts +153 -0
  369. package/dist/utils/timeout.js +205 -0
  370. package/dist/utils/yaml-parser.d.ts +58 -0
  371. package/dist/utils/yaml-parser.js +86 -0
  372. package/dist/validation/index.d.ts +32 -0
  373. package/dist/validation/index.js +32 -0
  374. package/dist/validation/semantic-test-generator.d.ts +50 -0
  375. package/dist/validation/semantic-test-generator.js +176 -0
  376. package/dist/validation/semantic-types.d.ts +66 -0
  377. package/dist/validation/semantic-types.js +94 -0
  378. package/dist/validation/semantic-validator.d.ts +38 -0
  379. package/dist/validation/semantic-validator.js +340 -0
  380. package/dist/verification/index.d.ts +6 -0
  381. package/dist/verification/index.js +5 -0
  382. package/dist/verification/types.d.ts +133 -0
  383. package/dist/verification/types.js +5 -0
  384. package/dist/verification/verifier.d.ts +30 -0
  385. package/dist/verification/verifier.js +309 -0
  386. package/dist/version.d.ts +19 -0
  387. package/dist/version.js +48 -0
  388. package/dist/workflow/auto-generator.d.ts +27 -0
  389. package/dist/workflow/auto-generator.js +513 -0
  390. package/dist/workflow/discovery.d.ts +40 -0
  391. package/dist/workflow/discovery.js +195 -0
  392. package/dist/workflow/executor.d.ts +82 -0
  393. package/dist/workflow/executor.js +611 -0
  394. package/dist/workflow/index.d.ts +10 -0
  395. package/dist/workflow/index.js +10 -0
  396. package/dist/workflow/loader.d.ts +24 -0
  397. package/dist/workflow/loader.js +194 -0
  398. package/dist/workflow/state-tracker.d.ts +98 -0
  399. package/dist/workflow/state-tracker.js +424 -0
  400. package/dist/workflow/types.d.ts +337 -0
  401. package/dist/workflow/types.js +5 -0
  402. package/package.json +94 -0
  403. package/schemas/bellwether-check.schema.json +651 -0
@@ -0,0 +1,141 @@
1
+ import { type SSETransportConfig } from './sse-transport.js';
2
+ import { type HTTPTransportConfig } from './http-transport.js';
3
+ import { type TransportType } from './base-transport.js';
4
+ import type { MCPInitializeResult, MCPTool, MCPPrompt, MCPResource, MCPToolCallResult, MCPResourceReadResult, MCPPromptGetResult, MCPServerCapabilities } from './types.js';
5
+ export interface MCPClientOptions {
6
+ /** Request timeout in milliseconds (default: 30000) */
7
+ timeout?: number;
8
+ /** Environment variables for the server process */
9
+ env?: Record<string, string>;
10
+ /** Delay before sending first request to allow server startup (default: 500ms) */
11
+ startupDelay?: number;
12
+ /** Enable debug logging */
13
+ debug?: boolean;
14
+ /** Transport type to use (default: stdio) */
15
+ transport?: TransportType;
16
+ /** Configuration for SSE transport */
17
+ sseConfig?: Omit<SSETransportConfig, 'debug'>;
18
+ /** Configuration for HTTP transport */
19
+ httpConfig?: Omit<HTTPTransportConfig, 'debug'>;
20
+ }
21
+ /**
22
+ * MCPClient connects to an MCP server via various transports and provides
23
+ * methods to interact with the server's capabilities.
24
+ *
25
+ * Supported transports:
26
+ * - stdio: Local subprocess communication (default)
27
+ * - sse: Server-Sent Events for remote servers
28
+ * - streamable-http: HTTP POST with streaming responses
29
+ */
30
+ export declare class MCPClient {
31
+ private process;
32
+ private transport;
33
+ private requestId;
34
+ private pendingRequests;
35
+ private serverCapabilities;
36
+ private timeout;
37
+ private startupDelay;
38
+ private serverReady;
39
+ private readyPromise;
40
+ private debug;
41
+ private transportType;
42
+ private sseConfig?;
43
+ private httpConfig?;
44
+ private logger;
45
+ /** Flag to prevent race condition during cleanup - ignore messages when true */
46
+ private cleaningUp;
47
+ constructor(options?: MCPClientOptions);
48
+ /**
49
+ * Get the current transport type.
50
+ */
51
+ getTransportType(): TransportType;
52
+ private log;
53
+ /**
54
+ * Check if an environment variable name looks like a secret.
55
+ */
56
+ private isSensitiveEnvVar;
57
+ /**
58
+ * Filter sensitive environment variables before passing to subprocess.
59
+ * Uses both explicit list and pattern matching to catch common secret naming conventions.
60
+ */
61
+ private filterEnv;
62
+ /**
63
+ * Connect to an MCP server by spawning it as a subprocess.
64
+ */
65
+ connect(command: string, args?: string[], env?: Record<string, string>): Promise<void>;
66
+ /**
67
+ * Connect to a remote MCP server via SSE or HTTP.
68
+ *
69
+ * @param url - The base URL of the MCP server
70
+ * @param options - Optional configuration overrides
71
+ */
72
+ connectRemote(url: string, options?: {
73
+ transport?: 'sse' | 'streamable-http';
74
+ sessionId?: string;
75
+ headers?: Record<string, string>;
76
+ }): Promise<void>;
77
+ /**
78
+ * Set up event handlers for the transport.
79
+ */
80
+ private setupTransportHandlers;
81
+ /**
82
+ * Wait for minimum startup delay before sending requests.
83
+ * The actual "ready" state is confirmed by successful initialization.
84
+ * This delay allows the server process to fully start before we attempt communication.
85
+ */
86
+ private waitForStartup;
87
+ /**
88
+ * Initialize the MCP connection with the server.
89
+ * This is the explicit confirmation that the server is ready.
90
+ * On failure, all pending requests are cleared.
91
+ */
92
+ initialize(): Promise<MCPInitializeResult>;
93
+ /**
94
+ * Clear all pending requests with an error.
95
+ * Used when initialization fails or connection is lost.
96
+ */
97
+ private clearPendingRequests;
98
+ /**
99
+ * List all tools available on the server.
100
+ */
101
+ listTools(): Promise<MCPTool[]>;
102
+ /**
103
+ * List all prompts available on the server.
104
+ */
105
+ listPrompts(): Promise<MCPPrompt[]>;
106
+ /**
107
+ * List all resources available on the server.
108
+ */
109
+ listResources(): Promise<MCPResource[]>;
110
+ /**
111
+ * Read a resource from the server by URI.
112
+ */
113
+ readResource(uri: string): Promise<MCPResourceReadResult>;
114
+ /**
115
+ * Get a prompt from the server with the given arguments.
116
+ */
117
+ getPrompt(name: string, args?: Record<string, string>): Promise<MCPPromptGetResult>;
118
+ /**
119
+ * Call a tool on the server.
120
+ */
121
+ callTool(name: string, args?: Record<string, unknown>): Promise<MCPToolCallResult>;
122
+ /**
123
+ * Get server capabilities.
124
+ */
125
+ getCapabilities(): MCPServerCapabilities | null;
126
+ /**
127
+ * Check if the server is ready (startup delay complete and initialized).
128
+ * Note: This only indicates if startup delay has passed - true readiness
129
+ * is confirmed by successful initialization.
130
+ */
131
+ isServerReady(): boolean;
132
+ /**
133
+ * Disconnect from the server.
134
+ */
135
+ disconnect(): Promise<void>;
136
+ private sendRequest;
137
+ private sendNotification;
138
+ private handleMessage;
139
+ private cleanup;
140
+ }
141
+ //# sourceMappingURL=mcp-client.d.ts.map
@@ -0,0 +1,496 @@
1
+ import { spawn } from 'child_process';
2
+ import { StdioTransport } from './stdio-transport.js';
3
+ import { SSETransport } from './sse-transport.js';
4
+ import { HTTPTransport } from './http-transport.js';
5
+ import { getLogger, startTiming } from '../logging/logger.js';
6
+ import { TIMEOUTS, MCP } from '../constants.js';
7
+ import { VERSION } from '../version.js';
8
+ /**
9
+ * Environment variables to filter out when spawning MCP server processes.
10
+ * These may contain sensitive credentials that should not be exposed.
11
+ */
12
+ const FILTERED_ENV_VARS = new Set([
13
+ // LLM API keys
14
+ 'OPENAI_API_KEY',
15
+ 'ANTHROPIC_API_KEY',
16
+ 'GOOGLE_API_KEY',
17
+ 'AZURE_OPENAI_API_KEY',
18
+ 'COHERE_API_KEY',
19
+ 'HUGGINGFACE_API_KEY',
20
+ 'REPLICATE_API_TOKEN',
21
+ // Bellwether-specific
22
+ 'BELLWETHER_SESSION',
23
+ // Cloud provider credentials
24
+ 'AWS_SECRET_ACCESS_KEY',
25
+ 'AWS_SESSION_TOKEN',
26
+ 'AZURE_CLIENT_SECRET',
27
+ 'GOOGLE_APPLICATION_CREDENTIALS',
28
+ // SCM/CI tokens
29
+ 'GITHUB_TOKEN',
30
+ 'GH_TOKEN',
31
+ 'GITLAB_TOKEN',
32
+ 'BITBUCKET_TOKEN',
33
+ 'NPM_TOKEN',
34
+ 'PYPI_TOKEN',
35
+ // Database credentials
36
+ 'DATABASE_URL',
37
+ 'DATABASE_PASSWORD',
38
+ 'POSTGRES_PASSWORD',
39
+ 'MYSQL_PASSWORD',
40
+ 'REDIS_PASSWORD',
41
+ 'MONGODB_URI',
42
+ // Application secrets
43
+ 'COOKIE_SECRET',
44
+ 'SESSION_SECRET',
45
+ 'JWT_SECRET',
46
+ 'ENCRYPTION_KEY',
47
+ 'PRIVATE_KEY',
48
+ ]);
49
+ /**
50
+ * Patterns for environment variable names that should be filtered.
51
+ * Matches common naming conventions for secrets.
52
+ */
53
+ const FILTERED_ENV_PATTERNS = [
54
+ /_API_KEY$/i,
55
+ /_SECRET$/i,
56
+ /_TOKEN$/i,
57
+ /_PASSWORD$/i,
58
+ /_PRIVATE_KEY$/i,
59
+ /_CREDENTIALS$/i,
60
+ /^SECRET_/i,
61
+ /^PRIVATE_/i,
62
+ ];
63
+ const DEFAULT_TIMEOUT = TIMEOUTS.DEFAULT;
64
+ const DEFAULT_STARTUP_DELAY = TIMEOUTS.SERVER_STARTUP;
65
+ /**
66
+ * MCPClient connects to an MCP server via various transports and provides
67
+ * methods to interact with the server's capabilities.
68
+ *
69
+ * Supported transports:
70
+ * - stdio: Local subprocess communication (default)
71
+ * - sse: Server-Sent Events for remote servers
72
+ * - streamable-http: HTTP POST with streaming responses
73
+ */
74
+ export class MCPClient {
75
+ process = null;
76
+ transport = null;
77
+ requestId = 0;
78
+ pendingRequests = new Map();
79
+ serverCapabilities = null;
80
+ timeout;
81
+ startupDelay;
82
+ serverReady = false;
83
+ readyPromise = null;
84
+ debug;
85
+ transportType;
86
+ sseConfig;
87
+ httpConfig;
88
+ logger = getLogger('mcp-client');
89
+ /** Flag to prevent race condition during cleanup - ignore messages when true */
90
+ cleaningUp = false;
91
+ constructor(options) {
92
+ this.timeout = options?.timeout ?? DEFAULT_TIMEOUT;
93
+ this.startupDelay = options?.startupDelay ?? DEFAULT_STARTUP_DELAY;
94
+ this.debug = options?.debug ?? false;
95
+ this.transportType = options?.transport ?? 'stdio';
96
+ this.sseConfig = options?.sseConfig;
97
+ this.httpConfig = options?.httpConfig;
98
+ }
99
+ /**
100
+ * Get the current transport type.
101
+ */
102
+ getTransportType() {
103
+ return this.transportType;
104
+ }
105
+ log(...args) {
106
+ if (this.debug) {
107
+ this.logger.debug({ args }, 'MCP Debug');
108
+ }
109
+ }
110
+ /**
111
+ * Check if an environment variable name looks like a secret.
112
+ */
113
+ isSensitiveEnvVar(name) {
114
+ // Check explicit list
115
+ if (FILTERED_ENV_VARS.has(name)) {
116
+ return true;
117
+ }
118
+ // Check patterns
119
+ return FILTERED_ENV_PATTERNS.some(pattern => pattern.test(name));
120
+ }
121
+ /**
122
+ * Filter sensitive environment variables before passing to subprocess.
123
+ * Uses both explicit list and pattern matching to catch common secret naming conventions.
124
+ */
125
+ filterEnv(baseEnv, additionalEnv) {
126
+ const filtered = {};
127
+ // Copy process.env, filtering out sensitive variables
128
+ for (const [key, value] of Object.entries(baseEnv)) {
129
+ if (value !== undefined && !this.isSensitiveEnvVar(key)) {
130
+ filtered[key] = value;
131
+ }
132
+ }
133
+ // Add additional env vars (these are explicitly provided, so allow them)
134
+ if (additionalEnv) {
135
+ Object.assign(filtered, additionalEnv);
136
+ }
137
+ return filtered;
138
+ }
139
+ /**
140
+ * Connect to an MCP server by spawning it as a subprocess.
141
+ */
142
+ async connect(command, args = [], env) {
143
+ this.logger.info({ command, args: args.length }, 'Connecting to MCP server');
144
+ // Reset cleanup flag for new connection
145
+ this.cleaningUp = false;
146
+ // Filter out sensitive environment variables before spawning subprocess
147
+ const filteredEnv = this.filterEnv(process.env, env);
148
+ this.process = spawn(command, args, {
149
+ stdio: ['pipe', 'pipe', 'pipe'],
150
+ env: filteredEnv,
151
+ });
152
+ if (!this.process.stdout || !this.process.stdin) {
153
+ throw new Error('Failed to create stdio streams for server process');
154
+ }
155
+ this.transport = new StdioTransport(this.process.stdout, this.process.stdin, { debug: this.debug });
156
+ this.transport.on('message', (msg) => {
157
+ this.log('Received:', JSON.stringify(msg));
158
+ this.handleMessage(msg);
159
+ });
160
+ this.transport.on('error', (error) => {
161
+ this.logger.error({ error: error.message }, 'Transport error');
162
+ });
163
+ this.transport.on('close', () => {
164
+ this.logger.debug('Transport closed');
165
+ this.cleanup();
166
+ });
167
+ this.process.on('error', (error) => {
168
+ this.logger.error({ error: error.message }, 'Process error');
169
+ this.cleanup();
170
+ });
171
+ this.process.on('exit', (code) => {
172
+ if (code !== 0) {
173
+ this.logger.warn({ exitCode: code }, 'Server process exited with non-zero code');
174
+ }
175
+ this.cleanup();
176
+ });
177
+ this.process.stderr?.on('data', (data) => {
178
+ const msg = data.toString().trim();
179
+ if (msg) {
180
+ this.logger.debug({ stderr: msg }, 'Server stderr');
181
+ }
182
+ });
183
+ this.readyPromise = this.waitForStartup();
184
+ this.logger.debug('Startup delay complete, connection established');
185
+ }
186
+ /**
187
+ * Connect to a remote MCP server via SSE or HTTP.
188
+ *
189
+ * @param url - The base URL of the MCP server
190
+ * @param options - Optional configuration overrides
191
+ */
192
+ async connectRemote(url, options) {
193
+ const transport = options?.transport ?? (this.transportType === 'stdio' ? 'sse' : this.transportType);
194
+ this.transportType = transport;
195
+ // Reset cleanup flag for new connection
196
+ this.cleaningUp = false;
197
+ this.logger.info({ url, transport }, 'Connecting to remote MCP server');
198
+ if (transport === 'sse') {
199
+ const sseTransport = new SSETransport({
200
+ baseUrl: url,
201
+ sessionId: options?.sessionId ?? this.sseConfig?.sessionId,
202
+ headers: options?.headers ?? this.sseConfig?.headers,
203
+ timeout: this.timeout,
204
+ debug: this.debug,
205
+ ...this.sseConfig,
206
+ });
207
+ await sseTransport.connect();
208
+ this.transport = sseTransport;
209
+ }
210
+ else if (transport === 'streamable-http') {
211
+ const httpTransport = new HTTPTransport({
212
+ baseUrl: url,
213
+ sessionId: options?.sessionId ?? this.httpConfig?.sessionId,
214
+ headers: options?.headers ?? this.httpConfig?.headers,
215
+ timeout: this.timeout,
216
+ debug: this.debug,
217
+ ...this.httpConfig,
218
+ });
219
+ await httpTransport.connect();
220
+ this.transport = httpTransport;
221
+ }
222
+ else {
223
+ throw new Error(`Unsupported transport type: ${transport}`);
224
+ }
225
+ this.setupTransportHandlers();
226
+ // For remote transports, server is ready immediately
227
+ this.serverReady = true;
228
+ }
229
+ /**
230
+ * Set up event handlers for the transport.
231
+ */
232
+ setupTransportHandlers() {
233
+ if (!this.transport)
234
+ return;
235
+ this.transport.on('message', (msg) => {
236
+ this.log('Received:', JSON.stringify(msg));
237
+ this.handleMessage(msg);
238
+ });
239
+ this.transport.on('error', (error) => {
240
+ this.logger.error({ error: error.message }, 'Transport error');
241
+ });
242
+ this.transport.on('close', () => {
243
+ this.logger.debug('Transport closed');
244
+ this.cleanup();
245
+ });
246
+ }
247
+ /**
248
+ * Wait for minimum startup delay before sending requests.
249
+ * The actual "ready" state is confirmed by successful initialization.
250
+ * This delay allows the server process to fully start before we attempt communication.
251
+ */
252
+ async waitForStartup() {
253
+ // Enforce minimum startup delay to allow server to fully start
254
+ // npx-based servers often need significant time to download and start
255
+ const delay = Math.max(this.startupDelay, TIMEOUTS.MIN_SERVER_STARTUP_WAIT);
256
+ this.logger.debug({ delay }, 'Waiting for server startup');
257
+ await new Promise(resolve => setTimeout(resolve, delay));
258
+ // Mark server as ready (startup delay complete)
259
+ // Note: This only means we can *try* to initialize - actual readiness
260
+ // is confirmed by successful initialization response
261
+ this.serverReady = true;
262
+ }
263
+ /**
264
+ * Initialize the MCP connection with the server.
265
+ * This is the explicit confirmation that the server is ready.
266
+ * On failure, all pending requests are cleared.
267
+ */
268
+ async initialize() {
269
+ // Wait for startup delay to complete
270
+ if (this.readyPromise) {
271
+ await this.readyPromise;
272
+ this.readyPromise = null;
273
+ }
274
+ try {
275
+ const result = await this.sendRequest('initialize', {
276
+ protocolVersion: MCP.PROTOCOL_VERSION,
277
+ capabilities: {},
278
+ clientInfo: {
279
+ name: 'bellwether',
280
+ version: VERSION,
281
+ },
282
+ });
283
+ this.serverCapabilities = result.capabilities;
284
+ // Send initialized notification
285
+ this.sendNotification('notifications/initialized', {});
286
+ this.logger.info({ capabilities: result.capabilities }, 'MCP server initialized successfully');
287
+ return result;
288
+ }
289
+ catch (error) {
290
+ // Clear all pending requests on initialization failure
291
+ // This prevents stale requests from hanging around
292
+ this.clearPendingRequests(error instanceof Error ? error.message : 'Initialization failed');
293
+ // Re-throw the error for the caller to handle
294
+ throw error;
295
+ }
296
+ }
297
+ /**
298
+ * Clear all pending requests with an error.
299
+ * Used when initialization fails or connection is lost.
300
+ */
301
+ clearPendingRequests(reason) {
302
+ const pendingCount = this.pendingRequests.size;
303
+ if (pendingCount > 0) {
304
+ this.logger.debug({ count: pendingCount, reason }, 'Clearing pending requests');
305
+ }
306
+ for (const [id, pending] of this.pendingRequests) {
307
+ clearTimeout(pending.timer);
308
+ pending.reject(new Error(`Request ${id} cancelled: ${reason}`));
309
+ }
310
+ this.pendingRequests.clear();
311
+ }
312
+ /**
313
+ * List all tools available on the server.
314
+ */
315
+ async listTools() {
316
+ const result = await this.sendRequest('tools/list', {});
317
+ return result.tools;
318
+ }
319
+ /**
320
+ * List all prompts available on the server.
321
+ */
322
+ async listPrompts() {
323
+ const result = await this.sendRequest('prompts/list', {});
324
+ return result.prompts;
325
+ }
326
+ /**
327
+ * List all resources available on the server.
328
+ */
329
+ async listResources() {
330
+ const result = await this.sendRequest('resources/list', {});
331
+ return result.resources;
332
+ }
333
+ /**
334
+ * Read a resource from the server by URI.
335
+ */
336
+ async readResource(uri) {
337
+ const done = startTiming(this.logger, `readResource:${uri}`);
338
+ try {
339
+ const result = await this.sendRequest('resources/read', {
340
+ uri,
341
+ });
342
+ done();
343
+ return result;
344
+ }
345
+ catch (error) {
346
+ done();
347
+ throw error;
348
+ }
349
+ }
350
+ /**
351
+ * Get a prompt from the server with the given arguments.
352
+ */
353
+ async getPrompt(name, args = {}) {
354
+ const done = startTiming(this.logger, `getPrompt:${name}`);
355
+ try {
356
+ const result = await this.sendRequest('prompts/get', {
357
+ name,
358
+ arguments: args,
359
+ });
360
+ done();
361
+ return result;
362
+ }
363
+ catch (error) {
364
+ done();
365
+ throw error;
366
+ }
367
+ }
368
+ /**
369
+ * Call a tool on the server.
370
+ */
371
+ async callTool(name, args = {}) {
372
+ const done = startTiming(this.logger, `callTool:${name}`);
373
+ try {
374
+ const result = await this.sendRequest('tools/call', {
375
+ name,
376
+ arguments: args,
377
+ });
378
+ done();
379
+ return result;
380
+ }
381
+ catch (error) {
382
+ done();
383
+ throw error;
384
+ }
385
+ }
386
+ /**
387
+ * Get server capabilities.
388
+ */
389
+ getCapabilities() {
390
+ return this.serverCapabilities;
391
+ }
392
+ /**
393
+ * Check if the server is ready (startup delay complete and initialized).
394
+ * Note: This only indicates if startup delay has passed - true readiness
395
+ * is confirmed by successful initialization.
396
+ */
397
+ isServerReady() {
398
+ return this.serverReady;
399
+ }
400
+ /**
401
+ * Disconnect from the server.
402
+ */
403
+ async disconnect() {
404
+ if (this.process) {
405
+ // Send graceful shutdown signal
406
+ this.process.kill('SIGTERM');
407
+ // Wait for process to exit or force kill after timeout
408
+ await new Promise((resolve) => {
409
+ const timeout = setTimeout(() => {
410
+ this.process?.kill('SIGKILL');
411
+ resolve();
412
+ }, TIMEOUTS.SHUTDOWN_KILL);
413
+ this.process?.once('exit', () => {
414
+ clearTimeout(timeout);
415
+ resolve();
416
+ });
417
+ });
418
+ }
419
+ this.cleanup();
420
+ }
421
+ sendRequest(method, params) {
422
+ return new Promise((resolve, reject) => {
423
+ if (!this.transport) {
424
+ reject(new Error('Not connected to server'));
425
+ return;
426
+ }
427
+ const id = ++this.requestId;
428
+ const request = {
429
+ jsonrpc: MCP.JSONRPC_VERSION,
430
+ id,
431
+ method,
432
+ params,
433
+ };
434
+ const timer = setTimeout(() => {
435
+ this.pendingRequests.delete(id);
436
+ reject(new Error(`Request timeout: ${method}`));
437
+ }, this.timeout);
438
+ this.pendingRequests.set(id, {
439
+ resolve: resolve,
440
+ reject,
441
+ timer,
442
+ });
443
+ this.log('Sending:', JSON.stringify(request));
444
+ this.transport.send(request);
445
+ });
446
+ }
447
+ sendNotification(method, params) {
448
+ if (!this.transport)
449
+ return;
450
+ this.transport.send({
451
+ jsonrpc: MCP.JSONRPC_VERSION,
452
+ method,
453
+ params,
454
+ });
455
+ }
456
+ handleMessage(msg) {
457
+ // Ignore messages during cleanup to prevent race conditions
458
+ // This avoids double-rejecting promises or accessing cleared timers
459
+ if (this.cleaningUp) {
460
+ this.log('Ignoring message during cleanup:', JSON.stringify(msg));
461
+ return;
462
+ }
463
+ // Check if it's a response to a pending request
464
+ if ('id' in msg && msg.id !== undefined) {
465
+ const pending = this.pendingRequests.get(msg.id);
466
+ if (pending) {
467
+ clearTimeout(pending.timer);
468
+ this.pendingRequests.delete(msg.id);
469
+ const response = msg;
470
+ if (response.error) {
471
+ pending.reject(new Error(`${response.error.message} (code: ${response.error.code})`));
472
+ }
473
+ else {
474
+ pending.resolve(response.result);
475
+ }
476
+ }
477
+ }
478
+ // Notifications from server are logged but not processed
479
+ }
480
+ cleanup() {
481
+ if (this.cleaningUp) {
482
+ return;
483
+ }
484
+ // Set cleanup flag to prevent race conditions with handleMessage
485
+ // Any messages arriving after this point will be ignored
486
+ this.cleaningUp = true;
487
+ // Clear all pending requests with appropriate error
488
+ this.clearPendingRequests('Connection closed');
489
+ this.transport?.close();
490
+ this.transport = null;
491
+ this.process = null;
492
+ this.serverCapabilities = null;
493
+ this.serverReady = false;
494
+ }
495
+ }
496
+ //# sourceMappingURL=mcp-client.js.map