Skip to content

Repository files navigation

Kindle Agent Controller (KAC) πŸ“–βš‘πŸ€–

An experimental agent harness, headless touch driver, and screenshot feedback loop for jailbroken Amazon Kindle devices running KOReader.

License: MIT Python 3.9+ MCP stdio

KAC lets local agents and test pipelines interact with a physical Kindle over SSH. It provides touch injection, gestures, bounded lifecycle operations, and framebuffer snapshots without modifying the Kindle root filesystem.

Warning

This is a field-tested research baseline, not a consumer-ready jailbreak or remote-desktop product. It controls a real device through an SSH service that commonly runs as root. Read SAFETY.md before use.


πŸ’‘ The Breakthrough

Modern Kindles running stripped-down BusyBox lack standard Linux automation packages like evemu, xdotool, adb, or python.

KAC solves this problem by using KOReader's bundled LuaJIT runtime with Foreign Function Interface (FFI) to dispatch Linux Multi-Touch Type B kernel events (struct input_event) to the input device selected by the active model profile.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     AI Agent (Claude / Codex / Antigravity / Cursor)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚ (JSON-RPC / MCP or CLI)
                            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚             Kindle Agent Controller (Mac / PC)         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ (SSH / Port 2222)        β”‚ (Frame Buffer SCP)
               β–Ό                          β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LuaJIT FFI System Calls      β”‚ β”‚ /dev/fb0 Raw Dump     β”‚
β”‚ (open, write, usleep)        β”‚ β”‚ (1272x1696 RGBA / L8) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚                          β”‚
               β–Ό                          β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚
β”‚ Linux Kernel (profiled evdev)β”‚          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚
               β–Ό                          β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        Physical Kindle Hardware (Colorsoft / Basic)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

✨ Features

  • 🏎️ No New Touch Binary On-Device: Uses KOReader's bundled LuaJIT FFI and a model profile instead of installing an input utility.
  • πŸ–οΈ Full Multi-Touch Protocol (Type B): Supports ABS_MT_TRACKING_ID, ABS_MT_POSITION_X/Y, SYN_REPORT, and BTN_TOUCH.
  • πŸ–ΌοΈ Framebuffer Snapshots: Captures a profiled frame from /dev/fb0; arbitrary partial-refresh and active-buffer reconstruction remain open work.
  • πŸ”Œ Model Context Protocol (MCP) Server: Plug KAC directly into Claude Desktop or Cursor so LLMs can invoke kindle_tap, kindle_swipe, and kindle_screenshot as native tools.
  • πŸ“± Profile Table: Includes Colorsoft, Basic, PW5, Oasis 3, and Scribe geometry. Physical field acceptance currently covers the Colorsoft and Basic only.

πŸš€ Quickstart

1. Prerequisites

  • A jailbroken Kindle with KOReader installed.
  • KOReader SSH Server enabled on port 2222 (passwordless or public key auth).
  • Python 3.9+ on your computer:
    python3 -m venv .venv
    . .venv/bin/activate
    python3 -m pip install -e .

2. Basic CLI Commands

# The device profile is auto-detected from the Kindle model/framebuffer.
# Capture a live screenshot from the Kindle
python3 -m kac.cli --host KINDLE_IP screenshot --out current_screen.png

# Tap a button at coordinate (x, y)
python3 -m kac.cli --host KINDLE_IP tap 636 1600

# Swipe left (Next Page)
python3 -m kac.cli --host KINDLE_IP swipe 1000 800 200 800

# Swipe right (Previous Page)
python3 -m kac.cli --host KINDLE_IP swipe 200 800 1000 800

# Restart KOReader without leaving a stale launcher or duplicate reader
python3 -m kac.cli --host KINDLE_IP restart

# Launch through the supported package manager on a modern Kindle jailbreak
python3 -m kac.cli --host KINDLE_IP restart --launch-mode kpm

# Launch through KPM while KOReader temporarily owns the device without Amazon UI
python3 -m kac.cli --host KINDLE_IP restart --launch-mode kpm-framework-stop

