driftguard-mcp
v0.1.13
Published
Real-time AI conversation drift monitor — MCP server for Claude Code, Gemini CLI, Codex CLI, and Cursor
Downloads
1,388
Maintainers
Readme
driftguard-mcp
Real-time AI conversation drift monitor for Claude Code, Gemini CLI, Codex CLI, and Cursor.
Long AI sessions degrade — the model fills its context window, starts repeating itself, and loses track of what you originally asked for. driftguard-mcp reads your session file directly, measures the signals that actually predict this, and tells you when to start fresh.
No browser. No API keys. No UI. Works as an MCP server your AI CLI can call mid-session.
Install
npm install -g driftguard-mcp
driftguard-mcp setupsetup automatically configures all supported AI CLIs on your machine. You must restart your AI CLI(s) after running it — the MCP server only loads at startup.
Claude Code — ~/.claude.json
{
"mcpServers": {
"driftguard": {
"command": "driftguard-mcp",
"env": { "DRIFTCLI_ADAPTER": "claude" }
}
}
}Gemini CLI — ~/.gemini/settings.json
{
"mcpServers": {
"driftguard": {
"command": "driftguard-mcp",
"env": { "DRIFTCLI_ADAPTER": "gemini" }
}
}
}Codex CLI — ~/.codex/config.toml
[mcp_servers.driftguard]
command = "driftguard-mcp"
env.DRIFTCLI_ADAPTER = "codex"Cursor — ~/.cursor/mcp.json
{
"mcpServers": {
"driftguard": {
"command": "driftguard-mcp",
"env": { "DRIFTCLI_ADAPTER": "claude" }
}
}
}
DRIFTCLI_ADAPTERtells driftguard-mcp which CLI's sessions to read.driftguard-mcp setupsets this automatically.
Usage
Call these tools from any session:
get_drift()— check if the session is degradingget_handoff()— write ahandoff.mdto continue in a fresh sessionget_trend()— full score history with sparkline
What it looks like
Healthy session:
✅ Context is healthy.
Context depth ███░░░░░░░ 28
Repetition ██░░░░░░░░ 15
Score: 12/100 · 14 messages
Session size: 56,210 input tokens totalSession that needs a reset:
⚠️ Start fresh now — context is full and responses are repeating heavily.
Context depth █████████░ 88
Repetition ████████░░ 72
Length collapse █████░░░░░ 48
Score: 84/100 · 67 messages
Session size: 176,432 input tokens total
→ Call get_handoff() to get a structured prompt for writing handoff.md before starting fresh.The score leads with a plain-English recommendation. The two bars that matter most — context depth and repetition — always appear. Others only show when they're contributing something meaningful.
See it in action
Handoff workflow
When drift is high, call get_handoff(). The AI writes a handoff.md in your project root using its full session context:
## What we accomplished
Implemented JWT authentication with refresh token rotation. Added middleware,
updated the user model, wrote integration tests. All tests passing.
## Current state
Auth flow is working end-to-end. Rate limiting is stubbed but not implemented.
The `/refresh` endpoint has a known edge case with concurrent requests (see TODO in auth.ts:142).
## Files modified
- src/middleware/auth.ts — JWT verify + refresh logic
- src/models/user.ts — added refreshToken field + index
- src/routes/auth.ts — /login, /logout, /refresh endpoints
- tests/integration/auth.test.ts — 14 new tests
## Open questions / next steps
- Implement rate limiting on /login (decided on: 5 attempts per 15 min)
- Fix concurrent refresh edge case
- Add token blacklist for logout
## Context for next session
Using jsonwebtoken@9, refresh tokens stored in DB (not Redis — decision was made
to keep it simple for now). Access token TTL: 15min. Refresh TTL: 7 days.Load handoff.md at the start of your next session. You continue without losing context.
What it measures
Weights are empirically calibrated against two public datasets: LMSYS-Chat-1M (1M real sessions — factor behaviour across turn depth) and Chatbot Arena (33K human preference pairs — which conversation the human judged better):
| Factor | Weight | What it measures | |--------|--------|-----------------| | Context depth | 30% | % of context window used — real token counts for all adapters | | Repetition | 25% | 3-gram overlap across recent responses — model recycling its own output | | Goal distance | 22% | Vocabulary drift from your stated goal — strongest pairwise signal in Arena data | | Uncertainty signals | 12% | Self-correction density ("I was wrong", "let me correct that") | | Response length collapse | 8% | Responses getting shorter — reliable symptom, short sessions can't measure it | | Confidence drift | 3% | Hedging language trend (early vs late responses) |
Context depth has +0.80 correlation with turn index on real long sessions (LMSYS). Goal distance and repetition were the strongest predictors of the losing model in Arena pairwise comparisons. Weights sum to 1.00.
get_drift() options
Pass an optional goal string to anchor the goal distance measurement to a specific objective:
get_drift({ goal: "build a JWT authentication system" })Without it, goal distance returns 0 (no anchor = no measurement).
Configuration
driftguard-mcp looks for config in two places, merged together:
- Global:
~/.driftclirc - Per-project:
.driftcliin the project root
Both are plain JSON. All fields are optional.
{
"preset": "coding",
"warnThreshold": 60
}Presets
| Preset | Best for |
|--------|----------|
| coding | Focused coding sessions |
| research | Research or planning — weights goal alignment heavily |
| brainstorm | Brainstorming — relaxed repetition and confidence penalties |
| strict | Equal weight across all six factors |
All options
| Key | Default | Description |
|-----|---------|-------------|
| preset | — | Named weight preset |
| weights | — | Per-factor weight overrides, applied on top of preset |
| warnThreshold | 60 | Score threshold for warnings |
| storage.enabled | true | Persist drift snapshots for get_trend() |
| storage.directory | ~/.driftcli/history | Override snapshot storage path |
| sessionResolution.cacheTtlMs | 5000 | Session file cache TTL (ms) |
Environment variables
| Variable | Description |
|----------|-------------|
| DRIFTCLI_ADAPTER | Pin to a specific CLI: claude, gemini, or codex. Set automatically by setup. |
| DRIFTCLI_SESSION_ID | Force a specific session UUID (Claude Code only). |
| DRIFTCLI_HOME | Override home directory for session file discovery. |
CLI watcher
Live terminal dashboard, polls every 3 seconds:
driftguard-mcp watchSupported CLIs
| CLI | Status | |-----|--------| | Claude Code | ✅ Supported — real token counts, 200k window | | Gemini CLI | ✅ Supported — real token counts, 1M window | | Codex CLI | ✅ Supported — real token counts, runtime window from session JSONL | | Cursor | ✅ Supported (monitors Claude Code / Gemini / Codex sessions) |
If driftguard-mcp is useful, a GitHub star helps others find it.

