@langwatch/mcp-server 2.1.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 (415) hide show
  1. package/.gitignore +7 -0
  2. package/.npmignore +41 -0
  3. package/CHANGELOG.md +192 -201
  4. package/CONTRIBUTING.md +10 -0
  5. package/README.md +70 -68
  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-W3IKI7UL.js → archive-project-SPVHXK6A.js} +4 -4
  10. package/dist/{archive-run-plan-474OKHHU.js → archive-run-plan-65QN3XRX.js} +4 -4
  11. package/dist/archive-run-plan-Z4SYE6BP.js +15 -0
  12. package/dist/{archive-scenario-V5UNYK26.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-O7FLDMXK.js → archive-test-suite-NKZDZY3D.js} +4 -4
  16. package/dist/assign-prompt-tag-5IUZXJ2T.js +23 -0
  17. package/dist/{assign-prompt-tag-Q46WRB6P.js → assign-prompt-tag-HBZLBIFD.js} +8 -4
  18. package/dist/{chunk-OJLYYJWI.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-UF6XIGYR.js → chunk-6YZUOD34.js} +2 -5
  22. package/dist/{chunk-WVI5CJ6S.js → chunk-7AQLPVFL.js} +2 -2
  23. package/dist/chunk-7VNSRCXO.js +129 -0
  24. package/dist/{chunk-G4ZAZTZW.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-EYXMLE5X.js → chunk-HGELNIVY.js} +56 -47
  30. package/dist/{chunk-UJPXFA26.js → chunk-HHMNZAPD.js} +101 -74
  31. package/dist/{chunk-RVAE2MEA.js → chunk-I7ATIZED.js} +7 -7
  32. package/dist/{chunk-S4GVX36W.js → chunk-ILZDO25L.js} +7 -10
  33. package/dist/{chunk-QRO35SOM.js → chunk-J7PQKBLD.js} +652 -528
  34. package/dist/{chunk-SR6QPRIE.js → chunk-JRJPH75H.js} +7 -13
  35. package/dist/chunk-K2I7Z3LZ.js +28 -0
  36. package/dist/{chunk-UFOYFYI7.js → chunk-NKMTIHIJ.js} +6 -9
  37. package/dist/{chunk-HV4DWKBI.js → chunk-O7EMWEVJ.js} +2 -4
  38. package/dist/{chunk-56OGTS24.js → chunk-PTDR56Z3.js} +4 -11
  39. package/dist/{chunk-JR6DJZOU.js → chunk-RABYBFX5.js} +4 -10
  40. package/dist/chunk-SUPUUC4W.js +64 -0
  41. package/dist/{chunk-JTQJRNFJ.js → chunk-SXFC3FNH.js} +4 -4
  42. package/dist/{chunk-CKNAH5TG.js → chunk-U24EACC4.js} +3 -10
  43. package/dist/chunk-UNJM3BIL.js +21 -0
  44. package/dist/{chunk-QAMP3CGR.js → chunk-UTJCWXPZ.js} +4 -4
  45. package/dist/chunk-UWLE5T2F.js +312 -0
  46. package/dist/{chunk-6DJDEXET.js → chunk-VMWJD732.js} +6 -12
  47. package/dist/{chunk-7E4FZIYJ.js → chunk-XUIJYNRJ.js} +1 -1
  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-JFJ2K6X3.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-EUXXQ6NS.js → create-annotation-VUSXULQK.js} +10 -5
  57. package/dist/{create-api-key-BGBB76JX.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-Z76AIPLS.js → create-dashboard-WTKKS5Z6.js} +4 -4
  61. package/dist/{create-dataset-FD5VAXU4.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-WQUXXOHI.js → create-dataset-records-W4GLN2FV.js} +5 -7
  65. package/dist/{create-evaluator-6NV33Z52.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 -10
  69. package/dist/create-project-6N7PIYRY.js +44 -0
  70. package/dist/{create-project-ZQ7TFIO2.js → create-project-KAIC46UY.js} +4 -4
  71. package/dist/{create-prompt-BS6QRCUU.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-FCQ5ELSQ.js → create-prompt-tag-OPQUEXWB.js} +3 -3
  75. package/dist/create-scenario-5PJBMAXO.js +33 -0
  76. package/dist/{create-scenario-DRPTPXU3.js → create-scenario-UEM77OE7.js} +5 -5
  77. package/dist/{create-test-suite-ZIZCCFJ4.js → create-test-suite-4IPXVSFQ.js} +6 -6
  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-SA4JMUZF.js → delete-agent-QMEK3XHK.js} +4 -4
  83. package/dist/delete-annotation-HY3O2OGR.js +17 -0
  84. package/dist/{delete-annotation-X3KKK7QY.js → delete-annotation-VKIQWUYW.js} +4 -4
  85. package/dist/delete-dashboard-76N66XXL.js +18 -0
  86. package/dist/{delete-dashboard-LYMRPF27.js → delete-dashboard-JVIVHNJM.js} +4 -4
  87. package/dist/delete-dataset-HQCR66MG.js +18 -0
  88. package/dist/{delete-dataset-W6EZ44HY.js → delete-dataset-WKRUW4FP.js} +5 -7
  89. package/dist/{delete-dataset-records-7CNOTALB.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-QB3OCZUV.js → delete-prompt-tag-YYQ4VMAD.js} +3 -3
  95. package/dist/{delete-workflow-NG2VXYYM.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-W7KBXA4J.js → discover-scenario-schema-OOFIQKOG.js} +37 -17
  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-7THF7HCU.js → get-agent-OTIYUFZA.js} +15 -11
  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-P4WWVHFU.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-RZ44UIN6.js → get-evaluator-ISMC4LLI.js} +4 -4
  112. package/dist/get-evaluator-XEUZGZCH.js +47 -0
  113. package/dist/{get-project-QSQEAB33.js → get-project-5VKROSDH.js} +4 -4
  114. package/dist/get-project-RM6FRCBK.js +26 -0
  115. package/dist/{get-prompt-GVKXF5NL.js → get-prompt-OWXJZHQQ.js} +53 -58
  116. package/dist/get-prompt-W52DY36E.js +94 -0
  117. package/dist/{get-run-plan-NY7J5GRE.js → get-run-plan-BE3M2AUX.js} +7 -9
  118. package/dist/get-run-plan-RUXQ6PAX.js +58 -0
  119. package/dist/get-scenario-RNM7BAX2.js +37 -0
  120. package/dist/{get-scenario-Q3LLQE4T.js → get-scenario-YM4ODWW6.js} +5 -5
  121. package/dist/get-simulation-run-6GIATQE5.js +69 -0
  122. package/dist/{get-simulation-run-WINEYDMK.js → get-simulation-run-LCFSMPGQ.js} +26 -22
  123. package/dist/{get-test-suite-4HKA7OKS.js → get-test-suite-GC2O7YH6.js} +5 -5
  124. package/dist/get-test-suite-P5LJ6VLF.js +48 -0
  125. package/dist/get-trace-KBRVV4NN.js +45 -0
  126. package/dist/{get-trace-RCUV7N4O.js → get-trace-SEF3FMR5.js} +11 -13
  127. package/dist/get-workflow-7PVED7JE.js +25 -0
  128. package/dist/{get-workflow-EEOC7Y45.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-WCDUARTH.js → http-server-IR4QOS43.js} +4071 -347
  131. package/dist/index.js +58671 -37983
  132. package/dist/langwatch-api-annotations-6SA4OB4C.js +17 -0
  133. package/dist/{langwatch-api-annotations-6DHVZWUK.js → langwatch-api-annotations-TBHLCQ5R.js} +4 -4
  134. package/dist/langwatch-api-dashboards-6EO2VVZW.js +17 -0
  135. package/dist/{langwatch-api-dashboards-2KJL2M42.js → langwatch-api-dashboards-NHU5BZD7.js} +4 -4
  136. package/dist/langwatch-api-monitors-CBF3FGIM.js +47 -0
  137. package/dist/{langwatch-api-monitors-6ISFJ7WX.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-6UJL5U4Z.js → langwatch-api-workflows-OKC4FXIF.js} +4 -4
  143. package/dist/langwatch-api-workflows-XGJE6SR5.js +15 -0
  144. package/dist/{list-agents-AMVDQPQL.js → list-agents-HVYWEQMI.js} +4 -4
  145. package/dist/list-agents-RBAOCF53.js +42 -0
  146. package/dist/list-annotations-HJH4NBLD.js +38 -0
  147. package/dist/{list-annotations-6PR5NLIC.js → list-annotations-J4UAHSUN.js} +10 -5
  148. package/dist/{list-api-keys-GVPNBIHQ.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-Z3BZKDGF.js → list-dashboards-ROSYFLDQ.js} +4 -4
  153. package/dist/list-dashboards-RQ635ZU7.js +32 -0
  154. package/dist/{list-dataset-records-O67HZ35Y.js → list-dataset-records-M5TKA6LK.js} +14 -10
  155. package/dist/list-dataset-records-WFM7F33C.js +43 -0
  156. package/dist/{list-datasets-WXZL6UMP.js → list-datasets-B5X4P7BQ.js} +9 -13
  157. package/dist/list-datasets-THUKQHPX.js +56 -0
  158. package/dist/{list-evaluators-PAX72WCN.js → list-evaluators-MYH2OVCI.js} +5 -7
  159. package/dist/list-evaluators-NLVWF6K7.js +32 -0
  160. package/dist/{list-model-providers-VVLZMLCX.js → list-model-providers-3JUGP4YI.js} +4 -4
  161. package/dist/list-model-providers-H3XKORFO.js +35 -0
  162. package/dist/{list-projects-AQVI6SUK.js → list-projects-6EJ5YYEW.js} +5 -7
  163. package/dist/list-projects-YNNSRMLC.js +40 -0
  164. package/dist/{list-prompt-tags-WZFBJOHG.js → list-prompt-tags-NVFQO6WX.js} +3 -3
  165. package/dist/list-prompt-tags-XUQTTAH4.js +23 -0
  166. package/dist/{list-prompts-BQOHRHYT.js → list-prompts-HSIMMHTF.js} +4 -6
  167. package/dist/list-prompts-IRI6AIXO.js +30 -0
  168. package/dist/{list-run-plans-UBAU2DGH.js → list-run-plans-PX2XI6EK.js} +5 -5
  169. package/dist/list-run-plans-QALLCN2K.js +45 -0
  170. package/dist/{list-scenarios-MS4IUIVM.js → list-scenarios-QZRPVHS4.js} +13 -11
  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-D6YF4ZOU.js → list-simulation-runs-OEADLLQR.js} +12 -8
  174. package/dist/list-test-suites-ANAQBLDG.js +34 -0
  175. package/dist/{list-test-suites-L7R2O6DR.js → list-test-suites-N4WVLBKK.js} +4 -4
  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-6MV4XJHF.js → list-workflows-IMSX7SXU.js} +5 -7
  181. package/dist/list-workflows-ZHTX5LCL.js +33 -0
  182. package/dist/{rename-prompt-tag-K5LQ4CY6.js → rename-prompt-tag-IQI7MHOI.js} +3 -3
  183. package/dist/rename-prompt-tag-PA2BRIE6.js +18 -0
  184. package/dist/{rename-test-suite-NTYHAO5X.js → rename-test-suite-4J7UX5S2.js} +4 -4
  185. package/dist/rename-test-suite-NNVLMLKY.js +20 -0
  186. package/dist/report-issue-AS34ZMJF.js +898 -0
  187. package/dist/{report-issue-RHZZ33IS.js → report-issue-DCZFLGDO.js} +81 -67
  188. package/dist/{rerun-run-plan-MUDWJBE4.js → rerun-run-plan-TG2V4WM4.js} +5 -5
  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-6LAZ3QZZ.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-T4ZYOZGA.js → run-plan-PAARQSI4.js} +7 -7
  196. package/dist/run-query-KJDH544C.js +47 -0
  197. package/dist/run-query-T4QW2Z5O.js +46 -0
  198. package/dist/{run-test-suite-L4MZ7G4D.js → run-test-suite-SQJELEZX.js} +6 -6
  199. package/dist/run-test-suite-STB6NUJM.js +25 -0
  200. package/dist/{run-workflow-DFIS23AP.js → run-workflow-D6PQNBI6.js} +4 -4
  201. package/dist/run-workflow-SP32SO5M.js +36 -0
  202. package/dist/search-traces-HCBGOG6R.js +170 -0
  203. package/dist/search-traces-HSTQ6WTQ.js +171 -0
  204. package/dist/{set-model-provider-XRNMFOVR.js → set-model-provider-GF7NXUJA.js} +4 -4
  205. package/dist/set-model-provider-KDQ7C4EZ.js +33 -0
  206. package/dist/{update-agent-DUWNYBNA.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-YSOMDCOB.js → update-dataset-SQZ6T4WX.js} +6 -6
  212. package/dist/{update-dataset-record-DEA2ITYR.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-NH7Q5GWV.js → update-evaluator-IGTX6PX4.js} +4 -4
  216. package/dist/{update-project-Q26FBSYH.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-ZQQ2C3KU.js → update-prompt-MY263DYF.js} +27 -29
  220. package/dist/update-scenario-7KA3JDXA.js +34 -0
  221. package/dist/{update-scenario-WUX34JAR.js → update-scenario-MOHRQKAQ.js} +5 -5
  222. package/package.json +35 -39
  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 +755 -609
  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 +18 -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 +12 -29
  244. package/src/langwatch-api-scenarios.ts +9 -11
  245. package/src/langwatch-api-secrets.ts +31 -24
  246. package/src/langwatch-api-simulation-runs.ts +6 -8
  247. package/src/langwatch-api-test-suites.ts +14 -33
  248. package/src/langwatch-api-triggers.ts +96 -34
  249. package/src/langwatch-api-workflows.ts +9 -9
  250. package/src/langwatch-api.ts +108 -124
  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 +13 -29
  255. package/src/schemas/suite-fields.ts +6 -23
  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 +2 -4
  260. package/src/tools/archive-scenario.ts +2 -4
  261. package/src/tools/archive-test-suite.ts +2 -4
  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 +5 -7
  274. package/src/tools/create-test-suite.ts +4 -9
  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 +41 -21
  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 +7 -21
  292. package/src/tools/format-scenario.ts +2 -4
  293. package/src/tools/format-suite-details.ts +6 -12
  294. package/src/tools/get-agent.ts +15 -6
  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 +63 -84
  302. package/src/tools/get-run-plan.ts +4 -6
  303. package/src/tools/get-scenario.ts +4 -6
  304. package/src/tools/get-simulation-run.ts +27 -24
  305. package/src/tools/get-test-suite.ts +2 -5
  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 +1 -1
  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 +2 -2
  323. package/src/tools/list-scenarios.ts +14 -15
  324. package/src/tools/list-simulation-runs.ts +8 -4
  325. package/src/tools/list-test-suites.ts +1 -1
  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 +2 -5
  331. package/src/tools/report-issue.ts +5 -9
  332. package/src/tools/rerun-run-plan.ts +2 -5
  333. package/src/tools/revoke-api-key.ts +2 -4
  334. package/src/tools/run-agent.ts +29 -26
  335. package/src/tools/run-experiment.ts +36 -37
  336. package/src/tools/run-plan.ts +4 -7
  337. package/src/tools/run-query.ts +47 -0
  338. package/src/tools/run-test-suite.ts +4 -7
  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 +2 -2
  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 +44 -59
  350. package/src/tools/update-scenario.ts +5 -7
  351. package/src/tools/update-test-suite.ts +6 -11
  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 +14 -12
  359. package/vitest.integration.config.js +10 -0
  360. package/vitest.scenario.config.js +9 -0
  361. package/.eslintrc.cjs +0 -36
  362. package/dist/chunk-AN4OUA4D.js +0 -86
  363. package/dist/chunk-GELJ2MQR.js +0 -226
  364. package/dist/chunk-K37ZNPXK.js +0 -24
  365. package/dist/config.d.ts +0 -17
  366. package/dist/create-mcp-server.d.ts +0 -10
  367. package/dist/delete-evaluator-RKYC4TNB.js +0 -16
  368. package/dist/discover-evaluator-schema-ESSHQGPY.js +0 -1912
  369. package/dist/get-analytics-R6AZD3AW.js +0 -73
  370. package/dist/get-dataset-AKTYSQDI.js +0 -49
  371. package/dist/index.d.ts +0 -2
  372. package/dist/langwatch-api-secrets-OEBD6GBU.js +0 -41
  373. package/dist/langwatch-api-triggers-5E6DDGX6.js +0 -31
  374. package/dist/run-agent-CAGWGTYT.js +0 -72
  375. package/dist/search-traces-4XTJYXIK.js +0 -79
  376. package/src/__tests__/agent-tools.unit.test.ts +0 -257
  377. package/src/__tests__/all-tools.integration.test.ts +0 -1872
  378. package/src/__tests__/config.unit.test.ts +0 -202
  379. package/src/__tests__/datasets.integration.test.ts +0 -620
  380. package/src/__tests__/datasets.unit.test.ts +0 -244
  381. package/src/__tests__/date-parsing.unit.test.ts +0 -78
  382. package/src/__tests__/discover-evaluator-schema.unit.test.ts +0 -89
  383. package/src/__tests__/discover-schema.unit.test.ts +0 -118
  384. package/src/__tests__/docker.integration.test.ts +0 -318
  385. package/src/__tests__/documentation-fetch-security.integration.test.ts +0 -182
  386. package/src/__tests__/evaluator-tools.unit.test.ts +0 -262
  387. package/src/__tests__/experiment-list-tools.unit.test.ts +0 -157
  388. package/src/__tests__/experiment-status.unit.test.ts +0 -194
  389. package/src/__tests__/feature-map-tool-drift.unit.test.ts +0 -93
  390. package/src/__tests__/get-experiment-results.unit.test.ts +0 -313
  391. package/src/__tests__/http-security-origin.unit.test.ts +0 -97
  392. package/src/__tests__/http-security-sessions.unit.test.ts +0 -209
  393. package/src/__tests__/http-security-verifier.unit.test.ts +0 -248
  394. package/src/__tests__/http-server-allocation.integration.test.ts +0 -279
  395. package/src/__tests__/http-server-origin.integration.test.ts +0 -169
  396. package/src/__tests__/http-server-session-auth.integration.test.ts +0 -341
  397. package/src/__tests__/http-transport.integration.test.ts +0 -395
  398. package/src/__tests__/integration.integration.test.ts +0 -284
  399. package/src/__tests__/langwatch-api.unit.test.ts +0 -661
  400. package/src/__tests__/model-provider-tools.unit.test.ts +0 -190
  401. package/src/__tests__/project-api-key-tools.unit.test.ts +0 -451
  402. package/src/__tests__/prompt-response-types.unit.test.ts +0 -51
  403. package/src/__tests__/prompts.integration.test.ts +0 -736
  404. package/src/__tests__/public-http-request-security.integration.test.ts +0 -118
  405. package/src/__tests__/report-issue.integration.test.ts +0 -147
  406. package/src/__tests__/run-plan-tools.unit.test.ts +0 -565
  407. package/src/__tests__/scenario-tools.integration.test.ts +0 -286
  408. package/src/__tests__/scenario-tools.unit.test.ts +0 -207
  409. package/src/__tests__/schemas.unit.test.ts +0 -85
  410. package/src/__tests__/simulation-run-tools.unit.test.ts +0 -116
  411. package/src/__tests__/support/http-server-harness.ts +0 -138
  412. package/src/__tests__/test-suite-tools.unit.test.ts +0 -615
  413. package/src/__tests__/tools.integration.test.ts +0 -896
  414. package/src/schemas/filter-fields.ts +0 -119
  415. package/src/schemas/index.ts +0 -9
