@langwatch/mcp-server 2.0.0 → 2.2.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 (430) hide show
  1. package/.gitignore +7 -0
  2. package/.npmignore +41 -0
  3. package/CHANGELOG.md +280 -200
  4. package/CONTRIBUTING.md +10 -0
  5. package/README.md +82 -52
  6. package/dist/add-dashboard-widget-4ZC5UN73.js +50 -0
  7. package/dist/add-dashboard-widget-ACC6QYBG.js +49 -0
  8. package/dist/archive-project-KWFM3I5Z.js +19 -0
  9. package/dist/{archive-project-4EQGLBJJ.js → archive-project-SPVHXK6A.js} +4 -4
  10. package/dist/archive-run-plan-65QN3XRX.js +16 -0
  11. package/dist/archive-run-plan-Z4SYE6BP.js +15 -0
  12. package/dist/{archive-scenario-W6BXYDZ3.js → archive-scenario-A6QV5LOW.js} +4 -4
  13. package/dist/archive-scenario-FXEYQNEH.js +19 -0
  14. package/dist/archive-test-suite-5ADQ3KPQ.js +15 -0
  15. package/dist/archive-test-suite-NKZDZY3D.js +16 -0
  16. package/dist/assign-prompt-tag-5IUZXJ2T.js +23 -0
  17. package/dist/{assign-prompt-tag-VLXUWEKU.js → assign-prompt-tag-HBZLBIFD.js} +8 -4
  18. package/dist/{chunk-CDYQOY5U.js → chunk-3OCG3QPU.js} +7 -10
  19. package/dist/chunk-3YLN3ATJ.js +241 -0
  20. package/dist/chunk-5FNCQRCX.js +91 -0
  21. package/dist/chunk-6YZUOD34.js +55 -0
  22. package/dist/{chunk-WVI5CJ6S.js → chunk-7AQLPVFL.js} +2 -2
  23. package/dist/chunk-7VNSRCXO.js +129 -0
  24. package/dist/{chunk-7RHG56OH.js → chunk-B4J3PJLX.js} +11 -10
  25. package/dist/{chunk-ZXKLPC2E.js → chunk-BIIKE3EI.js} +1 -1
  26. package/dist/{chunk-37SMPMQS.js → chunk-DMM3JQ42.js} +7 -2
  27. package/dist/{chunk-NUFPTHKU.js → chunk-FOKVY3BK.js} +1 -1
  28. package/dist/{chunk-WT4PO4A3.js → chunk-H6WGMG2T.js} +10 -7
  29. package/dist/{chunk-TOXJQDIZ.js → chunk-HGELNIVY.js} +135 -51
  30. package/dist/{chunk-UJPXFA26.js → chunk-HHMNZAPD.js} +101 -74
  31. package/dist/{chunk-J42FWRJ2.js → chunk-I7ATIZED.js} +7 -7
  32. package/dist/{chunk-AQJO2EI5.js → chunk-ILZDO25L.js} +7 -10
  33. package/dist/{chunk-4QC7SA2L.js → chunk-J7PQKBLD.js} +884 -559
  34. package/dist/{chunk-YX3A3CFM.js → chunk-JRJPH75H.js} +7 -13
  35. package/dist/chunk-K2I7Z3LZ.js +28 -0
  36. package/dist/{chunk-5CCZFUXS.js → chunk-NKMTIHIJ.js} +6 -9
  37. package/dist/chunk-O7EMWEVJ.js +44 -0
  38. package/dist/chunk-PTDR56Z3.js +37 -0
  39. package/dist/chunk-RABYBFX5.js +43 -0
  40. package/dist/chunk-SUPUUC4W.js +64 -0
  41. package/dist/{chunk-SFB4MU6H.js → chunk-SXFC3FNH.js} +4 -4
  42. package/dist/chunk-U24EACC4.js +67 -0
  43. package/dist/chunk-UNJM3BIL.js +21 -0
  44. package/dist/{chunk-ZWIL4EFL.js → chunk-UTJCWXPZ.js} +4 -4
  45. package/dist/chunk-UWLE5T2F.js +312 -0
  46. package/dist/chunk-VMWJD732.js +57 -0
  47. package/dist/chunk-XUIJYNRJ.js +15 -0
  48. package/dist/chunk-Y34DHR5K.js +67 -0
  49. package/dist/chunk-YCARO42Z.js +516 -0
  50. package/dist/config-EAKW6F26.js +16 -0
  51. package/dist/config.cjs +109 -0
  52. package/dist/config.js +5 -4
  53. package/dist/{create-agent-7XHO6UIS.js → create-agent-AYZ3LB3V.js} +4 -4
  54. package/dist/create-agent-S5ZBCEFT.js +23 -0
  55. package/dist/create-annotation-LHNCLHYP.js +29 -0
  56. package/dist/{create-annotation-YQXRQC6A.js → create-annotation-VUSXULQK.js} +10 -5
  57. package/dist/{create-api-key-YUS36KBU.js → create-api-key-NNYKARMG.js} +5 -7
  58. package/dist/create-api-key-T4KSNPKB.js +24 -0
  59. package/dist/create-dashboard-DHVFMEU4.js +18 -0
  60. package/dist/{create-dashboard-4Z5JO5LB.js → create-dashboard-WTKKS5Z6.js} +4 -4
  61. package/dist/{create-dataset-E6NMSVX7.js → create-dataset-2MC4SD4O.js} +6 -6
  62. package/dist/create-dataset-LUP5PVDM.js +22 -0
  63. package/dist/create-dataset-records-NSKBZP3G.js +20 -0
  64. package/dist/{create-dataset-records-SKHPRD2K.js → create-dataset-records-W4GLN2FV.js} +5 -7
  65. package/dist/{create-evaluator-JXF5PF33.js → create-evaluator-643G6LXL.js} +4 -4
  66. package/dist/create-evaluator-HMTYO5SS.js +27 -0
  67. package/dist/create-mcp-server.cjs +9513 -0
  68. package/dist/create-mcp-server.js +2647 -5
  69. package/dist/create-project-6N7PIYRY.js +44 -0
  70. package/dist/{create-project-CS2CB57Y.js → create-project-KAIC46UY.js} +4 -4
  71. package/dist/{create-prompt-F5RMX3L3.js → create-prompt-E67LXIYT.js} +5 -7
  72. package/dist/create-prompt-PKJ7EDRR.js +37 -0
  73. package/dist/create-prompt-tag-4YO3FSJ3.js +17 -0
  74. package/dist/{create-prompt-tag-GMRWTEFR.js → create-prompt-tag-OPQUEXWB.js} +3 -3
  75. package/dist/create-scenario-5PJBMAXO.js +33 -0
  76. package/dist/{create-scenario-JDR2VB2H.js → create-scenario-UEM77OE7.js} +11 -4
  77. package/dist/create-test-suite-4IPXVSFQ.js +37 -0
  78. package/dist/create-test-suite-SZEPVXSE.js +36 -0
  79. package/dist/create-trigger-5HZSCRAN.js +49 -0
  80. package/dist/create-trigger-PRELMT6J.js +48 -0
  81. package/dist/delete-agent-JUIZWAXG.js +18 -0
  82. package/dist/{delete-agent-O3EEH4S5.js → delete-agent-QMEK3XHK.js} +4 -4
  83. package/dist/delete-annotation-HY3O2OGR.js +17 -0
  84. package/dist/{delete-annotation-XP6FQM7A.js → delete-annotation-VKIQWUYW.js} +4 -4
  85. package/dist/delete-dashboard-76N66XXL.js +18 -0
  86. package/dist/{delete-dashboard-RFUNYCNP.js → delete-dashboard-JVIVHNJM.js} +4 -4
  87. package/dist/delete-dataset-HQCR66MG.js +18 -0
  88. package/dist/{delete-dataset-3MJFRDLP.js → delete-dataset-WKRUW4FP.js} +5 -7
  89. package/dist/{delete-dataset-records-WPMU5GL5.js → delete-dataset-records-C2IQFFVQ.js} +5 -7
  90. package/dist/delete-dataset-records-SDUHQLLM.js +19 -0
  91. package/dist/delete-evaluator-4SNSCLEE.js +16 -0
  92. package/dist/delete-evaluator-QP3QHTLN.js +15 -0
  93. package/dist/delete-prompt-tag-NZ4JQMYG.js +17 -0
  94. package/dist/{delete-prompt-tag-KNMZVSPB.js → delete-prompt-tag-YYQ4VMAD.js} +3 -3
  95. package/dist/{delete-workflow-3NUXO46U.js → delete-workflow-5J46T73T.js} +4 -4
  96. package/dist/delete-workflow-JSWABL5F.js +17 -0
  97. package/dist/discover-evaluator-schema-UHWA5HVL.js +120 -0
  98. package/dist/discover-evaluator-schema-XKCLLCB3.js +118 -0
  99. package/dist/discover-scenario-schema-NOJY6S7E.js +137 -0
  100. package/dist/discover-scenario-schema-OOFIQKOG.js +139 -0
  101. package/dist/{discover-schema-L6QDPON3.js → discover-schema-55YJBFGQ.js} +181 -186
  102. package/dist/discover-schema-A33SLMXW.js +442 -0
  103. package/dist/get-agent-LJQX7OF4.js +69 -0
  104. package/dist/get-agent-OTIYUFZA.js +70 -0
  105. package/dist/get-analytics-DCS72353.js +80 -0
  106. package/dist/get-analytics-IQZKJHLW.js +79 -0
  107. package/dist/get-dashboard-5NYJEIX2.js +29 -0
  108. package/dist/{get-dashboard-KHBEGZGL.js → get-dashboard-QMTYDQAZ.js} +4 -4
  109. package/dist/get-dataset-ALSP7RTX.js +64 -0
  110. package/dist/get-dataset-X4B5JDG2.js +63 -0
  111. package/dist/{get-evaluator-ADMKVWYZ.js → get-evaluator-ISMC4LLI.js} +4 -4
  112. package/dist/get-evaluator-XEUZGZCH.js +47 -0
  113. package/dist/{get-project-RAK7URQJ.js → get-project-5VKROSDH.js} +4 -4
  114. package/dist/get-project-RM6FRCBK.js +26 -0
  115. package/dist/get-prompt-OWXJZHQQ.js +95 -0
  116. package/dist/get-prompt-W52DY36E.js +94 -0
  117. package/dist/get-run-plan-BE3M2AUX.js +59 -0
  118. package/dist/get-run-plan-RUXQ6PAX.js +58 -0
  119. package/dist/get-scenario-RNM7BAX2.js +37 -0
  120. package/dist/{get-scenario-ZTAJJL5T.js → get-scenario-YM4ODWW6.js} +8 -4
  121. package/dist/get-simulation-run-6GIATQE5.js +69 -0
  122. package/dist/{get-simulation-run-T2ZQWYH2.js → get-simulation-run-LCFSMPGQ.js} +33 -20
  123. package/dist/get-test-suite-GC2O7YH6.js +49 -0
  124. package/dist/get-test-suite-P5LJ6VLF.js +48 -0
  125. package/dist/get-trace-KBRVV4NN.js +45 -0
  126. package/dist/{get-trace-K7U234Q4.js → get-trace-SEF3FMR5.js} +11 -13
  127. package/dist/get-workflow-7PVED7JE.js +25 -0
  128. package/dist/{get-workflow-L5L2PSK3.js → get-workflow-YXULW4GC.js} +4 -4
  129. package/dist/{http-security-EU3CHTY7.js → http-security-DNLBNQZL.js} +2 -2
  130. package/dist/{http-server-YXHFPPGA.js → http-server-IR4QOS43.js} +4071 -342
  131. package/dist/index.js +60221 -38077
  132. package/dist/langwatch-api-annotations-6SA4OB4C.js +17 -0
  133. package/dist/{langwatch-api-annotations-FDAS6NQ7.js → langwatch-api-annotations-TBHLCQ5R.js} +4 -4
  134. package/dist/langwatch-api-dashboards-6EO2VVZW.js +17 -0
  135. package/dist/{langwatch-api-dashboards-JTVCS7ZJ.js → langwatch-api-dashboards-NHU5BZD7.js} +4 -4
  136. package/dist/langwatch-api-monitors-CBF3FGIM.js +47 -0
  137. package/dist/{langwatch-api-monitors-3J7UIQME.js → langwatch-api-monitors-YNWA2M5Y.js} +11 -16
  138. package/dist/langwatch-api-secrets-ADTOJELP.js +56 -0
  139. package/dist/langwatch-api-secrets-RNFO4LF2.js +55 -0
  140. package/dist/langwatch-api-triggers-KQDQC6L5.js +22 -0
  141. package/dist/langwatch-api-triggers-QS7HDIVW.js +23 -0
  142. package/dist/{langwatch-api-workflows-NBJX5KOG.js → langwatch-api-workflows-OKC4FXIF.js} +4 -4
  143. package/dist/langwatch-api-workflows-XGJE6SR5.js +15 -0
  144. package/dist/list-agents-HVYWEQMI.js +43 -0
  145. package/dist/list-agents-RBAOCF53.js +42 -0
  146. package/dist/list-annotations-HJH4NBLD.js +38 -0
  147. package/dist/{list-annotations-ZTVP4EEL.js → list-annotations-J4UAHSUN.js} +10 -5
  148. package/dist/{list-api-keys-CWD4UQT5.js → list-api-keys-7UTJRZDG.js} +10 -5
  149. package/dist/list-api-keys-A2PMV435.js +42 -0
  150. package/dist/list-dashboard-boards-OPWROHMG.js +33 -0
  151. package/dist/list-dashboard-boards-U2GJ7GC5.js +34 -0
  152. package/dist/{list-dashboards-PWG6P6KR.js → list-dashboards-ROSYFLDQ.js} +4 -4
  153. package/dist/list-dashboards-RQ635ZU7.js +32 -0
  154. package/dist/{list-dataset-records-IOE7LQXS.js → list-dataset-records-M5TKA6LK.js} +14 -10
  155. package/dist/list-dataset-records-WFM7F33C.js +43 -0
  156. package/dist/{list-datasets-ZT4JYUDT.js → list-datasets-B5X4P7BQ.js} +9 -13
  157. package/dist/list-datasets-THUKQHPX.js +56 -0
  158. package/dist/{list-evaluators-SJHC7VBH.js → list-evaluators-MYH2OVCI.js} +5 -7
  159. package/dist/list-evaluators-NLVWF6K7.js +32 -0
  160. package/dist/{list-model-providers-PPD2WPD2.js → list-model-providers-3JUGP4YI.js} +4 -4
  161. package/dist/list-model-providers-H3XKORFO.js +35 -0
  162. package/dist/{list-projects-K7QAIX2I.js → list-projects-6EJ5YYEW.js} +5 -7
  163. package/dist/list-projects-YNNSRMLC.js +40 -0
  164. package/dist/{list-prompt-tags-FOO6TNHB.js → list-prompt-tags-NVFQO6WX.js} +3 -3
  165. package/dist/list-prompt-tags-XUQTTAH4.js +23 -0
  166. package/dist/{list-prompts-SC2HAUFG.js → list-prompts-HSIMMHTF.js} +4 -6
  167. package/dist/list-prompts-IRI6AIXO.js +30 -0
  168. package/dist/list-run-plans-PX2XI6EK.js +46 -0
  169. package/dist/list-run-plans-QALLCN2K.js +45 -0
  170. package/dist/list-scenarios-QZRPVHS4.js +46 -0
  171. package/dist/list-scenarios-SSJQEMJP.js +45 -0
  172. package/dist/list-simulation-runs-KNOLGMDV.js +53 -0
  173. package/dist/{list-simulation-runs-KF5THG5H.js → list-simulation-runs-OEADLLQR.js} +19 -9
  174. package/dist/list-test-suites-ANAQBLDG.js +34 -0
  175. package/dist/list-test-suites-N4WVLBKK.js +35 -0
  176. package/dist/list-trigger-fires-JV3WFYYG.js +19 -0
  177. package/dist/list-trigger-fires-WTW4DVIW.js +20 -0
  178. package/dist/list-triggers-SQNIG35Q.js +45 -0
  179. package/dist/list-triggers-V4Y356AK.js +46 -0
  180. package/dist/{list-workflows-QSJWURCK.js → list-workflows-IMSX7SXU.js} +5 -7
  181. package/dist/list-workflows-ZHTX5LCL.js +33 -0
  182. package/dist/{rename-prompt-tag-EKWU5QF3.js → rename-prompt-tag-IQI7MHOI.js} +3 -3
  183. package/dist/rename-prompt-tag-PA2BRIE6.js +18 -0
  184. package/dist/rename-test-suite-4J7UX5S2.js +21 -0
  185. package/dist/rename-test-suite-NNVLMLKY.js +20 -0
  186. package/dist/report-issue-AS34ZMJF.js +898 -0
  187. package/dist/report-issue-DCZFLGDO.js +899 -0
  188. package/dist/rerun-run-plan-TG2V4WM4.js +22 -0
  189. package/dist/rerun-run-plan-ZI5OY3VA.js +21 -0
  190. package/dist/revoke-api-key-3J3ZA4UB.js +15 -0
  191. package/dist/{revoke-api-key-FTRTZMOF.js → revoke-api-key-SFMEFWJC.js} +4 -4
  192. package/dist/run-agent-W4VJP72Z.js +75 -0
  193. package/dist/run-agent-YNV6ZHW4.js +74 -0
  194. package/dist/run-plan-6C77GWG4.js +38 -0
  195. package/dist/run-plan-PAARQSI4.js +39 -0
  196. package/dist/run-query-KJDH544C.js +47 -0
  197. package/dist/run-query-T4QW2Z5O.js +46 -0
  198. package/dist/run-test-suite-SQJELEZX.js +26 -0
  199. package/dist/run-test-suite-STB6NUJM.js +25 -0
  200. package/dist/{run-workflow-QPXC627O.js → run-workflow-D6PQNBI6.js} +4 -4
  201. package/dist/{run-agent-6SM4XNA7.js → run-workflow-SP32SO5M.js} +10 -11
  202. package/dist/search-traces-HCBGOG6R.js +170 -0
  203. package/dist/search-traces-HSTQ6WTQ.js +171 -0
  204. package/dist/{set-model-provider-3WKT63ZN.js → set-model-provider-GF7NXUJA.js} +4 -4
  205. package/dist/set-model-provider-KDQ7C4EZ.js +33 -0
  206. package/dist/{update-agent-SMAEHLXH.js → update-agent-DWG43T2P.js} +4 -4
  207. package/dist/update-agent-MXNOBS4H.js +20 -0
  208. package/dist/update-dashboard-widget-CJKJLCDY.js +71 -0
  209. package/dist/update-dashboard-widget-CYQDS2NR.js +70 -0
  210. package/dist/update-dataset-DQH3OHOU.js +22 -0
  211. package/dist/{update-dataset-BDUK7TUO.js → update-dataset-SQZ6T4WX.js} +6 -6
  212. package/dist/{update-dataset-record-4ZSDRBSW.js → update-dataset-record-3AT4IPBC.js} +4 -4
  213. package/dist/update-dataset-record-7PLDGTMR.js +19 -0
  214. package/dist/update-evaluator-4LFTKFPT.js +24 -0
  215. package/dist/{update-evaluator-LS6TIBY7.js → update-evaluator-IGTX6PX4.js} +4 -4
  216. package/dist/{update-project-LKVYXENH.js → update-project-PLJIOZS6.js} +4 -4
  217. package/dist/update-project-QVHSJRUP.js +24 -0
  218. package/dist/update-prompt-GDKRYJI3.js +140 -0
  219. package/dist/update-prompt-MY263DYF.js +141 -0
  220. package/dist/update-scenario-7KA3JDXA.js +34 -0
  221. package/dist/{update-scenario-NEXCAQI7.js → update-scenario-MOHRQKAQ.js} +11 -4
  222. package/package.json +39 -44
  223. package/pyproject.toml +8 -8
  224. package/src/config.d.ts +4 -0
  225. package/src/config.ts +20 -29
  226. package/src/create-mcp-server.ts +1021 -596
  227. package/src/documentation-fetch.ts +21 -20
  228. package/src/http-security.ts +166 -135
  229. package/src/http-server.ts +189 -224
  230. package/src/index.ts +14 -16
  231. package/src/langwatch-api-agents.ts +202 -21
  232. package/src/langwatch-api-annotations.ts +11 -12
  233. package/src/langwatch-api-api-keys.ts +8 -9
  234. package/src/langwatch-api-boards.ts +46 -0
  235. package/src/langwatch-api-dashboard-widgets.ts +112 -0
  236. package/src/langwatch-api-dashboards.ts +13 -10
  237. package/src/langwatch-api-datasets.ts +98 -32
  238. package/src/langwatch-api-evaluators.ts +13 -19
  239. package/src/langwatch-api-model-providers.ts +4 -4
  240. package/src/langwatch-api-monitors.ts +14 -18
  241. package/src/langwatch-api-projects.ts +27 -9
  242. package/src/langwatch-api-query.ts +114 -0
  243. package/src/langwatch-api-run-plans.ts +140 -0
  244. package/src/langwatch-api-scenarios.ts +17 -10
  245. package/src/langwatch-api-secrets.ts +31 -24
  246. package/src/langwatch-api-simulation-runs.ts +10 -7
  247. package/src/langwatch-api-test-suites.ts +116 -0
  248. package/src/langwatch-api-triggers.ts +96 -34
  249. package/src/langwatch-api-workflows.ts +9 -9
  250. package/src/langwatch-api.ts +143 -109
  251. package/src/public-http-request.ts +21 -12
  252. package/src/schemas/analytics-metrics.ts +3 -15
  253. package/src/schemas/create-dataset.ts +3 -4
  254. package/src/schemas/run-plan.ts +76 -0
  255. package/src/schemas/suite-fields.ts +132 -0
  256. package/src/schemas/triggers.ts +365 -0
  257. package/src/tools/add-dashboard-widget.ts +63 -0
  258. package/src/tools/archive-project.ts +2 -4
  259. package/src/tools/archive-run-plan.ts +10 -0
  260. package/src/tools/archive-scenario.ts +2 -4
  261. package/src/tools/archive-test-suite.ts +10 -0
  262. package/src/tools/assign-prompt-tag.ts +6 -2
  263. package/src/tools/create-agent.ts +1 -1
  264. package/src/tools/create-annotation.ts +7 -2
  265. package/src/tools/create-api-key.ts +4 -6
  266. package/src/tools/create-dashboard.ts +1 -1
  267. package/src/tools/create-dataset-records.ts +4 -8
  268. package/src/tools/create-dataset.ts +5 -7
  269. package/src/tools/create-evaluator.ts +3 -5
  270. package/src/tools/create-project.ts +2 -2
  271. package/src/tools/create-prompt-tag.ts +2 -4
  272. package/src/tools/create-prompt.ts +9 -18
  273. package/src/tools/create-scenario.ts +11 -5
  274. package/src/tools/create-test-suite.ts +38 -0
  275. package/src/tools/create-trigger.ts +55 -0
  276. package/src/tools/dashboard-exists.ts +25 -0
  277. package/src/tools/dashboard-widget-queries.ts +32 -0
  278. package/src/tools/delete-agent.ts +1 -1
  279. package/src/tools/delete-annotation.ts +1 -1
  280. package/src/tools/delete-dashboard.ts +1 -1
  281. package/src/tools/delete-dataset-records.ts +4 -8
  282. package/src/tools/delete-dataset.ts +3 -7
  283. package/src/tools/delete-evaluator.ts +4 -6
  284. package/src/tools/delete-prompt-tag.ts +2 -4
  285. package/src/tools/delete-workflow.ts +1 -1
  286. package/src/tools/discover-evaluator-schema.ts +34 -25
  287. package/src/tools/discover-scenario-schema.ts +86 -12
  288. package/src/tools/discover-schema.ts +149 -27
  289. package/src/tools/experiment-run-status.ts +2 -8
  290. package/src/tools/format-dataset-mutation.ts +5 -10
  291. package/src/tools/format-run-plan.ts +54 -0
  292. package/src/tools/format-scenario.ts +12 -0
  293. package/src/tools/format-suite-details.ts +90 -0
  294. package/src/tools/get-agent.ts +54 -3
  295. package/src/tools/get-analytics.ts +52 -46
  296. package/src/tools/get-dashboard.ts +1 -1
  297. package/src/tools/get-dataset.ts +34 -16
  298. package/src/tools/get-evaluator.ts +4 -11
  299. package/src/tools/get-experiment-results.ts +219 -186
  300. package/src/tools/get-project.ts +2 -4
  301. package/src/tools/get-prompt.ts +100 -37
  302. package/src/tools/get-run-plan.ts +60 -0
  303. package/src/tools/get-scenario.ts +6 -5
  304. package/src/tools/get-simulation-run.ts +32 -20
  305. package/src/tools/get-test-suite.ts +46 -0
  306. package/src/tools/get-trace.ts +16 -17
  307. package/src/tools/get-workflow.ts +1 -1
  308. package/src/tools/list-agents.ts +20 -3
  309. package/src/tools/list-annotations.ts +8 -5
  310. package/src/tools/list-api-keys.ts +7 -2
  311. package/src/tools/list-dashboard-boards.ts +28 -0
  312. package/src/tools/list-dashboards.ts +1 -1
  313. package/src/tools/list-dataset-records.ts +8 -6
  314. package/src/tools/list-datasets.ts +12 -23
  315. package/src/tools/list-evaluators.ts +4 -8
  316. package/src/tools/list-experiment-runs.ts +5 -9
  317. package/src/tools/list-experiments.ts +5 -11
  318. package/src/tools/list-model-providers.ts +3 -5
  319. package/src/tools/list-projects.ts +2 -4
  320. package/src/tools/list-prompt-tags.ts +3 -3
  321. package/src/tools/list-prompts.ts +4 -8
  322. package/src/tools/list-run-plans.ts +47 -0
  323. package/src/tools/list-scenarios.ts +26 -17
  324. package/src/tools/list-simulation-runs.ts +13 -5
  325. package/src/tools/list-test-suites.ts +35 -0
  326. package/src/tools/list-trigger-fires.ts +17 -0
  327. package/src/tools/list-triggers.ts +39 -0
  328. package/src/tools/list-workflows.ts +2 -4
  329. package/src/tools/rename-prompt-tag.ts +1 -1
  330. package/src/tools/rename-test-suite.ts +15 -0
  331. package/src/tools/report-issue.ts +5 -9
  332. package/src/tools/rerun-run-plan.ts +18 -0
  333. package/src/tools/revoke-api-key.ts +2 -4
  334. package/src/tools/run-agent.ts +65 -14
  335. package/src/tools/run-experiment.ts +36 -37
  336. package/src/tools/run-plan.ts +46 -0
  337. package/src/tools/run-query.ts +47 -0
  338. package/src/tools/run-test-suite.ts +27 -0
  339. package/src/tools/run-workflow.ts +2 -5
  340. package/src/tools/search-traces.ts +161 -47
  341. package/src/tools/set-model-provider.ts +4 -6
  342. package/src/tools/test-agent.ts +18 -0
  343. package/src/tools/update-agent.ts +1 -1
  344. package/src/tools/update-dashboard-widget.ts +97 -0
  345. package/src/tools/update-dataset-record.ts +1 -1
  346. package/src/tools/update-dataset.ts +5 -7
  347. package/src/tools/update-evaluator.ts +3 -5
  348. package/src/tools/update-project.ts +1 -1
  349. package/src/tools/update-prompt.ts +185 -15
  350. package/src/tools/update-scenario.ts +11 -5
  351. package/src/tools/update-test-suite.ts +40 -0
  352. package/src/utils/date-parsing.ts +1 -1
  353. package/src/utils/escape-markdown.ts +3 -8
  354. package/src/utils/format-evaluations.ts +6 -6
  355. package/src/utils/markdown-table.ts +58 -0
  356. package/src/utils/trace-id-shape.ts +20 -0
  357. package/tsconfig.app.json +24 -0
  358. package/tsconfig.json +19 -12
  359. package/uv.lock +416 -296
  360. package/vitest.integration.config.js +10 -0
  361. package/vitest.scenario.config.js +9 -0
  362. package/.eslintrc.cjs +0 -36
  363. package/dist/archive-suite-4T6BSRS7.js +0 -16
  364. package/dist/chunk-77BNWQ3U.js +0 -86
  365. package/dist/chunk-A2LEVYQ5.js +0 -217
  366. package/dist/chunk-TJCXFNDT.js +0 -24
  367. package/dist/chunk-YZLYHLLI.js +0 -48
  368. package/dist/config.d.ts +0 -17
  369. package/dist/create-mcp-server.d.ts +0 -10
  370. package/dist/create-suite-LZS6QIAF.js +0 -39
  371. package/dist/delete-evaluator-33SP2JFX.js +0 -16
  372. package/dist/discover-evaluator-schema-XTAD4X7D.js +0 -2191
  373. package/dist/discover-scenario-schema-FE64QK2D.js +0 -67
  374. package/dist/get-agent-Y7MWZ65F.js +0 -29
  375. package/dist/get-analytics-TETCSOK6.js +0 -73
  376. package/dist/get-dataset-RCMU5VAH.js +0 -49
  377. package/dist/get-prompt-OY5B7TRI.js +0 -46
  378. package/dist/get-suite-J7JVWO6O.js +0 -45
  379. package/dist/index.d.ts +0 -2
  380. package/dist/langwatch-api-secrets-BUBSNCNO.js +0 -41
  381. package/dist/langwatch-api-triggers-EDFUCJN6.js +0 -31
  382. package/dist/list-agents-KFHKGPXV.js +0 -33
  383. package/dist/list-scenarios-F2WYNRIE.js +0 -41
  384. package/dist/list-suites-CRY4VWW6.js +0 -43
  385. package/dist/report-issue-XYVAPAYJ.js +0 -412
  386. package/dist/run-suite-NKZCJ2IN.js +0 -30
  387. package/dist/search-traces-A6HFKPLJ.js +0 -79
  388. package/dist/update-prompt-ODCRQRN6.js +0 -25
  389. package/dist/update-suite-SNO3GS7T.js +0 -40
  390. package/src/__tests__/all-tools.integration.test.ts +0 -1626
  391. package/src/__tests__/config.unit.test.ts +0 -202
  392. package/src/__tests__/datasets.integration.test.ts +0 -620
  393. package/src/__tests__/datasets.unit.test.ts +0 -244
  394. package/src/__tests__/date-parsing.unit.test.ts +0 -78
  395. package/src/__tests__/discover-evaluator-schema.unit.test.ts +0 -89
  396. package/src/__tests__/discover-schema.unit.test.ts +0 -118
  397. package/src/__tests__/docker.integration.test.ts +0 -318
  398. package/src/__tests__/documentation-fetch-security.integration.test.ts +0 -182
  399. package/src/__tests__/evaluator-tools.unit.test.ts +0 -262
  400. package/src/__tests__/experiment-list-tools.unit.test.ts +0 -157
  401. package/src/__tests__/experiment-status.unit.test.ts +0 -194
  402. package/src/__tests__/feature-map-tool-drift.unit.test.ts +0 -93
  403. package/src/__tests__/get-experiment-results.unit.test.ts +0 -313
  404. package/src/__tests__/http-security-origin.unit.test.ts +0 -97
  405. package/src/__tests__/http-security-sessions.unit.test.ts +0 -209
  406. package/src/__tests__/http-security-verifier.unit.test.ts +0 -248
  407. package/src/__tests__/http-server-allocation.integration.test.ts +0 -279
  408. package/src/__tests__/http-server-origin.integration.test.ts +0 -169
  409. package/src/__tests__/http-server-session-auth.integration.test.ts +0 -341
  410. package/src/__tests__/http-transport.integration.test.ts +0 -395
  411. package/src/__tests__/integration.integration.test.ts +0 -288
  412. package/src/__tests__/langwatch-api.unit.test.ts +0 -661
  413. package/src/__tests__/model-provider-tools.unit.test.ts +0 -190
  414. package/src/__tests__/project-api-key-tools.unit.test.ts +0 -451
  415. package/src/__tests__/public-http-request-security.integration.test.ts +0 -118
  416. package/src/__tests__/report-issue.integration.test.ts +0 -147
  417. package/src/__tests__/scenario-tools.integration.test.ts +0 -286
  418. package/src/__tests__/scenario-tools.unit.test.ts +0 -188
  419. package/src/__tests__/schemas.unit.test.ts +0 -85
  420. package/src/__tests__/support/http-server-harness.ts +0 -138
  421. package/src/__tests__/tools.unit.test.ts +0 -924
  422. package/src/langwatch-api-suites.ts +0 -118
  423. package/src/schemas/filter-fields.ts +0 -119
  424. package/src/schemas/index.ts +0 -4
  425. package/src/tools/archive-suite.ts +0 -12
  426. package/src/tools/create-suite.ts +0 -42
  427. package/src/tools/get-suite.ts +0 -47
  428. package/src/tools/list-suites.ts +0 -43
  429. package/src/tools/run-suite.ts +0 -28
  430. package/src/tools/update-suite.ts +0 -44
