@langwatch/mcp-server 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/.python-version +1 -0
  2. package/CHANGELOG.md +110 -0
  3. package/CONTRIBUTING.md +1 -1
  4. package/README.md +86 -4
  5. package/dist/{archive-project-MK3673A7.js → archive-project-W3IKI7UL.js} +5 -5
  6. package/dist/archive-run-plan-474OKHHU.js +16 -0
  7. package/dist/{archive-scenario-KATSXRIN.js → archive-scenario-V5UNYK26.js} +5 -5
  8. package/dist/archive-test-suite-O7FLDMXK.js +16 -0
  9. package/dist/{assign-prompt-tag-E3C5W6PI.js → assign-prompt-tag-Q46WRB6P.js} +4 -4
  10. package/dist/chunk-56OGTS24.js +44 -0
  11. package/dist/chunk-6DJDEXET.js +63 -0
  12. package/dist/chunk-7E4FZIYJ.js +15 -0
  13. package/dist/{chunk-J45SVWPR.js → chunk-AN4OUA4D.js} +2 -2
  14. package/dist/chunk-CKNAH5TG.js +74 -0
  15. package/dist/{chunk-CE6QMZOP.js → chunk-EYXMLE5X.js} +86 -11
  16. package/dist/{chunk-XY4STOBE.js → chunk-G4ZAZTZW.js} +2 -2
  17. package/dist/{chunk-5UWY24RP.js → chunk-GELJ2MQR.js} +12 -3
  18. package/dist/chunk-HV4DWKBI.js +46 -0
  19. package/dist/chunk-JR6DJZOU.js +49 -0
  20. package/dist/{chunk-DAIQKS27.js → chunk-JTQJRNFJ.js} +2 -2
  21. package/dist/{chunk-WWMDHZZV.js → chunk-K37ZNPXK.js} +2 -2
  22. package/dist/{chunk-EU22L52K.js → chunk-OJLYYJWI.js} +2 -2
  23. package/dist/{chunk-Y3HDZ6OW.js → chunk-QAMP3CGR.js} +2 -2
  24. package/dist/{chunk-VYPSKRPN.js → chunk-QRO35SOM.js} +347 -146
  25. package/dist/{chunk-O3LWVN67.js → chunk-RVAE2MEA.js} +2 -2
  26. package/dist/{chunk-UXXA4D6K.js → chunk-S4GVX36W.js} +2 -2
  27. package/dist/{chunk-BJ7B4R26.js → chunk-SAS5OB7F.js} +18 -2
  28. package/dist/{chunk-RYRB2YVJ.js → chunk-SR6QPRIE.js} +2 -2
  29. package/dist/chunk-UF6XIGYR.js +58 -0
  30. package/dist/{chunk-T7WJVS2N.js → chunk-UFOYFYI7.js} +2 -2
  31. package/dist/chunk-UJPXFA26.js +267 -0
  32. package/dist/{chunk-KOO5733S.js → chunk-WT4PO4A3.js} +8 -2
  33. package/dist/config.js +2 -2
  34. package/dist/{create-agent-7W57J7MT.js → create-agent-JFJ2K6X3.js} +5 -5
  35. package/dist/{create-annotation-W2XELBCQ.js → create-annotation-EUXXQ6NS.js} +5 -5
  36. package/dist/{create-api-key-MKRXKFJM.js → create-api-key-BGBB76JX.js} +5 -5
  37. package/dist/{create-dashboard-QGL7IODC.js → create-dashboard-Z76AIPLS.js} +5 -5
  38. package/dist/{create-dataset-3PH7A4HG.js → create-dataset-FD5VAXU4.js} +5 -5
  39. package/dist/{create-dataset-records-4DZS3VRL.js → create-dataset-records-WQUXXOHI.js} +5 -5
  40. package/dist/{create-evaluator-YWH6NC4M.js → create-evaluator-6NV33Z52.js} +5 -5
  41. package/dist/create-mcp-server.js +9 -4
  42. package/dist/{create-project-BOBQ32C5.js → create-project-ZQ7TFIO2.js} +5 -5
  43. package/dist/{create-prompt-FLCFGITE.js → create-prompt-BS6QRCUU.js} +4 -4
  44. package/dist/{create-prompt-tag-EMPNIKEA.js → create-prompt-tag-FCQ5ELSQ.js} +4 -4
  45. package/dist/{create-scenario-BSBIHUL6.js → create-scenario-DRPTPXU3.js} +12 -5
  46. package/dist/create-test-suite-ZIZCCFJ4.js +37 -0
  47. package/dist/{delete-agent-7MSYNY5E.js → delete-agent-SA4JMUZF.js} +5 -5
  48. package/dist/{delete-annotation-ZT5IGN24.js → delete-annotation-X3KKK7QY.js} +5 -5
  49. package/dist/{delete-dashboard-BTIY5S3L.js → delete-dashboard-LYMRPF27.js} +5 -5
  50. package/dist/{delete-dataset-U45HQHPR.js → delete-dataset-W6EZ44HY.js} +5 -5
  51. package/dist/{delete-dataset-records-R43IMAWB.js → delete-dataset-records-7CNOTALB.js} +5 -5
  52. package/dist/{delete-evaluator-U6JMQ6C7.js → delete-evaluator-RKYC4TNB.js} +5 -5
  53. package/dist/{delete-prompt-tag-4EV4TDHB.js → delete-prompt-tag-QB3OCZUV.js} +4 -4
  54. package/dist/{delete-workflow-5QYALXEL.js → delete-workflow-NG2VXYYM.js} +5 -5
  55. package/dist/{discover-evaluator-schema-MRGHVNTT.js → discover-evaluator-schema-ESSHQGPY.js} +58 -321
  56. package/dist/{discover-scenario-schema-UPBTCWPG.js → discover-scenario-schema-W7KBXA4J.js} +54 -2
  57. package/dist/{discover-schema-ICGXPHUW.js → discover-schema-L6QDPON3.js} +2 -2
  58. package/dist/get-agent-7THF7HCU.js +66 -0
  59. package/dist/{get-analytics-PVERWOA5.js → get-analytics-R6AZD3AW.js} +4 -4
  60. package/dist/{get-dashboard-ZZPC3WMD.js → get-dashboard-P4WWVHFU.js} +5 -5
  61. package/dist/{get-dataset-25TB2LQH.js → get-dataset-AKTYSQDI.js} +5 -5
  62. package/dist/{get-evaluator-3FTRQKEC.js → get-evaluator-RZ44UIN6.js} +5 -5
  63. package/dist/{get-project-5OAXYC57.js → get-project-QSQEAB33.js} +5 -5
  64. package/dist/get-prompt-GVKXF5NL.js +100 -0
  65. package/dist/get-run-plan-NY7J5GRE.js +61 -0
  66. package/dist/{get-scenario-DSSTR6FI.js → get-scenario-Q3LLQE4T.js} +9 -5
  67. package/dist/{get-simulation-run-RQPMS2MC.js → get-simulation-run-WINEYDMK.js} +14 -5
  68. package/dist/get-test-suite-4HKA7OKS.js +49 -0
  69. package/dist/{get-trace-O5VT3NAC.js → get-trace-RCUV7N4O.js} +4 -4
  70. package/dist/{get-workflow-3EZDOEIF.js → get-workflow-EEOC7Y45.js} +5 -5
  71. package/dist/http-security-EU3CHTY7.js +26 -0
  72. package/dist/{http-server-2ACJ3CXW.js → http-server-WCDUARTH.js} +1038 -693
  73. package/dist/index.js +6437 -4020
  74. package/dist/{langwatch-api-annotations-E65MI3WZ.js → langwatch-api-annotations-6DHVZWUK.js} +5 -5
  75. package/dist/{langwatch-api-dashboards-QCDECRCY.js → langwatch-api-dashboards-2KJL2M42.js} +5 -5
  76. package/dist/{langwatch-api-monitors-UIO2KTDV.js → langwatch-api-monitors-6ISFJ7WX.js} +4 -4
  77. package/dist/{langwatch-api-secrets-4T2EKSJ7.js → langwatch-api-secrets-OEBD6GBU.js} +4 -4
  78. package/dist/{langwatch-api-triggers-MPOEKPUY.js → langwatch-api-triggers-5E6DDGX6.js} +4 -4
  79. package/dist/langwatch-api-workflows-6UJL5U4Z.js +16 -0
  80. package/dist/list-agents-AMVDQPQL.js +43 -0
  81. package/dist/{list-annotations-CGX5BT7E.js → list-annotations-6PR5NLIC.js} +5 -5
  82. package/dist/{list-api-keys-JLWJPFRX.js → list-api-keys-GVPNBIHQ.js} +5 -5
  83. package/dist/{list-dashboards-RNIWX3TX.js → list-dashboards-Z3BZKDGF.js} +5 -5
  84. package/dist/{list-dataset-records-B5MHZR66.js → list-dataset-records-O67HZ35Y.js} +5 -5
  85. package/dist/{list-datasets-BVCAMQCP.js → list-datasets-WXZL6UMP.js} +5 -5
  86. package/dist/{list-evaluators-65FBTL2U.js → list-evaluators-PAX72WCN.js} +5 -5
  87. package/dist/{list-model-providers-GRK3I3VV.js → list-model-providers-VVLZMLCX.js} +5 -5
  88. package/dist/{list-projects-JLMBFMW3.js → list-projects-AQVI6SUK.js} +5 -5
  89. package/dist/{list-prompt-tags-UHNWDGQI.js → list-prompt-tags-WZFBJOHG.js} +4 -4
  90. package/dist/{list-prompts-7254B3U7.js → list-prompts-BQOHRHYT.js} +4 -4
  91. package/dist/list-run-plans-UBAU2DGH.js +46 -0
  92. package/dist/{list-scenarios-46YNICKM.js → list-scenarios-MS4IUIVM.js} +10 -7
  93. package/dist/{list-simulation-runs-LGNEFNPN.js → list-simulation-runs-D6YF4ZOU.js} +13 -7
  94. package/dist/list-test-suites-L7R2O6DR.js +35 -0
  95. package/dist/{list-workflows-MLQDM6CP.js → list-workflows-6MV4XJHF.js} +5 -5
  96. package/dist/{rename-prompt-tag-RHQMNEQL.js → rename-prompt-tag-K5LQ4CY6.js} +4 -4
  97. package/dist/rename-test-suite-NTYHAO5X.js +21 -0
  98. package/dist/report-issue-RHZZ33IS.js +885 -0
  99. package/dist/rerun-run-plan-MUDWJBE4.js +22 -0
  100. package/dist/{revoke-api-key-3Y35EMBT.js → revoke-api-key-6LAZ3QZZ.js} +5 -5
  101. package/dist/run-agent-CAGWGTYT.js +72 -0
  102. package/dist/run-plan-T4ZYOZGA.js +39 -0
  103. package/dist/run-test-suite-L4MZ7G4D.js +26 -0
  104. package/dist/{run-workflow-5LVBZYLS.js → run-workflow-DFIS23AP.js} +5 -5
  105. package/dist/{search-traces-U4HLOCZ2.js → search-traces-4XTJYXIK.js} +4 -4
  106. package/dist/{set-model-provider-V3M5CDIY.js → set-model-provider-XRNMFOVR.js} +5 -5
  107. package/dist/{update-agent-47RZIHS7.js → update-agent-DUWNYBNA.js} +5 -5
  108. package/dist/{update-dataset-G6QJJGS5.js → update-dataset-YSOMDCOB.js} +5 -5
  109. package/dist/{update-dataset-record-RMWLSWCS.js → update-dataset-record-DEA2ITYR.js} +5 -5
  110. package/dist/{update-evaluator-SFRRI5Q3.js → update-evaluator-NH7Q5GWV.js} +5 -5
  111. package/dist/{update-project-PI5DWBVK.js → update-project-Q26FBSYH.js} +5 -5
  112. package/dist/update-prompt-ZQQ2C3KU.js +143 -0
  113. package/dist/{update-scenario-G3IU2UIB.js → update-scenario-WUX34JAR.js} +12 -5
  114. package/package.json +8 -9
  115. package/pyproject.toml +5 -5
  116. package/src/__tests__/agent-tools.unit.test.ts +257 -0
  117. package/src/__tests__/all-tools.integration.test.ts +321 -75
  118. package/src/__tests__/config.unit.test.ts +33 -0
  119. package/src/__tests__/docker.integration.test.ts +91 -7
  120. package/src/__tests__/documentation-fetch-security.integration.test.ts +8 -2
  121. package/src/__tests__/feature-map-tool-drift.unit.test.ts +93 -0
  122. package/src/__tests__/http-security-origin.unit.test.ts +97 -0
  123. package/src/__tests__/http-security-sessions.unit.test.ts +209 -0
  124. package/src/__tests__/http-security-verifier.unit.test.ts +248 -0
  125. package/src/__tests__/http-server-allocation.integration.test.ts +279 -0
  126. package/src/__tests__/http-server-origin.integration.test.ts +169 -0
  127. package/src/__tests__/http-server-session-auth.integration.test.ts +341 -0
  128. package/src/__tests__/http-transport.integration.test.ts +85 -87
  129. package/src/__tests__/integration.integration.test.ts +7 -11
  130. package/src/__tests__/prompt-response-types.unit.test.ts +51 -0
  131. package/src/__tests__/prompts.integration.test.ts +736 -0
  132. package/src/__tests__/run-plan-tools.unit.test.ts +565 -0
  133. package/src/__tests__/scenario-tools.unit.test.ts +19 -0
  134. package/src/__tests__/simulation-run-tools.unit.test.ts +116 -0
  135. package/src/__tests__/support/http-server-harness.ts +138 -0
  136. package/src/__tests__/test-suite-tools.unit.test.ts +615 -0
  137. package/src/__tests__/{tools.unit.test.ts → tools.integration.test.ts} +31 -59
  138. package/src/config.ts +17 -2
  139. package/src/create-mcp-server.ts +334 -55
  140. package/src/http-security.ts +492 -0
  141. package/src/http-server.ts +536 -152
  142. package/src/index.ts +49 -2
  143. package/src/langwatch-api-agents.ts +196 -12
  144. package/src/langwatch-api-run-plans.ts +157 -0
  145. package/src/langwatch-api-scenarios.ts +9 -0
  146. package/src/langwatch-api-simulation-runs.ts +5 -0
  147. package/src/langwatch-api-test-suites.ts +135 -0
  148. package/src/langwatch-api.ts +62 -12
  149. package/src/schemas/index.ts +5 -0
  150. package/src/schemas/run-plan.ts +92 -0
  151. package/src/schemas/suite-fields.ts +149 -0
  152. package/src/tools/archive-run-plan.ts +12 -0
  153. package/src/tools/archive-test-suite.ts +12 -0
  154. package/src/tools/create-scenario.ts +8 -0
  155. package/src/tools/create-test-suite.ts +43 -0
  156. package/src/tools/discover-evaluator-schema.ts +2 -2
  157. package/src/tools/discover-scenario-schema.ts +54 -0
  158. package/src/tools/format-run-plan.ts +68 -0
  159. package/src/tools/format-scenario.ts +14 -0
  160. package/src/tools/format-suite-details.ts +96 -0
  161. package/src/tools/get-agent.ts +45 -3
  162. package/src/tools/get-prompt.ts +108 -24
  163. package/src/tools/get-run-plan.ts +62 -0
  164. package/src/tools/get-scenario.ts +3 -0
  165. package/src/tools/get-simulation-run.ts +9 -0
  166. package/src/tools/get-test-suite.ts +49 -0
  167. package/src/tools/list-agents.ts +20 -3
  168. package/src/tools/list-run-plans.ts +47 -0
  169. package/src/tools/list-scenarios.ts +12 -2
  170. package/src/tools/list-simulation-runs.ts +6 -2
  171. package/src/tools/list-test-suites.ts +35 -0
  172. package/src/tools/rename-test-suite.ts +18 -0
  173. package/src/tools/rerun-run-plan.ts +21 -0
  174. package/src/tools/run-agent.ts +54 -6
  175. package/src/tools/run-plan.ts +49 -0
  176. package/src/tools/run-test-suite.ts +30 -0
  177. package/src/tools/test-agent.ts +18 -0
  178. package/src/tools/update-prompt.ts +195 -10
  179. package/src/tools/update-scenario.ts +8 -0
  180. package/src/tools/update-test-suite.ts +45 -0
  181. package/tsconfig.json +7 -2
  182. package/uv.lock +418 -298
  183. package/dist/archive-suite-C3KX6IIZ.js +0 -16
  184. package/dist/chunk-WDH5P5RF.js +0 -48
  185. package/dist/create-suite-TWF6BBR4.js +0 -39
  186. package/dist/get-agent-7QJVPH72.js +0 -29
  187. package/dist/get-prompt-I753LZKZ.js +0 -46
  188. package/dist/get-suite-GTOCY5PL.js +0 -45
  189. package/dist/langwatch-api-workflows-5HRZ7HR4.js +0 -16
  190. package/dist/list-agents-TIJTP566.js +0 -33
  191. package/dist/list-suites-5VK4HXEK.js +0 -43
  192. package/dist/report-issue-DXJ6TPTC.js +0 -412
  193. package/dist/run-agent-RBSIFKRT.js +0 -37
  194. package/dist/run-suite-K3DNQ3SE.js +0 -30
  195. package/dist/update-prompt-RQFTEO7Y.js +0 -25
  196. package/dist/update-suite-TRGGLNR7.js +0 -40
  197. package/pnpm-workspace.yaml +0 -34
  198. package/src/langwatch-api-suites.ts +0 -118
  199. package/src/tools/archive-suite.ts +0 -12
  200. package/src/tools/create-suite.ts +0 -42
  201. package/src/tools/get-suite.ts +0 -47
  202. package/src/tools/list-suites.ts +0 -43
  203. package/src/tools/run-suite.ts +0 -28
  204. package/src/tools/update-suite.ts +0 -44
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeRequest
3
- } from "./chunk-5UWY24RP.js";
3
+ } from "./chunk-GELJ2MQR.js";
4
4
 