@@ -1,48 +1,110 @@
1
- import { makeRequest } from "./langwatch-api.js";
1
+ import { z } from "zod";
2
2
 
3
- export interface TriggerSummary {
4
- id: string;
5
- name: string;
6
- action: string;
7
- actionParams: Record<string, unknown>;
8
- filters: Record<string, unknown>;
9
- active: boolean;
10
- message: string | null;
11
- alertType: string | null;
12
- createdAt: string;
13
- updatedAt: string;
14
- }
3
+ import { makeRequest } from "./langwatch-api.ts";
4
+ import {
5
+ deletedTriggerSchema,
6
+ type GraphAlertRule,
7
+ type NotificationCadence,
8
+ type ReportRule,
9
+ type TestFireResult,
10
+ type Trigger,
11
+ type TriggerAction,
12
+ type TriggerActionParams,
13
+ type TriggerAlertType,
14
+ type TriggerFirePage,
15
+ type TriggerTemplates,
16
+ testFireResultSchema,
17
+ triggerFirePageSchema,
18
+ triggerSchema,
19
+ } from "./schemas/triggers.ts";
15
20
 
16
- export async function listTriggers(): Promise<TriggerSummary[]> {
17
- return makeRequest("GET", "/api/triggers") as Promise<TriggerSummary[]>;
18
- }
21
+ /**
22
+ * The `/api/v1/triggers` calls, each answering with the shape `schemas/triggers` declares.
23
+ * Responses are read through that schema, not cast, so a deployment that stops sending something
24
+ * a tool renders fails loudly instead of leaving an `undefined` in an agent's message.
25
+ */
19
26
 