@@ -1,10 +1,8 @@
1
- import { listPrompts as apiListPrompts } from "../langwatch-api.js";
1
+ import { listPrompts as apiListPrompts } from "../langwatch-api.ts";
2
2
 
3
3
  /**
4
- * Handles the platform_list_prompts MCP tool invocation.
5
- *
6
- * Lists all prompts in the LangWatch project, formatted as an
7
- * AI-readable markdown table.
4
+ * Handles the platform_list_prompts MCP tool: lists prompts in the
5
+ * project as an AI-readable markdown table.
8
6
  */
9
7
  export async function handleListPrompts(): Promise<string> {
10
8
  const prompts = await apiListPrompts();
@@ -26,9 +24,7 @@ export async function handleListPrompts(): Promise<string> {
26
24
  lines.push(`| ${handle} | ${name} | ${version} |`);
27
25
  }
28
26
 
29
- lines.push(
30
- "\n> Use `platform_get_prompt` with the handle or ID to see full prompt details."
31
- );
27
+ lines.push("\n> Use `platform_get_prompt` with the handle or ID to see full prompt details.");
32
28
 
33
29
  return lines.join("\n");
34
30
  }
@@ -0,0 +1,47 @@
1
+ import { listRunPlans as apiListRunPlans } from "../langwatch-api-run-plans.ts";
2
+ import { describeRunPlanScope } from "./format-run-plan.ts";
3
+
4
+ /**
5
+ * Handles the platform_list_run_plans MCP tool invocation.
6
+ */
7
+ export async function handleListRunPlans(params: {
8
+ includeArchived?: boolean;
9
+ format?: "digest" | "json";
10
+ }): Promise<string> {
11
+ const plans = await apiListRunPlans({
12
+ includeArchived: params.includeArchived,
13
+ });
14
+
15
+ if (params.format === "json") {
16
+ return JSON.stringify(plans, null, 2);
17
+ }
18
+
19
+ if (!Array.isArray(plans) || plans.length === 0) {
20
+ return "No run plans found in this project.\n\n> Tip: Use `platform_run_plan` to start one. A run plan is created the first time you run its name.";
21
+ }
22
+
23
+ const lines: string[] = [];
24
+ lines.push(`# Run Plans (${plans.length} total)\n`);
25
+
26
+ for (const plan of plans) {
27
+ lines.push(`## ${plan.name}${plan.archivedAt ? " (archived)" : ""}`);
28
+ lines.push(`**ID**: ${plan.id}`);
29
+ lines.push(`**Covers**: ${describeRunPlanScope(plan.scope, plan.scenarioIds)}`);
30
+ lines.push(
31
+ `**Targets**: ${plan.targets.length} (${plan.targets
32
+ .map((t) => `${t.type}:${t.referenceId}`)
33
+ .join(", ")})`,
34
+ );
35
+ lines.push(`**Repeat**: ${plan.repeatCount}x`);
36
+ if (plan.labels.length > 0) {
37
+ lines.push(`**Labels**: ${plan.labels.join(", ")}`);
38
+ }
39
+ lines.push("");
40
+ }
41
+
42
+ lines.push(
43
+ "> Use `platform_get_run_plan` with the ID for the full configuration, or `platform_rerun_run_plan` to run it again.",
44
+ );
45
+
46
+ return lines.join("\n");
47
+ }
@@ -1,22 +1,30 @@
1
- import { listScenarios as apiListScenarios } from "../langwatch-api-scenarios.js";
1
+ import { listScenarios as apiListScenarios } from "../langwatch-api-scenarios.ts";
2
2
 
