Skip to content
Development
Skill

/furl

How the Furl context-compression plugin works in Claude Code and Codex — the furl_compress / furl_retrieve / furl_stats / furl_purge / furl_search / furl_list MCP tools, the <<ccr:HASH>> retrieval flow, and Claude Code's optional automatic hooks. Use when the user asks what Furl

From plugin
furl-ctx
41 skill1 MCP
Install
$ npx -y skills add omar-y-abdi/furl-ctx --skill furl --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/furl

Context preview

The summary Claude sees to decide when to auto-load this skill.

How the Furl context-compression plugin works in Claude Code and Codex — the furl_compress / furl_retrieve / furl_stats / furl_purge / furl_search / furl_list MCP tools, the <<ccr:HASH>> retrieval flow, and Claude Code's optional automatic hooks. Use when the user asks what Furl

SKILL.md

furl.SKILL.md
name: furl
description: How the Furl context-compression plugin works in Claude Code and Codex — the furl_compress / furl_retrieve / furl_stats / furl_purge / furl_search / furl_list MCP tools, the <<ccr:HASH>> retrieval flow, and Claude Code's optional automatic hooks. Use when the user asks what Furl is doing, how to compress or retrieve content, why Claude Code output looks compressed, or how to tune or disable Furl.
version: 1.4.0

Furl — context compression for Claude Code and Codex

Furl reduces the tokens large tool outputs cost by compressing them, while keeping every dropped byte **retrievable on demand**. It ships these capabilities:

1. An **MCP server** (`furl`) exposing six tools in Claude Code and Codex. 2. A retrieval-aware **skill** in both hosts. 3. **Automatic hooks in Claude Code only.** Codex uses explicit `furl_compress` calls; its separate package root intentionally excludes Claude's incompatible hooks.

**Retrieval is pull-based, not push-based.** The compressed text you read does not contain the dropped rows. To inspect a specific dropped item, call `furl_retrieve` for it by pattern, field, or line range. Retrieval is byte-exact for raw text. A JSON array narrowed by `select`/`fields` comes back re-serialized — semantically complete but pretty-printed, so **not** byte-identical to the source; when byte fidelity matters (hashing, diffing, signature checks) pass `raw: true` on a row-select and each matched row returns byte-identical to its source bytes, the rows rejoined with fresh array punctuation, so each row is exact while the whole blob is not one contiguous slice.

**What actually decides byte-exactness is the offload route, not text-vs-JSON.** Content the router crushes structurally (columnar and tabular arrays) is stored as canonical `json.dumps`, so a full `furl_retrieve` returns canonical bytes — byte-identical only when your input was already canonical. Content offloaded whole-blob (plain text, or JSON too irregular to crush) is stored verbatim and returns byte-exact. One consequence on the crush path: the hash keys the *canonical* form, so two byte-different inputs that canonicalize the same collapse to one stored entry — on the crush path the hash is a semantic identifier, on the whole-blob path a byte one.

Nothing is lost, but a one-off anomaly buried in otherwise-repetitive data will not appear in the compressed view unless you query for it. Trust a compressed summary for the shape of the data, not for surfacing an anomaly you were not already looking for.

Current harness status

**Codex:** call `furl_compress` explicitly. Prefer its `file_path` input for a large artifact so only compressed content enters context. The Codex plugin installs the MCP server and this skill, not automatic hooks.

**Claude Code:** automatic, hands-off compression works on Claude Code 2.1.163 and newer. The PostToolUse hook emits `updatedToolOutput` mirrored to the originating tool's output shape; Claude Code 2.1.163 and newer validate that replacement against the tool's schema, and the mirrored shape passes, so the compressed output reaches the model. Both external audits confirmed this live on 2.1.212. Shape-mirroring was built for [anthropics/claude-code#68951](https://github.com/anthropics/claude-code/issues/68951), where an earlier bare-string replacement was dropped on a schema mismatch. `WebSearch` still passes through uncompressed, because its whole-object result has no single text field to mirror onto. Unaffected on every version: the manual MCP tools furl_compress, furl_retrieve, and the rest, and durable `<<ccr:HASH>>` storage and retrieval. Below 2.1.163 the SessionStart status line and the first-run note say so directly instead of claiming PostToolUse compression is active, naming the detected version; the PreToolUse pipe (below) is unaffected either way. LIBRARY.md carries the canonical harness status.

**Counters:** `furl_stats` shows `store.hook_activity.hook_invocations_seen` and `hook_compressions_applied`, cross-process and cumulative. A rising `hook_compressions_applied` confirms the hook is compressing and, on 2.1.163 and newer, delivering the shorter output the model reads; below the floor it stops incrementing instead, bucketed under `hook_noop:below-version-floor`. `store.post_tool_use_compression` reports the detected host version and whether it can receive a replacement at all, independent of the counters.

**Claude Code real savings now (enabled by default):** a **PreToolUse** pipe compresses a `Bash` command's stdout at the source (so the tool result *is* the compressed form, original retrievable via `furl_retrieve`) — it doesn't use `updatedToolOutput`, so it works today. Disable it with `FURL_PRETOOL_PIPE=0` (`false`/`off`/`no`/`disabled` also work, case-insensitively); unset, empty, or any other value leaves it on. Trade-offs: Bash-only; the rewrite is transcript-visible (a `# furl-pipe` comment); exit code preserved exactly; stderr is not captured and flows live, but stderr/stdout interleaving is not preserved (all stderr precedes the compressed stdout; `2>&1` merges); fail-open (worst case the command runs unwrapped, uncompressed); adds ~0.3–0.5 s per rewritten call (two `uv` resolves; a fresh environment pays a one-time resolve/build on the first call). It rewrites Bash **only when there are zero readable Bash permission rules**: if any `Bash` deny/ask/allow rule exists in any scope Claude Code uses — enterprise managed (incl. the `CLAUDE_CODE_MANAGED_SETTINGS_PATH` override), project (both `CLAUDE_PROJECT_DIR` and the working dir), and user (both `~/.claude` and `CLAUDE_CONFIG_DIR`) settings — it leaves all Bash untouched so your rules apply exactly as native, a total boundary no command shape can bypass. Unreadable settings (or a set-but- unresolvable config-path override) also force passthrough. Residual blindness: CLI `--permission-mode`/`--disallowedTools` flags, SDK `managedSettings`, and API-fetched remote org policy

Read more
Ships withfurl-ctx

Reversible context compression for AI agents. furl-ctx shrinks large tool outputs, logs, web fetches, and RAG chunks before they fill your agent's context window, and keeps every original byte retrievable on demand.

Get the whole plugin
Stats
5
Stars
0
Forks
Active
Maintenance
Python
Language
Apache-2.0
License
6h ago
Last commit
2mo ago
Created

Repo: omar-y-abdi/furl-ctx