@langwatch/mcp-server 0.6.0 → 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 +30 -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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-agent.ts"],"sourcesContent":["import { getAgent as apiGetAgent } from \"../langwatch-api-agents.js\";\n\nexport async function handleGetAgent(params: { id: string }): Promise<string> {\n const agent = await apiGetAgent(params.id);\n\n const lines: string[] = [];\n lines.push(`# ${agent.name}\\n`);\n lines.push(`**ID**: ${agent.id}`);\n lines.push(`**Type**: ${agent.type}`);\n lines.push(`**Created**: ${agent.createdAt}`);\n lines.push(`**Updated**: ${agent.updatedAt}`);\n\n if (agent.config && Object.keys(agent.config).length > 0) {\n lines.push(\"\\n## Config\\n\");\n lines.push(\"```json\");\n lines.push(JSON.stringify(agent.config, null, 2));\n lines.push(\"```\");\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,eAAe,QAAyC;AAC5E,QAAM,QAAQ,MAAM,SAAY,OAAO,EAAE;AAEzC,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,MAAM,IAAI;AAAA,CAAI;AAC9B,QAAM,KAAK,WAAW,MAAM,EAAE,EAAE;AAChC,QAAM,KAAK,aAAa,MAAM,IAAI,EAAE;AACpC,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAC5C,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAE5C,MAAI,MAAM,UAAU,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS,GAAG;AACxD,UAAM,KAAK,eAAe;AAC1B,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK,UAAU,MAAM,QAAQ,MAAM,CAAC,CAAC;AAChD,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -3,10 +3,17 @@ import {
3
3
  } from "./chunk-ZXKLPC2E.js";
4
4
  import {
5
5
  getAnalyticsTimeseries
6
- } from "./chunk-LLRQIF52.js";
7
- import "./chunk-AAQNA53E.js";
6
+ } from "./chunk-2WPLXEKF.js";
7
+ import "./chunk-BWWY5KEF.js";
8
8
 
9
9
  // src/tools/get-analytics.ts