On the first touch action after a Kindle reboot, KAC automatically copies its small LuaJIT helpers into the device's temporary /tmp directory. You do not need to stage tap.lua, swipe.lua, or longpress.lua manually. SSH/SCP failures are surfaced instead of being treated as successful no-op gestures.

KAC preserves KOReader's live Kindle launcher flags during a normal restart. The restart transition is detached from the SSH session, asks KOReader to exit cleanly, waits for its wrapper to finish restoring the Kindle lifecycle, and then launches one fresh instance. It deliberately fails closed instead of using kill -9, because force-killing the wrapper can leave Amazon's framework or window manager suspended. Diagnostic output is written to /tmp/koreader-kac-restart.log on the Kindle. Modern KindleModding jailbreaks use KPM and scriptlets; --launch-mode kpm uses that supported path. KUAL modes remain available for older installations and migration diagnostics, but kual-framework-stop should only be used deliberately because it suspends the stock Kindle interface while KOReader is running.

--launch-mode kpm-framework-stop forwards KOReader's official --framework_stop flag through KPM. It is appropriate when KOReader should own the framebuffer and suspend screen completely, and KOReader's launcher will restore the Amazon framework on exit. This flag does not itself rewrite Kindle blanket modules; device-specific blanket correction belongs in a guarded, backed-up launcher such as the tested Basic recovery script.

If auto-detection cannot identify an unusual model, pass an explicit profile, for example --device basic_11th.

USB transport

KAC distinguishes two very different USB connections:

  • USB storage/MTP can stage installers, books, configuration, and recovery files. It cannot execute root commands or inspect live processes. Newer Kindles expose MTP rather than a Finder-mounted disk on macOS, so KAC needs a libmtp-backed transport and must serialize access to the single MTP session.
  • USBNetwork exposes SSH over the cable. Once installed and enabled, KAC's existing SSH controller can use it without Wi-Fi; only the host/addressing setup changes.

USBNetwork installation remains an explicit device bootstrap step. The exact package must be selected for the Kindle model, firmware, and jailbreak stack, then installed through that stack's supported package mechanism. KAC must not guess compatibility from a model nickname alone.

For development on macOS, tools/kac_mtp.c keeps one libmtp session open while it resolves device paths and backs up exact requested files. This avoids the Kindle disconnect/replug cycle caused by invoking several standalone libmtp utilities. Build it against Homebrew's libmtp:

cc -std=c11 -Wall -Wextra $(pkg-config --cflags libmtp) \
  tools/kac_mtp.c -o tools/kac-mtp $(pkg-config --libs libmtp)

The get command requires explicit absolute device paths, rejects traversal, and preserves those paths beneath the selected local destination. put resolves an explicit existing parent folder; put-root is the stricter root-only form. Both upload one or more files in one MTP session, refuse to overwrite a mismatched existing path, reuse an exact-size staged object for idempotent retries, and verify every resulting MTP object name, parent, and size before reporting success. Kindle firmware may acknowledge an MTP object before its index/storage commit is durable, so the uploader keeps the session open briefly after each transfer; critical recovery uploads still require a detach/reconnect read-back before execution.

For multi-step work, kac-mtp shell holds one libmtp device handle and accepts tab-delimited find, get, put, replace, refresh, and quit commands. This prevents the physical reconnect loop caused by releasing the Kindle after every operation. replace remains exact-path-only and should follow a get backup in the same session.

Kindle Basic ZenOS migration helpers

