@langwatch/mcp-server 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/.gitignore +7 -0
  2. package/.npmignore +41 -0
  3. package/CHANGELOG.md +218 -201
  4. package/CONTRIBUTING.md +10 -0
  5. package/README.md +70 -68
  6. package/dist/add-dashboard-widget-55UI6H22.js +44 -0
  7. package/dist/add-dashboard-widget-MJHIC3CC.js +45 -0
  8. package/dist/{archive-project-W3IKI7UL.js → archive-project-K5UD7A6X.js} +4 -4
  9. package/dist/archive-project-L4PAKT34.js +19 -0
  10. package/dist/{archive-run-plan-474OKHHU.js → archive-run-plan-5HSQG2HX.js} +4 -4
  11. package/dist/archive-run-plan-AOKNYQIO.js +15 -0
  12. package/dist/archive-scenario-2CWJW2VD.js +19 -0
  13. package/dist/{archive-scenario-V5UNYK26.js → archive-scenario-5IJQESHH.js} +4 -4
  14. package/dist/{archive-test-suite-O7FLDMXK.js → archive-test-suite-OPB7NFI7.js} +4 -4
  15. package/dist/archive-test-suite-ZC3TN6VH.js +15 -0
  16. package/dist/assign-prompt-tag-6DDE6ZZ5.js +23 -0
  17. package/dist/{assign-prompt-tag-Q46WRB6P.js → assign-prompt-tag-D7O23MJM.js} +8 -4
  18. package/dist/chunk-3YLN3ATJ.js +241 -0
  19. package/dist/{chunk-EYXMLE5X.js → chunk-4RX3G62A.js} +56 -47
  20. package/dist/{chunk-UF6XIGYR.js → chunk-6YZUOD34.js} +2 -5
  21. package/dist/{chunk-WVI5CJ6S.js → chunk-7AQLPVFL.js} +2 -2
  22. package/dist/chunk-7CZQDZ2K.js +319 -0
  23. package/dist/{chunk-RVAE2MEA.js → chunk-7GETGE6B.js} +7 -7
  24. package/dist/{chunk-OJLYYJWI.js → chunk-AASW2TO2.js} +7 -10
  25. package/dist/{chunk-QAMP3CGR.js → chunk-B4RFWIUP.js} +4 -4
  26. package/dist/{chunk-ZXKLPC2E.js → chunk-BIIKE3EI.js} +1 -1
  27. package/dist/{chunk-G4ZAZTZW.js → chunk-D2HS73VI.js} +7 -10
  28. package/dist/{chunk-37SMPMQS.js → chunk-DMM3JQ42.js} +7 -2
  29. package/dist/{chunk-WT4PO4A3.js → chunk-DULFP3MK.js} +10 -7
  30. package/dist/chunk-EYPJBL7P.js +516 -0
  31. package/dist/{chunk-NUFPTHKU.js → chunk-FOKVY3BK.js} +1 -1
  32. package/dist/chunk-GA5JUSPT.js +64 -0
  33. package/dist/{chunk-UJPXFA26.js → chunk-HHMNZAPD.js} +101 -74
  34. package/dist/chunk-HLQJXUR6.js +67 -0
  35. package/dist/{chunk-JTQJRNFJ.js → chunk-KILVK3FS.js} +4 -4
  36. package/dist/chunk-MOCU5XWF.js +79 -0
  37. package/dist/chunk-O2WGVCED.js +41 -0
  38. package/dist/{chunk-HV4DWKBI.js → chunk-O7EMWEVJ.js} +2 -4
  39. package/dist/{chunk-UFOYFYI7.js → chunk-QXLMHLRC.js} +6 -9
  40. package/dist/{chunk-QRO35SOM.js → chunk-R5YJIYPF.js} +981 -747
  41. package/dist/{chunk-JR6DJZOU.js → chunk-RABYBFX5.js} +4 -10
  42. package/dist/{chunk-SR6QPRIE.js → chunk-RFC2SBEX.js} +7 -13
  43. package/dist/chunk-SHSVN3SE.js +21 -0
  44. package/dist/{chunk-CKNAH5TG.js → chunk-U24EACC4.js} +3 -10
  45. package/dist/{chunk-56OGTS24.js → chunk-VOUGDY2O.js} +4 -11
  46. package/dist/chunk-WCKZDOGF.js +31 -0
  47. package/dist/chunk-XQYH52SI.js +129 -0
  48. package/dist/{chunk-7E4FZIYJ.js → chunk-XUIJYNRJ.js} +1 -1
  49. package/dist/{chunk-6DJDEXET.js → chunk-YCIUEZVK.js} +6 -12
  50. package/dist/config-2WQGMAEN.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-6JNLMYQD.js} +4 -4
  54. package/dist/create-agent-IRZOU4R5.js +23 -0
  55. package/dist/create-analytics-report-N4L4V5QL.js +19 -0
  56. package/dist/create-analytics-report-QEHXG7FU.js +18 -0
  57. package/dist/{create-annotation-EUXXQ6NS.js → create-annotation-CCEGIZ67.js} +10 -5
  58. package/dist/create-annotation-DTHCMWHB.js +29 -0
  59. package/dist/{create-api-key-BGBB76JX.js → create-api-key-JKM2DSZO.js} +5 -7
  60. package/dist/create-api-key-JPEUIXGM.js +24 -0
  61. package/dist/create-dataset-DJNXYJ5B.js +22 -0
  62. package/dist/{create-dataset-FD5VAXU4.js → create-dataset-WON4SOTC.js} +6 -6
  63. package/dist/create-dataset-records-TMEOTLTO.js +20 -0
  64. package/dist/{create-dataset-records-WQUXXOHI.js → create-dataset-records-UJBW3C7C.js} +5 -7
  65. package/dist/create-evaluator-N5AEHI4K.js +27 -0
  66. package/dist/{create-evaluator-6NV33Z52.js → create-evaluator-XYNY2YFY.js} +4 -4
  67. package/dist/create-mcp-server.cjs +9712 -0
  68. package/dist/create-mcp-server.js +2757 -10
  69. package/dist/{create-project-ZQ7TFIO2.js → create-project-EY4XZ7TH.js} +4 -4
  70. package/dist/create-project-YL345T5L.js +44 -0
  71. package/dist/{create-prompt-BS6QRCUU.js → create-prompt-JZQNQ7I3.js} +5 -7
  72. package/dist/create-prompt-ZUMQHHX7.js +37 -0
  73. package/dist/create-prompt-tag-CJ5FZ436.js +17 -0
  74. package/dist/{create-prompt-tag-FCQ5ELSQ.js → create-prompt-tag-JFP2Q3PO.js} +3 -3
  75. package/dist/create-scenario-CQU2SSFB.js +33 -0
  76. package/dist/{create-scenario-DRPTPXU3.js → create-scenario-S6OWWKJO.js} +5 -5
  77. package/dist/create-test-suite-OLGCAGJA.js +36 -0
  78. package/dist/{create-test-suite-ZIZCCFJ4.js → create-test-suite-Y7P2RI4L.js} +6 -6
  79. package/dist/create-trigger-4CNBTISJ.js +48 -0
  80. package/dist/create-trigger-RQ653WYF.js +49 -0
  81. package/dist/dashboards-BA7M6CMO.js +90 -0
  82. package/dist/dashboards-U663GUIB.js +91 -0
  83. package/dist/{delete-agent-SA4JMUZF.js → delete-agent-J2Q4DRZ2.js} +4 -4
  84. package/dist/delete-agent-ZAU4LTXB.js +18 -0
  85. package/dist/delete-analytics-report-QK6X7P4S.js +19 -0
  86. package/dist/delete-analytics-report-YUYLDHLL.js +18 -0
  87. package/dist/delete-annotation-7X4NYXXM.js +17 -0
  88. package/dist/{delete-annotation-X3KKK7QY.js → delete-annotation-KJOCDLV3.js} +4 -4
  89. package/dist/{delete-dataset-W6EZ44HY.js → delete-dataset-NXP7ZPPV.js} +5 -7
  90. package/dist/delete-dataset-RUTZBBVD.js +18 -0
  91. package/dist/{delete-dataset-records-7CNOTALB.js → delete-dataset-records-4Z7DZCDW.js} +5 -7
  92. package/dist/delete-dataset-records-75UAR5IS.js +19 -0
  93. package/dist/delete-evaluator-E3CUNGTQ.js +16 -0
  94. package/dist/delete-evaluator-RI4GALGX.js +15 -0
  95. package/dist/delete-prompt-tag-LE3WJPKS.js +17 -0
  96. package/dist/{delete-prompt-tag-QB3OCZUV.js → delete-prompt-tag-S4KBZTNG.js} +3 -3
  97. package/dist/delete-workflow-4CZFIQCQ.js +17 -0
  98. package/dist/{delete-workflow-NG2VXYYM.js → delete-workflow-PWQPDW6H.js} +4 -4
  99. package/dist/discover-evaluator-schema-UHWA5HVL.js +120 -0
  100. package/dist/discover-evaluator-schema-XKCLLCB3.js +118 -0
  101. package/dist/discover-scenario-schema-NOJY6S7E.js +137 -0
  102. package/dist/{discover-scenario-schema-W7KBXA4J.js → discover-scenario-schema-OOFIQKOG.js} +37 -17
  103. package/dist/discover-schema-7WHIIATI.js +442 -0
  104. package/dist/{discover-schema-L6QDPON3.js → discover-schema-J2ANOBKO.js} +181 -186
  105. package/dist/get-agent-5T3CXQOR.js +69 -0
  106. package/dist/{get-agent-7THF7HCU.js → get-agent-ZKYQJUQ7.js} +15 -11
  107. package/dist/get-analytics-4MPEK4KV.js +79 -0
  108. package/dist/get-analytics-ZLI3A4F5.js +80 -0
  109. package/dist/get-analytics-report-JCKYMA2S.js +29 -0
  110. package/dist/get-analytics-report-SKIP2JWH.js +30 -0
  111. package/dist/get-dataset-APGZBYMH.js +64 -0
  112. package/dist/get-dataset-LWXDVMVE.js +63 -0
  113. package/dist/get-evaluator-3A7BJBAB.js +47 -0
  114. package/dist/{get-evaluator-RZ44UIN6.js → get-evaluator-IWNJINRY.js} +4 -4
  115. package/dist/get-project-EQVB4LEL.js +26 -0
  116. package/dist/{get-project-QSQEAB33.js → get-project-RK6AJTEP.js} +4 -4
  117. package/dist/{get-prompt-GVKXF5NL.js → get-prompt-TLG2T2DS.js} +53 -58
  118. package/dist/get-prompt-ZER557X3.js +94 -0
  119. package/dist/get-run-plan-5X7DDJRN.js +58 -0
  120. package/dist/{get-run-plan-NY7J5GRE.js → get-run-plan-PEHRO5M3.js} +7 -9
  121. package/dist/{get-scenario-Q3LLQE4T.js → get-scenario-375W5D6I.js} +5 -5
  122. package/dist/get-scenario-UQX45ZZO.js +37 -0
  123. package/dist/{get-simulation-run-WINEYDMK.js → get-simulation-run-2NBXJADG.js} +26 -22
  124. package/dist/get-simulation-run-QZTLGL7W.js +69 -0
  125. package/dist/{get-test-suite-4HKA7OKS.js → get-test-suite-GVIBDG7K.js} +5 -5
  126. package/dist/get-test-suite-OODIR3RI.js +48 -0
  127. package/dist/{get-trace-RCUV7N4O.js → get-trace-AGCHVPJK.js} +11 -13
  128. package/dist/get-trace-KJLYAZRC.js +45 -0
  129. package/dist/get-workflow-3TV2YYC5.js +25 -0
  130. package/dist/{get-workflow-EEOC7Y45.js → get-workflow-7LZSVPP2.js} +4 -4
  131. package/dist/{http-security-EU3CHTY7.js → http-security-DNLBNQZL.js} +2 -2
  132. package/dist/{http-server-WCDUARTH.js → http-server-7CCN3EHJ.js} +4249 -325
  133. package/dist/index.js +59595 -38027
  134. package/dist/langwatch-api-analytics-reports-6CF6KUET.js +17 -0
  135. package/dist/langwatch-api-analytics-reports-RPFB5AO5.js +18 -0
  136. package/dist/{langwatch-api-annotations-6DHVZWUK.js → langwatch-api-annotations-H4AI4TKG.js} +4 -4
  137. package/dist/langwatch-api-annotations-QSJNUQQS.js +17 -0
  138. package/dist/langwatch-api-monitors-ENHLOL3S.js +47 -0
  139. package/dist/{langwatch-api-monitors-6ISFJ7WX.js → langwatch-api-monitors-OHSGADTH.js} +11 -16
  140. package/dist/langwatch-api-secrets-AGW6UUMD.js +55 -0
  141. package/dist/langwatch-api-secrets-CLTS766Q.js +56 -0
  142. package/dist/langwatch-api-triggers-G5UWFNN2.js +22 -0
  143. package/dist/langwatch-api-triggers-QMR7KEXW.js +23 -0
  144. package/dist/langwatch-api-workflows-HKTBIKKY.js +15 -0
  145. package/dist/{langwatch-api-workflows-6UJL5U4Z.js → langwatch-api-workflows-OMROZH2O.js} +4 -4
  146. package/dist/{list-agents-AMVDQPQL.js → list-agents-BYWDNAHT.js} +4 -4
  147. package/dist/list-agents-MG24MHZE.js +42 -0
  148. package/dist/list-analytics-reports-G3EPWGSQ.js +32 -0
  149. package/dist/list-analytics-reports-PPWIFRES.js +33 -0
  150. package/dist/list-annotations-QCLGEK5A.js +38 -0
  151. package/dist/{list-annotations-6PR5NLIC.js → list-annotations-Y4EUBJHG.js} +10 -5
  152. package/dist/list-api-keys-DAVOBPFK.js +42 -0
  153. package/dist/{list-api-keys-GVPNBIHQ.js → list-api-keys-JMW5WRXX.js} +10 -5
  154. package/dist/list-dashboards-2P3VJFRS.js +29 -0
  155. package/dist/list-dashboards-MW5O3MKH.js +30 -0
  156. package/dist/list-dataset-records-KEHT7G6Q.js +43 -0
  157. package/dist/{list-dataset-records-O67HZ35Y.js → list-dataset-records-KMLLMZAZ.js} +14 -10
  158. package/dist/{list-datasets-WXZL6UMP.js → list-datasets-P3JK2ZHS.js} +9 -13
  159. package/dist/list-datasets-Z7OOE4KI.js +56 -0
  160. package/dist/{list-evaluators-PAX72WCN.js → list-evaluators-7RRESBOU.js} +5 -7
  161. package/dist/list-evaluators-VATJVOHR.js +32 -0
  162. package/dist/{list-model-providers-VVLZMLCX.js → list-model-providers-OXDRPUCJ.js} +4 -4
  163. package/dist/list-model-providers-VXQJWDXU.js +35 -0
  164. package/dist/{list-projects-AQVI6SUK.js → list-projects-HUVK7L3W.js} +5 -7
  165. package/dist/list-projects-X72ZXVY5.js +40 -0
  166. package/dist/{list-prompt-tags-WZFBJOHG.js → list-prompt-tags-3I3LWFIR.js} +3 -3
  167. package/dist/list-prompt-tags-DRHUH2ND.js +23 -0
  168. package/dist/list-prompts-6DX3QECJ.js +30 -0
  169. package/dist/{list-prompts-BQOHRHYT.js → list-prompts-PS423RU3.js} +4 -6
  170. package/dist/list-run-plans-5SXPOV3X.js +45 -0
  171. package/dist/{list-run-plans-UBAU2DGH.js → list-run-plans-6VNHINPY.js} +5 -5
  172. package/dist/list-scenarios-EQWCW7Q4.js +45 -0
  173. package/dist/{list-scenarios-MS4IUIVM.js → list-scenarios-GKNH3YND.js} +13 -11
  174. package/dist/{list-simulation-runs-D6YF4ZOU.js → list-simulation-runs-KHY7KALI.js} +12 -8
  175. package/dist/list-simulation-runs-PUDK32C2.js +53 -0
  176. package/dist/list-test-suites-7H2DRILK.js +34 -0
  177. package/dist/{list-test-suites-L7R2O6DR.js → list-test-suites-GY56LGLY.js} +4 -4
  178. package/dist/list-trigger-fires-7RZUP54Y.js +19 -0
  179. package/dist/list-trigger-fires-OZUF65LI.js +20 -0
  180. package/dist/list-triggers-BGUCUXTJ.js +45 -0
  181. package/dist/list-triggers-XC5KMX4C.js +46 -0
  182. package/dist/list-workflows-55NYC3PC.js +33 -0
  183. package/dist/{list-workflows-6MV4XJHF.js → list-workflows-HV7FUWZA.js} +5 -7
  184. package/dist/{rename-prompt-tag-K5LQ4CY6.js → rename-prompt-tag-2I7Z5FCY.js} +3 -3
  185. package/dist/rename-prompt-tag-SZYTOWDX.js +18 -0
  186. package/dist/{rename-test-suite-NTYHAO5X.js → rename-test-suite-27AYY33K.js} +4 -4
  187. package/dist/rename-test-suite-CLIEPZDO.js +20 -0
  188. package/dist/report-issue-5HSL7CNB.js +924 -0
  189. package/dist/{report-issue-RHZZ33IS.js → report-issue-N7ND5TM6.js} +107 -67
  190. package/dist/{rerun-run-plan-MUDWJBE4.js → rerun-run-plan-O3VUZ6CG.js} +5 -5
  191. package/dist/rerun-run-plan-OJTVVGJI.js +21 -0
  192. package/dist/{revoke-api-key-6LAZ3QZZ.js → revoke-api-key-BU6BKGCG.js} +4 -4
  193. package/dist/revoke-api-key-NZNCFOIR.js +15 -0
  194. package/dist/run-agent-244O4Y5M.js +75 -0
  195. package/dist/run-agent-HPCGZGYW.js +74 -0
  196. package/dist/run-plan-2ZPGGZ4H.js +38 -0
  197. package/dist/{run-plan-T4ZYOZGA.js → run-plan-KSXUYQT3.js} +7 -7
  198. package/dist/run-query-4LMOQ5UW.js +47 -0
  199. package/dist/run-query-BQUHIUC2.js +46 -0
  200. package/dist/{run-test-suite-L4MZ7G4D.js → run-test-suite-P3WLVPXC.js} +6 -6
  201. package/dist/run-test-suite-UEOMCON6.js +25 -0
  202. package/dist/run-workflow-EFZ6HG5B.js +36 -0
  203. package/dist/{run-workflow-DFIS23AP.js → run-workflow-I4IHEN54.js} +4 -4
  204. package/dist/search-traces-6IR7PR4L.js +170 -0
  205. package/dist/search-traces-BYML2NQ4.js +171 -0
  206. package/dist/set-model-provider-RBNGWFVI.js +33 -0
  207. package/dist/{set-model-provider-XRNMFOVR.js → set-model-provider-SHEVKWRC.js} +4 -4
  208. package/dist/{update-agent-DUWNYBNA.js → update-agent-PTKTM2B5.js} +4 -4
  209. package/dist/update-agent-ZPXWRMS2.js +20 -0
  210. package/dist/update-dashboard-widget-HKCBXH7X.js +62 -0
  211. package/dist/update-dashboard-widget-IP2TTQ5G.js +63 -0
  212. package/dist/update-dataset-GHIN6JR3.js +22 -0
  213. package/dist/{update-dataset-YSOMDCOB.js → update-dataset-IRVMY5PF.js} +6 -6
  214. package/dist/update-dataset-record-6VI7K2CL.js +19 -0
  215. package/dist/{update-dataset-record-DEA2ITYR.js → update-dataset-record-Z3L7ACNF.js} +4 -4
  216. package/dist/update-evaluator-5NLNE6VY.js +24 -0
  217. package/dist/{update-evaluator-NH7Q5GWV.js → update-evaluator-FEH7H6NS.js} +4 -4
  218. package/dist/update-project-75H3LDQT.js +24 -0
  219. package/dist/{update-project-Q26FBSYH.js → update-project-QPR3QX55.js} +4 -4
  220. package/dist/update-prompt-BCDFTNLK.js +140 -0
  221. package/dist/{update-prompt-ZQQ2C3KU.js → update-prompt-NPRXYSWA.js} +27 -29
  222. package/dist/update-scenario-BNOMDCMV.js +34 -0
  223. package/dist/{update-scenario-WUX34JAR.js → update-scenario-EM5XGMB7.js} +5 -5
  224. package/package.json +35 -39
  225. package/pyproject.toml +23 -8
  226. package/src/config.d.ts +6 -0
  227. package/src/config.ts +22 -29
  228. package/src/create-mcp-server.ts +887 -634
  229. package/src/documentation-fetch.ts +21 -20
  230. package/src/http-security.ts +166 -135
  231. package/src/http-server.ts +189 -224
  232. package/src/index.ts +14 -16
  233. package/src/langwatch-api-agents.ts +18 -21
  234. package/src/langwatch-api-analytics-reports.ts +62 -0
  235. package/src/langwatch-api-annotations.ts +11 -12
  236. package/src/langwatch-api-api-keys.ts +8 -9
  237. package/src/langwatch-api-dashboard-widgets.ts +47 -0
  238. package/src/langwatch-api-dashboards.ts +109 -24
  239. package/src/langwatch-api-datasets.ts +98 -32
  240. package/src/langwatch-api-evaluators.ts +13 -19
  241. package/src/langwatch-api-model-providers.ts +4 -4
  242. package/src/langwatch-api-monitors.ts +14 -18
  243. package/src/langwatch-api-projects.ts +10 -9
  244. package/src/langwatch-api-query.ts +114 -0
  245. package/src/langwatch-api-run-plans.ts +12 -29
  246. package/src/langwatch-api-scenarios.ts +9 -11
  247. package/src/langwatch-api-secrets.ts +31 -24
  248. package/src/langwatch-api-simulation-runs.ts +6 -8
  249. package/src/langwatch-api-test-suites.ts +14 -33
  250. package/src/langwatch-api-triggers.ts +96 -34
  251. package/src/langwatch-api-workflows.ts +9 -9
  252. package/src/langwatch-api.ts +118 -124
  253. package/src/public-http-request.ts +21 -12
  254. package/src/schemas/analytics-metrics.ts +3 -15
  255. package/src/schemas/create-dataset.ts +3 -4
  256. package/src/schemas/run-plan.ts +13 -29
  257. package/src/schemas/suite-fields.ts +6 -23
  258. package/src/schemas/triggers.ts +365 -0
  259. package/src/schemas/widget-sources.ts +33 -0
  260. package/src/tools/add-dashboard-widget.ts +51 -0
  261. package/src/tools/archive-project.ts +2 -4
  262. package/src/tools/archive-run-plan.ts +2 -4
  263. package/src/tools/archive-scenario.ts +2 -4
  264. package/src/tools/archive-test-suite.ts +2 -4
  265. package/src/tools/assign-prompt-tag.ts +6 -2
  266. package/src/tools/create-agent.ts +1 -1
  267. package/src/tools/create-analytics-report.ts +7 -0
  268. package/src/tools/create-annotation.ts +7 -2
  269. package/src/tools/create-api-key.ts +4 -6
  270. package/src/tools/create-dataset-records.ts +4 -8
  271. package/src/tools/create-dataset.ts +5 -7
  272. package/src/tools/create-evaluator.ts +3 -5
  273. package/src/tools/create-project.ts +2 -2
  274. package/src/tools/create-prompt-tag.ts +2 -4
  275. package/src/tools/create-prompt.ts +9 -18
  276. package/src/tools/create-scenario.ts +5 -7
  277. package/src/tools/create-test-suite.ts +4 -9
  278. package/src/tools/create-trigger.ts +55 -0
  279. package/src/tools/dashboard-widget-queries.ts +45 -0
  280. package/src/tools/dashboards.ts +104 -0
  281. package/src/tools/delete-agent.ts +1 -1
  282. package/src/tools/delete-analytics-report.ts +7 -0
  283. package/src/tools/delete-annotation.ts +1 -1
  284. package/src/tools/delete-dataset-records.ts +4 -8
  285. package/src/tools/delete-dataset.ts +3 -7
  286. package/src/tools/delete-evaluator.ts +4 -6
  287. package/src/tools/delete-prompt-tag.ts +2 -4
  288. package/src/tools/delete-workflow.ts +1 -1
  289. package/src/tools/discover-evaluator-schema.ts +34 -25
  290. package/src/tools/discover-scenario-schema.ts +41 -21
  291. package/src/tools/discover-schema.ts +149 -27
  292. package/src/tools/experiment-run-status.ts +2 -8
  293. package/src/tools/format-dataset-mutation.ts +5 -10
  294. package/src/tools/format-run-plan.ts +7 -21
  295. package/src/tools/format-scenario.ts +2 -4
  296. package/src/tools/format-suite-details.ts +6 -12
  297. package/src/tools/get-agent.ts +15 -6
  298. package/src/tools/get-analytics-report.ts +23 -0
  299. package/src/tools/get-analytics.ts +52 -46
  300. package/src/tools/get-dataset.ts +34 -16
  301. package/src/tools/get-evaluator.ts +4 -11
  302. package/src/tools/get-experiment-results.ts +219 -186
  303. package/src/tools/get-project.ts +2 -4
  304. package/src/tools/get-prompt.ts +63 -84
  305. package/src/tools/get-run-plan.ts +4 -6
  306. package/src/tools/get-scenario.ts +4 -6
  307. package/src/tools/get-simulation-run.ts +27 -24
  308. package/src/tools/get-test-suite.ts +2 -5
  309. package/src/tools/get-trace.ts +16 -17
  310. package/src/tools/get-workflow.ts +1 -1
  311. package/src/tools/list-agents.ts +1 -1
  312. package/src/tools/list-analytics-reports.ts +27 -0
  313. package/src/tools/list-annotations.ts +8 -5
  314. package/src/tools/list-api-keys.ts +7 -2
  315. package/src/tools/list-dashboards.ts +20 -21
  316. package/src/tools/list-dataset-records.ts +8 -6
  317. package/src/tools/list-datasets.ts +12 -23
  318. package/src/tools/list-evaluators.ts +4 -8
  319. package/src/tools/list-experiment-runs.ts +5 -9
  320. package/src/tools/list-experiments.ts +5 -11
  321. package/src/tools/list-model-providers.ts +3 -5
  322. package/src/tools/list-projects.ts +2 -4
  323. package/src/tools/list-prompt-tags.ts +3 -3
  324. package/src/tools/list-prompts.ts +4 -8
  325. package/src/tools/list-run-plans.ts +2 -2
  326. package/src/tools/list-scenarios.ts +14 -15
  327. package/src/tools/list-simulation-runs.ts +8 -4
  328. package/src/tools/list-test-suites.ts +1 -1
  329. package/src/tools/list-trigger-fires.ts +17 -0
  330. package/src/tools/list-triggers.ts +39 -0
  331. package/src/tools/list-workflows.ts +2 -4
  332. package/src/tools/rename-prompt-tag.ts +1 -1
  333. package/src/tools/rename-test-suite.ts +2 -5
  334. package/src/tools/report-issue.ts +7 -9
  335. package/src/tools/rerun-run-plan.ts +2 -5
  336. package/src/tools/revoke-api-key.ts +2 -4
  337. package/src/tools/run-agent.ts +29 -26
  338. package/src/tools/run-experiment.ts +37 -34
  339. package/src/tools/run-plan.ts +4 -7
  340. package/src/tools/run-query.ts +47 -0
  341. package/src/tools/run-test-suite.ts +4 -7
  342. package/src/tools/run-workflow.ts +2 -5
  343. package/src/tools/search-traces.ts +161 -47
  344. package/src/tools/set-model-provider.ts +4 -6
  345. package/src/tools/test-agent.ts +2 -2
  346. package/src/tools/update-agent.ts +1 -1
  347. package/src/tools/update-dashboard-widget.ts +86 -0
  348. package/src/tools/update-dataset-record.ts +1 -1
  349. package/src/tools/update-dataset.ts +5 -7
  350. package/src/tools/update-evaluator.ts +3 -5
  351. package/src/tools/update-project.ts +1 -1
  352. package/src/tools/update-prompt.ts +44 -59
  353. package/src/tools/update-scenario.ts +5 -7
  354. package/src/tools/update-test-suite.ts +6 -11
  355. package/src/utils/date-parsing.ts +1 -1
  356. package/src/utils/escape-markdown.ts +3 -8
  357. package/src/utils/format-evaluations.ts +6 -6
  358. package/src/utils/markdown-table.ts +58 -0
  359. package/src/utils/trace-id-shape.ts +20 -0
  360. package/tsconfig.app.json +24 -0
  361. package/tsconfig.json +14 -12
  362. package/uv.lock +667 -341
  363. package/vitest.integration.config.js +10 -0
  364. package/vitest.scenario.config.js +9 -0
  365. package/.eslintrc.cjs +0 -36
  366. package/dist/chunk-AN4OUA4D.js +0 -86
  367. package/dist/chunk-GELJ2MQR.js +0 -226
  368. package/dist/chunk-K37ZNPXK.js +0 -24
  369. package/dist/chunk-S4GVX36W.js +0 -39
  370. package/dist/config.d.ts +0 -17
  371. package/dist/create-dashboard-Z76AIPLS.js +0 -19
  372. package/dist/create-mcp-server.d.ts +0 -10
  373. package/dist/delete-dashboard-LYMRPF27.js +0 -19
  374. package/dist/delete-evaluator-RKYC4TNB.js +0 -16
  375. package/dist/discover-evaluator-schema-ESSHQGPY.js +0 -1912
  376. package/dist/get-analytics-R6AZD3AW.js +0 -73
  377. package/dist/get-dashboard-P4WWVHFU.js +0 -30
  378. package/dist/get-dataset-AKTYSQDI.js +0 -49
  379. package/dist/index.d.ts +0 -2
  380. package/dist/langwatch-api-dashboards-2KJL2M42.js +0 -18
  381. package/dist/langwatch-api-secrets-OEBD6GBU.js +0 -41
  382. package/dist/langwatch-api-triggers-5E6DDGX6.js +0 -31
  383. package/dist/list-dashboards-Z3BZKDGF.js +0 -33
  384. package/dist/run-agent-CAGWGTYT.js +0 -72
  385. package/dist/search-traces-4XTJYXIK.js +0 -79
  386. package/src/__tests__/agent-tools.unit.test.ts +0 -257
  387. package/src/__tests__/all-tools.integration.test.ts +0 -1872
  388. package/src/__tests__/config.unit.test.ts +0 -202
  389. package/src/__tests__/datasets.integration.test.ts +0 -620
  390. package/src/__tests__/datasets.unit.test.ts +0 -244
  391. package/src/__tests__/date-parsing.unit.test.ts +0 -78
  392. package/src/__tests__/discover-evaluator-schema.unit.test.ts +0 -89
  393. package/src/__tests__/discover-schema.unit.test.ts +0 -118
  394. package/src/__tests__/docker.integration.test.ts +0 -318
  395. package/src/__tests__/documentation-fetch-security.integration.test.ts +0 -182
  396. package/src/__tests__/evaluator-tools.unit.test.ts +0 -262
  397. package/src/__tests__/experiment-list-tools.unit.test.ts +0 -157
  398. package/src/__tests__/experiment-status.unit.test.ts +0 -194
  399. package/src/__tests__/feature-map-tool-drift.unit.test.ts +0 -93
  400. package/src/__tests__/get-experiment-results.unit.test.ts +0 -313
  401. package/src/__tests__/http-security-origin.unit.test.ts +0 -97
  402. package/src/__tests__/http-security-sessions.unit.test.ts +0 -209
  403. package/src/__tests__/http-security-verifier.unit.test.ts +0 -248
  404. package/src/__tests__/http-server-allocation.integration.test.ts +0 -279
  405. package/src/__tests__/http-server-origin.integration.test.ts +0 -169
  406. package/src/__tests__/http-server-session-auth.integration.test.ts +0 -341
  407. package/src/__tests__/http-transport.integration.test.ts +0 -395
  408. package/src/__tests__/integration.integration.test.ts +0 -284
  409. package/src/__tests__/langwatch-api.unit.test.ts +0 -661
  410. package/src/__tests__/model-provider-tools.unit.test.ts +0 -190
  411. package/src/__tests__/project-api-key-tools.unit.test.ts +0 -451
  412. package/src/__tests__/prompt-response-types.unit.test.ts +0 -51
  413. package/src/__tests__/prompts.integration.test.ts +0 -736
  414. package/src/__tests__/public-http-request-security.integration.test.ts +0 -118
  415. package/src/__tests__/report-issue.integration.test.ts +0 -147
  416. package/src/__tests__/run-plan-tools.unit.test.ts +0 -565
  417. package/src/__tests__/scenario-tools.integration.test.ts +0 -286
  418. package/src/__tests__/scenario-tools.unit.test.ts +0 -207
  419. package/src/__tests__/schemas.unit.test.ts +0 -85
  420. package/src/__tests__/simulation-run-tools.unit.test.ts +0 -116
  421. package/src/__tests__/support/http-server-harness.ts +0 -138
  422. package/src/__tests__/test-suite-tools.unit.test.ts +0 -615
  423. package/src/__tests__/tools.integration.test.ts +0 -896
  424. package/src/schemas/filter-fields.ts +0 -119
  425. package/src/schemas/index.ts +0 -9
  426. package/src/tools/create-dashboard.ts +0 -7
  427. package/src/tools/delete-dashboard.ts +0 -7
  428. package/src/tools/get-dashboard.ts +0 -22
@@ -1,9 +1,23 @@
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
+ };
15
+
16
+ /** The dated API version every request names (specs/api-reference/client-api-version.feature). */
17
+ export const LANGWATCH_API_VERSION = "2026-10-26";
18
+
19
+ /** Names the hosted MCP server's calls apart from a local server's. */
20
+ export const HOSTED_MCP_HEADER = "X-LangWatch-MCP-Host";
7
21
 
8
22
  // --- Response types ---
9
23
 
@@ -46,7 +60,7 @@ export interface TraceDetailResponse {
46
60
  error?: Record<string, unknown>;
47
61
  ascii_tree?: string;
48
62
  evaluations?: EvaluationSummary[];
49
- spans?: Array<{
63
+ spans?: {
50
64
  span_id: string;
51
65
  name?: string;
52
66
  type?: string;
@@ -61,7 +75,7 @@ export interface TraceDetailResponse {
61
75
  tokens_estimated?: boolean;
62
76
  cost?: number;
63
77
  };
64
- }>;
78
+ }[];
65
79
  }
66
80
 
67
81
  export interface AnalyticsBucket {
@@ -87,14 +101,10 @@ export interface PromptTag {
87
101
  versionId: string;
88
102
  }
89
103
 
90
- export type PromptFieldList = Array<{ identifier: string; type: string }>;
104
+ export type PromptFieldList = { identifier: string; type: string }[];
91
105
 
92
106
  /**
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.
107
+ * A single versioned prompt payload.
98
108
  */
99
109
  export interface PromptVersion {
100
110
  versionId?: string;
@@ -103,7 +113,7 @@ export interface PromptVersion {
103
113
  model?: string;
104
114
  /** Legacy single-text prompt body. */
105
115
  prompt?: string;
106
- messages?: Array<{ role: string; content: string }>;
116
+ messages?: { role: string; content: string }[];
107
117
  temperature?: number;
108
118
  maxTokens?: number;
109
119
  responseFormat?: Record<string, unknown> | null;
@@ -134,10 +144,9 @@ export class LangWatchApiError extends Error {
134
144
  readonly docsUrl?: string;
135
145
  readonly fault?: HandledErrorFault;
136
146
  /**
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.
147
+ * The per-field failures behind this error, verbatim from the envelope. A validation failure
148
+ * carries the offending field and the values it would have accepted here — the difference
149
+ * between an agent correcting its own request and an agent guessing again.
141
150
  */
142
151
  readonly reasons?: SerializedReason[];
143
152
 
@@ -173,56 +182,42 @@ interface ParsedErrorBody {
173
182
  reasons?: SerializedReason[];
174
183
  }
175
184
 
176
- const VALID_FAULTS: readonly HandledErrorFault[] = ["customer", "platform", "provider"];
185
+ const VALID_FAULTS: readonly HandledErrorFault[] = [
186
+ "customer",
187
+ "platform",
188
+ "provider",
189
+ "presumed_platform",
190
+ ];
177
191
 
178
192
  /**
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.
193
+ * Parses an error response body as a handled-error envelope.
185
194
  */
186
195
  function parseErrorBody(responseBody: string): ParsedErrorBody {
187
196
  try {
188
197
  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>;
198
+ if (!isRecord(parsed)) return {};
199
+ const envelope = parsed;
193
200
  // The canonical v1 envelope nests everything under `error`. Read the
194
201
  // 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;
202
+ const nestedValue = envelope.error;
203
+ const nested = isRecord(nestedValue) ? nestedValue : null;
201
204
  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;
205
+ // `code` is the domain discriminant. The `error` fallback reads the
206
+ // legacy envelope some non-framework families still send; the framework's
207
+ // own unversioned union envelope, which used `error` for the HTTP status
208
+ // text, is gone (packages/api/adrs/002).
209
+ const code = readErrorCode(body);
211
210
  const message = typeof body.message === "string" ? body.message : undefined;
212
211
  if (code === undefined && message === undefined) {
213
212
  return {};
214
213
  }
215
- const tips =
216
- Array.isArray(body.tips) && body.tips.every((t) => typeof t === "string")
217
- ? (body.tips as string[])
218
- : undefined;
214
+ const tips = readStringArray(body.tips);
219
215
  const docsUrl = typeof body.docsUrl === "string" ? body.docsUrl : undefined;
220
216
  const fault = VALID_FAULTS.includes(body.fault as HandledErrorFault)
221
217
  ? (body.fault as HandledErrorFault)
222
218
  : undefined;
223
219
  const reasons =
224
- Array.isArray(body.reasons) &&
225
- body.reasons.every((r) => !!r && typeof r === "object")
220
+ Array.isArray(body.reasons) && body.reasons.every((r) => !!r && typeof r === "object")
226
221
  ? (body.reasons as SerializedReason[])
227
222
  : undefined;
228
223
  return { code, message, tips, docsUrl, fault, reasons };
@@ -231,14 +226,29 @@ function parseErrorBody(responseBody: string): ParsedErrorBody {
231
226
  }
232
227
  }
233
228
 
229
+ function isRecord(value: unknown): value is Record<string, unknown> {
230
+ return typeof value === "object" && value !== null && !Array.isArray(value);
231
+ }
232
+
233
+ function readErrorCode(body: Record<string, unknown>): string | undefined {
234
+ if (typeof body.code === "string") return body.code;
235
+ if (typeof body.error === "string") return body.error;
236
+ return undefined;
237
+ }
238
+
239
+ function readStringArray(value: unknown): string[] | undefined {
240
+ if (!Array.isArray(value) || !value.every(isString)) return undefined;
241
+ return value;
242
+ }
243
+
244
+ function isString(value: unknown): value is string {
245
+ return typeof value === "string";
246
+ }
247
+
234
248
  /**
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.
249
+ * The human line for one per-field failure: the field, what it would have accepted, and what it
250
+ * got. Returns null when a reason names no field, so a generic nested error adds no noise to
251
+ * the message.
242
252
  */
243
253
  function describeReason(reason: SerializedReason): string | null {
244
254
  const meta = reason.meta;
@@ -258,27 +268,28 @@ function describeReason(reason: SerializedReason): string | null {
258
268
  }
259
269
 
260
270
  /**
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.
271
+ * Sends an HTTP request to the LangWatch API. Builds the full URL from the configured endpoint,
272
+ * adds authentication, and handles JSON serialization/deserialization. @throws
273
+ * LangWatchApiError with status code and response body when the response is not OK.
268
274
  */
269
275
  export async function makeRequest(
270
276
  method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
271
277
  path: string,
272
- body?: unknown
278
+ body?: unknown,
273
279
  ): Promise<unknown> {
274
280
  const config = getConfig();
275
281
  const url = config.endpoint + path;
276
282
  const headers: Record<string, string> = {
283
+ ...MCP_IDENTITY_HEADERS,
284
+ "X-API-Version": LANGWATCH_API_VERSION,
277
285
  "X-Auth-Token": requireApiKey(),
278
286
  };
279
287
  if (config.projectId) {
280
288
  headers["X-Project-Id"] = config.projectId;
281
289
  }
290
+ if (config.hosted) {
291
+ headers[HOSTED_MCP_HEADER] = "hosted";
292
+ }
282
293
 
283
294
  if (body !== undefined) {
284
295
  headers["Content-Type"] = "application/json";
@@ -293,9 +304,7 @@ export async function makeRequest(
293
304
  if (!response.ok) {
294
305
  const responseBody = await response.text();
295
306
  const parsed = parseErrorBody(responseBody);
296
- const lines = [
297
- `LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`,
298
- ];
307
+ const lines = [`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`];
299
308
  const reasonLines = (parsed.reasons ?? [])
300
309
  .map(describeReason)
301
310
  .filter((line): line is string => line !== null);
@@ -308,18 +317,13 @@ export async function makeRequest(
308
317
  if (parsed.docsUrl) {
309
318
  lines.push(`Docs: ${parsed.docsUrl}`);
310
319
  }
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
- );
320
+ throw new LangWatchApiError(lines.join("\n"), response.status, responseBody, {
321
+ code: parsed.code,
322
+ tips: parsed.tips,
323
+ docsUrl: parsed.docsUrl,
324
+ fault: parsed.fault,
325
+ reasons: parsed.reasons,
326
+ });
323
327
  }
324
328
 
325
329
  if (response.status === 204 || response.headers?.get("content-length") === "0") {
@@ -329,16 +333,19 @@ export async function makeRequest(
329
333
  }
330
334
 
331
335
  /**
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).
336
+ * Searches traces with optional filters and pagination. Paging is by `scrollId` only: pass the
337
+ * one the previous response returned, and stop when a response carries none.
338
338
  */
339
339
  export async function searchTraces(params: {
340
340
  query?: string;
341
+ /** Exact trace ids: a primary-key seek on trace_summaries, not a scan (ADR-164). */
342
+ traceIds?: string[];
341
343
  filters?: Record<string, string[]>;
344
+ /**
345
+ * The Trace Explorer's query language, as one string. Combined server-side
346
+ * with `filters`, `query` and `traceIds` rather than replacing any of them.
347
+ */
348
+ filter?: string;
342
349
  startDate: number;
343
350
  endDate: number;
344
351
  pageSize?: number;
@@ -346,7 +353,7 @@ export async function searchTraces(params: {
346
353
  format?: "digest" | "json";
347
354
  }): Promise<SearchTracesResponse> {
348
355
  const { format = "digest", ...rest } = params;
349
- return makeRequest("POST", "/api/traces/search", {
356
+ return makeRequest("POST", "/api/v1/traces/search", {
350
357
  ...rest,
351
358
  format,
352
359
  }) as Promise<SearchTracesResponse>;
@@ -355,22 +362,22 @@ export async function searchTraces(params: {
355
362
  /** Retrieves a single trace by its ID. */
356
363
  export async function getTraceById(
357
364
  traceId: string,
358
- format: "digest" | "json" = "digest"
365
+ format: "digest" | "json" = "digest",
359
366
  ): Promise<TraceDetailResponse> {
360
367
  return makeRequest(
361
368
  "GET",
362
- `/api/traces/${encodeURIComponent(traceId)}?format=${format}`
369
+ `/api/v1/traces/${encodeURIComponent(traceId)}?format=${format}`,
363
370
  ) as Promise<TraceDetailResponse>;
364
371
  }
365
372
 
366
373
  /** Fetches analytics timeseries data for the given metrics and date range. */
367
374
  export async function getAnalyticsTimeseries(params: {
368
- series: Array<{
375
+ series: {
369
376
  metric: string;
370
377
  aggregation: string;
371
378
  key?: string;
372
379
  subkey?: string;
373
- }>;
380
+ }[];
374
381
  startDate: number;
375
382
  endDate: number;
376
383
  timeZone?: string;
@@ -380,20 +387,20 @@ export async function getAnalyticsTimeseries(params: {
380
387
  }): Promise<AnalyticsTimeseriesResponse> {
381
388
  return makeRequest(
382
389
  "POST",
383
- "/api/analytics/timeseries",
384
- params
390
+ "/api/v1/analytics/timeseries",
391
+ params,
385
392
  ) as Promise<AnalyticsTimeseriesResponse>;
386
393
  }
387
394
 
388
395
  /** Lists all prompts in the project. */
389
396
  export async function listPrompts(): Promise<PromptSummary[]> {
390
- return makeRequest("GET", "/api/prompts") as Promise<PromptSummary[]>;
397
+ return makeRequest("GET", "/api/v1/prompts") as Promise<PromptSummary[]>;
391
398
  }
392
399
 
393
400
  /** Retrieves a single prompt by ID or handle. */
394
401
  export async function getPrompt(
395
402
  idOrHandle: string,
396
- options?: { version?: number; tag?: string }
403
+ options?: { version?: number; tag?: string },
397
404
  ): Promise<PromptDetailResponse> {
398
405
  const params = new URLSearchParams();
399
406
  if (options?.version != null) params.set("version", String(options.version));
@@ -401,48 +408,42 @@ export async function getPrompt(
401
408
  const query = params.toString() ? `?${params}` : "";
402
409
  return makeRequest(
403
410
  "GET",
404
- `/api/prompts/${encodeURIComponent(idOrHandle)}${query}`
411
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}${query}`,
405
412
  ) as Promise<PromptDetailResponse>;
406
413
  }
407
414
 
408
415
  /** Lists all versions of a prompt (versioned data only). */
409
- export async function getPromptVersions(
410
- idOrHandle: string
411
- ): Promise<PromptVersion[]> {
416
+ export async function getPromptVersions(idOrHandle: string): Promise<PromptVersion[]> {
412
417
  return makeRequest(
413
418
  "GET",
414
- `/api/prompts/${encodeURIComponent(idOrHandle)}/versions`
419
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}/versions`,
415
420
  ) as Promise<PromptVersion[]>;
416
421
  }
417
422
 
418
423
  /** Creates a new prompt. */
419
424
  export async function createPrompt(data: {
420
425
  handle: string;
421
- messages: Array<{ role: string; content: string }>;
426
+ messages: { role: string; content: string }[];
422
427
  model: string;
423
428
  tags?: string[];
424
429
  }): Promise<PromptMutationResponse> {
425
- return makeRequest(
426
- "POST",
427
- "/api/prompts",
428
- data
429
- ) as Promise<PromptMutationResponse>;
430
+ return makeRequest("POST", "/api/v1/prompts", data) as Promise<PromptMutationResponse>;
430
431
  }
431
432
 
432
433
  /** Updates an existing prompt by ID or handle. */
433
434
  export async function updatePrompt(
434
435
  idOrHandle: string,
435
436
  data: {
436
- messages?: Array<{ role: string; content: string }>;
437
+ messages?: { role: string; content: string }[];
437
438
  model?: string;
438
439
  commitMessage: string;
439
440
  tags?: string[];
440
- }
441
+ },
441
442
  ): Promise<PromptMutationResponse> {
442
443
  return makeRequest(
443
444
  "PUT",
444
- `/api/prompts/${encodeURIComponent(idOrHandle)}`,
445
- data
445
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}`,
446
+ data,
446
447
  ) as Promise<PromptMutationResponse>;
447
448
  }
448
449
 
@@ -458,19 +459,19 @@ export async function assignPromptTag({
458
459
  }): Promise<unknown> {
459
460
  return makeRequest(
460
461
  "PUT",
461
- `/api/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
462
- { versionId }
462
+ `/api/v1/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
463
+ { versionId },
463
464
  );
464
465
  }
465
466
 
466
467
  /** Lists all prompt tag definitions for the organization. */
467
468
  export async function listPromptTags(): Promise<unknown> {
468
- return makeRequest("GET", "/api/prompts/tags");
469
+ return makeRequest("GET", "/api/v1/prompts/tags");
469
470
  }
470
471
 
471
472
  /** Creates a custom prompt tag definition. */
472
473
  export async function createPromptTag(name: string): Promise<unknown> {
473
- return makeRequest("POST", "/api/prompts/tags", { name });
474
+ return makeRequest("POST", "/api/v1/prompts/tags", { name });
474
475
  }
475
476
 
476
477
  /** Renames an existing prompt tag. */
@@ -481,17 +482,10 @@ export async function renamePromptTag({
481
482
  tag: string;
482
483
  name: string;
483
484
  }): Promise<unknown> {
484
- return makeRequest(
485
- "PUT",
486
- `/api/prompts/tags/${encodeURIComponent(tag)}`,
487
- { name }
488
- );
485
+ return makeRequest("PUT", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`, { name });
489
486
  }
490
487
 
491
488
  /** Deletes a prompt tag and all its assignments. */
492
489
  export async function deletePromptTag(tag: string): Promise<unknown> {
493
- return makeRequest(
494
- "DELETE",
495
- `/api/prompts/tags/${encodeURIComponent(tag)}`
496
- );
490
+ return makeRequest("DELETE", `/api/v1/prompts/tags/${encodeURIComponent(tag)}`);
497
491
  }
@@ -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"),