5
5
  // src/langwatch-api-scenarios.ts
6
6
  async function listScenarios() {
@@ -37,4 +37,4 @@ export {
37
37
  updateScenario,
38
38
  archiveScenario
39
39
  };
40
- //# sourceMappingURL=chunk-O3LWVN67.js.map
40
+ //# sourceMappingURL=chunk-RVAE2MEA.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeRequest
3
- } from "./chunk-5UWY24RP.js";
3
+ } from "./chunk-GELJ2MQR.js";
4
4
 
5
5
  // src/langwatch-api-dashboards.ts
6
6
  async function listDashboards() {
@@ -36,4 +36,4 @@ export {
36
36
  renameDashboard,
37
37
  deleteDashboard
38
38
  };
39
- //# sourceMappingURL=chunk-UXXA4D6K.js.map
39
+ //# sourceMappingURL=chunk-S4GVX36W.js.map
@@ -10,6 +10,14 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
10
10
  if (typeof require !== "undefined") return require.apply(this, arguments);
11
11
  throw Error('Dynamic require of "' + x + '" is not supported');
12
12
  });
13
+ var __esm = (fn, res, err) => function __init() {
14
+ if (err) throw err[0];
15
+ try {
16
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
17
+ } catch (e) {
18
+ throw err = [e], e;
19
+ }
20
+ };
13
21
  var __commonJS = (cb, mod) => function __require2() {
14
22
  try {
15
23
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
@@ -17,6 +25,10 @@ var __commonJS = (cb, mod) => function __require2() {
17
25
  throw mod = 0, e;
18
26
  }
19
27
  };
28
+ var __export = (target, all) => {
29
+ for (var name in all)
30
+ __defProp(target, name, { get: all[name], enumerable: true });
31
+ };
20
32
  var __copyProps = (to, from, except, desc) => {
21
33
  if (from && typeof from === "object" || typeof from === "function") {
22
34
  for (let key of __getOwnPropNames(from))
@@ -33,10 +45,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
45
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
46
  mod
35
47
  ));
48
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
49
 
37
50
  export {
38
51
  __require,
52
+ __esm,
39
53
  __commonJS,
40
- __toESM
54
+ __export,
55
+ __toESM,
56
+ __toCommonJS
41
57
  };
42
- //# sourceMappingURL=chunk-BJ7B4R26.js.map
58
+ //# sourceMappingURL=chunk-SAS5OB7F.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeRequest
3
- } from "./chunk-5UWY24RP.js";
3
+ } from "./chunk-GELJ2MQR.js";
4
4
 
