@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,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 {
@@ -82,25 +90,44 @@ export interface PromptSummary {
82
90
  version?: number;
83
91
  }
84
92
 
93
+ export interface PromptTag {
94
+ name: string;
95
+ versionId: string;
96
+ }
97
+
98
+ export type PromptFieldList = { identifier: string; type: string }[];
99
+
100
+ /**
101
+ * A single versioned prompt payload.
102
+ */
85
103
  export interface PromptVersion {
104
+ versionId?: string;
86
105
  version?: number;
87
- commitMessage?: string;
106
+ commitMessage?: string | null;
88
107
  model?: string;
89
- messages?: Array<{ role: string; content: string }>;
108
+ /** Legacy single-text prompt body. */
109
+ prompt?: string;
110
+ messages?: { role: string; content: string }[];
111
+ temperature?: number;
112
+ maxTokens?: number;
113
+ responseFormat?: Record<string, unknown> | null;
114
+ /** Runtime parameters: an object map of name -> JSON value, not an array. */
115
+ parameters?: Record<string, unknown>;
116
+ inputs?: PromptFieldList;
117
+ outputs?: PromptFieldList;
118
+ /** All tags on the prompt; each names the version it currently points to. */
119
+ tags?: PromptTag[];
90
120
  }
91
121
 
92
- export interface PromptDetailResponse extends PromptSummary {
93
- versions?: PromptVersion[];
94
- model?: string;
95
- messages?: Array<{ role: string; content: string }>;
96
- prompt?: Array<{ role: string; content: string }>;
97
- }
122
+ export interface PromptDetailResponse extends PromptSummary, PromptVersion {}
98
123
 
99
124
  export interface PromptMutationResponse {
100
125
  id?: string;
101
126
  handle?: string;
102
127
  name?: string;
103
128
  latestVersionNumber?: number;
129
+ versionId?: string;
130
+ tags?: string[];
104
131
  }
105
132
 
106
133
  // --- HTTP client ---
@@ -111,10 +138,9 @@ export class LangWatchApiError extends Error {
111
138
  readonly docsUrl?: string;
112
139
  readonly fault?: HandledErrorFault;
113
140
  /**
114
- * The per-field failures behind this error, verbatim from the envelope.
115
- * A validation failure carries the offending field and the values it would
116
- * have accepted here — the difference between an agent correcting its own
117
- * 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.
118
144
  */
119
145
  readonly reasons?: SerializedReason[];
120
146
 
@@ -150,45 +176,42 @@ interface ParsedErrorBody {
150
176
  reasons?: SerializedReason[];
151
177
  }
152
178
 
153
- const VALID_FAULTS: readonly HandledErrorFault[] = ["customer", "platform", "provider"];
179
+ const VALID_FAULTS: readonly HandledErrorFault[] = [
180
+ "customer",
181
+ "platform",
182
+ "provider",
183
+ "presumed_platform",
184
+ ];
154
185
 
155
186
  /**
156
- * Parses an error response body as a handled-error envelope. Accepts both the
157
- * REST shape (`{ error: "<code>", message, tips?, docsUrl?, fault? }`) and the
158
- * serialized tRPC shape (`{ code, message?, tips?, docsUrl?, fault?, ... }`).
159
- * Returns an empty object when the body is not a recognizable error envelope.
187
+ * Parses an error response body as a handled-error envelope.
160
188
  */
161
189
  function parseErrorBody(responseBody: string): ParsedErrorBody {
162
190
  try {
163
191
  const parsed: unknown = JSON.parse(responseBody);
164
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
165
- return {};
166
- }
167
- const body = parsed as Record<string, unknown>;
168
- // Prefer `code` (the domain discriminant) over `error` — the
169
- // packages/api unversioned envelope uses `error` for the HTTP status
170
- // text ("Not Found") while `code` holds the real code.
171
- const code =
172
- typeof body.code === "string"
173
- ? body.code
174
- : typeof body.error === "string"
175
- ? body.error
176
- : undefined;
192
+ if (!isRecord(parsed)) return {};
193
+ const envelope = parsed;
194
+ // The canonical v1 envelope nests everything under `error`. Read the
195
+ // nested object as the body so one parser serves both generations.
196
+ const nestedValue = envelope.error;
197
+ const nested = isRecord(nestedValue) ? nestedValue : null;
198
+ const body = nested ?? envelope;
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);
177
204
  const message = typeof body.message === "string" ? body.message : undefined;
178
205
  if (code === undefined && message === undefined) {
179
206
  return {};
180
207
  }
181
- const tips =
182
- Array.isArray(body.tips) && body.tips.every((t) => typeof t === "string")
183
- ? (body.tips as string[])
184
- : undefined;
208
+ const tips = readStringArray(body.tips);
185
209
  const docsUrl = typeof body.docsUrl === "string" ? body.docsUrl : undefined;
186
210
  const fault = VALID_FAULTS.includes(body.fault as HandledErrorFault)
187
211
  ? (body.fault as HandledErrorFault)
188
212
  : undefined;
189
213
  const reasons =
190
- Array.isArray(body.reasons) &&
191
- body.reasons.every((r) => !!r && typeof r === "object")
214
+ Array.isArray(body.reasons) && body.reasons.every((r) => !!r && typeof r === "object")
192
215
  ? (body.reasons as SerializedReason[])
193
216
  : undefined;
194
217
  return { code, message, tips, docsUrl, fault, reasons };
@@ -197,14 +220,29 @@ function parseErrorBody(responseBody: string): ParsedErrorBody {
197
220
  }
198
221
  }
199
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
+
200
242
  /**
201
- * The human line for one per-field failure: the field, what it would have
202
- * accepted, and what it got. Returns null when a reason names no field, so a
203
- * generic nested error adds no noise to the message.
204
- *
205
- * This exists because the MCP transport's only channel to the caller is the
206
- * error MESSAGE — an agent never sees the `reasons` array itself, so a
207
- * 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.
208
246
  */
209
247
  function describeReason(reason: SerializedReason): string | null {
210
248
  const meta = reason.meta;
@@ -224,22 +262,19 @@ function describeReason(reason: SerializedReason): string | null {
224
262
  }
225
263
 
226
264
  /**
227
- * Sends an HTTP request to the LangWatch API.
228
- *
229
- * Builds the full URL from the configured endpoint, adds authentication,
230
- * and handles JSON serialization/deserialization.
231
- *
232
- * @throws LangWatchApiError with status code and response body when the
233
- * 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.
234
268
  */
235
269
  export async function makeRequest(
236
270
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
237
271
  path: string,
238
- body?: unknown
272
+ body?: unknown,
239
273
  ): Promise<unknown> {
240
274
  const config = getConfig();
241
275
  const url = config.endpoint + path;
242
276
  const headers: Record<string, string> = {
277
+ ...MCP_IDENTITY_HEADERS,
243
278
  "X-Auth-Token": requireApiKey(),
244
279
  };
245
280
  if (config.projectId) {
@@ -259,9 +294,7 @@ export async function makeRequest(
259
294
  if (!response.ok) {
260
295
  const responseBody = await response.text();
261
296
  const parsed = parseErrorBody(responseBody);
262
- const lines = [
263
- `LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`,
264
- ];
297
+ const lines = [`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`];
265
298
  const reasonLines = (parsed.reasons ?? [])
266
299
  .map(describeReason)
267
300
  .filter((line): line is string => line !== null);
@@ -274,18 +307,13 @@ export async function makeRequest(
274
307
  if (parsed.docsUrl) {
275
308
  lines.push(`Docs: ${parsed.docsUrl}`);
276
309
  }
277
- throw new LangWatchApiError(
278
- lines.join("\n"),
279
- response.status,
280
- responseBody,
281
- {
282
- code: parsed.code,
283
- tips: parsed.tips,
284
- docsUrl: parsed.docsUrl,
285
- fault: parsed.fault,
286
- reasons: parsed.reasons,
287
- },
288
- );
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
+ });
289
317
  }
290
318
 
291
319
  if (response.status === 204 || response.headers?.get("content-length") === "0") {
@@ -294,19 +322,28 @@ export async function makeRequest(
294
322
  return response.json();
295
323
  }
296
324
 
297
- /** Searches traces with optional filters and pagination. */
325
+ /**
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.
328
+ */
298
329
  export async function searchTraces(params: {
299
330
  query?: string;
331
+ /** Exact trace ids: a primary-key seek on trace_summaries, not a scan (ADR-164). */
332
+ traceIds?: string[];
300
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;
301
339
  startDate: number;
302
340
  endDate: number;
303
341
  pageSize?: number;
304
- pageOffset?: number;
305
342
  scrollId?: string;
306
343
  format?: "digest" | "json";
307
344
  }): Promise<SearchTracesResponse> {
308
345
  const { format = "digest", ...rest } = params;
309
- return makeRequest("POST", "/api/traces/search", {
346
+ return makeRequest("POST", "/api/v1/traces/search", {
310
347
  ...rest,
311
348
  format,
312
349
  }) as Promise<SearchTracesResponse>;
@@ -315,22 +352,22 @@ export async function searchTraces(params: {
315
352
  /** Retrieves a single trace by its ID. */
316
353
  export async function getTraceById(
317
354
  traceId: string,
318
- format: "digest" | "json" = "digest"
355
+ format: "digest" | "json" = "digest",
319
356
  ): Promise<TraceDetailResponse> {
320
357
  return makeRequest(
321
358
  "GET",
322
- `/api/traces/${encodeURIComponent(traceId)}?format=${format}`
359
+ `/api/v1/traces/${encodeURIComponent(traceId)}?format=${format}`,
323
360
  ) as Promise<TraceDetailResponse>;
324
361
  }
325
362
 
326
363
  /** Fetches analytics timeseries data for the given metrics and date range. */
327
364
  export async function getAnalyticsTimeseries(params: {
328
- series: Array<{
365
+ series: {
329
366
  metric: string;
330
367
  aggregation: string;
331
368
  key?: string;
332
369
  subkey?: string;
333
- }>;
370
+ }[];
334
371
  startDate: number;
335
372
  endDate: number;
336
373
  timeZone?: string;
@@ -340,20 +377,20 @@ export async function getAnalyticsTimeseries(params: {
340
377
  }): Promise<AnalyticsTimeseriesResponse> {
341
378
  return makeRequest(
342
379
  "POST",
343
- "/api/analytics/timeseries",
344
- params
380
+ "/api/v1/analytics/timeseries",
381
+ params,
345
382
  ) as Promise<AnalyticsTimeseriesResponse>;
346
383
  }
347
384
 
348
385
  /** Lists all prompts in the project. */
349
386
  export async function listPrompts(): Promise<PromptSummary[]> {
350
- return makeRequest("GET", "/api/prompts") as Promise<PromptSummary[]>;
387
+ return makeRequest("GET", "/api/v1/prompts") as Promise<PromptSummary[]>;
351
388
  }
352
389
 
353
390
  /** Retrieves a single prompt by ID or handle. */
354
391
  export async function getPrompt(
355
392
  idOrHandle: string,
356
- options?: { version?: number; tag?: string }
393
+ options?: { version?: number; tag?: string },
357
394
  ): Promise<PromptDetailResponse> {
358
395
  const params = new URLSearchParams();
359
396
  if (options?.version != null) params.set("version", String(options.version));
@@ -361,38 +398,42 @@ export async function getPrompt(
361
398
  const query = params.toString() ? `?${params}` : "";
362
399
  return makeRequest(
363
400
  "GET",
364
- `/api/prompts/${encodeURIComponent(idOrHandle)}${query}`
401
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}${query}`,
365
402
  ) as Promise<PromptDetailResponse>;
366
403
  }
367
404
 
405
+ /** Lists all versions of a prompt (versioned data only). */
406
+ export async function getPromptVersions(idOrHandle: string): Promise<PromptVersion[]> {
407
+ return makeRequest(
408
+ "GET",
409
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}/versions`,
410
+ ) as Promise<PromptVersion[]>;
411
+ }
412
+
368
413
  /** Creates a new prompt. */
369
414
  export async function createPrompt(data: {
370
415
  handle: string;
371
- messages: Array<{ role: string; content: string }>;
416
+ messages: { role: string; content: string }[];
372
417
  model: string;
373
418
  tags?: string[];
374
419
  }): Promise<PromptMutationResponse> {
375
- return makeRequest(
376
- "POST",
377
- "/api/prompts",
378
- data
379
- ) as Promise<PromptMutationResponse>;
420
+ return makeRequest("POST", "/api/v1/prompts", data) as Promise<PromptMutationResponse>;
380
421
  }
381
422
 
382
423
  /** Updates an existing prompt by ID or handle. */
383
424
  export async function updatePrompt(
384
425
  idOrHandle: string,
385
426
  data: {
386
- messages?: Array<{ role: string; content: string }>;
427
+ messages?: { role: string; content: string }[];
387
428
  model?: string;
388
429
  commitMessage: string;
389
430
  tags?: string[];
390
- }
431
+ },
391
432
  ): Promise<PromptMutationResponse> {
392
433
  return makeRequest(
393
434
  "PUT",
394
- `/api/prompts/${encodeURIComponent(idOrHandle)}`,
395
- data
435
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}`,
436
+ data,
396
437
  ) as Promise<PromptMutationResponse>;
397
438
  }
398
439
 
@@ -408,19 +449,19 @@ export async function assignPromptTag({
408
449
  }): Promise<unknown> {
409
450
  return makeRequest(
410
451
  "PUT",
411
- `/api/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
412
- { versionId }
452
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
453
+ { versionId },
413
454
  );
414
455
  }
415
456
 
416
457
  /** Lists all prompt tag definitions for the organization. */
417
458
  export async function listPromptTags(): Promise<unknown> {
418
- return makeRequest("GET", "/api/prompts/tags");
459
+ return makeRequest("GET", "/api/v1/prompts/tags");
419
460
  }
420
461
 
421
462
  /** Creates a custom prompt tag definition. */
422
463
  export async function createPromptTag(name: string): Promise<unknown> {
423
- return makeRequest("POST", "/api/prompts/tags", { name });
464
+ return makeRequest("POST", "/api/v1/prompts/tags", { name });
424
465
  }
425
466
 
426
467
  /** Renames an existing prompt tag. */
@@ -431,17 +472,10 @@ export async function renamePromptTag({
431
472
  tag: string;
432
473
  name: string;
433
474
  }): Promise<unknown> {
434
- return makeRequest(
435
- "PUT",
436
- `/api/prompts/tags/${encodeURIComponent(tag)}`,
437
- { name }
438
- );
475
+ return makeRequest("PUT", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`, { name });
439
476
  }
440
477
 
441
478
  /** Deletes a prompt tag and all its assignments. */
442
479
  export async function deletePromptTag(tag: string): Promise<unknown> {
443
- return makeRequest(
444
- "DELETE",
445
- `/api/prompts/tags/${encodeURIComponent(tag)}`
446
- );
480
+ return makeRequest("DELETE", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`);
447
481
  }
@@ -3,7 +3,7 @@ import { request as httpRequest, type RequestOptions } from "node:http";
3
3
  import { request as httpsRequest } from "node:https";
4
4
  import { isIP } from "node:net";
5
5
 
6
- import { classify } from "@langwatch/ssrf";
6
+ import { classify } from "@langwatch/egress/ssrf";
7
7
 
8
8
  const MAX_REDIRECTS = 5;
9
9
  const MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
@@ -20,7 +20,10 @@ const SENSITIVE_REDIRECT_HEADERS = new Set([
20
20
  "x-access-token",
21
21
  ]);
22
22
 
23
- type DnsResolver = (hostname: string, options: { all: true; verbatim: true }) => Promise<ResolvedAddress[]>;
23
+ type DnsResolver = (
24
+ hostname: string,
25
+ options: { all: true; verbatim: true },
26
+ ) => Promise<ResolvedAddress[]>;
24
27
 
25
28
  interface ResolvedAddress {
26
29
  address: string;
@@ -34,7 +37,9 @@ export interface PublicDestination {
34
37
  }
35
38
 
36
39
  function unsafeDestinationError(): Error {
37
- return new Error("HTTP agent destinations must resolve only to globally routable public addresses");
40
+ return new Error(
41
+ "HTTP agent destinations must resolve only to globally routable public addresses",
42
+ );
38
43
  }
39
44
 
40
45
  function hostnameWithoutBrackets(hostname: string): string {
@@ -66,21 +71,21 @@ async function withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T
66
71
 
67
72
  export function headersForRedirect(
68
73
  headers: Record<string, string> | undefined,
69
- crossOrigin: boolean
74
+ crossOrigin: boolean,
70
75
  ): Record<string, string> | undefined {
71
76
  if (!headers || !crossOrigin) {
72
77
  return headers;
73
78
  }
74
79
 
75
80
  const safeHeaders = Object.fromEntries(
76
- Object.entries(headers).filter(([name]) => !SENSITIVE_REDIRECT_HEADERS.has(name.toLowerCase()))
81
+ Object.entries(headers).filter(([name]) => !SENSITIVE_REDIRECT_HEADERS.has(name.toLowerCase())),
77
82
  );
78
83
  return Object.keys(safeHeaders).length > 0 ? safeHeaders : undefined;
79
84
  }
80
85
 
81
86
  export async function resolvePublicDestination(
82
87
  input: string,
83
- resolver: DnsResolver = dnsLookup
88
+ resolver: DnsResolver = dnsLookup,
84
89
  ): Promise<PublicDestination> {
85
90
  let url: URL;
86
91
  try {
@@ -89,7 +94,11 @@ export async function resolvePublicDestination(
89
94
  throw new Error("HTTP agent URL is invalid");
90
95
  }
91
96
 
92
- if ((url.protocol !== "http:" && url.protocol !== "https:") || url.username !== "" || url.password !== "") {
97
+ if (
98
+ (url.protocol !== "http:" && url.protocol !== "https:") ||
99
+ url.username !== "" ||
100
+ url.password !== ""
101
+ ) {
93
102
  throw unsafeDestinationError();
94
103
  }
95
104
 
@@ -104,7 +113,7 @@ export async function resolvePublicDestination(
104
113
  try {
105
114
  addresses = await withTimeout(
106
115
  resolver(hostname, { all: true, verbatim: true }),
107
- REQUEST_TIMEOUT_MS
116
+ REQUEST_TIMEOUT_MS,
108
117
  );
109
118
  } catch {
110
119
  throw new Error("HTTP agent destination could not be resolved");
@@ -135,7 +144,7 @@ interface PublicJsonRequestOptions {
135
144
 
136
145
  function requestBody(
137
146
  destination: PublicDestination,
138
- options: PublicJsonRequestOptions
147
+ options: PublicJsonRequestOptions,
139
148
  ): Promise<{ body: string; location?: string; statusCode: number }> {
140
149
  return new Promise((resolve, reject) => {
141
150
  const hostname = hostnameWithoutBrackets(destination.url.hostname);
@@ -198,7 +207,7 @@ function requestBody(
198
207
  export async function requestPublicJson(
199
208
  input: string,
200
209
  options: PublicJsonRequestOptions = {},
201
- redirectCount = 0
210
+ redirectCount = 0,
202
211
  ): Promise<Record<string, unknown>> {
203
212
  const destination = await resolvePublicDestination(input);
204
213
  const response = await requestBody(destination, options);
@@ -210,7 +219,7 @@ export async function requestPublicJson(
210
219
  const redirectUrl = new URL(response.location, destination.url);
211
220
  const redirectHeaders = headersForRedirect(
212
221
  options.headers,
213
- redirectUrl.origin !== destination.url.origin
222
+ redirectUrl.origin !== destination.url.origin,
214
223
  );
215
224
  const preserveBody = response.statusCode === 307 || response.statusCode === 308;
216
225
  return requestPublicJson(
@@ -223,7 +232,7 @@ export async function requestPublicJson(
223
232
  headers: redirectHeaders,
224
233
  method: "GET",
225
234
  },
226
- redirectCount + 1
235
+ redirectCount + 1,
227
236
  );
228
237
  }
229
238
 
@@ -124,17 +124,7 @@ export const analyticsMetrics: MetricInfo[] = [
124
124
  category: "events",
125
125
  name: "event_score",
126
126
  label: "Event Score",
127
- allowedAggregations: [
128
- "terms",
129
- "avg",
130
- "sum",
131
- "min",
132
- "max",
133
- "median",
134
- "p99",
135
- "p95",
136
- "p90",
137
- ],
127
+ allowedAggregations: ["terms", "avg", "sum", "min", "max", "median", "p99", "p95", "p90"],
138
128
  description: "Numeric score from events (requires event_type key and metrics key)",
139
129
  },
140
130
  {
@@ -142,8 +132,7 @@ export const analyticsMetrics: MetricInfo[] = [
142
132
  name: "event_details",
143
133
  label: "Event Details",
144
134
  allowedAggregations: ["cardinality"],
145
- description:
146
- "Event detail key/value distribution (requires event_type key and details key)",
135
+ description: "Event detail key/value distribution (requires event_type key and details key)",
147
136
  },
148
137
  // evaluations
149
138
  {
@@ -158,8 +147,7 @@ export const analyticsMetrics: MetricInfo[] = [
158
147
  name: "evaluation_pass_rate",
159
148
  label: "Evaluation Pass Rate",
160
149
  allowedAggregations: ["avg", "sum", "min", "max", "median", "p99", "p95", "p90"],
161
- description:
162
- "Percentage of traces passing evaluation (requires evaluator_id key)",
150
+ description: "Percentage of traces passing evaluation (requires evaluator_id key)",
163
151
  },
164
152
  {
165
153
  category: "evaluations",
@@ -16,6 +16,7 @@ export const DATASET_COLUMN_TYPES = [
16
16
  "annotations",
17
17
  "evaluations",
18
18
  "image",
19
+ "file",
19
20
  ] as const;
20
21
 
21
22
  /**
@@ -34,10 +35,8 @@ export const datasetColumnDefinitionSchema = z.object({
34
35
  });
35
36
 
36
37
  /**
37
- * Zod schema for the platform_create_dataset MCP tool parameters.
38
- *
39
- * Extracted so it can be shared between the MCP tool registration
40
- * (create-mcp-server.ts) and unit tests.
38
+ * Zod schema for the platform_create_dataset MCP tool parameters,
39
+ * extracted so it's shared between create-mcp-server.ts and unit tests.
41
40
  */
42
41
  export const createDatasetSchema = z.object({
43
42
  name: z.string().min(1).describe("Dataset name"),