The recovery/ directory records the physical Basic 5 migration path. These are dated evidence scripts, not a universal installer; read recovery/README.md first.

  • install_zenos_trial_and_inventory.sh installs a checksum-verified ZenOS bundle from a one-tap document, moving SimpleUI and Bookshelf into a dated rollback directory before extraction.
  • tune_basic_zenos.sh narrows the library to /mnt/us/books, locks the root, removes redundant edge-brightness gestures, and collapses a verified Home/Away OPDS pair. Its expected HTTPS URL and public label are explicit environment parameters.
  • 2-basic-no-special-offers.lua is retained only as superseded experiment evidence. It did not solve framebuffer ownership and is not installed by the accepted tuning path.
  • cleanup_basic_send_to_kindle_pdocs.sh prepares an exact manifest from cc.db, then requires the expected document count and target-list SHA-256 before deleting downloaded PDOC files. It deliberately preserves non-PDOC KFX purchases and dictionaries and does not delete cloud/catalog records.
  • configure_basic_sleep_overlay.sh demonstrates the maintained overlay recipe: image-mode book-cover base plus one transparent PNG overlay.
  • configure_basic_transparent_sleep_screen.sh configures the tested page-peek recipe: transparent random-image sleep screens, image background none, and the separate Sleep Overlay patch disabled.

These scripts are evidence-bound to the tested MT8110 Bellatrix device / KOReader KindleBasic5. Do not reuse them on another Kindle model without fresh live-state checks and model-specific acceptance.


πŸ€– Using as an MCP Server with AI Agents

Add KAC to your Claude Desktop or Cursor MCP configuration (claude_desktop_config.json):

{
  "mcpServers": {
    "kindle": {
      "command": "python3",
      "args": ["-m", "kac.mcp_server", "--host", "KINDLE_IP", "--output-dir", "/absolute/path/to/kac-captures"]
    }
  }
}

The stdio server implements current stateless discovery plus the legacy initialization handshake. It exposes device info, confined screenshots, bounded touch gestures, and a lifecycle-aware KOReader restart. Arbitrary root shell execution is intentionally CLI-only and requires an explicit warning acknowledgement. This is not continuous screen mirroring: each capture is a snapshot, and control depends on a reachable, awake SSH service.

Verification

python3 -m unittest discover -s tests -v
python3 -m compileall -q kac tests
sh -n recovery/*.sh
cc -std=c11 -Wall -Wextra -Werror $(pkg-config --cflags libmtp) \
  tools/kac_mtp.c -o /tmp/kac-mtp $(pkg-config --libs libmtp)

See RETROSPECTIVE.md for the field lessons and PROJECT_HANDOFF.md for the clean starting point for a future official product.


πŸ“ Repository Structure

kindle-agent-controller/
β”œβ”€β”€ README.md               # Main project documentation
β”œβ”€β”€ SAFETY.md               # Trust boundary and mutation requirements
β”œβ”€β”€ RETROSPECTIVE.md        # Reusable lessons from the two-device deployment
β”œβ”€β”€ PROJECT_HANDOFF.md      # Product directions, boundaries, and release gates
β”œβ”€β”€ ARCHITECTURE.md         # Low-level evdev & framebuffer reverse engineering guide
β”œβ”€β”€ RESEARCH_NOTES.md       # Session hardware logs, kernel driver notes & discoveries
β”œβ”€β”€ ROADMAP.md              # Open tasks for future agents & contributors
β”œβ”€β”€ recovery/               # Guarded one-tap and SSH migration/recovery helpers
β”œβ”€β”€ tools/                  # Native transport prototypes such as kac-mtp
β”œβ”€β”€ kac/                    # Python package
β”‚   β”œβ”€β”€ controller.py       # High-level KindleController API
β”‚   β”œβ”€β”€ display.py          # Framebuffer decoder & device profiles
β”‚   β”œβ”€β”€ cli.py              # Command-line interface
β”‚   └── mcp_server.py       # Model Context Protocol server
└── scripts/                # Headless LuaJIT FFI injection scripts
    β”œβ”€β”€ tap.lua             # Multi-touch tap driver
    β”œβ”€β”€ swipe.lua           # Multi-touch gesture interpolator
    └── longpress.lua       # Long-press driver

πŸ“„ License

MIT License. Copyright holders are listed in LICENSE.

About

Autonomous AI agent harness, headless multi-touch driver, and live visual feedback loop for jailbroken Kindle devices running KOReader.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages