Use a coding agent
Sponge is a local read-later library. Agents can use it two ways: the sponge
CLI with --json, or the sponge mcp server. Both work on the same local
library, and capture always happens on your own device. Claude Code, Codex,
OpenCode, and any agent that can execute commands or connect a local MCP
server can use these interfaces. No particular model or coding agent is required.
Install and set up
Section titled “Install and set up”npm install -g @hraness/spongesponge init # create the library in ~/.local/share/spongesponge list --jsonUse Node.js 24.20 or newer. sponge init creates the local library. Read and
keyword search need no account or model download. Run sponge setup --digest when you
want local summaries. CLI semantic search needs sponge setup --embedding, on Apple Silicon Macs
with macOS 26; see Requirements and platforms. sponge doctor shows what is
installed. Run sponge login and
sponge sync when you want sync, the web library, and the save queue.
sponge login opens the approval page in the default browser (or prints the link
over SSH, in CI and with --no-browser) and waits. In scripts, use
sponge login --no-wait, approve the link, then run sponge login --finish.
Connect an MCP client
Section titled “Connect an MCP client”Claude Code:
claude mcp add --transport stdio sponge -- sponge mcpCodex:
codex mcp add sponge -- sponge mcpcodex mcp listYou can also configure Codex in ~/.codex/config.toml or a project’s
.codex/config.toml:
[mcp_servers.sponge]command = "sponge"args = ["mcp"]OpenCode (opencode.json):
{ "$schema": "https://opencode.ai/config.json", "mcp": { "sponge": { "type": "local", "command": ["sponge", "mcp"], "enabled": true } }}Other clients:
{ "mcpServers": { "sponge": { "command": "sponge", "args": ["mcp"] } } }To serve a library outside the default location, add
"--library", "/absolute/path" to args.
For OpenCode, append those two values to its command array instead. The
client starts a process that can read and change that library as you. Keep
its ordinary tool approval settings and choose the library you intend to expose.
Client configuration follows the official Claude Code MCP guide, Codex MCP guide, and OpenCode MCP guide.
| Tool | What it does |
|---|---|
search_library |
Search by meaning and keywords. Falls back to keyword search without models. |
list_items |
List items newest first. Filters: reading, kind, limit, offset. |
read_item |
Read Markdown a page at a time (offset, maxChars), or format: "summary". |
save_url |
Capture a URL into the local library now. An optional note becomes a comment. |
queue_save |
Queue a URL in your account. Your ingest leader captures it on its next sync. |
add_highlight |
Highlight a verbatim quote, with an optional comment; occurrence picks a match. |
add_comment |
Comment on an item. |
sync |
Sync; on the ingest leader, also capture queued saves. |
A failed tool call returns isError: true with { "code", "hint" }. The hint
says what to do next, such as “Run sponge login”. Some failures add a narrower
reason: item-not-found, item-deleted (a deleted source cannot be saved
again), sync-busy (another sync is running; retry), quote-not-found and
quote-ambiguous, which also carries matches, the number of places the quote
occurs.
read_item sends Markdown as plain text in content, 40,000 characters at a
time unless maxChars (up to 200,000) asks for more. structuredContent holds
the item’s fields with offset, nextOffset and totalChars, and not the
Markdown again. While nextOffset is a number there is more: call again with
offset set to it.
save_url attaches its note when the save is queued, so a capture still
pending when the call returns keeps it. Calling again with the same URL and
note adds nothing.
The MCP reference lists each tool’s input schema and effects.
Complete a reading task
Section titled “Complete a reading task”After connecting the server, ask your agent to search for a topic in the library,
read one result, and add a note explaining why it is useful. The sequence is
search_library, read_item, and add_comment. The first two calls read local
content; the final call writes an annotation. Confirm the result with
read_item using format: "summary", which includes annotations.
Without MCP, the same task works through the CLI:
sponge search "your topic" --jsonsponge show ITEM --jsonsponge comment ITEM "Why this source is useful" --jsonReplace ITEM with an itemId returned by search. CLI reference
covers commands, flags, and failure statuses. Sponge has no separately supported
JavaScript SDK; use these stable interfaces when integrating another tool.
CLI with –json
Section titled “CLI with –json”For ordinary CLI commands, --json returns a single JSON object with
"ok": true on stdout after success. On failure, stdout is empty and stderr
gets JSON containing code, reason and hint. phase appears only when a
capture failed while it ran. Without --json, a failure is the same JSON line
unless stdout is a terminal, where it is one plain line and the hint. The
long-running sponge mcp server uses the MCP JSON-RPC message stream
instead. The process exits with one of these statuses:
| Exit | Meaning |
|---|---|
| 0 | ok |
| 1 | failed |
| 2 | invalid input |
| 3 | partial |
| 4 | action required |
| 130 | cancelled |
Commands never prompt. Output written for a person (dates in list, next steps,
readable sizes) appears only when stdout is a terminal; piped output and --json
keep their shapes. reason narrows code without changing the exit status:
library-missing (run sponge init), item-not-found, item-deleted,
sync-busy (another sync held the library for 30 seconds; retry),
already-signed-in, unsupported-file, quote-not-found and quote-ambiguous.
sponge list --json lists every item, oldest first, each with createdAt;
--limit N asks for the N newest instead.
sponge add https://example.com/essay --wait --json # savesponge search "attention economy" --json # search (add --mode lexical without models)sponge list --jsonsponge show ITEM --json # read: Markdown plus annotations and digestsponge highlight ITEM "exact quote" --note "why" --jsonsponge comment ITEM "a thought" --jsonSave queue
Section titled “Save queue”A save request is a URL waiting in your account. You can queue one from the web
library, queue_save, or sponge saves add. The account’s ingest leader, one
signed-in device chosen by the cloud, claims it, captures it with the normal
sponge add pipeline, summarizes it with its local model when it has one and
syncs the item back. There is no summary tool: summaries happen on the leader. The
cloud keeps only the URL, the request’s state and a short error code; it never
captures pages itself.
sponge saves --json # open and recent requestssponge saves add https://example.com/a --json # queue a URLsponge saves run --json # capture queued requests on this device nowsponge sync # also captures and summarizes on the leader (--no-saves, --no-digest)sponge sync --watch # keeps doing both every 30 secondssponge status --json # "ingest": which device leads, from its last heartbeatA request moves through these states:
queuedbecomesclaimedwhen a device takes it.- A
claimedrequest becomessaved(with anitemId) orfailed(with anerrorCode). - A queued request can be cancelled.
- A failed request can be retried, which puts it back in
queued.
A claim lasts 10 minutes. If the device does not finish in time, another device can claim the request again.
Leadership prefers a device with a local summary model (sponge setup --digest)
and moves to another capable device when the leader stops checking in for two
minutes. sponge saves starts with “Saving on NAME”, or says no capable device
is online.
Documentation drafted with AI and checked against the product source.