contextpulse-mcp
Real-time context budget tracking for any AI coding agent.
Plug into Claude Code, Cursor, or any MCP-compatible tool and get:
- 📊 Live token budget bar per agent run
- 🔁 Loop detection (when an agent calls the same tool 3× in a row)
- ⚠️ Warning / critical alerts before context overflow
- 🗄️ Full run history stored in PostgreSQL
- 📈 Budget timeline for every run
- 🔴 BullMQ alert queue for async threshold notifications
- 🔄 Run diff engine — compare two agent runs side by side
No cloud. No telemetry. Runs entirely on your machine.
---
How it works
ContextPulse is a transparent MCP server. You call its tracking tools from your agent's workflow. It counts tokens using tiktoken, updates a live budget in memory, persists everything to PostgreSQL, and fires alerts when thresholds are crossed. Your agent → calls cp_track_tool_call → ContextPulse counts tokens
→ updates live budget
→ warns at configurable thresholds (70% / 90% by default, model-calibrated — see below)
→ detects loops
→ saves to DB
→ queues BullMQ alert jobs The contextpulse dashboard connects over WebSocket and visualizes everything in real time.
---
Quick start
1. Start PostgreSQL
brew services start postgresql@16
# or Docker
docker run -d --name contextpulse-db -e POSTGRES_DB=contextpulse -p 5432:5432 postgres:16
2. Start Redis (required for BullMQ alert queue)
brew services start redis
# or Docker
docker run -d --name contextpulse-redis -p 6379:6379 redis:7
3. Add to Claude Code (~/.claude/settings.json)
{
"mcpServers": {
"contextpulse": {
"command": "npx",
"args": ["-y", "contextpulse-mcp"],
"env": {
"DATABASE_URL": "postgresql://apple@localhost:5432/contextpulse"
}
}
}
}
4. Add to Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"contextpulse": {
"command": "npx",
"args": ["-y", "contextpulse-mcp"],
"env": {
"DATABASE_URL": "postgresql://localhost:5432/contextpulse"
}
}
}
}
The DB schema is created automatically on first run.
---
Usage in your agent
cp_start_session → get sessionId cp_start_run → get runId (optionally pass baselineOverheadTokens — see Accuracy & limitations) cp_track_tool_call → after every tool call (pass tool name, args, output) cp_get_budget → check current budget at any time cp_get_run_summary → full run summary with timeline cp_end_run → clean up
Example response from cp_track_tool_call
{
"toolCallId": "a1b2c3...",
"inputTokens": 142,
"outputTokens": 87,
"totalTokens": 229,
"budget": {
"used": 14820,
"limit": 200000,
"percentUsed": 7.41,
"warningThresholdPct": 60,
"criticalThresholdPct": 85
},
"budgetStatus": "ok",
"alert": null
}
When budget hits the warning threshold (60% by default for Claude models — see Accuracy & limitations):
{
"budgetStatus": "warning",
"alert": "warning"
}
---
Environment variables
| Variable | Default | Description | |---|---|---| | DATABASE_URL | postgresql://apple@localhost:5432/contextpulse | PostgreSQL connection string | | REDIS_URL | redis://localhost:6379 | Redis connection for BullMQ | | MODEL | claude-sonnet-4-6 | Model in use. Picks the default CONTEXT_LIMIT / thresholds below from a per-model profile (see Accuracy & limitations). | | CONTEXT_LIMIT | model-derived, else 200000 | Token limit per session. Set this to override the model's default. | | WARNING_THRESHOLD_PCT | model-derived, else 70 | Warning alert threshold (%). Set this to override the model's default. | | CRITICAL_THRESHOLD_PCT | model-derived, else 90 | Critical alert threshold (%). Set this to override the model's default. | | LOOP_DETECTION_THRESHOLD | 3 | Same tool calls before loop alert |
CONTEXT_LIMIT / WARNING_THRESHOLD_PCT / CRITICAL_THRESHOLD_PCT always win if set explicitly. Otherwise ContextPulse picks defaults from MODEL — currently claude, gpt, and gemini have profiles in src/config/index.ts; anything else falls back to 200k / 70% / 90%. Edit that file directly if your model isn't covered or the numbers don't match your plan.
---
Accuracy & limitations
Be aware of two gaps before you treat the reported percentage as exact:
Token counts are an approximation. ContextPulse counts tokens with tiktoken's cl100k_base encoding, which is OpenAI's tokenizer, not Claude's — there's no public Claude tokenizer to use instead. It will drift from what Claude actually bills, especially on code. Treat percentUsed as a trend signal ("am I climbing toward the wall") rather than an exact remaining-token count.
This proxy can't see everything in the context window. ContextPulse only counts tokens that flow through cp_track_tool_call. It has no visibility into your agent's system prompt, other MCP servers' tool schemas, or any server-side context injection — all of which can be substantial (a single MCP server's tool definitions alone can run tens of thousands of tokens). So the tracked total is a floor, not the full picture.
Two ways to close the gap a bit:
baselineOverheadTokensoncp_start_run— pass a rough estimate of what's already spent before the first tracked call (system prompt + other tool schemas), and it's added to the running total from the start.- Per-model thresholds —
claudeprofiles default to tighter thresholds (60% / 85%) than the generic default (70% / 90%) specifically to hedge against this blind spot. TuneWARNING_THRESHOLD_PCT/CRITICAL_THRESHOLD_PCTfurther if you find alerts firing early or late for your setup.
---
What gets stored
cp_sessions -- one row per coding session
cp_runs -- one row per agent task
cp_tool_calls -- every intercepted tool call
cp_budget_snapshots -- token usage timeline per run
cp_alerts -- warnings, criticals, loop detections ---
Architecture
contextpulse-mcp/
src/
mcp/ ← MCP tool handlers
context/ ← token counting + budget engine
alerts/ ← BullMQ queue + worker
diff/ ← run diff engine
db/ ← PostgreSQL schema + queries contextpulse/ ← dashboard repo
app/dashboard/
components/ ---
Related
- contextpulse — Real-time Next.js dashboard for this server
---
License
MIT











