@langwatch/mcp-server 1.0.0 → 2.0.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 (125) hide show
  1. package/.python-version +1 -0
  2. package/CHANGELOG.md +21 -0
  3. package/CONTRIBUTING.md +1 -1
  4. package/README.md +55 -1
  5. package/dist/{archive-project-MK3673A7.js → archive-project-4EQGLBJJ.js} +5 -5
  6. package/dist/{archive-scenario-KATSXRIN.js → archive-scenario-W6BXYDZ3.js} +5 -5
  7. package/dist/{archive-suite-C3KX6IIZ.js → archive-suite-4T6BSRS7.js} +5 -5
  8. package/dist/{assign-prompt-tag-E3C5W6PI.js → assign-prompt-tag-VLXUWEKU.js} +4 -4
  9. package/dist/{chunk-VYPSKRPN.js → chunk-4QC7SA2L.js} +91 -91
  10. package/dist/{chunk-T7WJVS2N.js → chunk-5CCZFUXS.js} +2 -2
  11. package/dist/{chunk-J45SVWPR.js → chunk-77BNWQ3U.js} +2 -2
  12. package/dist/{chunk-XY4STOBE.js → chunk-7RHG56OH.js} +2 -2
  13. package/dist/{chunk-5UWY24RP.js → chunk-A2LEVYQ5.js} +2 -2
  14. package/dist/{chunk-UXXA4D6K.js → chunk-AQJO2EI5.js} +2 -2
  15. package/dist/{chunk-EU22L52K.js → chunk-CDYQOY5U.js} +2 -2
  16. package/dist/{chunk-O3LWVN67.js → chunk-J42FWRJ2.js} +2 -2
  17. package/dist/{chunk-BJ7B4R26.js → chunk-SAS5OB7F.js} +18 -2
  18. package/dist/{chunk-DAIQKS27.js → chunk-SFB4MU6H.js} +2 -2
  19. package/dist/{chunk-WWMDHZZV.js → chunk-TJCXFNDT.js} +2 -2
  20. package/dist/{chunk-CE6QMZOP.js → chunk-TOXJQDIZ.js} +4 -4
  21. package/dist/chunk-UJPXFA26.js +267 -0
  22. package/dist/{chunk-KOO5733S.js → chunk-WT4PO4A3.js} +8 -2
  23. package/dist/{chunk-RYRB2YVJ.js → chunk-YX3A3CFM.js} +2 -2
  24. package/dist/{chunk-WDH5P5RF.js → chunk-YZLYHLLI.js} +2 -2
  25. package/dist/{chunk-Y3HDZ6OW.js → chunk-ZWIL4EFL.js} +2 -2
  26. package/dist/config.js +2 -2
  27. package/dist/{create-agent-7W57J7MT.js → create-agent-7XHO6UIS.js} +5 -5
  28. package/dist/{create-annotation-W2XELBCQ.js → create-annotation-YQXRQC6A.js} +5 -5
  29. package/dist/{create-api-key-MKRXKFJM.js → create-api-key-YUS36KBU.js} +5 -5
  30. package/dist/{create-dashboard-QGL7IODC.js → create-dashboard-4Z5JO5LB.js} +5 -5
  31. package/dist/{create-dataset-3PH7A4HG.js → create-dataset-E6NMSVX7.js} +5 -5
  32. package/dist/{create-dataset-records-4DZS3VRL.js → create-dataset-records-SKHPRD2K.js} +5 -5
  33. package/dist/{create-evaluator-YWH6NC4M.js → create-evaluator-JXF5PF33.js} +5 -5
  34. package/dist/create-mcp-server.js +4 -4
  35. package/dist/{create-project-BOBQ32C5.js → create-project-CS2CB57Y.js} +5 -5
  36. package/dist/{create-prompt-FLCFGITE.js → create-prompt-F5RMX3L3.js} +4 -4
  37. package/dist/{create-prompt-tag-EMPNIKEA.js → create-prompt-tag-GMRWTEFR.js} +4 -4
  38. package/dist/{create-scenario-BSBIHUL6.js → create-scenario-JDR2VB2H.js} +5 -5
  39. package/dist/{create-suite-TWF6BBR4.js → create-suite-LZS6QIAF.js} +5 -5
  40. package/dist/{delete-agent-7MSYNY5E.js → delete-agent-O3EEH4S5.js} +5 -5
  41. package/dist/{delete-annotation-ZT5IGN24.js → delete-annotation-XP6FQM7A.js} +5 -5
  42. package/dist/{delete-dashboard-BTIY5S3L.js → delete-dashboard-RFUNYCNP.js} +5 -5
  43. package/dist/{delete-dataset-U45HQHPR.js → delete-dataset-3MJFRDLP.js} +5 -5
  44. package/dist/{delete-dataset-records-R43IMAWB.js → delete-dataset-records-WPMU5GL5.js} +5 -5
  45. package/dist/{delete-evaluator-U6JMQ6C7.js → delete-evaluator-33SP2JFX.js} +5 -5
  46. package/dist/{delete-prompt-tag-4EV4TDHB.js → delete-prompt-tag-KNMZVSPB.js} +4 -4
  47. package/dist/{delete-workflow-5QYALXEL.js → delete-workflow-3NUXO46U.js} +5 -5
  48. package/dist/{discover-evaluator-schema-MRGHVNTT.js → discover-evaluator-schema-XTAD4X7D.js} +52 -36
  49. package/dist/{discover-scenario-schema-UPBTCWPG.js → discover-scenario-schema-FE64QK2D.js} +2 -2
  50. package/dist/{discover-schema-ICGXPHUW.js → discover-schema-L6QDPON3.js} +2 -2
  51. package/dist/{get-agent-7QJVPH72.js → get-agent-Y7MWZ65F.js} +5 -5
  52. package/dist/{get-analytics-PVERWOA5.js → get-analytics-TETCSOK6.js} +4 -4
  53. package/dist/{get-dashboard-ZZPC3WMD.js → get-dashboard-KHBEGZGL.js} +5 -5
  54. package/dist/{get-dataset-25TB2LQH.js → get-dataset-RCMU5VAH.js} +5 -5
  55. package/dist/{get-evaluator-3FTRQKEC.js → get-evaluator-ADMKVWYZ.js} +5 -5
  56. package/dist/{get-project-5OAXYC57.js → get-project-RAK7URQJ.js} +5 -5
  57. package/dist/{get-prompt-I753LZKZ.js → get-prompt-OY5B7TRI.js} +4 -4
  58. package/dist/{get-scenario-DSSTR6FI.js → get-scenario-ZTAJJL5T.js} +5 -5
  59. package/dist/{get-simulation-run-RQPMS2MC.js → get-simulation-run-T2ZQWYH2.js} +5 -5
  60. package/dist/{get-suite-GTOCY5PL.js → get-suite-J7JVWO6O.js} +5 -5
  61. package/dist/{get-trace-O5VT3NAC.js → get-trace-K7U234Q4.js} +4 -4
  62. package/dist/{get-workflow-3EZDOEIF.js → get-workflow-L5L2PSK3.js} +5 -5
  63. package/dist/http-security-EU3CHTY7.js +26 -0
  64. package/dist/{http-server-2ACJ3CXW.js → http-server-YXHFPPGA.js} +1033 -693
  65. package/dist/index.js +3066 -2105
  66. package/dist/{langwatch-api-annotations-E65MI3WZ.js → langwatch-api-annotations-FDAS6NQ7.js} +5 -5
  67. package/dist/{langwatch-api-dashboards-QCDECRCY.js → langwatch-api-dashboards-JTVCS7ZJ.js} +5 -5
  68. package/dist/{langwatch-api-monitors-UIO2KTDV.js → langwatch-api-monitors-3J7UIQME.js} +4 -4
  69. package/dist/{langwatch-api-secrets-4T2EKSJ7.js → langwatch-api-secrets-BUBSNCNO.js} +4 -4
  70. package/dist/{langwatch-api-triggers-MPOEKPUY.js → langwatch-api-triggers-EDFUCJN6.js} +4 -4
  71. package/dist/langwatch-api-workflows-NBJX5KOG.js +16 -0
  72. package/dist/{list-agents-TIJTP566.js → list-agents-KFHKGPXV.js} +5 -5
  73. package/dist/{list-annotations-CGX5BT7E.js → list-annotations-ZTVP4EEL.js} +5 -5
  74. package/dist/{list-api-keys-JLWJPFRX.js → list-api-keys-CWD4UQT5.js} +5 -5
  75. package/dist/{list-dashboards-RNIWX3TX.js → list-dashboards-PWG6P6KR.js} +5 -5
  76. package/dist/{list-dataset-records-B5MHZR66.js → list-dataset-records-IOE7LQXS.js} +5 -5
  77. package/dist/{list-datasets-BVCAMQCP.js → list-datasets-ZT4JYUDT.js} +5 -5
  78. package/dist/{list-evaluators-65FBTL2U.js → list-evaluators-SJHC7VBH.js} +5 -5
  79. package/dist/{list-model-providers-GRK3I3VV.js → list-model-providers-PPD2WPD2.js} +5 -5
  80. package/dist/{list-projects-JLMBFMW3.js → list-projects-K7QAIX2I.js} +5 -5
  81. package/dist/{list-prompt-tags-UHNWDGQI.js → list-prompt-tags-FOO6TNHB.js} +4 -4
  82. package/dist/{list-prompts-7254B3U7.js → list-prompts-SC2HAUFG.js} +4 -4
  83. package/dist/{list-scenarios-46YNICKM.js → list-scenarios-F2WYNRIE.js} +5 -5
  84. package/dist/{list-simulation-runs-LGNEFNPN.js → list-simulation-runs-KF5THG5H.js} +5 -5
  85. package/dist/{list-suites-5VK4HXEK.js → list-suites-CRY4VWW6.js} +5 -5
  86. package/dist/{list-workflows-MLQDM6CP.js → list-workflows-QSJWURCK.js} +5 -5
  87. package/dist/{rename-prompt-tag-RHQMNEQL.js → rename-prompt-tag-EKWU5QF3.js} +4 -4
  88. package/dist/{report-issue-DXJ6TPTC.js → report-issue-XYVAPAYJ.js} +7 -7
  89. package/dist/{revoke-api-key-3Y35EMBT.js → revoke-api-key-FTRTZMOF.js} +5 -5
  90. package/dist/{run-agent-RBSIFKRT.js → run-agent-6SM4XNA7.js} +5 -5
  91. package/dist/{run-suite-K3DNQ3SE.js → run-suite-NKZCJ2IN.js} +5 -5
  92. package/dist/{run-workflow-5LVBZYLS.js → run-workflow-QPXC627O.js} +5 -5
  93. package/dist/{search-traces-U4HLOCZ2.js → search-traces-A6HFKPLJ.js} +4 -4
  94. package/dist/{set-model-provider-V3M5CDIY.js → set-model-provider-3WKT63ZN.js} +5 -5
  95. package/dist/{update-agent-47RZIHS7.js → update-agent-SMAEHLXH.js} +5 -5
  96. package/dist/{update-dataset-G6QJJGS5.js → update-dataset-BDUK7TUO.js} +5 -5
  97. package/dist/{update-dataset-record-RMWLSWCS.js → update-dataset-record-4ZSDRBSW.js} +5 -5
  98. package/dist/{update-evaluator-SFRRI5Q3.js → update-evaluator-LS6TIBY7.js} +5 -5
  99. package/dist/{update-project-PI5DWBVK.js → update-project-LKVYXENH.js} +5 -5
  100. package/dist/{update-prompt-RQFTEO7Y.js → update-prompt-ODCRQRN6.js} +4 -4
  101. package/dist/{update-scenario-G3IU2UIB.js → update-scenario-NEXCAQI7.js} +5 -5
  102. package/dist/{update-suite-TRGGLNR7.js → update-suite-SNO3GS7T.js} +5 -5
  103. package/package.json +3 -3
  104. package/pyproject.toml +1 -1
  105. package/src/__tests__/config.unit.test.ts +33 -0
  106. package/src/__tests__/docker.integration.test.ts +91 -7
  107. package/src/__tests__/documentation-fetch-security.integration.test.ts +8 -2
  108. package/src/__tests__/feature-map-tool-drift.unit.test.ts +93 -0
  109. package/src/__tests__/http-security-origin.unit.test.ts +97 -0
  110. package/src/__tests__/http-security-sessions.unit.test.ts +209 -0
  111. package/src/__tests__/http-security-verifier.unit.test.ts +248 -0
  112. package/src/__tests__/http-server-allocation.integration.test.ts +279 -0
  113. package/src/__tests__/http-server-origin.integration.test.ts +169 -0
  114. package/src/__tests__/http-server-session-auth.integration.test.ts +341 -0
  115. package/src/__tests__/http-transport.integration.test.ts +85 -87
  116. package/src/__tests__/support/http-server-harness.ts +138 -0
  117. package/src/config.ts +17 -2
  118. package/src/http-security.ts +492 -0
  119. package/src/http-server.ts +536 -152
  120. package/src/index.ts +49 -2
  121. package/src/tools/discover-evaluator-schema.ts +2 -2
  122. package/tsconfig.json +2 -2
  123. package/uv.lock +2 -2
  124. package/dist/langwatch-api-workflows-5HRZ7HR4.js +0 -16
  125. package/pnpm-workspace.yaml +0 -34
