claude-webcache

io.github.theYahia由 GitHub 帳號 theYahia 發布v0.1.5更新於 Oct 24, 2026

Cross-session WebFetch cache for Claude Code. Unlimited TTL by default, SQLite, MCP plugin.

發布方自己的服務:Claude Platform Docs

概覽

AI 產生的概覽

為 Claude Code 的 WebFetch 與 WebSearch 結果提供本機 SQLite 快取,跨工作階段持久保存,讓助理重用已抓取的頁面而不必重複請求。

可以做什麼
  • 依 URL 與提示詞讀取快取的頁面文字,或依查詢讀取快取的搜尋結果,未命中時回傳快取未命中標記
  • 將 URL、提示詞與輸出寫入快取,並可批次預先檢查一組 URL
  • 檢視快取統計、最近 URL 與依命名空間的明細,並使單筆記錄失效或重新整理
  • 依時間清除項目或整批清空快取,並批次預熱或重新整理項目
  • 透過命令列工具或本機網頁儀表板執行相同操作
適用情境
適合在多個 Claude Code 工作階段中反覆查閱同一批文件或網頁、希望避免重複網路請求及其成本的情境。較適合內容穩定的頁面;搜尋排名與個人化頁面變化較快。
執行需求
以本機程序在使用者電腦上執行,可透過 npm 套件或 Claude Code 外掛安裝。需要 Node.js 22.5 或更新版本,因為使用內建的 node:sqlite 模組。資料存放在使用者家目錄下的本機 SQLite 檔案。選用行為由 WEBCACHE_TTL_DAYS、WEBCACHE_NAMESPACE、WEBCACHE_AUTOREAD 等環境變數控制。
安裝前請注意
快取會把抓取的 URL 與回應寫入本機磁碟;預設只對儲存的 URL 做表面遮蔽,快取鍵仍以原始 URL 計算雜湊。啟用 WEBCACHE_STRICT_REDACT 後快取鍵改用遮蔽後的 URL,可能讓不同使用者的個人化回應落入同一位置。建議改用標頭驗證而非 URL 中的權杖,且不要把快取資料庫提交到 git。清理類工具會刪除快取項目。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 claude-webcache,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

claude-webcache

[npm] [npm downloads] [license] [tests]

Persistent cross-session WebFetch cache for Claude Code. Cached reads in ~0.07ms — orders of magnitude faster than re-fetching.

Claude Code's built-in cache lasts 15 minutes, within one session. Every new session re-fetches from scratch. claude-webcache persists results across sessions in a local SQLite database — instant cache hits, zero network cost.

Session 1  →  WebFetch("docs.example.com")  →  fetched, auto-cached ✓Session 2  →  cached_fetch("docs.example.com")  →  instant hit, no network callSession 7  →  cached_fetch("docs.example.com")  →  still instant, unlimited TTL

v0.1.5+: every WebFetch is automatically saved via PostToolUse hook — nothing to configure.

[CACHE_MISS flow: WebFetch + cache_store in first session] [CACHE_HIT flow: instant hit, no WebFetch in second session]

Install

bash
claude plugin marketplace add theYahia/claude-webcache && claude plugin install claude-webcache@theyahia

Works in: Claude Code CLI · Desktop (Mac/Windows) · VS Code extension · JetBrains plugin — same command everywhere.

Done. Every WebFetch is auto-cached from now on.

Optionally add the usage pattern to ~/.claude/CLAUDE.md to also check the cache before fetching (saves the WebFetch call entirely on repeat URLs).

Plugin TUI not working? There's an open Claude Code bug (#41653) where /plugin install rejects third-party sources with "source type not supported." Use the CLI command above — it bypasses the TUI and works fine.

Fallback (no marketplace):

bash
git clone https://github.com/theYahia/claude-webcache && claude --plugin-dir ./claude-webcache/plugin

Option 2 — npm global

bash
npm i -g @theyahia/claude-webcache

Requires Node.js 22.5+ (uses built-in node:sqlite — no native deps, no install step).

Then register in ~/.claude/settings.json (replace path with output of npm root -g):

json
{  "mcpServers": {    "claude-webcache": {      "command": "node",      "args": ["/path/from/npm-root-g/claude-webcache/scripts/mcp-server.cjs"]    }  },  "hooks": {    "SessionStart": [      {        "matcher": "startup|clear|compact",        "hooks": [          { "type": "command", "command": "node /path/from/npm-root-g/claude-webcache/scripts/hook-stats.cjs" }        ]      }    ]  }}

Option 3 — clone (contributors)

See CONTRIBUTING.md.

Usage pattern (optional — for pre-fetch cache checks)

v0.1.5+ auto-caches every WebFetch automatically. The pattern below is optional: add it to ~/.claude/CLAUDE.md to also check the cache before making a WebFetch — this saves the WebFetch call entirely on repeat URLs.

Auto-read (v0.5+): nothing to do. A PreToolUse hook checks the cache before every WebFetch/WebSearch. On a hit it serves the cached copy and skips the network; on a miss the call runs normally and the PostToolUse hook stores the result. Same URL + same prompt (or same search query) in any future session = instant hit, zero network cost.

Manual lookup is still available if you want it: call cached_fetch(url, prompt) (or cached_search(query)) — returns the cached text, or [CACHE_MISS] … if absent. Disable auto-read with WEBCACHE_AUTOREAD=0.

⚠ Security — authenticated URLs

The cache stores the URL alongside the response in ~/.webcache/cache.db. By default, claude-webcache strips obvious credentials from the stored URL before write (user:pass@host and query params named token, api_key, apikey, access_token, auth, secret, password, key, signature, etc.).

That's display-level redaction, not key-level. The cache key still hashes the original URL, so re-fetching the same authenticated URL hits the cache. If you want a stricter trade-off:

bash
export WEBCACHE_STRICT_REDACT=1

