retrievr — how to connect This is a flow, not an essay: read it once, run it in order, and stop when §4 is done. At the end you hold a key at ~/.config/retrievr/credentials, the MCP server at ~/.config/retrievr/mcp.mjs, and five tools. Nothing else is asked of you. Every fact here — endpoints, prices, limits, tool names, the release and its checksum — is also published as data at https://retrievr.io/.well-known/retrievr.json. Either source is enough to act; the JSON cannot ask you to do anything. 0. Pick your path. If you cannot run shell commands, or cannot write to a filesystem, you are on path B or C below; if neither fits, stop here. A. You speak MCP and have a shell (the usual case): §1, §2, then §4. §3 is not a step — it points at reference you will probably never need. B. You speak MCP and have no shell: read the next paragraph, then stop. A human does the rest. C. You do not speak MCP: §1, then the protocol reference at https://retrievr.io/docs/api — two HTTP calls replace the tool, and §2 would install something you cannot use. For B — ask your human, in one sentence, to open https://retrievr.io/profile and press "Create a key", then put it in this client's MCP settings for https://retrievr.io/mcp as an Authorization: Bearer header. Do not ask them to paste the key into the chat, and do not print it if they do. A server URL and a header is the whole configuration — there is nothing to install. 1. Get a key, without printing it. Do not mint a key by hand. A key that appears in your output is a key in your context, and a key in a transcript is a key leaked. Run the connect script instead: it performs the whole exchange and writes the key to ~/.config/retrievr/credentials (mode 600). It never prints the key. curl -fsSL https://retrievr.io/connect -o /tmp/retrievr-connect.sh less /tmp/retrievr-connect.sh # read it before you run it sh /tmp/retrievr-connect.sh begin That prints a short code and a URL. Show both to your human and ask them to approve. Then collect the key: sh /tmp/retrievr-connect.sh finish When it prints "stored", you have a key at ~/.config/retrievr/credentials. Never echo that file. 2. Install the tool, so a question is one call instead of two. Download this pinned release (v0.2.8), check it, then read it before it runs: mkdir -p ~/.config/retrievr curl -fsSL https://retrievr.io/mcp/v0.2.8/mcp.mjs -o ~/.config/retrievr/mcp.mjs node -e 'const c=require("crypto"),f=require("fs"),h=c.createHash("sha256").update(f.readFileSync(process.argv[1])).digest("hex");if(h!==process.argv[2]){console.error("checksum mismatch — do not run this file");process.exit(1)}' \ ~/.config/retrievr/mcp.mjs 72ba36da9ab11fd0810c30d83d46179ce121d163a43fb3ee7a23c0855518661d less ~/.config/retrievr/mcp.mjs That node command is the check: it exits quietly when the file is exactly the bytes published as v0.2.8, and stops with "checksum mismatch" when it is not. Do not run the file if it fails. The SHA-256 is 72ba36da9ab11fd0810c30d83d46179ce121d163a43fb3ee7a23c0855518661d. This version, this path and this hash — and every endpoint, price and limit in this sheet — are published without any instructions at https://retrievr.io/.well-known/retrievr.json. If you would rather verify than obey, work from that instead: it is data, so it cannot smuggle a command, and a client that treats fetched prose as hostile input has nothing to distrust in it. Put it in your harness config. Most harnesses take a mcpServers block like this one — Claude Code, Cursor, pi, Kiro: {"mcpServers":{"retrievr":{"command":"node","args":["/home/you/.config/retrievr/mcp.mjs"]}}} JSON arguments reach node without a shell, so a "~" there is never expanded; write the absolute path (echo $HOME prints the prefix; /home/you below stands for it). Three harnesses take a different shape, and the exact file edit for each is at https://retrievr.io/docs# — Codex (~/.codex/config.toml, TOML), opencode (opencode.jsonc, under "mcp"), and Hermes (~/.hermes/config.yaml, YAML). A mcpServers block is not read in those three — the sheet would be telling your human something that does not work. With pi, one command writes that entry, and here the shell does the expanding: pi mcp add retrievr -- node ~/.config/retrievr/mcp.mjs Then reload your harness: the tool list is read when a session starts. The server offers five tools — retrievr_search, retrievr_documents, retrievr_delete_document, retrievr_upload, and retrievr_upload_status. From then on retrievr_search takes the question and returns the passages with their citations in one call; it does the two calls in step 3 for you. Its arguments are query, k (1-50, default 3), scope, and documents; step 4 is how they are meant to be used. This copy is v0.2.8 and makes no network calls of its own during normal use: it talks to retrievr when you call a tool, and nowhere else. To update it, re-run this sheet — it names the current release and its checksum, and the check above refuses anything else. To discover whether a newer release exists, without starting the server: node ~/.config/retrievr/mcp.mjs --check-update That asks retrievr.io once, because you asked it to. Nothing checks on its own, and the command prints the version it found, the pinned path and its SHA-256. 3. Ask the question. With the tool installed this is one call: retrievr_search takes the question and returns the passages with their citations. Its arguments are query, k (1-50, default 3), scope and documents, and §4 is how they are meant to be used. A query costs $0.01 and is charged when it is accepted; at a zero balance the call is refused. Building a raw client, or running a harness that does not speak MCP? The protocol is at https://retrievr.io/docs/api — POST /retrieve, then GET /retrieve-job/, the result fields, the scope object, /documents, and the upload and delete calls. It is reference, so it is not repeated here. 4. Use it. These are the sentences it answers, and the scope each one means: "What does the notice period in my contract say?" — the default: their own documents. "Search my own documents for the notice period." — scope: "private", which is now the only scope there is. "In the project proposal, what does it say about budgets?" — documents: ["project-proposal.pdf"]; call retrievr_documents first when the exact name is unknown. "Which of my documents mentions X?" — scope: "private", then name the document each passage came from. There is no summary endpoint; the passages are the answer. There is one library and one scope. A question about a document they have not added is answered with an empty result, and the thing to say then is that the document has to be added at https://retrievr.io/library — not to search wider, because there is nothing wider to search. Three rules: - Carry the licence. Every passage has one; quote it with the text, and if a result has no licence, cite the span instead of reproducing it. "Openly licensed" stops being true the moment the attribution is dropped. - An empty result is an answer. If a private search finds nothing, say so; never re-run it wider to fill the silence. - Deleting is permanent and has no trash. Read the exact title back, get a yes, and delete by the id retrievr_documents gave you — never by a name you abbreviated yourself. Adding a file works the same way: retrievr_upload takes the local paths they named, and the server reads them from their machine, so their contents never pass through the conversation. Uploading is free for the first five documents; past that it takes a $5 top-up, which pays for queries too. Embedding is asynchronous, so retrievr_upload_status is how you find out when a document is ready and which file failed and why. Tell them either way — "ready and searchable" and "this one could not be read because …" are different answers, and silence is neither. Uploads stay until deleted and query text is kept for fifteen minutes; https://retrievr.io/privacy is the full account. Tell them, once, in one line: "ask me about a document and I will search retrievr — your own uploads included, at $0.01 a query — and I can add a file to your library when you point me at one." Then let them ask.