20
- export async function getTrigger(id: string): Promise<TriggerSummary> {
21
- return makeRequest("GET", `/api/triggers/${encodeURIComponent(id)}`) as Promise<TriggerSummary>;
22
- }
23
-
24
- export async function createTrigger(data: {
27
+ export interface CreateTriggerInput {
25
28
  name: string;
26
- action: string;
27
- actionParams?: Record<string, unknown>;
29
+ action: TriggerAction;
30
+ /** Omitted sends `{}`, as before `actionParams` was stated per channel. */
31
+ actionParams?: TriggerActionParams;
28
32
  filters?: Record<string, unknown>;
33
+ filterQuery?: string | null;
29
34
  message?: string;
30
- alertType?: string;
31
- }): Promise<TriggerSummary> {
32
- return makeRequest("POST", "/api/triggers", data) as Promise<TriggerSummary>;
35
+ alertType?: TriggerAlertType;
36
+ customGraphId?: string;
37
+ graphAlert?: GraphAlertRule;
38
+ report?: ReportRule;
39
+ templates?: TriggerTemplates;
40
+ notificationCadence?: NotificationCadence;
33
41
  }
34
42
 
35
- export async function updateTrigger(params: {
43
+ /** `actionParams` replaces the delivery configuration as a whole; a credential
44
+ * sent back as `[redacted]` keeps the stored one. The channel cannot change. */
45
+ type UpdateTriggerInput = Partial<
46
+ Omit<CreateTriggerInput, "action" | "customGraphId" | "message" | "alertType">
47
+ > & {
36
48
  id: string;
37
- name?: string;
38
49
  active?: boolean;
39
50
  message?: string | null;
40
- alertType?: string | null;
41
- }): Promise<TriggerSummary> {
42
- const { id, ...data } = params;
43
- return makeRequest("PATCH", `/api/triggers/${encodeURIComponent(id)}`, data) as Promise<TriggerSummary>;
51
+ alertType?: TriggerAlertType | null;
52
+ };
53
+
54
+ export async function listTriggers(): Promise<Trigger[]> {
55
+ return z.array(triggerSchema).parse(await makeRequest("GET", "/api/v1/triggers"));
56
+ }
57
+
58
+ export async function getTrigger(id: string): Promise<Trigger> {
59
+ return triggerSchema.parse(
60
+ await makeRequest("GET", `/api/v1/triggers/${encodeURIComponent(id)}`),
61
+ );
62
+ }
63
+
64
+ export async function createTrigger(input: CreateTriggerInput): Promise<Trigger> {
65
+ return triggerSchema.parse(
66
+ await makeRequest("POST", "/api/v1/triggers", {
67
+ ...input,
68
+ actionParams: input.actionParams ?? {},
69
+ }),
70
+ );
71
+ }
72
+
73
+ export async function updateTrigger({ id, ...data }: UpdateTriggerInput): Promise<Trigger> {
74
+ return triggerSchema.parse(
75
+ await makeRequest("PATCH", `/api/v1/triggers/${encodeURIComponent(id)}`, data),
76
+ );
77
+ }
78
+
79
+ /** Send the automation's message to the destination it is saved with. */
80
+ export async function testFireTrigger(id: string): Promise<TestFireResult> {
81
+ return testFireResultSchema.parse(
82
+ await makeRequest("POST", `/api/v1/triggers/${encodeURIComponent(id)}/test-fire`),
83
+ );
84
+ }
85
+
86
+ /** What the automation has done, newest first. Metadata only. `cursor` reads
87
+ * the page after the one that answered with it as `nextCursor`. */
88
+ export async function listTriggerFires({
89
+ id,
90
+ limit,
91
+ cursor,
92
+ }: {
93
+ id: string;
94
+ limit?: number;
95
+ cursor?: string;
96
+ }): Promise<TriggerFirePage> {
97
+ const query = new URLSearchParams();
98
+ if (limit !== undefined) query.set("limit", String(limit));
99
+ if (cursor) query.set("cursor", cursor);
100
+ const search = query.toString() ? `?${query.toString()}` : "";
101
+ return triggerFirePageSchema.parse(
102
+ await makeRequest("GET", `/api/v1/triggers/${encodeURIComponent(id)}/fires${search}`),
103
+ );
44
104
  }
45
105
 
46
- export async function deleteTrigger(id: string): Promise<{ id: string; deleted: boolean }> {
47
- return makeRequest("DELETE", `/api/triggers/${encodeURIComponent(id)}`) as Promise<{ id: string; deleted: boolean }>;
106
+ export async function deleteTrigger(id: string): Promise<z.infer<typeof deletedTriggerSchema>> {
107
+ return deletedTriggerSchema.parse(
108
+ await makeRequest("DELETE", `/api/v1/triggers/${encodeURIComponent(id)}`),
109
+ );
48
110
  }
@@ -1,4 +1,4 @@
1
- import { makeRequest } from "./langwatch-api.js";
1
+ import { makeRequest } from "./langwatch-api.ts";
2
2
 
3
3
  export interface WorkflowSummary {
4
4
  id: string;
@@ -12,30 +12,30 @@ export interface WorkflowSummary {
12
12
  }
13
13
 
14
14
  export async function listWorkflows(): Promise<WorkflowSummary[]> {
15
- return makeRequest("GET", "/api/workflows") as Promise<WorkflowSummary[]>;
15
+ return makeRequest("GET", "/api/v1/workflows") as Promise<WorkflowSummary[]>;
16
16
  }
17
17
 
18
18
  export async function getWorkflow(id: string): Promise<WorkflowSummary> {
19
19
  return makeRequest(
20
20
  "GET",
21
- `/api/workflows/${encodeURIComponent(id)}`,
21
+ `/api/v1/workflows/${encodeURIComponent(id)}`,
22
22
  ) as Promise<WorkflowSummary>;
23
23
  }
24
24
 
25
25
  export async function runWorkflow(
26
26
  id: string,
27
- input?: Record<string, unknown>
27
+ input?: Record<string, unknown>,
28
28
  ): Promise<Record<string, unknown>> {
29
29
  return makeRequest(
30
30
  "POST",
31
- `/api/workflows/${encodeURIComponent(id)}/run`,
31
+ `/api/v1/workflows/${encodeURIComponent(id)}/run`,
32
32
  input ?? {},
33
33
  ) as Promise<Record<string, unknown>>;
34
34
  }
35
35
 
36
36
  export async function deleteWorkflow(id: string): Promise<{ id: string; archived: boolean }> {
37
- return makeRequest(
38
- "DELETE",
39
- `/api/workflows/${encodeURIComponent(id)}`,
40
- ) as Promise<{ id: string; archived: boolean }>;
37
+ return makeRequest("DELETE", `/api/v1/workflows/${encodeURIComponent(id)}`) as Promise<{
38
+ id: string;
39
+ archived: boolean;
40
+ }>;
41
41
  }
@@ -1,9 +1,17 @@
1
- import type {
2
- HandledErrorFault,
3
- SerializedReason,
4
- } from "@langwatch/handled-error";
5
- import { getConfig, requireApiKey } from "./config.js";
6
- import type { EvaluationSummary } from "./utils/format-evaluations.js";
1
+ import type { HandledErrorFault, SerializedReason } from "@langwatch/handled-error";
2
+
3
+ import packageJson from "../package.json" with { type: "json" };
4
+ import { getConfig, requireApiKey } from "./config.ts";
5
+ import type { EvaluationSummary } from "./utils/format-evaluations.ts";
6
+
7
+ /** Every request names itself so the platform attributes it. */
8
+ // See specs/observability/traffic-attribution.feature.
9
+ export const MCP_IDENTITY_HEADERS: Record<string, string> = {
10
+ "User-Agent": `langwatch-mcp/${packageJson.version}`,
11
+ "X-LangWatch-SDK-Name": "langwatch-mcp",
12
+ "X-LangWatch-SDK-Language": "typescript",
13
+ "X-LangWatch-SDK-Version": packageJson.version,
14
+ };
7
15
 
8
16
  // --- Response types ---
9
17
 
@@ -46,7 +54,7 @@ export interface TraceDetailResponse {
46
54
  error?: Record<string, unknown>;
47
55
  ascii_tree?: string;
48
56
  evaluations?: EvaluationSummary[];
49
- spans?: Array<{
57
+ spans?: {
50
58
  span_id: string;
51
59
  name?: string;
52
60
  type?: string;
@@ -61,7 +69,7 @@ export interface TraceDetailResponse {
61
69
  tokens_estimated?: boolean;
62
70
  cost?: number;
63
71
  };
64
- }>;
72
+ }[];
65
73
  }
66
74
 
67
75
  export interface AnalyticsBucket {
@@ -87,14 +95,10 @@ export interface PromptTag {
87
95
  versionId: string;
88
96
  }
89
97
 
90
- export type PromptFieldList = Array<{ identifier: string; type: string }>;
98
+ export type PromptFieldList = { identifier: string; type: string }[];
91
99
 
92
100
  /**
93
- * A single versioned prompt payload. `GET /api/prompts/:id` returns the
94
- * requested version's data flattened to the top level (merged with the base
95
- * prompt data), and `GET /api/prompts/:id/versions` returns an array of
96
- * entries in this same shape — there is no nested `versions` array on the
97
- * detail response.
101
+ * A single versioned prompt payload.
98
102
  */
99
103
  export interface PromptVersion {
100
104
  versionId?: string;
@@ -103,7 +107,7 @@ export interface PromptVersion {
103
107
  model?: string;
104
108
  /** Legacy single-text prompt body. */
105
109
  prompt?: string;
106
- messages?: Array<{ role: string; content: string }>;
110
+ messages?: { role: string; content: string }[];
107
111
  temperature?: number;
108
112
  maxTokens?: number;
109
113
  responseFormat?: Record<string, unknown> | null;
@@ -134,10 +138,9 @@ export class LangWatchApiError extends Error {
134
138
  readonly docsUrl?: string;
135
139
  readonly fault?: HandledErrorFault;
136
140
  /**
137
- * The per-field failures behind this error, verbatim from the envelope.
138
- * A validation failure carries the offending field and the values it would
139
- * have accepted here — the difference between an agent correcting its own
140
- * request and an agent guessing again.
141
+ * The per-field failures behind this error, verbatim from the envelope. A validation failure
142
+ * carries the offending field and the values it would have accepted here — the difference
143
+ * between an agent correcting its own request and an agent guessing again.
141
144
  */
142
145
  readonly reasons?: SerializedReason[];
143
146
 
@@ -173,56 +176,42 @@ interface ParsedErrorBody {
173
176
  reasons?: SerializedReason[];
174
177
  }
175
178
 
176
- const VALID_FAULTS: readonly HandledErrorFault[] = ["customer", "platform", "provider"];
179
+ const VALID_FAULTS: readonly HandledErrorFault[] = [
180
+ "customer",
181
+ "platform",
182
+ "provider",
183
+ "presumed_platform",
184
+ ];
177
185
 
178
186
  /**
179
- * Parses an error response body as a handled-error envelope. Accepts three
180
- * shapes: the canonical v1 envelope
181
- * (`{ error: { type, code, message, meta?, trace_id } }`), the legacy REST
182
- * shape (`{ error: "<code>", message, tips?, docsUrl?, fault? }`) and the
183
- * serialized tRPC shape (`{ code, message?, tips?, docsUrl?, fault?, ... }`).
184
- * Returns an empty object when the body is not a recognizable error envelope.
187
+ * Parses an error response body as a handled-error envelope.
185
188
  */
186
189
  function parseErrorBody(responseBody: string): ParsedErrorBody {
187
190
  try {
188
191
  const parsed: unknown = JSON.parse(responseBody);
189
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
190
- return {};
191
- }
192
- const envelope = parsed as Record<string, unknown>;
192
+ if (!isRecord(parsed)) return {};
193
+ const envelope = parsed;
193
194
  // The canonical v1 envelope nests everything under `error`. Read the
194
195
  // nested object as the body so one parser serves both generations.
195
- const nested =
196
- typeof envelope.error === "object" &&
197
- envelope.error !== null &&
198
- !Array.isArray(envelope.error)
199
- ? (envelope.error as Record<string, unknown>)
200
- : null;
196
+ const nestedValue = envelope.error;
197
+ const nested = isRecord(nestedValue) ? nestedValue : null;
201
198
  const body = nested ?? envelope;
202
- // Prefer `code` (the domain discriminant) over `error` — the
203
- // packages/api unversioned envelope uses `error` for the HTTP status
204
- // text ("Not Found") while `code` holds the real code.
205
- const code =
206
- typeof body.code === "string"
207
- ? body.code
208
- : typeof body.error === "string"
209
- ? body.error
210
- : undefined;
199
+ // `code` is the domain discriminant. The `error` fallback reads the
200
+ // legacy envelope some non-framework families still send; the framework's
201
+ // own unversioned union envelope, which used `error` for the HTTP status
202
+ // text, is gone (packages/api/adrs/002).
203
+ const code = readErrorCode(body);
211
204
  const message = typeof body.message === "string" ? body.message : undefined;
212
205
  if (code === undefined && message === undefined) {
213
206
  return {};
214
207
  }
215
- const tips =
216
- Array.isArray(body.tips) && body.tips.every((t) => typeof t === "string")
217
- ? (body.tips as string[])
218
- : undefined;
208
+ const tips = readStringArray(body.tips);
219
209
  const docsUrl = typeof body.docsUrl === "string" ? body.docsUrl : undefined;
220
210
  const fault = VALID_FAULTS.includes(body.fault as HandledErrorFault)
221
211
  ? (body.fault as HandledErrorFault)
222
212
  : undefined;
223
213
  const reasons =
224
- Array.isArray(body.reasons) &&
225
- body.reasons.every((r) => !!r && typeof r === "object")
214
+ Array.isArray(body.reasons) && body.reasons.every((r) => !!r && typeof r === "object")
226
215
  ? (body.reasons as SerializedReason[])
227
216
  : undefined;
228
217
  return { code, message, tips, docsUrl, fault, reasons };
@@ -231,14 +220,29 @@ function parseErrorBody(responseBody: string): ParsedErrorBody {
231
220
  }
232
221
  }
233
222
 
223
+ function isRecord(value: unknown): value is Record<string, unknown> {
224
+ return typeof value === "object" && value !== null && !Array.isArray(value);
225
+ }
226
+
227
+ function readErrorCode(body: Record<string, unknown>): string | undefined {
228
+ if (typeof body.code === "string") return body.code;
229
+ if (typeof body.error === "string") return body.error;
230
+ return undefined;
231
+ }
232
+
233
+ function readStringArray(value: unknown): string[] | undefined {
234
+ if (!Array.isArray(value) || !value.every(isString)) return undefined;
235
+ return value;
236
+ }
237
+
238
+ function isString(value: unknown): value is string {
239
+ return typeof value === "string";
240
+ }
241
+
234
242
  /**
235
- * The human line for one per-field failure: the field, what it would have
236
- * accepted, and what it got. Returns null when a reason names no field, so a
237
- * generic nested error adds no noise to the message.
238
- *
239
- * This exists because the MCP transport's only channel to the caller is the
240
- * error MESSAGE — an agent never sees the `reasons` array itself, so a
241
- * rejection whose remedy lives only there is unfollowable.
243
+ * The human line for one per-field failure: the field, what it would have accepted, and what it
244
+ * got. Returns null when a reason names no field, so a generic nested error adds no noise to
245
+ * the message.
242
246
  */
243
247
  function describeReason(reason: SerializedReason): string | null {
244
248
  const meta = reason.meta;
@@ -258,22 +262,19 @@ function describeReason(reason: SerializedReason): string | null {
258
262
  }
259
263
 
260
264
  /**
261
- * Sends an HTTP request to the LangWatch API.
262
- *
263
- * Builds the full URL from the configured endpoint, adds authentication,
264
- * and handles JSON serialization/deserialization.
265
- *
266
- * @throws LangWatchApiError with status code and response body when the
267
- * response is not OK.
265
+ * Sends an HTTP request to the LangWatch API. Builds the full URL from the configured endpoint,
266
+ * adds authentication, and handles JSON serialization/deserialization. @throws
267
+ * LangWatchApiError with status code and response body when the response is not OK.
268
268
  */
269
269
  export async function makeRequest(
270
270
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
271
271
  path: string,
272
- body?: unknown
272
+ body?: unknown,
273
273
  ): Promise<unknown> {
274
274
  const config = getConfig();
275
275
  const url = config.endpoint + path;
276
276
  const headers: Record<string, string> = {
277
+ ...MCP_IDENTITY_HEADERS,
277
278
  "X-Auth-Token": requireApiKey(),
278
279
  };
279
280
  if (config.projectId) {
@@ -293,9 +294,7 @@ export async function makeRequest(
293
294
  if (!response.ok) {
294
295
  const responseBody = await response.text();
295
296
  const parsed = parseErrorBody(responseBody);
296
- const lines = [
297
- `LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`,
298
- ];
297
+ const lines = [`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`];
299
298
  const reasonLines = (parsed.reasons ?? [])
300
299
  .map(describeReason)
301
300
  .filter((line): line is string => line !== null);
@@ -308,18 +307,13 @@ export async function makeRequest(
308
307
  if (parsed.docsUrl) {
309
308
  lines.push(`Docs: ${parsed.docsUrl}`);
310
309
  }
311
- throw new LangWatchApiError(
312
- lines.join("\n"),
313
- response.status,
314
- responseBody,
315
- {
316
- code: parsed.code,
317
- tips: parsed.tips,
318
- docsUrl: parsed.docsUrl,
319
- fault: parsed.fault,
320
- reasons: parsed.reasons,
321
- },
322
- );
310
+ throw new LangWatchApiError(lines.join("\n"), response.status, responseBody, {
311
+ code: parsed.code,
312
+ tips: parsed.tips,
313
+ docsUrl: parsed.docsUrl,
314
+ fault: parsed.fault,
315
+ reasons: parsed.reasons,
316
+ });
323
317
  }
324
318
 
325
319
  if (response.status === 204 || response.headers?.get("content-length") === "0") {
@@ -329,16 +323,19 @@ export async function makeRequest(
329
323
  }
330
324
 
331
325
  /**
332
- * Searches traces with optional filters and pagination.
333
- *
334
- * Paging is by `scrollId` only: pass the one the previous response returned,
335
- * and stop when a response carries none. `pageOffset` used to be accepted here
336
- * but was never read by the server, so an offset walk silently re-served the
337
- * first page; it is rejected at the boundary now (#6808).
326
+ * Searches traces with optional filters and pagination. Paging is by `scrollId` only: pass the
327
+ * one the previous response returned, and stop when a response carries none.
338
328
  */
339
329
  export async function searchTraces(params: {
340
330
  query?: string;
331
+ /** Exact trace ids: a primary-key seek on trace_summaries, not a scan (ADR-164). */
332
+ traceIds?: string[];
341
333
  filters?: Record<string, string[]>;
334
+ /**
335
+ * The Trace Explorer's query language, as one string. Combined server-side
336
+ * with `filters`, `query` and `traceIds` rather than replacing any of them.
337
+ */
338
+ filter?: string;
342
339
  startDate: number;
343
340
  endDate: number;
344
341
  pageSize?: number;
@@ -346,7 +343,7 @@ export async function searchTraces(params: {
346
343
  format?: "digest" | "json";
347
344
  }): Promise<SearchTracesResponse> {
348
345
  const { format = "digest", ...rest } = params;
349
- return makeRequest("POST", "/api/traces/search", {
346
+ return makeRequest("POST", "/api/v1/traces/search", {
350
347
  ...rest,
351
348
  format,
352
349
  }) as Promise<SearchTracesResponse>;
@@ -355,22 +352,22 @@ export async function searchTraces(params: {
355
352
  /** Retrieves a single trace by its ID. */
356
353
  export async function getTraceById(
357
354
  traceId: string,
358
- format: "digest" | "json" = "digest"
355
+ format: "digest" | "json" = "digest",
359
356
  ): Promise<TraceDetailResponse> {
360
357
  return makeRequest(
361
358
  "GET",
362
- `/api/traces/${encodeURIComponent(traceId)}?format=${format}`
359
+ `/api/v1/traces/${encodeURIComponent(traceId)}?format=${format}`,
363
360
  ) as Promise<TraceDetailResponse>;
364
361
  }
365
362
 
366
363
  /** Fetches analytics timeseries data for the given metrics and date range. */
367
364
  export async function getAnalyticsTimeseries(params: {
368
- series: Array<{
365
+ series: {
369
366
  metric: string;
370
367
  aggregation: string;
371
368
  key?: string;
372
369
  subkey?: string;
373
- }>;
370
+ }[];
374
371
  startDate: number;
375
372
  endDate: number;
376
373
  timeZone?: string;
@@ -380,20 +377,20 @@ export async function getAnalyticsTimeseries(params: {
380
377
  }): Promise<AnalyticsTimeseriesResponse> {
381
378
  return makeRequest(
382
379
  "POST",
383
- "/api/analytics/timeseries",
384
- params
380
+ "/api/v1/analytics/timeseries",
381
+ params,
385
382
  ) as Promise<AnalyticsTimeseriesResponse>;
386
383
  }
387
384
 
388
385
  /** Lists all prompts in the project. */
389
386
  export async function listPrompts(): Promise<PromptSummary[]> {
390
- return makeRequest("GET", "/api/prompts") as Promise<PromptSummary[]>;
387
+ return makeRequest("GET", "/api/v1/prompts") as Promise<PromptSummary[]>;
391
388
  }
392
389
 
393
390
  /** Retrieves a single prompt by ID or handle. */
394
391
  export async function getPrompt(
395
392
  idOrHandle: string,
396
- options?: { version?: number; tag?: string }
393
+ options?: { version?: number; tag?: string },
397
394
  ): Promise<PromptDetailResponse> {
398
395
  const params = new URLSearchParams();
399
396
  if (options?.version != null) params.set("version", String(options.version));
@@ -401,48 +398,42 @@ export async function getPrompt(
401
398
  const query = params.toString() ? `?${params}` : "";
402
399
  return makeRequest(
403
400
  "GET",
404
- `/api/prompts/${encodeURIComponent(idOrHandle)}${query}`
401
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}${query}`,
405
402
  ) as Promise<PromptDetailResponse>;
406
403
  }
407
404
 
408
405
  /** Lists all versions of a prompt (versioned data only). */
409
- export async function getPromptVersions(
410
- idOrHandle: string
411
- ): Promise<PromptVersion[]> {
406
+ export async function getPromptVersions(idOrHandle: string): Promise<PromptVersion[]> {
412
407
  return makeRequest(
413
408
  "GET",
414
- `/api/prompts/${encodeURIComponent(idOrHandle)}/versions`
409
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}/versions`,
415
410
  ) as Promise<PromptVersion[]>;
416
411
  }
417
412
 
418
413
  /** Creates a new prompt. */
419
414
  export async function createPrompt(data: {
420
415
  handle: string;
421
- messages: Array<{ role: string; content: string }>;
416
+ messages: { role: string; content: string }[];
422
417
  model: string;
423
418
  tags?: string[];
424
419
  }): Promise<PromptMutationResponse> {
425
- return makeRequest(
426
- "POST",
427
- "/api/prompts",
428
- data
429
- ) as Promise<PromptMutationResponse>;
420
+ return makeRequest("POST", "/api/v1/prompts", data) as Promise<PromptMutationResponse>;
430
421
  }
431
422
 
432
423
  /** Updates an existing prompt by ID or handle. */
433
424
  export async function updatePrompt(
434
425
  idOrHandle: string,
435
426
  data: {
436
- messages?: Array<{ role: string; content: string }>;
427
+ messages?: { role: string; content: string }[];
437
428
  model?: string;
438
429
  commitMessage: string;
439
430
  tags?: string[];
440
- }
431
+ },
441
432
  ): Promise<PromptMutationResponse> {
442
433
  return makeRequest(
443
434
  "PUT",
444
- `/api/prompts/${encodeURIComponent(idOrHandle)}`,
445
- data
435
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}`,
436
+ data,
446
437
  ) as Promise<PromptMutationResponse>;
447
438
  }
448
439
 
@@ -458,19 +449,19 @@ export async function assignPromptTag({
458
449
  }): Promise<unknown> {
459
450
  return makeRequest(
460
451
  "PUT",
461
- `/api/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
462
- { versionId }
452
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
453
+ { versionId },
463
454
  );
464
455
  }
465
456
 
466
457
  /** Lists all prompt tag definitions for the organization. */
467
458
  export async function listPromptTags(): Promise<unknown> {
468
- return makeRequest("GET", "/api/prompts/tags");
459
+ return makeRequest("GET", "/api/v1/prompts/tags");
469
460
  }
470
461
 
471
462
  /** Creates a custom prompt tag definition. */
472
463
  export async function createPromptTag(name: string): Promise<unknown> {
473
- return makeRequest("POST", "/api/prompts/tags", { name });
464
+ return makeRequest("POST", "/api/v1/prompts/tags", { name });
474
465
  }
475
466
 
476
467
  /** Renames an existing prompt tag. */
@@ -481,17 +472,10 @@ export async function renamePromptTag({
481
472
  tag: string;
482
473
  name: string;
483
474
  }): Promise<unknown> {
484
- return makeRequest(
485
- "PUT",
486
- `/api/prompts/tags/${encodeURIComponent(tag)}`,
487
- { name }
488
- );
475
+ return makeRequest("PUT", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`, { name });
489
476
  }
490
477
 
491
478
  /** Deletes a prompt tag and all its assignments. */
492
479
  export async function deletePromptTag(tag: string): Promise<unknown> {
493
- return makeRequest(
494
- "DELETE",
495
- `/api/prompts/tags/${encodeURIComponent(tag)}`
496
- );
480
+ return makeRequest("DELETE", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`);
497
481
  }