reqlog
Drop-in middleware for Django applications that logs HTTP requests with Rich formatting, optional body/header capture, and SQLite persistence for AI agent debugging.
Drop-in middleware for FastAPI applications that logs HTTP requests with Rich formatting, optional body/header capture, and SQLite persistence for AI agent debugging.
Provides persistent storage for HTTP request logs via SQLite, enabling querying through CLI tools and an MCP server for AI coding agents to inspect request details, errors, and statistics.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@reqlogwhat recent errors occurred?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
reqlog
HTTP logging middleware for Python with Rich formatting, SQLite persistence, and an MCP server for AI coding agents.
Drop-in middleware for FastAPI, Django, and any ASGI framework.
Quick Start
pip install reqlogfrom fastapi import FastAPI
from reqlog import ReqlogMiddleware
app = FastAPI()
app.add_middleware(ReqlogMiddleware) ● GET /api/users 200 8ms 14:23:46
● POST /api/users 201 145ms 14:23:47
● GET /api/users/999 404 15ms 14:23:48
✗ GET /api/crash 500 89ms 14:23:49Three lines of code. Bodies, headers, and richer formats are one kwarg away:
app.add_middleware(ReqlogMiddleware, capture_body=True, format="panel")Inside Claude Code, Cursor, or Aider, reqlog auto-selects a token-efficient format — no configuration needed.
For Django, see Django Support.
Related MCP server: Local Lens
Give Your AI Agent a Network Tab
Terminal output is a firehose. MCP is a faucet.
When an AI agent debugs your backend through terminal output, it sees everything — uvicorn startup messages, health checks, OPTIONS preflights, successful requests — all burning context tokens. It can't go back and ask "what was the request body for that 422?"
reqlog flips this. Persist requests to SQLite, point the MCP server at it, and your agent pulls exactly what it needs:
Without reqlog MCP:
Something breaks
Agent reads terminal — 200 lines of mixed output
"Can you reproduce the error?"
You curl the endpoint, paste the output
Agent guesses at the request body
With reqlog MCP:
Something breaks
Agent calls
get_error_summary()— sees "422 on POST /api/users, missing field 'email'"Agent calls
get_request_detail(id)— sees the exact request body and validation errorAgent writes the fix
No manual debugging. No pasting terminal output into chat.
Setup
Step 1: Persist requests to SQLite.
from reqlog import ReqlogMiddleware, ConsoleBackend, SQLiteBackend
app.add_middleware(
ReqlogMiddleware,
capture_body=True,
backends=[ConsoleBackend(), SQLiteBackend("reqlog.db")],
)Step 2: Add to your editor's MCP config.
{
"mcpServers": {
"reqlog": {
"command": "uvx",
"args": ["--from", "reqlog[mcp]", "reqlog", "mcp", "--db", "reqlog.db"]
}
}
}{
"mcpServers": {
"reqlog": {
"command": "uvx",
"args": ["--from", "reqlog[mcp]", "reqlog", "mcp", "--db", "reqlog.db"]
}
}
}{
"mcpServers": {
"reqlog": {
"command": "uv",
"args": ["run", "--with", "mcp>=1.2.0", "reqlog", "mcp", "--db", "reqlog.db"]
}
}
}The [mcp] extra is required for the MCP server. When using pip directly: pip install reqlog[mcp].
MCP Tools
Tool | What the agent asks | What it gets |
| "What just happened?" | Recent HTTP logs with filters for status, path, method, duration, time window |
| "Show me that 500." | Full headers + bodies for a specific request ID |
| "What's broken?" | Aggregated 4xx/5xx report grouped by status code |
| "Find requests containing 'user not found'" | Full-text search across paths, bodies, and headers |
| "Is /api/users slow?" | Per-endpoint p50/p95/p99 latency and status breakdown |
Two MCP resources provide ambient context: reqlog://status (session summary, error rate) and reqlog://recent-errors (last 5 errors in compact format).
The --redact-bodies flag strips all bodies from MCP responses, serving only metadata. Standard sanitization (header masking, body field redaction) always applies.
Output Formats
Five built-in formats. Set via format= or the REQLOG_FORMAT env var. reqlog auto-detects your environment — ai format inside Claude Code/Cursor/Aider, compact in TTY, json otherwise.
panel — two-column request/response
Side-by-side layout with aligned headers and syntax-highlighted JSON bodies.
ai — token-efficient for LLMs
Automatically selected inside Claude Code, Cursor, and Aider. Compact JSON, no Rich overhead.
compact — default for terminals
Morgan-style one-liner with color-coded status and method.
verbose — vertical panels
Stacked Rich panels with full headers and response details.
json — JSON-Lines
One object per request. Default when stderr is not a TTY.
{"method":"GET","path":"/api/users","status_code":200,"duration_ms":8.2,"timestamp":"2026-02-14T14:23:46"}CLI
A built-in command-line interface for querying SQLite-persisted logs.
reqlog tail --db reqlog.db # Live-tail with color
reqlog tail --status 500 --slow 100 # Only slow errors
reqlog tail --method POST --path /api/users # Filter by method + path
reqlog stats --db reqlog.db --minutes 60 # Aggregated stats with p50/p95/p99
reqlog export --db reqlog.db --format json # Export as JSON-Lines
reqlog export --format csv --since "1 hour ago" # Time-filtered CSV exportRequest Stats (last 60 min)
Total requests: 847
Avg duration: 45.2ms
P50: 12.3ms
P95: 234.5ms
P99: 890.1ms
Status Codes HTTP Methods Top 10 Slowest Endpoints
Class Count Method Count Method Path Avg (ms)
2xx 723 GET 612 GET /api/reports 520.1
4xx 98 POST 187 POST /api/auth/login 230.4
5xx 26 PUT 32 POST /api/users 145.2
DELETE 16Backends
reqlog fans out to multiple backends in parallel. When no backends= list is provided, it defaults to a single ConsoleBackend with the auto-detected format.
from reqlog import ReqlogMiddleware, ConsoleBackend, SQLiteBackend
from reqlog.backends.file import FileBackend
app.add_middleware(
ReqlogMiddleware,
capture_body=True,
backends=[
ConsoleBackend(format="compact"), # Terminal output
SQLiteBackend(db_path="reqlog.db"), # Queryable storage (CLI + MCP)
FileBackend(path="requests.jsonl"), # Rotating log files
],
)Backend | Use case | Key options |
ConsoleBackend | Terminal output via Rich |
|
SQLiteBackend | Persistent storage for CLI + MCP |
|
FileBackend | Rotating log files (JSON/text/AI) |
|
MemoryBackend | Testing and debugging |
|
SQLiteBackend uses a background writer thread — non-blocking, queue-bounded, with graceful shutdown via atexit. See Backends Guide for the full API and custom backend protocol.
Configuration
All options work as keyword arguments to ReqlogMiddleware, as fields on ReqlogConfig, or as REQLOG_* environment variables.
app.add_middleware(
ReqlogMiddleware,
capture_body=True, # Log request/response bodies (default: False)
capture_headers=True, # Log headers (default: False)
format="compact", # "compact" | "verbose" | "panel" | "ai" | "json"
exclude_paths=["/health"], # Paths to skip
sample_rate=1.0, # 1.0 = all, 0.1 = 10%
)from reqlog import ReqlogMiddleware, ReqlogConfig
config = ReqlogConfig(
capture_body=True,
capture_headers=True,
format="compact",
max_body_size=64_000, # Truncate bodies larger than this (bytes)
exclude_paths=["/health", "/healthz", "/ready", "/metrics", "/favicon.ico"],
exclude_methods=["OPTIONS"],
include_paths=None, # If set, only log these paths
sample_rate=1.0,
sanitize_headers=[ # Glob patterns supported
"Authorization", "Cookie", "Set-Cookie", "X-API-Key", "X-Auth-Token",
],
sanitize_body_fields=[ # Recursive JSON walk
"password", "secret", "token", "access_token", "credit_card",
],
generate_request_id=True,
request_id_header="X-Request-ID",
)
app.add_middleware(ReqlogMiddleware, config=config)Environment variable overrides — take precedence over programmatic defaults:
Variable | Type | Example |
| str |
|
| bool |
|
| bool |
|
| float |
|
| int |
|
| list |
|
| list |
|
| str |
|
Sanitization is on by default — Authorization, Cookie, and API key headers are redacted, along with password/token/secret body fields. Redaction uses glob matching on headers and recursive JSON walks on bodies.
Django Support
# settings.py
MIDDLEWARE = [
"reqlog.middleware.django.ReqlogMiddleware",
# ... other middleware
]
REQLOG = {
"CAPTURE_BODY": True,
"CAPTURE_HEADERS": True,
"FORMAT": "compact",
"EXCLUDE_PATHS": ["/health", "/admin/jsi18n/"],
}The Django middleware auto-detects sync (WSGI) vs. async (ASGI) and handles both. In WSGI mode, logging runs in a background thread — zero latency impact on the request cycle.
from reqlog import ConsoleBackend, SQLiteBackend
REQLOG = {
"CAPTURE_BODY": True,
"FORMAT": "compact",
"BACKENDS": [
ConsoleBackend(format="compact"),
SQLiteBackend(db_path="reqlog.db"),
],
}Documentation
Detailed guides for each component:
Backends — Console, SQLite, File, Memory backends and custom backend protocol
CLI —
tail,stats,export,mcpcommands with examplesConfiguration — All options, env vars, and Django settings
Formatters — Compact, verbose, panel, AI, and JSON formats
Middleware — FastAPI/ASGI and Django integration details
Development
git clone https://github.com/ankitksr/reqlog.git
cd reqlog && uv sync
uv run pytest tests/ -v # 184 tests
uv run mypy src/ # Type checking (strict)
uv run ruff check src/ tests/ # Linting
uv build # Build packageuv run uvicorn examples.demo:app --reload # FastAPI demo
uv run python examples/preview_cli.py # All formatters + CLI features
uv run python examples/demo_mcp.py # MCP demo (sample DB + SSE server)src/reqlog/
core/ models.py · config.py · pipeline.py · buffer.py
middleware/ asgi.py (pure ASGI) · django.py (sync + async)
backends/ console.py · sqlite.py · file.py · memory.py · protocols.py
formatters/ compact · verbose · panel · ai · json · text_format (shared)
sanitize/ redact.py (header glob + recursive JSON walk)
mcp/ server.py (5 tools + 2 resources) · formatting.py
cli/ main.py (tail · stats · export · mcp · demo)License
MIT. See LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ankitksr/reqlog'
If you have feedback or need assistance with the MCP directory API, please join our Discord server