readwise-mcp
by EvanOman
README.md
# readwise-mcp
[](https://github.com/EvanOman/readwise-mcp/actions/workflows/ci.yml)

[](https://pypi.org/project/readwise-mcp/)
[](https://pypi.org/project/readwise-mcp/)
[](LICENSE)
An [MCP](https://modelcontextprotocol.io) server that exposes [Readwise](https://readwise.io) and [Reader](https://read.readwise.io) operations as tools for AI agents — Claude Code, Claude Desktop, or any MCP client.
> **Built on [readwise-plus](https://github.com/EvanOman/readwise-plus).**
> This server is a thin, agent-friendly layer over [`readwise-plus`](https://pypi.org/project/readwise-plus/), a comprehensive async Python SDK for the Readwise (v2) and Reader (v3) APIs. `readwise-plus` does the real work — auth, pagination, typed models, retries — and `readwise-mcp` maps it to MCP tools. If you want to script Readwise directly in Python, use `readwise-plus`; if you want an agent to do it for you, use this.
It gives an agent nine tools for saving, searching, reading, and organizing your Reader documents and Readwise highlights — so you can ask it to "find that article I archived last week" or "save this URL to my reading list" and have it actually do it.
## Requirements
- Python 3.12+
- A Readwise access token — get one at <https://readwise.io/access_token>
- [`uv`](https://docs.astral.sh/uv/) (recommended) for the zero-install `uvx` launch path
## Authentication
The server reads `READWISE_API_KEY` from the environment, falling back to a
`READWISE_API_KEY=` line in `~/.env`. Provide it either way — via the MCP client
config (below), an exported shell variable, or `~/.env`. See [`.env.example`](.env.example).
## Install & register
### Claude Code
```bash
claude mcp add readwise --env READWISE_API_KEY=your-token -- uvx readwise-mcp
```
(Omit `--env ...` if you already keep `READWISE_API_KEY` in `~/.env`.)
### Any MCP client (Claude Desktop, etc.)
Add this to the client's MCP server config (e.g. `claude_desktop_config.json` or `~/.claude.json`):
```json
{
"mcpServers": {
"readwise": {
"command": "uvx",
"args": ["readwise-mcp"],
"env": { "READWISE_API_KEY": "your-token" }
}
}
}
```
`uvx readwise-mcp` fetches and runs the latest published version on demand — no manual install step. Prefer a pinned install? Use `uv tool install readwise-mcp` and point `command` at `readwise-mcp`.
### From source
```bash
git clone https://github.com/EvanOman/readwise-mcp
cd readwise-mcp
uv sync --dev
```
Then register the local checkout:
```json
{
"mcpServers": {
"readwise": {
"command": "uv",
"args": ["run", "--project", "/absolute/path/to/readwise-mcp", "python", "-m", "readwise_mcp"],
"env": { "READWISE_API_KEY": "your-token" }
}
}
}
```
Verify it connected: `claude mcp list` should show `readwise: ... Connected`.
## How to use
Once the server is registered, you don't call the tools directly — you talk to your agent in plain language and it picks the right tool. Some things you can ask:
| You say… | The agent uses… |
|----------|-----------------|
| "Save https://example.com/post to my reading list and tag it `ai`." | `save_to_reader` |
| "Find the article about vector databases I archived last week." | `search_documents` → `get_document` |
| "Summarize the top 3 unread articles in my inbox." | `search_documents(location="new")` → `get_document` |
| "Export my highlights from *Thinking, Fast and Slow*." | `get_books` → `export_highlights` |
| "Archive that document." / "Move it to my reading list." | `update_document` |
| "Save this quote as a highlight under *Deep Work*." | `create_highlight` |
### Walkthrough: "find and read that article"
> **You:** Find the article I saved about the OpenAI harness engineering post and give me the key points.
Behind the scenes the agent:
1. Calls `search_documents(query="harness engineering")` — a title substring search across your library — and gets back compact summaries (id, title, author, location), no body text.
2. Picks the best match and calls `get_document(document_id=...)` to pull the full HTML content.
3. Reads the content and answers you.
### Notes on behavior
- **Search is title-substring, client-side.** `query` filters on the document title, not full text. To narrow the set first, combine it with `location` (`new`/`later`/`archive`), `category`, or `tags`.
- **`get_document` is the only call that returns full content.** `search_documents` deliberately returns summaries so the agent can scan cheaply, then fetch the one it wants.
- **Uploads:** `save_to_reader` can save a plain URL, or upload your own HTML by passing `html=` alongside a synthetic `url` (used as the unique id).
- **Errors are data, not exceptions.** Tools return `{"error": "..."}` so the agent can read the problem and recover rather than crashing.
- **Deletes are permanent.** `delete_document` cannot be undone.
- Documents saved through this server are tagged `saved_using="readwise-mcp"` in Reader.
## Tools
### Documents (Reader v3)
| Tool | Description |
|------|-------------|
| `save_to_reader` | Save a URL to Reader, or upload HTML content with a synthetic URL. Supports title, author, summary, tags, notes, category, and location overrides. |
| `search_documents` | List/filter documents by location (inbox/later/archive), category, tags, updated_after. Client-side title substring search via `query`. Returns compact summaries (no content). |
| `get_document` | Fetch a single document by ID with full HTML content. |
| `update_document` | Update metadata, move between locations (inbox/later/archive), or replace tags. |
| `delete_document` | Permanently delete a document. |
### Highlights (Readwise v2)
| Tool | Description |
|------|-------------|
| `get_highlights` | List highlights with filters (book_id, updated_after, text query). |
| `export_highlights` | Bulk export highlights grouped by book — more efficient for pulling all highlights from multiple books. |
| `create_highlight` | Push a new highlight to Readwise. Auto-creates the book/source if it does not exist. |
### Books (Readwise v2)
| Tool | Description |
|------|-------------|
| `get_books` | List books/sources with category, source, and title query filters. |
## Design
Tools are shaped for agent ergonomics: a small set of well-composed tools rather than a thin wrapper per endpoint. Results are returned as compact JSON strings, and errors come back as `{"error": ...}` payloads instead of exceptions, so an agent can read and react to them. All Readwise access goes through the [`readwise-plus`](https://github.com/EvanOman/readwise-plus) SDK's async client.
## Development
```bash
just fc # format, lint-fix, lint, type-check, test (run before every commit)
just test # unit tests (mocked HTTP, no network)
just test-live # live tests against the real Readwise API (requires READWISE_API_KEY)
just ci # what CI runs: lint, format-check, type, test
```
Stack: [uv](https://docs.astral.sh/uv/) · [ruff](https://docs.astral.sh/ruff/) · [ty](https://github.com/astral-sh/ty) · [pytest](https://docs.pytest.org/) · [just](https://github.com/casey/just).
Releases are automated with [release-please](https://github.com/googleapis/release-please): merging the release PR tags a version and publishes to PyPI via trusted publishing.
## License
MIT — see [LICENSE](LICENSE). Built on [readwise-plus](https://github.com/EvanOman/readwise-plus), also MIT.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing