LogLens

LogLens

Enables log analysis through MCP tools for searching logs, retrieving error contexts, and summarizing incidents with self-verified root-cause hypotheses.

Category
访问服务器

README

LogLens

An MCP (Model Context Protocol) server for log analysis. Instead of pasting a log file into a chat and asking an LLM to debug it, LogLens exposes log search, context retrieval, and incident summarization as tools that any MCP-compatible client (Claude Desktop, Claude Code, or your own agent) can call directly — with targeted retrieval instead of context-stuffing, and a self-verification step to catch unsupported root-cause claims before they're returned.

Why this exists

Built as a public, portfolio version of an AI-powered log analyzer that won 1st place at an internal hackathon. Short version of why this beats paste-into-chat: production logs don't fit in a context window, a chat-paste isn't callable by other systems, and raw prompting has no mechanism to check whether the model's answer is actually grounded in the log data.

Status

  • Core server, 3 tools — working end-to-end against a sample log. ✅
  • LLM-based root-cause generation with a hallucination-verification loop that checks the hypothesis on two independent axes and retries once if it fails either. ✅
  • Mixed-provider architecture (Groq + Gemini) — the verifier runs on a different model family than the generator, so the check doesn't share the generator's blind spots. ✅
  • 8-case eval suite, deterministic scoring, 8/8 passing. ✅
  • Dockerized, runs as a network-reachable HTTP server, verified end-to-end against a live container. ✅
  • Next: cloud deployment (Azure Container Apps or similar), a demo GIF.

Tools

Tool What it does
search_logs Keyword search over the log file; returns matches with surrounding context and a line id.
get_error_context Given a line id, returns a wider window of lines — full stack traces, sequence of events.
summarize_incident Extracts search terms from a natural-language question, retrieves evidence (lexical + time-window + global-anomaly expansion), generates a root-cause hypothesis, then independently verifies it on two axes — retrying once if the verifier rejects it.

Architecture

Question ──▶ extract search terms (Groq, gpt-oss-20b)
                 │
                 ▼
         search_logs (lexical match)
                 │
                 ▼
    + time-window expansion (asymmetric: 900s before / 180s after —
      causes precede symptoms)
                 │
                 ▼
    + global anomaly scan (all WARN/ERROR lines, not just in-window —
      the explaining line is often itself a warning)
                 │
                 ▼
       generate hypothesis (Groq, gpt-oss-120b)
                 │
                 ▼
    verify: soundness + completeness (Gemini — DIFFERENT provider
    from the generator, on purpose; falls back to same-provider
    Groq if Gemini is unavailable, and reports which happened)
                 │
          unsound/incomplete? ──▶ regenerate once, feeding back
                 │                the lines the first pass overlooked
                 ▼
              answer

Two providers, deliberately — not just a cost workaround

Groq carries extraction and hypothesis generation; Gemini carries verification. This started as a quota workaround (Gemini's free tier caps at 20 requests/day; Groq's is far more generous) but turned into a real architectural improvement: a verifier running on the same model that produced a claim shares that model's blind spots. Checking the claim with a different model family makes the hallucination check genuinely independent, not just a second opinion from the same source. Verification.independent reports whether a given answer actually got the cross-provider check or fell back to same-provider (Gemini down/unconfigured) — surfaced, not hidden.

The cross-service retrieval gap — found via testing, fixed at the right layer

Early testing surfaced a real limitation: summarize_incident found the immediate cause of a checkout failure (DB pool exhaustion) but missed the upstream cause the sample log also encodes — a long-running query on a different service holding the connection. Two structural problems:

  • Retrieval was purely lexical. Extracted terms were checkout-scoped, so inventory-service lines could never enter the evidence set no matter how good the reasoning was. Fixed with time-window expansion, asymmetric on purpose (900s before / 180s after) — causes precede symptoms, often by more than a short symmetric window would catch — plus a global scan for anomalous (WARN/ERROR) lines regardless of window, since the explaining line is often itself a warning ("NTP sync failed", "rotation skipped").
  • The verifier could only rubber-stamp. It originally saw only the lines a claim cited, which made it structurally incapable of noticing an incomplete answer — a claim describing a symptom will always look supported by the lines it chose to cite. It now sees the full evidence set and scores soundness and completeness independently; a sound-but- incomplete verdict feeds the overlooked lines back into regeneration.

Eval suite

npx tsx evals/run-evals.ts          # all 8 cases
npx tsx evals/run-evals.ts 03 08    # a subset, by id substring

8 cases spanning distinct failure archetypes: cross-service resource contention, unbounded-cache OOM, retry-storm amplification, a bad deploy, two compounding causes, a single-bad-node clock skew, a healthy log (correct answer is "nothing failed"), and a loud-symptom-masking-subtle-cause case built specifically to exercise the completeness axis. Scoring is deterministic — concept groups with synonyms, plus required evidence citations, no LLM judge — so runs are reproducible. The report separates retrieval misses (evidence never reached the model) from reasoning misses (evidence was there, answer still wrong), since those need different fixes.

Current result: 8/8 passing, 0 retrieval misses, 0 reasoning misses.

