Multi-Container Log Correlator MCP Server

Multi-Container Log Correlator MCP Server

Enables debugging of distributed transactions by continuously ingesting Docker container logs, indexing them by trace/request ID, and exposing MCP tools to search, tail, and correlate logs across services.

Category
访问服务器

README

Multi-Container Log Correlator MCP Server

An MCP (Model Context Protocol) server that continuously ingests logs from all running Docker containers, indexes them by trace/request ID, and exposes a clean tools so an LLM can debug distributed transactions without ever switching terminal windows.


How it works

Docker daemon
  Windows  →  //./pipe/docker_engine  (named pipe, auto-detected)
  Linux/Mac →  /var/run/docker.sock   (Unix socket, auto-detected)
  Custom   →  DOCKER_HOST=tcp://...   (TCP via env var)
        │  (multiplexed stdout/stderr streams)
        ▼
  DockerLogWatcher  ──►  LogParser  ──►  TraceIndexedRingBuffer
  (per-container)         (zero-copy         (10 000 lines/container +
   log streams)            parsing)           O(1) trace_id index)
                                                      │
                                                      ▼
                                            MCP stdio transport
                                                      │
                                                      ▼
                                              LLM tool calls

The ring buffer retains the last 10 000 log lines per container. A secondary Map<traceId, Set<slotKey>> index lets search_by_trace_id resolve cross-service timelines in O(1) time regardless of buffer size.


Exposed MCP Tools

The server exposes 7 tools. Use them in the order shown below for a typical debugging session start with topology, narrow to errors, then correlate by trace ID.


1. list_active_containers

Lists all Docker containers currently being monitored by the server.

Use this first to understand the service topology before calling any other tool it tells you the exact service names you will need to pass as arguments.

Argument Type Required Description
project_name string No Filter by Docker Compose project name. Omit to list all running containers.

Returns: Service name, short container ID (12-char), Docker image, running status, and Compose project for each container.

Example:

list_active_containers()
→ api-gateway      (id: a1b2c3d4e5f6, image: nginx:latest,   Up 3 hours)
→ checkout-worker  (id: b2c3d4e5f6a1, image: node:20,        Up 3 hours)
→ inventory-db     (id: c3d4e5f6a1b2, image: postgres:16,    Up 3 hours)

2. search_by_trace_id — Primary debug tool

The core power tool. Takes a trace/request/correlation ID and returns a chronologically merged timeline of every log event across all containers that share that ID resolved in O(1) time using the in-memory trace index.

This is the tool that turns a 500 error into a root cause in seconds. A single call spans every service that touched the request.

Argument Type Required Description
trace_id string Yes The correlation ID to search for e.g. req-998877, a W3C traceparent hex, or an X-Request-ID value.
limit number No Maximum log events to return. Default 200, max 500.

Returns: A merged, chronologically sorted list of log lines from all services that logged this trace ID, including the service name, timestamp, log level, and full message for each event.

Example:

search_by_trace_id({ trace_id: "req-998877" })
→ 14:03:21.001  [api-gateway]      INFO   POST /checkout received
→ 14:03:21.045  [checkout-worker]  INFO   Reserving 2x item #42
→ 14:03:22.100  [inventory-db]     ERROR  Deadlock detected on stock_reservations
→ 14:03:22.441  [checkout-worker]  ERROR  DB timeout after 1400ms
→ 14:03:22.443  [api-gateway]      ERROR  Responding 500 to client

3. tail_service_errors

Retrieves the most recent ERROR and FATAL log lines from a specific container. The fastest way to find an initial failure point when you do not yet have a trace ID grab the error, extract its trace ID, then pass it to search_by_trace_id.

Argument Type Required Description
service_name string Yes Docker container name or Compose service name (e.g. checkout-worker).
limit number No Number of most-recent error lines to return. Default 50, max 500.
include_warnings boolean No Also include WARN-level lines alongside errors. Default false.

Returns: The N most-recent ERROR/FATAL (and optionally WARN) log lines from the named service in chronological order.

Detected levels: FATAL, CRITICAL, ERROR and optionally WARN / WARNING.

Example:

tail_service_errors({ service_name: "checkout-worker", limit: 10, include_warnings: true })
→ 14:03:22.441  ERROR  DB timeout after 1400ms trace_id=req-998877
→ 14:03:19.100  WARN   Slow query detected (980ms) trace_id=req-998800

4. tail_service_logs

Retrieves the N most-recent log lines from a specific container with optional level filtering. Use this to get general context around a service see what it was doing before or after an event without restricting to errors only.

Argument Type Required Description
service_name string Yes Docker container name or Compose service name.
limit number No Number of most-recent lines to return. Default 100, max 500.
level_filter string[] No Restrict to specific levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN. Omit for all levels.

Returns: The most-recent matching log lines in chronological order with timestamp, service name, level, and message.

Example:

tail_service_logs({ service_name: "api-gateway", limit: 50, level_filter: ["INFO", "ERROR"] })
→ Returns the last 50 INFO and ERROR lines from api-gateway

5. search_logs

Case-insensitive full-text search across the buffered log lines of one or all containers. Useful when you know part of an error message but not which service threw it, or when hunting for a specific SQL query, function name, or stack trace snippet that does not carry a trace ID.

Argument Type Required Description
query string Yes Case-insensitive substring to match against log messages (e.g. "connection refused", "NullPointerException").
service_name string No Restrict search to one container. Omit to search all containers simultaneously.
limit number No Maximum matching lines to return. Default 100, max 500.
level_filter string[] No Restrict results to specific log levels.

