Httap
Inspect, intercept & mock HTTP traffic from your terminal or AI agent
Install / Use
/learn @mtford90/HttapREADME
httap
httap is a powerful HTTP proxy for your terminal. Intercept, inspect & rewrite HTTP traffic — from your shell or your AI agent.

Feature Highlights
- Project-scoped — each project gets its own
.httap/directory with isolated daemon, database, CA cert and interceptors. No cross-project bleed. - Multiple surfaces — powerful CLI for scripting, a lazygit-style TUI for browsing traffic, an MCP server for AI agents, and a Node.js API for programmatic access.
- Interceptors — mock, modify or observe traffic by writing TypeScript. Your AI agent can write these for you, so you can express complex scenarios in natural language.
Quick Start
npm install -g @mtford/httap
# Configure environment e.g. HTTP_PROXY
eval "$(httap on)"
# Send a request
curl https://api.example.com/users
# Open UI
httap tui
# Add MCP server to your AI tool
claude mcp add httap -- httap mcp
Browser Interception
Launch any browser pre-configured to route through httap — no manual proxy setup, no certificate warnings:
# Auto-detect and launch your default browser
httap browser
# Open a specific URL
httap browser https://example.com
# Choose a specific browser
httap browser --browser firefox
httap browser --browser brave
Each browser session gets its own isolated profile and is automatically attributed in the TUI (e.g. source: chrome). Close the browser or press Ctrl+C to stop — the temp profile is cleaned up automatically.
Supported browsers:
| Engine | Browsers | | -------- | ------------------------------------------- | | Chromium | Chrome, Brave, Edge, Vivaldi, Arc, Chromium | | Firefox | Firefox, Zen Browser, LibreWolf |
Project Scoping
httap doesn't use a global system proxy. Each project gets its own .httap/ directory in the project root (detected by .git or an existing .httap/):
your-project/
├── .httap/
│ ├── interceptors/ # TypeScript interceptor files
│ ├── config.json # Optional project config
│ ├── proxy.port # Proxy TCP port
│ ├── control.sock # IPC socket
│ ├── requests.db # Captured traffic
│ ├── ca.pem # CA certificate
│ └── daemon.pid # Process ID
└── src/...
Separate daemon, database, certificates etc. You can run httap in multiple projects at the same time without them interfering with each other.
For non-project contexts or custom setups, use --config to point directly at a data directory (no .httap appended):
httap --config /tmp/my-httap-data on
See CLI Reference for the full resolution order (--config > --dir > auto-detect).
MCP Integration
httap has a built-in MCP server that gives AI agents full access to your captured traffic and interceptor system.
Setup
Claude Code:
claude mcp add httap -- httap mcp
Codex:
codex mcp add httap -- httap mcp
Cursor — add to .cursor/mcp.json:
{
"mcpServers": {
"httap": {
"command": "httap",
"args": ["mcp"]
}
}
}
Other MCP clients (Windsurf, etc.) — add to your client's MCP config:
{
"mcpServers": {
"httap": {
"command": "httap",
"args": ["mcp"]
}
}
}
The proxy must be running (eval "$(httap on)") — the MCP server connects to the same daemon as the TUI.
Available Tools
| Tool | Description |
| -------------------------- | ---------------------------------------------------- |
| httap_get_status | Daemon status, proxy port, request count |
| httap_list_requests | Search and filter captured requests |
| httap_get_request | Full request details by ID (headers, bodies, timing) |
| httap_search_bodies | Full-text search through body content |
| httap_query_json | Extract values from JSON bodies via JSONPath |
| httap_count_requests | Count matching requests |
| httap_clear_requests | Delete all captured requests |
| httap_list_sessions | List active proxy sessions |
| httap_list_interceptors | List loaded interceptors with status and errors |
| httap_reload_interceptors | Reload interceptors from disk |
See full MCP documentation for filtering, output formats, and examples.
Interceptors
TypeScript files in .httap/interceptors/ that intercept HTTP traffic as it passes through the proxy. They can return mock responses, modify upstream responses, or just observe.
import type { Interceptor } from "@mtford/httap/interceptors";
export default {
name: "mock-users",
match: (req) => req.path === "/api/users",
handler: async () => ({
status: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify([{ id: 1, name: "Alice" }]),
}),
} satisfies Interceptor;
See full interceptors documentation for modify, observe, querying past traffic, handler context, and how they work.
How It Works
┌─────────────────────────────────────────────────────────────┐
│ Your Shell │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ curl, wget, node, python... │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ HTTP_PROXY=localhost:54321 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
└──────────────────────────┼──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ httap daemon │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ MITM Proxy │───▶│ SQLite │◀───│ Control API │ │
│ │ (mockttp) │ │ requests │ │ (unix sock) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
▲
│
┌──────────────────────────┼──────────────────────────────────┐
│ httap tui │ │
│ ┌───────────────────────┴─────────────────────────────┐ │
│ │ ● POST /api/users │ POST https://api.example.com │ │
│ │ GET /health │ Status: 200 │ Duration: 45ms │ │
│ │ POST /login │ │ │
│ │ │ Request Headers: │ │
│ │ │ Content-Type: application/ │ │
│ └─────────────────────┴───────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
eval "$(httap on)" starts a daemon, sets HTTP_PROXY/HTTPS_PROXY in your shell, and captures everything that flows through. eval "$(httap off)" unsets them. The TUI connects to the daemon via Unix socket.
Environment Variables
eval "$(httap on)" sets these in your shell (eval "$(httap off)" unsets them):
| Variable | Purpose |
| --------------------- | ------------------------------------ |
| HTTP_PROXY | Proxy URL for HTTP clients |
| HTTPS_PROXY | Proxy URL for HTTPS clients |
| SSL_CERT_FILE | CA cert path (curl, OpenSSL) |
| REQUESTS_CA_BUNDLE | CA cert path (Python requests) |
| CURL_CA_BUNDLE | CA cert path (curl/Python fallback) |
| NODE_EXTRA_CA_CERTS | CA cert path (Node.js) |
| DENO_CERT | CA cert path (Deno) |
| CARGO_HTTP_CAINFO | CA cert path (Rust Cargo) |
| GIT_SSL_CAINFO | CA cert path (Git) |
| AWS_CA_BUNDLE | CA cert path (AWS CLI) |
| CGI_HTTP_PROXY | Proxy URL (PHP CGI, HTTPoxy-safe) |
| HTTAP_SESSION_ID | UUID identifying the current session |
| HTTAP_LABEL | Session label (when -l flag used) |
Additionally, httap on sets PYTHONPATH, RUBYOPT, and PHP_INI_SCAN_DIR to load runtime-specific override scripts that ensure edge-case HTTP clients trust the proxy CA.
Configuration
Create .httap/config.json to override defaults:
{
"maxStoredRequests": 5000,
"maxBodySize": 10485760,
"maxLogSize": 10485760,
"pollInterval": 2000
}
See full configuration documentation for details on each setting.
Supported HTTP Clients
Anything that respects HTTP_PROXY works. httap sets the right CA cert env vars for each runtime automatically.
Works automatically (env vars only):
| Client | Support |
| ------------------- | ------------------------------- |
| curl | Automatic |
| wget | Automatic |
| Go (net/http) | Automatic |
| Rust (reqwest) | Automatic |
| .NET (HttpClient) | Automatic |
| Deno | Automatic (DENO_CERT) |
| Bun | Automatic (SSL_CERT_FILE) |
| Git | Automatic (`GIT_SSL_CAINF