package/src/index.ts CHANGED
@@ -24,6 +24,17 @@ const argv = await yargs(hideBin(process.argv))
24
24
  description: "HTTP server port (only used with --http)",
25
25
  default: 3000,
26
26
  })
27
+ .option("host", {
28
+ type: "string",
29
+ description:
30
+ "HTTP listen address (only used with --http). Defaults to loopback; pass 0.0.0.0 to accept connections from other machines",
31
+ })
32
+ .option("allowedOrigin", {
33
+ type: "array",
34
+ string: true,
35
+ description:
36
+ "Browser origin allowed to call the HTTP server, repeatable. Loopback origins are always allowed",
37
+ })
27
38
  .help()
28
39
  .parseAsync();
29
40
 
@@ -34,11 +45,47 @@ initConfig({
34
45
 
35
46
  if (argv.http) {
36
47
  const { startHttpServer } = await import("./http-server.js");
37
- const { port } = await startHttpServer({ port: argv.port });
38
- console.log(`LangWatch MCP server listening on http://0.0.0.0:${port}/mcp`);
48
+ const { isLoopbackHost, parseAllowedOrigins } = await import(
49
+ "./http-security.js"
50
+ );
51
+
52
+ const allowedOrigins =
53
+ argv.allowedOrigin && argv.allowedOrigin.length > 0
54
+ ? parseAllowedOrigins(argv.allowedOrigin.join(","))
55
+ : undefined;
56
+
57
+ const { port, host } = await startHttpServer({
58
+ port: argv.port,
59
+ host: argv.host,
60
+ allowedOrigins,
61
+ });
62
+
63
+ // An IPv6 literal has to be bracketed inside a URL, and must not be
64
+ // double-bracketed when the operator already wrote it that way.
65
+ const displayHost =
66
+ host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
67
+ console.log(
68
+ `LangWatch MCP server listening on http://${displayHost}:${port}/mcp`
69
+ );
39
70
  console.log(
40
71
  "Clients must provide their API key via Authorization: Bearer <key> header"
41
72
  );
73
+ if (!isLoopbackHost(host)) {
74
+ console.warn(
75
+ `Warning: bound to ${host}, so the server is reachable from other machines. ` +
76
+ "Make sure it sits behind a trusted network boundary and that --allowedOrigin " +
77
+ "lists only origins you control."
78
+ );
79
+ }
80
+ if (process.env.LANGWATCH_MCP_TRUST_PROXY === "true") {
81
+ console.warn(
82
+ "Warning: LANGWATCH_MCP_TRUST_PROXY=true, so the rate limit on failed " +
83
+ "authentication uses the client address from X-Forwarded-For. Keep this " +
84
+ "on only when a trusted proxy terminates in front of the port and " +
85
+ "overwrites that header. Otherwise a client can supply any address there " +
86
+ "and the limit stops counting."
87
+ );
88
+ }
42
89
  } else {
43
90
  const transport = new StdioServerTransport();
44
91
  const server = createMcpServer();
@@ -1,5 +1,5 @@
1
- import { AVAILABLE_EVALUATORS } from "../../../langevals/ts-integration/evaluators.generated.js";
2
- import type { EvaluatorDefinition, EvaluatorTypes } from "../../../langevals/ts-integration/evaluators.generated.js";
1
+ import { AVAILABLE_EVALUATORS } from "../../../../services/langevals/ts-integration/evaluators.generated.js";
2
+ import type { EvaluatorDefinition, EvaluatorTypes } from "../../../../services/langevals/ts-integration/evaluators.generated.js";
3
3
 
4
4
  /**
5
5
  * Formats evaluator schema information for the discover_schema tool.
package/tsconfig.json CHANGED
@@ -13,8 +13,8 @@
13
13
  "skipLibCheck": true,
14
14
  "forceConsistentCasingInFileNames": true,
15
15
  "moduleResolution": "bundler",
16
- "rootDir": "..",
17
- // The evaluator catalog we import (langevals/ts-integration/evaluators.generated.ts)
16
+ "rootDir": "../..",
17
+ // The evaluator catalog we import (services/langevals/ts-integration/evaluators.generated.ts)
18
18
  // is Zod-first and imports `zod`, but lives outside this package's
19
19
  // node_modules tree, so plain resolution cannot find it. Point `zod` at this
20
20
  // package's own copy (a declared dependency) so the type-checker resolves it.
package/uv.lock CHANGED
@@ -967,7 +967,7 @@ wheels = [
967
967
  [[package]]
968
968
  name = "langwatch"
969
969
  version = "0.26.0"
970
- source = { editable = "../python-sdk" }
970
+ source = { editable = "../../sdks/python" }
971
971
  dependencies = [
972
972
  { name = "attrs" },
973
973
  { name = "coolname" },
@@ -1210,7 +1210,7 @@ dependencies = [
1210
1210
  [package.metadata]
1211
1211
  requires-dist = [
1212
1212
  { name = "ipykernel", specifier = ">=6.30.1" },
1213
- { name = "langwatch", editable = "../python-sdk" },
1213
+ { name = "langwatch", editable = "../../sdks/python" },
1214
1214
  { name = "litellm", specifier = ">=1.84.0" },
1215
1215
  { name = "mcp", extras = ["cli"], specifier = ">=1.13.1" },
1216
1216
  { name = "pandas", specifier = ">=2.3.2" },
@@ -1,16 +0,0 @@
1
- import {
2
- deleteWorkflow,
3
- getWorkflow,
4
- listWorkflows,
5
- runWorkflow
6
- } from "./chunk-T7WJVS2N.js";
7
- import "./chunk-5UWY24RP.js";
8
- import "./chunk-KOO5733S.js";
9
- import "./chunk-BJ7B4R26.js";
10
- export {
11
- deleteWorkflow,
12
- getWorkflow,
13
- listWorkflows,
14
- runWorkflow
15
- };
16
- //# sourceMappingURL=langwatch-api-workflows-5HRZ7HR4.js.map
@@ -1,34 +0,0 @@
1
- # Standalone workspace: mcp-server is installed on its own in CI, the
2
- # release workflow, and its Dockerfile. Shared source-only contract packages
3
- # are bundled by tsup for publish.
4
- packages:
5
- - .
6
- - ../packages/handled-error
7
- - ../langwatch/packages/redaction
8
- - ../langwatch/packages/ssrf
9
-
10
- minimumReleaseAge: 10080
11
-
12
- overrides:
13
- # Security: protobufjs code execution + prototype-pollution + DoS + Any-expansion DoS + property shadowing
14
- # (GHSA-xq3m-2v4x-88gg, GHSA-66ff-xgx4-vchm, GHSA-75px-5xx7-5xc7,
15
- # GHSA-jvwf-75h9-cwgg, GHSA-685m-2w69-288q, GHSA-wcpc-wj8m-hjx6, GHSA-f38q-mgvj-vph7)
16
- "protobufjs": ">=7.5.6 <8.0.0 || >=8.6.0"
17
- # Security: langsmith untrusted manifest deserialization (GHSA-3644-q5cj-c5c7).
18
- # langsmith is only a transitive of the @langwatch/scenario devDependency
19
- # (via langchain / @langchain/core); pinned to a known-safe version.
20
- "langsmith": "0.6.0"
21
- # Security: esbuild Deno binary integrity RCE + dev-server file read (GHSA-gv7w-rqvm-qjhr / GHSA-g7r4-m6w7-qqqr)
22
- "esbuild@<0.28.1": ">=0.28.1"
23
- # Security: vite dev-server file read / middleware path bypass
24
- "vite@>=7.0.0 <7.3.5": ">=7.3.5 <8"
25
- # Security: hono request smuggling / path confusion
26
- "hono@<4.12.25": ">=4.12.25"
27
- # Security: fast-uri path traversal + host confusion
28
- "fast-uri@<3.1.2": "3.1.2"
29
- liquidjs: ">=10.26.0"
30
- # Security: uuid missing buffer bounds check in v3/v5/v6 (GHSA-w5hq-g745-h8pq)
31
- "uuid@<11.1.1": ">=11.1.1 <12"
32
-
33
- onlyBuiltDependencies:
34
- - node-pty