@langwatch/mcp-server 0.6.1 → 0.7.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 (258) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/Dockerfile +22 -0
  3. package/README.md +51 -8
  4. package/dist/{archive-scenario-YFD5THOR.js → archive-scenario-WJ2A7ETN.js} +4 -4
  5. package/dist/archive-suite-4JOM4SSL.js +15 -0
  6. package/dist/archive-suite-4JOM4SSL.js.map +1 -0
  7. package/dist/assign-prompt-tag-GL7EAAF3.js +19 -0
  8. package/dist/assign-prompt-tag-GL7EAAF3.js.map +1 -0
  9. package/dist/{chunk-6U4TCGFC.js → chunk-2GT7IFWK.js} +2 -2
  10. package/dist/{chunk-LLRQIF52.js → chunk-2WPLXEKF.js} +49 -5
  11. package/dist/chunk-2WPLXEKF.js.map +1 -0
  12. package/dist/chunk-4AUB2BIA.js +71 -0
  13. package/dist/chunk-4AUB2BIA.js.map +1 -0
  14. package/dist/chunk-BWWY5KEF.js +71 -0
  15. package/dist/chunk-BWWY5KEF.js.map +1 -0
  16. package/dist/{chunk-IX6QJKAD.js → chunk-CCWCIJJ3.js} +2 -2
  17. package/dist/chunk-E5JYYU3J.js +1567 -0
  18. package/dist/chunk-E5JYYU3J.js.map +1 -0
  19. package/dist/chunk-EGH5RPXM.js +25 -0
  20. package/dist/chunk-EGH5RPXM.js.map +1 -0
  21. package/dist/chunk-EUQDVOSU.js +39 -0
  22. package/dist/chunk-EUQDVOSU.js.map +1 -0
  23. package/dist/{chunk-5UOPNRXW.js → chunk-HYMIWO3U.js} +10 -3
  24. package/dist/{chunk-5UOPNRXW.js.map → chunk-HYMIWO3U.js.map} +1 -1
  25. package/dist/chunk-IE4M5OGE.js +42 -0
  26. package/dist/chunk-IE4M5OGE.js.map +1 -0
  27. package/dist/chunk-LUMEZEHL.js +48 -0
  28. package/dist/chunk-LUMEZEHL.js.map +1 -0
  29. package/dist/chunk-NUFPTHKU.js +9 -0
  30. package/dist/chunk-NUFPTHKU.js.map +1 -0
  31. package/dist/chunk-WQG2DFHX.js +86 -0
  32. package/dist/chunk-WQG2DFHX.js.map +1 -0
  33. package/dist/chunk-WVI5CJ6S.js +21 -0
  34. package/dist/chunk-WVI5CJ6S.js.map +1 -0
  35. package/dist/chunk-ZVS4UKN2.js +35 -0
  36. package/dist/chunk-ZVS4UKN2.js.map +1 -0
  37. package/dist/config.d.ts +17 -0
  38. package/dist/config.js +13 -0
  39. package/dist/create-agent-MBOOT3XK.js +23 -0
  40. package/dist/create-agent-MBOOT3XK.js.map +1 -0
  41. package/dist/create-annotation-XMV6A7ED.js +24 -0
  42. package/dist/create-annotation-XMV6A7ED.js.map +1 -0
  43. package/dist/create-dashboard-VRKLFVZJ.js +18 -0
  44. package/dist/create-dashboard-VRKLFVZJ.js.map +1 -0
  45. package/dist/create-dataset-7HQPZCRE.js +22 -0
  46. package/dist/create-dataset-7HQPZCRE.js.map +1 -0
  47. package/dist/create-dataset-records-2NIVFYTV.js +22 -0
  48. package/dist/create-dataset-records-2NIVFYTV.js.map +1 -0
  49. package/dist/{create-evaluator-E5X5ZP3B.js → create-evaluator-WYFRFLRC.js} +4 -4
  50. package/dist/create-mcp-server.d.ts +8 -0
  51. package/dist/create-mcp-server.js +8 -0
  52. package/dist/create-mcp-server.js.map +1 -0
  53. package/dist/{create-prompt-7Z35MIL6.js → create-prompt-IEN7O6JT.js} +7 -4
  54. package/dist/create-prompt-IEN7O6JT.js.map +1 -0
  55. package/dist/create-prompt-tag-CAEZ45VO.js +17 -0
  56. package/dist/create-prompt-tag-CAEZ45VO.js.map +1 -0
  57. package/dist/{create-scenario-DIMPJRPY.js → create-scenario-6YHSMGLP.js} +4 -4
  58. package/dist/create-suite-H5XOFDE5.js +38 -0
  59. package/dist/create-suite-H5XOFDE5.js.map +1 -0
  60. package/dist/delete-agent-JKTNBWAA.js +18 -0
  61. package/dist/delete-agent-JKTNBWAA.js.map +1 -0
  62. package/dist/delete-annotation-ACMDV6QO.js +17 -0
  63. package/dist/delete-annotation-ACMDV6QO.js.map +1 -0
  64. package/dist/delete-dashboard-VJSR7CRU.js +18 -0
  65. package/dist/delete-dashboard-VJSR7CRU.js.map +1 -0
  66. package/dist/delete-dataset-RTTTWP4D.js +20 -0
  67. package/dist/delete-dataset-RTTTWP4D.js.map +1 -0
  68. package/dist/delete-dataset-records-KNQTIPQK.js +21 -0
  69. package/dist/delete-dataset-records-KNQTIPQK.js.map +1 -0
  70. package/dist/delete-evaluator-7FVC5WM4.js +15 -0
  71. package/dist/delete-evaluator-7FVC5WM4.js.map +1 -0
  72. package/dist/delete-prompt-tag-ZMZUAGFW.js +17 -0
  73. package/dist/delete-prompt-tag-ZMZUAGFW.js.map +1 -0
  74. package/dist/delete-workflow-EYQ3T4RQ.js +17 -0
  75. package/dist/delete-workflow-EYQ3T4RQ.js.map +1 -0
  76. package/dist/get-agent-E3QSTVKG.js +28 -0
  77. package/dist/get-agent-E3QSTVKG.js.map +1 -0
  78. package/dist/{get-analytics-4YJW4S5L.js → get-analytics-2OHV763I.js} +22 -5
  79. package/dist/get-analytics-2OHV763I.js.map +1 -0
  80. package/dist/get-dashboard-PC7JDHH6.js +29 -0
  81. package/dist/get-dashboard-PC7JDHH6.js.map +1 -0
  82. package/dist/get-dataset-H5IK5FVU.js +48 -0
  83. package/dist/get-dataset-H5IK5FVU.js.map +1 -0
  84. package/dist/{get-evaluator-WDEH2F7M.js → get-evaluator-UWVUPYTM.js} +4 -4
  85. package/dist/{get-prompt-F6PDVC76.js → get-prompt-WZUOLLQC.js} +4 -4
  86. package/dist/get-prompt-WZUOLLQC.js.map +1 -0
  87. package/dist/{get-scenario-H24ZYNT5.js → get-scenario-Q6LCNUYN.js} +4 -4
  88. package/dist/get-simulation-run-Z2XKO256.js +56 -0
  89. package/dist/get-simulation-run-Z2XKO256.js.map +1 -0
  90. package/dist/get-suite-BXK5TN7P.js +44 -0
  91. package/dist/get-suite-BXK5TN7P.js.map +1 -0
  92. package/dist/{get-trace-27USKGO7.js → get-trace-4EJAYVBG.js} +3 -3
  93. package/dist/get-workflow-O34QJLHD.js +25 -0
  94. package/dist/get-workflow-O34QJLHD.js.map +1 -0
  95. package/dist/http-server-ISHF7NJX.js +224 -0
  96. package/dist/http-server-ISHF7NJX.js.map +1 -0
  97. package/dist/index.js +61109 -31519
  98. package/dist/index.js.map +1 -1
  99. package/dist/langwatch-api-annotations-ERBG27RF.js +17 -0
  100. package/dist/langwatch-api-annotations-ERBG27RF.js.map +1 -0
  101. package/dist/langwatch-api-dashboards-G6TR7VVO.js +17 -0
  102. package/dist/langwatch-api-dashboards-G6TR7VVO.js.map +1 -0
  103. package/dist/langwatch-api-monitors-WSXZLS2B.js +52 -0
  104. package/dist/langwatch-api-monitors-WSXZLS2B.js.map +1 -0
  105. package/dist/langwatch-api-secrets-RR5DKG2X.js +40 -0
  106. package/dist/langwatch-api-secrets-RR5DKG2X.js.map +1 -0
  107. package/dist/langwatch-api-triggers-2RTNSWQY.js +30 -0
  108. package/dist/langwatch-api-triggers-2RTNSWQY.js.map +1 -0
  109. package/dist/langwatch-api-workflows-VJRIIDZ7.js +15 -0
  110. package/dist/langwatch-api-workflows-VJRIIDZ7.js.map +1 -0
  111. package/dist/list-agents-AW3P6FJV.js +32 -0
  112. package/dist/list-agents-AW3P6FJV.js.map +1 -0
  113. package/dist/list-annotations-QNCGWPQ3.js +33 -0
  114. package/dist/list-annotations-QNCGWPQ3.js.map +1 -0
  115. package/dist/list-dashboards-R7RK2IXL.js +32 -0
  116. package/dist/list-dashboards-R7RK2IXL.js.map +1 -0
  117. package/dist/list-dataset-records-WVCSQP7P.js +39 -0
  118. package/dist/list-dataset-records-WVCSQP7P.js.map +1 -0
  119. package/dist/list-datasets-KEXRLDEU.js +60 -0
  120. package/dist/list-datasets-KEXRLDEU.js.map +1 -0
  121. package/dist/{list-evaluators-KRGI72EH.js → list-evaluators-7R2LB4JH.js} +4 -4
  122. package/dist/{list-model-providers-A5YCFTPI.js → list-model-providers-OBYJCKBX.js} +4 -4
  123. package/dist/list-prompt-tags-6LY3ZPYI.js +23 -0
  124. package/dist/list-prompt-tags-6LY3ZPYI.js.map +1 -0
  125. package/dist/{list-prompts-LKJSE7XN.js → list-prompts-VWEZ4CDE.js} +3 -3
  126. package/dist/{list-scenarios-ZK5CMGC4.js → list-scenarios-TXD4W2ZJ.js} +4 -4
  127. package/dist/list-simulation-runs-RHPOLMFI.js +43 -0
  128. package/dist/list-simulation-runs-RHPOLMFI.js.map +1 -0
  129. package/dist/list-suites-FSGBX27Z.js +42 -0
  130. package/dist/list-suites-FSGBX27Z.js.map +1 -0
  131. package/dist/list-workflows-VRGEZ3EN.js +35 -0
  132. package/dist/list-workflows-VRGEZ3EN.js.map +1 -0
  133. package/dist/rename-prompt-tag-VOJJLX4M.js +18 -0
  134. package/dist/rename-prompt-tag-VOJJLX4M.js.map +1 -0
  135. package/dist/run-agent-KTCC7TB7.js +36 -0
  136. package/dist/run-agent-KTCC7TB7.js.map +1 -0
  137. package/dist/run-evaluation-2X3V3Q6L.js +64 -0
  138. package/dist/run-evaluation-2X3V3Q6L.js.map +1 -0
  139. package/dist/run-suite-BTMHGI2D.js +29 -0
  140. package/dist/run-suite-BTMHGI2D.js.map +1 -0
  141. package/dist/run-workflow-IGAYGKJL.js +36 -0
  142. package/dist/run-workflow-IGAYGKJL.js.map +1 -0
  143. package/dist/{search-traces-SOKAAMAR.js → search-traces-VYFUIMXH.js} +3 -3
  144. package/dist/{set-model-provider-7MGULZDH.js → set-model-provider-W5IUI326.js} +4 -4
  145. package/dist/update-agent-4BB7EYLR.js +20 -0
  146. package/dist/update-agent-4BB7EYLR.js.map +1 -0
  147. package/dist/update-dataset-CXBKZ4W3.js +22 -0
  148. package/dist/update-dataset-CXBKZ4W3.js.map +1 -0
  149. package/dist/update-dataset-record-HOHAMHXG.js +19 -0
  150. package/dist/update-dataset-record-HOHAMHXG.js.map +1 -0
  151. package/dist/{update-evaluator-A3XINFLJ.js → update-evaluator-IVOR6FTR.js} +4 -4
  152. package/dist/{update-prompt-IW7X2UQM.js → update-prompt-OWQAKE7K.js} +5 -3
  153. package/dist/update-prompt-OWQAKE7K.js.map +1 -0
  154. package/dist/{update-scenario-ZT7TOBFR.js → update-scenario-GDFVILPN.js} +4 -4
  155. package/dist/update-suite-BXYUYSPT.js +39 -0
  156. package/dist/update-suite-BXYUYSPT.js.map +1 -0
  157. package/package.json +17 -3
  158. package/src/__tests__/all-tools.integration.test.ts +344 -0
  159. package/src/__tests__/config.unit.test.ts +81 -1
  160. package/src/__tests__/datasets.integration.test.ts +603 -0
  161. package/src/__tests__/datasets.unit.test.ts +240 -0
  162. package/src/__tests__/docker.integration.test.ts +234 -0
  163. package/src/__tests__/http-transport.integration.test.ts +397 -0
  164. package/src/__tests__/langwatch-api.unit.test.ts +174 -0
  165. package/src/__tests__/tools.unit.test.ts +177 -0
  166. package/src/config.d.ts +15 -0
  167. package/src/config.ts +83 -7
  168. package/src/create-mcp-server.d.ts +6 -0
  169. package/src/create-mcp-server.ts +1799 -0
  170. package/src/http-server.ts +329 -0
  171. package/src/index.ts +22 -593
  172. package/src/langwatch-api-agents.ts +108 -0
  173. package/src/langwatch-api-annotations.ts +49 -0
  174. package/src/langwatch-api-dashboards.ts +48 -0
  175. package/src/langwatch-api-datasets.ts +191 -0
  176. package/src/langwatch-api-evaluators.ts +10 -0
  177. package/src/langwatch-api-monitors.ts +82 -0
  178. package/src/langwatch-api-secrets.ts +48 -0
  179. package/src/langwatch-api-simulation-runs.ts +51 -0
  180. package/src/langwatch-api-suites.ts +118 -0
  181. package/src/langwatch-api-triggers.ts +48 -0
  182. package/src/langwatch-api-workflows.ts +41 -0
  183. package/src/langwatch-api.ts +60 -2
  184. package/src/schemas/create-dataset.ts +48 -0
  185. package/src/schemas/index.ts +1 -0
  186. package/src/tools/archive-suite.ts +12 -0
  187. package/src/tools/assign-prompt-tag.ts +16 -0
  188. package/src/tools/create-agent.ts +15 -0
  189. package/src/tools/create-annotation.ts +18 -0
  190. package/src/tools/create-dashboard.ts +7 -0
  191. package/src/tools/create-dataset-records.ts +23 -0
  192. package/src/tools/create-dataset.ts +22 -0
  193. package/src/tools/create-prompt-tag.ts +12 -0
  194. package/src/tools/create-prompt.ts +4 -0
  195. package/src/tools/create-suite.ts +42 -0
  196. package/src/tools/delete-agent.ts +7 -0
  197. package/src/tools/delete-annotation.ts +7 -0
  198. package/src/tools/delete-dashboard.ts +7 -0
  199. package/src/tools/delete-dataset-records.ts +22 -0
  200. package/src/tools/delete-dataset.ts +20 -0
  201. package/src/tools/delete-evaluator.ts +12 -0
  202. package/src/tools/delete-prompt-tag.ts +12 -0
  203. package/src/tools/delete-workflow.ts +7 -0
  204. package/src/tools/format-dataset-mutation.ts +25 -0
  205. package/src/tools/get-agent.ts +21 -0
  206. package/src/tools/get-analytics.ts +30 -3
  207. package/src/tools/get-dashboard.ts +22 -0
  208. package/src/tools/get-dataset.ts +63 -0
  209. package/src/tools/get-prompt.ts +2 -1
  210. package/src/tools/get-simulation-run.ts +60 -0
  211. package/src/tools/get-suite.ts +47 -0
  212. package/src/tools/get-workflow.ts +17 -0
  213. package/src/tools/list-agents.ts +27 -0
  214. package/src/tools/list-annotations.ts +33 -0
  215. package/src/tools/list-dashboards.ts +27 -0
  216. package/src/tools/list-dataset-records.ts +46 -0
  217. package/src/tools/list-datasets.ts +80 -0
  218. package/src/tools/list-prompt-tags.ts +21 -0
  219. package/src/tools/list-simulation-runs.ts +49 -0
  220. package/src/tools/list-suites.ts +43 -0
  221. package/src/tools/list-workflows.ts +31 -0
  222. package/src/tools/rename-prompt-tag.ts +14 -0
  223. package/src/tools/run-agent.ts +36 -0
  224. package/src/tools/run-evaluation.ts +87 -0
  225. package/src/tools/run-suite.ts +28 -0
  226. package/src/tools/run-workflow.ts +36 -0
  227. package/src/tools/update-agent.ts +13 -0
  228. package/src/tools/update-dataset-record.ts +21 -0
  229. package/src/tools/update-dataset.ts +23 -0
  230. package/src/tools/update-prompt.ts +3 -0
  231. package/src/tools/update-suite.ts +44 -0
  232. package/src/utils/escape-markdown.ts +12 -0
  233. package/tsup.config.ts +5 -1
  234. package/dist/chunk-AAQNA53E.js +0 -28
  235. package/dist/chunk-AAQNA53E.js.map +0 -1
  236. package/dist/chunk-LLRQIF52.js.map +0 -1
  237. package/dist/config-FIQWQRUB.js +0 -11
  238. package/dist/create-prompt-7Z35MIL6.js.map +0 -1
  239. package/dist/get-analytics-4YJW4S5L.js.map +0 -1
  240. package/dist/get-prompt-F6PDVC76.js.map +0 -1
  241. package/dist/update-prompt-IW7X2UQM.js.map +0 -1
  242. /package/dist/{archive-scenario-YFD5THOR.js.map → archive-scenario-WJ2A7ETN.js.map} +0 -0
  243. /package/dist/{chunk-6U4TCGFC.js.map → chunk-2GT7IFWK.js.map} +0 -0
  244. /package/dist/{chunk-IX6QJKAD.js.map → chunk-CCWCIJJ3.js.map} +0 -0
  245. /package/dist/{config-FIQWQRUB.js.map → config.js.map} +0 -0
  246. /package/dist/{create-evaluator-E5X5ZP3B.js.map → create-evaluator-WYFRFLRC.js.map} +0 -0
  247. /package/dist/{create-scenario-DIMPJRPY.js.map → create-scenario-6YHSMGLP.js.map} +0 -0
  248. /package/dist/{get-evaluator-WDEH2F7M.js.map → get-evaluator-UWVUPYTM.js.map} +0 -0
  249. /package/dist/{get-scenario-H24ZYNT5.js.map → get-scenario-Q6LCNUYN.js.map} +0 -0
  250. /package/dist/{get-trace-27USKGO7.js.map → get-trace-4EJAYVBG.js.map} +0 -0
  251. /package/dist/{list-evaluators-KRGI72EH.js.map → list-evaluators-7R2LB4JH.js.map} +0 -0
  252. /package/dist/{list-model-providers-A5YCFTPI.js.map → list-model-providers-OBYJCKBX.js.map} +0 -0
  253. /package/dist/{list-prompts-LKJSE7XN.js.map → list-prompts-VWEZ4CDE.js.map} +0 -0
  254. /package/dist/{list-scenarios-ZK5CMGC4.js.map → list-scenarios-TXD4W2ZJ.js.map} +0 -0
  255. /package/dist/{search-traces-SOKAAMAR.js.map → search-traces-VYFUIMXH.js.map} +0 -0
  256. /package/dist/{set-model-provider-7MGULZDH.js.map → set-model-provider-W5IUI326.js.map} +0 -0
  257. /package/dist/{update-evaluator-A3XINFLJ.js.map → update-evaluator-IVOR6FTR.js.map} +0 -0
  258. /package/dist/{update-scenario-ZT7TOBFR.js.map → update-scenario-GDFVILPN.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.0](https://github.com/langwatch/langwatch/compare/mcp-server@v0.6.1...mcp-server@v0.7.0) (2026-04-16)
4
+
5
+
6
+ ### Features
7
+
8
+ * add mcp-server to langwatch pnpm workspace ([#3069](https://github.com/langwatch/langwatch/issues/3069)) ([73915d2](https://github.com/langwatch/langwatch/commit/73915d24fd47b8d6b5e33210fd3f73ac0f745e11))
9
+ * add prompt tag support to MCP tools, docs, and skills ([#2934](https://github.com/langwatch/langwatch/issues/2934)) ([858e0d7](https://github.com/langwatch/langwatch/commit/858e0d7df3df8c70822e2155a73453bf1a6fd324))
10
+ * full CLI, API, and MCP coverage for all platform features ([#3168](https://github.com/langwatch/langwatch/issues/3168)) ([921b7b9](https://github.com/langwatch/langwatch/commit/921b7b92d3ccc038556fe2241a3a90302786631e))
11
+ * **mcp-server:** oauth 2.0 + SSE client compatibility ([#2557](https://github.com/langwatch/langwatch/issues/2557)) ([7327579](https://github.com/langwatch/langwatch/commit/73275796aca80b90c4d78beb9033e33b0e4a8da9))
12
+ * **mcp:** add dataset mcp tools ([#2926](https://github.com/langwatch/langwatch/issues/2926)) ([666710c](https://github.com/langwatch/langwatch/commit/666710cbb1052f9b7180378a7c24490e4a103b9f))
13
+ * **mcp:** mount MCP HTTP server in-app with OAuth PKCE authorization ([#2847](https://github.com/langwatch/langwatch/issues/2847)) ([9d57dd8](https://github.com/langwatch/langwatch/commit/9d57dd877f80ba529d32879a387d4f4d0d0216b6))
14
+ * **skills:** agent skills-based onboarding with feature map and scenario tests ([#2377](https://github.com/langwatch/langwatch/issues/2377)) ([6f6abdb](https://github.com/langwatch/langwatch/commit/6f6abdb67b97fcb7c2958dbc193dcde37d4c82a8))
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * analytics groupBy returns empty in MCP tool and trigger alerts ([#3012](https://github.com/langwatch/langwatch/issues/3012)) ([634db38](https://github.com/langwatch/langwatch/commit/634db380de35132b6ed88ce04e3998a3229f90db))
20
+ * **mcp:** build config and create-mcp-server with tsup to fix dual-module bug ([640c2e4](https://github.com/langwatch/langwatch/commit/640c2e42024cc40b0b02c1abac4cf07f6881f497))
21
+ * **mcp:** build subexports with tsup to eliminate dual-module bug ([#2985](https://github.com/langwatch/langwatch/issues/2985)) ([640c2e4](https://github.com/langwatch/langwatch/commit/640c2e42024cc40b0b02c1abac4cf07f6881f497))
22
+ * **mcp:** resolve dual-module config bug causing "Config not initialized" in production ([fcf0e0b](https://github.com/langwatch/langwatch/commit/fcf0e0b0f85bfc6b10a26ac917fe2c3f0335771d))
23
+ * **mcp:** resolve dual-module config bug in production ([#2956](https://github.com/langwatch/langwatch/issues/2956)) ([fcf0e0b](https://github.com/langwatch/langwatch/commit/fcf0e0b0f85bfc6b10a26ac917fe2c3f0335771d))
24
+ * **mcp:** use globalThis for config singleton to fix CJS/ESM dual cache ([#3123](https://github.com/langwatch/langwatch/issues/3123)) ([a7ece22](https://github.com/langwatch/langwatch/commit/a7ece22144b67dcd5318d9abdd5d3ba66464bbb7))
25
+
3
26
  ## [0.6.1](https://github.com/langwatch/langwatch/compare/mcp-server@v0.6.0...mcp-server@v0.6.1) (2026-03-13)
4
27
 
5
28
 
package/Dockerfile ADDED
@@ -0,0 +1,22 @@
1
+ FROM node:24-alpine
2
+
3
+ # node-pty requires native compilation tools
4
+ RUN apk add --no-cache python3 make g++
5
+
6
+ RUN corepack enable && corepack prepare pnpm@10 --activate
7
+
8
+ WORKDIR /app
9
+
10
+ # Build from repo root: docker build -t langwatch-mcp -f mcp-server/Dockerfile .
11
+ COPY mcp-server/package.json mcp-server/pnpm-lock.yaml mcp-server/pnpm-workspace.yaml ./mcp-server/
12
+ WORKDIR /app/mcp-server
13
+ RUN pnpm install --frozen-lockfile
14
+
15
+ WORKDIR /app
16
+ COPY mcp-server/ ./mcp-server/
17
+ COPY langevals/ ./langevals/
18
+
19
+ EXPOSE 3000
20
+
21
+ WORKDIR /app/mcp-server
22
+ CMD ["node", "--import", "tsx/esm", "src/index.ts", "--http", "--port", "3000"]
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # LangWatch MCP Server
2
2
 
3
- MCP server that gives AI coding agents access to LangWatch observability data, prompts, and documentation via the [Model Context Protocol](https://modelcontextprotocol.io/introduction).
3
+ MCP server that gives AI coding agents access to LangWatch observability data, prompts, datasets, scenarios, evaluators, and documentation via the [Model Context Protocol](https://modelcontextprotocol.io/introduction).
4
4
 
5
5
  ## Quick Setup
6
6
 
@@ -57,17 +57,58 @@ The API key is required for observability and prompt tools. Documentation tools
57
57
 
58
58
  | Tool | Description |
59
59
  |------|-------------|
60
- | `list_prompts` | List all prompts |
61
- | `get_prompt` | Get prompt with messages and version history |
62
- | `create_prompt` | Create a new prompt |
63
- | `update_prompt` | Update prompt or create new version |
60
+ | `platform_list_prompts` | List all prompts |
61
+ | `platform_get_prompt` | Get prompt with messages and version history |
62
+ | `platform_create_prompt` | Create a new prompt |
63
+ | `platform_update_prompt` | Update prompt or create new version |
64
+
65
+ ### Datasets (requires API key)
66
+
67
+ | Tool | Description |
68
+ |------|-------------|
69
+ | `platform_list_datasets` | List all datasets with record counts |
70
+ | `platform_get_dataset` | Get dataset metadata, columns, and record preview |
71
+ | `platform_create_dataset` | Create a new dataset with optional column definitions |
72
+ | `platform_update_dataset` | Update dataset name or column types |
73
+ | `platform_delete_dataset` | Archive a dataset |
74
+ | `platform_create_dataset_records` | Add records to a dataset (max 1000 per call) |
75
+ | `platform_update_dataset_record` | Update a single record |
76
+ | `platform_delete_dataset_records` | Delete records by IDs (max 1000 per call) |
77
+
78
+ ### Scenarios (requires API key)
79
+
80
+ | Tool | Description |
81
+ |------|-------------|
82
+ | `platform_list_scenarios` | List all scenarios |
83
+ | `platform_get_scenario` | Get scenario details |
84
+ | `platform_create_scenario` | Create a new scenario |
85
+ | `platform_update_scenario` | Update a scenario |
86
+ | `platform_archive_scenario` | Archive a scenario |
87
+
88
+ ### Evaluators (requires API key)
89
+
90
+ | Tool | Description |
91
+ |------|-------------|
92
+ | `platform_list_evaluators` | List all evaluators |
93
+ | `platform_get_evaluator` | Get evaluator details |
94
+ | `platform_create_evaluator` | Create a new evaluator |
95
+ | `platform_update_evaluator` | Update an evaluator |
96
+
97
+ ### Model Providers (requires API key)
98
+
99
+ | Tool | Description |
100
+ |------|-------------|
101
+ | `platform_list_model_providers` | List configured model providers |
102
+ | `platform_set_model_provider` | Configure a model provider |
64
103
 
65
104
  ## Output Formats
66
105
 
67
- The `search_traces` and `get_trace` tools support a `format` parameter:
106
+ Several tools support a `format` parameter:
107
+
108
+ - **`digest`** (default) — AI-readable markdown output. Optimized for LLM consumption — compact and information-dense.
109
+ - **`json`** — Full raw data. Useful for programmatic access or when you need the complete schema.
68
110
 
69
- - **`digest`** (default) — AI-readable trace digest with hierarchical span tree, timing, inputs/outputs, and errors. Optimized for LLM consumption — compact and information-dense.
70
- - **`json`** — Full raw trace data with all fields. Useful for programmatic access or when you need the complete schema.
111
+ Supported on: `search_traces`, `get_trace`, `platform_list_datasets`, `platform_get_dataset`, `platform_list_scenarios`, `platform_get_scenario`.
71
112
 
72
113
  ## Usage Tips
73
114
 
@@ -76,6 +117,8 @@ The `search_traces` and `get_trace` tools support a `format` parameter:
76
117
  - Search returns 25 traces per page by default. Use `scrollId` from the response to paginate.
77
118
  - Analytics uses `category.name` format for metrics (e.g., `performance.completion_time`).
78
119
  - Use `create_prompt` / `update_prompt` with `createVersion: true` for safe prompt iteration.
120
+ - Use `platform_list_datasets` then `platform_get_dataset` to browse dataset contents.
121
+ - Dataset tools support full CRUD: create datasets, add/update/delete records, and archive datasets.
79
122
 
80
123
  ## Development
81
124
 
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  archiveScenario
3
- } from "./chunk-6U4TCGFC.js";
4
- import "./chunk-LLRQIF52.js";
5
- import "./chunk-AAQNA53E.js";
3
+ } from "./chunk-2GT7IFWK.js";
4
+ import "./chunk-2WPLXEKF.js";
5
+ import "./chunk-BWWY5KEF.js";
6
6
 
7
7
  // src/tools/archive-scenario.ts
8
8
  async function handleArchiveScenario(params) {
@@ -16,4 +16,4 @@ async function handleArchiveScenario(params) {
16
16
  export {
17
17
  handleArchiveScenario
18
18
  };
19
- //# sourceMappingURL=archive-scenario-YFD5THOR.js.map
19
+ //# sourceMappingURL=archive-scenario-WJ2A7ETN.js.map
@@ -0,0 +1,15 @@
1
+ import {
2
+ archiveSuite
3
+ } from "./chunk-LUMEZEHL.js";
4
+ import "./chunk-2WPLXEKF.js";
5
+ import "./chunk-BWWY5KEF.js";
6
+
7
+ // src/tools/archive-suite.ts
8
+ async function handleArchiveSuite(params) {
9
+ const result = await archiveSuite(params.id);
10
+ return `Suite ${result.id} has been archived (soft-deleted).`;
11
+ }
12
+ export {
13
+ handleArchiveSuite
14
+ };
15
+ //# sourceMappingURL=archive-suite-4JOM4SSL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/archive-suite.ts"],"sourcesContent":["import { archiveSuite as apiArchiveSuite } from \"../langwatch-api-suites.js\";\n\n/**\n * Handles the platform_archive_suite MCP tool invocation.\n */\nexport async function handleArchiveSuite(params: {\n id: string;\n}): Promise<string> {\n const result = await apiArchiveSuite(params.id);\n\n return `Suite ${result.id} has been archived (soft-deleted).`;\n}\n"],"mappings":";;;;;;;AAKA,eAAsB,mBAAmB,QAErB;AAClB,QAAM,SAAS,MAAM,aAAgB,OAAO,EAAE;AAE9C,SAAO,SAAS,OAAO,EAAE;AAC3B;","names":[]}
@@ -0,0 +1,19 @@
1
+ import {
2
+ assignPromptTag
3
+ } from "./chunk-2WPLXEKF.js";
4
+ import "./chunk-BWWY5KEF.js";
5
+
6
+ // src/tools/assign-prompt-tag.ts
7
+ async function handleAssignPromptTag(params) {
8
+ await assignPromptTag({ idOrHandle: params.idOrHandle, tag: params.tag, versionId: params.versionId });
9
+ const lines = [];
10
+ lines.push("Tag assigned successfully!\n");
11
+ lines.push(`**Prompt**: ${params.idOrHandle}`);
12
+ lines.push(`**Tag**: ${params.tag}`);
13
+ lines.push(`**Version ID**: ${params.versionId}`);
14
+ return lines.join("\n");
15
+ }
16
+ export {
17
+ handleAssignPromptTag
18
+ };
19
+ //# sourceMappingURL=assign-prompt-tag-GL7EAAF3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/assign-prompt-tag.ts"],"sourcesContent":["import { assignPromptTag as apiAssignPromptTag } from \"../langwatch-api.js\";\n\nexport async function handleAssignPromptTag(params: {\n idOrHandle: string;\n tag: string;\n versionId: string;\n}): Promise<string> {\n await apiAssignPromptTag({ idOrHandle: params.idOrHandle, tag: params.tag, versionId: params.versionId });\n\n const lines: string[] = [];\n lines.push(\"Tag assigned successfully!\\n\");\n lines.push(`**Prompt**: ${params.idOrHandle}`);\n lines.push(`**Tag**: ${params.tag}`);\n lines.push(`**Version ID**: ${params.versionId}`);\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAEA,eAAsB,sBAAsB,QAIxB;AAClB,QAAM,gBAAmB,EAAE,YAAY,OAAO,YAAY,KAAK,OAAO,KAAK,WAAW,OAAO,UAAU,CAAC;AAExG,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,8BAA8B;AACzC,QAAM,KAAK,eAAe,OAAO,UAAU,EAAE;AAC7C,QAAM,KAAK,YAAY,OAAO,GAAG,EAAE;AACnC,QAAM,KAAK,mBAAmB,OAAO,SAAS,EAAE;AAChD,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeRequest
3
- } from "./chunk-LLRQIF52.js";
3
+ } from "./chunk-2WPLXEKF.js";
4
4
 
5
5
  // src/langwatch-api-scenarios.ts
6
6
  async function listScenarios() {
@@ -37,4 +37,4 @@ export {
37
37
  updateScenario,
38
38
  archiveScenario
39
39
  };
40
- //# sourceMappingURL=chunk-6U4TCGFC.js.map
40
+ //# sourceMappingURL=chunk-2GT7IFWK.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getConfig,
3
3
  requireApiKey
4
- } from "./chunk-AAQNA53E.js";
4
+ } from "./chunk-BWWY5KEF.js";
5
5
 
6
6
  // src/langwatch-api.ts
7
7
  async function makeRequest(method, path, body) {
@@ -23,6 +23,9 @@ async function makeRequest(method, path, body) {
23
23
  `LangWatch API error ${response.status}: ${responseBody}`
24
24
  );
25
25
  }
26
+ if (response.status === 204 || response.headers?.get("content-length") === "0") {
27
+ return null;
28
+ }
26
29
  return response.json();
27
30
  }
28
31
  async function searchTraces(params) {
@@ -48,8 +51,11 @@ async function getAnalyticsTimeseries(params) {
48
51
  async function listPrompts() {
49
52
  return makeRequest("GET", "/api/prompts");
50
53
  }
51
- async function getPrompt(idOrHandle, version) {
52
- const query = version != null ? `?version=${version}` : "";
54
+ async function getPrompt(idOrHandle, options) {
55
+ const params = new URLSearchParams();
56
+ if (options?.version != null) params.set("version", String(options.version));
57
+ if (options?.tag) params.set("tag", options.tag);
58
+ const query = params.toString() ? `?${params}` : "";
53
59
  return makeRequest(
54
60
  "GET",
55
61
  `/api/prompts/${encodeURIComponent(idOrHandle)}${query}`
@@ -69,6 +75,39 @@ async function updatePrompt(idOrHandle, data) {
69
75
  data
70
76
  );
71
77
  }
78
+ async function assignPromptTag({
79
+ idOrHandle,
80
+ tag,
81
+ versionId
82
+ }) {
83
+ return makeRequest(
84
+ "PUT",
85
+ `/api/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,
86
+ { versionId }
87
+ );
88
+ }
89
+ async function listPromptTags() {
90
+ return makeRequest("GET", "/api/prompts/tags");
91
+ }
92
+ async function createPromptTag(name) {
93
+ return makeRequest("POST", "/api/prompts/tags", { name });
94
+ }
95
+ async function renamePromptTag({
96
+ tag,
97
+ name
98
+ }) {
99
+ return makeRequest(
100
+ "PUT",
101
+ `/api/prompts/tags/${encodeURIComponent(tag)}`,
102
+ { name }
103
+ );
104
+ }
105
+ async function deletePromptTag(tag) {
106
+ return makeRequest(
107
+ "DELETE",
108
+ `/api/prompts/tags/${encodeURIComponent(tag)}`
109
+ );
110
+ }
72
111
 
73
112
  export {
74
113
  makeRequest,
@@ -78,6 +117,11 @@ export {
78
117
  listPrompts,
79
118
  getPrompt,
80
119
  createPrompt,
81
- updatePrompt
120
+ updatePrompt,
121
+ assignPromptTag,
122
+ listPromptTags,
123
+ createPromptTag,
124
+ renamePromptTag,
125
+ deletePromptTag
82
126
  };
83
- //# sourceMappingURL=chunk-LLRQIF52.js.map
127
+ //# sourceMappingURL=chunk-2WPLXEKF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langwatch-api.ts"],"sourcesContent":["import { getConfig, requireApiKey } from \"./config.js\";\n\n// --- Response types ---\n\nexport interface TraceSearchResult {\n trace_id: string;\n formatted_trace?: string;\n input?: { value: string };\n output?: { value: string };\n timestamps?: { started_at?: string | number };\n metadata?: Record<string, unknown>;\n error?: Record<string, unknown>;\n}\n\nexport interface SearchTracesResponse {\n traces: TraceSearchResult[];\n pagination?: {\n totalHits?: number;\n scrollId?: string;\n };\n}\n\nexport interface TraceDetailResponse {\n trace_id: string;\n formatted_trace?: string;\n input?: { value: string };\n output?: { value: string };\n timestamps?: {\n started_at?: string | number;\n updated_at?: string | number;\n inserted_at?: string | number;\n };\n metadata?: {\n user_id?: string;\n thread_id?: string;\n customer_id?: string;\n labels?: string[];\n [key: string]: unknown;\n };\n error?: Record<string, unknown>;\n ascii_tree?: string;\n evaluations?: Array<{\n evaluator_id?: string;\n name?: string;\n score?: number;\n passed?: boolean;\n label?: string;\n }>;\n spans?: Array<{\n span_id: string;\n name?: string;\n type?: string;\n model?: string;\n input?: { value: string };\n output?: { value: string };\n timestamps?: { started_at?: number; finished_at?: number };\n metrics?: {\n completion_time_ms?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n tokens_estimated?: boolean;\n cost?: number;\n };\n }>;\n}\n\nexport interface AnalyticsBucket {\n date: string;\n [key: string]: unknown;\n}\n\nexport interface AnalyticsTimeseriesResponse {\n currentPeriod: AnalyticsBucket[];\n previousPeriod: AnalyticsBucket[];\n}\n\nexport interface PromptSummary {\n id?: string;\n handle?: string;\n name?: string;\n latestVersionNumber?: number;\n version?: number;\n}\n\nexport interface PromptVersion {\n version?: number;\n commitMessage?: string;\n model?: string;\n messages?: Array<{ role: string; content: string }>;\n}\n\nexport interface PromptDetailResponse extends PromptSummary {\n versions?: PromptVersion[];\n model?: string;\n messages?: Array<{ role: string; content: string }>;\n prompt?: Array<{ role: string; content: string }>;\n}\n\nexport interface PromptMutationResponse {\n id?: string;\n handle?: string;\n name?: string;\n latestVersionNumber?: number;\n}\n\n// --- HTTP client ---\n\n/**\n * Sends an HTTP request to the LangWatch API.\n *\n * Builds the full URL from the configured endpoint, adds authentication,\n * and handles JSON serialization/deserialization.\n *\n * @throws Error with status code and response body when the response is not OK\n */\nexport async function makeRequest(\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\",\n path: string,\n body?: unknown\n): Promise<unknown> {\n const url = getConfig().endpoint + path;\n const headers: Record<string, string> = {\n \"X-Auth-Token\": requireApiKey(),\n };\n\n if (body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const response = await fetch(url, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!response.ok) {\n const responseBody = await response.text();\n throw new Error(\n `LangWatch API error ${response.status}: ${responseBody}`\n );\n }\n\n if (response.status === 204 || response.headers?.get(\"content-length\") === \"0\") {\n return null;\n }\n return response.json();\n}\n\n/** Searches traces with optional filters and pagination. */\nexport async function searchTraces(params: {\n query?: string;\n filters?: Record<string, string[]>;\n startDate: number;\n endDate: number;\n pageSize?: number;\n pageOffset?: number;\n scrollId?: string;\n format?: \"digest\" | \"json\";\n}): Promise<SearchTracesResponse> {\n const { format = \"digest\", ...rest } = params;\n return makeRequest(\"POST\", \"/api/traces/search\", {\n ...rest,\n format,\n }) as Promise<SearchTracesResponse>;\n}\n\n/** Retrieves a single trace by its ID. */\nexport async function getTraceById(\n traceId: string,\n format: \"digest\" | \"json\" = \"digest\"\n): Promise<TraceDetailResponse> {\n return makeRequest(\n \"GET\",\n `/api/traces/${encodeURIComponent(traceId)}?format=${format}`\n ) as Promise<TraceDetailResponse>;\n}\n\n/** Fetches analytics timeseries data for the given metrics and date range. */\nexport async function getAnalyticsTimeseries(params: {\n series: Array<{\n metric: string;\n aggregation: string;\n key?: string;\n subkey?: string;\n }>;\n startDate: number;\n endDate: number;\n timeZone?: string;\n groupBy?: string;\n groupByKey?: string;\n filters?: Record<string, string[]>;\n}): Promise<AnalyticsTimeseriesResponse> {\n return makeRequest(\n \"POST\",\n \"/api/analytics/timeseries\",\n params\n ) as Promise<AnalyticsTimeseriesResponse>;\n}\n\n/** Lists all prompts in the project. */\nexport async function listPrompts(): Promise<PromptSummary[]> {\n return makeRequest(\"GET\", \"/api/prompts\") as Promise<PromptSummary[]>;\n}\n\n/** Retrieves a single prompt by ID or handle. */\nexport async function getPrompt(\n idOrHandle: string,\n options?: { version?: number; tag?: string }\n): Promise<PromptDetailResponse> {\n const params = new URLSearchParams();\n if (options?.version != null) params.set(\"version\", String(options.version));\n if (options?.tag) params.set(\"tag\", options.tag);\n const query = params.toString() ? `?${params}` : \"\";\n return makeRequest(\n \"GET\",\n `/api/prompts/${encodeURIComponent(idOrHandle)}${query}`\n ) as Promise<PromptDetailResponse>;\n}\n\n/** Creates a new prompt. */\nexport async function createPrompt(data: {\n handle: string;\n messages: Array<{ role: string; content: string }>;\n model: string;\n tags?: string[];\n}): Promise<PromptMutationResponse> {\n return makeRequest(\n \"POST\",\n \"/api/prompts\",\n data\n ) as Promise<PromptMutationResponse>;\n}\n\n/** Updates an existing prompt by ID or handle. */\nexport async function updatePrompt(\n idOrHandle: string,\n data: {\n messages?: Array<{ role: string; content: string }>;\n model?: string;\n commitMessage: string;\n tags?: string[];\n }\n): Promise<PromptMutationResponse> {\n return makeRequest(\n \"PUT\",\n `/api/prompts/${encodeURIComponent(idOrHandle)}`,\n data\n ) as Promise<PromptMutationResponse>;\n}\n\n/** Assigns a tag to a specific prompt version. */\nexport async function assignPromptTag({\n idOrHandle,\n tag,\n versionId,\n}: {\n idOrHandle: string;\n tag: string;\n versionId: string;\n}): Promise<unknown> {\n return makeRequest(\n \"PUT\",\n `/api/prompts/${encodeURIComponent(idOrHandle)}/tags/${encodeURIComponent(tag)}`,\n { versionId }\n );\n}\n\n/** Lists all prompt tag definitions for the organization. */\nexport async function listPromptTags(): Promise<unknown> {\n return makeRequest(\"GET\", \"/api/prompts/tags\");\n}\n\n/** Creates a custom prompt tag definition. */\nexport async function createPromptTag(name: string): Promise<unknown> {\n return makeRequest(\"POST\", \"/api/prompts/tags\", { name });\n}\n\n/** Renames an existing prompt tag. */\nexport async function renamePromptTag({\n tag,\n name,\n}: {\n tag: string;\n name: string;\n}): Promise<unknown> {\n return makeRequest(\n \"PUT\",\n `/api/prompts/tags/${encodeURIComponent(tag)}`,\n { name }\n );\n}\n\n/** Deletes a prompt tag and all its assignments. */\nexport async function deletePromptTag(tag: string): Promise<unknown> {\n return makeRequest(\n \"DELETE\",\n `/api/prompts/tags/${encodeURIComponent(tag)}`\n );\n}\n"],"mappings":";;;;;;AAmHA,eAAsB,YACpB,QACA,MACA,MACkB;AAClB,QAAM,MAAM,UAAU,EAAE,WAAW;AACnC,QAAM,UAAkC;AAAA,IACtC,gBAAgB,cAAc;AAAA,EAChC;AAEA,MAAI,SAAS,QAAW;AACtB,YAAQ,cAAc,IAAI;AAAA,EAC5B;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC;AAAA,IACA;AAAA,IACA,GAAI,SAAS,SAAY,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE,IAAI,CAAC;AAAA,EAC7D,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,eAAe,MAAM,SAAS,KAAK;AACzC,UAAM,IAAI;AAAA,MACR,uBAAuB,SAAS,MAAM,KAAK,YAAY;AAAA,IACzD;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,OAAO,SAAS,SAAS,IAAI,gBAAgB,MAAM,KAAK;AAC9E,WAAO;AAAA,EACT;AACA,SAAO,SAAS,KAAK;AACvB;AAGA,eAAsB,aAAa,QASD;AAChC,QAAM,EAAE,SAAS,UAAU,GAAG,KAAK,IAAI;AACvC,SAAO,YAAY,QAAQ,sBAAsB;AAAA,IAC/C,GAAG;AAAA,IACH;AAAA,EACF,CAAC;AACH;AAGA,eAAsB,aACpB,SACA,SAA4B,UACE;AAC9B,SAAO;AAAA,IACL;AAAA,IACA,eAAe,mBAAmB,OAAO,CAAC,WAAW,MAAM;AAAA,EAC7D;AACF;AAGA,eAAsB,uBAAuB,QAaJ;AACvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,eAAsB,cAAwC;AAC5D,SAAO,YAAY,OAAO,cAAc;AAC1C;AAGA,eAAsB,UACpB,YACA,SAC+B;AAC/B,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,SAAS,WAAW,KAAM,QAAO,IAAI,WAAW,OAAO,QAAQ,OAAO,CAAC;AAC3E,MAAI,SAAS,IAAK,QAAO,IAAI,OAAO,QAAQ,GAAG;AAC/C,QAAM,QAAQ,OAAO,SAAS,IAAI,IAAI,MAAM,KAAK;AACjD,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,UAAU,CAAC,GAAG,KAAK;AAAA,EACxD;AACF;AAGA,eAAsB,aAAa,MAKC;AAClC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,eAAsB,aACpB,YACA,MAMiC;AACjC,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,UAAU,CAAC;AAAA,IAC9C;AAAA,EACF;AACF;AAGA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,GAIqB;AACnB,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,UAAU,CAAC,SAAS,mBAAmB,GAAG,CAAC;AAAA,IAC9E,EAAE,UAAU;AAAA,EACd;AACF;AAGA,eAAsB,iBAAmC;AACvD,SAAO,YAAY,OAAO,mBAAmB;AAC/C;AAGA,eAAsB,gBAAgB,MAAgC;AACpE,SAAO,YAAY,QAAQ,qBAAqB,EAAE,KAAK,CAAC;AAC1D;AAGA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA;AACF,GAGqB;AACnB,SAAO;AAAA,IACL;AAAA,IACA,qBAAqB,mBAAmB,GAAG,CAAC;AAAA,IAC5C,EAAE,KAAK;AAAA,EACT;AACF;AAGA,eAAsB,gBAAgB,KAA+B;AACnE,SAAO;AAAA,IACL;AAAA,IACA,qBAAqB,mBAAmB,GAAG,CAAC;AAAA,EAC9C;AACF;","names":[]}
@@ -0,0 +1,71 @@
1
+ import {
2
+ makeRequest
3
+ } from "./chunk-2WPLXEKF.js";
4
+
5
+ // src/langwatch-api-agents.ts
6
+ async function listAgents(params) {
7
+ const query = new URLSearchParams();
8
+ if (params?.page) query.set("page", String(params.page));
9
+ if (params?.limit) query.set("limit", String(params.limit));
10
+ const qs = query.toString() ? `?${query}` : "";
11
+ return makeRequest("GET", `/api/agents${qs}`);
12
+ }
13
+ async function getAgent(id) {
14
+ return makeRequest(
15
+ "GET",
16
+ `/api/agents/${encodeURIComponent(id)}`
17
+ );
18
+ }
19
+ async function createAgent(data) {
20
+ return makeRequest("POST", "/api/agents", data);
21
+ }
22
+ async function updateAgent(params) {
23
+ const { id, ...data } = params;
24
+ return makeRequest(
25
+ "PATCH",
26
+ `/api/agents/${encodeURIComponent(id)}`,
27
+ data
28
+ );
29
+ }
30
+ async function runAgent(id, input) {
31
+ const agent = await getAgent(id);
32
+ const config = agent.config ?? {};
33
+ if (agent.type === "http") {
34
+ const url = config.url;
35
+ if (!url) {
36
+ throw new Error("HTTP agent has no URL configured");
37
+ }
38
+ const response = await fetch(url, {
39
+ method: "POST",
40
+ headers: { "Content-Type": "application/json" },
41
+ body: JSON.stringify(input ?? {})
42
+ });
43
+ const result2 = await response.json();
44
+ return { agentType: "http", result: result2 };
45
+ }
46
+ const workflowId = config.workflowId;
47
+ if (!workflowId) {
48
+ throw new Error(
49
+ `Agent "${agent.name}" (type: ${agent.type}) cannot be executed directly. Only HTTP agents and workflow-linked agents can be run.`
50
+ );
51
+ }
52
+ const { runWorkflow } = await import("./langwatch-api-workflows-VJRIIDZ7.js");
53
+ const result = await runWorkflow(workflowId, input);
54
+ return { agentType: agent.type, result };
55
+ }
56
+ async function deleteAgent(id) {
57
+ return makeRequest(
58
+ "DELETE",
59
+ `/api/agents/${encodeURIComponent(id)}`
60
+ );
61
+ }
62
+
63
+ export {
64
+ listAgents,
65
+ getAgent,
66
+ createAgent,
67
+ updateAgent,
68
+ runAgent,
69
+ deleteAgent
70
+ };
71
+ //# sourceMappingURL=chunk-4AUB2BIA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langwatch-api-agents.ts"],"sourcesContent":["import { makeRequest } from \"./langwatch-api.js\";\n\nexport interface AgentSummary {\n id: string;\n name: string;\n type: string;\n config: Record<string, unknown> | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AgentListResponse {\n data: AgentSummary[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport async function listAgents(params?: {\n page?: number;\n limit?: number;\n}): Promise<AgentListResponse> {\n const query = new URLSearchParams();\n if (params?.page) query.set(\"page\", String(params.page));\n if (params?.limit) query.set(\"limit\", String(params.limit));\n const qs = query.toString() ? `?${query}` : \"\";\n return makeRequest(\"GET\", `/api/agents${qs}`) as Promise<AgentListResponse>;\n}\n\nexport async function getAgent(id: string): Promise<AgentSummary> {\n return makeRequest(\n \"GET\",\n `/api/agents/${encodeURIComponent(id)}`,\n ) as Promise<AgentSummary>;\n}\n\nexport async function createAgent(data: {\n name: string;\n type: string;\n config: Record<string, unknown>;\n}): Promise<AgentSummary> {\n return makeRequest(\"POST\", \"/api/agents\", data) as Promise<AgentSummary>;\n}\n\nexport async function updateAgent(params: {\n id: string;\n name?: string;\n type?: string;\n config?: Record<string, unknown>;\n}): Promise<AgentSummary> {\n const { id, ...data } = params;\n return makeRequest(\n \"PATCH\",\n `/api/agents/${encodeURIComponent(id)}`,\n data,\n ) as Promise<AgentSummary>;\n}\n\n/**\n * Run an agent. For HTTP agents, calls the configured URL directly.\n * For workflow-linked agents, calls the workflow run endpoint.\n */\nexport async function runAgent(\n id: string,\n input?: Record<string, unknown>,\n): Promise<{ agentType: string; result: Record<string, unknown> }> {\n const agent = await getAgent(id);\n const config = agent.config ?? {};\n\n if (agent.type === \"http\") {\n const url = (config as Record<string, unknown>).url as string | undefined;\n if (!url) {\n throw new Error(\"HTTP agent has no URL configured\");\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(input ?? {}),\n });\n\n const result = (await response.json()) as Record<string, unknown>;\n return { agentType: \"http\", result };\n }\n\n // For workflow-linked agents, use the workflow run endpoint\n const workflowId = (config as Record<string, unknown>).workflowId as string | undefined;\n if (!workflowId) {\n throw new Error(\n `Agent \"${agent.name}\" (type: ${agent.type}) cannot be executed directly. ` +\n `Only HTTP agents and workflow-linked agents can be run.`,\n );\n }\n\n const { runWorkflow } = await import(\"./langwatch-api-workflows.js\");\n const result = await runWorkflow(workflowId, input);\n return { agentType: agent.type, result };\n}\n\nexport async function deleteAgent(id: string): Promise<{ id: string; name: string }> {\n return makeRequest(\n \"DELETE\",\n `/api/agents/${encodeURIComponent(id)}`,\n ) as Promise<{ id: string; name: string }>;\n}\n"],"mappings":";;;;;AAqBA,eAAsB,WAAW,QAGF;AAC7B,QAAM,QAAQ,IAAI,gBAAgB;AAClC,MAAI,QAAQ,KAAM,OAAM,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AACvD,MAAI,QAAQ,MAAO,OAAM,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAC1D,QAAM,KAAK,MAAM,SAAS,IAAI,IAAI,KAAK,KAAK;AAC5C,SAAO,YAAY,OAAO,cAAc,EAAE,EAAE;AAC9C;AAEA,eAAsB,SAAS,IAAmC;AAChE,SAAO;AAAA,IACL;AAAA,IACA,eAAe,mBAAmB,EAAE,CAAC;AAAA,EACvC;AACF;AAEA,eAAsB,YAAY,MAIR;AACxB,SAAO,YAAY,QAAQ,eAAe,IAAI;AAChD;AAEA,eAAsB,YAAY,QAKR;AACxB,QAAM,EAAE,IAAI,GAAG,KAAK,IAAI;AACxB,SAAO;AAAA,IACL;AAAA,IACA,eAAe,mBAAmB,EAAE,CAAC;AAAA,IACrC;AAAA,EACF;AACF;AAMA,eAAsB,SACpB,IACA,OACiE;AACjE,QAAM,QAAQ,MAAM,SAAS,EAAE;AAC/B,QAAM,SAAS,MAAM,UAAU,CAAC;AAEhC,MAAI,MAAM,SAAS,QAAQ;AACzB,UAAM,MAAO,OAAmC;AAChD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,SAAS,CAAC,CAAC;AAAA,IAClC,CAAC;AAED,UAAMA,UAAU,MAAM,SAAS,KAAK;AACpC,WAAO,EAAE,WAAW,QAAQ,QAAAA,QAAO;AAAA,EACrC;AAGA,QAAM,aAAc,OAAmC;AACvD,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR,UAAU,MAAM,IAAI,YAAY,MAAM,IAAI;AAAA,IAE5C;AAAA,EACF;AAEA,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,uCAA8B;AACnE,QAAM,SAAS,MAAM,YAAY,YAAY,KAAK;AAClD,SAAO,EAAE,WAAW,MAAM,MAAM,OAAO;AACzC;AAEA,eAAsB,YAAY,IAAmD;AACnF,SAAO;AAAA,IACL;AAAA,IACA,eAAe,mBAAmB,EAAE,CAAC;AAAA,EACvC;AACF;","names":["result"]}
@@ -0,0 +1,71 @@
1
+ // src/config.ts
2
+ import { AsyncLocalStorage } from "async_hooks";
3
+ var GLOBAL_KEY = "__langwatch_mcp_config";
4
+ var STORAGE_KEY = "__langwatch_mcp_config_storage";
5
+ function getGlobalState() {
6
+ const g = globalThis;
7
+ if (!g[GLOBAL_KEY]) {
8
+ g[GLOBAL_KEY] = void 0;
9
+ }
10
+ if (!g[STORAGE_KEY]) {
11
+ g[STORAGE_KEY] = new AsyncLocalStorage();
12
+ }
13
+ return {
14
+ get globalConfig() {
15
+ return g[GLOBAL_KEY];
16
+ },
17
+ set globalConfig(val) {
18
+ g[GLOBAL_KEY] = val;
19
+ },
20
+ get configStorage() {
21
+ return g[STORAGE_KEY];
22
+ }
23
+ };
24
+ }
25
+ function initConfig(args) {
26
+ const state = getGlobalState();
27
+ state.globalConfig = {
28
+ apiKey: args.apiKey || process.env.LANGWATCH_API_KEY,
29
+ endpoint: args.endpoint || process.env.LANGWATCH_ENDPOINT || "https://app.langwatch.ai"
30
+ };
31
+ }
32
+ function getConfig() {
33
+ const state = getGlobalState();
34
+ const scoped = state.configStorage.getStore();
35
+ if (scoped) return scoped;
36
+ if (!state.globalConfig) {
37
+ console.error(
38
+ "[MCP config] getConfig() failed: globalConfig is null, no scoped config active. Was initConfig() called? Stack:",
39
+ new Error().stack
40
+ );
41
+ throw new Error("Config not initialized");
42
+ }
43
+ return state.globalConfig;
44
+ }
45
+ function requireApiKey() {
46
+ const config = getConfig();
47
+ if (!config.apiKey) {
48
+ const state = getGlobalState();
49
+ const hasScoped = !!state.configStorage.getStore();
50
+ console.error(
51
+ `[MCP config] requireApiKey() failed: apiKey is undefined. scopedConfig=${hasScoped}, endpoint=${config.endpoint}. In HTTP mode, the API key should be set per-session via runWithConfig(). Stack:`,
52
+ new Error().stack
53
+ );
54
+ throw new Error(
55
+ "LANGWATCH_API_KEY is required. Set it via --apiKey flag or LANGWATCH_API_KEY environment variable."
56
+ );
57
+ }
58
+ return config.apiKey;
59
+ }
60
+ function runWithConfig(config, fn) {
61
+ const state = getGlobalState();
62
+ return state.configStorage.run(config, fn);
63
+ }
64
+
65
+ export {
66
+ initConfig,
67
+ getConfig,
68
+ requireApiKey,
69
+ runWithConfig
70
+ };
71
+ //# sourceMappingURL=chunk-BWWY5KEF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface McpConfig {\n apiKey: string | undefined;\n endpoint: string;\n}\n\n// ---------------------------------------------------------------------------\n// Singleton storage on globalThis\n//\n// When the langwatch app (CJS, no \"type\": \"module\") imports this module,\n// tsx creates a CJS-cached copy. When mcp-server's own ESM dist chunks\n// do `await import(\"./search-traces-*.js\")`, Node creates a separate\n// ESM-cached copy. Module-level variables are NOT shared between them.\n//\n// By storing config on globalThis, both CJS and ESM instances read/write\n// the same object, fixing the \"Config not initialized\" error that occurs\n// when initConfig() runs on the CJS side but tool handlers execute on\n// the ESM side.\n// ---------------------------------------------------------------------------\n\nconst GLOBAL_KEY = \"__langwatch_mcp_config\" as const;\nconst STORAGE_KEY = \"__langwatch_mcp_config_storage\" as const;\n\ninterface McpGlobalState {\n globalConfig: McpConfig | undefined;\n configStorage: AsyncLocalStorage<McpConfig>;\n}\n\nfunction getGlobalState(): McpGlobalState {\n const g = globalThis as unknown as Record<string, unknown>;\n if (!g[GLOBAL_KEY]) {\n g[GLOBAL_KEY] = undefined;\n }\n if (!g[STORAGE_KEY]) {\n g[STORAGE_KEY] = new AsyncLocalStorage<McpConfig>();\n }\n return {\n get globalConfig() {\n return g[GLOBAL_KEY] as McpConfig | undefined;\n },\n set globalConfig(val: McpConfig | undefined) {\n g[GLOBAL_KEY] = val;\n },\n get configStorage() {\n return g[STORAGE_KEY] as AsyncLocalStorage<McpConfig>;\n },\n };\n}\n\nexport function initConfig(args: { apiKey?: string; endpoint?: string }): void {\n const state = getGlobalState();\n state.globalConfig = {\n apiKey: args.apiKey || process.env.LANGWATCH_API_KEY,\n endpoint:\n args.endpoint ||\n process.env.LANGWATCH_ENDPOINT ||\n \"https://app.langwatch.ai\",\n };\n}\n\n/**\n * Returns the current config: the per-request scoped config if inside\n * a `runWithConfig()` callback, otherwise the global config.\n */\nexport function getConfig(): McpConfig {\n const state = getGlobalState();\n const scoped = state.configStorage.getStore();\n if (scoped) return scoped;\n if (!state.globalConfig) {\n console.error(\n \"[MCP config] getConfig() failed: globalConfig is null, no scoped config active. \" +\n \"Was initConfig() called? Stack:\",\n new Error().stack,\n );\n throw new Error(\"Config not initialized\");\n }\n return state.globalConfig;\n}\n\nexport function requireApiKey(): string {\n const config = getConfig();\n if (!config.apiKey) {\n const state = getGlobalState();\n const hasScoped = !!state.configStorage.getStore();\n console.error(\n \"[MCP config] requireApiKey() failed: apiKey is undefined. \" +\n `scopedConfig=${hasScoped}, endpoint=${config.endpoint}. ` +\n \"In HTTP mode, the API key should be set per-session via runWithConfig(). Stack:\",\n new Error().stack,\n );\n throw new Error(\n \"LANGWATCH_API_KEY is required. Set it via --apiKey flag or LANGWATCH_API_KEY environment variable.\"\n );\n }\n return config.apiKey;\n}\n\n/**\n * Runs `fn` with a per-request scoped config. All calls to `getConfig()`\n * and `requireApiKey()` within `fn` (including async continuations) will\n * see the provided config instead of the global one.\n */\nexport function runWithConfig<T>(config: McpConfig, fn: () => T): T {\n const state = getGlobalState();\n return state.configStorage.run(config, fn);\n}\n"],"mappings":";AAAA,SAAS,yBAAyB;AAqBlC,IAAM,aAAa;AACnB,IAAM,cAAc;AAOpB,SAAS,iBAAiC;AACxC,QAAM,IAAI;AACV,MAAI,CAAC,EAAE,UAAU,GAAG;AAClB,MAAE,UAAU,IAAI;AAAA,EAClB;AACA,MAAI,CAAC,EAAE,WAAW,GAAG;AACnB,MAAE,WAAW,IAAI,IAAI,kBAA6B;AAAA,EACpD;AACA,SAAO;AAAA,IACL,IAAI,eAAe;AACjB,aAAO,EAAE,UAAU;AAAA,IACrB;AAAA,IACA,IAAI,aAAa,KAA4B;AAC3C,QAAE,UAAU,IAAI;AAAA,IAClB;AAAA,IACA,IAAI,gBAAgB;AAClB,aAAO,EAAE,WAAW;AAAA,IACtB;AAAA,EACF;AACF;AAEO,SAAS,WAAW,MAAoD;AAC7E,QAAM,QAAQ,eAAe;AAC7B,QAAM,eAAe;AAAA,IACnB,QAAQ,KAAK,UAAU,QAAQ,IAAI;AAAA,IACnC,UACE,KAAK,YACL,QAAQ,IAAI,sBACZ;AAAA,EACJ;AACF;AAMO,SAAS,YAAuB;AACrC,QAAM,QAAQ,eAAe;AAC7B,QAAM,SAAS,MAAM,cAAc,SAAS;AAC5C,MAAI,OAAQ,QAAO;AACnB,MAAI,CAAC,MAAM,cAAc;AACvB,YAAQ;AAAA,MACN;AAAA,MAEA,IAAI,MAAM,EAAE;AAAA,IACd;AACA,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACA,SAAO,MAAM;AACf;AAEO,SAAS,gBAAwB;AACtC,QAAM,SAAS,UAAU;AACzB,MAAI,CAAC,OAAO,QAAQ;AAClB,UAAM,QAAQ,eAAe;AAC7B,UAAM,YAAY,CAAC,CAAC,MAAM,cAAc,SAAS;AACjD,YAAQ;AAAA,MACN,0EACkB,SAAS,cAAc,OAAO,QAAQ;AAAA,MAExD,IAAI,MAAM,EAAE;AAAA,IACd;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO;AAChB;AAOO,SAAS,cAAiB,QAAmB,IAAgB;AAClE,QAAM,QAAQ,eAAe;AAC7B,SAAO,MAAM,cAAc,IAAI,QAAQ,EAAE;AAC3C;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeRequest
3
- } from "./chunk-LLRQIF52.js";
3
+ } from "./chunk-2WPLXEKF.js";
4
4
 
5
5
  // src/langwatch-api-model-providers.ts
6
6
  async function listModelProviders() {
@@ -19,4 +19,4 @@ export {
19
19
  listModelProviders,
20
20
  setModelProvider
21
21
  };
22
- //# sourceMappingURL=chunk-IX6QJKAD.js.map
22
+ //# sourceMappingURL=chunk-CCWCIJJ3.js.map