mcp-show-on-kindle
An MCP server with one tool, show(file_path). You tell your LLM to put a document on your Kindle, and a few seconds later the document is on the Kindle, open, on screen. That is the entire feature set.
It works like this: the server finds the Kindle on the local network by its KOReader SSH banner, copies the file in over KOReader's SSH server plugin, and then asks the running KOReader to open it through the HTTP inspector plugin. The inspector is only ever reached through the SSH session against the Kindle's loopback, so the only thing on the wire is SSH.
Three details of the implementation deserve a mention, because each one cost me an evening:
An e-reader's wifi radio sleeps very hard. Hard enough that the first sweep of the subnet usually finds nothing; its real job is to wake the radio up. The second sweep finds the Kindle. So the sweep runs twice, 64 probes wide, and the result is cached for next time.
Dropbear has no scp. The file is copied with cat > over the SSH session's
stdin, like it is 1987, and this works fine.
When KOReader opens a document it tears down the whole UI and builds a new one, and the HTTP inspector goes down with it. A successful open therefore looks exactly like a failure: the request that worked is the one whose connection died. The server tells the two apart by polling afterwards and asking the new UI which document it has open.
Setup on the Kindle
Enable two KOReader plugins on autostart:
- SSH server: port 2222
- HTTP inspector: port 8080
Install a dedicated key:
ssh-keygen -t ed25519 -N "" -f ~/.config/mcp-show-on-kindle/id_ed25519
cat ~/.config/mcp-show-on-kindle/id_ed25519.pub | \
ssh -p 2222 root@KINDLE "cat >> /mnt/us/koreader/settings/SSH/authorized_keys"
The inspector has no authentication, so block it from the network:
ssh -p 2222 root@KINDLE "iptables -I INPUT 1 -p tcp --dport 8080 ! -i lo -j DROP"
Add the same line near the top of /mnt/us/koreader/koreader.sh to apply it on every start.
Setup on the computer
Add to your MCP client config (Claude Desktop, Claude Code, ...):
{
"mcpServers": {
"show_on_kindle": {
"command": "uvx",
"args": ["--from", "mcp-show-on-kindle==2026.10.15.174202",
"--refresh-package", "mcp-show-on-kindle", "mcp-show-on-kindle"],
"env": {
"KINDLE_ALLOWED_DIRECTORIES": "/some/dir"
}
}
}
}
Or run it as a long-running service with --transport streamable-http --port 7004 and this client config:
{"mcpServers": {"show_on_kindle": {"type": "http", "url": "http://localhost:7004/mcp"}}}
For hacking on a checkout: uv sync, then point the client at "command": "uv", "args": ["run", "--directory", "/path/to/checkout", "mcp-show-on-kindle"].
Configuration
KINDLE_ALLOWED_DIRECTORIES directories show() may read from. Required.
KINDLE_HOST Kindle IP. Default: scan the /24, cache the result.
KINDLE_SSH_PORT default 2222
KINDLE_HTTP_PORT default 8080
KINDLE_DIR target directory, default /mnt/us/documents/llm
KINDLE_SSH_KEY path to the dedicated private key (default: ssh's normal
identity resolution, which needs an agent for passphrase keys)
KINDLE_KNOWN_HOSTS pinned host key, default ~/.config/mcp-show-on-kindle/known_hosts
Security
The banner only locates the Kindle. Authentication is the SSH host key, pinned on first contact under a fixed alias; a different host presenting the same banner fails. File reads are restricted to KINDLE_ALLOWED_DIRECTORIES, and filenames are reduced to [A-Za-z0-9._-] before they are used in a remote command. With the iptables rule in place the Kindle exposes nothing but public-key SSH. Set KINDLE_SSH_KEY to a separate passphrase-less key that grants access to nothing else.
Tests
make tests-run
ssh and sockets are mocked; the tests run without a Kindle.
My Other LLM Projects
- MCP Alchemy - Connect Claude Desktop to databases for exploring schema and running SQL.
- MCP Redmine - Let Claude Desktop manage your Redmine projects and issues.
- MCP Notmuch Sendmail - Email assistant for Claude Desktop using notmuch.
- Diffpilot - Multi-column git diff viewer with file grouping and tagging.
- Claude Local Files - Access local files in Claude Desktop artifacts.
License
MPL 2.0
Metadata
Release files for mcp-show-on-kindle 2026.10.15.174202
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcp_show_on_kindle-2026.10.15.174202.tar.gz | 82.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_show_on_kindle-2026.10.15.174202-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 95.0 kB
Release files / mcp_show_on_kindle-2026.10.15.174202.tar.gz
| Download URL | mcp_show_on_kindle-2026.10.15.174202.tar.gz |
|---|---|
| Size | 82.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1c784138a61f2a4aa98c851699daecd136907092f623e83d52f4dfeb63cdc8a1
|
|
BLAKE2b-256 checksum How to use checksums |
0337c824782b4b25c1e31224b7e0c5d00f02cde9c56a2fb2ecdf8ce008600e0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.12
|
Release files / mcp_show_on_kindle-2026.10.15.174202-py3-none-any.whl
| Download URL | mcp_show_on_kindle-2026.10.15.174202-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ffb9b13d463181bf5e49dab4c0bb7ea7e2c10f4cb188c68d2543374f681bb7a
|
|
BLAKE2b-256 checksum How to use checksums |
03cddccee15606126013c5783d3be7e79eec812cfee91e15ffa40e883934e8b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.12
|