Debugging this suite is itself a decent engineering story: an asymmetric time window and a global anomaly scan fixed real retrieval brittleness; on Groq's free tier, max_tokens is a reservation against a per-minute token budget, not a pay-for-what-you-use ceiling — an oversized value gets a 413 regardless of actual prompt size; reasoning_effort: "low" was needed on the gpt-oss models, which otherwise spend the budget on reasoning tokens and truncate before emitting valid JSON; and the harness itself had two scoring bugs (Unicode punctuation variants, then a plain-space variant of the same compound identifier) that reported correct answers as failures — worth knowing when you write your own eval harness: it needs debugging too.

Docker

docker build -t loglens:local .
docker run -d -p 3000:3000 \
  -e GROQ_API_KEY=your-key \
  -e GEMINI_API_KEY=your-key \
  loglens:local
curl http://localhost:3000/health

Multi-stage build (compile with devDependencies, run with production-only deps + a non-root user + a container healthcheck on /health). The container runs the HTTP transport (MCP_TRANSPORT=http, set by default in the image) rather than stdio, since a deployed container has no parent process to spawn it locally the way Claude Desktop/Code do.

Real bug found and fixed while wiring this up, worth knowing if you build your own stateless streamable-HTTP MCP server: the SDK's stateless mode requires a fresh transport per request — reusing one transport across requests silently 500s every request after the first, with no thrown exception to catch. Separately, a single McpServer can only be connected to one transport at a time ("Already connected to a transport"). The fix (see createServer() and the HTTP handler in src/index.ts) creates both a fresh McpServer and a fresh StreamableHTTPServerTransport per request — cheap, since the server only holds tool definitions, no per-connection state (none of these tools carry state between calls anyway). Verified against a real running container: search_logs and a full summarize_incident pass both completed correctly end-to-end after the fix.

Environment variables

Variable Required for Notes
GROQ_API_KEY summarize_incident (extraction + hypothesis) Get one free at console.groq.com/keys. search_logs and get_error_context work without it.
GEMINI_API_KEY independent verification Get one free at aistudio.google.com/apikey. Without it, verification falls back to same-provider (Groq) and is no longer independent — reported via Verification.independent, not silently downgraded.
LOGLENS_LOG_FILE optional Point at a real log file instead of the bundled sample.
MCP_TRANSPORT optional http runs the network-reachable server (used by Docker); unset/anything else runs stdio (used by Claude Desktop/Code).
PORT optional HTTP port, default 3000.

Setup

npm install
npm run build

By default the server reads fixtures/sample.log, a synthetic incident (a long-running unindexed query on inventory-service exhausts a shared DB connection pool, cascading into checkout-service failures). Point it at a real log file instead with:

LOGLENS_LOG_FILE=/path/to/real.log node dist/index.js

Smoke tests (no MCP client needed)

npx tsx scripts/smoke-test.ts                              # stdio transport
npx tsx scripts/smoke-test-http.ts http://localhost:3000/mcp  # HTTP transport

Spawns (or connects to) the server and calls all three tools — useful for verifying it works before wiring up a real client. A full summarize_incident pass is 3-4 sequential LLM calls and can take 30-90s; pass a generous timeout if calling it programmatically (both scripts do).

Connect to Claude Desktop

Edit %APPDATA%\Claude\claude_desktop_config.json (Windows) and add:

{
  "mcpServers": {
    "loglens": {
      "command": "node",
      "args": ["C:\\Users\\sarve\\OneDrive\\Desktop\\LogLens\\dist\\index.js"],
      "env": {
        "GROQ_API_KEY": "your-groq-key",
        "GEMINI_API_KEY": "your-gemini-key"
      }
    }
  }
}

The env block is required, not optional — MCP clients spawn the server with a sanitized environment by default, not your shell's full environment, so the keys won't be visible to summarize_incident without it even if set globally on your machine.

Restart Claude Desktop, then ask it something like "search the logs for 'pool exhausted'" — it should call search_logs automatically.

Connect to Claude Code

claude mcp add loglens --scope user --env GROQ_API_KEY=your-groq-key --env GEMINI_API_KEY=your-gemini-key -- node C:\Users\sarve\OneDrive\Desktop\LogLens\dist\index.js

(Same reason as above — --env passes the keys explicitly since the spawned process doesn't inherit your shell environment by default.)

Project structure

src/
  index.ts       MCP server (dual transport: stdio + HTTP) + tool registration
  logParser.ts   log loading, search, time-window expansion, anomaly scan
  summarize.ts   the summarize_incident pipeline: extract -> retrieve -> hypothesize -> verify -> retry
  providers.ts   Groq + Gemini clients, model config, schema-constrained JSON generation
fixtures/
  sample.log     synthetic incident for local testing
evals/
  cases.ts       8 eval case definitions
  run-evals.ts   deterministic scoring harness
  logs/          synthetic logs for eval cases 02-08
scripts/
  smoke-test.ts       stdio transport smoke test
  smoke-test-http.ts  HTTP transport smoke test
Dockerfile       multi-stage build, non-root user, container healthcheck

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选