5
5
  // src/langwatch-api-annotations.ts
6
6
  async function listAnnotations() {
@@ -39,4 +39,4 @@ export {
39
39
  createAnnotation,
40
40
  deleteAnnotation
41
41
  };
42
- //# sourceMappingURL=chunk-RYRB2YVJ.js.map
42
+ //# sourceMappingURL=chunk-SR6QPRIE.js.map
@@ -0,0 +1,58 @@
1
+ // src/tools/format-suite-details.ts
2
+ function describeMapping(mapping) {
3
+ return mapping.type === "value" ? JSON.stringify(mapping.value) : `${mapping.sourceId}.${mapping.path.join(".")}`;
4
+ }
5
+ function formatSuiteFields(fields) {
6
+ if (!fields || fields.length === 0) return [];
7
+ return [
8
+ "\n## Fields",
9
+ ...fields.map((field) => `- ${field.identifier} (${field.type})`)
10
+ ];
11
+ }
12
+ function formatEvaluatorAttachments(evaluators) {
13
+ if (!evaluators || evaluators.length === 0) return [];
14
+ const lines = ["\n## Evaluators"];
15
+ for (const attachment of evaluators) {
16
+ const gate = attachment.required ? "required" : "reports only";
17
+ lines.push(`- ${attachment.evaluatorId} (${gate}, attachment ${attachment.id})`);
18
+ for (const [input, mapping] of Object.entries(attachment.mappings)) {
19
+ lines.push(` - ${input}: ${describeMapping(mapping)}`);
20
+ }
21
+ }
22
+ return lines;
23
+ }
24
+ var PENDING_EVALUATION_STATUS = "PENDING_EVALUATION";
25
+ function formatRunStatus(status) {
26
+ if (status === PENDING_EVALUATION_STATUS) return "evaluating";
27
+ if (status === "SUCCESS") return "pass";
28
+ if (status === "FAILED") return "FAIL";
29
+ return status;
30
+ }
31
+ function pendingEvaluationNote(status) {
32
+ if (status !== PENDING_EVALUATION_STATUS) return [];
33
+ return [
34
+ "> The evaluators attached to this run have not been recorded yet. A required one may still fail it, so read the verdict again once the status changes."
35
+ ];
36
+ }
37
+ function formatEvaluations(evaluations) {
38
+ if (!evaluations || evaluations.length === 0) return [];
39
+ const lines = ["\n## Evaluators"];
40
+ for (const evaluation of evaluations) {
41
+ const parts = [evaluation.status];
42
+ if (evaluation.score !== void 0) parts.push(`score ${evaluation.score}`);
43
+ if (evaluation.label !== void 0) parts.push(evaluation.label);
44
+ if (evaluation.required) parts.push("required");
45
+ lines.push(`- **${evaluation.name}**: ${parts.join(", ")}`);
46
+ if (evaluation.details) lines.push(` ${evaluation.details}`);
47
+ }
48
+ return lines;
49
+ }
50
+
51
+ export {
52
+ formatSuiteFields,
53
+ formatEvaluatorAttachments,
54
+ formatRunStatus,
55
+ pendingEvaluationNote,
56
+ formatEvaluations
57
+ };
58
+ //# sourceMappingURL=chunk-UF6XIGYR.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  makeRequest
3
- } from "./chunk-5UWY24RP.js";
3
+ } from "./chunk-GELJ2MQR.js";
4
4
 
