@langwatch/mcp-server 3.0.0 → 3.1.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 (209) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/{add-dashboard-widget-MJHIC3CC.js → add-dashboard-widget-3IE3W5RR.js} +8 -7
  3. package/dist/{add-dashboard-widget-55UI6H22.js → add-dashboard-widget-XNAIGV37.js} +8 -7
  4. package/dist/{archive-project-L4PAKT34.js → archive-project-LAWWNKTX.js} +3 -3
  5. package/dist/{archive-project-K5UD7A6X.js → archive-project-X64627XS.js} +3 -3
  6. package/dist/{archive-run-plan-AOKNYQIO.js → archive-run-plan-3HKFL5MS.js} +3 -3
  7. package/dist/{archive-run-plan-5HSQG2HX.js → archive-run-plan-C35EJACZ.js} +3 -3
  8. package/dist/{archive-scenario-5IJQESHH.js → archive-scenario-3DOXHOJJ.js} +3 -3
  9. package/dist/{archive-scenario-2CWJW2VD.js → archive-scenario-7KDGEZM5.js} +3 -3
  10. package/dist/{archive-test-suite-OPB7NFI7.js → archive-test-suite-KZOESY2Y.js} +3 -3
  11. package/dist/{archive-test-suite-ZC3TN6VH.js → archive-test-suite-RPJ6ZKBV.js} +3 -3
  12. package/dist/{assign-prompt-tag-6DDE6ZZ5.js → assign-prompt-tag-2A25CXB7.js} +2 -2
  13. package/dist/{assign-prompt-tag-D7O23MJM.js → assign-prompt-tag-TQRV6D6V.js} +2 -2
  14. package/dist/{chunk-HLQJXUR6.js → chunk-27SS5FBC.js} +2 -2
  15. package/dist/{chunk-MOCU5XWF.js → chunk-2RLDGMPZ.js} +2 -2
  16. package/dist/{chunk-YCIUEZVK.js → chunk-3GVTJ7NK.js} +2 -2
  17. package/dist/{chunk-WCKZDOGF.js → chunk-6DF65T3B.js} +11 -6
  18. package/dist/{chunk-AASW2TO2.js → chunk-6OLI3LFY.js} +2 -2
  19. package/dist/{chunk-D2HS73VI.js → chunk-7HJSQOSZ.js} +2 -2
  20. package/dist/{chunk-7CZQDZ2K.js → chunk-7MNQDTKJ.js} +38 -26
  21. package/dist/{chunk-7GETGE6B.js → chunk-BHCYKMRH.js} +2 -2
  22. package/dist/{chunk-QXLMHLRC.js → chunk-FSU2ZBUM.js} +2 -2
  23. package/dist/{chunk-KILVK3FS.js → chunk-I2Z5CBOU.js} +2 -2
  24. package/dist/{chunk-R5YJIYPF.js → chunk-JEMUBKLJ.js} +130 -109
  25. package/dist/{chunk-XQYH52SI.js → chunk-JOFSQFCN.js} +2 -2
  26. package/dist/{chunk-4RX3G62A.js → chunk-JQN3VXPH.js} +3 -3
  27. package/dist/{chunk-B4RFWIUP.js → chunk-LXBQK3J3.js} +2 -2
  28. package/dist/{chunk-RFC2SBEX.js → chunk-MQRTYXHJ.js} +2 -2
  29. package/dist/{chunk-EYPJBL7P.js → chunk-P2JRKSYI.js} +3 -3
  30. package/dist/{chunk-VOUGDY2O.js → chunk-QF7ZGYVI.js} +2 -2
  31. package/dist/{chunk-SHSVN3SE.js → chunk-QTAHHJH3.js} +2 -2
  32. package/dist/{chunk-O2WGVCED.js → chunk-SLRQHMJZ.js} +2 -2
  33. package/dist/{chunk-GA5JUSPT.js → chunk-YQWZ4CDN.js} +5 -3
  34. package/dist/{create-agent-IRZOU4R5.js → create-agent-IE7Q2Z4C.js} +3 -3
  35. package/dist/{create-agent-6JNLMYQD.js → create-agent-JMCQ5WZC.js} +3 -3
  36. package/dist/{create-analytics-report-N4L4V5QL.js → create-analytics-report-4X5N7EOT.js} +3 -3
  37. package/dist/{create-analytics-report-QEHXG7FU.js → create-analytics-report-IKWZRS2O.js} +3 -3
  38. package/dist/{create-annotation-CCEGIZ67.js → create-annotation-IZ53SJOX.js} +3 -3
  39. package/dist/{create-annotation-DTHCMWHB.js → create-annotation-JR6DBHPW.js} +3 -3
  40. package/dist/{create-api-key-JPEUIXGM.js → create-api-key-IKMOTWCD.js} +3 -3
  41. package/dist/{create-api-key-JKM2DSZO.js → create-api-key-YUDAGOWL.js} +3 -3
  42. package/dist/{create-dataset-WON4SOTC.js → create-dataset-54FJCX45.js} +3 -3
  43. package/dist/{create-dataset-DJNXYJ5B.js → create-dataset-ONX3RADL.js} +3 -3
  44. package/dist/{create-dataset-records-UJBW3C7C.js → create-dataset-records-HPLMFDJY.js} +3 -3
  45. package/dist/{create-dataset-records-TMEOTLTO.js → create-dataset-records-QZZZF64Z.js} +3 -3
  46. package/dist/{create-evaluator-N5AEHI4K.js → create-evaluator-I5I52HOQ.js} +3 -3
  47. package/dist/{create-evaluator-XYNY2YFY.js → create-evaluator-L66QGSDX.js} +3 -3
  48. package/dist/create-mcp-server.cjs +96 -41
  49. package/dist/create-mcp-server.js +129 -108
  50. package/dist/{create-project-YL345T5L.js → create-project-UPZGETN5.js} +3 -3
  51. package/dist/{create-project-EY4XZ7TH.js → create-project-Y5EGJKDG.js} +3 -3
  52. package/dist/{create-prompt-ZUMQHHX7.js → create-prompt-RNUJOL25.js} +2 -2
  53. package/dist/{create-prompt-JZQNQ7I3.js → create-prompt-WGQLJASD.js} +2 -2
  54. package/dist/{create-prompt-tag-JFP2Q3PO.js → create-prompt-tag-3ZCA7M7O.js} +2 -2
  55. package/dist/{create-prompt-tag-CJ5FZ436.js → create-prompt-tag-R6KIAZTB.js} +2 -2
  56. package/dist/{create-scenario-S6OWWKJO.js → create-scenario-WIMKZLQO.js} +3 -3
  57. package/dist/{create-scenario-CQU2SSFB.js → create-scenario-WO5NWXVQ.js} +3 -3
  58. package/dist/{create-test-suite-Y7P2RI4L.js → create-test-suite-AVSR7IIM.js} +3 -3
  59. package/dist/{create-test-suite-OLGCAGJA.js → create-test-suite-LRKCNIJA.js} +3 -3
  60. package/dist/{create-trigger-RQ653WYF.js → create-trigger-CBO2XDYC.js} +3 -3
  61. package/dist/{create-trigger-4CNBTISJ.js → create-trigger-M3VFK5UH.js} +3 -3
  62. package/dist/{dashboards-BA7M6CMO.js → dashboards-4X6QUT3E.js} +3 -3
  63. package/dist/{dashboards-U663GUIB.js → dashboards-CX2T6RKH.js} +3 -3
  64. package/dist/{delete-agent-J2Q4DRZ2.js → delete-agent-QUVDMSOC.js} +3 -3
  65. package/dist/{delete-agent-ZAU4LTXB.js → delete-agent-Y4QTEQ3B.js} +3 -3
  66. package/dist/{delete-analytics-report-YUYLDHLL.js → delete-analytics-report-T4GIMEOA.js} +3 -3
  67. package/dist/{delete-analytics-report-QK6X7P4S.js → delete-analytics-report-WIP24EXV.js} +3 -3
  68. package/dist/{delete-annotation-KJOCDLV3.js → delete-annotation-BWO5ZEZY.js} +3 -3
  69. package/dist/{delete-annotation-7X4NYXXM.js → delete-annotation-ESUH3RWN.js} +3 -3
  70. package/dist/{delete-dataset-NXP7ZPPV.js → delete-dataset-N4AEYIAA.js} +3 -3
  71. package/dist/{delete-dataset-RUTZBBVD.js → delete-dataset-ZRD23FLO.js} +3 -3
  72. package/dist/{delete-dataset-records-75UAR5IS.js → delete-dataset-records-HC7VLBT7.js} +3 -3
  73. package/dist/{delete-dataset-records-4Z7DZCDW.js → delete-dataset-records-XC2DFVXD.js} +3 -3
  74. package/dist/{delete-evaluator-RI4GALGX.js → delete-evaluator-27P5XLNV.js} +3 -3
  75. package/dist/{delete-evaluator-E3CUNGTQ.js → delete-evaluator-LJII4YLC.js} +3 -3
  76. package/dist/{delete-prompt-tag-S4KBZTNG.js → delete-prompt-tag-DH7IQO4X.js} +2 -2
  77. package/dist/{delete-prompt-tag-LE3WJPKS.js → delete-prompt-tag-OC57CN32.js} +2 -2
  78. package/dist/{delete-workflow-PWQPDW6H.js → delete-workflow-I4IXK3ZL.js} +3 -3
  79. package/dist/{delete-workflow-4CZFIQCQ.js → delete-workflow-JXREDDW7.js} +3 -3
  80. package/dist/{discover-schema-7WHIIATI.js → discover-schema-ME5BAD2S.js} +3 -3
  81. package/dist/{discover-schema-J2ANOBKO.js → discover-schema-OHYBG3CY.js} +3 -3
  82. package/dist/{get-agent-5T3CXQOR.js → get-agent-6GKIKKL7.js} +3 -3
  83. package/dist/{get-agent-ZKYQJUQ7.js → get-agent-UKZUBVPB.js} +3 -3
  84. package/dist/{get-analytics-4MPEK4KV.js → get-analytics-TI2U3JLA.js} +2 -2
  85. package/dist/{get-analytics-ZLI3A4F5.js → get-analytics-ZGQ4LY3I.js} +2 -2
  86. package/dist/{get-analytics-report-JCKYMA2S.js → get-analytics-report-PD6XZ4ZA.js} +3 -3
  87. package/dist/{get-analytics-report-SKIP2JWH.js → get-analytics-report-QMXNQ7VA.js} +3 -3
  88. package/dist/{get-dataset-APGZBYMH.js → get-dataset-5QORNVOZ.js} +3 -3
  89. package/dist/{get-dataset-LWXDVMVE.js → get-dataset-E5WLIPNK.js} +3 -3
  90. package/dist/{get-evaluator-3A7BJBAB.js → get-evaluator-GYQFB4F3.js} +3 -3
  91. package/dist/{get-evaluator-IWNJINRY.js → get-evaluator-QQV65MQB.js} +3 -3
  92. package/dist/{get-project-RK6AJTEP.js → get-project-43SGQCAT.js} +3 -3
  93. package/dist/{get-project-EQVB4LEL.js → get-project-W5DCKXZP.js} +3 -3
  94. package/dist/{get-prompt-TLG2T2DS.js → get-prompt-IUTPSRRI.js} +2 -2
  95. package/dist/{get-prompt-ZER557X3.js → get-prompt-ZTCWGYJV.js} +2 -2
  96. package/dist/{get-run-plan-PEHRO5M3.js → get-run-plan-M3LVXMGO.js} +3 -3
  97. package/dist/{get-run-plan-5X7DDJRN.js → get-run-plan-MEPEU353.js} +3 -3
  98. package/dist/{get-scenario-UQX45ZZO.js → get-scenario-2DM4XR44.js} +3 -3
  99. package/dist/{get-scenario-375W5D6I.js → get-scenario-D6EPSSPW.js} +3 -3
  100. package/dist/{get-simulation-run-QZTLGL7W.js → get-simulation-run-53WM2XOO.js} +3 -3
  101. package/dist/{get-simulation-run-2NBXJADG.js → get-simulation-run-RKQ52TKP.js} +3 -3
  102. package/dist/{get-test-suite-OODIR3RI.js → get-test-suite-DP2HNOQZ.js} +3 -3
  103. package/dist/{get-test-suite-GVIBDG7K.js → get-test-suite-MUSY2CDJ.js} +3 -3
  104. package/dist/{get-trace-AGCHVPJK.js → get-trace-5Z2BIZ3V.js} +2 -2
  105. package/dist/{get-trace-KJLYAZRC.js → get-trace-THPWSLD3.js} +2 -2
  106. package/dist/{get-workflow-7LZSVPP2.js → get-workflow-63E7BNLY.js} +3 -3
  107. package/dist/{get-workflow-3TV2YYC5.js → get-workflow-R6XUKTZ7.js} +3 -3
  108. package/dist/{http-server-7CCN3EHJ.js → http-server-4JHSQN56.js} +5 -5
  109. package/dist/index.js +112 -44
  110. package/dist/{langwatch-api-analytics-reports-6CF6KUET.js → langwatch-api-analytics-reports-IIHGTTQA.js} +3 -3
  111. package/dist/{langwatch-api-analytics-reports-RPFB5AO5.js → langwatch-api-analytics-reports-IQ6CHM5Y.js} +3 -3
  112. package/dist/{langwatch-api-annotations-H4AI4TKG.js → langwatch-api-annotations-CN2KYV3Z.js} +3 -3
  113. package/dist/{langwatch-api-annotations-QSJNUQQS.js → langwatch-api-annotations-CRI6JTQR.js} +3 -3
  114. package/dist/{langwatch-api-monitors-ENHLOL3S.js → langwatch-api-monitors-66O5Z5LB.js} +2 -2
  115. package/dist/{langwatch-api-monitors-OHSGADTH.js → langwatch-api-monitors-GNHQRPMR.js} +2 -2
  116. package/dist/{langwatch-api-secrets-AGW6UUMD.js → langwatch-api-secrets-B7BURV76.js} +2 -2
  117. package/dist/{langwatch-api-secrets-CLTS766Q.js → langwatch-api-secrets-P6SHZOHE.js} +2 -2
  118. package/dist/{langwatch-api-triggers-G5UWFNN2.js → langwatch-api-triggers-6FR4VWDL.js} +3 -3
  119. package/dist/{langwatch-api-triggers-QMR7KEXW.js → langwatch-api-triggers-VKNGXSJH.js} +3 -3
  120. package/dist/{langwatch-api-workflows-HKTBIKKY.js → langwatch-api-workflows-22RQFYO7.js} +3 -3
  121. package/dist/{langwatch-api-workflows-OMROZH2O.js → langwatch-api-workflows-KDACD36L.js} +3 -3
  122. package/dist/{list-agents-MG24MHZE.js → list-agents-SVXWLLO7.js} +3 -3
  123. package/dist/{list-agents-BYWDNAHT.js → list-agents-XM5JNCVK.js} +3 -3
  124. package/dist/{list-analytics-reports-G3EPWGSQ.js → list-analytics-reports-DEKKC6BU.js} +3 -3
  125. package/dist/{list-analytics-reports-PPWIFRES.js → list-analytics-reports-E7QFC22G.js} +3 -3
  126. package/dist/{list-annotations-Y4EUBJHG.js → list-annotations-5CGNOIKI.js} +3 -3
  127. package/dist/{list-annotations-QCLGEK5A.js → list-annotations-P26ELIAO.js} +3 -3
  128. package/dist/{list-api-keys-DAVOBPFK.js → list-api-keys-B4YL7STE.js} +3 -3
  129. package/dist/{list-api-keys-JMW5WRXX.js → list-api-keys-ZIJJH755.js} +3 -3
  130. package/dist/{list-dashboards-2P3VJFRS.js → list-dashboards-F4YJPDKD.js} +3 -3
  131. package/dist/{list-dashboards-MW5O3MKH.js → list-dashboards-XHYTXEQK.js} +3 -3
  132. package/dist/{list-dataset-records-KEHT7G6Q.js → list-dataset-records-SWCEDRPX.js} +3 -3
  133. package/dist/{list-dataset-records-KMLLMZAZ.js → list-dataset-records-YWGROVKC.js} +3 -3
  134. package/dist/{list-datasets-P3JK2ZHS.js → list-datasets-32SCF66H.js} +3 -3
  135. package/dist/{list-datasets-Z7OOE4KI.js → list-datasets-YYADWT4D.js} +3 -3
  136. package/dist/{list-evaluators-7RRESBOU.js → list-evaluators-KKQKBJKN.js} +3 -3
  137. package/dist/{list-evaluators-VATJVOHR.js → list-evaluators-V6LP6ZQA.js} +3 -3
  138. package/dist/{list-model-providers-OXDRPUCJ.js → list-model-providers-RCPVT7R4.js} +3 -3
  139. package/dist/{list-model-providers-VXQJWDXU.js → list-model-providers-TMBSB6EE.js} +3 -3
  140. package/dist/{list-projects-X72ZXVY5.js → list-projects-4Y74TFDZ.js} +3 -3
  141. package/dist/{list-projects-HUVK7L3W.js → list-projects-R4MTRF3C.js} +3 -3
  142. package/dist/{list-prompt-tags-3I3LWFIR.js → list-prompt-tags-C345AGM2.js} +2 -2
  143. package/dist/{list-prompt-tags-DRHUH2ND.js → list-prompt-tags-RITKQDC5.js} +2 -2
  144. package/dist/{list-prompts-6DX3QECJ.js → list-prompts-DSJ2LUSU.js} +2 -2
  145. package/dist/{list-prompts-PS423RU3.js → list-prompts-F7C5L5XK.js} +2 -2
  146. package/dist/{list-run-plans-6VNHINPY.js → list-run-plans-YPGLC5QG.js} +3 -3
  147. package/dist/{list-run-plans-5SXPOV3X.js → list-run-plans-ZHRZHCDL.js} +3 -3
  148. package/dist/{list-scenarios-EQWCW7Q4.js → list-scenarios-6HN72TMW.js} +3 -3
  149. package/dist/{list-scenarios-GKNH3YND.js → list-scenarios-HCYFOTSL.js} +3 -3
  150. package/dist/{list-simulation-runs-KHY7KALI.js → list-simulation-runs-BKVMQQMT.js} +3 -3
  151. package/dist/{list-simulation-runs-PUDK32C2.js → list-simulation-runs-JNST5PQU.js} +3 -3
  152. package/dist/{list-test-suites-GY56LGLY.js → list-test-suites-4ZVYYKVB.js} +3 -3
  153. package/dist/{list-test-suites-7H2DRILK.js → list-test-suites-YY4J3L7H.js} +3 -3
  154. package/dist/{list-trigger-fires-OZUF65LI.js → list-trigger-fires-3XM6YZWG.js} +3 -3
  155. package/dist/{list-trigger-fires-7RZUP54Y.js → list-trigger-fires-5C5XM2KQ.js} +3 -3
  156. package/dist/{list-triggers-XC5KMX4C.js → list-triggers-DARBIIRA.js} +3 -3
  157. package/dist/{list-triggers-BGUCUXTJ.js → list-triggers-MRSWN7RR.js} +3 -3
  158. package/dist/{list-workflows-55NYC3PC.js → list-workflows-BGUSQUJX.js} +3 -3
  159. package/dist/{list-workflows-HV7FUWZA.js → list-workflows-NXOWP3XS.js} +3 -3
  160. package/dist/{rename-prompt-tag-2I7Z5FCY.js → rename-prompt-tag-F3WT4FB4.js} +2 -2
  161. package/dist/{rename-prompt-tag-SZYTOWDX.js → rename-prompt-tag-HR5HZZI2.js} +2 -2
  162. package/dist/{rename-test-suite-CLIEPZDO.js → rename-test-suite-2ZRXG5O7.js} +3 -3
  163. package/dist/{rename-test-suite-27AYY33K.js → rename-test-suite-PWXKE7Z4.js} +3 -3
  164. package/dist/{report-issue-5HSL7CNB.js → report-issue-HG7XCPOY.js} +2 -2
  165. package/dist/{report-issue-N7ND5TM6.js → report-issue-TWRFUPGB.js} +2 -2
  166. package/dist/{rerun-run-plan-O3VUZ6CG.js → rerun-run-plan-BFRZFEJB.js} +3 -3
  167. package/dist/{rerun-run-plan-OJTVVGJI.js → rerun-run-plan-LXM3RFZC.js} +3 -3
  168. package/dist/{revoke-api-key-NZNCFOIR.js → revoke-api-key-GR55PUP4.js} +3 -3
  169. package/dist/{revoke-api-key-BU6BKGCG.js → revoke-api-key-KCDOYPUK.js} +3 -3
  170. package/dist/{run-agent-HPCGZGYW.js → run-agent-HRVRHRHI.js} +3 -3
  171. package/dist/{run-agent-244O4Y5M.js → run-agent-WS6TADJQ.js} +3 -3
  172. package/dist/{run-plan-2ZPGGZ4H.js → run-plan-G24DBB5D.js} +3 -3
  173. package/dist/{run-plan-KSXUYQT3.js → run-plan-NSXMBEC5.js} +3 -3
  174. package/dist/{run-query-BQUHIUC2.js → run-query-6YVOA5NV.js} +18 -4
  175. package/dist/{run-query-4LMOQ5UW.js → run-query-7QIYSDVI.js} +18 -4
  176. package/dist/{run-test-suite-UEOMCON6.js → run-test-suite-NTKLJZCJ.js} +3 -3
  177. package/dist/{run-test-suite-P3WLVPXC.js → run-test-suite-P33XFQ6H.js} +3 -3
  178. package/dist/{run-workflow-I4IHEN54.js → run-workflow-E5ZRSXUB.js} +3 -3
  179. package/dist/{run-workflow-EFZ6HG5B.js → run-workflow-HDF6CRLM.js} +3 -3
  180. package/dist/{search-traces-6IR7PR4L.js → search-traces-X7NSRTTP.js} +2 -2
  181. package/dist/{search-traces-BYML2NQ4.js → search-traces-XWZYOZOM.js} +2 -2
  182. package/dist/{set-model-provider-SHEVKWRC.js → set-model-provider-XJF47L6H.js} +3 -3
  183. package/dist/{set-model-provider-RBNGWFVI.js → set-model-provider-YPUCFEXG.js} +3 -3
  184. package/dist/{update-agent-ZPXWRMS2.js → update-agent-6FHGWOO7.js} +3 -3
  185. package/dist/{update-agent-PTKTM2B5.js → update-agent-VEDXQRSM.js} +3 -3
  186. package/dist/{update-dashboard-widget-IP2TTQ5G.js → update-dashboard-widget-VOKXN7JA.js} +11 -10
  187. package/dist/{update-dashboard-widget-HKCBXH7X.js → update-dashboard-widget-VUIQZ7F5.js} +11 -10
  188. package/dist/{update-dataset-IRVMY5PF.js → update-dataset-7AQ24NRS.js} +3 -3
  189. package/dist/{update-dataset-GHIN6JR3.js → update-dataset-GHKDCJJQ.js} +3 -3
  190. package/dist/{update-dataset-record-Z3L7ACNF.js → update-dataset-record-IRD6FH2C.js} +3 -3
  191. package/dist/{update-dataset-record-6VI7K2CL.js → update-dataset-record-ZZUPG7AS.js} +3 -3
  192. package/dist/{update-evaluator-5NLNE6VY.js → update-evaluator-O6EJFTQJ.js} +3 -3
  193. package/dist/{update-evaluator-FEH7H6NS.js → update-evaluator-PUJFU5LT.js} +3 -3
  194. package/dist/{update-project-QPR3QX55.js → update-project-HO53IHXC.js} +3 -3
  195. package/dist/{update-project-75H3LDQT.js → update-project-VTVU6KNP.js} +3 -3
  196. package/dist/{update-prompt-BCDFTNLK.js → update-prompt-FABVQCAC.js} +2 -2
  197. package/dist/{update-prompt-NPRXYSWA.js → update-prompt-MNRLCLBA.js} +2 -2
  198. package/dist/{update-scenario-EM5XGMB7.js → update-scenario-MQZZM5CP.js} +3 -3
  199. package/dist/{update-scenario-BNOMDCMV.js → update-scenario-XIZNUH4I.js} +3 -3
  200. package/package.json +1 -1
  201. package/src/create-mcp-server.ts +18 -1
  202. package/src/langwatch-api-dashboard-widgets.ts +1 -0
  203. package/src/langwatch-api-query.ts +6 -0
  204. package/src/langwatch-api.ts +50 -27
  205. package/src/schemas/widget-sources.ts +36 -0
  206. package/src/tools/add-dashboard-widget.ts +5 -2
  207. package/src/tools/dashboard-widget-queries.ts +13 -4
  208. package/src/tools/run-query.ts +23 -1
  209. package/src/tools/update-dashboard-widget.ts +9 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langwatch/mcp-server",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "An MCP server for Langwatch.",
