Let a coding agent search the library pedro has read - #19
Merged
Conversation
pedro borrows a coding agent's credentials to answer a question about a book. This runs the same relationship the other way round: `pedro-mcp` serves the library over MCP, so an agent working on your code can search the documents you actually read and quote the page it found them on. Five tools — `list_books`, `search_library`, `read_pages`, `book_contents`, `add_book` — over the same hybrid index the reader's search box uses. It opens the same SQLite database the reader does, in WAL mode, so both can be open at once. JSON-RPC by hand rather than an SDK: the workspace has no async runtime, and MCP's stdio transport is newline-delimited JSON with four methods, so a client library would have brought tokio along for nothing. Two things are deliberately absent. There is no tool for asking a question: pedro answers questions by handing a passage to an agent CLI, and whatever is calling these tools is already that agent — what it wants from pedro is the retrieval, not a second opinion from a second model one step further away from it. And there is none for removing a book, because deleting one takes its highlights and conversations with it, which is the reader's own decision to make. Hits are numbered rather than scored. The two rankings are fused by position, so the number that falls out is a rank wearing a score, and a model shown `0.03` would read a good hit as a bad one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
pedro borrows a coding agent's credentials to answer a question about a book.
This runs the same relationship the other way round: a new
pedro-mcpcrateserves the library over MCP, so an agent working on your code can search the
documents you actually read and quote the page it found them on.
The tools
list_bookssearch_libraryread_pagesbook_contentsadd_bookThe same hybrid index the reader's search box uses: the words, and — once the
embedding model has been fetched — what they mean, the two rankings fused. It
opens the same SQLite database the reader does, in WAL mode, so both can be
open at once and a book added in one is there in the other. Nothing but
add_bookneeds pdfium, because the pages come from text already extractedinto the library.
cargo build --release -p pedro-mcp claude mcp add pedro -- "$PWD/target/release/pedro-mcp"What is deliberately absent
No tool for asking a question. pedro answers questions by handing a passage
to an agent CLI, and whatever is calling these tools is already that agent —
what it wants from pedro is the retrieval, not a second opinion from a second
model one step further away from it.
No tool for removing a book. Adding one costs a file and is undone in the
reader; deleting one takes its highlights and conversations with it, which is
the reader's own decision to make.
Two decisions worth the review
JSON-RPC by hand rather than an SDK. The workspace has no async runtime
anywhere, and MCP's stdio transport is newline-delimited JSON with four
methods, so
rmcpwould have brought tokio along for nothing.protocol.rsis85 lines.
Hits are numbered, not scored. The two rankings are fused by position, so
the number that falls out is a rank wearing a score: a genuinely good hit
prints
0.03, and a model shown that would read it as a bad one. Rank order isthe only interpretable signal, so that is what the tool returns.
A limitation to know about
search_librarywithbook_idfilters afterStore::searchhas ranked thewhole library and taken its top 40, so a book whose matches sit deep in a
library-wide ranking can come back empty. The tool says "Other books in the
library do match" so a caller can tell that case from a genuine miss, but the
real fix is pushing a book filter into
index::search's SQL — upstream inpedro-core/pedro-search, wherepassages_forhas the same shape. Left forits own change.
Checks
cargo fmt --all --check,clippy --locked --workspace --all-targets --all-featuresunderRUSTFLAGS=-D warnings, andcargo test --locked --workspace --all-featuresall pass: 338 tests, 22 of them new.The new tests drive
Session::handledirectly, which is what the stdio loopcalls per line, so they cover the protocol and the tools without a subprocess:
parse errors, notifications going unanswered, a stray reply, a request naming
no method (which would otherwise leave a client waiting on an id for ever), and
the whole add → list → search → read path against real PDFs.
Also checked by hand against a real library over an actual pipe — a search for
ヴィジュネル暗号の鍵長を推定する方法 returned the Kasiski-examination pages of
the book on the shelf.
🤖 Generated with Claude Code