Logpond
TUI log viewer with built-in MCP server for AI agents
Ask AI about Logpond
Powered by Claude Β· Grounded in docs
I know everything about Logpond. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
logpond
A lightweight TUI log viewer with a built-in MCP server. Pipe JSON logs in, get a searchable terminal UI and an AI-queryable endpoint out.
your-app 2>&1 | logpond --config ./config.yaml
Features
- TUI β Column-based log viewer with live scrolling, search, and copy
- MCP Server β AI agents query your logs via
stats,search_logs,tail,get_schema - Hub β Auto-spawning aggregator discovers all running instances, one MCP endpoint for all services
- Config-driven β YAML defines columns, field mappings, and MCP behavior
- JSON + logfmt β Supports structured JSON and key=value logfmt formats
- Ring buffer β Fixed-capacity circular buffer (default 50k entries), zero-copy iteration
- Cross-platform β macOS and Linux, clipboard support on both
Install
Homebrew (macOS/Linux)
brew tap lodibrahim/tap
brew install logpond
Go
go install github.com/lodibrahim/logpond/cmd/logpond@latest
Binary
Download from GitHub Releases.
Quick Start
1. Create a config
# config.yaml
name: my-app
type: json
mapping:
timestamp:
field: ts
severity:
field: level
body:
field: msg
columns:
- name: Time
source: timestamp
format: time_short
width: 8
- name: Level
source: severity
width: 5
- name: Message
source: body
flex: true
2. Pipe your logs
my-app 2>&1 | logpond --config ./config.yaml
The first instance auto-spawns the hub on port 9800. No extra setup.
3. Use the TUI
| Key | Action |
|---|---|
j / k | Scroll down / up |
G / g | Jump to bottom / top |
/ | Live search (filters as you type) |
Esc | Clear search |
y | Copy visible entries to clipboard |
c | Clear all logs |
q | Quit |
Mouse wheel scrolling is also supported.
4. Connect your AI agent
Point your AI agent at the hub (not the individual instance):
// .mcp.json (Claude Code)
{
"mcpServers": {
"logpond": {
"type": "http",
"url": "http://localhost:9800/mcp"
}
}
}
The hub discovers all running logpond instances automatically. Start more services, they appear. Stop them, they disappear.
Hub
The hub is an MCP aggregator that sits in front of all logpond instances.
How it works
- First logpond instance checks if port 9800 is open
- If not, spawns
logpond hubas a detached background process - Each instance registers itself in
~/.logpond/<name>-<pid>.json - Hub discovers instances on every query (no polling)
- Hub persists across instance restarts β start/stop services freely
Note: The hub must be running before the MCP client (e.g. Claude Code) connects. If you start the client first, run any logpond instance to auto-spawn the hub, then restart the client.
Hub tools
All tools fan out to every live instance and merge results:
list_instancesβ show all discovered instances with statusstatsβ merged severity breakdown, field values, time range per instancesearch_logsβ search across all instances, results interleaved by timestampget_schemaβ all instance schemas and contexts in one calltailβ last N entries merged across all instances
Use the instance parameter on search_logs and tail to target a specific service.
Manual hub
The hub is normally auto-spawned, but you can start it manually:
logpond hub # default port 9800
logpond hub --port 9900 # custom port
Instance MCP Tools
Each logpond instance also exposes its own MCP endpoint (default port 9876):
stats
Quick overview β total entries, severity breakdown, active field values, time range.
{
"instance": "my-app",
"total_entries": 1731,
"time_range": { "oldest": "...", "newest": "..." },
"severity": { "INFO": 1365, "WARN": 50, "DEBUG": 316 },
"fields": {
"component": [{ "value": "engine", "count": 578 }]
}
}
search_logs
Search with regex, field filters, severity, and time range. All filters are AND-ed.
| Param | Type | Description |
|---|---|---|
text | string | Regex against body and all field values (case-insensitive) |
fields | object | Exact field matches, e.g. {"symbol": "NVDA"} |
level | string | INFO, WARN, ERROR, DEBUG |
after / before | string | ISO 8601 time range |
limit | int | Max results (default from config) |
count_only | bool | Return just the count, no entries |
tail
Last N entries (default 10).
get_schema
Returns column definitions, sample values, and the context string from your config β gives AI agents operational context about your app.
Config Reference
name: my-app # Instance name (shown in MCP responses)
type: json
mapping:
timestamp:
field: timestamp # JSON path to timestamp
severity:
field: level # JSON path to log level
body:
field: fields.message # Supports nested paths (dot-separated)
auto_map_remaining: true # Append unmapped fields to message body
mcp:
exclude_fields: # Fields to strip from MCP responses
- span
- target
default_limit: 100 # Default search result limit
context: | # Operational context for AI agents
my-app is a web server.
"Connection reset" warnings are normal during deploys.
columns:
- name: Time
source: timestamp
format: time_short # HH:MM:SS
width: 8
- name: Level
source: severity
width: 5
- name: Service
source: field:service # Extract from top-level JSON field
width: 10
- name: Trace
source: span_field:trace_id # Extract from spans[] array
width: 12
- name: Message
source: body
flex: true # Exactly one column must be flex
exclude: # Fields to hide from auto_map body
- target
Column Source Types
| Source | Example | Description |
|---|---|---|
timestamp | -- | Parsed timestamp |
severity | -- | Log level |
body | -- | Log message |
field:<name> | field:service | Top-level JSON field |
span_field:<name> | span_field:trace_id | Field from spans[] array |
CLI
# Instance mode (pipe logs)
app 2>&1 | logpond --config ./config.yaml [flags]
Flags:
--config Path to YAML config file (required)
--buffer Ring buffer capacity (default: 50000)
--mcp-port MCP server port (default: 9876)
--name Instance name override (default: from config)
# Hub mode (aggregator)
logpond hub [flags]
Flags:
--port Hub MCP server port (default: 9800)
Architecture
ββββββββββββββββββββββββββββ
β Hub (:9800/mcp) β
β Auto-spawned by first β
β instance. Fans out β
β queries to all live β
β instances. β
βββββββ¬βββββββββββ¬ββββββββββ
β β
ββββββββββββββββ ββββββββββββββββ
βΌ βΌ
βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ
β Instance A (:9876) β β Instance B (:9877) β
β β β β
β stdin ββΆ Parser β β stdin ββΆ Parser β
β βΌ β β βΌ β
β Store βββ MCP β β Store βββ MCP β
β βΌ β β βΌ β
β TUI β β TUI β
βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ
~/.logpond/app-a-1234.json ~/.logpond/app-b-5678.json
- Hub discovers instances via
~/.logpond/*.jsonregistration files - Instances register on startup, deregister on exit
- AI agent connects to hub once β sees all services
Multiple Services
Just pipe each service through its own logpond instance:
# Terminal 1
api-server 2>&1 | logpond --config ./api.yaml
# Terminal 2
worker 2>&1 | logpond --config ./worker.yaml --mcp-port 9877
Each instance gets its own TUI, its own config, and its own columns. The hub merges them all β the AI agent sees everything from one endpoint.
License
MIT
