@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,17 +1,142 @@
1
- import { searchTraces as apiSearchTraces } from "../langwatch-api.js";
2
- import { parseRelativeDate } from "../utils/date-parsing.js";
3
- import { formatEvaluationLines } from "../utils/format-evaluations.js";
1
+ import { searchTraces as apiSearchTraces, type TraceSearchResult } from "../langwatch-api.ts";
2
+ import { parseRelativeDate } from "../utils/date-parsing.ts";
3
+ import { formatEvaluationLines } from "../utils/format-evaluations.ts";
4
+ import { looksLikeTraceId } from "../utils/trace-id-shape.ts";
5
+
6
+ const HOUR_MS = 3600000;
7
+ const DAY_MS = 86400000;
8
+
9
+ /** Default window for a text search. */
10
+ const TEXT_SEARCH_WINDOW_MS = DAY_MS;
11
+
12
+ /**
13
+ * Default window when trace ids are named: an exact-match intent must not be
14
+ * answered against yesterday alone. Mirrors the platform's 90-day id lookup
15
+ * bound (ADR-164).
16
+ */
17
+ const ID_LOOKUP_WINDOW_MS = 90 * DAY_MS;
18
+
19
+ function previewLine({
20
+ label,
21
+ text,
22
+ }: {
23
+ label: string;
24
+ text: { value: string } | undefined;
25
+ }): string {
26
+ const value = text?.value ? String(text.value) : "N/A";
27
+ return `- **${label}**: ${value.slice(0, 100)}${value.length > 100 ? "..." : ""}`;
28
+ }
29
+
30
+ function traceLines(trace: TraceSearchResult): string[] {
31
+ const lines = [`### Trace: ${trace.trace_id}`];
32
+
33
+ if (trace.formatted_trace) {
34
+ lines.push(trace.formatted_trace);
35
+ } else {
36
+ lines.push(previewLine({ label: "Input", text: trace.input }));
37
+ lines.push(previewLine({ label: "Output", text: trace.output }));
38
+ }
39
+
40
+ if (trace.timestamps) {
41
+ lines.push(`- **Time**: ${trace.timestamps.started_at || "N/A"}`);
42
+ }
43
+ if (trace.error) {
44
+ lines.push(`- **Error**: ${JSON.stringify(trace.error)}`);
45
+ }
46
+ if (trace.evaluations && trace.evaluations.length > 0) {
47
+ lines.push(...formatEvaluationLines(trace.evaluations));
48
+ }
49
+ lines.push("");
50
+ return lines;
51
+ }
52
+
53
+ function describeSpan({ ms }: { ms: number }): string {
54
+ if (ms % DAY_MS === 0) {
55
+ const days = ms / DAY_MS;
56
+ return days === 1 ? "24 hours" : `${days} days`;
57
+ }
58
+ const hours = Math.round(ms / HOUR_MS);
59
+ return hours === 1 ? "1 hour" : `${hours} hours`;
60
+ }
61
+
62
+ /** The next sensible window to offer, or undefined once the span is already wide. */
63
+ function suggestWiderWindow({ spanMs }: { spanMs: number }): string | undefined {
64
+ if (spanMs < 7 * DAY_MS) return "7d";
65
+ if (spanMs < 30 * DAY_MS) return "30d";
66
+ if (spanMs < 90 * DAY_MS) return "90d";
67
+ return undefined;
68
+ }
69
+
70
+ /** An empty result states the searched window and names the tool that looks an id up. */
71
+ function buildEmptyResult({
72
+ query,
73
+ traceIds,
74
+ spanMs,
75
+ windowWasDefaulted,
76
+ startDate,
77
+ endDate,
78
+ }: {
79
+ query?: string;
80
+ traceIds?: string[];
81
+ spanMs: number;
82
+ windowWasDefaulted: boolean;
83
+ startDate: number;
84
+ endDate: number;
85
+ }): string {
86
+ const hasTraceIds = (traceIds?.length ?? 0) > 0;
87
+ const lines = [
88
+ hasTraceIds
89
+ ? "No traces matched the requested trace ids in the searched window."
90
+ : "No traces found matching your query.",
91
+ "",
92
+ ];
93
+
94
+ const range = `${new Date(startDate).toISOString()} to ${new Date(endDate).toISOString()}`;
95
+ lines.push(
96
+ windowWasDefaulted
97
+ ? `Searched the last ${describeSpan({ ms: spanMs })} (the default): ${range}.`
98
+ : `Searched ${range}.`,
99
+ );
100
+ lines.push("", "Tips:");
101
+
102
+ if (query && looksLikeTraceId(query)) {
103
+ lines.push(
104
+ `- "${query}" looks like a trace id. Free text never matches trace ids — use \`get_trace\` with traceId: "${query}".`,
105
+ );
106
+ }
107
+
108
+ const wider = suggestWiderWindow({ spanMs });
109
+ if (wider) {
110
+ lines.push(
111
+ `- Widen the window with startDate, e.g. startDate: "${wider}". Accepts h (hours), d (days), w (weeks), m (30-day months), or an ISO date.`,
112
+ );
113
+ }
114
+
115
+ if (hasTraceIds) {
116
+ lines.push(
117
+ "- Retry with an earlier startDate, or relax the query and filters if you supplied them.",
118
+ "- Looking up one full id? `get_trace` has no time window. A unique 8–31 character hex prefix searches the last 90 days.",
119
+ );
120
+ } else {
121
+ lines.push(
122
+ "- Looking up a known trace id? `get_trace` takes a traceId. A full id has no time window; a unique 8–31 character hex prefix searches the last 90 days.",
123
+ "- To fetch several known trace ids at once, pass `traceIds` instead of `query`.",
124
+ );
125
+ }
126
+
127
+ return lines.join("\n");
128
+ }
4
129
 