5
5
  "license": "MIT",
6
6
  "author": "",
@@ -28,7 +28,11 @@ import {
28
28
  triggerActionSchema,
29
29
  validateActionParamsForAction,
30
30
  } from "./schemas/triggers.ts";
31
- import { widgetSourcesInput } from "./schemas/widget-sources.ts";
31
+ import {
32
+ runQueryProjectsInput,
33
+ widgetProjectsInput,
34
+ widgetSourcesInput,
35
+ } from "./schemas/widget-sources.ts";
32
36
  import { handleExperimentResults } from "./tools/get-experiment-results.ts";
33
37
  import { handleExperimentListRuns } from "./tools/list-experiment-runs.ts";
34
38
  import { handleExperimentList } from "./tools/list-experiments.ts";
@@ -248,6 +252,17 @@ function registerObservabilityTools(server: McpServer): void {
248
252
  .describe(
249
253
  'Values for the parameters the statement declares, e.g. {"days": 7} for {days:UInt32}',
250
254
  ),
255
+ projects: runQueryProjectsInput
256
+ .optional()
257
+ .describe(
258
+ 'The project ids to read, or the string "all" for every project the key can read (params.dashboard_context_projects lists them). A key that reaches several projects must name them or send "all"; a key that reads one project defaults to it',
259
+ ),
260
+ sources: z
261
+ .array(z.string())
262
+ .optional()
263
+ .describe(
264
+ "The trace sources {dashboard_context_sources:Array(String)} is bound to (default application). Only a statement that reads that parameter is kept to them; a SOURCES_IGNORED diagnostic says it did not",
265
+ ),
251
266
  },
