@graphty/remote-logger 1.1.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 (110) hide show
  1. package/README.md +318 -10
  2. package/dist/client/RemoteLogClient.d.ts +2 -0
  3. package/dist/client/RemoteLogClient.d.ts.map +1 -1
  4. package/dist/client/RemoteLogClient.js +35 -4
  5. package/dist/client/RemoteLogClient.js.map +1 -1
  6. package/dist/client/types.d.ts +13 -0
  7. package/dist/client/types.d.ts.map +1 -1
  8. package/dist/mcp/index.d.ts +9 -0
  9. package/dist/mcp/index.d.ts.map +1 -0
  10. package/dist/mcp/index.js +9 -0
  11. package/dist/mcp/index.js.map +1 -0
  12. package/dist/mcp/mcp-server.d.ts +32 -0
  13. package/dist/mcp/mcp-server.d.ts.map +1 -0
  14. package/dist/mcp/mcp-server.js +270 -0
  15. package/dist/mcp/mcp-server.js.map +1 -0
  16. package/dist/mcp/tools/index.d.ts +14 -0
  17. package/dist/mcp/tools/index.d.ts.map +1 -0
  18. package/dist/mcp/tools/index.js +14 -0
  19. package/dist/mcp/tools/index.js.map +1 -0
  20. package/dist/mcp/tools/logs-clear.d.ts +76 -0
  21. package/dist/mcp/tools/logs-clear.d.ts.map +1 -0
  22. package/dist/mcp/tools/logs-clear.js +58 -0
  23. package/dist/mcp/tools/logs-clear.js.map +1 -0
  24. package/dist/mcp/tools/logs-get-all.d.ts +60 -0
  25. package/dist/mcp/tools/logs-get-all.d.ts.map +1 -0
  26. package/dist/mcp/tools/logs-get-all.js +50 -0
  27. package/dist/mcp/tools/logs-get-all.js.map +1 -0
  28. package/dist/mcp/tools/logs-get-errors.d.ts +65 -0
  29. package/dist/mcp/tools/logs-get-errors.d.ts.map +1 -0
  30. package/dist/mcp/tools/logs-get-errors.js +46 -0
  31. package/dist/mcp/tools/logs-get-errors.js.map +1 -0
  32. package/dist/mcp/tools/logs-get-file-path.d.ts +75 -0
  33. package/dist/mcp/tools/logs-get-file-path.d.ts.map +1 -0
  34. package/dist/mcp/tools/logs-get-file-path.js +90 -0
  35. package/dist/mcp/tools/logs-get-file-path.js.map +1 -0
  36. package/dist/mcp/tools/logs-get-recent.d.ts +89 -0
  37. package/dist/mcp/tools/logs-get-recent.d.ts.map +1 -0
  38. package/dist/mcp/tools/logs-get-recent.js +74 -0
  39. package/dist/mcp/tools/logs-get-recent.js.map +1 -0
  40. package/dist/mcp/tools/logs-list-sessions.d.ts +64 -0
  41. package/dist/mcp/tools/logs-list-sessions.d.ts.map +1 -0
  42. package/dist/mcp/tools/logs-list-sessions.js +48 -0
  43. package/dist/mcp/tools/logs-list-sessions.js.map +1 -0
  44. package/dist/mcp/tools/logs-receive.d.ts +150 -0
  45. package/dist/mcp/tools/logs-receive.d.ts.map +1 -0
  46. package/dist/mcp/tools/logs-receive.js +68 -0
  47. package/dist/mcp/tools/logs-receive.js.map +1 -0
  48. package/dist/mcp/tools/logs-search.d.ts +91 -0
  49. package/dist/mcp/tools/logs-search.d.ts.map +1 -0
  50. package/dist/mcp/tools/logs-search.js +68 -0
  51. package/dist/mcp/tools/logs-search.js.map +1 -0
  52. package/dist/mcp/tools/logs-status.d.ts +45 -0
  53. package/dist/mcp/tools/logs-status.d.ts.map +1 -0
  54. package/dist/mcp/tools/logs-status.js +45 -0
  55. package/dist/mcp/tools/logs-status.js.map +1 -0
  56. package/dist/server/dual-server.d.ts +76 -0
  57. package/dist/server/dual-server.d.ts.map +1 -0
  58. package/dist/server/dual-server.js +214 -0
  59. package/dist/server/dual-server.js.map +1 -0
  60. package/dist/server/index.d.ts +5 -1
  61. package/dist/server/index.d.ts.map +1 -1
  62. package/dist/server/index.js +5 -1
  63. package/dist/server/index.js.map +1 -1
  64. package/dist/server/jsonl-writer.d.ts +93 -0
  65. package/dist/server/jsonl-writer.d.ts.map +1 -0
  66. package/dist/server/jsonl-writer.js +205 -0
  67. package/dist/server/jsonl-writer.js.map +1 -0
  68. package/dist/server/log-server.d.ts +62 -11
  69. package/dist/server/log-server.d.ts.map +1 -1
  70. package/dist/server/log-server.js +237 -101
  71. package/dist/server/log-server.js.map +1 -1
  72. package/dist/server/log-storage.d.ts +301 -0
  73. package/dist/server/log-storage.d.ts.map +1 -0
  74. package/dist/server/log-storage.js +408 -0
  75. package/dist/server/log-storage.js.map +1 -0
  76. package/dist/server/marker-utils.d.ts +69 -0
  77. package/dist/server/marker-utils.d.ts.map +1 -0
  78. package/dist/server/marker-utils.js +118 -0
  79. package/dist/server/marker-utils.js.map +1 -0
  80. package/dist/vite/index.d.ts +8 -0
  81. package/dist/vite/index.d.ts.map +1 -0
  82. package/dist/vite/index.js +8 -0
  83. package/dist/vite/index.js.map +1 -0
  84. package/dist/vite/plugin.d.ts +42 -0
  85. package/dist/vite/plugin.d.ts.map +1 -0
  86. package/dist/vite/plugin.js +46 -0
  87. package/dist/vite/plugin.js.map +1 -0
  88. package/package.json +12 -2
  89. package/src/client/RemoteLogClient.ts +52 -4
  90. package/src/client/types.ts +13 -0
  91. package/src/mcp/index.ts +25 -0
  92. package/src/mcp/mcp-server.ts +364 -0
  93. package/src/mcp/tools/index.ts +69 -0
  94. package/src/mcp/tools/logs-clear.ts +86 -0
  95. package/src/mcp/tools/logs-get-all.ts +78 -0
  96. package/src/mcp/tools/logs-get-errors.ts +71 -0
  97. package/src/mcp/tools/logs-get-file-path.ts +121 -0
  98. package/src/mcp/tools/logs-get-recent.ts +104 -0
  99. package/src/mcp/tools/logs-list-sessions.ts +71 -0
  100. package/src/mcp/tools/logs-receive.ts +96 -0
  101. package/src/mcp/tools/logs-search.ts +95 -0
  102. package/src/mcp/tools/logs-status.ts +69 -0
  103. package/src/server/dual-server.ts +308 -0
  104. package/src/server/index.ts +37 -0
  105. package/src/server/jsonl-writer.ts +277 -0
  106. package/src/server/log-server.ts +311 -119
  107. package/src/server/log-storage.ts +651 -0
  108. package/src/server/marker-utils.ts +144 -0
  109. package/src/vite/index.ts +8 -0
  110. package/src/vite/plugin.ts +59 -0