5
5
  // src/langwatch-api-workflows.ts
6
6
  async function listWorkflows() {
@@ -32,4 +32,4 @@ export {
32
32
  runWorkflow,
33
33
  deleteWorkflow
34
34
  };
35
- //# sourceMappingURL=chunk-T7WJVS2N.js.map
35
+ //# sourceMappingURL=chunk-UFOYFYI7.js.map
@@ -0,0 +1,267 @@
1
+ // src/http-security.ts
2
+ import { createHmac, randomBytes, timingSafeEqual } from "crypto";
3
+ var DEFAULT_BIND_HOST = "127.0.0.1";
4
+ var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "::1", "localhost"]);
5
+ function stripBrackets(host) {
6
+ return host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
7
+ }
8
+ function isLoopbackHost(host) {
9
+ return LOOPBACK_HOSTS.has(stripBrackets(host.trim().toLowerCase()));
10
+ }
11
+ var ALWAYS_ALLOWED_ORIGIN_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
12
+ function normalizeOrigin(origin) {
13
+ let parsed;
14
+ try {
15
+ parsed = new URL(origin.trim());
16
+ } catch {
17
+ return null;
18
+ }
19
+ if (parsed.origin === "null") return null;
20
+ return {
21
+ origin: parsed.origin,
22
+ hostname: stripBrackets(parsed.hostname.toLowerCase())
23
+ };
24
+ }
25
+ function parseAllowedOrigins(raw) {
26
+ if (!raw) return [];
27
+ const parsed = raw.split(",").map((entry) => normalizeOrigin(entry)?.origin).filter((entry) => entry !== void 0);
28
+ return [...new Set(parsed)];
29
+ }
30
+ function isOriginAllowed({
31
+ origin,
32
+ allowedOrigins
33
+ }) {
34
+ const normalized = normalizeOrigin(origin);
35
+ if (!normalized) return false;
36
+ if (ALWAYS_ALLOWED_ORIGIN_HOSTS.has(normalized.hostname)) return true;
37
+ return allowedOrigins.includes(normalized.origin);
38
+ }
39
+ var KEY_DERIVATION_SECRET = randomBytes(32);
40
+ function hashApiKey(apiKey) {
41
+ return createHmac("sha256", KEY_DERIVATION_SECRET).update(apiKey).digest("hex");
42
+ }
43
+ function apiKeysMatch({
44
+ presentedKey,
45
+ expectedKey
46
+ }) {
47
+ const presented = createHmac("sha256", KEY_DERIVATION_SECRET).update(presentedKey).digest();
48
+ const expected = createHmac("sha256", KEY_DERIVATION_SECRET).update(expectedKey).digest();
49
+ return timingSafeEqual(presented, expected);
50
+ }
51
+ function createRateLimiter({
52
+ windowMs,
53
+ maxRequests
54
+ }) {
55
+ const entries = /* @__PURE__ */ new Map();
56
+ return {
57
+ isBlocked(ip) {
58
+ const entry = entries.get(ip);
59
+ if (!entry || Date.now() - entry.windowStart > windowMs) return false;
60
+ return entry.count >= maxRequests;
61
+ },
62
+ track(ip) {
63
+ const now = Date.now();
64
+ const entry = entries.get(ip);
65
+ if (!entry || now - entry.windowStart > windowMs) {
66
+ entries.set(ip, { count: 1, windowStart: now });
67
+ } else {
68
+ entry.count++;
69
+ }
70
+ },
71
+ sweep() {
72
+ const now = Date.now();
73
+ for (const [ip, entry] of entries) {
74
+ if (now - entry.windowStart > windowMs) entries.delete(ip);
75
+ }
76
+ },
77
+ clear() {
78
+ entries.clear();
79
+ }
80
+ };
81
+ }
82
+ var VERIFY_PATH = "/api/me/project";
83
+ function createApiKeyVerifier({
84
+ endpoint,
85
+ positiveTtlMs = 6e4,
86
+ negativeTtlMs = 3e4,
87
+ maxEntries = 1e4,
88
+ requestTimeoutMs = 5e3,
89
+ fetchImpl = fetch
90
+ }) {
91
+ const cache = /* @__PURE__ */ new Map();
92
+ const inFlight = /* @__PURE__ */ new Map();
93
+ function sweep() {
94
+ const now = Date.now();
95
+ for (const [key, entry] of cache) {
96
+ if (now >= entry.expiresAt) cache.delete(key);
97
+ }
98
+ }
99
+ function remember(hashed, valid) {
100
+ if (cache.size >= maxEntries) {
101
+ sweep();
102
+ while (cache.size >= maxEntries) {
103
+ const oldest = cache.keys().next();
104
+ if (oldest.done) break;
105
+ cache.delete(oldest.value);
106
+ }
107
+ }
108
+ cache.set(hashed, {
109
+ valid,
110
+ expiresAt: Date.now() + (valid ? positiveTtlMs : negativeTtlMs)
111
+ });
112
+ }
113
+ async function askApi(apiKey) {
114
+ let response;
115
+ try {
116
+ response = await fetchImpl(`${endpoint}${VERIFY_PATH}`, {
117
+ method: "GET",
118
+ headers: { "X-Auth-Token": apiKey },
119
+ // An upstream that accepts the connection and never answers would
120
+ // otherwise leave the in-flight promise unsettled, parking every
121
+ // request for this key behind it until the socket dies.
122
+ signal: AbortSignal.timeout(requestTimeoutMs)
123
+ });
124
+ } catch {
125
+ return null;
126
+ }
127
+ await response.body?.cancel().catch(() => void 0);
128
+ if (response.ok) return true;
129
+ if (response.status === 401 || response.status === 403) return false;
130
+ return null;
131
+ }
132
+ return {
133
+ async verify(apiKey) {
134
+ const hashed = hashApiKey(apiKey);
135
+ const cached = cache.get(hashed);
136
+ if (cached && Date.now() < cached.expiresAt) return cached.valid;
137
+ const pending = inFlight.get(hashed);
138
+ if (pending) return pending;
139
+ const request = askApi(apiKey).then((result) => {
140
+ if (result !== null) remember(hashed, result);
141
+ return result === true;
142
+ }).finally(() => {
143
+ inFlight.delete(hashed);
144
+ });
145
+ inFlight.set(hashed, request);
146
+ return request;
147
+ },
148
+ sweep,
149
+ clear() {
150
+ cache.clear();
151
+ inFlight.clear();
152
+ }
153
+ };
154
+ }
155
+ function createSessionStore({
156
+ maxAgeMs,
157
+ closeTransport
158
+ }) {
159
+ const sessions = /* @__PURE__ */ new Map();
160
+ const countByKey = /* @__PURE__ */ new Map();
161
+ function decrement(apiKey) {
162
+ const hashed = hashApiKey(apiKey);
163
+ const next = (countByKey.get(hashed) ?? 1) - 1;
164
+ if (next <= 0) countByKey.delete(hashed);
165
+ else countByKey.set(hashed, next);
166
+ }
167
+ function drop(sessionId, record) {
168
+ sessions.delete(sessionId);
169
+ decrement(record.apiKey);
170
+ }
171
+ function reserve(apiKey) {
172
+ const hashed = hashApiKey(apiKey);
173
+ countByKey.set(hashed, (countByKey.get(hashed) ?? 0) + 1);
174
+ let settled = false;
175
+ return {
176
+ commit({ sessionId, transport }) {
177
+ if (settled) return;
178
+ settled = true;
179
+ const existing = sessions.get(sessionId);
180
+ if (existing) drop(sessionId, existing);
181
+ sessions.set(sessionId, {
182
+ transport,
183
+ apiKey,
184
+ lastActivityAt: Date.now()
185
+ });
186
+ },
187
+ release() {
188
+ if (settled) return;
189
+ settled = true;
190
+ decrement(apiKey);
191
+ }
192
+ };
193
+ }
194
+ return {
195
+ get(sessionId) {
196
+ return sessions.get(sessionId);
197
+ },
198
+ reserve,
199
+ add({ sessionId, transport, apiKey }) {
200
+ reserve(apiKey).commit({ sessionId, transport });
201
+ },
202
+ touch(sessionId) {
203
+ const record = sessions.get(sessionId);
204
+ if (record) record.lastActivityAt = Date.now();
205
+ },
206
+ remove(sessionId) {
207
+ const record = sessions.get(sessionId);
208
+ if (record) drop(sessionId, record);
209
+ },
210
+ countForKey(apiKey) {
211
+ return countByKey.get(hashApiKey(apiKey)) ?? 0;
212
+ },
213
+ sweep() {
214
+ const now = Date.now();
215
+ for (const [sessionId, record] of sessions) {
216
+ if (now - record.lastActivityAt > maxAgeMs) {
217
+ drop(sessionId, record);
218
+ closeTransport(record.transport);
219
+ }
220
+ }
221
+ },
222
+ closeAll() {
223
+ for (const [sessionId, record] of sessions) {
224
+ drop(sessionId, record);
225
+ closeTransport(record.transport);
226
+ }
227
+ },
228
+ get size() {
229
+ return sessions.size;
230
+ }
231
+ };
232
+ }
233
+ function admitOAuthToken({
234
+ apiKey,
235
+ tokens,
236
+ maxPerKey
237
+ }) {
238
+ const now = Date.now();
239
+ const held = [];
240
+ for (const [token, entry] of tokens) {
241
+ if (now >= entry.expiresAt) {
242
+ tokens.delete(token);
243
+ continue;
244
+ }
245
+ if (entry.apiKey === apiKey) {
246
+ held.push({ token, expiresAt: entry.expiresAt });
247
+ }
248
+ }
249
+ held.sort((a, b) => a.expiresAt - b.expiresAt);
250
+ for (let i = 0; i <= held.length - maxPerKey; i += 1) {
251
+ tokens.delete(held[i].token);
252
+ }
253
+ }
254
+
255
+ export {
256
+ DEFAULT_BIND_HOST,
257
+ isLoopbackHost,
258
+ parseAllowedOrigins,
259
+ isOriginAllowed,
260
+ hashApiKey,
261
+ apiKeysMatch,
262
+ createRateLimiter,
263
+ createApiKeyVerifier,
264
+ createSessionStore,
265
+ admitOAuthToken
266
+ };
267
+ //# sourceMappingURL=chunk-UJPXFA26.js.map
@@ -22,11 +22,17 @@ function getGlobalState() {
22
22
  }