252
267
  withToolLogging("run_query", async (params) => {
253
268
  requireApiKey();
@@ -1460,6 +1475,7 @@ function registerDashboardTools(server: McpServer): void {
1460
1475
  "The widget's named LangWatchQL queries: either {name: sql} or an array of {name, sql}. Max 8. Validate each statement with run_query first.",
1461
1476
  ),
1462
1477
  sources: widgetSourcesInput,
1478
+ projects: widgetProjectsInput,
1463
1479
  },
1464
1480
  withToolLogging("add_dashboard_widget", async (params) => {
1465
1481
  requireApiKey();
@@ -1504,6 +1520,7 @@ function registerDashboardTools(server: McpServer): void {
1504
1520
  .optional()
1505
1521
  .describe("What the widget's info tip says: a sentence or two"),
1506
1522
  sources: widgetSourcesInput,
1523
+ projects: widgetProjectsInput,
1507
1524
  },
1508
1525
  withToolLogging("update_dashboard_widget", async (params) => {
1509
1526
  requireApiKey();
@@ -14,6 +14,7 @@ export interface DashboardWidgetQueryInput {
14
14
  }[];
15
15
  /** The trace origins the query counts; `null` makes it unset, counting application. */
16
16
  sources?: WidgetSource[] | null;
17
+ projects?: string[] | null;
17
18
  }
18
19
 
19
20
  /** Where a widget came from, as the platform records it. */
@@ -25,6 +25,8 @@ export interface QueryRunResponse {
25
25
  };
26
26
  truncated: boolean;
27
27
  diagnostics: { code: string; message: string }[];
28
+ /** Each placeholder the SQL declares by its name, plus `period`; absent on an older platform. */
29
+ params?: Record<string, unknown>;
28
30
  }
29
31
 
30
32
  /** One published dataset. */
@@ -101,10 +103,14 @@ export interface QueryReferenceResponse {
101
103
  export async function runQuery(params: {
102
104
  sql: string;
103
105
  parameters?: Record<string, string | number | boolean | null>;
106
+ projects?: string[] | string;
107
+ sources?: string[];
104
108
  }): Promise<QueryRunResponse> {
105
109
  return makeRequest("POST", "/api/v1/query", {
106
110
  sql: params.sql,
107
111
  ...(params.parameters ? { parameters: params.parameters } : {}),
112
+ ...(params.projects ? { projects: params.projects } : {}),
113
+ ...(params.sources ? { sources: params.sources } : {}),
108
114
  }) as Promise<QueryRunResponse>;
109
115
  }
110
116
 
@@ -180,6 +180,15 @@ interface ParsedErrorBody {
180
180
  docsUrl?: string;
181
181
  fault?: HandledErrorFault;
182
182
  reasons?: SerializedReason[];
183
+ /** What the error says beyond its reasons, such as the names it refused. */
184
+ meta?: Record<string, unknown>;
185
+ }
186
+
187
+ /** The error's own facts: `meta` without the reasons (shown apart) and the request echo. */
188
+ function detailsOf(meta: Record<string, unknown>): Record<string, unknown> | undefined {
189
+ const { reasons: _reasons, target: _target, fields: _fields, ...details } = meta;
190
+
191
+ return Object.keys(details).length > 0 ? details : undefined;
183
192
  }
184
193
 
185
194
  const VALID_FAULTS: readonly HandledErrorFault[] = [
@@ -216,11 +225,14 @@ function parseErrorBody(responseBody: string): ParsedErrorBody {
216
225
  const fault = VALID_FAULTS.includes(body.fault as HandledErrorFault)
217
226
  ? (body.fault as HandledErrorFault)
218
227
  : undefined;
228
+ // The v1 envelope carries the per-field failures in `meta.reasons`; older ones at the top.
229
+ const meta = isRecord(body.meta) ? body.meta : {};
230
+ const rawReasons = Array.isArray(body.reasons) ? body.reasons : meta.reasons;
219
231
  const reasons =
220
- Array.isArray(body.reasons) && body.reasons.every((r) => !!r && typeof r === "object")
221
- ? (body.reasons as SerializedReason[])
232
+ Array.isArray(rawReasons) && rawReasons.every((r) => !!r && typeof r === "object")
233
+ ? (rawReasons as SerializedReason[])
222
234
  : undefined;
223
- return { code, message, tips, docsUrl, fault, reasons };
235
+ return { code, message, tips, docsUrl, fault, reasons, meta: detailsOf(meta) };
224
236
  } catch {
225
237
  return {};
226
238
  }
@@ -267,6 +279,39 @@ function describeReason(reason: SerializedReason): string | null {
267
279
  return parts.join(" — ");
268
280
  }
269
281
 
282
+ /** The error an unsuccessful response becomes: its message, code, details, fields and tips. */
283
+ function apiErrorOf({
284
+ status,
285
+ responseBody,
286
+ }: {
287
+ status: number;
288
+ responseBody: string;
289
+ }): LangWatchApiError {
290
+ const parsed = parseErrorBody(responseBody);
291
+ const lines = [`LangWatch API error ${status}: ${parsed.message ?? responseBody}`];
292
+ if (parsed.code) lines.push(`Code: ${parsed.code}`);
293
+ if (parsed.meta) lines.push(`Details: ${JSON.stringify(parsed.meta)}`);
294
+ const reasonLines = (parsed.reasons ?? [])
295
+ .map(describeReason)
296
+ .filter((line): line is string => line !== null);
297
+ if (reasonLines.length > 0) {
298
+ lines.push("Rejected fields:", ...reasonLines);
299
+ }
300
+ if (parsed.tips && parsed.tips.length > 0) {
301
+ lines.push("Tips:", ...parsed.tips.map((tip) => `- ${tip}`));
302
+ }
303
+ if (parsed.docsUrl) {
304
+ lines.push(`Docs: ${parsed.docsUrl}`);
305
+ }
306
+ return new LangWatchApiError(lines.join("\n"), status, responseBody, {
307
+ code: parsed.code,
308
+ tips: parsed.tips,
309
+ docsUrl: parsed.docsUrl,
310
+ fault: parsed.fault,
311
+ reasons: parsed.reasons,
312
+ });
313
+ }
314
+
270
315
  /**
271
316
  * Sends an HTTP request to the LangWatch API. Builds the full URL from the configured endpoint,
272
317
  * adds authentication, and handles JSON serialization/deserialization. @throws
@@ -301,30 +346,8 @@ export async function makeRequest(
301
346
  ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
302
347
  });
303
348
 
304
- if (!response.ok) {
305
- const responseBody = await response.text();
306
- const parsed = parseErrorBody(responseBody);
307
- const lines = [`LangWatch API error ${response.status}: ${parsed.message ?? responseBody}`];
308
- const reasonLines = (parsed.reasons ?? [])
309
- .map(describeReason)
310
- .filter((line): line is string => line !== null);
311
- if (reasonLines.length > 0) {
312
- lines.push("Rejected fields:", ...reasonLines);
313
- }
314
- if (parsed.tips && parsed.tips.length > 0) {
315
- lines.push("Tips:", ...parsed.tips.map((tip) => `- ${tip}`));
316
- }
317
- if (parsed.docsUrl) {
318
- lines.push(`Docs: ${parsed.docsUrl}`);
319
- }
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
- });
327
- }
349
+ if (!response.ok)
350
+ throw apiErrorOf({ status: response.status, responseBody: await response.text() });
328
351
 
329
352
  if (response.status === 204 || response.headers?.get("content-length") === "0") {
330
353
  return null;
@@ -4,6 +4,8 @@
4
4
  */
5
5
  import { z } from "zod";
6
6
 
7
+ const isAllWord = (id: string) => id.trim().toLowerCase() === "all";
8
+
7
9
  /** The sources the platform takes, "other" being every origin not listed before it. */
8
10
  export const WIDGET_SOURCES = [
9
11
  "application",
@@ -31,3 +33,37 @@ export const widgetSourcesInput = z
31
33
  .describe(
32
34
  `The trace origins every query of the widget counts: any of ${WIDGET_SOURCES.join(", ")} (other = any origin not listed). A new widget counts ["application"]; add "langy" to count your own conversations, as a widget about Langy's requests needs. null makes it unset again, counting the default.`,
33
35
  );
36
+
37
+ /**
38
+ * The tools' `projects` input: the project ids every query of the widget reads. Absent, a query
39
+ * keeps what it stores (a new widget reads its board's project); null makes it unset again.
40
+ */
41
+ const ALL_NOT_STORED = 'projects holds project ids; "all" is not stored in a widget';
42
+ // run_query takes "all"; a widget stores ids. The refine carries the message for "all" as a
43
+ // string or inside the array, and adds nothing to the tool's JSON Schema.
44
+ export const widgetProjectsInput = z
45
+ .array(z.string().min(1), {
46
+ error: (issue) =>
47
+ typeof issue.input === "string" && isAllWord(issue.input) ? ALL_NOT_STORED : undefined,
48
+ })
49
+ .min(1)
50
+ .refine((ids) => !ids.some(isAllWord), { message: ALL_NOT_STORED })
51
+ .nullable()
52
+ .optional()
53
+ .describe(
54
+ "The project ids every query of the widget reads, each one you can read. A new widget reads its board's project. null makes it unset again, reading the board's project.",
55
+ );
56
+
57
+ /**
58
+ * run_query's `projects`: ids, or the lone word "all" in any case. Mirrors holdsAllWord and
59
+ * LWQL_ALL_STANDS_ALONE in analytics-lwql.schemas.ts, which MCP cannot import.
60
+ */
61
+ export const runQueryProjectsInput = z.union([
62
+ z.string().refine(isAllWord),
63
+ z
64
+ .array(z.string().min(1))
65
+ .min(1)
66
+ .refine((ids) => !ids.some(isAllWord), {
67
+ message: '"all" stands alone; send it by itself, or list project ids',
68
+ }),
69
+ ]);
@@ -8,7 +8,7 @@ import type { WidgetSource } from "../schemas/widget-sources.js";
8
8
  import {
9
9
  type DashboardWidgetQueriesInput,
10
10
  normalizeDashboardWidgetQueries,
11
- withSources,
11
+ withLists,
12
12
  } from "./dashboard-widget-queries.js";
13
13
 
14
14
  export interface AddDashboardWidgetParams {
@@ -18,12 +18,15 @@ export interface AddDashboardWidgetParams {
18
18
  queries: DashboardWidgetQueriesInput;
19
19
  /** Set on every query; absent, the platform stores application on each. */
20
20
  sources?: WidgetSource[] | null;
21
+ /** Set on every query; absent, the widget reads its board's project. */
22
+ projects?: string[] | null;
21
23
  }
22
24
 
23
25
  export async function handleAddDashboardWidget(params: AddDashboardWidgetParams): Promise<string> {
24
- const queries = withSources({
26
+ const queries = withLists({
25
27
  queries: normalizeDashboardWidgetQueries({ queries: params.queries }),
26
28
  sources: params.sources,
29
+ projects: params.projects,
27
30
  });
28
31
 
29
32
  let widget;
@@ -1,16 +1,25 @@
1
1
  import type { DashboardWidgetQueryInput } from "../langwatch-api-dashboard-widgets.js";
2
2
  import type { WidgetSource } from "../schemas/widget-sources.js";
3
3
 
4
- /** Every query with `sources` set to the list given; as given when no list was named. */
5
- export function withSources({
4
+ /**
5
+ * Every query with `sources` and `projects` set to the lists given; a list not named is left as
6
+ * the query has it.
7
+ */
8
+ export function withLists({
6
9
  queries,
7
10
  sources,
11
+ projects,
8
12
  }: {
9
13
  queries: readonly DashboardWidgetQueryInput[];
10
14
  sources: WidgetSource[] | null | undefined;
15
+ projects?: string[] | null | undefined;
11
16
  }): DashboardWidgetQueryInput[] {
12
- if (sources === undefined) return [...queries];
13
- return queries.map((query) => ({ ...query, sources }));
17
+ if (sources === undefined && projects === undefined) return [...queries];
18
+ return queries.map((query) => ({
19
+ ...query,
20
+ ...(sources === undefined ? {} : { sources }),
21
+ ...(projects === undefined ? {} : { projects }),
22
+ }));
14
23
  }
15
24
 
16
25
  /** A widget file rarely needs more than a couple of named queries (server bound). */
@@ -5,16 +5,28 @@
5
5
  */
6
6
 
7
7
  import { runQuery } from "../langwatch-api-query.ts";
8
+ import { LangWatchApiError } from "../langwatch-api.ts";
8
9
  import { markdownTable } from "../utils/markdown-table.ts";
9
10
 
10
11
  /** Rows the table prints. Beyond this, aggregate or export through the CLI. */
11
12
  export const RUN_QUERY_ROW_CAP = 50;
12
13
 
14
+ /** What the tool tells an agent whose key names no project (the platform's `projects_required`). */
15
+ const PROJECTS_REQUIRED_MESSAGE =
16
+ 'Name the projects to query: pass `projects`, a list of project ids, or "all"';
17
+
13
18
  export async function handleRunQuery(params: {
14
19
  sql: string;
15
20
  parameters?: Record<string, string | number | boolean | null>;
21
+ projects?: string[] | string;
22
+ sources?: string[];
16
23
  }): Promise<string> {
17
- const result = await runQuery(params);
24
+ const result = await runQuery(params).catch((error: unknown) => {
25
+ if (error instanceof LangWatchApiError && error.code === "projects_required") {
26
+ throw new Error(PROJECTS_REQUIRED_MESSAGE);
27
+ }
28
+ throw error;
29
+ });
18
30
  const headers = result.columns.map((column) => column.name);
19
31
  const shown = result.rows.slice(0, RUN_QUERY_ROW_CAP);
20
32
 
@@ -43,5 +55,15 @@ export async function handleRunQuery(params: {
43
55
  for (const diagnostic of result.diagnostics) {
44
56
  lines.push(`${diagnostic.code}: ${diagnostic.message}`);
45
57
  }
58
+ if (result.params) lines.push("", describeParams(result.params));
46
59
  return lines.join("\n");
47
60
  }
61
+
62
+ /** What the run was bound to: every placeholder the SQL declares, by its SQL name. */
63
+ function describeParams(
64
+ params: NonNullable<Awaited<ReturnType<typeof runQuery>>["params"]>,
65
+ ): string {
66
+ return ["Ran with these placeholders:", "```json", JSON.stringify(params, null, 2), "```"].join(
67
+ "\n",
68
+ );
69
+ }
@@ -11,7 +11,7 @@ import type { WidgetSource } from "../schemas/widget-sources.js";
11
11
  import {
12
12
  type DashboardWidgetQueriesInput,
13
13
  normalizeDashboardWidgetQueries,
14
- withSources,
14
+ withLists,
15
15
  } from "./dashboard-widget-queries.js";
16
16
 
17
17
  export interface UpdateDashboardWidgetParams {
@@ -23,16 +23,18 @@ export interface UpdateDashboardWidgetParams {
23
23
  description?: string;
24
24
  /** Set on every query; alone, it is sent with the widget's stored queries. */
25
25
  sources?: WidgetSource[] | null;
26
+ /** Set on every query; alone, it is sent with the widget's stored queries. */
27
+ projects?: string[] | null;
26
28
  }
27
29
 
28
30
  export async function handleUpdateDashboardWidget(
29
31
  params: UpdateDashboardWidgetParams,
30
32
  ): Promise<string> {
31
- const { dashboardId, widgetId, name, code, description, sources } = params;
32
- const fields = [name, code, params.queries, description, sources];
33
+ const { dashboardId, widgetId, name, code, description, sources, projects } = params;
34
+ const fields = [name, code, params.queries, description, sources, projects];
33
35
  if (fields.every((field) => field === undefined)) {
34
36
  throw new Error(
35
- "Provide at least one of name, code, queries, description or sources to change.",
37
+ "Provide at least one of name, code, queries, description, sources or projects to change.",
36
38
  );
37
39
  }
38
40
 
@@ -42,8 +44,9 @@ export async function handleUpdateDashboardWidget(
42
44
  ? undefined
43
45
  : normalizeDashboardWidgetQueries({ queries: params.queries });
44
46
  // 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
+ const listed = sources !== undefined || projects !== undefined;
48
+ const base = given ?? (listed ? current.definition.queries : undefined);
49
+ const queries = base === undefined ? undefined : withLists({ queries: base, sources, projects });
47
50
 
48
51
  const changes = {
49
52
  ...(name === undefined ? {} : { name }),