@graphty/remote-logger 0.0.1 → 1.2.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 (138) hide show
  1. package/README.md +944 -28
  2. package/bin/remote-log-server.js +3 -0
  3. package/dist/client/RemoteLogClient.d.ts +116 -0
  4. package/dist/client/RemoteLogClient.d.ts.map +1 -0
  5. package/dist/client/RemoteLogClient.js +269 -0
  6. package/dist/client/RemoteLogClient.js.map +1 -0
  7. package/dist/client/index.d.ts +7 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +6 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/client/types.d.ts +60 -0
  12. package/dist/client/types.d.ts.map +1 -0
  13. package/dist/client/types.js +6 -0
  14. package/dist/client/types.js.map +1 -0
  15. package/dist/index.d.ts +22 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +23 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/mcp/index.d.ts +9 -0
  20. package/dist/mcp/index.d.ts.map +1 -0
  21. package/dist/mcp/index.js +9 -0
  22. package/dist/mcp/index.js.map +1 -0
  23. package/dist/mcp/mcp-server.d.ts +32 -0
  24. package/dist/mcp/mcp-server.d.ts.map +1 -0
  25. package/dist/mcp/mcp-server.js +270 -0
  26. package/dist/mcp/mcp-server.js.map +1 -0
  27. package/dist/mcp/tools/index.d.ts +14 -0
  28. package/dist/mcp/tools/index.d.ts.map +1 -0
  29. package/dist/mcp/tools/index.js +14 -0
  30. package/dist/mcp/tools/index.js.map +1 -0
  31. package/dist/mcp/tools/logs-clear.d.ts +76 -0
  32. package/dist/mcp/tools/logs-clear.d.ts.map +1 -0
  33. package/dist/mcp/tools/logs-clear.js +58 -0
  34. package/dist/mcp/tools/logs-clear.js.map +1 -0
  35. package/dist/mcp/tools/logs-get-all.d.ts +60 -0
  36. package/dist/mcp/tools/logs-get-all.d.ts.map +1 -0
  37. package/dist/mcp/tools/logs-get-all.js +50 -0
  38. package/dist/mcp/tools/logs-get-all.js.map +1 -0
  39. package/dist/mcp/tools/logs-get-errors.d.ts +65 -0
  40. package/dist/mcp/tools/logs-get-errors.d.ts.map +1 -0
  41. package/dist/mcp/tools/logs-get-errors.js +46 -0
  42. package/dist/mcp/tools/logs-get-errors.js.map +1 -0
  43. package/dist/mcp/tools/logs-get-file-path.d.ts +75 -0
  44. package/dist/mcp/tools/logs-get-file-path.d.ts.map +1 -0
  45. package/dist/mcp/tools/logs-get-file-path.js +90 -0
  46. package/dist/mcp/tools/logs-get-file-path.js.map +1 -0
  47. package/dist/mcp/tools/logs-get-recent.d.ts +89 -0
  48. package/dist/mcp/tools/logs-get-recent.d.ts.map +1 -0
  49. package/dist/mcp/tools/logs-get-recent.js +74 -0
  50. package/dist/mcp/tools/logs-get-recent.js.map +1 -0
  51. package/dist/mcp/tools/logs-list-sessions.d.ts +64 -0
  52. package/dist/mcp/tools/logs-list-sessions.d.ts.map +1 -0
  53. package/dist/mcp/tools/logs-list-sessions.js +48 -0
  54. package/dist/mcp/tools/logs-list-sessions.js.map +1 -0
  55. package/dist/mcp/tools/logs-receive.d.ts +150 -0
  56. package/dist/mcp/tools/logs-receive.d.ts.map +1 -0
  57. package/dist/mcp/tools/logs-receive.js +68 -0
  58. package/dist/mcp/tools/logs-receive.js.map +1 -0
  59. package/dist/mcp/tools/logs-search.d.ts +91 -0
  60. package/dist/mcp/tools/logs-search.d.ts.map +1 -0
  61. package/dist/mcp/tools/logs-search.js +68 -0
  62. package/dist/mcp/tools/logs-search.js.map +1 -0
  63. package/dist/mcp/tools/logs-status.d.ts +45 -0
  64. package/dist/mcp/tools/logs-status.d.ts.map +1 -0
  65. package/dist/mcp/tools/logs-status.js +45 -0
  66. package/dist/mcp/tools/logs-status.js.map +1 -0
  67. package/dist/server/dual-server.d.ts +76 -0
  68. package/dist/server/dual-server.d.ts.map +1 -0
  69. package/dist/server/dual-server.js +214 -0
  70. package/dist/server/dual-server.js.map +1 -0
  71. package/dist/server/index.d.ts +12 -0
  72. package/dist/server/index.d.ts.map +1 -0
  73. package/dist/server/index.js +12 -0
  74. package/dist/server/index.js.map +1 -0
  75. package/dist/server/jsonl-writer.d.ts +93 -0
  76. package/dist/server/jsonl-writer.d.ts.map +1 -0
  77. package/dist/server/jsonl-writer.js +205 -0
  78. package/dist/server/jsonl-writer.js.map +1 -0
  79. package/dist/server/log-server.d.ts +126 -0
  80. package/dist/server/log-server.d.ts.map +1 -0
  81. package/dist/server/log-server.js +589 -0
  82. package/dist/server/log-server.js.map +1 -0
  83. package/dist/server/log-storage.d.ts +301 -0
  84. package/dist/server/log-storage.d.ts.map +1 -0
  85. package/dist/server/log-storage.js +408 -0
  86. package/dist/server/log-storage.js.map +1 -0
  87. package/dist/server/marker-utils.d.ts +69 -0
  88. package/dist/server/marker-utils.d.ts.map +1 -0
  89. package/dist/server/marker-utils.js +118 -0
  90. package/dist/server/marker-utils.js.map +1 -0
  91. package/dist/server/self-signed-cert.d.ts +30 -0
  92. package/dist/server/self-signed-cert.d.ts.map +1 -0
  93. package/dist/server/self-signed-cert.js +83 -0
  94. package/dist/server/self-signed-cert.js.map +1 -0
  95. package/dist/ui/ConsoleCaptureUI.d.ts +118 -0
  96. package/dist/ui/ConsoleCaptureUI.d.ts.map +1 -0
  97. package/dist/ui/ConsoleCaptureUI.js +571 -0
  98. package/dist/ui/ConsoleCaptureUI.js.map +1 -0
  99. package/dist/ui/index.d.ts +15 -0
  100. package/dist/ui/index.d.ts.map +1 -0
  101. package/dist/ui/index.js +15 -0
  102. package/dist/ui/index.js.map +1 -0
  103. package/dist/vite/index.d.ts +8 -0
  104. package/dist/vite/index.d.ts.map +1 -0
  105. package/dist/vite/index.js +8 -0
  106. package/dist/vite/index.js.map +1 -0
  107. package/dist/vite/plugin.d.ts +42 -0
  108. package/dist/vite/plugin.d.ts.map +1 -0
  109. package/dist/vite/plugin.js +46 -0
  110. package/dist/vite/plugin.js.map +1 -0
  111. package/package.json +90 -7
  112. package/src/client/RemoteLogClient.ts +328 -0
  113. package/src/client/index.ts +7 -0
  114. package/src/client/types.ts +62 -0
  115. package/src/index.ts +28 -0
  116. package/src/mcp/index.ts +25 -0
  117. package/src/mcp/mcp-server.ts +364 -0
  118. package/src/mcp/tools/index.ts +69 -0
  119. package/src/mcp/tools/logs-clear.ts +86 -0
  120. package/src/mcp/tools/logs-get-all.ts +78 -0
  121. package/src/mcp/tools/logs-get-errors.ts +71 -0
  122. package/src/mcp/tools/logs-get-file-path.ts +121 -0
  123. package/src/mcp/tools/logs-get-recent.ts +104 -0
  124. package/src/mcp/tools/logs-list-sessions.ts +71 -0
  125. package/src/mcp/tools/logs-receive.ts +96 -0
  126. package/src/mcp/tools/logs-search.ts +95 -0
  127. package/src/mcp/tools/logs-status.ts +69 -0
  128. package/src/server/dual-server.ts +308 -0
  129. package/src/server/index.ts +54 -0
  130. package/src/server/jsonl-writer.ts +277 -0
  131. package/src/server/log-server.ts +763 -0
  132. package/src/server/log-storage.ts +651 -0
  133. package/src/server/marker-utils.ts +144 -0
  134. package/src/server/self-signed-cert.ts +93 -0
  135. package/src/ui/ConsoleCaptureUI.ts +649 -0
  136. package/src/ui/index.ts +15 -0
  137. package/src/vite/index.ts +8 -0
  138. package/src/vite/plugin.ts +59 -0