23
23
  };
24
24
  }
25
+ function normalizeEndpoint(endpoint) {
26
+ const trimmed = endpoint.trim();
27
+ let end = trimmed.length;
28
+ while (end > 0 && trimmed[end - 1] === "/") end--;
29
+ return trimmed.slice(0, end);
30
+ }
25
31
  function initConfig(args) {
26
32
  const state = getGlobalState();
27
33
  state.globalConfig = {
28
34
  apiKey: args.apiKey || process.env.LANGWATCH_API_KEY,
29
- endpoint: args.endpoint || process.env.LANGWATCH_ENDPOINT || "https://app.langwatch.ai",
35
+ endpoint: normalizeEndpoint(args.endpoint ?? "") || normalizeEndpoint(process.env.LANGWATCH_ENDPOINT ?? "") || "https://app.langwatch.ai",
30
36
  projectId: process.env.LANGWATCH_PROJECT_ID
31
37
  };
32
38
  }
@@ -69,4 +75,4 @@ export {
69
75
  requireApiKey,
70
76
  runWithConfig
71
77
  };
72
- //# sourceMappingURL=chunk-KOO5733S.js.map
78
+ //# sourceMappingURL=chunk-WT4PO4A3.js.map
package/dist/config.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  initConfig,
4
4
  requireApiKey,