5
130
  /**
6
- * Handles the search_traces MCP tool invocation.
7
- *
8
- * Searches LangWatch traces with optional filters, text query, and date range.
9
- * In digest mode (default), returns AI-readable formatted digests per trace.
10
- * In json mode, returns the full raw JSON.
131
+ * Handles the search_traces MCP tool: searches with optional filters, text
132
+ * query, trace ids and date range. Digest mode (default) returns AI-readable
133
+ * digests per trace; json mode returns the full raw JSON.
11
134
  */
12
135
  export async function handleSearchTraces(params: {
13
136
  query?: string;
137
+ traceIds?: string[];
14
138
  filters?: Record<string, string[]>;
139
+ filter?: string;
15
140
  startDate?: string;
16
141
  endDate?: string;
17
142
  pageSize?: number;
@@ -19,15 +144,27 @@ export async function handleSearchTraces(params: {
19
144
  format?: "digest" | "json";
20
145
  }): Promise<string> {
21
146
  const now = Date.now();
22
- const startDate = params.startDate
23
- ? parseRelativeDate(params.startDate)
24
- : now - 86400000;
25
- const endDate = params.endDate ? parseRelativeDate(params.endDate) : now;
147
+ const hasTraceIds = (params.traceIds?.length ?? 0) > 0;
148
+ const defaultSpanMs = hasTraceIds ? ID_LOOKUP_WINDOW_MS : TEXT_SEARCH_WINDOW_MS;
149
+
150
+ const endDate = params.endDate !== undefined ? parseRelativeDate(params.endDate) : now;
151
+ const startDate =
152
+ params.startDate !== undefined ? parseRelativeDate(params.startDate) : endDate - defaultSpanMs;
153
+
154
+ if (startDate >= endDate) {
155
+ throw new Error(
156
+ `Invalid trace search window: startDate (${new Date(startDate).toISOString()}) must be before endDate (${new Date(endDate).toISOString()}).`,
157
+ );
158
+ }
26
159
  const format = params.format ?? "digest";
27
160
 
28
161
  const result = await apiSearchTraces({
29
162
  query: params.query,
163
+ traceIds: params.traceIds,
30
164
  filters: params.filters,
165
+ // Forwarded as itself: the filter language and the free-text query are two
166
+ // different searches, and the server combines them.
167
+ ...(params.filter ? { filter: params.filter } : {}),
31
168
  startDate,
32
169
  endDate,
33
170
  pageSize: params.pageSize ?? 25,
@@ -37,7 +174,14 @@ export async function handleSearchTraces(params: {
37
174
 
38
175
  const traces = result.traces ?? [];
39
176
  if (traces.length === 0) {
40
- return "No traces found matching your query.";
177
+ return buildEmptyResult({
178
+ query: params.query,
179
+ traceIds: params.traceIds,
180
+ spanMs: endDate - startDate,
181
+ windowWasDefaulted: params.startDate === undefined,
182
+ startDate,
183
+ endDate,
184
+ });
41
185
  }
42
186
 
43
187
  if (format === "json") {
@@ -45,50 +189,20 @@ export async function handleSearchTraces(params: {
45
189
  }
46
190
 
47
191
  const lines: string[] = [];
48
- lines.push(
49
- `Found ${result.pagination?.totalHits ?? traces.length} traces:\n`
50
- );
192
+ lines.push(`Found ${result.pagination?.totalHits ?? traces.length} traces:\n`);
51
193
 
52
194
  for (const trace of traces) {
53
- lines.push(`### Trace: ${trace.trace_id}`);
54
-
55
- if (trace.formatted_trace) {
56
- lines.push(trace.formatted_trace);
57
- } else {
58
- const inputStr = trace.input?.value
59
- ? String(trace.input.value)
60
- : "N/A";
61
- const outputStr = trace.output?.value
62
- ? String(trace.output.value)
63
- : "N/A";
64
- lines.push(
65
- `- **Input**: ${inputStr.slice(0, 100)}${inputStr.length > 100 ? "..." : ""}`
66
- );
67
- lines.push(
68
- `- **Output**: ${outputStr.slice(0, 100)}${outputStr.length > 100 ? "..." : ""}`
69
- );
70
- }
71
-
72
- if (trace.timestamps) {
73
- lines.push(`- **Time**: ${trace.timestamps.started_at || "N/A"}`);
74
- }
75
- if (trace.error) {
76
- lines.push(`- **Error**: ${JSON.stringify(trace.error)}`);
77
- }
78
- if (trace.evaluations && trace.evaluations.length > 0) {
79
- lines.push(...formatEvaluationLines(trace.evaluations));
80
- }
81
- lines.push("");
195
+ lines.push(...traceLines(trace));
82
196
  }
83
197
 
84
198
  if (result.pagination?.scrollId) {
85
199
  lines.push(
86
- `\n**More results available.** Use scrollId: "${result.pagination.scrollId}" to get next page.`
200
+ `\n**More results available.** Use scrollId: "${result.pagination.scrollId}" to get next page.`,
87
201
  );
88
202
  }
89
203
 
90
204
  lines.push(
91
- '\n> Tip: Use `get_trace` with a trace_id for full details. Use `search_traces` with `format: "json"` for raw data. Use `discover_schema` to see available filter fields.'
205
+ '\n> Tip: Use `get_trace` with a traceId for full details. Use `search_traces` with `format: "json"` for raw data. Use `discover_schema` to see available filter fields.',
92
206
  );
93
207
 
94
208
  return lines.join("\n");
@@ -1,10 +1,8 @@
1
- import { setModelProvider as apiSetModelProvider } from "../langwatch-api-model-providers.js";
1
+ import { setModelProvider as apiSetModelProvider } from "../langwatch-api-model-providers.ts";
2
2
 
3
3
  /**
4
- * Handles the platform_set_model_provider MCP tool invocation.
5
- *
6
- * Creates or updates a model provider configuration, including API keys.
7
- * Returns confirmation with the updated provider status.
4
+ * Handles the platform_set_model_provider MCP tool: creates or updates
5
+ * a provider config (including API keys) and returns its status.
8
6
  */
9
7
  export async function handleSetModelProvider(params: {
10
8
  provider: string;
@@ -18,7 +16,7 @@ export async function handleSetModelProvider(params: {
18
16
 
19
17
  if (!updated) {
20
18
  throw new Error(
21
- `Model provider "${params.provider}" was not found in the response. The provider name may be invalid.`
19
+ `Model provider "${params.provider}" was not found in the response. The provider name may be invalid.`,
22
20
  );
23
21
  }
24
22
 
@@ -1,4 +1,4 @@
1
- import { testAgent as apiTestAgent } from "../langwatch-api-agents.js";
1
+ import { testAgent as apiTestAgent } from "../langwatch-api-agents.ts";
2
2
 
3
3
  /**
4
4
  * Handles the platform_test_agent MCP tool invocation.
@@ -8,7 +8,7 @@ import { testAgent as apiTestAgent } from "../langwatch-api-agents.js";
8
8
  export async function handleTestAgent(params: { id: string }): Promise<string> {
9
9
  const run = await apiTestAgent(params.id);
10
10
  return [
11
- "Test run scheduled. The user sends \"ping\"; the run succeeds when the agent answers.",
11
+ 'Test run scheduled. The user sends "ping"; the run succeeds when the agent answers.',
12
12
  "",
13
13
  `**Scenario run ID:** ${run.scenarioRunId}`,
14
14
  `**Batch run ID:** ${run.batchRunId}`,
@@ -1,4 +1,4 @@
1
- import { updateAgent as apiUpdateAgent } from "../langwatch-api-agents.js";
1
+ import { updateAgent as apiUpdateAgent } from "../langwatch-api-agents.ts";
2
2
 
3
3
  export async function handleUpdateAgent(params: {
4
4
  id: string;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * `update_dashboard_widget`: the widget must sit on the named dashboard, so an agent never edits
3
+ * one it found elsewhere by mistake.
4
+ * Spec: modules/dashboard/specs/dashboard-widget-mcp.feature
5
+ */
6
+
7
+ import type { DashboardWidget } from "../langwatch-api-dashboard-widgets.js";
8
+ import { getWidgetOnDashboard, updateWidgetOnDashboard } from "../langwatch-api-dashboards.js";
9
+ import { LangWatchApiError } from "../langwatch-api.js";
10
+ import type { WidgetSource } from "../schemas/widget-sources.js";
11
+ import {
12
+ type DashboardWidgetQueriesInput,
13
+ normalizeDashboardWidgetQueries,
14
+ withSources,
15
+ } from "./dashboard-widget-queries.js";
16
+
17
+ export interface UpdateDashboardWidgetParams {
18
+ dashboardId: string;
19
+ widgetId: string;
20
+ name?: string;
21
+ code?: string;
22
+ queries?: DashboardWidgetQueriesInput;
23
+ description?: string;
24
+ /** Set on every query; alone, it is sent with the widget's stored queries. */
25
+ sources?: WidgetSource[] | null;
26
+ }
27
+
28
+ export async function handleUpdateDashboardWidget(
29
+ params: UpdateDashboardWidgetParams,
30
+ ): Promise<string> {
31
+ const { dashboardId, widgetId, name, code, description, sources } = params;
32
+ const fields = [name, code, params.queries, description, sources];
33
+ if (fields.every((field) => field === undefined)) {
34
+ throw new Error(
35
+ "Provide at least one of name, code, queries, description or sources to change.",
36
+ );
37
+ }
38
+
39
+ const current = await widgetOnDashboardOrRefused({ widgetId, dashboardId });
40
+ const given =
41
+ params.queries === undefined
42
+ ? undefined
43
+ : normalizeDashboardWidgetQueries({ queries: params.queries });
44
+ // Sources alone: the stored queries go back with the new list on each.
45
+ const base = given ?? (sources === undefined ? undefined : current.definition.queries);
46
+ const queries = base === undefined ? undefined : withSources({ queries: base, sources });
47
+
48
+ const changes = {
49
+ ...(name === undefined ? {} : { name }),
50
+ ...(code === undefined ? {} : { code }),
51
+ ...(queries === undefined ? {} : { queries }),
52
+ ...(description === undefined ? {} : { description }),
53
+ };
54
+
55
+ const widget = await updateWidgetOnDashboard({ dashboardId, widgetId: current.id, ...changes });
56
+
57
+ return [
58
+ `Widget "${widget.name}" updated on dashboard "${dashboardId}".`,
59
+ `**Widget ID**: ${widget.id}`,
60
+ `**Queries**: ${widget.definition.queries.map((query) => query.name).join(", ") || "(none)"}`,
61
+ "",
62
+ "```json",
63
+ JSON.stringify(widget, null, 2),
64
+ "```",
65
+ ].join("\n");
66
+ }
67
+
68
+ /** The widget, refused by id when it is not on this dashboard (the dashboard route answers 404). */
69
+ async function widgetOnDashboardOrRefused({
70
+ widgetId,
71
+ dashboardId,
72
+ }: {
73
+ widgetId: string;
74
+ dashboardId: string;
75
+ }): Promise<DashboardWidget> {
76
+ try {
77
+ return await getWidgetOnDashboard({ dashboardId, widgetId });
78
+ } catch (error) {
79
+ if (error instanceof LangWatchApiError && error.status === 404) {
80
+ throw new Error(
81
+ `No widget with ID "${widgetId}" was found on dashboard "${dashboardId}". Use the widget ID add_dashboard_widget returned, and the dashboard it was added to.`,
82
+ );
83
+ }
84
+ throw error;
85
+ }
86
+ }
@@ -1,4 +1,4 @@
1
- import { updateDatasetRecord as apiUpdateDatasetRecord } from "../langwatch-api-datasets.js";
1
+ import { updateDatasetRecord as apiUpdateDatasetRecord } from "../langwatch-api-datasets.ts";
2
2
 
3
3
  /**
4
4
  * Handles the platform_update_dataset_record MCP tool invocation.
@@ -1,12 +1,10 @@
1
- import { updateDataset as apiUpdateDataset } from "../langwatch-api-datasets.js";
2
- import type { DatasetColumnType } from "../langwatch-api-datasets.js";
3
- import { formatDatasetMutationDetails } from "./format-dataset-mutation.js";
1
+ import { updateDataset as apiUpdateDataset } from "../langwatch-api-datasets.ts";
2
+ import type { DatasetColumnType } from "../langwatch-api-datasets.ts";
3
+ import { formatDatasetMutationDetails } from "./format-dataset-mutation.ts";
4
4
 
5
5
  /**
6
- * Handles the platform_update_dataset MCP tool invocation.
7
- *
8
- * Updates an existing dataset and returns a confirmation
9
- * with the updated details.
6
+ * Handles the platform_update_dataset MCP tool: updates a dataset and
7
+ * returns a confirmation with the updated details.
10
8
  */
11
9
  export async function handleUpdateDataset(params: {
12
10
  slugOrId: string;
@@ -1,13 +1,11 @@
1
1
  import {
2
2
  updateEvaluator as apiUpdateEvaluator,
3
3
  getEvaluatorType,
4
- } from "../langwatch-api-evaluators.js";
4
+ } from "../langwatch-api-evaluators.ts";
5
5
 
6
6
  /**
7
- * Handles the platform_update_evaluator MCP tool invocation.
8
- *
9
- * Updates an existing evaluator and returns a confirmation
10
- * with the updated details.
7
+ * Handles the platform_update_evaluator MCP tool: updates an evaluator
8
+ * and returns a confirmation with the updated details.
11
9
  */
12
10
  export async function handleUpdateEvaluator(params: {
13
11
  evaluatorId: string;
@@ -1,4 +1,4 @@
1
- import { updateProject as apiUpdateProject } from "../langwatch-api-projects.js";
1
+ import { updateProject as apiUpdateProject } from "../langwatch-api-projects.ts";
2
2
 
3
3
  export async function handleUpdateProject(params: {
4
4
  id: string;
@@ -4,25 +4,13 @@ import {
4
4
  updatePrompt as apiUpdatePrompt,
5
5
  type PromptDetailResponse,
6
6
  type PromptTag,
7
- } from "../langwatch-api.js";
7
+ } from "../langwatch-api.ts";
8
8
 
9
- /**
10
- * Handles the platform_update_prompt MCP tool invocation.
11
- *
12
- * Updates an existing prompt via the PUT endpoint. Every update with a
13
- * commitMessage creates a new version automatically. The mutation response
14
- * does not carry the tags the server actually applied, so this re-fetches
15
- * the prompt via getPrompt: the GET response is the prompt's latest version
16
- * flattened to the top level (version, versionId, commitMessage) plus a
17
- * `tags` array of { name, versionId } naming which version each tag points
18
- * to. The new version is identified by matching the request's commitMessage
19
- * against that top level (falling back to the versions listing), and
20
- * deployment state is derived from the tags that point at it — never from
21
- * the request's tags directly.
22
- */
9
+ // Updates a prompt via PUT, creating a new version. Re-fetches the full prompt
10
+ // to get tags since the mutation response doesn't include them.
23
11
  export async function handleUpdatePrompt(params: {
24
12
  idOrHandle: string;
25
- messages?: Array<{ role: string; content: string }>;
13
+ messages?: { role: string; content: string }[];
26
14
  model?: string;
27
15
  commitMessage: string;
28
16
  tags?: string[];
@@ -51,10 +39,9 @@ interface IdentifiedVersion {
51
39
  }
52
40
 
53
41
  /**
54
- * Finds the version created by this update. The GET detail response IS the
55
- * latest version, so a top-level commitMessage match identifies it directly;
56
- * otherwise (e.g. a concurrent update landed after ours) the versions
57
- * listing is consulted, best-effort.
42
+ * Finds the version created by this update. The GET detail response IS
43
+ * the latest version, so a commitMessage match identifies it directly;
44
+ * otherwise the versions listing is consulted, best-effort.
58
45
  */
59
46
  async function identifyNewVersion({
60
47
  idOrHandle,
@@ -71,7 +58,7 @@ async function identifyNewVersion({
71
58
  try {
72
59
  const versions = await apiGetPromptVersions(idOrHandle);
73
60
  const match = (Array.isArray(versions) ? versions : []).find(
74
- (v) => v.commitMessage === commitMessage
61
+ (v) => v.commitMessage === commitMessage,
75
62
  );
76
63
  if (match) return { version: match.version, versionId: match.versionId };
77
64
  } catch {
@@ -85,6 +72,36 @@ function deploymentTagsOf(prompt: PromptDetailResponse): PromptTag[] {
85
72
  return (prompt.tags ?? []).filter((tag) => tag?.name !== "latest");
86
73
  }
87
74
 
75
+ function deploymentLines({
76
+ prompt,
77
+ newVersion,
78
+ }: {
79
+ prompt: PromptDetailResponse;
80
+ newVersion: IdentifiedVersion;
81
+ }): string[] {
82
+ const allDeployments = deploymentTagsOf(prompt);
83
+ const newTags = allDeployments
84
+ .filter((tag) => newVersion.versionId != null && tag.versionId === newVersion.versionId)
85
+ .map((tag) => tag.name);
86
+ if (newTags.length > 0) {
87
+ return [`**Deployed to**: ${newTags.join(", ")}`];
88
+ }
89
+ const lines = [`**Deployment**: not deployed`];
90
+
91
+ // Tags pointing at other versions are untouched by this update —
92
+ // surface them on their own line so no line pairs a version number
93
+ // with a deployment tag name.
94
+ const otherTags = Array.from(
95
+ new Set(
96
+ allDeployments.filter((tag) => tag.versionId !== newVersion.versionId).map((tag) => tag.name),
97
+ ),
98
+ );
99
+ if (otherTags.length > 0) {
100
+ lines.push(`**Existing deployments (untouched)**: ${otherTags.join(", ")}`);
101
+ }
102
+ return lines;
103
+ }
104
+
88
105
  async function renderUpdateSuccess({
89
106
  idOrHandle,
90
107
  params,
@@ -109,7 +126,7 @@ async function renderUpdateSuccess({
109
126
  if (updated?.handle) lines.push(`**Handle**: ${updated.handle}`);
110
127
  lines.push(`**Commit**: ${params.commitMessage}`);
111
128
  lines.push(
112
- `**Note**: the update succeeded, but version and deployment details are unavailable (confirmation read failed). Run platform_get_prompt to inspect the current state. Do not retry the update.`
129
+ `**Note**: the update succeeded, but version and deployment details are unavailable (confirmation read failed). Run platform_get_prompt to inspect the current state. Do not retry the update.`,
113
130
  );
114
131
  return lines.join("\n");
115
132
  }
@@ -124,10 +141,8 @@ async function renderUpdateSuccess({
124
141
  lines.push("Prompt updated successfully!\n");
125
142
  if (prompt.id) lines.push(`**ID**: ${prompt.id}`);
126
143
  if (prompt.handle) lines.push(`**Handle**: ${prompt.handle}`);
127
- if (newVersion?.version != null)
128
- lines.push(`**Version**: v${newVersion.version}`);
129
- if (newVersion?.versionId)
130
- lines.push(`**Version ID**: ${newVersion.versionId}`);
144
+ if (newVersion?.version != null) lines.push(`**Version**: v${newVersion.version}`);
145
+ if (newVersion?.versionId) lines.push(`**Version ID**: ${newVersion.versionId}`);
131
146
  lines.push(`**Commit**: ${params.commitMessage}`);
132
147
 
133
148
  if (!newVersion) {
@@ -135,40 +150,12 @@ async function renderUpdateSuccess({
135
150
  // version by commit message — say so instead of silently omitting the
136
151
  // version and deployment lines.
137
152
  lines.push(
138
- `**Note**: update succeeded, but the new version could not be identified in the re-fetched prompt — version and deployment details are unavailable. Run platform_get_prompt to inspect the current state.`
153
+ `**Note**: update succeeded, but the new version could not be identified in the re-fetched prompt — version and deployment details are unavailable. Run platform_get_prompt to inspect the current state.`,
139
154
  );
140
155
  }
141
156
 
142
157
  if (newVersion) {
143
- const allDeployments = deploymentTagsOf(prompt);
144
- const newTags = allDeployments
145
- .filter(
146
- (tag) =>
147
- newVersion.versionId != null &&
148
- tag.versionId === newVersion.versionId
149
- )
150
- .map((tag) => tag.name);
151
- if (newTags.length > 0) {
152
- lines.push(`**Deployed to**: ${newTags.join(", ")}`);
153
- } else {
154
- lines.push(`**Deployment**: not deployed`);
155
-
156
- // Tags pointing at other versions are untouched by this update —
157
- // surface them on their own line so no line pairs a version number
158
- // with a deployment tag name.
159
- const otherTags = Array.from(
160
- new Set(
161
- allDeployments
162
- .filter((tag) => tag.versionId !== newVersion.versionId)
163
- .map((tag) => tag.name)
164
- )
165
- );
166
- if (otherTags.length > 0) {
167
- lines.push(
168
- `**Existing deployments (untouched)**: ${otherTags.join(", ")}`
169
- );
170
- }
171
- }
158
+ lines.push(...deploymentLines({ prompt, newVersion }));
172
159
  }
173
160
 
174
161
  return lines.join("\n");
@@ -203,9 +190,7 @@ async function renderTagFailure({
203
190
  if (matched) {
204
191
  const lines: string[] = [];
205
192
  lines.push("Prompt update partially failed.\n");
206
- lines.push(
207
- "A new version was created, but assigning the requested tag(s) failed."
208
- );
193
+ lines.push("A new version was created, but assigning the requested tag(s) failed.");
209
194
  if (matched.versionId) lines.push(`**Version ID**: ${matched.versionId}`);
210
195
  lines.push(`**Status**: created, untagged`);
211
196
  lines.push(`**Failed tag(s)**: ${failedTags}`);
@@ -1,12 +1,10 @@
1
- import { updateScenario as apiUpdateScenario } from "../langwatch-api-scenarios.js";
2
- import type { ScenarioFieldValues } from "../schemas/suite-fields.js";
3
- import { formatScenarioFields } from "./format-scenario.js";
1
+ import { updateScenario as apiUpdateScenario } from "../langwatch-api-scenarios.ts";
2
+ import type { ScenarioFieldValues } from "../schemas/suite-fields.ts";
3
+ import { formatScenarioFields } from "./format-scenario.ts";
4
4
 
5
5
  /**
6
- * Handles the platform_update_scenario MCP tool invocation.
7
- *
8
- * Updates an existing scenario and returns a confirmation
9
- * with the updated details.
6
+ * Handles the platform_update_scenario MCP tool: updates a scenario and
7
+ * returns a confirmation with the updated details.
10
8
  */
11
9
  export async function handleUpdateScenario(params: {
12
10
  scenarioId: string;
@@ -1,20 +1,15 @@
1
- import { updateTestSuite as apiUpdateTestSuite } from "../langwatch-api-test-suites.js";
1
+ import { updateTestSuite as apiUpdateTestSuite } from "../langwatch-api-test-suites.ts";
2
2
  import {
3
3
  type EvaluatorAttachmentInput,
4
4
  type SuiteField,
5
5
  toWireAttachments,
6
- } from "../schemas/suite-fields.js";
7
- import {
8
- formatEvaluatorAttachments,
9
- formatSuiteFields,
10
- } from "./format-suite-details.js";
6
+ } from "../schemas/suite-fields.ts";
7
+ import { formatEvaluatorAttachments, formatSuiteFields } from "./format-suite-details.ts";
11
8
 
12
9
  /**
13
- * Handles the platform_update_test_suite MCP tool invocation.
14
- *
15
- * Any of the name, the fields and the evaluators. A field list or an
16
- * evaluator list replaces the one the suite holds; a key left out keeps
17
- * what the suite has.
10
+ * Handles the platform_update_test_suite MCP tool: updates any of name,
11
+ * fields and evaluators. A field or evaluator list replaces what the
12
+ * suite holds; a key left out keeps its current value.
18
13
  */
19
14
  export async function handleUpdateTestSuite(params: {
20
15
  id: string;
@@ -24,7 +24,7 @@ export function parseRelativeDate(input: string): number {
24
24
  const parsed = Date.parse(input);
25
25
  if (Number.isNaN(parsed)) {
26
26
  throw new Error(
27
- `Invalid date: "${input}". Use a relative duration (e.g. "24h", "7d", "4w") or an ISO date string.`
27
+ `Invalid date: "${input}". Use a relative duration (e.g. "24h", "7d", "4w") or an ISO date string.`,
28
28
  );
29
29
  }
30
30
  return parsed;
@@ -1,12 +1,7 @@
1
1
  /**
2
- * Escapes characters that would break markdown table formatting.
3
- *
4
- * Replaces pipe characters (`|`) with `\|` and newlines with spaces
5
- * so that values can be safely embedded in markdown tables and headers.
2
+ * Escapes characters that would break markdown table formatting:
3
+ * replaces `|` with `\|` and newlines with spaces.
6
4
  */
7
5
  export function escapeMarkdown(value: string): string {
8
- return value
9
- .replace(/\\/g, "\\\\")
10
- .replace(/\|/g, "\\|")
11
- .replace(/\n/g, " ");
6
+ return value.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\n/g, " ");
12
7
  }