@@ -0,0 +1,364 @@
1
+ /**
2
+ * MCP Server for remote logging.
3
+ *
4
+ * Provides an MCP interface for Claude Code to query logs from browser
5
+ * applications. Uses STDIO transport for communication.
6
+ * @module mcp/mcp-server
7
+ */
8
+
9
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+
12
+ import type { LogStorage } from "../server/log-storage.js";
13
+ import {
14
+ logsClearHandler,
15
+ type LogsClearInput,
16
+ logsClearInputSchema,
17
+ logsClearTool,
18
+ logsGetAllHandler,
19
+ type LogsGetAllInput,
20
+ logsGetAllInputSchema,
21
+ logsGetAllTool,
22
+ logsGetErrorsHandler,
23
+ type LogsGetErrorsInput,
24
+ logsGetErrorsInputSchema,
25
+ logsGetErrorsTool,
26
+ logsGetFilePathHandler,
27
+ type LogsGetFilePathInput,
28
+ logsGetFilePathInputSchema,
29
+ logsGetFilePathTool,
30
+ logsGetRecentHandler,
31
+ type LogsGetRecentInput,
32
+ logsGetRecentInputSchema,
33
+ logsGetRecentTool,
34
+ logsListSessionsHandler,
35
+ type LogsListSessionsInput,
36
+ logsListSessionsInputSchema,
37
+ logsListSessionsTool,
38
+ logsReceiveHandler,
39
+ type LogsReceiveInput,
40
+ logsReceiveInputSchema,
41
+ logsReceiveTool,
42
+ logsSearchHandler,
43
+ type LogsSearchInput,
44
+ logsSearchInputSchema,
45
+ logsSearchTool,
46
+ logsStatusHandler,
47
+ logsStatusTool,
48
+ } from "./tools/index.js";
49
+
50
+ // Track registered tool names for testing
51
+ let registeredTools: string[] = [];
52
+
53
+ /**
54
+ * Get the names of all registered tools.
55
+ * Useful for testing.
56
+ * @returns Array of registered tool names
57
+ */
58
+ export function getToolNames(): string[] {
59
+ return [...registeredTools];
60
+ }
61
+
62
+ /**
63
+ * Server instructions for LLMs describing the overall purpose and usage.
64
+ */
65
+ const SERVER_INSTRUCTIONS = `Remote Logger MCP Server - View console.log output from browser applications.
66
+
67
+ ## What is Remote Logging?
68
+
69
+ Browser applications run in a sandbox - their console.log() output appears in browser DevTools but is NOT visible to CLI tools or this assistant. Remote logging bridges this gap by sending browser logs to a server where they can be queried.
70
+
71
+ ## When to Use Remote Logging
72
+
73
+ Use this when debugging applications where developer tools aren't easily accessible:
74
+ - Storybook components (stories running in browser)
75
+ - Web applications during development
76
+ - Mobile web apps (phones, tablets) where DevTools requires USB debugging
77
+ - VR/AR applications where you can't see a console while wearing a headset
78
+ - Embedded devices, kiosks, or smart displays without keyboard access
79
+ - Any JavaScript running in a browser context
80
+
81
+ Remote logging is especially valuable for LLM assistants like this one - it enables reading, interpreting, and acting on application logs without requiring user interaction with browser DevTools.
82
+
83
+ ## Architecture
84
+
85
+ Browser App → HTTP POST to /logs → Log Server (stores in memory + JSONL files) → MCP Tools (query logs)
86
+
87
+ ## Setting Up a Browser App to Send Logs
88
+
89
+ First, get the server endpoint URL by calling logs_status - look for server.httpEndpoint in the response.
90
+
91
+ ### Option 1: Using the RemoteLogClient SDK (Recommended)
92
+
93
+ Install: npm install @graphty/remote-logger
94
+
95
+ \`\`\`typescript
96
+ import { RemoteLogClient } from "@graphty/remote-logger";
97
+
98
+ const logger = new RemoteLogClient({
99
+ serverUrl: "http://localhost:9080/logs", // Get this from logs_status
100
+ projectMarker: "my-project", // Optional: for filtering
101
+ });
102
+
103
+ // Intercept all console.log/warn/error calls
104
+ logger.interceptConsole();
105
+
106
+ // Or log manually
107
+ logger.log("INFO", "Hello from browser!");
108
+ \`\`\`
109
+
110
+ ### Option 2: Raw fetch() calls
111
+
112
+ \`\`\`typescript
113
+ fetch("http://localhost:9080/logs", {
114
+ method: "POST",
115
+ headers: { "Content-Type": "application/json" },
116
+ body: JSON.stringify({
117
+ sessionId: "unique-session-id",
118
+ logs: [
119
+ { time: new Date().toISOString(), level: "INFO", message: "Hello!" }
120
+ ]
121
+ })
122
+ });
123
+ \`\`\`
124
+
125
+ ## Querying Logs (MCP Tools)
126
+
127
+ Once browser logs are flowing to the server:
128
+
129
+ 1. logs_status - Check server health, get endpoint URL, see retention settings
130
+ 2. logs_get_recent - View recent logs (primary tool, sorted chronologically)
131
+ 3. logs_get_errors - Quick filter for ERROR level only
132
+ 4. logs_search - Find specific text (supports regex)
133
+ 5. logs_list_sessions - See all browser sessions
134
+ 6. logs_get_all - Get all logs grouped by session
135
+ 7. logs_get_file_path - Get JSONL file path for Grep/Read tools
136
+ 8. logs_clear - Delete logs (requires confirmation)
137
+
138
+ ## Typical Debugging Workflow
139
+
140
+ 1. Call logs_status to verify server is running and get the endpoint URL
141
+ 2. Ensure the browser app is configured to send logs to that endpoint
142
+ 3. Trigger the action in the browser you want to debug
143
+ 4. Call logs_get_recent to see what happened
144
+ 5. Use logs_search if looking for specific errors or messages`;
145
+
146
+ /**
147
+ * Create an MCP server with logging tools.
148
+ *
149
+ * Registers all logging tools and returns the configured server.
150
+ * The server is not started; use `startMcpServer` to run it.
151
+ * @param storage - The LogStorage instance to use for log operations
152
+ * @returns Configured McpServer instance
153
+ */
154
+ export function createMcpServer(storage: LogStorage): McpServer {
155
+ const server = new McpServer(
156
+ {
157
+ name: "remote-logger",
158
+ version: "1.0.0",
159
+ },
160
+ {
161
+ instructions: SERVER_INSTRUCTIONS,
162
+ },
163
+ );
164
+
165
+ // Reset registered tools
166
+ registeredTools = [];
167
+
168
+ // Register logs_get_recent tool
169
+ server.registerTool(
170
+ logsGetRecentTool.name,
171
+ {
172
+ description: logsGetRecentTool.description,
173
+ inputSchema: logsGetRecentInputSchema,
174
+ },
175
+ (args: LogsGetRecentInput) => {
176
+ return logsGetRecentHandler(storage, args).then((r) => ({
177
+ content: [
178
+ {
179
+ type: "text" as const,
180
+ text: JSON.stringify(r, null, 2),
181
+ },
182
+ ],
183
+ }));
184
+ },
185
+ );
186
+ registeredTools.push(logsGetRecentTool.name);
187
+
188
+ // Register logs_status tool
189
+ server.registerTool(
190
+ logsStatusTool.name,
191
+ {
192
+ description: logsStatusTool.description,
193
+ },
194
+ () => {
195
+ return logsStatusHandler(storage).then((r) => ({
196
+ content: [
197
+ {
198
+ type: "text" as const,
199
+ text: JSON.stringify(r, null, 2),
200
+ },
201
+ ],
202
+ }));
203
+ },
204
+ );
205
+ registeredTools.push(logsStatusTool.name);
206
+
207
+ // Register logs_list_sessions tool
208
+ server.registerTool(
209
+ logsListSessionsTool.name,
210
+ {
211
+ description: logsListSessionsTool.description,
212
+ inputSchema: logsListSessionsInputSchema,
213
+ },
214
+ (args: LogsListSessionsInput) => {
215
+ return logsListSessionsHandler(storage, args).then((r) => ({
216
+ content: [
217
+ {
218
+ type: "text" as const,
219
+ text: JSON.stringify(r, null, 2),
220
+ },
221
+ ],
222
+ }));
223
+ },
224
+ );
225
+ registeredTools.push(logsListSessionsTool.name);
226
+
227
+ // Register logs_receive tool
228
+ server.registerTool(
229
+ logsReceiveTool.name,
230
+ {
231
+ description: logsReceiveTool.description,
232
+ inputSchema: logsReceiveInputSchema,
233
+ },
234
+ (args: LogsReceiveInput) => {
235
+ return logsReceiveHandler(storage, args).then((r) => ({
236
+ content: [
237
+ {
238
+ type: "text" as const,
239
+ text: JSON.stringify(r, null, 2),
240
+ },
241
+ ],
242
+ }));
243
+ },
244
+ );
245
+ registeredTools.push(logsReceiveTool.name);
246
+
247
+ // Register logs_get_all tool
248
+ server.registerTool(
249
+ logsGetAllTool.name,
250
+ {
251
+ description: logsGetAllTool.description,
252
+ inputSchema: logsGetAllInputSchema,
253
+ },
254
+ (args: LogsGetAllInput) => {
255
+ return logsGetAllHandler(storage, args).then((r) => ({
256
+ content: [
257
+ {
258
+ type: "text" as const,
259
+ text: JSON.stringify(r, null, 2),
260
+ },
261
+ ],
262
+ }));
263
+ },
264
+ );
265
+ registeredTools.push(logsGetAllTool.name);
266
+
267
+ // Register logs_get_errors tool
268
+ server.registerTool(
269
+ logsGetErrorsTool.name,
270
+ {
271
+ description: logsGetErrorsTool.description,
272
+ inputSchema: logsGetErrorsInputSchema,
273
+ },
274
+ (args: LogsGetErrorsInput) => {
275
+ return logsGetErrorsHandler(storage, args).then((r) => ({
276
+ content: [
277
+ {
278
+ type: "text" as const,
279
+ text: JSON.stringify(r, null, 2),
280
+ },
281
+ ],
282
+ }));
283
+ },
284
+ );
285
+ registeredTools.push(logsGetErrorsTool.name);
286
+
287
+ // Register logs_clear tool
288
+ server.registerTool(
289
+ logsClearTool.name,
290
+ {
291
+ description: logsClearTool.description,
292
+ inputSchema: logsClearInputSchema,
293
+ },
294
+ (args: LogsClearInput) => {
295
+ return logsClearHandler(storage, args).then((r) => ({
296
+ content: [
297
+ {
298
+ type: "text" as const,
299
+ text: JSON.stringify(r, null, 2),
300
+ },
301
+ ],
302
+ }));
303
+ },
304
+ );
305
+ registeredTools.push(logsClearTool.name);
306
+
307
+ // Register logs_search tool
308
+ server.registerTool(
309
+ logsSearchTool.name,
310
+ {
311
+ description: logsSearchTool.description,
312
+ inputSchema: logsSearchInputSchema,
313
+ },
314
+ (args: LogsSearchInput) => {
315
+ return logsSearchHandler(storage, args).then((r) => ({
316
+ content: [
317
+ {
318
+ type: "text" as const,
319
+ text: JSON.stringify(r, null, 2),
320
+ },
321
+ ],
322
+ }));
323
+ },
324
+ );
325
+ registeredTools.push(logsSearchTool.name);
326
+
327
+ // Register logs_get_file_path tool
328
+ server.registerTool(
329
+ logsGetFilePathTool.name,
330
+ {
331
+ description: logsGetFilePathTool.description,
332
+ inputSchema: logsGetFilePathInputSchema,
333
+ },
334
+ (args: LogsGetFilePathInput) => {
335
+ return logsGetFilePathHandler(storage, args).then((r) => ({
336
+ content: [
337
+ {
338
+ type: "text" as const,
339
+ text: JSON.stringify(r, null, 2),
340
+ },
341
+ ],
342
+ }));
343
+ },
344
+ );
345
+ registeredTools.push(logsGetFilePathTool.name);
346
+
347
+ return server;
348
+ }
349
+
350
+ /**
351
+ * Start the MCP server with STDIO transport.
352
+ *
353
+ * This function runs the MCP server and blocks until the connection is closed.
354
+ * @param storage - The LogStorage instance to use for log operations
355
+ */
356
+ export async function startMcpServer(storage: LogStorage): Promise<void> {
357
+ const server = createMcpServer(storage);
358
+ const transport = new StdioServerTransport();
359
+
360
+ await server.connect(transport);
361
+
362
+ // Keep the process alive
363
+ // The connection will handle cleanup when stdin closes
364
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * MCP tool exports and registration.
3
+ * @module mcp/tools
4
+ */
5
+
6
+ export {
7
+ logsClearHandler,
8
+ type LogsClearInput,
9
+ logsClearInputSchema,
10
+ type LogsClearOutput,
11
+ logsClearTool,
12
+ } from "./logs-clear.js";
13
+ export {
14
+ logsGetAllHandler,
15
+ type LogsGetAllInput,
16
+ logsGetAllInputSchema,
17
+ type LogsGetAllOutput,
18
+ logsGetAllTool,
19
+ } from "./logs-get-all.js";
20
+ export {
21
+ logsGetErrorsHandler,
22
+ type LogsGetErrorsInput,
23
+ logsGetErrorsInputSchema,
24
+ type LogsGetErrorsOutput,
25
+ logsGetErrorsTool,
26
+ } from "./logs-get-errors.js";
27
+ export {
28
+ getLogFilePath,
29
+ logsGetFilePathHandler,
30
+ type LogsGetFilePathInput,
31
+ logsGetFilePathInputSchema,
32
+ type LogsGetFilePathOutput,
33
+ logsGetFilePathTool,
34
+ } from "./logs-get-file-path.js";
35
+ export {
36
+ logsGetRecentHandler,
37
+ type LogsGetRecentInput,
38
+ logsGetRecentInputSchema,
39
+ type LogsGetRecentOutput,
40
+ logsGetRecentTool,
41
+ } from "./logs-get-recent.js";
42
+ export {
43
+ logsListSessionsHandler,
44
+ type LogsListSessionsInput,
45
+ logsListSessionsInputSchema,
46
+ type LogsListSessionsOutput,
47
+ logsListSessionsTool,
48
+ } from "./logs-list-sessions.js";
49
+ export {
50
+ logsReceiveHandler,
51
+ type LogsReceiveInput,
52
+ logsReceiveInputSchema,
53
+ type LogsReceiveOutput,
54
+ logsReceiveTool,
55
+ } from "./logs-receive.js";
56
+ export {
57
+ logsSearchHandler,
58
+ type LogsSearchInput,
59
+ logsSearchInputSchema,
60
+ type LogsSearchOutput,
61
+ logsSearchTool,
62
+ } from "./logs-search.js";
63
+ export {
64
+ logsStatusHandler,
65
+ type LogsStatusInput,
66
+ logsStatusInputSchema,
67
+ type LogsStatusOutput,
68
+ logsStatusTool,
69
+ } from "./logs-status.js";
@@ -0,0 +1,86 @@
1
+ /**
2
+ * logs_clear MCP tool implementation.
3
+ *
4
+ * Clears logs with confirmation requirement for safety.
5
+ * @module mcp/tools/logs-clear
6
+ */
7
+
8
+ import * as z from "zod/v3";
9
+
10
+ import type { LogStorage } from "../../server/log-storage.js";
11
+
12
+ /**
13
+ * Input schema for the logs_clear tool.
14
+ */
15
+ export const logsClearInputSchema = z.object({
16
+ /** Safety flag: must be set to true for the operation to proceed. Prevents accidental deletion. */
17
+ confirm: z.boolean().optional(),
18
+ /** Clear only logs for this project. Clears all projects if omitted. */
19
+ projectMarker: z.string().optional(),
20
+ /** Clear only logs for this specific session. Clears all sessions if omitted. */
21
+ sessionId: z.string().optional(),
22
+ });
23
+
24
+ /**
25
+ * Input type for the logs_clear handler.
26
+ */
27
+ export type LogsClearInput = z.infer<typeof logsClearInputSchema>;
28
+
29
+ /**
30
+ * Output type for the logs_clear handler.
31
+ */
32
+ export interface LogsClearOutput {
33
+ /** Whether the operation succeeded */
34
+ success: boolean;
35
+ /** Number of sessions cleared */
36
+ cleared: number;
37
+ /** Error message if operation failed */
38
+ error?: string;
39
+ }
40
+
41
+ /**
42
+ * Handler for the logs_clear tool.
43
+ *
44
+ * Clears logs with optional filtering. Requires explicit confirmation
45
+ * to prevent accidental data loss.
46
+ * @param storage - The log storage instance
47
+ * @param input - Input parameters
48
+ * @returns Success status and count of cleared sessions
49
+ */
50
+ export function logsClearHandler(
51
+ storage: LogStorage,
52
+ input: Partial<LogsClearInput>,
53
+ ): Promise<LogsClearOutput> {
54
+ // Require explicit confirmation
55
+ if (input.confirm !== true) {
56
+ return Promise.resolve({
57
+ success: false,
58
+ cleared: 0,
59
+ error: "Operation requires confirm: true to proceed. This prevents accidental data loss.",
60
+ });
61
+ }
62
+
63
+ const result = storage.clearLogs({
64
+ projectMarker: input.projectMarker,
65
+ sessionId: input.sessionId,
66
+ });
67
+
68
+ return Promise.resolve({
69
+ success: true,
70
+ cleared: result.cleared,
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Tool definition for MCP registration.
76
+ */
77
+ export const logsClearTool = {
78
+ name: "logs_clear",
79
+ description:
80
+ "Clear logs from the server. " +
81
+ "Requires confirm: true to proceed - this prevents accidental data loss. " +
82
+ "Can optionally filter by projectMarker to clear only one project, " +
83
+ "or by sessionId to clear a specific session. " +
84
+ "Without filters, clears ALL logs.",
85
+ inputSchema: logsClearInputSchema,
86
+ };
@@ -0,0 +1,78 @@
1
+ /**
2
+ * logs_get_all MCP tool implementation.
3
+ *
4
+ * Returns all logs grouped by session.
5
+ * @module mcp/tools/logs-get-all
6
+ */
7
+
8
+ import * as z from "zod/v3";
9
+
10
+ import type { LogEntry, LogStorage } from "../../server/log-storage.js";
11
+
12
+ /**
13
+ * Input schema for the logs_get_all tool.
14
+ */
15
+ export const logsGetAllInputSchema = z.object({
16
+ /** Filter results to a specific project identifier. Returns all projects if omitted. */
17
+ projectMarker: z.string().optional(),
18
+ });
19
+
20
+ /**
21
+ * Input type for the logs_get_all handler.
22
+ */
23
+ export type LogsGetAllInput = z.infer<typeof logsGetAllInputSchema>;
24
+
25
+ /**
26
+ * Output type for the logs_get_all handler.
27
+ */
28
+ export interface LogsGetAllOutput {
29
+ /** Logs grouped by session ID */
30
+ sessions: Record<string, LogEntry[]>;
31
+ /** Number of sessions */
32
+ sessionCount: number;
33
+ /** Total number of logs across all sessions */
34
+ totalLogs: number;
35
+ }
36
+
37
+ /**
38
+ * Handler for the logs_get_all tool.
39
+ *
40
+ * Returns all logs grouped by session ID, with optional filtering by
41
+ * project marker.
42
+ * @param storage - The log storage instance
43
+ * @param input - Input parameters
44
+ * @returns Logs grouped by session
45
+ */
46
+ export function logsGetAllHandler(
47
+ storage: LogStorage,
48
+ input: Partial<LogsGetAllInput>,
49
+ ): Promise<LogsGetAllOutput> {
50
+ const sessions = storage.getAllLogsBySession({
51
+ projectMarker: input.projectMarker,
52
+ });
53
+
54
+ // Calculate totals
55
+ let totalLogs = 0;
56
+ for (const logs of Object.values(sessions)) {
57
+ totalLogs += logs.length;
58
+ }
59
+
60
+ return Promise.resolve({
61
+ sessions,
62
+ sessionCount: Object.keys(sessions).length,
63
+ totalLogs,
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Tool definition for MCP registration.
69
+ */
70
+ export const logsGetAllTool = {
71
+ name: "logs_get_all",
72
+ description:
73
+ "Get all logs grouped by session. " +
74
+ "Use this to see a complete view of logging activity across all browser sessions. " +
75
+ "Returns logs organized by session ID, making it easy to trace activity per browser tab. " +
76
+ "For a flat list of recent logs, use logs_get_recent instead.",
77
+ inputSchema: logsGetAllInputSchema,
78
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * logs_get_errors MCP tool implementation.
3
+ *
4
+ * Returns only ERROR level logs.
5
+ * @module mcp/tools/logs-get-errors
6
+ */
7
+
8
+ import * as z from "zod/v3";
9
+
10
+ import type { LogEntryWithSession, LogStorage } from "../../server/log-storage.js";
11
+
12
+ /**
13
+ * Input schema for the logs_get_errors tool.
14
+ */
15
+ export const logsGetErrorsInputSchema = z.object({
16
+ /** Filter errors to a specific project identifier. Returns all projects if omitted. */
17
+ projectMarker: z.string().optional(),
18
+ /** Return only errors after this timestamp. Format: ISO 8601 (e.g., "2025-01-08T12:00:00Z"). */
19
+ since: z.string().optional(),
20
+ });
21
+
22
+ /**
23
+ * Input type for the logs_get_errors handler.
24
+ */
25
+ export type LogsGetErrorsInput = z.infer<typeof logsGetErrorsInputSchema>;
26
+
27
+ /**
28
+ * Output type for the logs_get_errors handler.
29
+ */
30
+ export interface LogsGetErrorsOutput {
31
+ /** Array of ERROR level log entries */
32
+ errors: LogEntryWithSession[];
33
+ /** Number of errors returned */
34
+ count: number;
35
+ }
36
+
37
+ /**
38
+ * Handler for the logs_get_errors tool.
39
+ *
40
+ * Returns only ERROR level logs, sorted chronologically.
41
+ * @param storage - The log storage instance
42
+ * @param input - Input parameters
43
+ * @returns Error logs and count
44
+ */
45
+ export function logsGetErrorsHandler(
46
+ storage: LogStorage,
47
+ input: Partial<LogsGetErrorsInput>,
48
+ ): Promise<LogsGetErrorsOutput> {
49
+ const errors = storage.getErrors({
50
+ projectMarker: input.projectMarker,
51
+ since: input.since,
52
+ });
53
+
54
+ return Promise.resolve({
55
+ errors,
56
+ count: errors.length,
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Tool definition for MCP registration.
62
+ */
63
+ export const logsGetErrorsTool = {
64
+ name: "logs_get_errors",
65
+ description:
66
+ "Get only ERROR level logs. " +
67
+ "Use this to quickly find error messages across all sessions. " +
68
+ "This is faster and more focused than logs_get_recent when you only need errors. " +
69
+ "Results are sorted chronologically.",
70
+ inputSchema: logsGetErrorsInputSchema,
71
+ };