10
+ function getGroupedData(bucket, groupBy) {
11
+ const data = bucket[groupBy];
12
+ if (typeof data === "object" && data !== null && !Array.isArray(data)) {
13
+ return data;
14
+ }
15
+ return void 0;
16
+ }
10
17
  async function handleGetAnalytics(params) {
11
18
  const now = Date.now();
12
19
  const startDate = params.startDate ? parseRelativeDate(params.startDate) : now - 7 * 864e5;
@@ -33,15 +40,25 @@ async function handleGetAnalytics(params) {
33
40
  const currentPeriod = result.currentPeriod ?? [];
34
41
  if (currentPeriod.length === 0) {
35
42
  lines.push("No data available for this period.");
43
+ } else if (params.groupBy && currentPeriod.some((b) => getGroupedData(b, params.groupBy) !== void 0)) {
44
+ lines.push("| Date | Group | Value |");
45
+ lines.push("|------|-------|-------|");
46
+ for (const bucket of currentPeriod) {
47
+ const groups = getGroupedData(bucket, params.groupBy);
48
+ if (!groups) continue;
49
+ for (const [groupKey, metrics] of Object.entries(groups)) {
50
+ const value = Object.values(metrics).find((v) => typeof v === "number") ?? "N/A";
51
+ lines.push(`| ${bucket.date} | ${groupKey} | ${value} |`);
52
+ }
53
+ }
36
54
  } else {
37
55
  lines.push("| Date | Value |");
38
56
  lines.push("|------|-------|");
39
57
  for (const bucket of currentPeriod) {
40
- const date = bucket.date;
41
58
  const value = Object.entries(bucket).find(
42
59
  ([k]) => k !== "date" && typeof bucket[k] === "number"
43
60
  )?.[1] ?? "N/A";
44
- lines.push(`| ${date} | ${value} |`);
61
+ lines.push(`| ${bucket.date} | ${value} |`);
45
62
  }
46
63
  }
47
64
  lines.push(
@@ -52,4 +69,4 @@ async function handleGetAnalytics(params) {
52
69
  export {
53
70
  handleGetAnalytics
54
71
  };
55
- //# sourceMappingURL=get-analytics-4YJW4S5L.js.map
72
+ //# sourceMappingURL=get-analytics-2OHV763I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-analytics.ts"],"sourcesContent":["import type { AnalyticsBucket } from \"../langwatch-api.js\";\nimport { getAnalyticsTimeseries as apiGetAnalytics } from \"../langwatch-api.js\";\nimport { parseRelativeDate } from \"../utils/date-parsing.js\";\n\ntype GroupedData = Record<string, Record<string, number>>;\n\nfunction getGroupedData(\n bucket: AnalyticsBucket,\n groupBy: string,\n): GroupedData | undefined {\n const data = bucket[groupBy];\n if (typeof data === \"object\" && data !== null && !Array.isArray(data)) {\n return data as GroupedData;\n }\n return undefined;\n}\n\n/**\n * Handles the get_analytics MCP tool invocation.\n *\n * Queries analytics timeseries from LangWatch and formats the results\n * as an AI-readable markdown table.\n */\nexport async function handleGetAnalytics(params: {\n metric: string;\n aggregation?: string;\n startDate?: string;\n endDate?: string;\n timeZone?: string;\n groupBy?: string;\n filters?: Record<string, string[]>;\n}): Promise<string> {\n const now = Date.now();\n const startDate = params.startDate\n ? parseRelativeDate(params.startDate)\n : now - 7 * 86400000;\n const endDate = params.endDate ? parseRelativeDate(params.endDate) : now;\n\n // Parse metric format \"category.name\"\n const [category, name] = params.metric.includes(\".\")\n ? params.metric.split(\".\", 2)\n : [\"metadata\", params.metric];\n const metricKey = `${category}.${name}`;\n const aggregation = params.aggregation ?? \"avg\";\n\n const result = await apiGetAnalytics({\n series: [{ metric: metricKey, aggregation }],\n startDate,\n endDate,\n timeZone: params.timeZone ?? \"UTC\",\n groupBy: params.groupBy,\n filters: params.filters,\n });\n\n const lines: string[] = [];\n lines.push(`# Analytics: ${metricKey} (${aggregation})\\n`);\n lines.push(\n `Period: ${new Date(startDate).toISOString().split(\"T\")[0]} to ${new Date(endDate).toISOString().split(\"T\")[0]}`\n );\n if (params.groupBy) lines.push(`Grouped by: ${params.groupBy}`);\n lines.push(\"\");\n\n const currentPeriod = result.currentPeriod ?? [];\n if (currentPeriod.length === 0) {\n lines.push(\"No data available for this period.\");\n } else if (\n params.groupBy &&\n currentPeriod.some((b) => getGroupedData(b, params.groupBy!) !== undefined)\n ) {\n lines.push(\"| Date | Group | Value |\");\n lines.push(\"|------|-------|-------|\");\n for (const bucket of currentPeriod) {\n const groups = getGroupedData(bucket, params.groupBy);\n if (!groups) continue;\n for (const [groupKey, metrics] of Object.entries(groups)) {\n const value =\n Object.values(metrics).find((v) => typeof v === \"number\") ?? \"N/A\";\n lines.push(`| ${bucket.date} | ${groupKey} | ${value} |`);\n }\n }\n } else {\n lines.push(\"| Date | Value |\");\n lines.push(\"|------|-------|\");\n for (const bucket of currentPeriod) {\n const value =\n Object.entries(bucket).find(\n ([k]) => k !== \"date\" && typeof bucket[k] === \"number\"\n )?.[1] ?? \"N/A\";\n lines.push(`| ${bucket.date} | ${value} |`);\n }\n }\n\n lines.push(\n \"\\n> Tip: Use `discover_schema` to see all available metrics and aggregation types.\"\n );\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;AAMA,SAAS,eACP,QACA,SACyB;AACzB,QAAM,OAAO,OAAO,OAAO;AAC3B,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,CAAC,MAAM,QAAQ,IAAI,GAAG;AACrE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAQA,eAAsB,mBAAmB,QAQrB;AAClB,QAAM,MAAM,KAAK,IAAI;AACrB,QAAM,YAAY,OAAO,YACrB,kBAAkB,OAAO,SAAS,IAClC,MAAM,IAAI;AACd,QAAM,UAAU,OAAO,UAAU,kBAAkB,OAAO,OAAO,IAAI;AAGrE,QAAM,CAAC,UAAU,IAAI,IAAI,OAAO,OAAO,SAAS,GAAG,IAC/C,OAAO,OAAO,MAAM,KAAK,CAAC,IAC1B,CAAC,YAAY,OAAO,MAAM;AAC9B,QAAM,YAAY,GAAG,QAAQ,IAAI,IAAI;AACrC,QAAM,cAAc,OAAO,eAAe;AAE1C,QAAM,SAAS,MAAM,uBAAgB;AAAA,IACnC,QAAQ,CAAC,EAAE,QAAQ,WAAW,YAAY,CAAC;AAAA,IAC3C;AAAA,IACA;AAAA,IACA,UAAU,OAAO,YAAY;AAAA,IAC7B,SAAS,OAAO;AAAA,IAChB,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,gBAAgB,SAAS,KAAK,WAAW;AAAA,CAAK;AACzD,QAAM;AAAA,IACJ,WAAW,IAAI,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,EAChH;AACA,MAAI,OAAO,QAAS,OAAM,KAAK,eAAe,OAAO,OAAO,EAAE;AAC9D,QAAM,KAAK,EAAE;AAEb,QAAM,gBAAgB,OAAO,iBAAiB,CAAC;AAC/C,MAAI,cAAc,WAAW,GAAG;AAC9B,UAAM,KAAK,oCAAoC;AAAA,EACjD,WACE,OAAO,WACP,cAAc,KAAK,CAAC,MAAM,eAAe,GAAG,OAAO,OAAQ,MAAM,MAAS,GAC1E;AACA,UAAM,KAAK,0BAA0B;AACrC,UAAM,KAAK,0BAA0B;AACrC,eAAW,UAAU,eAAe;AAClC,YAAM,SAAS,eAAe,QAAQ,OAAO,OAAO;AACpD,UAAI,CAAC,OAAQ;AACb,iBAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,MAAM,GAAG;AACxD,cAAM,QACJ,OAAO,OAAO,OAAO,EAAE,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,KAAK;AAC/D,cAAM,KAAK,KAAK,OAAO,IAAI,MAAM,QAAQ,MAAM,KAAK,IAAI;AAAA,MAC1D;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,kBAAkB;AAC7B,eAAW,UAAU,eAAe;AAClC,YAAM,QACJ,OAAO,QAAQ,MAAM,EAAE;AAAA,QACrB,CAAC,CAAC,CAAC,MAAM,MAAM,UAAU,OAAO,OAAO,CAAC,MAAM;AAAA,MAChD,IAAI,CAAC,KAAK;AACZ,YAAM,KAAK,KAAK,OAAO,IAAI,MAAM,KAAK,IAAI;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -0,0 +1,29 @@
1
+ import {
2
+ getDashboard
3
+ } from "./chunk-EUQDVOSU.js";
4
+ import "./chunk-2WPLXEKF.js";
5
+ import "./chunk-BWWY5KEF.js";
6
+
7
+ // src/tools/get-dashboard.ts
8
+ async function handleGetDashboard(params) {
9
+ const dashboard = await getDashboard(params.id);
10
+ const lines = [];
11
+ lines.push(`# ${dashboard.name}
12
+ `);
13
+ lines.push(`**ID**: ${dashboard.id}`);
14
+ lines.push(`**Order**: ${dashboard.order}`);
15
+ lines.push(`**Graphs**: ${Array.isArray(dashboard.graphs) ? dashboard.graphs.length : 0}`);
16
+ lines.push(`**Created**: ${dashboard.createdAt}`);
17
+ lines.push(`**Updated**: ${dashboard.updatedAt}`);
18
+ if (Array.isArray(dashboard.graphs) && dashboard.graphs.length > 0) {
19
+ lines.push("\n## Graphs\n");
20
+ lines.push("```json");
21
+ lines.push(JSON.stringify(dashboard.graphs, null, 2));
22
+ lines.push("```");
23
+ }
24
+ return lines.join("\n");
25
+ }
26
+ export {
27
+ handleGetDashboard
28
+ };
29
+ //# sourceMappingURL=get-dashboard-PC7JDHH6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-dashboard.ts"],"sourcesContent":["import { getDashboard as apiGetDashboard } from \"../langwatch-api-dashboards.js\";\n\nexport async function handleGetDashboard(params: { id: string }): Promise<string> {\n const dashboard = await apiGetDashboard(params.id);\n\n const lines: string[] = [];\n lines.push(`# ${dashboard.name}\\n`);\n lines.push(`**ID**: ${dashboard.id}`);\n lines.push(`**Order**: ${dashboard.order}`);\n lines.push(`**Graphs**: ${Array.isArray(dashboard.graphs) ? dashboard.graphs.length : 0}`);\n lines.push(`**Created**: ${dashboard.createdAt}`);\n lines.push(`**Updated**: ${dashboard.updatedAt}`);\n\n if (Array.isArray(dashboard.graphs) && dashboard.graphs.length > 0) {\n lines.push(\"\\n## Graphs\\n\");\n lines.push(\"```json\");\n lines.push(JSON.stringify(dashboard.graphs, null, 2));\n lines.push(\"```\");\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,mBAAmB,QAAyC;AAChF,QAAM,YAAY,MAAM,aAAgB,OAAO,EAAE;AAEjD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,UAAU,IAAI;AAAA,CAAI;AAClC,QAAM,KAAK,WAAW,UAAU,EAAE,EAAE;AACpC,QAAM,KAAK,cAAc,UAAU,KAAK,EAAE;AAC1C,QAAM,KAAK,eAAe,MAAM,QAAQ,UAAU,MAAM,IAAI,UAAU,OAAO,SAAS,CAAC,EAAE;AACzF,QAAM,KAAK,gBAAgB,UAAU,SAAS,EAAE;AAChD,QAAM,KAAK,gBAAgB,UAAU,SAAS,EAAE;AAEhD,MAAI,MAAM,QAAQ,UAAU,MAAM,KAAK,UAAU,OAAO,SAAS,GAAG;AAClE,UAAM,KAAK,eAAe;AAC1B,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,KAAK,UAAU,UAAU,QAAQ,MAAM,CAAC,CAAC;AACpD,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -0,0 +1,48 @@
1
+ import {
2
+ escapeMarkdown
3
+ } from "./chunk-NUFPTHKU.js";
4
+ import {
5
+ getDataset
6
+ } from "./chunk-WQG2DFHX.js";
7
+ import "./chunk-2WPLXEKF.js";
8
+ import "./chunk-BWWY5KEF.js";
9
+
10
+ // src/tools/get-dataset.ts
11
+ function formatDatasetResponse(dataset) {
12
+ const lines = [];
13
+ lines.push(`# Dataset: ${escapeMarkdown(dataset.name)}
14
+ `);
15
+ lines.push(`**Slug**: ${escapeMarkdown(dataset.slug)}`);
16
+ lines.push(`**ID**: ${escapeMarkdown(dataset.id)}`);
17
+ if (Array.isArray(dataset.columnTypes) && dataset.columnTypes.length > 0) {
18
+ lines.push("\n## Columns\n");
19
+ lines.push("| Name | Type |");
20
+ lines.push("|------|------|");
21
+ for (const col of dataset.columnTypes) {
22
+ lines.push(`| ${escapeMarkdown(col.name)} | ${escapeMarkdown(col.type)} |`);
23
+ }
24
+ }
25
+ if (Array.isArray(dataset.data) && dataset.data.length > 0) {
26
+ lines.push(`
27
+ ## Records (${dataset.data.length} shown)
28
+ `);
29
+ for (const record of dataset.data) {
30
+ lines.push(`**${escapeMarkdown(record.id)}**: ${escapeMarkdown(JSON.stringify(record.entry))}`);
31
+ }
32
+ } else {
33
+ lines.push("\nNo records in this dataset.");
34
+ }
35
+ return lines.join("\n");
36
+ }
37
+ async function handleGetDataset(params) {
38
+ const dataset = await getDataset(params.slugOrId);
39
+ if (params.format === "json") {
40
+ return JSON.stringify(dataset, null, 2);
41
+ }
42
+ return formatDatasetResponse(dataset);
43
+ }
44
+ export {
45
+ formatDatasetResponse,
46
+ handleGetDataset
47
+ };
48
+ //# sourceMappingURL=get-dataset-H5IK5FVU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-dataset.ts"],"sourcesContent":["import {\n getDataset as apiGetDataset,\n type DatasetDetailResponse,\n} from \"../langwatch-api-datasets.js\";\nimport { escapeMarkdown } from \"../utils/escape-markdown.js\";\n\n/**\n * Formats a dataset detail response into AI-readable markdown.\n *\n * Exported for unit testing.\n */\nexport function formatDatasetResponse(\n dataset: DatasetDetailResponse,\n): string {\n const lines: string[] = [];\n lines.push(`# Dataset: ${escapeMarkdown(dataset.name)}\\n`);\n lines.push(`**Slug**: ${escapeMarkdown(dataset.slug)}`);\n lines.push(`**ID**: ${escapeMarkdown(dataset.id)}`);\n\n // Column table\n if (\n Array.isArray(dataset.columnTypes) &&\n dataset.columnTypes.length > 0\n ) {\n lines.push(\"\\n## Columns\\n\");\n lines.push(\"| Name | Type |\");\n lines.push(\"|------|------|\");\n for (const col of dataset.columnTypes) {\n lines.push(`| ${escapeMarkdown(col.name)} | ${escapeMarkdown(col.type)} |`);\n }\n }\n\n // Record preview\n if (Array.isArray(dataset.data) && dataset.data.length > 0) {\n lines.push(`\\n## Records (${dataset.data.length} shown)\\n`);\n for (const record of dataset.data) {\n lines.push(`**${escapeMarkdown(record.id)}**: ${escapeMarkdown(JSON.stringify(record.entry))}`);\n }\n } else {\n lines.push(\"\\nNo records in this dataset.\");\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Handles the platform_get_dataset MCP tool invocation.\n *\n * Retrieves a specific dataset by slug or ID and formats it as\n * AI-readable markdown or raw JSON.\n */\nexport async function handleGetDataset(params: {\n slugOrId: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const dataset = await apiGetDataset(params.slugOrId);\n\n if (params.format === \"json\") {\n return JSON.stringify(dataset, null, 2);\n }\n\n return formatDatasetResponse(dataset);\n}\n"],"mappings":";;;;;;;;;;AAWO,SAAS,sBACd,SACQ;AACR,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,cAAc,eAAe,QAAQ,IAAI,CAAC;AAAA,CAAI;AACzD,QAAM,KAAK,aAAa,eAAe,QAAQ,IAAI,CAAC,EAAE;AACtD,QAAM,KAAK,WAAW,eAAe,QAAQ,EAAE,CAAC,EAAE;AAGlD,MACE,MAAM,QAAQ,QAAQ,WAAW,KACjC,QAAQ,YAAY,SAAS,GAC7B;AACA,UAAM,KAAK,gBAAgB;AAC3B,UAAM,KAAK,iBAAiB;AAC5B,UAAM,KAAK,iBAAiB;AAC5B,eAAW,OAAO,QAAQ,aAAa;AACrC,YAAM,KAAK,KAAK,eAAe,IAAI,IAAI,CAAC,MAAM,eAAe,IAAI,IAAI,CAAC,IAAI;AAAA,IAC5E;AAAA,EACF;AAGA,MAAI,MAAM,QAAQ,QAAQ,IAAI,KAAK,QAAQ,KAAK,SAAS,GAAG;AAC1D,UAAM,KAAK;AAAA,cAAiB,QAAQ,KAAK,MAAM;AAAA,CAAW;AAC1D,eAAW,UAAU,QAAQ,MAAM;AACjC,YAAM,KAAK,KAAK,eAAe,OAAO,EAAE,CAAC,OAAO,eAAe,KAAK,UAAU,OAAO,KAAK,CAAC,CAAC,EAAE;AAAA,IAChG;AAAA,EACF,OAAO;AACL,UAAM,KAAK,+BAA+B;AAAA,EAC5C;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAQA,eAAsB,iBAAiB,QAGnB;AAClB,QAAM,UAAU,MAAM,WAAc,OAAO,QAAQ;AAEnD,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,EACxC;AAEA,SAAO,sBAAsB,OAAO;AACtC;","names":[]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getEvaluator,
3
3
  getEvaluatorType
4
- } from "./chunk-5UOPNRXW.js";
5
- import "./chunk-LLRQIF52.js";
6
- import "./chunk-AAQNA53E.js";
4
+ } from "./chunk-HYMIWO3U.js";
5
+ import "./chunk-2WPLXEKF.js";
6
+ import "./chunk-BWWY5KEF.js";
7
7
 
8
8
  // src/tools/get-evaluator.ts
9
9
  async function handleGetEvaluator(params) {
@@ -44,4 +44,4 @@ async function handleGetEvaluator(params) {
44
44
  export {
45
45
  handleGetEvaluator
46
46
  };
47
- //# sourceMappingURL=get-evaluator-WDEH2F7M.js.map
47
+ //# sourceMappingURL=get-evaluator-UWVUPYTM.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getPrompt
3
- } from "./chunk-LLRQIF52.js";
4
- import "./chunk-AAQNA53E.js";
3
+ } from "./chunk-2WPLXEKF.js";
4
+ import "./chunk-BWWY5KEF.js";
5
5
 
6
6
  // src/tools/get-prompt.ts
7
7
  async function handleGetPrompt(params) {
8
- const prompt = await getPrompt(params.idOrHandle, params.version);
8
+ const prompt = await getPrompt(params.idOrHandle, { version: params.version, tag: params.tag });
9
9
  const lines = [];
10
10
  lines.push(
11
11
  `# Prompt: ${prompt.name || prompt.handle || prompt.id}
@@ -42,4 +42,4 @@ async function handleGetPrompt(params) {
42
42
  export {
43
43
  handleGetPrompt
44
44
  };
45
- //# sourceMappingURL=get-prompt-F6PDVC76.js.map
45
+ //# sourceMappingURL=get-prompt-WZUOLLQC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-prompt.ts"],"sourcesContent":["import { getPrompt as apiGetPrompt } from \"../langwatch-api.js\";\n\n/**\n * Handles the platform_get_prompt MCP tool invocation.\n *\n * Retrieves a specific prompt by ID or handle and formats it as\n * AI-readable markdown, including messages, model config, and version history.\n */\nexport async function handleGetPrompt(params: {\n idOrHandle: string;\n version?: number;\n tag?: string;\n}): Promise<string> {\n const prompt = await apiGetPrompt(params.idOrHandle, { version: params.version, tag: params.tag });\n\n const lines: string[] = [];\n lines.push(\n `# Prompt: ${prompt.name || prompt.handle || prompt.id}\\n`\n );\n\n if (prompt.handle) lines.push(`**Handle**: ${prompt.handle}`);\n if (prompt.id) lines.push(`**ID**: ${prompt.id}`);\n if (prompt.latestVersionNumber != null)\n lines.push(`**Latest Version**: v${prompt.latestVersionNumber}`);\n\n // Show model config\n const version = prompt.versions?.[0] ?? prompt;\n if (version.model) lines.push(`**Model**: ${version.model}`);\n\n // Show messages\n const messages = version.messages || prompt.prompt || [];\n if (Array.isArray(messages) && messages.length > 0) {\n lines.push(\"\\n## Messages\");\n for (const msg of messages) {\n lines.push(`\\n### ${msg.role}`);\n lines.push(msg.content);\n }\n }\n\n // Show version history\n if (prompt.versions && prompt.versions.length > 0) {\n lines.push(\"\\n## Version History\");\n for (const v of prompt.versions.slice(0, 10)) {\n const versionNum = v.version ?? \"?\";\n const commitMsg = v.commitMessage || \"No message\";\n lines.push(`- **v${versionNum}**: ${commitMsg}`);\n }\n if (prompt.versions.length > 10) {\n lines.push(`... and ${prompt.versions.length - 10} more versions`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAQA,eAAsB,gBAAgB,QAIlB;AAClB,QAAM,SAAS,MAAM,UAAa,OAAO,YAAY,EAAE,SAAS,OAAO,SAAS,KAAK,OAAO,IAAI,CAAC;AAEjG,QAAM,QAAkB,CAAC;AACzB,QAAM;AAAA,IACJ,aAAa,OAAO,QAAQ,OAAO,UAAU,OAAO,EAAE;AAAA;AAAA,EACxD;AAEA,MAAI,OAAO,OAAQ,OAAM,KAAK,eAAe,OAAO,MAAM,EAAE;AAC5D,MAAI,OAAO,GAAI,OAAM,KAAK,WAAW,OAAO,EAAE,EAAE;AAChD,MAAI,OAAO,uBAAuB;AAChC,UAAM,KAAK,wBAAwB,OAAO,mBAAmB,EAAE;AAGjE,QAAM,UAAU,OAAO,WAAW,CAAC,KAAK;AACxC,MAAI,QAAQ,MAAO,OAAM,KAAK,cAAc,QAAQ,KAAK,EAAE;AAG3D,QAAM,WAAW,QAAQ,YAAY,OAAO,UAAU,CAAC;AACvD,MAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,GAAG;AAClD,UAAM,KAAK,eAAe;AAC1B,eAAW,OAAO,UAAU;AAC1B,YAAM,KAAK;AAAA,MAAS,IAAI,IAAI,EAAE;AAC9B,YAAM,KAAK,IAAI,OAAO;AAAA,IACxB;AAAA,EACF;AAGA,MAAI,OAAO,YAAY,OAAO,SAAS,SAAS,GAAG;AACjD,UAAM,KAAK,sBAAsB;AACjC,eAAW,KAAK,OAAO,SAAS,MAAM,GAAG,EAAE,GAAG;AAC5C,YAAM,aAAa,EAAE,WAAW;AAChC,YAAM,YAAY,EAAE,iBAAiB;AACrC,YAAM,KAAK,QAAQ,UAAU,OAAO,SAAS,EAAE;AAAA,IACjD;AACA,QAAI,OAAO,SAAS,SAAS,IAAI;AAC/B,YAAM,KAAK,WAAW,OAAO,SAAS,SAAS,EAAE,gBAAgB;AAAA,IACnE;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  getScenario
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/get-scenario.ts
8
8
  async function handleGetScenario(params) {
@@ -30,4 +30,4 @@ async function handleGetScenario(params) {
30
30
  export {
31
31
  handleGetScenario
32
32
  };
33
- //# sourceMappingURL=get-scenario-H24ZYNT5.js.map
33
+ //# sourceMappingURL=get-scenario-Q6LCNUYN.js.map
@@ -0,0 +1,56 @@
1
+ import {
2
+ getSimulationRun
3
+ } from "./chunk-EGH5RPXM.js";
4
+ import "./chunk-2WPLXEKF.js";
5
+ import "./chunk-BWWY5KEF.js";
6
+
7
+ // src/tools/get-simulation-run.ts
8
+ async function handleGetSimulationRun(params) {
9
+ const run = await getSimulationRun(params.scenarioRunId);
10
+ if (params.format === "json") {
11
+ return JSON.stringify(run, null, 2);
12
+ }
13
+ const lines = [];
14
+ lines.push(`# Simulation Run: ${run.name ?? run.scenarioRunId}
15
+ `);
16
+ lines.push(`**Run ID**: ${run.scenarioRunId}`);
17
+ lines.push(`**Scenario ID**: ${run.scenarioId}`);
18
+ lines.push(`**Batch ID**: ${run.batchRunId}`);
19
+ lines.push(`**Status**: ${run.status}`);
20
+ const duration = run.durationInMs > 0 ? `${(run.durationInMs / 1e3).toFixed(1)}s` : "\u2014";
21
+ lines.push(`**Duration**: ${duration}`);
22
+ if (run.totalCost) {
23
+ lines.push(`**Cost**: $${run.totalCost.toFixed(4)}`);
24
+ }
25
+ lines.push(`**Started**: ${new Date(run.timestamp).toISOString()}`);
26
+ if (run.results) {
27
+ lines.push("\n## Results");
28
+ if (run.results.verdict) {
29
+ lines.push(`**Verdict**: ${run.results.verdict}`);
30
+ }
31
+ if (run.results.reasoning) {
32
+ lines.push(`**Reasoning**: ${run.results.reasoning}`);
33
+ }
34
+ if (run.results.metCriteria && run.results.metCriteria.length > 0) {
35
+ lines.push(`**Met Criteria**: ${run.results.metCriteria.join(", ")}`);
36
+ }
37
+ if (run.results.unmetCriteria && run.results.unmetCriteria.length > 0) {
38
+ lines.push(`**Unmet Criteria**: ${run.results.unmetCriteria.join(", ")}`);
39
+ }
40
+ if (run.results.error) {
41
+ lines.push(`**Error**: ${run.results.error}`);
42
+ }
43
+ }
44
+ if (run.messages && run.messages.length > 0) {
45
+ lines.push("\n## Conversation");
46
+ for (const msg of run.messages) {
47
+ const content = msg.content.length > 300 ? msg.content.slice(0, 300) + "..." : msg.content;
48
+ lines.push(`**[${msg.role}]**: ${content}`);
49
+ }
50
+ }
51
+ return lines.join("\n");
52
+ }
53
+ export {
54
+ handleGetSimulationRun
55
+ };
56
+ //# sourceMappingURL=get-simulation-run-Z2XKO256.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-simulation-run.ts"],"sourcesContent":["import { getSimulationRun as apiGetSimulationRun } from \"../langwatch-api-simulation-runs.js\";\n\n/**\n * Handles the platform_get_simulation_run MCP tool invocation.\n */\nexport async function handleGetSimulationRun(params: {\n scenarioRunId: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const run = await apiGetSimulationRun(params.scenarioRunId);\n\n if (params.format === \"json\") {\n return JSON.stringify(run, null, 2);\n }\n\n const lines: string[] = [];\n lines.push(`# Simulation Run: ${run.name ?? run.scenarioRunId}\\n`);\n lines.push(`**Run ID**: ${run.scenarioRunId}`);\n lines.push(`**Scenario ID**: ${run.scenarioId}`);\n lines.push(`**Batch ID**: ${run.batchRunId}`);\n lines.push(`**Status**: ${run.status}`);\n\n const duration = run.durationInMs > 0 ? `${(run.durationInMs / 1000).toFixed(1)}s` : \"—\";\n lines.push(`**Duration**: ${duration}`);\n if (run.totalCost) {\n lines.push(`**Cost**: $${run.totalCost.toFixed(4)}`);\n }\n lines.push(`**Started**: ${new Date(run.timestamp).toISOString()}`);\n\n if (run.results) {\n lines.push(\"\\n## Results\");\n if (run.results.verdict) {\n lines.push(`**Verdict**: ${run.results.verdict}`);\n }\n if (run.results.reasoning) {\n lines.push(`**Reasoning**: ${run.results.reasoning}`);\n }\n if (run.results.metCriteria && run.results.metCriteria.length > 0) {\n lines.push(`**Met Criteria**: ${run.results.metCriteria.join(\", \")}`);\n }\n if (run.results.unmetCriteria && run.results.unmetCriteria.length > 0) {\n lines.push(`**Unmet Criteria**: ${run.results.unmetCriteria.join(\", \")}`);\n }\n if (run.results.error) {\n lines.push(`**Error**: ${run.results.error}`);\n }\n }\n\n if (run.messages && run.messages.length > 0) {\n lines.push(\"\\n## Conversation\");\n for (const msg of run.messages) {\n const content = msg.content.length > 300\n ? msg.content.slice(0, 300) + \"...\"\n : msg.content;\n lines.push(`**[${msg.role}]**: ${content}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAKA,eAAsB,uBAAuB,QAGzB;AAClB,QAAM,MAAM,MAAM,iBAAoB,OAAO,aAAa;AAE1D,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,EACpC;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,qBAAqB,IAAI,QAAQ,IAAI,aAAa;AAAA,CAAI;AACjE,QAAM,KAAK,eAAe,IAAI,aAAa,EAAE;AAC7C,QAAM,KAAK,oBAAoB,IAAI,UAAU,EAAE;AAC/C,QAAM,KAAK,iBAAiB,IAAI,UAAU,EAAE;AAC5C,QAAM,KAAK,eAAe,IAAI,MAAM,EAAE;AAEtC,QAAM,WAAW,IAAI,eAAe,IAAI,IAAI,IAAI,eAAe,KAAM,QAAQ,CAAC,CAAC,MAAM;AACrF,QAAM,KAAK,iBAAiB,QAAQ,EAAE;AACtC,MAAI,IAAI,WAAW;AACjB,UAAM,KAAK,cAAc,IAAI,UAAU,QAAQ,CAAC,CAAC,EAAE;AAAA,EACrD;AACA,QAAM,KAAK,gBAAgB,IAAI,KAAK,IAAI,SAAS,EAAE,YAAY,CAAC,EAAE;AAElE,MAAI,IAAI,SAAS;AACf,UAAM,KAAK,cAAc;AACzB,QAAI,IAAI,QAAQ,SAAS;AACvB,YAAM,KAAK,gBAAgB,IAAI,QAAQ,OAAO,EAAE;AAAA,IAClD;AACA,QAAI,IAAI,QAAQ,WAAW;AACzB,YAAM,KAAK,kBAAkB,IAAI,QAAQ,SAAS,EAAE;AAAA,IACtD;AACA,QAAI,IAAI,QAAQ,eAAe,IAAI,QAAQ,YAAY,SAAS,GAAG;AACjE,YAAM,KAAK,qBAAqB,IAAI,QAAQ,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,IACtE;AACA,QAAI,IAAI,QAAQ,iBAAiB,IAAI,QAAQ,cAAc,SAAS,GAAG;AACrE,YAAM,KAAK,uBAAuB,IAAI,QAAQ,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,IAC1E;AACA,QAAI,IAAI,QAAQ,OAAO;AACrB,YAAM,KAAK,cAAc,IAAI,QAAQ,KAAK,EAAE;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,IAAI,YAAY,IAAI,SAAS,SAAS,GAAG;AAC3C,UAAM,KAAK,mBAAmB;AAC9B,eAAW,OAAO,IAAI,UAAU;AAC9B,YAAM,UAAU,IAAI,QAAQ,SAAS,MACjC,IAAI,QAAQ,MAAM,GAAG,GAAG,IAAI,QAC5B,IAAI;AACR,YAAM,KAAK,MAAM,IAAI,IAAI,QAAQ,OAAO,EAAE;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -0,0 +1,44 @@
1
+ import {
2
+ getSuite
3
+ } from "./chunk-LUMEZEHL.js";
4
+ import "./chunk-2WPLXEKF.js";
5
+ import "./chunk-BWWY5KEF.js";
6
+
7
+ // src/tools/get-suite.ts
8
+ async function handleGetSuite(params) {
9
+ const suite = await getSuite(params.id);
10
+ if (params.format === "json") {
11
+ return JSON.stringify(suite, null, 2);
12
+ }
13
+ const lines = [];
14
+ lines.push(`# Suite: ${suite.name}
15
+ `);
16
+ lines.push(`**ID**: ${suite.id}`);
17
+ lines.push(`**Slug**: ${suite.slug}`);
18
+ lines.push(`**Description**: ${suite.description ?? "\u2014"}`);
19
+ lines.push(`**Repeat Count**: ${suite.repeatCount}`);
20
+ lines.push(`**Created**: ${suite.createdAt}`);
21
+ lines.push(`**Updated**: ${suite.updatedAt}`);
22
+ if (suite.labels.length > 0) {
23
+ lines.push(`**Labels**: ${suite.labels.join(", ")}`);
24
+ }
25
+ lines.push("\n## Scenarios");
26
+ for (const id of suite.scenarioIds) {
27
+ lines.push(`- ${id}`);
28
+ }
29
+ lines.push("\n## Targets");
30
+ for (const t of suite.targets) {
31
+ lines.push(`- ${t.type}:${t.referenceId}`);
32
+ }
33
+ const totalJobs = suite.scenarioIds.length * suite.targets.length * suite.repeatCount;
34
+ lines.push(`
35
+ **Total jobs per run**: ${totalJobs}`);
36
+ lines.push(
37
+ "\n> Use `platform_run_suite` to trigger a run, or `platform_update_suite` to modify."
38
+ );
39
+ return lines.join("\n");
40
+ }
41
+ export {
42
+ handleGetSuite
43
+ };
44
+ //# sourceMappingURL=get-suite-BXK5TN7P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-suite.ts"],"sourcesContent":["import { getSuite as apiGetSuite } from \"../langwatch-api-suites.js\";\n\n/**\n * Handles the platform_get_suite MCP tool invocation.\n */\nexport async function handleGetSuite(params: {\n id: string;\n format?: \"digest\" | \"json\";\n}): Promise<string> {\n const suite = await apiGetSuite(params.id);\n\n if (params.format === \"json\") {\n return JSON.stringify(suite, null, 2);\n }\n\n const lines: string[] = [];\n lines.push(`# Suite: ${suite.name}\\n`);\n lines.push(`**ID**: ${suite.id}`);\n lines.push(`**Slug**: ${suite.slug}`);\n lines.push(`**Description**: ${suite.description ?? \"—\"}`);\n lines.push(`**Repeat Count**: ${suite.repeatCount}`);\n lines.push(`**Created**: ${suite.createdAt}`);\n lines.push(`**Updated**: ${suite.updatedAt}`);\n\n if (suite.labels.length > 0) {\n lines.push(`**Labels**: ${suite.labels.join(\", \")}`);\n }\n\n lines.push(\"\\n## Scenarios\");\n for (const id of suite.scenarioIds) {\n lines.push(`- ${id}`);\n }\n\n lines.push(\"\\n## Targets\");\n for (const t of suite.targets) {\n lines.push(`- ${t.type}:${t.referenceId}`);\n }\n\n const totalJobs = suite.scenarioIds.length * suite.targets.length * suite.repeatCount;\n lines.push(`\\n**Total jobs per run**: ${totalJobs}`);\n\n lines.push(\n \"\\n> Use `platform_run_suite` to trigger a run, or `platform_update_suite` to modify.\"\n );\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAKA,eAAsB,eAAe,QAGjB;AAClB,QAAM,QAAQ,MAAM,SAAY,OAAO,EAAE;AAEzC,MAAI,OAAO,WAAW,QAAQ;AAC5B,WAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,EACtC;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,YAAY,MAAM,IAAI;AAAA,CAAI;AACrC,QAAM,KAAK,WAAW,MAAM,EAAE,EAAE;AAChC,QAAM,KAAK,aAAa,MAAM,IAAI,EAAE;AACpC,QAAM,KAAK,oBAAoB,MAAM,eAAe,QAAG,EAAE;AACzD,QAAM,KAAK,qBAAqB,MAAM,WAAW,EAAE;AACnD,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAC5C,QAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAE5C,MAAI,MAAM,OAAO,SAAS,GAAG;AAC3B,UAAM,KAAK,eAAe,MAAM,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,EACrD;AAEA,QAAM,KAAK,gBAAgB;AAC3B,aAAW,MAAM,MAAM,aAAa;AAClC,UAAM,KAAK,KAAK,EAAE,EAAE;AAAA,EACtB;AAEA,QAAM,KAAK,cAAc;AACzB,aAAW,KAAK,MAAM,SAAS;AAC7B,UAAM,KAAK,KAAK,EAAE,IAAI,IAAI,EAAE,WAAW,EAAE;AAAA,EAC3C;AAEA,QAAM,YAAY,MAAM,YAAY,SAAS,MAAM,QAAQ,SAAS,MAAM;AAC1E,QAAM,KAAK;AAAA,0BAA6B,SAAS,EAAE;AAEnD,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getTraceById
3
- } from "./chunk-LLRQIF52.js";
4
- import "./chunk-AAQNA53E.js";
3
+ } from "./chunk-2WPLXEKF.js";
4
+ import "./chunk-BWWY5KEF.js";
5
5
 
6
6
  // src/tools/get-trace.ts
7
7
  async function handleGetTrace(params) {
@@ -47,4 +47,4 @@ ${result.formatted_trace}`);
47
47
  export {
48
48
  handleGetTrace
49
49
  };
50
- //# sourceMappingURL=get-trace-27USKGO7.js.map
50
+ //# sourceMappingURL=get-trace-4EJAYVBG.js.map
@@ -0,0 +1,25 @@
1
+ import {
2
+ getWorkflow
3
+ } from "./chunk-ZVS4UKN2.js";
4
+ import "./chunk-2WPLXEKF.js";
5
+ import "./chunk-BWWY5KEF.js";
6
+
7
+ // src/tools/get-workflow.ts
8
+ async function handleGetWorkflow(params) {
9
+ const workflow = await getWorkflow(params.id);
10
+ const lines = [];
11
+ lines.push(`# ${workflow.name}
12
+ `);
13
+ lines.push(`**ID**: ${workflow.id}`);
14
+ if (workflow.description) lines.push(`**Description**: ${workflow.description}`);
15
+ if (workflow.icon) lines.push(`**Icon**: ${workflow.icon}`);
16
+ lines.push(`**Evaluator**: ${workflow.isEvaluator ? "yes" : "no"}`);
17
+ lines.push(`**Component**: ${workflow.isComponent ? "yes" : "no"}`);
18
+ lines.push(`**Created**: ${workflow.createdAt}`);
19
+ lines.push(`**Updated**: ${workflow.updatedAt}`);
20
+ return lines.join("\n");
21
+ }
22
+ export {
23
+ handleGetWorkflow
24
+ };
25
+ //# sourceMappingURL=get-workflow-O34QJLHD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/get-workflow.ts"],"sourcesContent":["import { getWorkflow as apiGetWorkflow } from \"../langwatch-api-workflows.js\";\n\nexport async function handleGetWorkflow(params: { id: string }): Promise<string> {\n const workflow = await apiGetWorkflow(params.id);\n\n const lines: string[] = [];\n lines.push(`# ${workflow.name}\\n`);\n lines.push(`**ID**: ${workflow.id}`);\n if (workflow.description) lines.push(`**Description**: ${workflow.description}`);\n if (workflow.icon) lines.push(`**Icon**: ${workflow.icon}`);\n lines.push(`**Evaluator**: ${workflow.isEvaluator ? \"yes\" : \"no\"}`);\n lines.push(`**Component**: ${workflow.isComponent ? \"yes\" : \"no\"}`);\n lines.push(`**Created**: ${workflow.createdAt}`);\n lines.push(`**Updated**: ${workflow.updatedAt}`);\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,kBAAkB,QAAyC;AAC/E,QAAM,WAAW,MAAM,YAAe,OAAO,EAAE;AAE/C,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,SAAS,IAAI;AAAA,CAAI;AACjC,QAAM,KAAK,WAAW,SAAS,EAAE,EAAE;AACnC,MAAI,SAAS,YAAa,OAAM,KAAK,oBAAoB,SAAS,WAAW,EAAE;AAC/E,MAAI,SAAS,KAAM,OAAM,KAAK,aAAa,SAAS,IAAI,EAAE;AAC1D,QAAM,KAAK,kBAAkB,SAAS,cAAc,QAAQ,IAAI,EAAE;AAClE,QAAM,KAAK,kBAAkB,SAAS,cAAc,QAAQ,IAAI,EAAE;AAClE,QAAM,KAAK,gBAAgB,SAAS,SAAS,EAAE;AAC/C,QAAM,KAAK,gBAAgB,SAAS,SAAS,EAAE;AAE/C,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -0,0 +1,224 @@
1
+ import {
2
+ createMcpServer
3
+ } from "./chunk-E5JYYU3J.js";
4
+ import {
5
+ getConfig,
6
+ runWithConfig
7
+ } from "./chunk-BWWY5KEF.js";
8
+
9
+ // src/http-server.ts
10
+ import express from "express";
11
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
12
+ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
13
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
14
+ import { randomUUID, createHash } from "crypto";
15
+ var oauthTokens = /* @__PURE__ */ new Map();
16
+ function extractBearerToken(req) {
17
+ const authHeader = req.headers.authorization;
18
+ if (!authHeader?.startsWith("Bearer ")) return null;
19
+ const token = authHeader.slice(7) || null;
20
+ if (!token) return null;
21
+ const oauthEntry = oauthTokens.get(token);
22
+ if (oauthEntry) {
23
+ if (Date.now() < oauthEntry.expiresAt) {
24
+ return oauthEntry.apiKey;
25
+ }
26
+ oauthTokens.delete(token);
27
+ return null;
28
+ }
29
+ return token;
30
+ }
31
+ function generateAccessToken() {
32
+ return createHash("sha256").update(randomUUID()).digest("hex");
33
+ }
34
+ async function handleWithSessionConfig(apiKey, fn) {
35
+ const baseConfig = getConfig();
36
+ return runWithConfig({ ...baseConfig, apiKey }, fn);
37
+ }
38
+ async function startHttpServer({
39
+ port
40
+ }) {
41
+ const app = express();
42
+ app.set("trust proxy", true);
43
+ app.use(express.json());
44
+ app.use((_req, res, next) => {
45
+ res.header("Access-Control-Allow-Origin", "*");
46
+ res.header(
47
+ "Access-Control-Allow-Methods",
48
+ "GET, POST, DELETE, OPTIONS"
49
+ );
50
+ res.header(
51
+ "Access-Control-Allow-Headers",
52
+ "Content-Type, Authorization, mcp-session-id, MCP-Protocol-Version"
53
+ );
54
+ if (_req.method === "OPTIONS") {
55
+ res.sendStatus(200);
56
+ return;
57
+ }
58
+ next();
59
+ });
60
+ app.get("/health", (_req, res) => {
61
+ res.json({ status: "ok" });
62
+ });
63
+ app.get(
64
+ "/.well-known/oauth-authorization-server",
65
+ (_req, res) => {
66
+ const baseUrl = `${_req.protocol}://${_req.get("host")}`;
67
+ res.json({
68
+ issuer: baseUrl,
69
+ token_endpoint: `${baseUrl}/oauth/token`,
70
+ token_endpoint_auth_methods_supported: ["client_secret_post"],
71
+ grant_types_supported: ["client_credentials"],
72
+ response_types_supported: [],
73
+ scopes_supported: ["mcp:tools"]
74
+ });
75
+ }
76
+ );
77
+ app.post(
78
+ "/oauth/token",
79
+ express.urlencoded({ extended: false }),
80
+ (req, res) => {
81
+ const grantType = req.body.grant_type;
82
+ if (grantType !== "client_credentials") {
83
+ res.status(400).json({
84
+ error: "unsupported_grant_type",
85
+ error_description: "Only client_credentials grant type is supported"
86
+ });
87
+ return;
88
+ }
89
+ const clientSecret = req.body.client_secret;
90
+ if (!clientSecret || typeof clientSecret !== "string") {
91
+ res.status(400).json({
92
+ error: "invalid_request",
93
+ error_description: "client_secret is required (use your LangWatch API key)"
94
+ });
95
+ return;
96
+ }
97
+ const expiresIn = 3600;
98
+ const accessToken = generateAccessToken();
99
+ oauthTokens.set(accessToken, {
100
+ apiKey: clientSecret,
101
+ expiresAt: Date.now() + expiresIn * 1e3
102
+ });
103
+ res.json({
104
+ access_token: accessToken,
105
+ token_type: "Bearer",
106
+ expires_in: expiresIn,
107
+ scope: "mcp:tools"
108
+ });
109
+ }
110
+ );
111
+ const sessions = {};
112
+ app.post("/mcp", async (req, res) => {
113
+ const sessionId = req.headers["mcp-session-id"];
114
+ if (sessionId && sessions[sessionId]) {
115
+ const session = sessions[sessionId];
116
+ await handleWithSessionConfig(
117
+ session.apiKey,
118
+ () => session.transport.handleRequest(req, res, req.body)
119
+ );
120
+ return;
121
+ }
122
+ if (!sessionId && isInitializeRequest(req.body)) {
123
+ const apiKey = extractBearerToken(req);
124
+ if (!apiKey) {
125
+ res.status(401).json({
126
+ error: "Authorization: Bearer <LANGWATCH_API_KEY> header required"
127
+ });
128
+ return;
129
+ }
130
+ const transport = new StreamableHTTPServerTransport({
131
+ sessionIdGenerator: () => randomUUID(),
132
+ onsessioninitialized: (id) => {
133
+ sessions[id] = { transport, apiKey };
134
+ }
135
+ });
136
+ transport.onclose = () => {
137
+ if (transport.sessionId) {
138
+ delete sessions[transport.sessionId];
139
+ }
140
+ };
141
+ const sessionServer = createMcpServer();
142
+ await handleWithSessionConfig(
143
+ apiKey,
144
+ () => sessionServer.connect(transport)
145
+ );
146
+ await handleWithSessionConfig(
147
+ apiKey,
148
+ () => transport.handleRequest(req, res, req.body)
149
+ );
150
+ return;
151
+ }
152
+ res.status(400).json({
153
+ error: "Invalid request \u2014 no session ID or not an initialize request"
154
+ });
155
+ });
156
+ app.get("/mcp", async (req, res) => {
157
+ const sessionId = req.headers["mcp-session-id"];
158
+ if (sessionId && sessions[sessionId]) {
159
+ const session = sessions[sessionId];
160
+ await handleWithSessionConfig(
161
+ session.apiKey,
162
+ () => session.transport.handleRequest(req, res)
163
+ );
164
+ } else {
165
+ res.status(400).json({ error: "Invalid request \u2014 no valid session ID" });
166
+ }
167
+ });
168
+ app.delete("/mcp", async (req, res) => {
169
+ const sessionId = req.headers["mcp-session-id"];
170
+ if (sessionId && sessions[sessionId]) {
171
+ const session = sessions[sessionId];
172
+ await session.transport.close();
173
+ delete sessions[sessionId];
174
+ res.status(200).json({ status: "session closed" });
175
+ } else {
176
+ res.status(404).json({ error: "Session not found" });
177
+ }
178
+ });
179
+ const sseSessions = {};
180
+ app.get("/sse", async (req, res) => {
181
+ const apiKey = extractBearerToken(req) || req.query["apiKey"] || null;
182
+ if (!apiKey) {
183
+ res.status(401).json({
184
+ error: "Authorization: Bearer <LANGWATCH_API_KEY> header or ?apiKey= query parameter required"
185
+ });
186
+ return;
187
+ }
188
+ const transport = new SSEServerTransport("/messages", res);
189
+ sseSessions[transport.sessionId] = { transport, apiKey };
190
+ const sessionServer = createMcpServer();
191
+ res.on("close", () => {
192
+ delete sseSessions[transport.sessionId];
193
+ });
194
+ await handleWithSessionConfig(
195
+ apiKey,
196
+ () => sessionServer.connect(transport)
197
+ );
198
+ });
199
+ const handleSseMessage = async (req, res) => {
200
+ const sessionId = req.query["sessionId"];
201
+ if (!sessionId || !sseSessions[sessionId]) {
202
+ res.status(400).json({ error: "Invalid or missing session ID" });
203
+ return;
204
+ }
205
+ const session = sseSessions[sessionId];
206
+ await handleWithSessionConfig(
207
+ session.apiKey,
208
+ () => session.transport.handlePostMessage(req, res, req.body)
209
+ );
210
+ };
211
+ app.post("/messages", handleSseMessage);
212
+ app.post("/sse/messages", handleSseMessage);
213
+ return new Promise((resolve) => {
214
+ const server = app.listen(port, "0.0.0.0", () => {
215
+ const addr = server.address();
216
+ const resolvedPort = typeof addr === "object" && addr ? addr.port : port;
217
+ resolve({ server, port: resolvedPort });
218
+ });
219
+ });
220
+ }
221
+ export {
222
+ startHttpServer
223
+ };
224
+ //# sourceMappingURL=http-server-ISHF7NJX.js.map