5
5
  runWithConfig
6
- } from "./chunk-KOO5733S.js";
7
- import "./chunk-BJ7B4R26.js";
6
+ } from "./chunk-WT4PO4A3.js";
7
+ import "./chunk-SAS5OB7F.js";
8
8
  export {
9
9
  getConfig,
10
10
  initConfig,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createAgent
3
- } from "./chunk-CE6QMZOP.js";
4
- import "./chunk-5UWY24RP.js";
5
- import "./chunk-KOO5733S.js";
6
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-EYXMLE5X.js";
4
+ import "./chunk-GELJ2MQR.js";
5
+ import "./chunk-WT4PO4A3.js";
6
+ import "./chunk-SAS5OB7F.js";
7
7
 
8
8
  // src/tools/create-agent.ts
9
9
  async function handleCreateAgent(params) {
@@ -21,4 +21,4 @@ async function handleCreateAgent(params) {
21
21
  export {
22
22
  handleCreateAgent
23
23
  };
24
- //# sourceMappingURL=create-agent-7W57J7MT.js.map
24
+ //# sourceMappingURL=create-agent-JFJ2K6X3.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createAnnotation
3
- } from "./chunk-RYRB2YVJ.js";
4
- import "./chunk-5UWY24RP.js";
5
- import "./chunk-KOO5733S.js";
6
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-SR6QPRIE.js";
4
+ import "./chunk-GELJ2MQR.js";
5
+ import "./chunk-WT4PO4A3.js";
6
+ import "./chunk-SAS5OB7F.js";
7
7
 
8
8
  // src/tools/create-annotation.ts
9
9
  async function handleCreateAnnotation(params) {
@@ -22,4 +22,4 @@ async function handleCreateAnnotation(params) {
22
22
  export {
23
23
  handleCreateAnnotation
24
24
  };
25
- //# sourceMappingURL=create-annotation-W2XELBCQ.js.map
25
+ //# sourceMappingURL=create-annotation-EUXXQ6NS.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createApiKey
3
- } from "./chunk-WWMDHZZV.js";
4
- import "./chunk-5UWY24RP.js";
5
- import "./chunk-KOO5733S.js";
6
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-K37ZNPXK.js";
4
+ import "./chunk-GELJ2MQR.js";
5
+ import "./chunk-WT4PO4A3.js";
6
+ import "./chunk-SAS5OB7F.js";
7
7
 
8
8
  // src/tools/create-api-key.ts
9
9
  async function handleCreateApiKey(params) {
@@ -24,4 +24,4 @@ async function handleCreateApiKey(params) {
24
24
  export {
25
25
  handleCreateApiKey
26
26
  };
27
- //# sourceMappingURL=create-api-key-MKRXKFJM.js.map
27
+ //# sourceMappingURL=create-api-key-BGBB76JX.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createDashboard
3
- } from "./chunk-UXXA4D6K.js";
4
- import "./chunk-5UWY24RP.js";
5
- import "./chunk-KOO5733S.js";
6
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-S4GVX36W.js";
4
+ import "./chunk-GELJ2MQR.js";
5
+ import "./chunk-WT4PO4A3.js";
6
+ import "./chunk-SAS5OB7F.js";
7
7
 
8
8
  // src/tools/create-dashboard.ts
9
9
  async function handleCreateDashboard(params) {
@@ -16,4 +16,4 @@ async function handleCreateDashboard(params) {
16
16
  export {
17
17
  handleCreateDashboard
18
18
  };
19
- //# sourceMappingURL=create-dashboard-QGL7IODC.js.map
19
+ //# sourceMappingURL=create-dashboard-Z76AIPLS.js.map
@@ -4,10 +4,10 @@ import {
4
4
  import "./chunk-NUFPTHKU.js";
5
5
  import {
6
6
  createDataset
7
- } from "./chunk-J45SVWPR.js";
8
- import "./chunk-5UWY24RP.js";
9
- import "./chunk-KOO5733S.js";
10
- import "./chunk-BJ7B4R26.js";
7
+ } from "./chunk-AN4OUA4D.js";
8
+ import "./chunk-GELJ2MQR.js";
9
+ import "./chunk-WT4PO4A3.js";
10
+ import "./chunk-SAS5OB7F.js";
11
11
 
12
12
  // src/tools/create-dataset.ts
13
13
  async function handleCreateDataset(params) {
@@ -20,4 +20,4 @@ async function handleCreateDataset(params) {
20
20
  export {
21
21
  handleCreateDataset
22
22
  };
23
- //# sourceMappingURL=create-dataset-3PH7A4HG.js.map
23
+ //# sourceMappingURL=create-dataset-FD5VAXU4.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createDatasetRecords
3
- } from "./chunk-J45SVWPR.js";
4
- import "./chunk-5UWY24RP.js";
5
- import "./chunk-KOO5733S.js";
6
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-AN4OUA4D.js";
4
+ import "./chunk-GELJ2MQR.js";
5
+ import "./chunk-WT4PO4A3.js";
6
+ import "./chunk-SAS5OB7F.js";
7
7
 
8
8
  // src/tools/create-dataset-records.ts
9
9
  async function handleCreateDatasetRecords(params) {
@@ -20,4 +20,4 @@ async function handleCreateDatasetRecords(params) {
20
20
  export {
21
21
  handleCreateDatasetRecords
22
22
  };
23
- //# sourceMappingURL=create-dataset-records-4DZS3VRL.js.map
23
+ //# sourceMappingURL=create-dataset-records-WQUXXOHI.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createEvaluator,
3
3
  getEvaluatorType
4
- } from "./chunk-EU22L52K.js";
5
- import "./chunk-5UWY24RP.js";
6
- import "./chunk-KOO5733S.js";
7
- import "./chunk-BJ7B4R26.js";
4
+ } from "./chunk-OJLYYJWI.js";
5
+ import "./chunk-GELJ2MQR.js";
6
+ import "./chunk-WT4PO4A3.js";
7
+ import "./chunk-SAS5OB7F.js";
8
8
 
9
9
  // src/tools/create-evaluator.ts
10
10
  async function handleCreateEvaluator(params) {
@@ -25,4 +25,4 @@ async function handleCreateEvaluator(params) {
25
25
  export {
26
26
  handleCreateEvaluator
27
27
  };
28
- //# sourceMappingURL=create-evaluator-YWH6NC4M.js.map
28
+ //# sourceMappingURL=create-evaluator-6NV33Z52.js.map
@@ -1,9 +1,14 @@
1
1
  import {
2
2
  createMcpServer
3
- } from "./chunk-VYPSKRPN.js";
4
- import "./chunk-5UWY24RP.js";
5
- import "./chunk-KOO5733S.js";
6
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-QRO35SOM.js";
4
+ import "./chunk-EYXMLE5X.js";
5
+ import "./chunk-HV4DWKBI.js";
6
+ import "./chunk-CKNAH5TG.js";
7
+ import "./chunk-UF6XIGYR.js";
8
+ import "./chunk-6DJDEXET.js";
9
+ import "./chunk-GELJ2MQR.js";
10
+ import "./chunk-WT4PO4A3.js";
11
+ import "./chunk-SAS5OB7F.js";
7
12
  export {
8
13
  createMcpServer
9
14
  };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  createProject
3
- } from "./chunk-XY4STOBE.js";
4
- import "./chunk-5UWY24RP.js";
5
- import "./chunk-KOO5733S.js";
6
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-G4ZAZTZW.js";
4
+ import "./chunk-GELJ2MQR.js";
5
+ import "./chunk-WT4PO4A3.js";
6
+ import "./chunk-SAS5OB7F.js";
7
7
 
8
8
  // src/tools/create-project.ts
9
9
  async function handleCreateProject(params) {
@@ -42,4 +42,4 @@ async function handleCreateProject(params) {
42
42
  export {
43
43
  handleCreateProject
44
44
  };
45
- //# sourceMappingURL=create-project-BOBQ32C5.js.map
45
+ //# sourceMappingURL=create-project-ZQ7TFIO2.js.map
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createPrompt
3
- } from "./chunk-5UWY24RP.js";
4
- import "./chunk-KOO5733S.js";
5
- import "./chunk-BJ7B4R26.js";
3
+ } from "./chunk-GELJ2MQR.js";
4
+ import "./chunk-WT4PO4A3.js";
5
+ import "./chunk-SAS5OB7F.js";
6
6
 
7
7
  // src/tools/create-prompt.ts
8
8
  var HANDLE_PATTERN = /^[a-z0-9_-]+(?:\/[a-z0-9_-]+)?$/;
@@ -37,4 +37,4 @@ async function handleCreatePrompt(params) {
37
37
  export {
38
38
  handleCreatePrompt
39
39
  };
40
- //# sourceMappingURL=create-prompt-FLCFGITE.js.map
40
+ //# sourceMappingURL=create-prompt-BS6QRCUU.js.map