@agimon-ai/log-sink-mcp 0.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.
package/README.md ADDED
@@ -0,0 +1,755 @@
1
+ # log-sink-mcp
2
+
3
+ AI-powered log analysis MCP server with HTTP ingestion and SQLite storage.
4
+
5
+ ## Overview
6
+
7
+ `log-sink-mcp` provides a complete log analysis solution for AI assistants like Claude. It combines:
8
+
9
+ - **HTTP Server**: REST endpoint for log ingestion from any application
10
+ - **MCP Server**: 7 AI-optimized tools for querying and analyzing logs
11
+ - **SQLite Database**: Fast local storage with FTS5 full-text search
12
+ - **Real-time Analysis**: Query logs, trace distributed requests, analyze error patterns
13
+
14
+ Perfect for debugging, monitoring, and understanding application behavior through AI-powered analysis.
15
+
16
+ ## Features
17
+
18
+ - ✅ **HTTP Log Ingestion**: POST logs from any application via REST API
19
+ - ✅ **7 MCP Tools**: Query, search, trace, analyze, and manage logs
20
+ - ✅ **Full-Text Search**: Fast FTS5-powered search across messages and errors
21
+ - ✅ **Distributed Tracing**: Timeline view for trace IDs and span relationships
22
+ - ✅ **Error Analysis**: Pattern detection and error categorization
23
+ - ✅ **Structured Logging**: JSON metadata, trace IDs, span IDs
24
+ - ✅ **Auto-Migration**: Drizzle ORM with automatic schema migrations
25
+ - ✅ **Type-Safe**: Full TypeScript coverage with Drizzle schema inference
26
+
27
+ ## Architecture
28
+
29
+ ```
30
+ ┌─────────────┐ HTTP POST ┌─────────────────┐
31
+ │ Application │ ───────────────────────> │ HTTP Server │
32
+ │ (Pino, │ /logs endpoint │ (Hono) │
33
+ │ Winston) │ │ Port 3100 │
34
+ └─────────────┘ └────────┬────────┘
35
+
36
+
37
+ ┌─────────────────┐
38
+ │ LogStorage │
39
+ │ Service │
40
+ └────────┬────────┘
41
+
42
+
43
+ ┌──────────────┐ MCP Protocol ┌─────────────────┐
44
+ │ Claude / │ <─────────────────────> │ MCP Server │
45
+ │ AI Agent │ 7 Analysis Tools │ (stdio) │
46
+ └──────────────┘ └────────┬────────┘
47
+
48
+
49
+ ┌─────────────────┐
50
+ │ SQLite + FTS5 │
51
+ │ ./logs/ │
52
+ │ session.db │
53
+ └─────────────────┘
54
+ ```
55
+
56
+ ## Singleton HTTP Server Management
57
+
58
+ `log-sink-mcp` implements automatic singleton coordination to prevent port conflicts when multiple MCP servers run concurrently.
59
+
60
+ ### How It Works
61
+
62
+ 1. **Service Discovery**: When an MCP server starts, it checks `.agiflow/registry/log-sink-mcp-http_{env}.json` for an existing HTTP server
63
+ 2. **Health Check**: Pings `/health` endpoint to verify the registered server is alive
64
+ 3. **Reuse or Start**: If healthy, reuses existing server; otherwise starts a new one
65
+ 4. **PID Tracking**: Process IDs stored in `.pids/` for lifecycle management
66
+ 5. **Auto-Cleanup**: Registry and PID files removed on graceful shutdown
67
+
68
+ ### Service Registry Schema
69
+
70
+ ```json
71
+ {
72
+ "name": "log-sink-mcp-http",
73
+ "port": 3100,
74
+ "host": "localhost",
75
+ "environment": "development",
76
+ "pid": 12345,
77
+ "status": "running",
78
+ "startedAt": "2026-01-15T10:00:00.000Z",
79
+ "metadata": {
80
+ "healthCheckUrl": "http://localhost:3100/health",
81
+ "dbPath": "./logs/session.db"
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### Management Commands
87
+
88
+ ```bash
89
+ # Check status of HTTP server
90
+ bun run src/cli.ts status
91
+
92
+ # Stop HTTP server
93
+ bun run src/cli.ts stop
94
+
95
+ # Start with auto-coordination
96
+ bun run src/cli.ts start
97
+ ```
98
+
99
+ ## Installation
100
+
101
+ ```bash
102
+ # From monorepo root
103
+ pnpm install
104
+
105
+ # Or install globally
106
+ pnpm add -g log-sink-mcp
107
+ ```
108
+
109
+ ## Quick Start
110
+
111
+ ### 1. Start the Servers
112
+
113
+ ```bash
114
+ # Start both HTTP and MCP servers (recommended)
115
+ bun run src/cli.ts start
116
+
117
+ # Or start only HTTP server
118
+ bun run src/cli.ts start --http-only
119
+
120
+ # Or start only MCP server (stdio transport)
121
+ bun run src/cli.ts start --mcp-only
122
+
123
+ # With custom configuration
124
+ bun run src/cli.ts start --port 3100 --db-path ./logs/session.db
125
+ ```
126
+
127
+ The `start` command uses singleton pattern - multiple MCP servers will share a single HTTP server automatically.
128
+
129
+ ### 2. Configure MCP Server
130
+
131
+ Add to your `mcp-config.yaml`:
132
+
133
+ ```yaml
134
+ mcpServers:
135
+ log-sink:
136
+ type: stdio
137
+ command: bun
138
+ args:
139
+ - ./packages/log-sink-mcp/src/cli.ts
140
+ - mcp-serve
141
+ - --db-path
142
+ - ./logs/session.db
143
+ disabled: false
144
+ ```
145
+
146
+ ### 3. Send Logs
147
+
148
+ ```bash
149
+ # Send a test log
150
+ curl -X POST http://localhost:3100/logs \
151
+ -H "Content-Type: application/json" \
152
+ -d '{
153
+ "logs": [{
154
+ "level": "info",
155
+ "message": "Application started",
156
+ "service": "my-app",
157
+ "metadata": {"version": "1.0.0"}
158
+ }]
159
+ }'
160
+ ```
161
+
162
+ ### 4. Query with AI
163
+
164
+ Ask Claude:
165
+
166
+ > "Query all error logs from the database"
167
+ >
168
+ > "Show me the trace timeline for trace ID abc123"
169
+ >
170
+ > "Analyze error patterns in the logs"
171
+
172
+ ## HTTP API Reference
173
+
174
+ ### POST /logs
175
+
176
+ Ingest log entries in batch.
177
+
178
+ **Request Body:**
179
+
180
+ ```typescript
181
+ {
182
+ logs: Array<{
183
+ // Required fields
184
+ level: 'debug' | 'info' | 'warn' | 'error';
185
+ message: string;
186
+ service: string;
187
+
188
+ // Optional fields
189
+ timestamp?: string; // ISO 8601, defaults to now
190
+ traceId?: string; // 32-char hex for distributed tracing
191
+ spanId?: string; // 16-char hex for span identification
192
+ parentSpanId?: string; // 16-char hex for parent span
193
+ hostname?: string;
194
+ pid?: number;
195
+ metadata?: Record<string, any>;
196
+ errorType?: string;
197
+ errorMessage?: string;
198
+ errorStack?: string;
199
+ }>
200
+ }
201
+ ```
202
+
203
+ **Response (201 Created):**
204
+
205
+ ```json
206
+ {
207
+ "success": true,
208
+ "count": 5,
209
+ "message": "Successfully inserted 5 logs"
210
+ }
211
+ ```
212
+
213
+ **Response (400 Bad Request):**
214
+
215
+ ```json
216
+ {
217
+ "success": false,
218
+ "error": "Validation failed",
219
+ "details": [...]
220
+ }
221
+ ```
222
+
223
+ ### GET /health
224
+
225
+ Health check endpoint.
226
+
227
+ **Response (200 OK):**
228
+
229
+ ```json
230
+ {
231
+ "status": "healthy",
232
+ "service": "log-sink-mcp",
233
+ "timestamp": "2026-01-15T10:00:00.000Z"
234
+ }
235
+ ```
236
+
237
+ ## MCP Tools Reference
238
+
239
+ ### 1. `query_logs`
240
+
241
+ Filter logs by level, service, or trace ID.
242
+
243
+ **Parameters:**
244
+ - `level?`: string - Filter by log level (debug, info, warn, error)
245
+ - `service?`: string - Filter by service name
246
+ - `traceId?`: string - Filter by trace ID
247
+ - `limit?`: number - Maximum results (default: 100)
248
+
249
+ **Example:**
250
+ ```
251
+ Query all error logs from user-service
252
+ ```
253
+
254
+ **Returns:** JSON array of matching log entries with timestamps, messages, metadata.
255
+
256
+ ---
257
+
258
+ ### 2. `search_logs`
259
+
260
+ Full-text search across log messages and error messages.
261
+
262
+ **Parameters:**
263
+ - `searchQuery`: string (required) - Text to search for
264
+ - `limit?`: number - Maximum results (default: 50)
265
+
266
+ **Example:**
267
+ ```
268
+ Search logs for "database connection timeout"
269
+ ```
270
+
271
+ **Returns:** Matching logs with search relevance, count of results.
272
+
273
+ ---
274
+
275
+ ### 3. `get_trace_timeline`
276
+
277
+ Get chronological timeline for a distributed trace.
278
+
279
+ **Parameters:**
280
+ - `traceId`: string (required) - Trace ID to retrieve
281
+
282
+ **Example:**
283
+ ```
284
+ Show me the trace timeline for trace ID a1b2c3d4e5f6789012345678901234ab
285
+ ```
286
+
287
+ **Returns:** Ordered sequence of log entries for the trace, showing service call flow.
288
+
289
+ ---
290
+
291
+ ### 4. `analyze_errors`
292
+
293
+ Analyze error patterns and categorize by error type.
294
+
295
+ **Parameters:**
296
+ - `limit?`: number - Maximum errors to analyze (default: 100)
297
+
298
+ **Example:**
299
+ ```
300
+ Analyze error patterns in the logs
301
+ ```
302
+
303
+ **Returns:** Error categories, frequencies, example stack traces, common patterns.
304
+
305
+ ---
306
+
307
+ ### 5. `get_log_stats`
308
+
309
+ Get statistics grouped by log level.
310
+
311
+ **Parameters:** None
312
+
313
+ **Example:**
314
+ ```
315
+ Show me log statistics
316
+ ```
317
+
318
+ **Returns:** Count per log level (debug, info, warn, error), total count.
319
+
320
+ ---
321
+
322
+ ### 6. `get_services`
323
+
324
+ List all unique services that have logged.
325
+
326
+ **Parameters:** None
327
+
328
+ **Example:**
329
+ ```
330
+ What services are logging to the database?
331
+ ```
332
+
333
+ **Returns:** Array of service names with log counts.
334
+
335
+ ---
336
+
337
+ ### 7. `clear_logs`
338
+
339
+ Delete all logs from the database.
340
+
341
+ **Parameters:** None
342
+
343
+ **Example:**
344
+ ```
345
+ Clear all logs from the database
346
+ ```
347
+
348
+ **Returns:** Confirmation with count of deleted entries.
349
+
350
+ ⚠️ **Warning:** This operation cannot be undone.
351
+
352
+ ## Integration Examples
353
+
354
+ ### Pino Logger
355
+
356
+ ```typescript
357
+ import pino from 'pino';
358
+
359
+ const logger = pino({
360
+ transport: {
361
+ target: 'pino-http-send',
362
+ options: {
363
+ url: 'http://localhost:3100/logs',
364
+ method: 'POST',
365
+ },
366
+ },
367
+ });
368
+
369
+ logger.info({ traceId: 'abc123', userId: '456' }, 'User logged in');
370
+ ```
371
+
372
+ ### Winston Logger
373
+
374
+ ```typescript
375
+ import winston from 'winston';
376
+
377
+ const logger = winston.createLogger({
378
+ transports: [
379
+ new winston.transports.Http({
380
+ host: 'localhost',
381
+ port: 3100,
382
+ path: '/logs',
383
+ }),
384
+ ],
385
+ });
386
+
387
+ logger.error('Database connection failed', {
388
+ service: 'api',
389
+ errorType: 'ConnectionError'
390
+ });
391
+ ```
392
+
393
+ ### Custom Fetch
394
+
395
+ ```typescript
396
+ async function sendLog(level: string, message: string, metadata?: any) {
397
+ await fetch('http://localhost:3100/logs', {
398
+ method: 'POST',
399
+ headers: { 'Content-Type': 'application/json' },
400
+ body: JSON.stringify({
401
+ logs: [{
402
+ level,
403
+ message,
404
+ service: 'my-service',
405
+ metadata,
406
+ timestamp: new Date().toISOString(),
407
+ }],
408
+ }),
409
+ });
410
+ }
411
+
412
+ await sendLog('info', 'Request processed', { duration: 245, status: 200 });
413
+ ```
414
+
415
+ ## Configuration
416
+
417
+ ### CLI Options
418
+
419
+ #### `start` command (Recommended)
420
+
421
+ Start HTTP and/or MCP servers with automatic singleton coordination.
422
+
423
+ ```bash
424
+ bun run src/cli.ts start [options]
425
+ ```
426
+
427
+ Options:
428
+ - `--port <number>`: HTTP server port (default: 3100)
429
+ - `--db-path <path>`: SQLite database path (default: ./logs/session.db)
430
+ - `--in-memory`: Use in-memory database for testing (default: false)
431
+ - `--http-only`: Start only the HTTP server
432
+ - `--mcp-only`: Start only the MCP server (stdio transport)
433
+
434
+ Examples:
435
+ ```bash
436
+ # Start both servers with defaults
437
+ bun run src/cli.ts start
438
+
439
+ # Production mode with persistent database
440
+ bun run src/cli.ts start --port 3100 --db-path ./logs/production.db
441
+
442
+ # Testing with in-memory database
443
+ bun run src/cli.ts start --in-memory
444
+ ```
445
+
446
+ #### `status` command
447
+
448
+ Show diagnostic information about running services.
449
+
450
+ ```bash
451
+ bun run src/cli.ts status
452
+ ```
453
+
454
+ Displays:
455
+ - HTTP server status (running/stopped)
456
+ - Process ID and port
457
+ - Database file path and size
458
+ - Health check URL
459
+
460
+ #### `stop` command
461
+
462
+ Gracefully stop HTTP server and cleanup registry/PID files.
463
+
464
+ ```bash
465
+ bun run src/cli.ts stop
466
+ ```
467
+
468
+ Behavior:
469
+ - Sends SIGTERM to HTTP server process
470
+ - Removes `.agiflow/registry/` entries
471
+ - Cleans up `.pids/` files
472
+
473
+ #### `http-serve` command
474
+
475
+ Manually start HTTP log ingestion server (for advanced use).
476
+
477
+ ```bash
478
+ bun run src/cli.ts http-serve [options]
479
+ ```
480
+
481
+ Options:
482
+ - `--port <number>`: HTTP server port (default: 3000)
483
+ - `--db-path <path>`: SQLite database path (default: ./logs.db)
484
+ - `--in-memory`: Use in-memory database (default: false)
485
+
486
+ **Note:** Prefer using `start` command for automatic singleton coordination.
487
+
488
+ #### `mcp-serve` command
489
+
490
+ Manually start MCP server (for advanced use or custom transports).
491
+
492
+ ```bash
493
+ bun run src/cli.ts mcp-serve [options]
494
+ ```
495
+
496
+ Options:
497
+ - `--type <type>`: Transport type: stdio, http, or sse (default: stdio)
498
+ - `--port <number>`: Port for http/sse transport (default: 3000)
499
+ - `--host <host>`: Host for http/sse transport (default: localhost)
500
+ - `--db-path <path>`: SQLite database path (default: ./logs/session.db)
501
+ - `--in-memory`: Use in-memory database (default: false)
502
+ - `--cleanup`: Stop HTTP server on MCP shutdown (stdio only, default: false)
503
+
504
+ Examples:
505
+ ```bash
506
+ # stdio transport (for Claude Desktop)
507
+ bun run src/cli.ts mcp-serve --type stdio
508
+
509
+ # HTTP transport
510
+ bun run src/cli.ts mcp-serve --type http --port 3001
511
+
512
+ # SSE transport
513
+ bun run src/cli.ts mcp-serve --type sse --port 3002
514
+ ```
515
+
516
+ **Note:** For stdio transport, prefer using `start --mcp-only` for automatic HTTP coordination.
517
+
518
+ #### `logs` command
519
+
520
+ Run the same analysis capabilities exposed by the package MCP tools directly from the shell.
521
+
522
+ ```bash
523
+ bun run src/cli.ts logs <subcommand> [options]
524
+ ```
525
+
526
+ Subcommands:
527
+ - `query`: Equivalent to `query_logs`
528
+ - `search`: Equivalent to `search_logs`
529
+ - `trace`: Equivalent to `get_trace_timeline`
530
+ - `analyze-errors`: Equivalent to `analyze_errors`
531
+ - `stats`: Equivalent to `get_log_stats`
532
+ - `services`: Equivalent to `get_services`
533
+ - `clear`: Equivalent to `clear_logs`
534
+
535
+ All subcommands support:
536
+ - `--db-path <path>`: SQLite database path (default: `./logs/session.db`)
537
+ - `--in-memory`: Use an in-memory database
538
+
539
+ Examples:
540
+
541
+ ```bash
542
+ # Query error logs
543
+ bun run src/cli.ts logs query --level error --db-path ./logs/session.db
544
+
545
+ # Search for timeout failures
546
+ bun run src/cli.ts logs search "timeout OR retry" --service api-gateway user-service
547
+
548
+ # Inspect one trace
549
+ bun run src/cli.ts logs trace a1b2c3d4e5f6789012345678901234ab
550
+
551
+ # Analyze grouped errors in a time window
552
+ bun run src/cli.ts logs analyze-errors \
553
+ --start-time 2026-01-15T10:00:00Z \
554
+ --end-time 2026-01-15T11:00:00Z
555
+
556
+ # View service names discovered in the log database
557
+ bun run src/cli.ts logs services
558
+ ```
559
+
560
+ ### Environment Variables
561
+
562
+ None required. All configuration via CLI flags.
563
+
564
+ ## Development
565
+
566
+ ### Setup
567
+
568
+ ```bash
569
+ # Install dependencies
570
+ pnpm install
571
+
572
+ # Run development server
573
+ pnpm dev
574
+
575
+ # Run HTTP server in dev mode
576
+ bun run src/cli.ts http-serve --port 3100
577
+ ```
578
+
579
+ ### Project Structure
580
+
581
+ ```
582
+ log-sink-mcp/
583
+ ├── src/
584
+ │ ├── cli.ts # CLI entry point
585
+ │ ├── commands/ # CLI commands
586
+ │ │ ├── http-serve.ts # HTTP server command
587
+ │ │ └── mcp-serve.ts # MCP server command
588
+ │ ├── container/ # InversifyJS DI container
589
+ │ ├── models/ # Drizzle schemas
590
+ │ │ └── schema.ts # Log table schema
591
+ │ ├── server/
592
+ │ │ ├── http.ts # Hono HTTP server
593
+ │ │ └── index.ts # MCP server
594
+ │ ├── services/ # Business logic
595
+ │ │ ├── LogStorageService.ts
596
+ │ │ ├── LogQueryService.ts
597
+ │ │ ├── LogSearchService.ts
598
+ │ │ └── LogRetentionService.ts
599
+ │ ├── tools/ # MCP tools
600
+ │ │ ├── QueryLogsTool.ts
601
+ │ │ ├── SearchLogsTool.ts
602
+ │ │ ├── GetTraceTimelineTool.ts
603
+ │ │ ├── AnalyzeErrorsTool.ts
604
+ │ │ ├── GetLogStatsTool.ts
605
+ │ │ ├── GetServicesTool.ts
606
+ │ │ └── ClearLogsTool.ts
607
+ │ └── types/ # TypeScript types
608
+ ├── migrations/ # Drizzle migrations
609
+ ├── tests/
610
+ │ ├── integration/ # Integration tests
611
+ │ ├── services/ # Service unit tests
612
+ │ ├── tools/ # Tool unit tests
613
+ │ └── commands/ # Command tests
614
+ └── README.md
615
+ ```
616
+
617
+ ### Testing
618
+
619
+ ```bash
620
+ # Run all tests
621
+ pnpm test
622
+
623
+ # Run integration tests only
624
+ pnpm test integration
625
+
626
+ # Run with coverage
627
+ pnpm test --coverage
628
+ ```
629
+
630
+ **Test Coverage:**
631
+ - HTTP server integration tests (8 tests)
632
+ - MCP tools integration tests (17 tests)
633
+ - Command tests (5 tests)
634
+
635
+ ### Adding New Tools
636
+
637
+ 1. Create tool class in `src/tools/`
638
+ 2. Implement `Tool` interface with `getDefinition()` and `execute()`
639
+ 3. Register in `src/server/index.ts`
640
+ 4. Add integration tests in `tests/integration/`
641
+
642
+ See existing tools for patterns.
643
+
644
+ ## Troubleshooting
645
+
646
+ ### Check Service Status
647
+
648
+ Use the `status` command to diagnose issues:
649
+
650
+ ```bash
651
+ bun run src/cli.ts status
652
+ ```
653
+
654
+ This shows:
655
+ - Whether HTTP server is running
656
+ - Process ID and port
657
+ - Database path and size
658
+ - Health check URL
659
+
660
+ ### Logs not appearing
661
+
662
+ 1. Check HTTP server is running:
663
+ ```bash
664
+ # Using status command
665
+ bun run src/cli.ts status
666
+
667
+ # Or direct health check
668
+ curl http://localhost:3100/health
669
+ ```
670
+
671
+ 2. Verify log format matches API schema
672
+ 3. Check database path is accessible
673
+ 4. Review HTTP server logs for errors
674
+
675
+ ### MCP tools not working
676
+
677
+ 1. Verify database file exists and has logs:
678
+ ```bash
679
+ bun run src/cli.ts status
680
+ ```
681
+
682
+ 2. Check `--db-path` matches between HTTP and MCP servers
683
+ 3. Restart MCP server after configuration changes:
684
+ ```bash
685
+ bun run src/cli.ts stop
686
+ bun run src/cli.ts start
687
+ ```
688
+
689
+ ### Database locked errors
690
+
691
+ SQLite uses WAL mode for better concurrency, but:
692
+ - Don't run multiple HTTP servers on same database
693
+ - Ensure file permissions allow writes
694
+ - Use separate databases for testing
695
+
696
+ ### Finding and Killing HTTP Server
697
+
698
+ If you need to manually stop the HTTP server:
699
+
700
+ ```bash
701
+ # Graceful stop (recommended)
702
+ bun run src/cli.ts stop
703
+
704
+ # Find process manually
705
+ cat .pids/log-sink-mcp-http-development.pid
706
+
707
+ # Kill process (if graceful stop fails)
708
+ kill $(cat .pids/log-sink-mcp-http-development.pid)
709
+
710
+ # Force kill (last resort)
711
+ kill -9 $(cat .pids/log-sink-mcp-http-development.pid)
712
+ ```
713
+
714
+ ### Stale Registry Entries
715
+
716
+ If the registry file exists but server isn't running:
717
+
718
+ ```bash
719
+ # Clean up stale registry
720
+ rm .agiflow/registry/log-sink-mcp-http_development.json
721
+ rm .pids/log-sink-mcp-http-development.pid
722
+
723
+ # Restart
724
+ bun run src/cli.ts start
725
+ ```
726
+
727
+ The health check will automatically detect stale registries and start a new server.
728
+
729
+ ### Port Already in Use
730
+
731
+ If port 3100 is already taken:
732
+
733
+ ```bash
734
+ # Use different port
735
+ bun run src/cli.ts start --port 3101
736
+
737
+ # Or find what's using the port
738
+ lsof -i :3100
739
+
740
+ # Kill the process using the port
741
+ kill $(lsof -t -i :3100)
742
+ ```
743
+
744
+ ## License
745
+
746
+ MIT
747
+
748
+ ## Contributing
749
+
750
+ This package is part of the Agiflow monorepo. Contributions welcome!
751
+
752
+ 1. Follow coding standards in `/docs/CODING_STANDARDS.md`
753
+ 2. Use architect MCP before modifying code
754
+ 3. Add tests for new features
755
+ 4. Run `pnpm test` before committing