3
3
  /**
4
- * Handles the platform_list_scenarios MCP tool invocation.
5
- *
6
- * Lists all scenarios in the LangWatch project, formatted as an
7
- * AI-readable digest or raw JSON.
4
+ * Handles the platform_list_scenarios MCP tool: lists scenarios in the
5
+ * project as an AI-readable digest or raw JSON.
8
6
  */
9
7
  export async function handleListScenarios(params: {
8
+ testSuiteId?: string;
10
9
  format?: "digest" | "json";
11
10
  }): Promise<string> {
12
- const scenarios = await apiListScenarios();
11
+ const all = await apiListScenarios();
12
+
13
+ // The REST list takes no test suite query, so the filter runs here on the
14
+ // testSuiteId every scenario already carries in the response.
15
+ const scenarios =
16
+ params.testSuiteId !== undefined && Array.isArray(all)
17
+ ? all.filter((s) => s.testSuiteId === params.testSuiteId)
18
+ : all;
13
19
 
14
20
  if (params.format === "json") {
15
21
  return JSON.stringify(scenarios, null, 2);
16
22
  }
17
23
 
18
24
  if (!Array.isArray(scenarios) || scenarios.length === 0) {
19
- return "No scenarios found in this project.\n\n> Tip: Use `platform_create_scenario` to create your first scenario.";
25
+ return params.testSuiteId !== undefined
26
+ ? `No scenarios found in test suite ${params.testSuiteId}.\n\n> Tip: Use \`platform_create_scenario\` with testSuiteId \`${params.testSuiteId}\` to file one there.`
27
+ : "No scenarios found in this project.\n\n> Tip: Use `platform_create_scenario` to create your first scenario.";
20
28
  }
21
29
 
22
30
  const lines: string[] = [];
@@ -25,23 +33,24 @@ export async function handleListScenarios(params: {
25
33
  for (const s of scenarios) {
26
34
  lines.push(`## ${s.name}`);
27
35
  lines.push(`**ID**: ${s.id}`);
28
- const preview =
29
- s.situation && s.situation.length > 60
30
- ? s.situation.slice(0, 60) + "..."
31
- : s.situation;
36
+ const preview = formatSituationPreview(s.situation);
32
37
  lines.push(`**Situation**: ${preview}`);
33
- lines.push(
34
- `**Criteria**: ${Array.isArray(s.criteria) ? s.criteria.length : 0} criteria`,
35
- );
38
+ lines.push(`**Criteria**: ${Array.isArray(s.criteria) ? s.criteria.length : 0} criteria`);
36
39
  if (Array.isArray(s.labels) && s.labels.length > 0) {
37
40
  lines.push(`**Labels**: ${s.labels.join(", ")}`);
38
41
  }
39
42
  lines.push("");
40
43
  }
41
44
 
42
- lines.push(
43
- "> Use `platform_get_scenario` with the ID to see full scenario details.",
44
- );
45
+ lines.push("> Use `platform_get_scenario` with the ID to see full scenario details.");
45
46
 
46
47
  return lines.join("\n");
47
48
  }
49
+
50
+ function formatSituationPreview(situation: string | undefined): string | undefined {
51
+ if (situation && situation.length > 60) {
52
+ return situation.slice(0, 60) + "...";
53
+ }
54
+
55
+ return situation;
56
+ }
@@ -1,4 +1,5 @@
1
- import { listSimulationRuns as apiListSimulationRuns } from "../langwatch-api-simulation-runs.js";
1
+ import { listSimulationRuns as apiListSimulationRuns } from "../langwatch-api-simulation-runs.ts";
2
+ import { formatRunStatus } from "./format-suite-details.ts";
2
3
 
3
4
  /**
4
5
  * Handles the platform_list_simulation_runs MCP tool invocation.
@@ -22,14 +23,16 @@ export async function handleListSimulationRuns(params: {
22
23
  const { runs } = result;
23
24
 
24
25
  if (runs.length === 0) {
25
- return "No simulation runs found.\n\n> Run a suite first with `platform_run_suite` to create simulation runs.";
26
+ return "No simulation runs found.\n\n> Run scenarios first with `platform_run_plan` or `platform_run_test_suite` to create simulation runs.";
26
27
  }
27
28
 
28
29
  const lines: string[] = [];
29
- lines.push(`# Simulation Runs (${runs.length} results${result.hasMore ? ", more available" : ""})\n`);
30
+ lines.push(
31
+ `# Simulation Runs (${runs.length} results${result.hasMore ? ", more available" : ""})\n`,
32
+ );
30
33
 
31
34
  for (const run of runs) {
32
- const statusIcon = run.status === "SUCCESS" ? "pass" : run.status === "FAILED" ? "FAIL" : run.status;
35
+ const statusIcon = formatRunStatus(run.status);
33
36
  const duration = run.durationInMs > 0 ? `${(run.durationInMs / 1000).toFixed(1)}s` : "—";
34
37
  const verdict = run.results?.verdict ?? "";
35
38
 
@@ -40,10 +43,15 @@ export async function handleListSimulationRuns(params: {
40
43
  if (run.totalCost) {
41
44
  lines.push(`**Cost**: $${run.totalCost.toFixed(4)}`);
42
45
  }
46
+ if (run.note) {
47
+ lines.push(`**Note**: ${run.note}`);
48
+ }
43
49
  lines.push("");
44
50
  }
45
51
 
46
- lines.push("> Use `platform_get_simulation_run` with a run ID to see full details (messages, results).");
52
+ lines.push(
53
+ "> Use `platform_get_simulation_run` with a run ID to see full details (messages, results).",
54
+ );
47
55
 
48
56
  return lines.join("\n");
49
57
  }
@@ -0,0 +1,35 @@
1
+ import { listTestSuites as apiListTestSuites } from "../langwatch-api-test-suites.ts";
2
+
3
+ /**
4
+ * Handles the platform_list_test_suites MCP tool invocation.
5
+ */
6
+ export async function handleListTestSuites(params: {
7
+ format?: "digest" | "json";
8
+ }): Promise<string> {
9
+ const suites = await apiListTestSuites();
10
+
11
+ if (params.format === "json") {
12
+ return JSON.stringify(suites, null, 2);
13
+ }
14
+
15
+ if (!Array.isArray(suites) || suites.length === 0) {
16
+ return "No test suites found in this project.\n\n> Tip: Use `platform_create_test_suite` to create one, then file scenarios in it with `testSuiteId`.";
17
+ }
18
+
19
+ const lines: string[] = [];
20
+ lines.push(`# Test Suites (${suites.length} total)\n`);
21
+
22
+ for (const suite of suites) {
23
+ lines.push(`## ${suite.name}${suite.archivedAt ? " (archived)" : ""}`);
24
+ lines.push(`**ID**: ${suite.id}`);
25
+ lines.push(`**Slug**: ${suite.slug}`);
26
+ lines.push(`**Scenarios**: ${suite.scenarioCount}`);
27
+ lines.push("");
28
+ }
29
+
30
+ lines.push(
31
+ "> Use `platform_get_test_suite` with the ID to read the scenarios, or `platform_run_test_suite` to run them against a target.",
32
+ );
33
+
34
+ return lines.join("\n");
35
+ }
@@ -0,0 +1,17 @@
1
+ import { listTriggerFires as apiListTriggerFires } from "../langwatch-api-triggers.ts";
2
+
3
+ /**
4
+ * Handles the platform_list_trigger_fires MCP tool invocation: one page of
5
+ * fires, newest first, and the cursor for the next page when there is one.
6
+ */
7
+ export async function handleListTriggerFires(params: {
8
+ id: string;
9
+ limit?: number;
10
+ cursor?: string;
11
+ }): Promise<string> {
12
+ const page = await apiListTriggerFires(params);
13
+ if (page.fires.length === 0) {
14
+ return params.cursor ? "No more fires." : "This automation has not fired yet.";
15
+ }
16
+ return JSON.stringify(page, null, 2);
17
+ }
@@ -0,0 +1,39 @@
1
+ import { listTriggers as apiListTriggers } from "../langwatch-api-triggers.ts";
2
+ import type { Trigger } from "../schemas/triggers.ts";
3
+
4
+ /**
5
+ * Handles the platform_list_triggers MCP tool invocation.
6
+ */
7
+ export async function handleListTriggers(params: { format?: "digest" | "json" }): Promise<string> {
8
+ const triggers = await apiListTriggers();
9
+ if (params.format === "json") return JSON.stringify(triggers, null, 2);
10
+ if (triggers.length === 0) {
11
+ return "No triggers found. Use `platform_create_trigger` to create one.";
12
+ }
13
+ const lines = [`# Triggers (${triggers.length} total)\n`];
14
+ for (const trigger of triggers) lines.push(...digestTrigger(trigger), "");
15
+ return lines.join("\n");
16
+ }
17
+
18
+ function digestTrigger(trigger: Trigger): string[] {
19
+ const lines = [
20
+ `## ${trigger.name}`,
21
+ `**ID**: ${trigger.id}`,
22
+ `**Kind**: ${trigger.kind ?? "AUTOMATION"}`,
23
+ `**Action**: ${trigger.action}`,
24
+ `**Status**: ${trigger.active ? "active" : "inactive"}`,
25
+ ];
26
+ if (trigger.alertType) lines.push(`**Alert**: ${trigger.alertType}`);
27
+ if (trigger.filterQuery) lines.push(`**Filter query**: ${trigger.filterQuery}`);
28
+ else if (Object.keys(trigger.filters).length > 0) {
29
+ lines.push(`**Filters**: ${JSON.stringify(trigger.filters)}`);
30
+ }
31
+ if (trigger.graphAlert) {
32
+ const rule = trigger.graphAlert;
33
+ lines.push(
34
+ `**Fires when**: ${rule.seriesName} ${rule.operator} ${rule.threshold} over ${rule.timePeriod}m${trigger.customGraphId ? ` on graph ${trigger.customGraphId}` : ""}`,
35
+ );
36
+ }
37
+ if (trigger.report) lines.push(`**Report**: ${JSON.stringify(trigger.report)}`);
38
+ return lines;
39
+ }
@@ -1,4 +1,4 @@
1
- import { listWorkflows as apiListWorkflows } from "../langwatch-api-workflows.js";
1
+ import { listWorkflows as apiListWorkflows } from "../langwatch-api-workflows.ts";
2
2
 
3
3
  export async function handleListWorkflows(): Promise<string> {
4
4
  const workflows = await apiListWorkflows();
@@ -23,9 +23,7 @@ export async function handleListWorkflows(): Promise<string> {
23
23
  lines.push("");
24
24
  }
25
25
 
26
- lines.push(
27
- "> Use `platform_get_workflow` with the ID to see full workflow details.",
28
- );
26
+ lines.push("> Use `platform_get_workflow` with the ID to see full workflow details.");
29
27
 
30
28
  return lines.join("\n");
31
29
  }
@@ -1,4 +1,4 @@
1
- import { renamePromptTag as apiRenamePromptTag } from "../langwatch-api.js";
1
+ import { renamePromptTag as apiRenamePromptTag } from "../langwatch-api.ts";
2
2
 
3
3
  export async function handleRenamePromptTag(params: {
4
4
  tag: string;
@@ -0,0 +1,15 @@
1
+ import { renameTestSuite as apiRenameTestSuite } from "../langwatch-api-test-suites.ts";
2
+
3
+ /**
4
+ * Handles the platform_rename_test_suite MCP tool invocation.
5
+ */
6
+ export async function handleRenameTestSuite(params: { id: string; name: string }): Promise<string> {
7
+ const suite = await apiRenameTestSuite(params);
8
+
9
+ return [
10
+ `Test suite ${suite.id} is now named "${suite.name}".`,
11
+ "",
12
+ `**Slug**: ${suite.slug}`,
13
+ `**Scenarios**: ${suite.scenarioCount}`,
14
+ ].join("\n");
15
+ }
@@ -5,7 +5,8 @@ import {
5
5
  redactSessionJsonl,
6
6
  truncateJsonlToByteBudget,
7
7
  } from "@langwatch/redaction";
8
- import { getConfig } from "../config.js";
8
+
9
+ import { getConfig } from "../config.ts";
9
10
 
10
11
  /** Transcripts are capped after redaction; oldest lines are dropped first. */
11
12
  const MAX_SESSION_BYTES = 8 * 1024 * 1024;
@@ -68,14 +69,11 @@ function redactReport(params: ReportIssueParams): RedactedReport {
68
69
  };
69
70
  }
70
71
 
71
- async function deliverReport(
72
- report: RedactedReport,
73
- params: ReportIssueParams,
74
- ): Promise<string> {
72
+ async function deliverReport(report: RedactedReport, params: ReportIssueParams): Promise<string> {
75
73
  const config = getConfig();
76
74
  const endpoint = config.endpoint.replace(/\/+$/, "");
77
75
 
78
- const response = await fetch(`${endpoint}/api/bug-reports`, {
76
+ const response = await fetch(`${endpoint}/api/v1/bug-reports`, {
79
77
  method: "POST",
80
78
  headers: {
81
79
  "content-type": "application/json",
@@ -117,9 +115,7 @@ async function deliverReport(
117
115
  * an API key: the reporter may be struggling precisely because setup failed.
118
116
  * When a key is configured it only links the report to the project.
119
117
  */
120
- export async function handleReportIssue(
121
- params: ReportIssueParams,
122
- ): Promise<string> {
118
+ export async function handleReportIssue(params: ReportIssueParams): Promise<string> {
123
119
  if (!params.user_approved) {
124
120
  throw new Error(
125
121
  "This sends a report to the LangWatch team, so the user must approve it first. " +
@@ -0,0 +1,18 @@
1
+ import { rerunRunPlan as apiRerunRunPlan, type RunParameters } from "../langwatch-api-run-plans.ts";
2
+ import { formatRunPlanRun } from "./format-run-plan.ts";
3
+
4
+ /**
5
+ * Handles the platform_rerun_run_plan MCP tool invocation.
6
+ */
7
+ export async function handleRerunRunPlan(params: {
8
+ id: string;
9
+ parameters?: RunParameters;
10
+ note?: string;
11
+ }): Promise<string> {
12
+ const result = await apiRerunRunPlan(params.id, {
13
+ parameters: params.parameters,
14
+ note: params.note,
15
+ });
16
+
17
+ return formatRunPlanRun(result);
18
+ }
@@ -1,8 +1,6 @@
1
- import { revokeApiKey as apiRevokeApiKey } from "../langwatch-api-api-keys.js";
1
+ import { revokeApiKey as apiRevokeApiKey } from "../langwatch-api-api-keys.ts";
2
2
 
3
- export async function handleRevokeApiKey(params: {
4
- id: string;
5
- }): Promise<string> {
3
+ export async function handleRevokeApiKey(params: { id: string }): Promise<string> {
6
4
  await apiRevokeApiKey(params.id);
7
5
 
8
6
  return `API key ${params.id} revoked successfully.`;
@@ -1,35 +1,86 @@
1
- import { runAgent as apiRunAgent } from "../langwatch-api-agents.js";
1
+ import { z } from "zod";
2
+
3
+ import { runAgent as apiRunAgent, type AgentCallParams } from "../langwatch-api-agents.ts";
4
+
5
+ /**
6
+ * A scalar and an array both parse as JSON, and either one reaches the agent
7
+ * as a body it cannot read, so only an object passes.
8
+ */
9
+ const jsonObjectSchema = z.looseObject({});
10
+ type JsonObject = z.infer<typeof jsonObjectSchema>;
11
+
12
+ function outputLines(result: object): string[] {
13
+ const output = (result as Record<string, unknown>).output;
14
+ if (output !== undefined) {
15
+ return ["**Output:**", typeof output === "string" ? output : JSON.stringify(output, null, 2)];
16
+ }
17
+ return ["**Result:**", JSON.stringify(result, null, 2)];
18
+ }
19
+
20
+ function connectedLines(result: object): string[] {
21
+ const lines: string[] = [];
22
+ const instance = (result as { instance?: { hostname?: string; label?: string | null } }).instance;
23
+ const durationMs = (result as { durationMs?: number }).durationMs;
24
+ if (instance?.hostname) {
25
+ const label = instance.label ? ` (${instance.label})` : "";
26
+ lines.push(`\n**Instance:** ${instance.hostname}${label}`);
27
+ }
28
+ if (typeof durationMs === "number") lines.push(`**Duration:** ${durationMs} ms`);
29
+ const session = (result as { session?: unknown }).session;
30
+ if (session !== undefined && session !== null) {
31
+ lines.push("**Session:**");
32
+ lines.push(JSON.stringify(session, null, 2));
33
+ }
34
+ return lines;
35
+ }
2
36
 
3
37
  /**
4
38
  * Handles the platform_run_agent MCP tool invocation.
39
+ *
40
+ * @see specs/mcp-server/agent-tools.feature
5
41
  */
6
- export async function handleRunAgent(params: {
42
+ export async function handleRunAgent({
43
+ id,
44
+ input,
45
+ message,
46
+ parameters,
47
+ threadId,
48
+ }: {
7
49
  id: string;
8
50
  input?: string;
51
+ message?: string;
52
+ parameters?: AgentCallParams;
53
+ threadId?: string;
9
54
  }): Promise<string> {
10
- let parsedInput: Record<string, unknown> = {};
11
- if (params.input) {
55
+ let parsedInput: JsonObject = {};
56
+ if (input) {
57
+ let decoded: unknown;
12
58
  try {
13
- parsedInput = JSON.parse(params.input) as Record<string, unknown>;
59
+ decoded = JSON.parse(input);
14
60
  } catch {
15
61
  return "Error: `input` must be a valid JSON object.";
16
62
  }
63
+ const result = jsonObjectSchema.safeParse(decoded);
64
+ if (!result.success) {
65
+ return "Error: `input` must be a valid JSON object.";
66
+ }
67
+ parsedInput = result.data;
17
68
  }
18
69
 
19
- const { agentType, result } = await apiRunAgent(params.id, parsedInput);
70
+ const { agentType, result } = await apiRunAgent({
71
+ id,
72
+ input: parsedInput,
73
+ message,
74
+ parameters,
75
+ threadId,
76
+ });
20
77
 
21
78
  const lines: string[] = [];
22
79
  lines.push(`Agent executed successfully (type: ${agentType}).\n`);
23
80
 
24
81
  if (typeof result === "object" && result !== null) {
25
- const output = (result as Record<string, unknown>).output;
26
- if (output !== undefined) {
27
- lines.push("**Output:**");
28
- lines.push(typeof output === "string" ? output : JSON.stringify(output, null, 2));
29
- } else {
30
- lines.push("**Result:**");
31
- lines.push(JSON.stringify(result, null, 2));
32
- }
82
+ lines.push(...outputLines(result));
83
+ if (agentType === "connected") lines.push(...connectedLines(result));
33
84
  }
34
85
 
35
86
  return lines.join("\n");
@@ -1,5 +1,5 @@
1
- import { LangWatchApiError, makeRequest } from "../langwatch-api.js";
2
- import { deriveRunStatus } from "./experiment-run-status.js";
1
+ import { LangWatchApiError, makeRequest } from "../langwatch-api.ts";
2
+ import { deriveRunStatus } from "./experiment-run-status.ts";
3
3
 
4
4
  interface EvaluationRunResponse {
5
5
  runId: string;
@@ -24,12 +24,10 @@ interface EvaluationStatusResponse {
24
24
  };
25
25
  }
26
26
 
27
- export async function handleRunExperiment(params: {
28
- slug: string;
29
- }): Promise<string> {
27
+ export async function handleRunExperiment(params: { slug: string }): Promise<string> {
30
28
  const result = (await makeRequest(
31
29
  "POST",
32
- `/api/experiments/${encodeURIComponent(params.slug)}/run`,
30
+ `/api/v1/experiments/${encodeURIComponent(params.slug)}/run`,
33
31
  )) as EvaluationRunResponse;
34
32
 
35
33
  const lines: string[] = [];
@@ -75,7 +73,7 @@ async function statusFromResults(params: {
75
73
  try {
76
74
  results = (await makeRequest(
77
75
  "GET",
78
- `/api/experiments/runs/${encodeURIComponent(params.runId)}/results${qs}`,
76
+ `/api/v1/experiments/runs/${encodeURIComponent(params.runId)}/results${qs}`,
79
77
  )) as ResultsForStatus;
80
78
  } catch (error) {
81
79
  // Only a genuine "no such run" is a fallback miss (-> guidance). Real
@@ -97,19 +95,13 @@ async function statusFromResults(params: {
97
95
  lines.push(`**Status**: ${status}`);
98
96
  lines.push(`**Progress**: ${progress}/${total} cells`);
99
97
  if (results.timestamps.createdAt) {
100
- lines.push(
101
- `**Started**: ${new Date(results.timestamps.createdAt).toISOString()}`,
102
- );
98
+ lines.push(`**Started**: ${new Date(results.timestamps.createdAt).toISOString()}`);
103
99
  }
104
100
  if (results.timestamps.finishedAt) {
105
- lines.push(
106
- `**Finished**: ${new Date(results.timestamps.finishedAt).toISOString()}`,
107
- );
101
+ lines.push(`**Finished**: ${new Date(results.timestamps.finishedAt).toISOString()}`);
108
102
  }
109
103
  if (results.timestamps.stoppedAt) {
110
- lines.push(
111
- `**Stopped**: ${new Date(results.timestamps.stoppedAt).toISOString()}`,
112
- );
104
+ lines.push(`**Stopped**: ${new Date(results.timestamps.stoppedAt).toISOString()}`);
113
105
  }
114
106
  lines.push("");
115
107
  lines.push(
@@ -118,6 +110,31 @@ async function statusFromResults(params: {
118
110
  return lines.join("\n");
119
111
  }
120
112
 
113
+ async function statusAfterFailedRead({
114
+ params,
115
+ error,
116
+ }: {
117
+ params: { runId: string; experimentSlug?: string };
118
+ error: unknown;
119
+ }): Promise<string> {
120
+ const code = error instanceof LangWatchApiError ? error.status : undefined;
121
+ const message = error instanceof Error ? error.message : String(error);
122
+ if (code === 404 || /404|not found/i.test(message)) {
123
+ const fallback = await statusFromResults(params);
124
+ if (fallback) return fallback;
125
+ return [
126
+ `# Evaluation Run ${params.runId}`,
127
+ "",
128
+ "**Status**: not found",
129
+ "",
130
+ `Could not find run \`${params.runId}\`. SDK-logged runs and runs older than 24h are not in the live run-state and must be resolved by experiment slug.`,
131
+ "",
132
+ "> Pass `experimentSlug`: discover it with `platform_experiment_list`, then use `platform_experiment_list_runs` for the run ids. Or fetch the rows directly with `platform_experiment_results`.",
133
+ ].join("\n");
134
+ }
135
+ throw error;
136
+ }
137
+
121
138
  export async function handleExperimentStatus(params: {
122
139
  runId: string;
123
140
  experimentSlug?: string;
@@ -126,26 +143,10 @@ export async function handleExperimentStatus(params: {
126
143
  try {
127
144
  status = (await makeRequest(
128
145
  "GET",
129
- `/api/experiments/runs/${encodeURIComponent(params.runId)}`,
146
+ `/api/v1/experiments/runs/${encodeURIComponent(params.runId)}`,
130
147
  )) as EvaluationStatusResponse;
131
148
  } catch (error) {
132
- const code =
133
- error instanceof LangWatchApiError ? error.status : undefined;
134
- const message = error instanceof Error ? error.message : String(error);
135
- if (code === 404 || /404|not found/i.test(message)) {
136
- const fallback = await statusFromResults(params);
137
- if (fallback) return fallback;
138
- return [
139
- `# Evaluation Run ${params.runId}`,
140
- "",
141
- "**Status**: not found",
142
- "",
143
- `Could not find run \`${params.runId}\`. SDK-logged runs and runs older than 24h are not in the live run-state and must be resolved by experiment slug.`,
144
- "",
145
- "> Pass `experimentSlug`: discover it with `platform_experiment_list`, then use `platform_experiment_list_runs` for the run ids. Or fetch the rows directly with `platform_experiment_results`.",
146
- ].join("\n");
147
- }
148
- throw error;
149
+ return statusAfterFailedRead({ params, error });
149
150
  }
150
151
 
151
152
  const lines: string[] = [];
@@ -169,9 +170,7 @@ export async function handleExperimentStatus(params: {
169
170
  lines.push(`**Failed**: ${status.summary.failedCells}`);
170
171
  }
171
172
  if (status.summary.duration) {
172
- lines.push(
173
- `**Duration**: ${(status.summary.duration / 1000).toFixed(1)}s`,
174
- );
173
+ lines.push(`**Duration**: ${(status.summary.duration / 1000).toFixed(1)}s`);
175
174
  }
176
175
  if (status.summary.runUrl) {
177
176
  lines.push(`**View results**: ${status.summary.runUrl}`);
@@ -0,0 +1,46 @@
1
+ import {
2
+ runRunPlan as apiRunRunPlan,
3
+ type RunParameters,
4
+ type RunPlanScope,
5
+ type RunPlanTarget,
6
+ } from "../langwatch-api-run-plans.ts";
7
+ import { toWireTargets } from "../schemas/run-plan.ts";
8
+ import { type EvaluatorAttachmentInput, toWireAttachments } from "../schemas/suite-fields.ts";
9
+ import { formatRunPlanRun } from "./format-run-plan.ts";
10
+
11
+ /**
12
+ * Handles the platform_run_plan MCP tool invocation.
13
+ */
14
+ export async function handleRunPlan(params: {
15
+ name?: string;
16
+ scope: RunPlanScope;
17
+ scenarioIds?: string[];
18
+ targets: RunPlanTarget[];
19
+ repeatCount?: number;
20
+ simulatorModel?: string;
21
+ judgeModel?: string;
22
+ evaluators?: EvaluatorAttachmentInput[];
23
+ parameters?: RunParameters;
24
+ note?: string;
25
+ idempotencyKey?: string;
26
+ }): Promise<string> {
27
+ const result = await apiRunRunPlan({
28
+ name: params.name,
29
+ config: {
30
+ scope: params.scope,
31
+ targets: toWireTargets(params.targets),
32
+ repeatCount: params.repeatCount,
33
+ simulatorModel: params.simulatorModel,
34
+ judgeModel: params.judgeModel,
35
+ scenarioIds: params.scenarioIds,
36
+ ...(params.evaluators !== undefined
37
+ ? { evaluators: toWireAttachments(params.evaluators) }
38
+ : {}),
39
+ },
40
+ idempotencyKey: params.idempotencyKey,
41
+ parameters: params.parameters,
42
+ note: params.note,
43
+ });
44
+
45
+ return formatRunPlanRun(result);
46
+ }