Dcp Rc
OpenCode DCP fork: hidden context compression with a selection-only compress tool (Sleev-style)
0
0
20.0
Multi-signal model
1 day ago
2026-10-04
Install and configure
opencode.jsonWrites to this project's opencode.json — applies to this repository only.
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@royalcat/opencode-dcp-rc@4.0.3"]
}Writes to ~/.config/opencode/opencode.json — applies to every project.
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@royalcat/opencode-dcp-rc@4.0.3"]
}If you want to modify the plugin locally, install it into the project and reference the local path.
shell
pnpm add -D @royalcat/opencode-dcp-rcOpenCode loads npm dependencies through its embedded runtime on startup and caches them locally — no manual global install needed.
A fork of Dynamic Context Pruning
Why this fork exists
Upstream DCP is solid engineering, but its developers have clearly focused on their commercial product, Sleev, and the open plugin gets the leftovers. The core idea — the model picks stale messages and the summaries are generated locally through your existing provider — needs no account, device lease, or telemetry pipeline. This fork ports that idea back into the plugin, keeps it fully local and invisible, and stays open for anyone who wants better context management in OpenCode.
Design goal: the plugin stays invisible. Injected system prompts, message-ID
tags, nudges, and summary replacement only ever exist in the outgoing model
request. The user's stored history is never rewritten, and the only
user-visible artifact is the compress tool call itself. If the model echoes
injected tags or reminders into its reply, the fork strips them from the
response before OpenCode stores or displays it.
How it differs from upstream DCP
The model selects; the plugin compresses.
compresstakes only message IDs, block IDs, or inclusive ranges — for example{ "ids": ["m0004-m0008", "m0011"] }— never summary text. The plugin produces one summary per selection with a dedicated prompt through your existing provider, so compression follows a fixed, repeatable format instead of depending on what the chat model would write inside the tool call.OpenCode V2 only. No V1 support and no upstream
range/messagemodes.Invisible by design. Hiding is the intended behavior, not a setting: injected prompts, message IDs, and nudges exist only in the request copy sent to the model, stored history is never rewritten, and the only visible artifact is the
compresstool call and its result.Fork names. Package
@royalcat/opencode-dcp-rc, configdcp-rc.jsonc/dcp-rc.json, and no self-update. Commands and prompt overrides keep upstream names:/dcp,/dcp-compress, anddcp-prompts/overrides/.Echoes are filtered. Models sometimes copy injected reminders or message-ID tags into their replies. The fork scrubs those copies from the model response before OpenCode stores or displays it. Controlled by
compress.scrubModelOutputandcompress.scrubMessageIds(both on by default); it never touches tool-call arguments, so working with DCP files or quoting tags intentionally still works.
Install
Requires OpenCode V2 (@opencode/plugin ^2.0.22; verified against 2.0.4).
opencode plugin add @royalcat/opencode-dcp-rc@latest
or reference the package in opencode.json(c):
{
"plugins": ["@royalcat/opencode-dcp-rc"],
}
Note: installing directly from the Git URL (
opencode plugin add https://github.com/royalcat/opencode-dcp-rc) currently fails because of an OpenCode bug when installing git dependencies. Install from npm as above.
Local development
npm install --legacy-peer-deps
npm run build
opencode plugin add /path/to/opencode-dcp-rc
Configuration
~/.config/opencode/dcp-rc.jsonc (created on first run):
{
"compress": {
"permission": "allow",
"minContextLimit": "20%",
"maxContextLimit": "80%",
"scrubModelOutput": true,
"scrubMessageIds": true,
},
"pruneNotification": "off",
}
Both context limits accept a token count or a percentage of the model's context
window; the defaults are "20%" and "80%", and compress.modelMinLimits /
compress.modelMaxLimits override them per providerID/modelID.
The rest of the upstream configuration (strategies, protection lists, manual
mode, subagents) still applies, except compress.mode and autoUpdate, which
the fork no longer uses. Compress prompt text can be overridden through
dcp-prompts/overrides/ when experimental.customPrompts is enabled.
scrubModelOutput removes DCP tags and reminder blocks the model may echo into
its reply; scrubMessageIds also removes message-ID refs (@N@, @bN@,
@blocked@) that appear alone on a line. Both default to true and are
kill-switches only — for example to debug the raw model output.
Status and limitations
- The hidden summary call uses the session's provider/model and consumes a normal model request. Its system prompt is a prefix of the main request, so providers with prefix caching can reuse it.
- If the host rejects nested generation, the
compresscall fails visibly and the selection is left uncompressed so it can be retried. - Output scrubbing covers HTTP provider responses (OpenAI Responses/Chat, Anthropic, Google) and the AI SDK text/reasoning path. Providers using the experimental WebSocket transport are not covered, and copies already stored before upgrading are not rewritten.
- Forked from DCP v3.2.0. Upstream is AGPL-3.0-or-later; this fork keeps the
same license and attribution (see
LICENSE).
Upstream README
Dynamic Context Pruning Plugin
Automatically reduces token usage in OpenCode by managing conversation context.

Installation
Install from the OpenCode V2 CLI:
opencode plugin add @tarquinen/opencode-dcp@latest
This installs the package and adds it to your global OpenCode config.
Project Status
Development on DCP has slowed because most new context-management work has moved to Sleev and the sleev CLI.
Sleev builds on DCP's core ideas with more advanced context management and significantly better performance. It's a local proxy that already supports Claude Code, Codex, OpenCode, Pi, and Hermes, and can be extended to support any harness.
DCP remains available for OpenCode plugin users, but new features are landing in Sleev first. If you are starting fresh, we recommend trying Sleev:
npm i -g sleev
sleev
How It Works
DCP reduces context size through a compress tool and automatic cleanup. Your session history is never modified — DCP replaces pruned content with placeholders before sending requests to your LLM.
Compress
Compress is a tool exposed to your model that replaces closed, stale conversation content with high-fidelity technical summaries. You can think of this as a much smarter version of Opencode's compaction process. Instead of triggering statically when your session reaches its maximum context and on the entire coding session, Compress allows the model to pick when to activate based on task completion, and to only compress the specific messages that are no longer needed verbatim.
DCP supports two compression modes:
rangemode compresses contiguous spans of conversation into one or more summaries.messagemode (experimental) compresses individual raw messages independently, letting the model manage context much more surgically.
In range mode, when a new compression overlaps an earlier one, the earlier summary is nested inside the new one so information is preserved through layers of compression rather than diluted away. In both modes, protected tool outputs (such as subagents and skills) and protected file patterns are kept in compression summaries, ensuring that the most important information is never lost. You can also enable protectUserMessages to preserve your messages verbatim during compression, though note that large prompts (e.g. copy-pasting log files in the prompt) will then never be compressed away.
Deduplication
Identifies repeated tool calls (same tool, same arguments) and keeps only the most recent output. Recalculated when the compress tool runs, so prompt cache is only impacted alongside compression.
Purge Errors
Prunes inputs from errored tool calls after a configurable number of turns. Error messages are preserved; only the potentially large input content is removed. Recalculated on compress tool use.
Configuration
DCP uses its own config file, searched in order:
- Global:
~/.config/opencode/dcp.jsonc(ordcp.json), created automatically on first run - Custom config directory:
$OPENCODE_CONFIG_DIR/dcp.jsonc(ordcp.json), ifOPENCODE_CONFIG_DIRis set - Project:
.opencode/dcp.jsonc(ordcp.json) in your project's.opencodedirectory
Each level overrides the previous, so project settings take priority over global. Restart OpenCode after making config changes.
[!NOTE] If your model has a smaller context window, lower
compress.minContextLimitandcompress.maxContextLimitin your configuration to match the available context.
[!IMPORTANT] Defaults are applied automatically. Expand this if you want to review or override settings.
Default Configuration (click to expand)
{
"$schema": "https://raw.githubusercontent.com/royalcat/opencode-dcp-rc/master/dcp.schema.json",
// Enable or disable the plugin
"enabled": true,
// Enable debug logging to ~/.config/opencode/logs/dcp/
"debug": false,
// Notification display: "off", "minimal", or "detailed"
"pruneNotification": "off",
// Notification type: "chat" (in-conversation) or "toast" (system toast)
"pruneNotificationType": "chat",
// Slash commands configuration
"commands": {
"enabled": true,
// Additional tools to protect from pruning via commands (e.g., /dcp sweep)
"protectedTools": [],
},
// Manual mode: disables autonomous context management,
// tools only run when explicitly triggered via /dcp commands
"manualMode": {
"enabled": false,
// When true, automatic cleanup (deduplication, purgeErrors)
// still runs even in manual mode
"automaticStrategies": true,
},
// Protect from pruning for <turns> message turns past tool invocation
"turnProtection": {
"enabled": false,
"turns": 4,
},
// Experimental settings
"experimental": {
// Allow DCP processing in subagent sessions
"allowSubAgents": false,
// Enable user-editable prompt overrides under dcp-prompts directories
// When false (default), prompt override files/directories are ignored
"customPrompts": false,
},
// Protect file operations from pruning via glob patterns
// Patterns match tool parameters.filePath (e.g. read/write/edit)
"protectedFilePatterns": [],
// Unified context compression tool and behavior settings
"compress": {
// Permission mode: "allow" (no prompt), "ask" (prompt), "deny" (tool not registered)
"permission": "allow",
// Show compression content in a chat notification
"showCompression": false,
// Let active summary tokens extend the effective maxContextLimit
"summaryBuffer": true,
// Soft upper threshold: above this, DCP keeps injecting strong
// compression nudges (based on nudgeFrequency), so compression is
// much more likely. Accepts: number or "X%" of model context window.
"maxContextLimit": "80%",
// Soft lower threshold for reminder nudges: below this, turn/iteration
// reminders are off (compression less likely). At/above this, reminders
// are on. Accepts: number or "X%" of model context window.
"minContextLimit": "20%",
// Optional per-model override for maxContextLimit by providerID/modelID.
// If present, this wins over the global maxContextLimit.
// Accepts: number or "X%".
// Example:
// "modelMaxLimits": {
// "provider/model": "80%"
// },
// Optional per-model override for minContextLimit.
// If present, this wins over the global minContextLimit.
// "modelMinLimits": {
// "provider/model": "25%"
// },
// How often the context-limit nudge fires (1 = every fetch, 5 = every 5th)
"nudgeFrequency": 5,
// Start adding compression reminders after this many
// messages have happened since the last user message
"iterationNudgeThreshold": 15,
// Controls how likely compression is after user messages
// ("strong" = more likely, "soft" = less likely)
"nudgeForce": "soft",
// Tool names whose completed outputs are appended to the compression
"protectedTools": [],
// Preserve text wrapped in <protect>...</protect> when compressed
"protectTags": false,
// Preserve your messages during compression.
// Warning: large copy-pasted prompts will never be compressed away
"protectUserMessages": false,
},
// Automatic pruning strategies
"strategies": {
// Remove duplicate tool calls (same tool with same arguments)
"deduplication": {
"enabled": true,
// Additional tools to protect from pruning
"protectedTools": [],
},
// Prune tool inputs for errored tools after X turns
"purgeErrors": {
"enabled": true,
// Number of turns before errored tool inputs are pruned
"turns": 4,
// Additional tools to protect from pruning
"protectedTools": [],
},
},
}
Commands
DCP provides a TUI panel and one prompt-producing slash command:
/dcp— Opens the DCP panel with context, stats, and manual-mode controls./dcp-compress [focus]— Asks the model to run one compression pass. Optional focus text directs what content to compress, following the activecompress.mode.
Prompt Overrides
DCP exposes the following editable prompts:
systemcompress-rangecompress-messagecontext-limit-nudgeturn-nudgeiteration-nudge
This feature is disabled by default. Set experimental.customPrompts to true in your DCP config to activate it.
When enabled, managed defaults are written to ~/.config/opencode/dcp-prompts/defaults/ as plain-text prompt files. A single README.md in that directory explains each prompt and how to create overrides.
To customize behavior, add a file with the same name under an overrides directory and edit it as plain text.
To reset an override, delete the matching file from your overrides directory.
Protected Tools
By default, these tools are always protected from pruning:
task, skill, todowrite, todoread, compress, batch, plan_enter, plan_exit, write, edit
The protectedTools arrays in commands and strategies add to this default list.
For the compress tool, compress.protectedTools ensures specific tool outputs are appended to the compressed summary. By default it includes task, skill, todowrite, and todoread.
Impact on Prompt Caching
LLM providers cache prompts based on exact prefix matching. When DCP prunes content, it changes messages, which invalidates cached prefixes from that point forward.
Trade-off: Pruning reduces context size but can increase cache misses. The cost balance depends on your conversation, compression frequency, and provider pricing.
No impact for:
- Request-based billing — Some providers charge per request, not tokens.
- Uniform token pricing — Providers that bill cached and uncached tokens at the same rate.
Contributing
See CONTRIBUTING.md for development setup, local installation, and testing with the V1/V2 sandbox.
License
AGPL-3.0-or-later
Similar plugins
Better Compact
better-compact
OpenCode plugin that improves long-session context with boundary-time pruning
Acp
opencode-acp
Active Context Pruning — model-driven context management for OpenCode (hardened fork of DCP with 35 bug fixes)
V2 Slim
@serkanalgur/opencodev2-slim
Smart context management plugin for OpenCode v2 - semantic compression, cost-aware pruning, adaptive thresholds