With WEBCACHE_STRICT_REDACT=1, the cache key is computed from the redacted URL too — endpoints differing only in ?token=A vs ?token=B collide in one slot. Safe for pass-through auth (identical content), unsafe for personalized endpoints (different users see each other's cached data).

Bottom line: prefer header-based auth (Authorization: headers) over URL-embedded tokens. Don't commit ~/.webcache/cache.db to git.

Namespaces

Multiple projects sharing one machine? Isolate per-project caches:

bash
WEBCACHE_NAMESPACE=gosdelo  claude    # cache writes/reads scoped to ns "gosdelo"WEBCACHE_NAMESPACE=qsearch  claude    # separate ns, no cross-contamination

Default namespace is the empty string "" (shared cache for v0.3 behavior). Inspect/manage per-namespace via CLI: claude-webcache namespaces, claude-webcache --namespace gosdelo stats.

Tools (MCP)

ToolArgsReturns
cached_fetchurl, promptcached text, or [CACHE_MISS] <url>
cached_searchquerycached WebSearch results, or [CACHE_MISS] <query> (websearch namespace, short TTL)
cache_storeurl, prompt, outputstored
cache_statsglobal?{ namespace, total, hits, misses, hit_rate, last, db_size_bytes, evicted, oversize_skipped, last_hook_error_at, top_urls, ... }
cache_listlimit?, offset?, global?recent URLs (most recent first)
cache_invalidateurl{ deleted: N } — drops every entry for that URL in current namespace
cache_clearolder_than_days?, confirm?{ deleted: N } — partial wipe by age, or full wipe with confirm:"YES"
cache_warmentries: [{url,prompt}] or urls[]+prompt{ hits, misses, invalid } — bulk pre-flight in one call
cache_refreshurl, prompt[CACHE_MISS] <url> — invalidates and signals re-fetch

CLI

The npm package ships a claude-webcache binary for ad-hoc inspection and a local web dashboard:

bash
claude-webcache stats                            # JSON statsclaude-webcache stats --by-domain                # per-domain breakdownclaude-webcache list 20                          # 20 most-recent URLsclaude-webcache list 50 --offset 100             # paginationclaude-webcache invalidate https://news.com/123  # drop one URLclaude-webcache refresh https://news.com/123 --prompt "extract title"   # invalidate one (url,prompt) pairclaude-webcache warm urls.txt --prompt "extract" # bulk pre-flight checkclaude-webcache clear --older-than-days 30       # partial wipeclaude-webcache clear --confirm YES              # full wipe (requires explicit confirm)claude-webcache clear-logs                       # truncate ~/.webcache/hook.logclaude-webcache namespaces                       # list all namespaces presentclaude-webcache export --out cache.json --all    # export metadataclaude-webcache dashboard                        # open http://localhost:37778claude-webcache --namespace gosdelo stats        # scope command to namespace

The dashboard renders top URLs by hits, top domains (with avg hits / last fetch / entry counts), full search-able paginated list with one-click invalidate + refresh buttons. Pure stdlib — no extra deps to install.

Configuration (env vars)

VariableDefaultEffect
WEBCACHE_TTL_DAYSunlimitedGlobal TTL in days. 0 or unset = unlimited.
WEBCACHE_MAX_SIZE_MBunlimitedAbove this size, LRU eviction drops ~20% of oldest-by-last_hit_at entries on next write (debounced every 100 writes).
WEBCACHE_DOMAIN_TTLnonePer-domain TTL JSON: {"news.com":1,"reuters.com":1,"arxiv.org":0}. Days; 0 = unlimited. Suffix-matches subdomains. Overrides global TTL when matched.
WEBCACHE_NAMESPACE"" (shared)Isolate the cache per project. Different namespaces never see each other's entries.
WEBCACHE_MAX_OUTPUT_MB10Reject WebFetch responses larger than N MB. Stats track oversize_skipped counter and last_oversize_url.
WEBCACHE_COMPRESSoff1 enables gzip on responses ≥4 KB. Stored as base64 in TEXT column. Existing uncompressed rows read fine (BC).
WEBCACHE_STRICT_REDACToff1 makes the cache key use the redacted URL — collides per endpoint regardless of token value. See Security above.
WEBCACHE_QUIEToff1 suppresses hook stderr output (file log at ~/.webcache/hook.log still written).
WEBCACHE_DEBUGoff1 enables verbose tracing in the auto-cache hook.
WEBCACHE_SEARCH_TTL_HOURS6TTL for cached WebSearch results (the websearch namespace). Search rankings drift, so this is short by default. 0 = never expire.
WEBCACHE_AUTOREADon0 disables the PreToolUse auto-read hooks (cache still fills via PostToolUse; you read it manually via cached_fetch/cached_search).

SessionStart hook

Every new session injects a one-liner so Claude knows the cache exists:

webcache [ns=gosdelo] 142 pages cached, 87% hit rate, last fetch 3h ago

No output if cache is empty. [ns=...] is omitted when using the default namespace.

Storage

SQLite at ~/.webcache/cache.db (WAL mode, synchronous=NORMAL, busy_timeout=5000). Cache key = SHA256(namespace + "|" + canonical(url) + "|" + prompt). Default TTL: unlimited (set WEBCACHE_TTL_DAYS=N for N-day expiry).

URL canonicalization (v0.4+): lowercase hostname, strip default ports (:80/:443), strip fragment, sort query parameters alphabetically. So https://EXAMPLE.com/p?b=2&a=1#frag and https://example.com/p?a=1&b=2 produce the same cache key — no silent miss on URL formatting variance.

FieldType
keyTEXT PRIMARY KEY
urlTEXT (redacted)
prompt_hashTEXT
outputTEXT (gzip+base64 when compressed=1)
cached_atINTEGER (ms epoch)
hit_countINTEGER
last_hit_atINTEGER
namespaceTEXT (default "")
compressedINTEGER (0/1)

Concurrent-safe via WAL + 5-second busy_timeout — multiple Claude Code sessions can read/write simultaneously without SQLITE_BUSY errors.

Limits

  • Cache key includes the prompt — use consistent prompts to maximize hit rate.
  • Output is whatever WebFetch returns (already summarized). No re-processing.
  • No semantic search. Exact (namespace, canonical_url, prompt) match only.

Benchmarks

Single-process latency on a populated DB (N=10000 entries, 1KB output each), measured via npm run bench:

Opp50p95p99ops/sec
write0.09ms0.15ms2.66ms5,800
read_hit0.07ms0.12ms0.23ms7,600
read_miss0.04ms0.07ms0.13ms17,600
list_500.11ms0.16ms0.53ms7,400

Storage overhead: ~2 KB per entry for a 1 KB payload (key + indexes + WAL + new v0.4 columns). With WEBCACHE_COMPRESS=1 on text-heavy responses, expect 3-7× reduction.

WebFetch over the network typically takes 1-5 seconds — a cached hit is ~15,000-70,000× faster. Reproduce on your hardware: npm run bench. See bench/README.md for methodology and full results metadata (CPU, RAM, OS, commit) saved per run.

Related

  • claude-mem — persistent memory across sessions (complements claude-webcache: memory vs. web cache)
  • WWmcp — catalog of 46 MCP servers for non-Western APIs

License

MIT — see LICENSE.


Часть WWmcp · Telegram: @vhodvai

來源:README.md,提交 58d6198

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.1.5最新Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

其他 Claude 整合