Up and running in 60 seconds.
npm install purgr
import { Purgr } from 'purgr'
const purgr = new Purgr({ activeWindow: 8, anchorCount: 3 })
const result = purgr.compress(conversationHistory)
// Pass compressed messages to your LLM
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: result.messages
})
// Access the cryptographic receipt
const receipt = purgr.getSignedReceipt()
npm install -g purgr
purgr proxy
# Now point your app at http://localhost:3000 instead of https://api.anthropic.com
npm install -g purgr
purgr proxy
purgr setup claude-desktop
# Restart Claude Desktop
npm install purgr
The most recent N messages are never compressed. They always pass through to the LLM unchanged. Everything older than the active window is eligible for compression. Default: 8 messages.
Every message receives a momentum score based on EWMA Jaccard overlap with recent messages. Messages that stay topically relevant maintain high momentum and survive compression. Messages that drift from current topics decay toward compression candidates. O(N) time complexity.
After sufficient conversation history accumulates, the AutoScorer transitions to Dynamic Mode Decomposition. The Koopman operator models conversation dynamics as an evolving linear system, identifying structural topics that persist across topic changes. Achieves 91.4% TRR at 1M tokens.
Every compression produces an Ed25519-signed receipt containing a Merkle root over all compression decisions, input hash, query binding, and chain link to the previous receipt. Receipts are independently verifiable at purgr.dev/verify without sending data to any server.
| Option | Type | Default | Description |
|---|---|---|---|
| activeWindow | number | 8 | Messages protected from compression at the tail |
| anchorCount | number | 3 | Maximum anchor summaries injected per compression pass |
| scorerMode | string | 'auto' | Phase 1 only ('momentum'), Phase 2 only ('dmd'), or automatic transition |
| protectedLeadMessages | number | 5 | Messages at the head permanently protected (system prompts) |
| tailProtectMessages | number | 3 | Messages just outside active window, protected from fallback compression |
| anchorPosition | string | 'after-system' | Where anchors are injected ('before', 'after-system', 'end') |
| debug | boolean | false | Verbose compression logging to console |
{
"activeWindow": 12,
"anchorCount": 4,
"scorerMode": "dmd",
"threshold": 3000,
"target": "https://api.anthropic.com",
"port": 3000,
"receipts": true,
"debug": false
}
import { Purgr } from 'purgr'
import type { Message } from 'purgr'
const purgr = new Purgr({
activeWindow: 8,
anchorCount: 3,
scorerMode: 'auto'
})
const messages: Message[] = [
{ role: 'user', content: 'Hello' },
{ role: 'assistant', content: 'Hi there' },
// ... conversation history
]
const result = purgr.compress(messages)
// result.messages — compressed array ready for LLM
// result.stats — compression statistics
const result = purgr.compress(messages, {
query: "What was the approved budget?",
response: "The approved budget is $2.4M"
})
// Receipt will bind to this specific query/response pair
console.log(result.stats.originalTokens) // tokens before
console.log(result.stats.compressedTokens) // tokens after
console.log(result.stats.reductionPct) // 0.0 to 1.0
console.log(result.stats.latencyMs) // compression time
console.log(result.stats.anchorsInjected) // anchors added
const receipt = purgr.getSignedReceipt()
// receipt.payload.merkleRoot — Merkle root over all decisions
// receipt.payload.inputHash — SHA-256 of original input
// receipt.signature — Ed25519 signature
// receipt.publicKey — public key for independent verification
Wrap any async function that takes messages as its first argument. Compression happens automatically before every call. Zero changes to your existing code structure.
import { Purgr, withCompression } from 'purgr'
import Anthropic from '@anthropic-ai/sdk'
const client = new Anthropic()
const purgr = new Purgr({ activeWindow: 8 })
const compressed = withCompression(purgr, async (messages) => {
return client.messages.create({
model: 'claude-opus-4-6',
max_tokens: 1024,
messages
})
})
// Use exactly like the original function
const response = await compressed(conversationHistory)
// Receipt available after each call
const receipt = purgr.getSignedReceipt()
The Purgr proxy is a local HTTP server that intercepts LLM API traffic, compresses messages, and forwards requests transparently. No code changes required in your application.
npm install -g purgr
purgr proxy
┌─ Purgr Proxy ──────────────────────────────────┐ │ Listening on http://localhost:3000 │ │ Target https://api.anthropic.com │ │ Scorer momentum │ │ Active window 8 messages │ │ Receipts ~/.purgr/receipts/ │ └────────────────────────────────────────────────┘
// Anthropic
const client = new Anthropic({ baseURL: 'http://localhost:3000' })
// OpenAI
const client = new OpenAI({ baseURL: 'http://localhost:3000/v1' })
Point the proxy at any local LLM server that serves an OpenAI-compatible API. No code changes — just change the target in purgr.config.json.
{
"target": "http://localhost:11434",
"scorerMode": "dmd"
}
compressDocument() automatically detects academic papers, legal filings, compliance documents, and technical reports. Section types (Abstract, Introduction, Results, Conclusion, References) are detected and scored independently.
const result = purgr.compressDocument(documentText, {
targetTokens: 4000
})
// result.messages — compressed document chunks
// result.stats.sections — per-section breakdown
| Document | Tokens | TRR | Numeric Facts |
|---|---|---|---|
| Bank Secrecy Act | 20,034 | 68.8% | 100% preserved |
| USA PATRIOT Act §5318 | 21,579 | 72.0% | 100% preserved |
| OCC AML Guidance | ~3,000 | 18.3% | 100% preserved |
| FinCEN BSA Regulations | ~2,000 | 16.0% | 100% preserved |
Every compression pass produces an Ed25519-signed cryptographic receipt. Receipts form a tamper-evident chain — each receipt commits to the hash of the previous receipt.
{
"payload": {
"version": "1.0.2",
"timestamp": "2026-04-20T23:14:02.441Z",
"inputHash": "8829f3e1a7c2d4b6e9f0a1c3d5e7f2b4",
"merkleRoot": "a3f8c91d0e724b5f6e8d9c2a1b3e4f7a",
"queryHash": "c7d2e4f6a8b0c1d3e5f7a9b2c4d6e8f0",
"responseCommitment": "d4e6f8a0b2c4d6e8f0a2b4c6d8e0f2a4",
"previousReceiptHash": "f1a3b5c7d9e0f2a4b6c8d0e2f4a6b8c0",
"statsHash": "b2c4d6e8f0a2b4c6d8e0f2a4b6c8d0e2",
"decisions": [
{
"id": "msg-001",
"outcome": "compressed",
"evidence": {
"momentumScore": 0.08,
"decayStreak": 4,
"normalizedPosition": 0.12
}
}
]
},
"signature": "7/Ly01j7cZKK...base64...",
"publicKey": "MCowBQYDK2VdAyEA...base64 SPKI..."
}
| Field | Description |
|---|---|
| inputHash | SHA-256 of the original uncompressed input |
| merkleRoot | Merkle root committing to all compression decisions |
| queryHash | SHA-256 of the query string if provided |
| responseCommitment | Binds a specific LLM response to this compression |
| previousReceiptHash | Links to prior receipt forming tamper-evident chain |
| signature | Ed25519 signature over the payload |
| publicKey | SPKI DER public key for independent verification |
Any Purgr receipt can be independently verified at purgr.dev/verify. The verifier performs Ed25519 signature validation and Merkle tree reconstruction entirely in your browser. No data is transmitted to any server.
- [✓] The compression decisions were produced by an unmodified Purgr instance
- [✓] The decision record has not been tampered with since signing
- [✓] The Merkle root correctly commits to all recorded decisions
- [✓] The receipt is cryptographically linked to the specific input that was compressed
Purgr exposes an MCP (Model Context Protocol) server for integration with Claude Desktop and other MCP-compatible tools.
purgr mcp
{
"mcpServers": {
"purgr": {
"command": "purgr",
"args": ["mcp"]
}
}
}
| Command | Description |
|---|---|
| purgr proxy | Start the local compression proxy on port 3000 |
| purgr proxy --port 4000 | Start on custom port |
| purgr proxy --scorer dmd | Force Phase 2 DMD scorer |
| purgr proxy --debug | Enable verbose compression logging |
| purgr setup claude-desktop | Configure Claude Desktop to use proxy |
| purgr setup revert | Restore Claude Desktop original config |
| purgr mcp | Start MCP server |
| purgr receipts | View today's receipt log |
| purgr receipts --verify | Verify all receipts in today's log |
| purgr receipts --date 2026-04-20 | View receipts for specific date |
Purgr is engineered for speed and cryptographic integrity. This requires specific engineering tradeoffs.
Purgr uses lexical and dynamical scoring. Paraphrase detection without embeddings is an unsolved problem. Category 2 semantic NIAH (conceptual similarity without keyword overlap) scores 0% without an embedding model.
When a topic is discussed early, drops away for 100+ turns, and is referenced again late, Phase 2 DMD may compress the original discussion before the resurrection signal arrives.
Fact protection triggers on high-specificity signals: currency values, precise dates, version strings, named persons with titles. General conversational details (pet names, informal references) do not trigger protection.
The default token counter uses a 4 chars ≈ 1 token heuristic. For exact token counts install the optional tiktoken peer dependency.