@tailormade/seq-mcp 1.1.1
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.
- package/README.md +121 -0
- package/dist/api/client.d.ts +63 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +176 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/formatter.d.ts +4 -0
- package/dist/api/formatter.d.ts.map +1 -0
- package/dist/api/formatter.js +214 -0
- package/dist/api/formatter.js.map +1 -0
- package/dist/api/history.d.ts +26 -0
- package/dist/api/history.d.ts.map +1 -0
- package/dist/api/history.js +122 -0
- package/dist/api/history.js.map +1 -0
- package/dist/api/prefs.d.ts +12 -0
- package/dist/api/prefs.d.ts.map +1 -0
- package/dist/api/prefs.js +59 -0
- package/dist/api/prefs.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/history.d.ts +3 -0
- package/dist/tools/history.d.ts.map +1 -0
- package/dist/tools/history.js +78 -0
- package/dist/tools/history.js.map +1 -0
- package/dist/tools/live.d.ts +4 -0
- package/dist/tools/live.d.ts.map +1 -0
- package/dist/tools/live.js +26 -0
- package/dist/tools/live.js.map +1 -0
- package/dist/tools/prefs.d.ts +3 -0
- package/dist/tools/prefs.d.ts.map +1 -0
- package/dist/tools/prefs.js +34 -0
- package/dist/tools/prefs.js.map +1 -0
- package/dist/tools/query.d.ts +4 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +220 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/tools/recent.d.ts +4 -0
- package/dist/tools/recent.d.ts.map +1 -0
- package/dist/tools/recent.js +31 -0
- package/dist/tools/recent.js.map +1 -0
- package/dist/tools/search.d.ts +4 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +42 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/signals.d.ts +4 -0
- package/dist/tools/signals.d.ts.map +1 -0
- package/dist/tools/signals.js +19 -0
- package/dist/tools/signals.js.map +1 -0
- package/dist/tools/stream.d.ts +4 -0
- package/dist/tools/stream.d.ts.map +1 -0
- package/dist/tools/stream.js +36 -0
- package/dist/tools/stream.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerQueryTools = registerQueryTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
function respond(text) {
|
|
6
|
+
return { content: [{ type: "text", text }] };
|
|
7
|
+
}
|
|
8
|
+
function formatQueryResult(result) {
|
|
9
|
+
if (result.Error) {
|
|
10
|
+
let msg = `Error: ${result.Error}`;
|
|
11
|
+
if (result.Suggestion)
|
|
12
|
+
msg += `\nSuggestion: ${result.Suggestion}`;
|
|
13
|
+
return msg;
|
|
14
|
+
}
|
|
15
|
+
if (!result.Columns || !result.Rows || result.Rows.length === 0)
|
|
16
|
+
return "No results.";
|
|
17
|
+
const cols = result.Columns;
|
|
18
|
+
const rows = result.Rows;
|
|
19
|
+
// Calculate column widths
|
|
20
|
+
const widths = cols.map((c, i) => Math.max(c.length, ...rows.map((r) => String(r[i] ?? "").length)));
|
|
21
|
+
// Cap widths at 40
|
|
22
|
+
const capped = widths.map((w) => Math.min(w, 40));
|
|
23
|
+
const hdr = cols.map((c, i) => c.padEnd(capped[i])).join(" | ");
|
|
24
|
+
const sep = capped.map((w) => "-".repeat(w)).join("-|-");
|
|
25
|
+
const body = rows.map((r) => cols.map((_, i) => {
|
|
26
|
+
const val = String(r[i] ?? "");
|
|
27
|
+
return val.length > capped[i] ? val.slice(0, capped[i] - 3) + "..." : val.padEnd(capped[i]);
|
|
28
|
+
}).join(" | "));
|
|
29
|
+
return [`${rows.length} rows`, "", hdr, sep, ...body].join("\n");
|
|
30
|
+
}
|
|
31
|
+
const QUERY_HELP = `# Seq Query Reference
|
|
32
|
+
|
|
33
|
+
## Filter Syntax (seq_search, seq_recent, seq_stream, seq_fields)
|
|
34
|
+
|
|
35
|
+
### Comparison operators
|
|
36
|
+
= <> < <= > >=
|
|
37
|
+
Application = 'MyApp'
|
|
38
|
+
@Level <> 'Warning'
|
|
39
|
+
@Elapsed > 500
|
|
40
|
+
|
|
41
|
+
### Case-insensitive matching — ci postfix modifier
|
|
42
|
+
Application = 'myapp' ci -- matches 'MyApp', 'MYAPP', etc.
|
|
43
|
+
@Message like '%error%' ci
|
|
44
|
+
|
|
45
|
+
### Pattern matching — like / not like
|
|
46
|
+
@Message like '%keyword%' -- % = any chars, _ = one char
|
|
47
|
+
@Message like '%timeout%' and @Level = 'Error'
|
|
48
|
+
@Message not like '%healthcheck%'
|
|
49
|
+
|
|
50
|
+
### Regular expressions
|
|
51
|
+
Source = /(Microsoft|System).*Internal/
|
|
52
|
+
|
|
53
|
+
### IN operator
|
|
54
|
+
@Level in ['Warning', 'Error']
|
|
55
|
+
Application in ['Web', 'API']
|
|
56
|
+
|
|
57
|
+
### Null / property existence
|
|
58
|
+
Has(RequestPath) -- property exists
|
|
59
|
+
RequestPath is not null
|
|
60
|
+
RequestPath is null
|
|
61
|
+
|
|
62
|
+
### Collection indexers
|
|
63
|
+
Tags[?] like 'seq%' -- [?] = any element matches
|
|
64
|
+
Tags[*] = 'required' -- [*] = all elements match
|
|
65
|
+
|
|
66
|
+
### Dot notation for nested properties
|
|
67
|
+
Cart.Total > 100
|
|
68
|
+
|
|
69
|
+
### Logical operators
|
|
70
|
+
System = 'X' and @Level = 'Error'
|
|
71
|
+
System = 'X' or System = 'Y'
|
|
72
|
+
not @Level = 'Information'
|
|
73
|
+
|
|
74
|
+
### String functions (scalar)
|
|
75
|
+
StartsWith(RequestPath, '/api')
|
|
76
|
+
EndsWith(RequestPath, '.jpg')
|
|
77
|
+
Contains(@Message, 'timeout')
|
|
78
|
+
Substring(@Message, 0, 50)
|
|
79
|
+
ToUpper(Application) ToLower(Application)
|
|
80
|
+
Length(@Message) > 200
|
|
81
|
+
|
|
82
|
+
### Date/time
|
|
83
|
+
@Timestamp > DateTime('2026-03-18T00:00:00Z')
|
|
84
|
+
@Timestamp > now() - 1d -- relative: 30d, 1h, 60s, 500ms
|
|
85
|
+
|
|
86
|
+
### Built-in event properties
|
|
87
|
+
@Timestamp @Message @MessageTemplate @Level
|
|
88
|
+
@Exception @EventType @Properties @Id
|
|
89
|
+
@TraceId @SpanId @ParentId
|
|
90
|
+
|
|
91
|
+
### Conditional
|
|
92
|
+
if @Level = 'Error' then 1 else 0
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## SQL Syntax (seq_query)
|
|
97
|
+
|
|
98
|
+
CRITICAL: use 'from stream' — NOT 'from events'
|
|
99
|
+
WARNING: always set rangeStartUtc — without it the query scans all time and will timeout
|
|
100
|
+
|
|
101
|
+
### Structure
|
|
102
|
+
select <expressions>
|
|
103
|
+
from stream
|
|
104
|
+
[where <filter>]
|
|
105
|
+
[group by <dimensions>]
|
|
106
|
+
[having <aggregate_filter>]
|
|
107
|
+
[order by <col> asc|desc]
|
|
108
|
+
[limit <n>]
|
|
109
|
+
|
|
110
|
+
### Count / group
|
|
111
|
+
select count(*) from stream limit 50
|
|
112
|
+
select count(*) from stream group by System limit 50
|
|
113
|
+
select count(*) from stream group by System, @Level limit 50
|
|
114
|
+
select count(*) from stream where @Level = 'Error' group by System
|
|
115
|
+
|
|
116
|
+
### Aggregations
|
|
117
|
+
select mean(Elapsed) from stream group by RequestPath
|
|
118
|
+
select percentile(Elapsed, 95) from stream group by System
|
|
119
|
+
select min(Elapsed), max(Elapsed), mean(Elapsed) from stream group by System
|
|
120
|
+
select sum(Elapsed) from stream where System = 'X' group by RequestPath
|
|
121
|
+
|
|
122
|
+
### Distinct
|
|
123
|
+
select distinct(System) from stream limit 50
|
|
124
|
+
select count(distinct(UserId)) from stream group by System
|
|
125
|
+
|
|
126
|
+
### Time grouping
|
|
127
|
+
select count(*) from stream group by time(1h)
|
|
128
|
+
select count(*) from stream group by time(5m)
|
|
129
|
+
select mean(Elapsed) from stream where System = 'X' group by time(1h)
|
|
130
|
+
|
|
131
|
+
### First / last value
|
|
132
|
+
select first(RequestPath) from stream group by @EventType limit 20
|
|
133
|
+
|
|
134
|
+
### Strings: always single-quoted
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Signals
|
|
139
|
+
|
|
140
|
+
Signal IDs are instance-specific — always call seq_signals first to find the right IDs.
|
|
141
|
+
Signals filter events server-side (faster than filter expressions for large volumes).
|
|
142
|
+
Combine multiple signals with comma: signal-AAA,signal-BBB
|
|
143
|
+
|
|
144
|
+
WARNING: do NOT add @Level = 'Error' when using error signals — signals already include Fatal.
|
|
145
|
+
Adding the level filter excludes Fatal events.
|
|
146
|
+
WARNING: @Level = 'Error' alone can return 0 results on some systems — prefer an error signal.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Recommended Workflow
|
|
151
|
+
|
|
152
|
+
1. seq_history — check if system/properties already cached
|
|
153
|
+
2. seq_signals — discover available signals (errors, environments, etc.)
|
|
154
|
+
3. seq_fields — discover available properties for a system
|
|
155
|
+
4. seq_search — search with filter + optional signal
|
|
156
|
+
5. seq_query — aggregate/count queries
|
|
157
|
+
`;
|
|
158
|
+
function registerQueryTools(server, client) {
|
|
159
|
+
server.tool("seq_query_help", "Returns inline reference documentation for Seq filter syntax, SQL syntax, signals, and recommended workflow. Use this before building a filter or query on an unfamiliar system.", {}, async () => respond(QUERY_HELP));
|
|
160
|
+
server.tool("seq_query", "Execute a SQL query against Seq event data. Returns tabular results. Supports SELECT, COUNT, DISTINCT, GROUP BY, ORDER BY, LIMIT.\n\nllmTip: CRITICAL: use `from stream` not `from events` — wrong table name returns empty results. NOTE: strings are single-quoted. WARNING: always set rangeStartUtc — without it the query scans all time and will timeout on large datasets. EXAMPLE: `select count(*) from stream group by System limit 50` | `select count(*) from stream where System = 'MyApp' group by RequestPath` | `select count(*) from stream where @Level = 'Error' group by System`.", {
|
|
161
|
+
q: zod_1.z.string().describe("SQL query. Must use 'from stream'. Example: select distinct(System) from stream limit 50"),
|
|
162
|
+
rangeStartUtc: zod_1.z.string().optional().describe("Start of time range, ISO8601. Default: last 24h"),
|
|
163
|
+
rangeEndUtc: zod_1.z.string().optional().describe("End of time range, ISO8601"),
|
|
164
|
+
signal: zod_1.z.string().optional().describe("Signal ID to scope the query. Use seq_signals to discover available IDs."),
|
|
165
|
+
timeout: zod_1.z.coerce.number().optional().describe("Query timeout in ms (default 30000)"),
|
|
166
|
+
format: zod_1.z.enum(["table", "raw"]).optional().describe("Output format: table (default) or raw JSON"),
|
|
167
|
+
}, async (params) => {
|
|
168
|
+
const result = await client.query({
|
|
169
|
+
q: params.q,
|
|
170
|
+
rangeStartUtc: params.rangeStartUtc,
|
|
171
|
+
rangeEndUtc: params.rangeEndUtc,
|
|
172
|
+
signal: params.signal,
|
|
173
|
+
timeout: params.timeout ?? 30000,
|
|
174
|
+
});
|
|
175
|
+
if (params.format === "raw")
|
|
176
|
+
return respond(JSON.stringify(result, null, 2));
|
|
177
|
+
return respond(formatQueryResult(result));
|
|
178
|
+
});
|
|
179
|
+
server.tool("seq_expression_indexes", "List expression indexes configured in Seq. These define which fields have dedicated indexes for fast querying.\n\nllmTip: NOTE: only indexed fields (@EventType, @TraceId) benefit from fast lookups. For field discovery, use seq_query with `group by` or seq_fields instead.", {
|
|
180
|
+
format: zod_1.z.enum(["table", "raw"]).optional().describe("Output format: table (default) or raw JSON"),
|
|
181
|
+
}, async (params) => {
|
|
182
|
+
const exprIndexes = await client.listExpressionIndexes();
|
|
183
|
+
if (params.format === "raw")
|
|
184
|
+
return respond(JSON.stringify(exprIndexes, null, 2));
|
|
185
|
+
if (exprIndexes.length === 0)
|
|
186
|
+
return respond("No expression indexes configured.");
|
|
187
|
+
const w = Math.max(10, ...exprIndexes.map((i) => i.Expression.length));
|
|
188
|
+
const lines = [
|
|
189
|
+
`${exprIndexes.length} expression indexes`, "",
|
|
190
|
+
["Expression".padEnd(w), "Description"].join(" | "),
|
|
191
|
+
["-".repeat(w), "-".repeat(11)].join("-|-"),
|
|
192
|
+
...exprIndexes.map((i) => [i.Expression.padEnd(w), i.Description ?? ""].join(" | ")),
|
|
193
|
+
];
|
|
194
|
+
return respond(lines.join("\n"));
|
|
195
|
+
});
|
|
196
|
+
server.tool("seq_fields", "Discover which properties/fields a system (or filter) logs by sampling recent events. Shows field names and sample values. Cached 10 min.\n\nllmTip: NOTE: fields vary per system, environment, and event type — increase sampleSize for better coverage. NOTE: also check seq_history for already-discovered properties before calling this. EXAMPLE: follow up with seq_query: `select count(*) from stream where System = 'X' group by FieldName` for exact value counts.", {
|
|
197
|
+
filter: zod_1.z.string().describe("Seq filter expression, e.g. System = 'MyApp' or System = 'MyApp' and @Level = 'Error'"),
|
|
198
|
+
sampleSize: zod_1.z.coerce.number().optional().describe("Number of events to sample (default 20, max 100). More = better coverage but slower."),
|
|
199
|
+
}, async (params) => {
|
|
200
|
+
const size = Math.min(params.sampleSize ?? 20, 100);
|
|
201
|
+
const { fields, sampleCount } = await client.discoverFields(params.filter, size);
|
|
202
|
+
const entries = Object.entries(fields).sort((a, b) => b[1].size - a[1].size);
|
|
203
|
+
if (entries.length === 0)
|
|
204
|
+
return respond("No fields found (no events matched the filter).");
|
|
205
|
+
const lines = [
|
|
206
|
+
`${entries.length} fields found (sampled ${sampleCount} events)`,
|
|
207
|
+
"",
|
|
208
|
+
];
|
|
209
|
+
for (const [field, values] of entries) {
|
|
210
|
+
const vals = [...values];
|
|
211
|
+
const preview = vals.slice(0, 5).join(", ");
|
|
212
|
+
const more = vals.length > 5 ? ` (+${vals.length - 5} more)` : "";
|
|
213
|
+
lines.push(`${field} (${vals.length} unique):`);
|
|
214
|
+
lines.push(` ${preview}${more}`);
|
|
215
|
+
lines.push("");
|
|
216
|
+
}
|
|
217
|
+
return respond(lines.join("\n").trimEnd());
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/tools/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recent.d.ts","sourceRoot":"","sources":["../../src/tools/recent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAS7C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAwB9E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerRecentTools = registerRecentTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const formatter_js_1 = require("../api/formatter.js");
|
|
6
|
+
const prefs_js_1 = require("../api/prefs.js");
|
|
7
|
+
const history_js_1 = require("../api/history.js");
|
|
8
|
+
function respond(text) {
|
|
9
|
+
return { content: [{ type: "text", text }] };
|
|
10
|
+
}
|
|
11
|
+
function registerRecentTools(server, client) {
|
|
12
|
+
server.tool("seq_recent", "Fetch the most recent events from Seq. Use afterId to poll for new events since a previous call. For continuous monitoring, use seq_stream instead.\n\nllmTip: NOTE: polling pattern — first call without afterId, then pass the newest event Id as afterId in subsequent calls. EXAMPLE: text search: `@Message like '%keyword%'` | structured: `@Level = 'Error'` | combined: `System = 'X' and @Level = 'Error'`.", {
|
|
13
|
+
filter: zod_1.z.string().optional().describe("Seq filter expression. For text search: @Message like '%keyword%'. For structured: @Level = 'Error'. Combine with and/or."),
|
|
14
|
+
signal: zod_1.z.string().optional().describe("Signal ID to filter by. Use seq_signals to discover available IDs."),
|
|
15
|
+
count: zod_1.z.coerce.number().optional().describe("Max events to return (default 10)"),
|
|
16
|
+
afterId: zod_1.z.string().optional().describe("Only return events newer than this event ID. Use for polling: pass the Id of the last event from your previous call."),
|
|
17
|
+
format: zod_1.z.enum(["compact", "table", "detail", "raw"]).optional()
|
|
18
|
+
.describe("Output format: compact (default), table, detail, or raw (full JSON)"),
|
|
19
|
+
}, async (params) => {
|
|
20
|
+
const events = await client.recent({
|
|
21
|
+
filter: params.filter,
|
|
22
|
+
signal: params.signal,
|
|
23
|
+
count: params.count ?? 10,
|
|
24
|
+
afterId: params.afterId,
|
|
25
|
+
});
|
|
26
|
+
(0, history_js_1.recordQuery)({ filter: params.filter }, events);
|
|
27
|
+
const mode = params.format ?? (0, prefs_js_1.loadPrefs)().defaultFormat;
|
|
28
|
+
return respond((0, formatter_js_1.formatEvents)(events, mode));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=recent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recent.js","sourceRoot":"","sources":["../../src/tools/recent.ts"],"names":[],"mappings":";;AAWA,kDAwBC;AAlCD,6BAAwB;AAExB,sDAA+D;AAC/D,8CAA4C;AAC5C,kDAAgD;AAEhD,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,SAAgB,mBAAmB,CAAC,MAAiB,EAAE,MAAiB;IACtE,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,sZAAsZ,EACtZ;QACE,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2HAA2H,CAAC;QACnK,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;QAC5G,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACjF,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sHAAsH,CAAC;QAC/J,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;aAC7D,QAAQ,CAAC,qEAAqE,CAAC;KACnF,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;YACjC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;QACH,IAAA,wBAAW,EAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAe,MAAM,CAAC,MAAM,IAAI,IAAA,oBAAS,GAAE,CAAC,aAAa,CAAC;QACpE,OAAO,OAAO,CAAC,IAAA,2BAAY,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAY7C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAuC9E"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSearchTools = registerSearchTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const formatter_js_1 = require("../api/formatter.js");
|
|
6
|
+
const prefs_js_1 = require("../api/prefs.js");
|
|
7
|
+
const history_js_1 = require("../api/history.js");
|
|
8
|
+
function respond(text) {
|
|
9
|
+
return { content: [{ type: "text", text }] };
|
|
10
|
+
}
|
|
11
|
+
const formatParam = zod_1.z.enum(["compact", "table", "detail", "raw"]).optional()
|
|
12
|
+
.describe("Output format: compact (default), table, detail, or raw (full JSON)");
|
|
13
|
+
function registerSearchTools(server, client) {
|
|
14
|
+
server.tool("seq_search", "Search Seq events by filter, signal, and/or date range. Returns newest first. Next steps: seq_get_event for full details, seq_signals to discover signals, seq_query for aggregations, seq_history for known systems/properties.\n\nllmTip: NOTE: before building a filter, call seq_signals to discover available signals (e.g. error signals, environment signals) and seq_history for known systems/properties — avoids blind trial-and-error. EXAMPLE: text search: `@Message like '%keyword%'` | structured: `Environment = 'Production'` | combine: `System = 'X' and @Level = 'Error'`. Date params are ISO8601 UTC. WARNING: always set startedAt — without it Seq scans all time and is slow. WARNING: do NOT add `@Level = 'Error'` filter when using error signals — signals already filter on level; adding it excludes Fatal events. WARNING: `@Level = 'Error'` alone can be unreliable on some systems — prefer an error signal (use seq_signals to find the right one). NOTE: combine multiple signals with comma: `signal-AAA,signal-BBB`.", {
|
|
15
|
+
filter: zod_1.z.string().optional().describe("Seq filter expression. For text search: @Message like '%keyword%'. For structured: Environment = 'Production', @Level = 'Error'. Combine with and/or."),
|
|
16
|
+
signal: zod_1.z.string().optional().describe("Signal ID to filter by. Use seq_signals to discover available IDs."),
|
|
17
|
+
count: zod_1.z.coerce.number().optional().describe("Max events to return (default 20, max 200)"),
|
|
18
|
+
startedAt: zod_1.z.string().optional().describe("Only events after this timestamp. ISO8601 format, e.g. 2026-03-18T00:00:00Z"),
|
|
19
|
+
endedAt: zod_1.z.string().optional().describe("Only events before this timestamp. ISO8601 format, e.g. 2026-03-19T00:00:00Z"),
|
|
20
|
+
format: formatParam,
|
|
21
|
+
}, async (params) => {
|
|
22
|
+
const events = await client.search({
|
|
23
|
+
filter: params.filter,
|
|
24
|
+
signal: params.signal,
|
|
25
|
+
count: Math.min(params.count ?? 20, 200),
|
|
26
|
+
startedAt: params.startedAt,
|
|
27
|
+
endedAt: params.endedAt,
|
|
28
|
+
});
|
|
29
|
+
(0, history_js_1.recordQuery)({ filter: params.filter, startedAt: params.startedAt, endedAt: params.endedAt }, events);
|
|
30
|
+
const mode = params.format ?? (0, prefs_js_1.loadPrefs)().defaultFormat;
|
|
31
|
+
return respond((0, formatter_js_1.formatEvents)(events, mode));
|
|
32
|
+
});
|
|
33
|
+
server.tool("seq_get_event", "Get a single Seq event by ID with full rendered message and all properties (detail format). Use after seq_search, seq_recent, or seq_stream to inspect a specific event.\n\nllmTip: Event IDs look like 'event-34070bec858e08de73ab2ef100000000'. You get these from the Id field in search/recent/stream results.", {
|
|
34
|
+
eventId: zod_1.z.string().describe("The full event ID, e.g. event-34070bec858e08de73ab2ef100000000"),
|
|
35
|
+
format: formatParam,
|
|
36
|
+
}, async (params) => {
|
|
37
|
+
const event = await client.getEvent(params.eventId);
|
|
38
|
+
const mode = params.format ?? "detail";
|
|
39
|
+
return respond((0, formatter_js_1.formatEvents)([event], mode));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":";;AAcA,kDAuCC;AApDD,6BAAwB;AAExB,sDAA+D;AAC/D,8CAA4C;AAC5C,kDAAgD;AAEhD,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,WAAW,GAAG,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;KACzE,QAAQ,CAAC,qEAAqE,CAAC,CAAC;AAEnF,SAAgB,mBAAmB,CAAC,MAAiB,EAAE,MAAiB;IACtE,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,6/BAA6/B,EAC7/B;QACE,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uJAAuJ,CAAC;QAC/L,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;QAC5G,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;QAC1F,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6EAA6E,CAAC;QACxH,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8EAA8E,CAAC;QACvH,MAAM,EAAE,WAAW;KACpB,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;YACjC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC;YACxC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;QACH,IAAA,wBAAW,EAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;QACrG,MAAM,IAAI,GAAe,MAAM,CAAC,MAAM,IAAI,IAAA,oBAAS,GAAE,CAAC,aAAa,CAAC;QACpE,OAAO,OAAO,CAAC,IAAA,2BAAY,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,oTAAoT,EACpT;QACE,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gEAAgE,CAAC;QAC9F,MAAM,EAAE,WAAW;KACpB,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,IAAI,GAAe,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC;QACnD,OAAO,OAAO,CAAC,IAAA,2BAAY,EAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/tools/signals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAO7C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAc9E"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSignalTools = registerSignalTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const formatter_js_1 = require("../api/formatter.js");
|
|
6
|
+
function respond(text) {
|
|
7
|
+
return { content: [{ type: "text", text }] };
|
|
8
|
+
}
|
|
9
|
+
function registerSignalTools(server, client) {
|
|
10
|
+
server.tool("seq_signals", "List all available Seq signals (cached 10 min). Signals are saved filters/groups like 'Production', 'Errors', 'Warnings'. Use the returned signal ID in seq_search, seq_recent, seq_stream, or seq_query.\n\nllmTip: NOTE: call this before filtering — signal IDs are required and look like 'signal-NNN'. NOTE: signals can be combined with filter expressions and with each other (comma-separated).", {
|
|
11
|
+
format: zod_1.z.enum(["compact", "table", "detail", "raw"]).optional()
|
|
12
|
+
.describe("Output format: table (default), detail, or raw (full JSON)"),
|
|
13
|
+
}, async (params) => {
|
|
14
|
+
const signals = await client.listSignals();
|
|
15
|
+
const mode = params.format ?? "table";
|
|
16
|
+
return respond((0, formatter_js_1.formatSignals)(signals, mode));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=signals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/tools/signals.ts"],"names":[],"mappings":";;AASA,kDAcC;AAtBD,6BAAwB;AAExB,sDAAgE;AAEhE,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,SAAgB,mBAAmB,CAAC,MAAiB,EAAE,MAAiB;IACtE,MAAM,CAAC,IAAI,CACT,aAAa,EACb,0YAA0Y,EAC1Y;QACE,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;aAC7D,QAAQ,CAAC,4DAA4D,CAAC;KAC1E,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAe,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC;QAClD,OAAO,OAAO,CAAC,IAAA,4BAAa,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/tools/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAS7C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA4B9E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerStreamTools = registerStreamTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const formatter_js_1 = require("../api/formatter.js");
|
|
6
|
+
const prefs_js_1 = require("../api/prefs.js");
|
|
7
|
+
const history_js_1 = require("../api/history.js");
|
|
8
|
+
function respond(text) {
|
|
9
|
+
return { content: [{ type: "text", text }] };
|
|
10
|
+
}
|
|
11
|
+
function registerStreamTools(server, client) {
|
|
12
|
+
server.tool("seq_stream", "Wait for new events from Seq using long-polling. Blocks up to `wait` ms for new events. Ideal for real-time monitoring.\n\nllmTip: Pass afterId from a previous seq_recent or seq_stream call to only get NEW events. Without afterId, returns most recent events. Default wait 5000ms, max 10000ms. Use `filter` for text search (`@Message like '%keyword%'`) or structured filters (`@Level = 'Error'`).\n\nWARNING: afterId on /api/events/scan scans BACKWARDS from that event ID, not forward. Do not use afterId in seq_stream for forward polling — use seq_recent instead.", {
|
|
13
|
+
filter: zod_1.z.string().optional().describe("Seq filter expression. For text search: @Message like '%keyword%'. For structured: @Level = 'Error'. Combine with and/or."),
|
|
14
|
+
signal: zod_1.z.string().optional().describe("Signal ID to filter by. Use seq_signals to discover available IDs."),
|
|
15
|
+
count: zod_1.z.coerce.number().optional().describe("Max events to return (default 10)"),
|
|
16
|
+
afterId: zod_1.z.string().optional().describe("Only return events newer than this event ID. Pass the Id of the last event from your previous call."),
|
|
17
|
+
wait: zod_1.z.coerce.number().optional().describe("Max milliseconds to wait for new events (default 5000, max 10000)"),
|
|
18
|
+
format: zod_1.z.enum(["compact", "table", "detail", "raw"]).optional()
|
|
19
|
+
.describe("Output format: compact (default), table, detail, or raw (full JSON)"),
|
|
20
|
+
}, async (params) => {
|
|
21
|
+
const wait = Math.min(params.wait ?? 5000, 10000);
|
|
22
|
+
const events = await client.scan({
|
|
23
|
+
filter: params.filter,
|
|
24
|
+
signal: params.signal,
|
|
25
|
+
count: params.count ?? 10,
|
|
26
|
+
afterId: params.afterId,
|
|
27
|
+
wait,
|
|
28
|
+
});
|
|
29
|
+
if (events.length === 0)
|
|
30
|
+
return respond("No new events within the wait period.");
|
|
31
|
+
(0, history_js_1.recordQuery)({ filter: params.filter }, events);
|
|
32
|
+
const mode = params.format ?? (0, prefs_js_1.loadPrefs)().defaultFormat;
|
|
33
|
+
return respond((0, formatter_js_1.formatEvents)(events, mode));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/tools/stream.ts"],"names":[],"mappings":";;AAWA,kDA4BC;AAtCD,6BAAwB;AAExB,sDAA+D;AAC/D,8CAA4C;AAC5C,kDAAgD;AAEhD,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,SAAgB,mBAAmB,CAAC,MAAiB,EAAE,MAAiB;IACtE,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,qjBAAqjB,EACrjB;QACE,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2HAA2H,CAAC;QACnK,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;QAC5G,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QACjF,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qGAAqG,CAAC;QAC9I,IAAI,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mEAAmE,CAAC;QAChH,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;aAC7D,QAAQ,CAAC,qEAAqE,CAAC;KACnF,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI;SACL,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACjF,IAAA,wBAAW,EAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAe,MAAM,CAAC,MAAM,IAAI,IAAA,oBAAS,GAAE,CAAC,aAAa,CAAC;QACpE,OAAO,OAAO,CAAC,IAAA,2BAAY,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tailormade/seq-mcp",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "MCP server for Seq structured logging — search, signals, live events.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"seq-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"dev": "tsx src/index.ts",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"lint": "eslint src/ && tsc --noEmit",
|
|
17
|
+
"prepare": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"seq",
|
|
22
|
+
"logging",
|
|
23
|
+
"model-context-protocol",
|
|
24
|
+
"ai",
|
|
25
|
+
"claude",
|
|
26
|
+
"tailormade"
|
|
27
|
+
],
|
|
28
|
+
"author": "Tailormade",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=20.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@modelcontextprotocol/sdk": "^1.5.0",
|
|
35
|
+
"zod": "^4.3.6"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@eslint/js": "^10.0.1",
|
|
39
|
+
"@types/node": "^22.0.0",
|
|
40
|
+
"tsx": "^4.19.0",
|
|
41
|
+
"typescript": "^5.7.0",
|
|
42
|
+
"typescript-eslint": "^8.57.1"
|
|
43
|
+
}
|
|
44
|
+
}
|