Install
$ agentstack add mcp-maxturazzini-local-agent-viewer Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Dangerous shell/eval execution.
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Local Agent Viewer
Your local long-term memory for AI agent interactions.
Every interaction you have with Claude Code, Codex CLI, Claude Desktop, and ChatGPT — parsed, classified, searchable, and visualized. Across all your machines.
Want to build your own AI agent?
If LocalAgentViewer sparked your curiosity about AI agents, you might want to go deeper.
AI, MAX Academy offers practical AI training born from 200+ real-world workshops with 2000+ professionals. One of the flagship courses is:
Your AI assistant. On your computer.
A hands-on course that walks you through building a personal AI assistant that works on your own files, knows your work, and stays where it belongs — with you. No cloud dependency, no black boxes. You learn how to think with AI, not just how to click buttons.
> The course is currently in Italian, but an English version is on the way. First lesson is free.
The problem
You talk to AI agents every day. You solve bugs, design systems, refactor codebases, debug deployments. But those interactions vanish into scattered JSONL files buried in ~/.claude/, ~/.codex/, and platform-specific directories. No search. No analytics. No memory.
What if you could remember everything?
What LAV does
LocalAgentViewer turns your AI agent logs into a persistent, searchable knowledge base — entirely on your machine.
- Parse raw JSONL/JSON logs from multiple agents into a single SQLite database
- Classify interactions with AI (topics, sensitivity, people, clients, tags)
- Search by keyword (FTS5) or by meaning (Qdrant vector search)
- Visualize tokens, costs, tools, files, and activity patterns in a real-time dashboard
- Distribute across machines — each device parses locally, a central collector unifies everything
No cloud. No accounts. No external dependencies. Just pip install and go.
Supported Agents
| Agent | Source Format | Auto-detected | |-------|--------------|---------------| | Claude Code | JSONL | ~/.claude/projects/ | | Codex CLI | JSONL | ~/.codex/sessions/ | | Claude Desktop (Cowork) | JSONL | ~/Library/Application Support/Claude/local-agent-mode-sessions/ | | ChatGPT | JSON export | Manual (conversations.json from data export) |
Screenshots
More screenshots
Installation
1. Clone and install
git clone https://github.com/maxturazzini/local-agent-viewer.git
cd local-agent-viewer
pip install -e .
This installs the core package (zero external dependencies — stdlib only). All CLI commands become available immediately.
2. (Optional) Install extras
pip install -e ".[classifiers]" # AI classification (openai)
pip install -e ".[qdrant]" # Semantic search (qdrant-client, openai, anthropic)
pip install -e ".[mcp]" # MCP server (fastmcp)
pip install -e ".[all]" # Everything
3. (Optional) Configure environment
Copy the example and fill in what you need:
cp .env.example .env
# Only needed for optional features — core works without any of these
OPENAI_API_KEY=sk-... # AI classification (lav-classify) + embeddings (lav-index)
ANTHROPIC_API_KEY=sk-ant-... # Qdrant KB auto-tagging via Haiku
QDRANT_URL=http://localhost:6333 # Remote Qdrant server (omit for local file storage)
CHATGPT_EXPORT_PATH= # Path to ChatGPT conversations.json
CLAUDE_AI_EXPORT_PATH= # Folder of Anthropic claude.ai export (data-*-batch-0000)
# Auth for CLI (lav) and MCP server (lav-mcp)
# LAV_API_KEY=your-secret-key # Required for write operations (sync, kb index, pricing add)
# LAV_READ_API_KEY=your-read-key # Optional — if set, read operations require this key
# Classification config (optional — defaults work with OpenAI)
# LAV_CLASSIFY_MODEL=gpt-4.1-mini
# LAV_CLASSIFY_BASE_URL=http://localhost:11434/v1 # Ollama, vLLM, Azure, etc.
# LAV_CLASSIFY_SYSTEM_PROMPT=/path/to/prompt.txt # or inline text
Quick Start
# Parse interactions from this machine
lav-parse
# Start the server
lav-server
Open http://localhost:8764 — that's it.
The database is created automatically at ~/.local/share/local-agent-viewer/local_agent_viewer.db. No configuration required for core functionality.
CLI Commands
| Command | Description | Requires | |---------|-------------|----------| | lav | Unified CLI — query, search, KB management, sync, pricing | — | | lav-parse | Parse JSONL interactions (Claude Code, Codex, Desktop) | — | | lav-parse-chatgpt | Parse ChatGPT export | CHATGPT_EXPORT_PATH | | lav-parse-claude-ai | Parse Anthropic claude.ai account export | CLAUDE_AI_EXPORT_PATH (or --folder) | | lav-server | Start the web server | — | | lav-classify | Classify interactions via gpt-4.1-mini | OPENAI_API_KEY | | lav-index | Index interactions into Qdrant | qdrant-client, openai | | lav-mcp | Start MCP server | fastmcp | | lav-pricing | Manage model pricing for cost tracking | — |
Unified CLI (lav)
The lav command provides direct access to queries, KB management, sync, and pricing — no server or MCP required.
# Search interactions (SQLite FTS5)
lav search "newsletter pipeline"
lav search "newsletter" --project miniMe --limit 5 --start 2026-03-01
# Show full transcript
lav show
# Semantic search (Qdrant KB)
lav kb search "how does the blog publisher work"
lav kb search "debugging MCP" --classification development
# KB management
lav kb status
lav kb index --tags "blog,newsletter"
lav kb remove
lav kb tags --set "new,tags"
# Day View — daily Gantt + honest worktime metrics
lav day 2026-05-12
lav day 2026-05-12 --project miniMe --format brief
# Sync & pricing
lav sync
lav sync --scope project --project miniMe --full
lav pricing list
lav pricing add --model gpt-5.4 --input 2.0 --output 8.0 --from-date 2026-04-01
Output formats: JSON (default, for piping/scripting), --format table (human-readable), --format brief (one line per result).
Auth: write operations (sync, kb index/remove/tags, pricing add) require LAV_API_KEY env var. Read operations are open by default, or gated by LAV_READ_API_KEY if set.
Parser options
lav-parse # incremental (default, fast)
lav-parse --project myProject # parse one project only
lav-parse --full # force full reparse
lav-parse-chatgpt # parse ChatGPT export
lav-parse-chatgpt --full # full reparse
Data Pipeline
Three layers turn raw agent logs into a searchable, classified knowledge base:
JSONL / JSON logs
│
▼
┌─────────────────────────────────────────────────┐
│ 1. PARSE → SQLite │
│ Raw interactions: sessions, messages, tokens, │
│ file ops, tool calls, costs, models │
│ ─ lav-parse / lav-parse-chatgpt │
└─────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ 2. CLASSIFY → interaction_metadata (optional) │
│ AI classification via gpt-4.1-mini: │
│ summary, topics, people, clients, sensitivity, │
│ process type, tags │
│ ─ lav-classify (or auto after sync) │
└─────────────────┬───────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ 3. INDEX → Qdrant vector DB (optional) │
│ Semantic embeddings for meaning-based search. │
│ Reuses SQL metadata when available (no extra │
│ LLM call). Enables KB search in dashboard. │
│ ─ lav-index │
└─────────────────────────────────────────────────┘
Each layer is independent — the core works with just layer 1. Classification adds structured metadata. Qdrant adds semantic search on top.
Features
Analytics Dashboard
- Overview — sessions, messages, tokens, costs across time
- Tokens — input/output/cache breakdown by model and day
- Files — most-modified files, operations heatmap
- Tools — tool call frequency and distribution
- Timeline — activity patterns and session duration
- Users — per-user drill-down with 7 views
- Knowledge Base — semantic search across interactions
- Cost Intelligence — work patterns, task-type costs, efficiency metrics
- Day View — daily Gantt of all sessions grouped by project, concurrency curve, and two honest worktime metrics (
active_wallclock,assistant_wallclock) that avoid the ~13× inflation of span-sum. Hover any metric card for its definition. Toggle "Show subagents" to include sessions withparent_session_id.
4D Filtering
Every query supports four independent dimensions:
| Dimension | What it filters | |-----------|----------------| | Project | Which codebase | | User | Which person | | Host | Which machine | | Source | Which agent (claudecode, codexcli, cowork_desktop, chatgpt) |
Search
- Full-text search via SQLite FTS5 — fast, no external dependencies
- Semantic search via Qdrant vector DB (optional, layer 3)
- Classification filters — search by topic, sensitivity, process type (layer 2)
AI Classification (optional)
# Requires OPENAI_API_KEY in .env
lav-classify # classify unclassified interactions
lav-classify --full # reclassify everything
lav-classify --dry-run # preview
Also runs automatically after each sync when OPENAI_API_KEY is set.
Configuration — all optional, set in .env:
| Variable | Default | Description | |----------|---------|-------------| | LAV_CLASSIFY_MODEL | gpt-4.1-mini | Model name (any OpenAI-compatible model) | | LAV_CLASSIFY_BASE_URL | (OpenAI default) | API endpoint — e.g. http://localhost:11434/v1 for Ollama | | LAV_CLASSIFY_SYSTEM_PROMPT | (built-in) | Custom system prompt: inline text or path to a .txt file | | LAV_CLASSIFY_MAX_CHARS | 12000 | Max chars of interaction text sent to the model | | LAV_CLASSIFY_LANGUAGE | en | Language for summary/abstract/process fields (enum fields stay English) |
The --model CLI flag overrides LAV_CLASSIFY_MODEL for a single run.
> Note on small models: The built-in prompt is optimized for small local models (phi4-mini, etc.). Avoid uppercase/NOT-heavy custom prompts — some small models enter degenerate repetition loops. See tests/evals/ for model comparison reports.
MCP Server
Expose your analytics to AI tools via the Model Context Protocol. This lets Claude Code, Claude Desktop, or any MCP-compatible client query your interaction history, search the knowledge base, and trigger syncs — all through natural language.
# Requires: pip install fastmcp
lav-mcp
Available tools:
| Tool | Auth | Description | |------|------|-------------| | get_interactions | LAV_READ_API_KEY | List/search interactions (FTS, filters by project/user/date) | | get_interaction_details | LAV_READ_API_KEY | Full transcript by session ID | | semantic_search | LAV_READ_API_KEY | Qdrant vector search with classification/tag/project filters | | kb_status | LAV_READ_API_KEY | Check if an interaction is indexed | | sync | LAV_API_KEY | Trigger data re-parse (all, by project, or by source) | | kb_index | LAV_API_KEY | Index an interaction into Qdrant (auto-tag or pre-metadata) | | kb_remove | LAV_API_KEY | Remove an interaction from Qdrant | | kb_update_tags | LAV_API_KEY | Update tags without re-embedding | | manage_pricing | LAV_READ_API_KEY / LAV_API_KEY | List, add, or lookup model pricing |
Claude Code configuration (~/.claude/claude_code_config.json):
{
"mcpServers": {
"local-agent-viewer": {
"command": "lav-mcp",
"env": {
"LAV_API_KEY": "your-write-api-key",
"LAV_READ_API_KEY": "your-read-api-key"
}
}
}
}
Write tools require LAV_API_KEY. Read tools require LAV_READ_API_KEY if set on the server — if not set, read access is open. Both keys are defined in .env and passed to MCP clients via config.
Remote MCP server (HTTP transport)
By default lav-mcp runs in stdio mode (in-process, local clients only). To consume the same tools from a different machine — without ssh-stdio tunnels — switch to the streamable-http transport:
LAV_MCP_TRANSPORT=streamable-http LAV_MCP_PORT=8765 lav-mcp
# Listens on http://127.0.0.1:8765/mcp by default (loopback).
# Set LAV_MCP_HOST=0.0.0.0 to expose on LAN/VPN.
| Env var | Default | Purpose | |---------|---------|---------| | LAV_MCP_TRANSPORT | stdio | Set to streamable-http to enable the HTTP server | | LAV_MCP_HOST | 127.0.0.1 | Bind address (use 0.0.0.0 for LAN/VPN) | | LAV_MCP_PORT | 8765 | HTTP port |
Client config (Claude Desktop / Claude Code) via mcp-remote:
{
"mcpServers": {
"local-agent-viewer": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://:8765/mcp"]
}
}
}
API keys are passed as tool arguments (field api_key), not as HTTP headers — the client reads them from local env and includes them in the MCP request payload.
Security: when LAV_MCP_HOST=0.0.0.0, always set LAV_READ_API_KEY in your .env so read access is not open to the network. The transport itself is unencrypted (no TLS) — keep the port behind a VPN or trusted LAN.
For LaunchAgent / systemd templates and installation, see [utils/services/README.md](utils/services/README.md). Full reference: [docs/remote-mcp-server.md](docs/remote-mcp-server.md).
Multi-Machine Setup
Expand for distributed architecture details
Architecture
LocalAgentViewer supports a distributed agent/collector model. Each machine parses its own interactions locally. A central collector pulls from all agents into one unified database.
GET /api/export
┌──────────────┐◄──────────────────┌──────────────┐
│ Collector │ (pull sessions) │ Agent │
│ role: both │ │ role: agent │
│ │ │ │
│ Dashboard │ │ Parse local │
│ Unified DB │ │ Local DB │
│ All APIs │ │ Thin API │
└──────────────┘ └──────────────┘
Roles
| Role | Bind | Function | |------|------|----------| | agent | 0.0.0.0:8764 | Parses local interactions, exposes /api/export | | both (default) | 0.0.0.0:8764 | Full server: local parse + pull from agents + dashboard |
Configuration
Each machine has a local config at ~/.local/share/local-agent-viewer/config.json (not synced via git):
Collector (the machine with the dashboard) — see [config.collector.example.json](config.collector.example.json):
{
"role": "both",
"port": 8764,
"agents": [
{
"name": "laptop",
"url": "http://laptop.local:8764",
"fallback_url": "http://10.0.0.5:8764",
"timeout_seconds": 10
}
]
}
Agent (each remote machine) — see [config.agent.example.json](config.agent.example.json):
{
"role": "agent",
"port": 8764,
"collector_url": "http://collector.local:8764"
}
Data flow
Agent machine (every 15 min via LaunchAgent)
→ lav-parse parses local ~/.claude/projects
→ notify_collector() → POST http://collector:8764/api/sync
→ Collector pulls from agent via GET /api/export
→ Canonical DB updated
Pull is on-demand (triggered by the agent after each parse), not periodic polling.
Setup
On the agent:
mkdir -p ~/.local/share/local-agent-viewer
cp config.agent.example.json ~/.local/share/local-agent
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [maxturazzini](https://github.com/maxturazzini)
- **Source:** [maxturazzini/local-agent-viewer](https://github.com/maxturazzini/local-agent-viewer)
- **License:** MIT
- **Homepage:** https://aimax.it
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.