@@ -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
+ };
@@ -0,0 +1,121 @@
1
+ /**
2
+ * logs_get_file_path MCP tool implementation.
3
+ *
4
+ * Returns the path to the JSONL log file for a project.
5
+ * @module mcp/tools/logs-get-file-path
6
+ */
7
+
8
+ import * as fs from "fs";
9
+ import * as os from "os";
10
+ import * as path from "path";
11
+ import * as z from "zod/v3";
12
+
13
+ import type { LogStorage } from "../../server/log-storage.js";
14
+ import { resolveProjectMarker } from "../../server/marker-utils.js";
15
+
16
+ /**
17
+ * Input schema for the logs_get_file_path tool.
18
+ */
19
+ export const logsGetFilePathInputSchema = z.object({
20
+ /** Project identifier to get the log file for. Derived from workingDirectory if not provided. */
21
+ projectMarker: z.string().optional(),
22
+ /** Directory path to derive project marker from. Ignored if projectMarker is set. */
23
+ workingDirectory: z.string().optional(),
24
+ });
25
+
26
+ /**
27
+ * Input type for the logs_get_file_path handler.
28
+ */
29
+ export type LogsGetFilePathInput = z.infer<typeof logsGetFilePathInputSchema>;
30
+
31
+ /**
32
+ * Output type for the logs_get_file_path handler.
33
+ */
34
+ export interface LogsGetFilePathOutput {
35
+ /** Full path to the JSONL log file */
36
+ path: string;
37
+ /** Whether the file exists */
38
+ exists: boolean;
39
+ /** File size in bytes (0 if file doesn't exist) */
40
+ size: number;
41
+ }
42
+
43
+ /**
44
+ * Get the default JSONL file path for a project marker.
45
+ * This is used when no JsonlWriter is configured.
46
+ * @param projectMarker - The project marker
47
+ * @returns Full path to the JSONL file
48
+ */
49
+ export function getLogFilePath(projectMarker: string): string {
50
+ return path.join(os.tmpdir(), "remote-logger", projectMarker, "logs.jsonl");
51
+ }
52
+
53
+ /**
54
+ * Handler for the logs_get_file_path tool.
55
+ *
56
+ * Returns the path to the JSONL log file for the specified project.
57
+ * The file may not exist if no logs have been written yet.
58
+ * @param storage - The log storage instance
59
+ * @param input - Input parameters
60
+ * @returns File path, existence status, and size
61
+ */
62
+ export function logsGetFilePathHandler(
63
+ storage: LogStorage,
64
+ input: Partial<LogsGetFilePathInput>,
65
+ ): Promise<LogsGetFilePathOutput> {
66
+ // Resolve project marker
67
+ const projectMarker = resolveProjectMarker({
68
+ projectMarker: input.projectMarker,
69
+ workingDirectory: input.workingDirectory,
70
+ });
71
+
72
+ // Get file path from JsonlWriter if available, otherwise use default
73
+ const jsonlWriter = storage.getJsonlWriter();
74
+ const filePath = jsonlWriter
75
+ ? jsonlWriter.getFilePath(projectMarker)
76
+ : getLogFilePath(projectMarker);
77
+
78
+ // Check if file exists and get stats
79
+ // Prefer JsonlWriter stats if available for consistency
80
+ if (jsonlWriter) {
81
+ const stats = jsonlWriter.getFileStats(projectMarker);
82
+ if (stats) {
83
+ return Promise.resolve({
84
+ path: filePath,
85
+ exists: stats.exists,
86
+ size: stats.size,
87
+ });
88
+ }
89
+ }
90
+
91
+ // Fall back to direct file system check
92
+ let exists = false;
93
+ let size = 0;
94
+
95
+ try {
96
+ const stats = fs.statSync(filePath);
97
+ exists = true;
98
+ ({ size } = stats);
99
+ } catch {
100
+ // File doesn't exist, use defaults
101
+ }
102
+
103
+ return Promise.resolve({
104
+ path: filePath,
105
+ exists,
106
+ size,
107
+ });
108
+ }
109
+
110
+ /**
111
+ * Tool definition for MCP registration.
112
+ */
113
+ export const logsGetFilePathTool = {
114
+ name: "logs_get_file_path",
115
+ description:
116
+ "Get the file path to the JSONL log file for a project. " +
117
+ "Use this to access logs via file-based tools like Grep or Read. " +
118
+ "Each project has its own log file. " +
119
+ "The file may not exist if no logs have been written yet for that project.",
120
+ inputSchema: logsGetFilePathInputSchema,
121
+ };
@@ -0,0 +1,104 @@
1
+ /**
2
+ * logs_get_recent MCP tool implementation.
3
+ *
4
+ * Returns recent logs sorted by time with optional filtering.
5
+ * @module mcp/tools/logs-get-recent
6
+ */
7
+
8
+ import * as z from "zod/v3";
9
+
10
+ import type { LogEntryWithSession, LogFilter,LogStorage } from "../../server/log-storage.js";
11
+ import { resolveProjectMarker } from "../../server/marker-utils.js";
12
+
13
+ /**
14
+ * Input schema for the logs_get_recent tool.
15
+ * Note: We use a simple shape without .default() to be compatible with MCP SDK.
16
+ */
17
+ export const logsGetRecentInputSchema = z.object({
18
+ /** Number of logs to return. Defaults to 50. Range: 1-500. */
19
+ count: z.number().int().min(1).max(500).optional(),
20
+ /** Filter logs to a specific project. Derived from workingDirectory if not provided. */
21
+ projectMarker: z.string().optional(),
22
+ /** Directory path to derive project marker from. Ignored if projectMarker is set. */
23
+ workingDirectory: z.string().optional(),
24
+ /** Filter by log level (e.g., "INFO", "ERROR", "DEBUG"). Case-sensitive. */
25
+ level: z.string().optional(),
26
+ /** Return only logs after this timestamp. Format: ISO 8601 (e.g., "2025-01-08T12:00:00Z"). */
27
+ since: z.string().optional(),
28
+ });
29
+
30
+ /**
31
+ * Input type for the logs_get_recent handler.
32
+ */
33
+ export type LogsGetRecentInput = z.infer<typeof logsGetRecentInputSchema>;
34
+
35
+ /**
36
+ * Output type for the logs_get_recent handler.
37
+ */
38
+ export interface LogsGetRecentOutput {
39
+ logs: LogEntryWithSession[];
40
+ count: number;
41
+ }
42
+
43
+ /**
44
+ * Handler for the logs_get_recent tool.
45
+ *
46
+ * Returns recent logs sorted by time (oldest first), with optional filtering
47
+ * by project marker, level, or timestamp.
48
+ * @param storage - The log storage instance
49
+ * @param input - Input parameters
50
+ * @returns Recent logs and count
51
+ */
52
+ export function logsGetRecentHandler(
53
+ storage: LogStorage,
54
+ input: Partial<LogsGetRecentInput>,
55
+ ): Promise<LogsGetRecentOutput> {
56
+ // Apply defaults
57
+ const requestedCount = input.count ?? 50;
58
+
59
+ // Resolve project marker from input
60
+ const projectMarker = resolveProjectMarker({
61
+ projectMarker: input.projectMarker,
62
+ workingDirectory: input.workingDirectory,
63
+ });
64
+
65
+ // Build filter
66
+ const filter: LogFilter = {};
67
+
68
+ if (projectMarker !== "default") {
69
+ filter.projectMarker = projectMarker;
70
+ }
71
+
72
+ if (input.level) {
73
+ filter.level = input.level;
74
+ }
75
+
76
+ if (input.since) {
77
+ filter.since = input.since;
78
+ }
79
+
80
+ // Ensure count doesn't exceed 500
81
+ const limitedCount = Math.min(requestedCount, 500);
82
+
83
+ // Get recent logs
84
+ const logs = storage.getRecentLogs(limitedCount, filter);
85
+
86
+ return Promise.resolve({
87
+ logs,
88
+ count: logs.length,
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Tool definition for MCP registration.
94
+ */
95
+ export const logsGetRecentTool = {
96
+ name: "logs_get_recent",
97
+ description:
98
+ "Get recent logs from the remote log server, sorted by time (oldest first). " +
99
+ "Use this to see the latest log output from browser applications. " +
100
+ "This is the primary tool for viewing logs. " +
101
+ "For error-only logs, use logs_get_errors instead. " +
102
+ "For searching specific text, use logs_search.",
103
+ inputSchema: logsGetRecentInputSchema,
104
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * logs_list_sessions MCP tool implementation.
3
+ *
4
+ * Lists all logging sessions with their metadata.
5
+ * @module mcp/tools/logs-list-sessions
6
+ */
7
+
8
+ import * as z from "zod/v3";
9
+
10
+ import type { LogStorage, SessionMetadata } from "../../server/log-storage.js";
11
+
12
+ /**
13
+ * Input schema for the logs_list_sessions tool.
14
+ */
15
+ export const logsListSessionsInputSchema = z.object({
16
+ /** Filter sessions to a specific project identifier. */
17
+ projectMarker: z.string().optional(),
18
+ /** When true, only return sessions that contain error-level logs. */
19
+ hasErrors: z.boolean().optional(),
20
+ });
21
+
22
+ /**
23
+ * Input type for the logs_list_sessions handler.
24
+ */
25
+ export type LogsListSessionsInput = z.infer<typeof logsListSessionsInputSchema>;
26
+
27
+ /**
28
+ * Output type for the logs_list_sessions handler.
29
+ */
30
+ export interface LogsListSessionsOutput {
31
+ sessions: SessionMetadata[];
32
+ count: number;
33
+ }
34
+
35
+ /**
36
+ * Handler for the logs_list_sessions tool.
37
+ *
38
+ * Lists all logging sessions with their metadata including project marker,
39
+ * log counts, error counts, and timestamps.
40
+ * @param storage - The log storage instance
41
+ * @param input - Input parameters
42
+ * @returns List of sessions and count
43
+ */
44
+ export function logsListSessionsHandler(
45
+ storage: LogStorage,
46
+ input: Partial<LogsListSessionsInput>,
47
+ ): Promise<LogsListSessionsOutput> {
48
+ // Get sessions with filter
49
+ const sessions = storage.getSessions({
50
+ projectMarker: input.projectMarker,
51
+ hasErrors: input.hasErrors,
52
+ });
53
+
54
+ return Promise.resolve({
55
+ sessions,
56
+ count: sessions.length,
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Tool definition for MCP registration.
62
+ */
63
+ export const logsListSessionsTool = {
64
+ name: "logs_list_sessions",
65
+ description:
66
+ "List all logging sessions with their metadata. " +
67
+ "Each session represents a browser tab or application instance. " +
68
+ "Use this to discover active sessions before fetching their logs, " +
69
+ "or to find sessions with errors using the hasErrors filter.",
70
+ inputSchema: logsListSessionsInputSchema,
71
+ };
@@ -0,0 +1,96 @@
1
+ /**
2
+ * logs_receive MCP tool implementation.
3
+ *
4
+ * Stores logs with session metadata for later retrieval.
5
+ * @module mcp/tools/logs-receive
6
+ */
7
+
8
+ import * as z from "zod/v3";
9
+
10
+ import type { LogStorage } from "../../server/log-storage.js";
11
+
12
+ /**
13
+ * Schema for a single log entry.
14
+ */
15
+ const logEntrySchema = z.object({
16
+ /** When the log was created. Format: ISO 8601 (e.g., "2025-01-08T12:00:00Z"). */
17
+ time: z.string(),
18
+ /** Severity level (e.g., "INFO", "DEBUG", "WARN", "ERROR"). */
19
+ level: z.string(),
20
+ /** The log message text. */
21
+ message: z.string(),
22
+ /** Additional structured data to attach to the log entry. */
23
+ data: z.record(z.unknown()).optional(),
24
+ });
25
+
26
+ /**
27
+ * Input schema for the logs_receive tool.
28
+ */
29
+ export const logsReceiveInputSchema = z.object({
30
+ /** Unique identifier for this logging session. Links related logs together. */
31
+ sessionId: z.string(),
32
+ /** Array of log entries to store. At least one entry required. */
33
+ logs: z.array(logEntrySchema),
34
+ /** Project identifier for filtering. Derived from sessionId prefix if not provided. */
35
+ projectMarker: z.string().optional(),
36
+ /** Git worktree path for project identification. */
37
+ worktreePath: z.string().optional(),
38
+ /** URL of the page that generated these logs. */
39
+ pageUrl: z.string().optional(),
40
+ });
41
+
42
+ /**
43
+ * Input type for the logs_receive handler.
44
+ */
45
+ export type LogsReceiveInput = z.infer<typeof logsReceiveInputSchema>;
46
+
47
+ /**
48
+ * Output type for the logs_receive handler.
49
+ */
50
+ export interface LogsReceiveOutput {
51
+ /** Whether the operation succeeded */
52
+ success: boolean;
53
+ /** Number of logs stored */
54
+ count: number;
55
+ /** The session ID used */
56
+ sessionId: string;
57
+ }
58
+
59
+ /**
60
+ * Handler for the logs_receive tool.
61
+ *
62
+ * Stores logs with session metadata. The project marker is derived from
63
+ * the session ID prefix if not explicitly provided.
64
+ * @param storage - The log storage instance
65
+ * @param input - Input parameters
66
+ * @returns Success status, count, and session ID
67
+ */
68
+ export function logsReceiveHandler(
69
+ storage: LogStorage,
70
+ input: LogsReceiveInput,
71
+ ): Promise<LogsReceiveOutput> {
72
+ storage.addLogs(input.sessionId, input.logs, {
73
+ projectMarker: input.projectMarker,
74
+ worktreePath: input.worktreePath,
75
+ pageUrl: input.pageUrl,
76
+ });
77
+
78
+ return Promise.resolve({
79
+ success: true,
80
+ count: input.logs.length,
81
+ sessionId: input.sessionId,
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Tool definition for MCP registration.
87
+ */
88
+ export const logsReceiveTool = {
89
+ name: "logs_receive",
90
+ description:
91
+ "Store logs from a browser or application session. " +
92
+ "Logs are associated with a session ID and can be filtered by project marker. " +
93
+ "This tool is called by browser clients to send logs to the server. " +
94
+ "You typically don't need to call this directly - use it when manually testing log ingestion.",
95
+ inputSchema: logsReceiveInputSchema,
96
+ };