Returns: All matching log lines in chronological order annotated with service name, timestamp, and level. Indicates when results are truncated.

Example:

search_logs({ query: "connection refused", limit: 20 })
→ Finds every "connection refused" line across all running containers

6. get_container_stats

Returns buffer statistics for one or all containers at a glance: total lines buffered, error/warn counts, a sample of known trace IDs, and the oldest/newest log timestamps. Useful for a quick system health overview or to verify the buffer is actively filling with live data.

Argument Type Required Description
service_name string No A specific container to inspect. Omit to get stats for all running containers.

Returns per container:

  • Lines buffered (ring buffer holds up to 10,000 lines per container)
  • Error count and warning count
  • Oldest and newest log timestamps in the buffer
  • Sample of known trace IDs seen in that container's logs

Example:

get_container_stats()
→ checkout-worker:  4,821 lines | Errors: 12 | Warnings: 34 | Traces: req-998877, req-998800 …
→ inventory-db:     2,103 lines | Errors: 3  | Warnings: 1  | Traces: req-998877 …
→ api-gateway:      9,441 lines | Errors: 12 | Warnings: 89 | Traces: req-998877, req-998800 …

7. list_trace_ids

Lists all trace/request IDs currently held in the in-memory buffer. Use this when a user reports "something went wrong" with no trace ID browse the available IDs, pick the one closest to the reported time, and feed it directly into search_by_trace_id.

Argument Type Required Description
service_name string No Only list trace IDs seen in this specific service. Omit for all services.
limit number No Maximum number of trace IDs to return. Default 50, max 1000.

Returns: A numbered list of trace ID strings currently in the buffer.

Example:

list_trace_ids({ service_name: "checkout-worker", limit: 5 })
→ 1. req-998877
→ 2. req-998800
→ 3. req-998741
→ 4. req-998603
→ 5. req-998512

Trace ID Detection

The parser automatically extracts trace identifiers from:

  • JSON fields: trace_id, traceId
  • W3C traceparent header values embedded in logs
  • X-Request-ID, X-Trace-ID, requestid, request_id key-value pairs
  • req-XXXXX style short IDs (common in Node.js / Express apps)
  • OpenTelemetry trace_id=<hex32> fields
  • OpenTelemetry span_id / spanId for span-level correlation

Prerequisites

  • Node.js 18+
  • Docker running locally (or accessible socket)
  • Windows: Docker Desktop running uses //./pipe/docker_engine automatically
  • Linux/Mac: Read access to /var/run/docker.sock

Installation & Usage

npm install
node index.js

Environment variables

The server auto-detects the Docker connection for your platform no configuration needed in most cases.

Variable Default Description
DOCKER_HOST (auto) Override with tcp://localhost:2375 for TCP mode (useful on Windows if named pipe access is blocked)
DOCKER_SOCKET_PATH /var/run/docker.sock Linux/Mac only override the Unix socket path

Windows tip: If the server cannot find containers, enable "Expose daemon on tcp://localhost:2375" in Docker Desktop → Settings → General, then set DOCKER_HOST=tcp://localhost:2375 in your MCP config (see below).


Claude Desktop / Cursor config

Add this to your claude_desktop_config.json:

Config file location

  • Windows: C:\Users\<you>\AppData\Roaming\Claude\claude_desktop_config.json
  • Mac: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Linux / Mac

{
  "mcpServers": {
    "multi-container-log-correlator-mcp-server": {
      "command": "node",
      "args": ["/absolute/path/to/multi-container-log-correlator-mcp-server/index.js"]
    }
  }
}

Windows (named pipe works out of the box with Docker Desktop)

{
  "mcpServers": {
    "multi-container-log-correlator-mcp-server": {
      "command": "node",
      "args": ["C:\\path\\to\\multi-container-log-correlator-mcp-server\\index.js"]
    }
  }
}

Windows (TCP fallback if named pipe does not work, enable TCP in Docker Desktop → Settings → General first)

{
  "mcpServers": {
    "multi-container-log-correlator-mcp-server": {
      "command": "node",
      "args": ["C:\\path\\to\\multi-container-log-correlator-mcp-server\\index.js"],
      "env": {
        "DOCKER_HOST": "tcp://localhost:2375"
      }
    }
  }
}

Typical debugging session

User: "The frontend is throwing a 500 error on checkout. Trace ID is req-998877. What happened?"

LLM:
  1. list_active_containers()             → sees api-gateway, checkout-worker, inventory-db
  2. search_by_trace_id("req-998877")     → gets merged timeline across all 3 services
  3. Reads the timeline, spots the DB deadlock in inventory-db at 14:03:22.441
  4. Reports: "inventory-db hit a deadlock on the stock reservation table,
     which caused checkout-worker to time out, propagating a 500 to api-gateway."

Project structure

src/
├── constants.js              # Buffer sizes, regex patterns, socket path
├── services/
│   ├── ringBuffer.js         # TraceIndexedRingBuffer (core data structure)
│   ├── dockerClient.js       # DockerLogWatcher streams from daemon
│   ├── logParser.js          # Stateless line parser (timestamps, levels, trace IDs)
│   └── formatter.js          # Human-readable output helpers
├── schemas/
│   └── toolSchemas.js        # Zod input schemas for every MCP tool
└── tools/
    └── containerTools.js     # All 7 MCP tool registrations
── index.js                  # Entry point wires everything together

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选