@langwatch/mcp-server 0.3.2 → 0.4.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 (55) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +97 -25
  3. package/dist/chunk-AAQNA53E.js +28 -0
  4. package/dist/chunk-AAQNA53E.js.map +1 -0
  5. package/dist/chunk-HOPTUDCZ.js +90 -0
  6. package/dist/chunk-HOPTUDCZ.js.map +1 -0
  7. package/dist/chunk-ZXKLPC2E.js +27 -0
  8. package/dist/chunk-ZXKLPC2E.js.map +1 -0
  9. package/dist/config-FIQWQRUB.js +11 -0
  10. package/dist/config-FIQWQRUB.js.map +1 -0
  11. package/dist/create-prompt-UBC537BJ.js +22 -0
  12. package/dist/create-prompt-UBC537BJ.js.map +1 -0
  13. package/dist/discover-schema-3T52ORPB.js +446 -0
  14. package/dist/discover-schema-3T52ORPB.js.map +1 -0
  15. package/dist/get-analytics-3IFTN6MY.js +55 -0
  16. package/dist/get-analytics-3IFTN6MY.js.map +1 -0
  17. package/dist/get-prompt-2ZB5B3QC.js +48 -0
  18. package/dist/get-prompt-2ZB5B3QC.js.map +1 -0
  19. package/dist/get-trace-7IXKKCJJ.js +50 -0
  20. package/dist/get-trace-7IXKKCJJ.js.map +1 -0
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.js +20003 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/list-prompts-J72LTP7Z.js +33 -0
  25. package/dist/list-prompts-J72LTP7Z.js.map +1 -0
  26. package/dist/search-traces-RW2NDHN5.js +72 -0
  27. package/dist/search-traces-RW2NDHN5.js.map +1 -0
  28. package/dist/update-prompt-G6HHZSUM.js +31 -0
  29. package/dist/update-prompt-G6HHZSUM.js.map +1 -0
  30. package/package.json +8 -8
  31. package/src/__tests__/config.unit.test.ts +89 -0
  32. package/src/__tests__/date-parsing.unit.test.ts +78 -0
  33. package/src/__tests__/discover-schema.unit.test.ts +118 -0
  34. package/src/__tests__/integration.integration.test.ts +313 -0
  35. package/src/__tests__/langwatch-api.unit.test.ts +309 -0
  36. package/src/__tests__/schemas.unit.test.ts +85 -0
  37. package/src/__tests__/tools.unit.test.ts +729 -0
  38. package/src/config.ts +31 -0
  39. package/src/index.ts +254 -0
  40. package/src/langwatch-api.ts +265 -0
  41. package/src/schemas/analytics-groups.ts +78 -0
  42. package/src/schemas/analytics-metrics.ts +179 -0
  43. package/src/schemas/filter-fields.ts +119 -0
  44. package/src/schemas/index.ts +3 -0
  45. package/src/tools/create-prompt.ts +29 -0
  46. package/src/tools/discover-schema.ts +106 -0
  47. package/src/tools/get-analytics.ts +71 -0
  48. package/src/tools/get-prompt.ts +56 -0
  49. package/src/tools/get-trace.ts +61 -0
  50. package/src/tools/list-prompts.ts +35 -0
  51. package/src/tools/search-traces.ts +91 -0
  52. package/src/tools/update-prompt.ts +44 -0
  53. package/src/utils/date-parsing.ts +31 -0
  54. package/tests/evaluations.ipynb +634 -634
  55. package/tests/scenario-openai.test.ts +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.0](https://github.com/langwatch/langwatch/compare/mcp-server@v0.3.3...mcp-server@v0.4.0) (2026-02-08)
4
+
5
+
6
+ ### Features
7
+
8
+ * add CI/CD execution support for evaluations v3 ([#1118](https://github.com/langwatch/langwatch/issues/1118)) ([d28adac](https://github.com/langwatch/langwatch/commit/d28adaceeb87921d9c7c0f1cf76b5e03f3b90fbd))
9
+ * add observability and prompt MCP tools to @langwatch/mcp-server v0.4.0 ([#1410](https://github.com/langwatch/langwatch/issues/1410)) ([b770040](https://github.com/langwatch/langwatch/commit/b7700401dd87e7f1b76fefb213d67c906bcc1202))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * **mcp-server:** skip integration test in CI ([#1300](https://github.com/langwatch/langwatch/issues/1300)) ([c16f232](https://github.com/langwatch/langwatch/commit/c16f2320b5c99818324d506a64ed3588085d8517))
15
+
16
+ ## [0.3.3](https://github.com/langwatch/langwatch/compare/mcp-server@v0.3.2...mcp-server@v0.3.3) (2025-12-18)
17
+
18
+
19
+ ### Miscellaneous
20
+
21
+ * trigger release ([#1011](https://github.com/langwatch/langwatch/issues/1011)) ([6173f53](https://github.com/langwatch/langwatch/commit/6173f53b041d9ee7e6b930270224954ba3c6621e))
22
+
3
23
  ## [0.3.2](https://github.com/langwatch/langwatch/compare/mcp-server@v0.3.1...mcp-server@v0.3.2) (2025-12-17)
4
24
 
5
25
 
package/README.md CHANGED
@@ -1,56 +1,128 @@
1
- # LangWatch 🏰 MCP Server
1
+ # LangWatch MCP Server
2
2
 
3
- The LangWatch MCP Server makes your AI coding assistant an expert in both [LangWatch](https://langwatch.ai/docs), for automatically instrumenting your code, managing versioned prompts and creating evaluations; and [Scenario](https://langwatch.ai/scenario), for automatically testing your agents via simulations.
3
+ MCP server that gives AI coding agents access to LangWatch observability data, prompts, and documentation via the [Model Context Protocol](https://modelcontextprotocol.io/introduction).
4
4
 
5
- ## Setup in your Coding Assistant 👩‍💻
5
+ ## Quick Setup
6
6
 
7
- 1. Open Cursor/Claude Code/your editor Settings
8
- 2. Navigate to the MCP settings
9
- 3. Set the "name" as "LangWatch"
10
- 4. Add the LangWatch MCP:
7
+ Add to your MCP client configuration (Claude Code, Cursor, etc.):
11
8
 
12
9
  ```json
13
10
  {
14
11
  "mcpServers": {
15
12
  "langwatch": {
16
13
  "command": "npx",
17
- "args": ["-y", "@langwatch/mcp-server"]
14
+ "args": ["-y", "@langwatch/mcp-server"],
15
+ "env": {
16
+ "LANGWATCH_API_KEY": "your-api-key-here"
17
+ }
18
18
  }
19
19
  }
20
20
  }
21
21
  ```
22
22
 
23
+ For Claude Code, you can also run:
24
+
25
+ ```bash
26
+ claude mcp add langwatch -- npx -y @langwatch/mcp-server --apiKey your-api-key-here
27
+ ```
28
+
29
+ The API key is required for observability and prompt tools. Documentation tools work without it.
30
+
31
+ ## Configuration
32
+
33
+ | Env Var | CLI Arg | Description |
34
+ |---------|---------|-------------|
35
+ | `LANGWATCH_API_KEY` | `--apiKey` | API key for authentication |
36
+ | `LANGWATCH_ENDPOINT` | `--endpoint` | API endpoint (default: `https://app.langwatch.ai`) |
37
+
23
38
  ## Tools
24
39
 
25
- The MCP Server provides the following tools:
40
+ ### Documentation
41
+
42
+ | Tool | Description |
43
+ |------|-------------|
44
+ | `fetch_langwatch_docs` | Fetch LangWatch integration docs |
45
+ | `fetch_scenario_docs` | Fetch Scenario agent testing docs |
46
+
47
+ ### Observability (requires API key)
48
+
49
+ | Tool | Description |
50
+ |------|-------------|
51
+ | `discover_schema` | Explore available filters, metrics, aggregations, and groups |
52
+ | `search_traces` | Search traces with filters, text query, and date range |
53
+ | `get_trace` | Get full trace details with AI-readable formatting |
54
+ | `get_analytics` | Query timeseries analytics data |
55
+
56
+ ### Prompts (requires API key)
57
+
58
+ | Tool | Description |
59
+ |------|-------------|
60
+ | `list_prompts` | List all prompts |
61
+ | `get_prompt` | Get prompt with messages and version history |
62
+ | `create_prompt` | Create a new prompt |
63
+ | `update_prompt` | Update prompt or create new version |
64
+
65
+ ## Output Formats
66
+
67
+ The `search_traces` and `get_trace` tools support a `format` parameter:
68
+
69
+ - **`digest`** (default) — AI-readable trace digest with hierarchical span tree, timing, inputs/outputs, and errors. Optimized for LLM consumption — compact and information-dense.
70
+ - **`json`** — Full raw trace data with all fields. Useful for programmatic access or when you need the complete schema.
26
71
 
27
- ### `fetch_langwatch_docs`
72
+ ## Usage Tips
28
73
 
29
- - **Description:** Fetches the LangWatch docs for understanding how to implement LangWatch in your codebase.
30
- - **Parameters:**
31
- - `url`: (Optional) The full url of the specific doc page. If not provided, the docs index will be fetched.
74
+ - Start with `discover_schema` to understand available filter fields and metrics.
75
+ - Use `search_traces` to find relevant traces, then `get_trace` for full details.
76
+ - Search returns 25 traces per page by default. Use `scrollId` from the response to paginate.
77
+ - Analytics uses `category.name` format for metrics (e.g., `performance.completion_time`).
78
+ - Use `create_prompt` / `update_prompt` with `createVersion: true` for safe prompt iteration.
32
79
 
33
- ### `fetch_scenario_docs`
80
+ ## Development
34
81
 
35
- - **Description:** Fetches Scenario docs for understanding how to write agent simulations to test the agents on your codebase.
36
- - **Parameters:**
37
- - `url`: (Optional) The full url of the specific doc page. If not provided, the docs index will be fetched.
82
+ ### Prerequisites
38
83
 
39
- ## Example Usage
84
+ - Node.js 18+
85
+ - pnpm
40
86
 
41
- Ask your coding assistant to instrument your code:
87
+ ### Setup
42
88
 
43
- > "Can you instrument my LLM code with LangWatch"
89
+ ```bash
90
+ pnpm install
91
+ ```
92
+
93
+ ### Build
44
94
 
45
- Or ask it to write a scenario test:
95
+ ```bash
96
+ pnpm build
97
+ ```
46
98
 
47
- > "Can you implement a scenario test for my agent?"
99
+ ### Test
48
100
 
49
- <img alt="LangWatch MCP Cursor Example" src="../assets/mcp-server/cursor-example.png" width="900">
101
+ ```bash
102
+ pnpm test # Run all tests
103
+ pnpm test:unit # Unit tests only
104
+ ```
50
105
 
51
- ## 🛟 Support
106
+ ### Local testing
107
+
108
+ Build and point your MCP client to the local dist:
109
+
110
+ ```json
111
+ {
112
+ "mcpServers": {
113
+ "langwatch": {
114
+ "command": "node",
115
+ "args": [
116
+ "/path/to/mcp-server/dist/index.js",
117
+ "--apiKey", "your-api-key",
118
+ "--endpoint", "http://localhost:5560"
119
+ ]
120
+ }
121
+ }
122
+ }
123
+ ```
52
124
 
53
- If you have questions or need help, join our community:
125
+ ## Support
54
126
 
55
127
  - [Discord Community](https://discord.gg/kT4PhDS2gH)
56
128
  - [LangWatch Docs](https://langwatch.ai/docs)
@@ -0,0 +1,28 @@
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
@@ -0,0 +1 @@
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":[]}
@@ -0,0 +1,90 @@
1
+ import {
2
+ getConfig,
3
+ requireApiKey
4
+ } from "./chunk-AAQNA53E.js";
5
+
6
+ // src/langwatch-api.ts
7
+ async function makeRequest(method, path, body) {
8
+ const url = getConfig().endpoint + path;
9
+ const headers = {
10
+ "X-Auth-Token": requireApiKey()
11
+ };
12
+ if (method === "POST") {
13
+ headers["Content-Type"] = "application/json";
14
+ }
15
+ const response = await fetch(url, {
16
+ method,
17
+ headers,
18
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {}
19
+ });
20
+ if (!response.ok) {
21
+ const responseBody = await response.text();
22
+ throw new Error(
23
+ `LangWatch API error ${response.status}: ${responseBody}`
24
+ );
25
+ }
26
+ return response.json();
27
+ }
28
+ async function searchTraces(params) {
29
+ const { format = "digest", ...rest } = params;
30
+ return makeRequest("POST", "/api/traces/search", {
31
+ ...rest,
32
+ format
33
+ });
34
+ }
35
+ async function getTraceById(traceId, format = "digest") {
36
+ return makeRequest(
37
+ "GET",
38
+ `/api/traces/${encodeURIComponent(traceId)}?format=${format}`
39
+ );
40
+ }
41
+ async function getAnalyticsTimeseries(params) {
42
+ return makeRequest(
43
+ "POST",
44
+ "/api/analytics/timeseries",
45
+ params
46
+ );
47
+ }
48
+ async function listPrompts() {
49
+ return makeRequest("GET", "/api/prompts");
50
+ }
51
+ async function getPrompt(idOrHandle, version) {
52
+ const query = version != null ? `?version=${version}` : "";
53
+ return makeRequest(
54
+ "GET",
55
+ `/api/prompts/${encodeURIComponent(idOrHandle)}${query}`
56
+ );
57
+ }
58
+ async function createPrompt(data) {
59
+ return makeRequest(
60
+ "POST",
61
+ "/api/prompts",
62
+ data
63
+ );
64
+ }
65
+ async function updatePrompt(idOrHandle, data) {
66
+ return makeRequest(
67
+ "POST",
68
+ `/api/prompts/${encodeURIComponent(idOrHandle)}`,
69
+ data
70
+ );
71
+ }
72
+ async function createPromptVersion(idOrHandle, data) {
73
+ return makeRequest(
74
+ "POST",
75
+ `/api/prompts/${encodeURIComponent(idOrHandle)}/versions`,
76
+ data
77
+ );
78
+ }
79
+
80
+ export {
81
+ searchTraces,
82
+ getTraceById,
83
+ getAnalyticsTimeseries,
84
+ listPrompts,
85
+ getPrompt,
86
+ createPrompt,
87
+ updatePrompt,
88
+ createPromptVersion
89
+ };
90
+ //# sourceMappingURL=chunk-HOPTUDCZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langwatch-api.ts"],"sourcesContent":["import { getConfig, requireApiKey } from \"./config.js\";\n\n// --- Response types ---\n\nexport interface TraceSearchResult {\n trace_id: string;\n formatted_trace?: string;\n input?: { value: string };\n output?: { value: string };\n timestamps?: { started_at?: string | number };\n metadata?: Record<string, unknown>;\n error?: Record<string, unknown>;\n}\n\nexport interface SearchTracesResponse {\n traces: TraceSearchResult[];\n pagination?: {\n totalHits?: number;\n scrollId?: string;\n };\n}\n\nexport interface TraceDetailResponse {\n trace_id: string;\n formatted_trace?: string;\n input?: { value: string };\n output?: { value: string };\n timestamps?: {\n started_at?: string | number;\n updated_at?: string | number;\n inserted_at?: string | number;\n };\n metadata?: {\n user_id?: string;\n thread_id?: string;\n customer_id?: string;\n labels?: string[];\n [key: string]: unknown;\n };\n error?: Record<string, unknown>;\n ascii_tree?: string;\n evaluations?: Array<{\n evaluator_id?: string;\n name?: string;\n score?: number;\n passed?: boolean;\n label?: string;\n }>;\n spans?: Array<{\n span_id: string;\n name?: string;\n type?: string;\n model?: string;\n input?: { value: string };\n output?: { value: string };\n timestamps?: { started_at?: number; finished_at?: number };\n metrics?: {\n completion_time_ms?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n tokens_estimated?: boolean;\n cost?: number;\n };\n }>;\n}\n\nexport interface AnalyticsBucket {\n date: string;\n [key: string]: unknown;\n}\n\nexport interface AnalyticsTimeseriesResponse {\n currentPeriod: AnalyticsBucket[];\n previousPeriod: AnalyticsBucket[];\n}\n\nexport interface PromptSummary {\n id?: string;\n handle?: string;\n name?: string;\n description?: string | null;\n latestVersionNumber?: number;\n version?: number;\n}\n\nexport interface PromptVersion {\n version?: number;\n commitMessage?: string;\n model?: string;\n modelProvider?: string;\n messages?: Array<{ role: string; content: string }>;\n}\n\nexport interface PromptDetailResponse extends PromptSummary {\n versions?: PromptVersion[];\n model?: string;\n modelProvider?: 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 */\nasync function makeRequest(\n method: \"GET\" | \"POST\",\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 (method === \"POST\") {\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 name: string;\n handle?: string;\n messages: Array<{ role: string; content: string }>;\n model: string;\n modelProvider: string;\n description?: 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 modelProvider?: string;\n commitMessage?: string;\n }\n): Promise<PromptMutationResponse> {\n return makeRequest(\n \"POST\",\n `/api/prompts/${encodeURIComponent(idOrHandle)}`,\n data\n ) as Promise<PromptMutationResponse>;\n}\n\n/** Creates a new version of an existing prompt. */\nexport async function createPromptVersion(\n idOrHandle: string,\n data: {\n messages?: Array<{ role: string; content: string }>;\n model?: string;\n modelProvider?: string;\n commitMessage?: string;\n }\n): Promise<PromptMutationResponse> {\n return makeRequest(\n \"POST\",\n `/api/prompts/${encodeURIComponent(idOrHandle)}/versions`,\n data\n ) as Promise<PromptMutationResponse>;\n}\n"],"mappings":";;;;;;AAsHA,eAAe,YACb,QACA,MACA,MACkB;AAClB,QAAM,MAAM,UAAU,EAAE,WAAW;AACnC,QAAM,UAAkC;AAAA,IACtC,gBAAgB,cAAc;AAAA,EAChC;AAEA,MAAI,WAAW,QAAQ;AACrB,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,MAOC;AAClC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,eAAsB,aACpB,YACA,MAMiC;AACjC,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,UAAU,CAAC;AAAA,IAC9C;AAAA,EACF;AACF;AAGA,eAAsB,oBACpB,YACA,MAMiC;AACjC,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,mBAAmB,UAAU,CAAC;AAAA,IAC9C;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,27 @@
1
+ // src/utils/date-parsing.ts
2
+ var RELATIVE_UNITS = {
3
+ h: 36e5,
4
+ d: 864e5,
5
+ w: 6048e5,
6
+ m: 2592e6
7
+ };
8
+ function parseRelativeDate(input) {
9
+ if (input === "now") return Date.now();
10
+ const match = input.match(/^(\d+)(h|d|w|m)$/);
11
+ if (match) {
12
+ const [, amount, unit] = match;
13
+ return Date.now() - parseInt(amount) * (RELATIVE_UNITS[unit] ?? 864e5);
14
+ }
15
+ const parsed = Date.parse(input);
16
+ if (Number.isNaN(parsed)) {
17
+ throw new Error(
18
+ `Invalid date: "${input}". Use a relative duration (e.g. "24h", "7d", "4w") or an ISO date string.`
19
+ );
20
+ }
21
+ return parsed;
22
+ }
23
+
24
+ export {
25
+ parseRelativeDate
26
+ };
27
+ //# sourceMappingURL=chunk-ZXKLPC2E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/date-parsing.ts"],"sourcesContent":["const RELATIVE_UNITS: Record<string, number> = {\n h: 3600000,\n d: 86400000,\n w: 604800000,\n m: 2592000000,\n};\n\n/**\n * Parses a date string that can be either a relative duration (e.g. \"24h\", \"7d\")\n * or an ISO date string. Throws on invalid input rather than silently falling back.\n *\n * @returns epoch milliseconds\n * @throws Error if the input is not a valid relative duration or parseable date string\n */\nexport function parseRelativeDate(input: string): number {\n if (input === \"now\") return Date.now();\n\n const match = input.match(/^(\\d+)(h|d|w|m)$/);\n if (match) {\n const [, amount, unit] = match;\n return Date.now() - parseInt(amount!) * (RELATIVE_UNITS[unit!] ?? 86400000);\n }\n\n const parsed = Date.parse(input);\n if (Number.isNaN(parsed)) {\n throw new Error(\n `Invalid date: \"${input}\". Use a relative duration (e.g. \"24h\", \"7d\", \"4w\") or an ISO date string.`\n );\n }\n return parsed;\n}\n"],"mappings":";AAAA,IAAM,iBAAyC;AAAA,EAC7C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AASO,SAAS,kBAAkB,OAAuB;AACvD,MAAI,UAAU,MAAO,QAAO,KAAK,IAAI;AAErC,QAAM,QAAQ,MAAM,MAAM,kBAAkB;AAC5C,MAAI,OAAO;AACT,UAAM,CAAC,EAAE,QAAQ,IAAI,IAAI;AACzB,WAAO,KAAK,IAAI,IAAI,SAAS,MAAO,KAAK,eAAe,IAAK,KAAK;AAAA,EACpE;AAEA,QAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,MAAI,OAAO,MAAM,MAAM,GAAG;AACxB,UAAM,IAAI;AAAA,MACR,kBAAkB,KAAK;AAAA,IACzB;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -0,0 +1,11 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,22 @@
1
+ import {
2
+ createPrompt
3
+ } from "./chunk-HOPTUDCZ.js";
4
+ import "./chunk-AAQNA53E.js";
5
+
6
+ // src/tools/create-prompt.ts
7
+ async function handleCreatePrompt(params) {
8
+ const result = await createPrompt(params);
9
+ const lines = [];
10
+ lines.push("Prompt created successfully!\n");
11
+ if (result.id) lines.push(`**ID**: ${result.id}`);
12
+ if (result.handle) lines.push(`**Handle**: ${result.handle}`);
13
+ lines.push(`**Name**: ${result.name || params.name}`);
14
+ lines.push(`**Model**: ${params.model} (${params.modelProvider})`);
15
+ if (result.latestVersionNumber != null)
16
+ lines.push(`**Version**: v${result.latestVersionNumber}`);
17
+ return lines.join("\n");
18
+ }
19
+ export {
20
+ handleCreatePrompt
21
+ };
22
+ //# sourceMappingURL=create-prompt-UBC537BJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/create-prompt.ts"],"sourcesContent":["import { createPrompt as apiCreatePrompt } from \"../langwatch-api.js\";\n\n/**\n * Handles the 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 modelProvider: string;\n description?: string;\n}): Promise<string> {\n const result = await apiCreatePrompt(params);\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} (${params.modelProvider})`);\n if (result.latestVersionNumber != null)\n lines.push(`**Version**: v${result.latestVersionNumber}`);\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAQA,eAAsB,mBAAmB,QAOrB;AAClB,QAAM,SAAS,MAAM,aAAgB,MAAM;AAE3C,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,KAAK,OAAO,aAAa,GAAG;AACjE,MAAI,OAAO,uBAAuB;AAChC,UAAM,KAAK,iBAAiB,OAAO,mBAAmB,EAAE;AAE1D,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}