@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,31 @@
1
+ import { listWorkflows as apiListWorkflows } from "../langwatch-api-workflows.js";
2
+
3
+ export async function handleListWorkflows(): Promise<string> {
4
+ const workflows = await apiListWorkflows();
5
+
6
+ if (!Array.isArray(workflows) || workflows.length === 0) {
7
+ return "No workflows found in this project.";
8
+ }
9
+
10
+ const lines: string[] = [];
11
+ lines.push(`# Workflows (${workflows.length} total)\n`);
12
+
13
+ for (const w of workflows) {
14
+ const tags: string[] = [];
15
+ if (w.isEvaluator) tags.push("evaluator");
16
+ if (w.isComponent) tags.push("component");
17
+ const tagStr = tags.length > 0 ? ` [${tags.join(", ")}]` : "";
18
+
19
+ lines.push(`## ${w.name}${tagStr}`);
20
+ lines.push(`**ID**: ${w.id}`);
21
+ if (w.description) lines.push(`**Description**: ${w.description}`);
22
+ lines.push(`**Updated**: ${w.updatedAt}`);
23
+ lines.push("");
24
+ }
25
+
26
+ lines.push(
27
+ "> Use `platform_get_workflow` with the ID to see full workflow details.",
28
+ );
29
+
30
+ return lines.join("\n");
31
+ }
@@ -0,0 +1,14 @@
1
+ import { renamePromptTag as apiRenamePromptTag } from "../langwatch-api.js";
2
+
3
+ export async function handleRenamePromptTag(params: {
4
+ tag: string;
5
+ name: string;
6
+ }): Promise<string> {
7
+ await apiRenamePromptTag({ tag: params.tag, name: params.name });
8
+
9
+ const lines: string[] = [];
10
+ lines.push("Tag renamed successfully!\n");
11
+ lines.push(`**Old name**: ${params.tag}`);
12
+ lines.push(`**New name**: ${params.name}`);
13
+ return lines.join("\n");
14
+ }
@@ -0,0 +1,36 @@
1
+ import { runAgent as apiRunAgent } from "../langwatch-api-agents.js";
2
+
3
+ /**
4
+ * Handles the platform_run_agent MCP tool invocation.
5
+ */
6
+ export async function handleRunAgent(params: {
7
+ id: string;
8
+ input?: string;
9
+ }): Promise<string> {
10
+ let parsedInput: Record<string, unknown> = {};
11
+ if (params.input) {
12
+ try {
13
+ parsedInput = JSON.parse(params.input) as Record<string, unknown>;
14
+ } catch {
15
+ return "Error: `input` must be a valid JSON object.";
16
+ }
17
+ }
18
+
19
+ const { agentType, result } = await apiRunAgent(params.id, parsedInput);
20
+
21
+ const lines: string[] = [];
22
+ lines.push(`Agent executed successfully (type: ${agentType}).\n`);
23
+
24
+ if (typeof result === "object" && result !== null) {
25
+ const output = (result as Record<string, unknown>).output;
26
+ if (output !== undefined) {
27
+ lines.push("**Output:**");
28
+ lines.push(typeof output === "string" ? output : JSON.stringify(output, null, 2));
29
+ } else {
30
+ lines.push("**Result:**");
31
+ lines.push(JSON.stringify(result, null, 2));
32
+ }
33
+ }
34
+
35
+ return lines.join("\n");
36
+ }
@@ -0,0 +1,87 @@
1
+ import { makeRequest } from "../langwatch-api.js";
2
+
3
+ interface EvaluationRunResponse {
4
+ runId: string;
5
+ status: string;
6
+ total: number;
7
+ runUrl?: string;
8
+ }
9
+
10
+ interface EvaluationStatusResponse {
11
+ runId: string;
12
+ status: string;
13
+ progress: number;
14
+ total: number;
15
+ startedAt?: number;
16
+ finishedAt?: number;
17
+ summary?: {
18
+ totalCells?: number;
19
+ completedCells?: number;
20
+ failedCells?: number;
21
+ duration?: number;
22
+ runUrl?: string;
23
+ };
24
+ }
25
+
26
+ export async function handleRunEvaluation(params: {
27
+ slug: string;
28
+ }): Promise<string> {
29
+ const result = (await makeRequest(
30
+ "POST",
31
+ `/api/evaluations/v3/${encodeURIComponent(params.slug)}/run`,
32
+ )) as EvaluationRunResponse;
33
+
34
+ const lines: string[] = [];
35
+ lines.push(`Evaluation started!\n`);
36
+ lines.push(`**Run ID**: ${result.runId}`);
37
+ lines.push(`**Status**: ${result.status}`);
38
+ lines.push(`**Total cells**: ${result.total}`);
39
+ if (result.runUrl) lines.push(`**View at**: ${result.runUrl}`);
40
+ lines.push("");
41
+ lines.push(
42
+ `> Use \`platform_evaluation_status\` with run ID "${result.runId}" to check progress.`,
43
+ );
44
+
45
+ return lines.join("\n");
46
+ }
47
+
48
+ export async function handleEvaluationStatus(params: {
49
+ runId: string;
50
+ }): Promise<string> {
51
+ const status = (await makeRequest(
52
+ "GET",
53
+ `/api/evaluations/v3/runs/${encodeURIComponent(params.runId)}`,
54
+ )) as EvaluationStatusResponse;
55
+
56
+ const lines: string[] = [];
57
+ lines.push(`# Evaluation Run ${status.runId}\n`);
58
+ lines.push(`**Status**: ${status.status}`);
59
+ lines.push(`**Progress**: ${status.progress}/${status.total} cells`);
60
+
61
+ if (status.startedAt) {
62
+ lines.push(`**Started**: ${new Date(status.startedAt).toISOString()}`);
63
+ }
64
+ if (status.finishedAt) {
65
+ lines.push(`**Finished**: ${new Date(status.finishedAt).toISOString()}`);
66
+ }
67
+
68
+ if (status.summary) {
69
+ lines.push("\n## Summary\n");
70
+ if (status.summary.completedCells !== undefined) {
71
+ lines.push(`**Completed**: ${status.summary.completedCells}`);
72
+ }
73
+ if (status.summary.failedCells) {
74
+ lines.push(`**Failed**: ${status.summary.failedCells}`);
75
+ }
76
+ if (status.summary.duration) {
77
+ lines.push(
78
+ `**Duration**: ${(status.summary.duration / 1000).toFixed(1)}s`,
79
+ );
80
+ }
81
+ if (status.summary.runUrl) {
82
+ lines.push(`**View results**: ${status.summary.runUrl}`);
83
+ }
84
+ }
85
+
86
+ return lines.join("\n");
87
+ }
@@ -0,0 +1,28 @@
1
+ import { runSuite as apiRunSuite } from "../langwatch-api-suites.js";
2
+
3
+ /**
4
+ * Handles the platform_run_suite MCP tool invocation.
5
+ */
6
+ export async function handleRunSuite(params: {
7
+ id: string;
8
+ }): Promise<string> {
9
+ const result = await apiRunSuite(params.id);
10
+
11
+ const lines: string[] = [];
12
+ lines.push(`Suite run scheduled successfully.`);
13
+ lines.push("");
14
+ lines.push(`**Batch Run ID**: ${result.batchRunId}`);
15
+ lines.push(`**Jobs**: ${result.jobCount}`);
16
+ lines.push(`**Set ID**: ${result.setId}`);
17
+
18
+ if (result.skippedArchived.scenarios.length > 0) {
19
+ lines.push(`\n⚠️ Skipped archived scenarios: ${result.skippedArchived.scenarios.join(", ")}`);
20
+ }
21
+ if (result.skippedArchived.targets.length > 0) {
22
+ lines.push(`⚠️ Skipped archived targets: ${result.skippedArchived.targets.join(", ")}`);
23
+ }
24
+
25
+ lines.push("\nView results in the LangWatch dashboard under Simulations.");
26
+
27
+ return lines.join("\n");
28
+ }
@@ -0,0 +1,36 @@
1
+ import { runWorkflow as apiRunWorkflow } from "../langwatch-api-workflows.js";
2
+
3
+ /**
4
+ * Handles the platform_run_workflow MCP tool invocation.
5
+ */
6
+ export async function handleRunWorkflow(params: {
7
+ id: string;
8
+ input?: string;
9
+ }): Promise<string> {
10
+ let parsedInput: Record<string, unknown> = {};
11
+ if (params.input) {
12
+ try {
13
+ parsedInput = JSON.parse(params.input) as Record<string, unknown>;
14
+ } catch {
15
+ return "Error: `input` must be a valid JSON object.";
16
+ }
17
+ }
18
+
19
+ const result = await apiRunWorkflow(params.id, parsedInput);
20
+
21
+ const lines: string[] = [];
22
+ lines.push(`Workflow "${params.id}" executed successfully.\n`);
23
+
24
+ if (typeof result === "object" && result !== null) {
25
+ const output = (result as Record<string, unknown>).output;
26
+ if (output !== undefined) {
27
+ lines.push("**Output:**");
28
+ lines.push(typeof output === "string" ? output : JSON.stringify(output, null, 2));
29
+ } else {
30
+ lines.push("**Result:**");
31
+ lines.push(JSON.stringify(result, null, 2));
32
+ }
33
+ }
34
+
35
+ return lines.join("\n");
36
+ }
@@ -0,0 +1,13 @@
1
+ import { updateAgent as apiUpdateAgent } from "../langwatch-api-agents.js";
2
+
3
+ export async function handleUpdateAgent(params: {
4
+ id: string;
5
+ name?: string;
6
+ type?: string;
7
+ config?: Record<string, unknown>;
8
+ }): Promise<string> {
9
+ const { id, ...data } = params;
10
+ const agent = await apiUpdateAgent({ id, ...data });
11
+
12
+ return `Agent updated successfully!\n\n**Name**: ${agent.name}\n**ID**: ${agent.id}\n**Type**: ${agent.type}`;
13
+ }
@@ -0,0 +1,21 @@
1
+ import { updateDatasetRecord as apiUpdateDatasetRecord } from "../langwatch-api-datasets.js";
2
+
3
+ /**
4
+ * Handles the platform_update_dataset_record MCP tool invocation.
5
+ *
6
+ * Updates a single record in a dataset and returns confirmation.
7
+ */
8
+ export async function handleUpdateDatasetRecord(params: {
9
+ slugOrId: string;
10
+ recordId: string;
11
+ entry: Record<string, unknown>;
12
+ }): Promise<string> {
13
+ const result = await apiUpdateDatasetRecord(params);
14
+
15
+ const lines: string[] = [];
16
+ lines.push("Record updated successfully!\n");
17
+ lines.push(`**Record ID**: ${result.id}`);
18
+ lines.push(`**Entry**: ${JSON.stringify(result.entry)}`);
19
+
20
+ return lines.join("\n");
21
+ }
@@ -0,0 +1,23 @@
1
+ import { updateDataset as apiUpdateDataset } from "../langwatch-api-datasets.js";
2
+ import type { DatasetColumnType } from "../langwatch-api-datasets.js";
3
+ import { formatDatasetMutationDetails } from "./format-dataset-mutation.js";
4
+
5
+ /**
6
+ * Handles the platform_update_dataset MCP tool invocation.
7
+ *
8
+ * Updates an existing dataset and returns a confirmation
9
+ * with the updated details.
10
+ */
11
+ export async function handleUpdateDataset(params: {
12
+ slugOrId: string;
13
+ name?: string;
14
+ columnTypes?: DatasetColumnType[];
15
+ }): Promise<string> {
16
+ const result = await apiUpdateDataset(params);
17
+
18
+ const lines: string[] = [];
19
+ lines.push("Dataset updated successfully!\n");
20
+ lines.push(...formatDatasetMutationDetails(result));
21
+
22
+ return lines.join("\n");
23
+ }
@@ -11,6 +11,7 @@ export async function handleUpdatePrompt(params: {
11
11
  messages?: Array<{ role: string; content: string }>;
12
12
  model?: string;
13
13
  commitMessage: string;
14
+ tags?: string[];
14
15
  }): Promise<string> {
15
16
  const { idOrHandle, ...data } = params;
16
17
 
@@ -23,6 +24,8 @@ export async function handleUpdatePrompt(params: {
23
24
  if (result.latestVersionNumber != null)
24
25
  lines.push(`**Version**: v${result.latestVersionNumber}`);
25
26
  lines.push(`**Commit**: ${params.commitMessage}`);
27
+ if (params.tags && params.tags.length > 0)
28
+ lines.push(`**Tags**: ${params.tags.join(", ")}`);
26
29
 
27
30
  return lines.join("\n");
28
31
  }
@@ -0,0 +1,44 @@
1
+ import { updateSuite as apiUpdateSuite } from "../langwatch-api-suites.js";
2
+ import type { SuiteTarget } from "../langwatch-api-suites.js";
3
+
4
+ /**
5
+ * Handles the platform_update_suite MCP tool invocation.
6
+ */
7
+ export async function handleUpdateSuite(params: {
8
+ id: string;
9
+ name?: string;
10
+ description?: string;
11
+ scenarioIds?: string[];
12
+ targets?: string;
13
+ repeatCount?: number;
14
+ labels?: string[];
15
+ }): Promise<string> {
16
+ let parsedTargets: SuiteTarget[] | undefined;
17
+ if (params.targets) {
18
+ try {
19
+ parsedTargets = JSON.parse(params.targets) as SuiteTarget[];
20
+ } catch {
21
+ return "Error: `targets` must be a valid JSON array.";
22
+ }
23
+ }
24
+
25
+ const suite = await apiUpdateSuite({
26
+ id: params.id,
27
+ name: params.name,
28
+ description: params.description,
29
+ scenarioIds: params.scenarioIds,
30
+ targets: parsedTargets,
31
+ repeatCount: params.repeatCount,
32
+ labels: params.labels,
33
+ });
34
+
35
+ return [
36
+ `Suite "${suite.name}" updated successfully.`,
37
+ "",
38
+ `**ID**: ${suite.id}`,
39
+ `**Slug**: ${suite.slug}`,
40
+ `**Scenarios**: ${suite.scenarioIds.length}`,
41
+ `**Targets**: ${suite.targets.length}`,
42
+ `**Repeat**: ${suite.repeatCount}x`,
43
+ ].join("\n");
44
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Escapes characters that would break markdown table formatting.
3
+ *
4
+ * Replaces pipe characters (`|`) with `\|` and newlines with spaces
5
+ * so that values can be safely embedded in markdown tables and headers.
6
+ */
7
+ export function escapeMarkdown(value: string): string {
8
+ return value
9
+ .replace(/\\/g, "\\\\")
10
+ .replace(/\|/g, "\\|")
11
+ .replace(/\n/g, " ");
12
+ }
package/tsup.config.ts CHANGED
@@ -2,7 +2,11 @@ import { defineConfig } from "tsup";
2
2
 
3
3
  export default defineConfig([
4
4
  {
5
- entry: ["src/index.ts"],
5
+ entry: [
6
+ "src/index.ts",
7
+ "src/create-mcp-server.ts",
8
+ "src/config.ts",
9
+ ],
6
10
  format: ["esm"],
7
11
  dts: true,
8
12
  sourcemap: true,
@@ -1,28 +0,0 @@
1
- // src/config.ts
2
- var config;
3
- function initConfig(args) {
4
- config = {
5
- apiKey: args.apiKey || process.env.LANGWATCH_API_KEY,
6
- endpoint: args.endpoint || process.env.LANGWATCH_ENDPOINT || "https://app.langwatch.ai"
7
- };
8
- }
9
- function getConfig() {
10
- if (!config) throw new Error("Config not initialized");
11
- return config;
12
- }
13
- function requireApiKey() {
14
- const { apiKey } = getConfig();
15
- if (!apiKey) {
16
- throw new Error(
17
- "LANGWATCH_API_KEY is required. Set it via --apiKey flag or LANGWATCH_API_KEY environment variable."
18
- );
19
- }
20
- return apiKey;
21
- }
22
-
23
- export {
24
- initConfig,
25
- getConfig,
26
- requireApiKey
27
- };
28
- //# sourceMappingURL=chunk-AAQNA53E.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config.ts"],"sourcesContent":["export interface McpConfig {\n apiKey: string | undefined;\n endpoint: string;\n}\n\nlet config: McpConfig | undefined;\n\nexport function initConfig(args: { apiKey?: string; endpoint?: string }): void {\n config = {\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\nexport function getConfig(): McpConfig {\n if (!config) throw new Error(\"Config not initialized\");\n return config;\n}\n\nexport function requireApiKey(): string {\n const { apiKey } = getConfig();\n if (!apiKey) {\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 apiKey;\n}\n"],"mappings":";AAKA,IAAI;AAEG,SAAS,WAAW,MAAoD;AAC7E,WAAS;AAAA,IACP,QAAQ,KAAK,UAAU,QAAQ,IAAI;AAAA,IACnC,UACE,KAAK,YACL,QAAQ,IAAI,sBACZ;AAAA,EACJ;AACF;AAEO,SAAS,YAAuB;AACrC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,wBAAwB;AACrD,SAAO;AACT;AAEO,SAAS,gBAAwB;AACtC,QAAM,EAAE,OAAO,IAAI,UAAU;AAC7B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -1 +0,0 @@
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 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 version?: number\n): Promise<PromptDetailResponse> {\n const query = version != null ? `?version=${version}` : \"\";\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}): 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 }\n): Promise<PromptMutationResponse> {\n return makeRequest(\n \"PUT\",\n `/api/prompts/${encodeURIComponent(idOrHandle)}`,\n data\n ) as Promise<PromptMutationResponse>;\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,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,QAAQ,WAAW,OAAO,YAAY,OAAO,KAAK;AACxD,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,UAAU,CAAC,GAAG,KAAK;AAAA,EACxD;AACF;AAGA,eAAsB,aAAa,MAIC;AAClC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,eAAsB,aACpB,YACA,MAKiC;AACjC,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,UAAU,CAAC;AAAA,IAC9C;AAAA,EACF;AACF;","names":[]}
@@ -1,11 +0,0 @@
1
- import {
2
- getConfig,
3
- initConfig,
4
- requireApiKey
5
- } from "./chunk-AAQNA53E.js";
6
- export {
7
- getConfig,
8
- initConfig,
9
- requireApiKey
10
- };
11
- //# sourceMappingURL=config-FIQWQRUB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tools/create-prompt.ts"],"sourcesContent":["import { createPrompt as apiCreatePrompt } from \"../langwatch-api.js\";\n\nconst HANDLE_PATTERN = /^[a-z0-9_-]+(?:\\/[a-z0-9_-]+)?$/;\n\n/**\n * Converts a human-readable name into a URL-friendly handle.\n *\n * Lowercases the input, replaces non-alphanumeric runs with hyphens,\n * and strips leading/trailing hyphens. May return an empty string\n * for inputs with no alphanumeric characters — callers must validate.\n */\nfunction toHandle(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\n/**\n * Handles the platform_create_prompt MCP tool invocation.\n *\n * Creates a new prompt in the LangWatch project and returns a\n * confirmation with the created prompt's details.\n */\nexport async function handleCreatePrompt(params: {\n name: string;\n handle?: string;\n messages: Array<{ role: string; content: string }>;\n model: string;\n}): Promise<string> {\n const handle = params.handle?.trim() || toHandle(params.name);\n if (!handle || !HANDLE_PATTERN.test(handle)) {\n throw new Error(\n `Invalid prompt handle \"${handle || \"\"}\". Handle must match ${HANDLE_PATTERN}. Provide a valid \\`handle\\` explicitly.`\n );\n }\n\n const result = await apiCreatePrompt({\n handle,\n messages: params.messages,\n model: params.model,\n });\n\n const lines: string[] = [];\n lines.push(\"Prompt created successfully!\\n\");\n if (result.id) lines.push(`**ID**: ${result.id}`);\n if (result.handle) lines.push(`**Handle**: ${result.handle}`);\n lines.push(`**Name**: ${result.name || params.name}`);\n lines.push(`**Model**: ${params.model}`);\n if (result.latestVersionNumber != null)\n lines.push(`**Version**: v${result.latestVersionNumber}`);\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAEA,IAAM,iBAAiB;AASvB,SAAS,SAAS,MAAsB;AACtC,SAAO,KACJ,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,UAAU,EAAE;AACzB;AAQA,eAAsB,mBAAmB,QAKrB;AAClB,QAAM,SAAS,OAAO,QAAQ,KAAK,KAAK,SAAS,OAAO,IAAI;AAC5D,MAAI,CAAC,UAAU,CAAC,eAAe,KAAK,MAAM,GAAG;AAC3C,UAAM,IAAI;AAAA,MACR,0BAA0B,UAAU,EAAE,wBAAwB,cAAc;AAAA,IAC9E;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,aAAgB;AAAA,IACnC;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO;AAAA,EAChB,CAAC;AAED,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,gCAAgC;AAC3C,MAAI,OAAO,GAAI,OAAM,KAAK,WAAW,OAAO,EAAE,EAAE;AAChD,MAAI,OAAO,OAAQ,OAAM,KAAK,eAAe,OAAO,MAAM,EAAE;AAC5D,QAAM,KAAK,aAAa,OAAO,QAAQ,OAAO,IAAI,EAAE;AACpD,QAAM,KAAK,cAAc,OAAO,KAAK,EAAE;AACvC,MAAI,OAAO,uBAAuB;AAChC,UAAM,KAAK,iBAAiB,OAAO,mBAAmB,EAAE;AAE1D,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tools/get-analytics.ts"],"sourcesContent":["import { getAnalyticsTimeseries as apiGetAnalytics } from \"../langwatch-api.js\";\nimport { parseRelativeDate } from \"../utils/date-parsing.js\";\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 {\n lines.push(\"| Date | Value |\");\n lines.push(\"|------|-------|\");\n for (const bucket of currentPeriod) {\n const date = bucket.date;\n // Find the metric value - it's typically keyed by index\n const value =\n Object.entries(bucket).find(\n ([k]) => k !== \"date\" && typeof bucket[k] === \"number\"\n )?.[1] ?? \"N/A\";\n lines.push(`| ${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":";;;;;;;;;AASA,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,OAAO;AACL,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,kBAAkB;AAC7B,eAAW,UAAU,eAAe;AAClC,YAAM,OAAO,OAAO;AAEpB,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,IAAI,MAAM,KAAK,IAAI;AAAA,IACrC;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -1 +0,0 @@
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}): Promise<string> {\n const prompt = await apiGetPrompt(params.idOrHandle, params.version);\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,QAGlB;AAClB,QAAM,SAAS,MAAM,UAAa,OAAO,YAAY,OAAO,OAAO;AAEnE,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 +0,0 @@
1
- {"version":3,"sources":["../src/tools/update-prompt.ts"],"sourcesContent":["import { updatePrompt as apiUpdatePrompt } from \"../langwatch-api.js\";\n\n/**\n * Handles the platform_update_prompt MCP tool invocation.\n *\n * Updates an existing prompt via the PUT endpoint.\n * Every update with a commitMessage creates a new version automatically.\n */\nexport async function handleUpdatePrompt(params: {\n idOrHandle: string;\n messages?: Array<{ role: string; content: string }>;\n model?: string;\n commitMessage: string;\n}): Promise<string> {\n const { idOrHandle, ...data } = params;\n\n const result = await apiUpdatePrompt(idOrHandle, data);\n\n const lines: string[] = [];\n lines.push(\"Prompt updated successfully!\\n\");\n if (result.id) lines.push(`**ID**: ${result.id}`);\n if (result.handle) lines.push(`**Handle**: ${result.handle}`);\n if (result.latestVersionNumber != null)\n lines.push(`**Version**: v${result.latestVersionNumber}`);\n lines.push(`**Commit**: ${params.commitMessage}`);\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAQA,eAAsB,mBAAmB,QAKrB;AAClB,QAAM,EAAE,YAAY,GAAG,KAAK,IAAI;AAEhC,QAAM,SAAS,MAAM,aAAgB,YAAY,IAAI;AAErD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,gCAAgC;AAC3C,MAAI,OAAO,GAAI,OAAM,KAAK,WAAW,OAAO,EAAE,EAAE;AAChD,MAAI,OAAO,OAAQ,OAAM,KAAK,eAAe,OAAO,MAAM,EAAE;AAC5D,MAAI,OAAO,uBAAuB;AAChC,UAAM,KAAK,iBAAiB,OAAO,mBAAmB,EAAE;AAC1D,QAAM,KAAK,eAAe,OAAO,aAAa,EAAE;AAEhD,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
File without changes