remarkable-mcp

remarkable-mcp

Gives AI assistants direct control of a reMarkable tablet over SSH, enabling listing notes, uploading PDFs, exporting handwriting, and writing on pages via a single MCP tool.

Category
Visit Server

README

remarkable-mcp

Give an AI assistant direct control of your reMarkable tablet — list notes, upload PDFs, export handwriting, write on pages — over SSH.

The assistant gets one MCP tool, remarkable_execute, and writes a short JavaScript snippet that calls rme.* (list, mkdir, write, export, …) in one shot.

You have This project is
A reMarkable with developer mode An MCP server
SSH over USB (10.11.99.1) or Wi‑Fi stdio or Streamable HTTP (Docker)
Claude / Cursor / VS Code / any MCP client SFTP into the tablet’s xochitl library

How it works

MCP client                    this process                         tablet
───────────                   ────────────                         ──────
remarkable_execute({          node:vm sandbox                      SSH/SFTP
  code: `async () => {   →    rme.list / rme.mkdir / …      →      /home/root/.local/share/remarkable/xochitl
    await rme.mkdir(…)
    return await rme.list({})
  }`
})
  1. Enable Settings → General → Developer mode on the tablet.
  2. SSH in over USB (root@10.11.99.1) or Wi‑Fi (IP under About → Copyrights).
  3. Run this server. Point your MCP client at it.

Install

Node 22+. No clone required.

Claude Desktop, Cursor, VS Code, …

{
  "mcpServers": {
    "remarkable": {
      "command": "npx",
      "args": ["-y", "@lukaisailovic/remarkable-mcp"],
      "env": {
        "REMARKABLE_HOST": "10.11.99.1",
        "REMARKABLE_USER": "root",
        "REMARKABLE_PASSWORD": "your-tablet-password"
      }
    }
  }
}

Prefer a key? Set REMARKABLE_KEY to a private-key path (or the PEM). If unset, ~/.ssh/id_ed25519 then id_rsa are tried.

HTTP

Same server, Streamable HTTP on /mcp:

npx -y @lukaisailovic/remarkable-mcp --http
# → http://127.0.0.1:8080/mcp    health: /health

Or pull the image from GHCR:

docker run --rm -p 8080:8080 \
  -e REMARKABLE_HOST=10.11.99.1 \
  -e REMARKABLE_PASSWORD=your-tablet-password \
  ghcr.io/lukaisailovic/remarkable-mcp:latest

From a clone: docker compose up --build (bind 0.0.0.0:8080, pass REMARKABLE_*).

A local checkout’s .mcp.json watches src/ and restarts the stdio child on save (no client restart). pnpm dev:http does the same for Streamable HTTP. In Grok, /mcps disable+enable respawns the process; r only refreshes the list.


What the model can do

The client only lists remarkable_execute. Inside the snippet, methods live on rme.

async () => {
  const folder = await rme.mkdir({ name: "Projects" });
  await rme.createNotebook({ name: "Ideas", parent: folder.id });
  await rme.writeText({
    notebook: "Ideas",
    newPage: true,
    blocks: [
      { text: "Ship it", style: "title" },
      { text: "Talk to design", style: "checkbox" },
    ],
  });
  await rme.writeText({ notebook: "Ideas", text: "Write the RFC", style: "checkbox" });
  return await rme.read({ notebook: "Ideas", page: 2 });
};

A notebook is the file (name, path /Work/Notes, or UUID). A page is 1-based inside that notebook. writeText always writes native Type Folio text and appends — call it again to stack more paragraphs. Ink points are [x, y] in 0–1 from the top-left. remove moves to trash. Writes restart xochitl once after the tool returns so the UI refreshes.

rme.* What it does
list({ includeTrash?, folder? }) Library listing (trash hidden by default)
browse({ path? }) One folder, or a single notebook
search({ query, tag? }) Name / path search, optional tag
info({ notebook }) Id, path, type, tags, page count, pages[].title
read({ notebook, page? }) Native paragraphs (and checkbox state), or all pages if page is omitted. PDF/EPUB text.
download({ notebook }) Raw PDF/EPUB as base64
exportPage({ notebook, page?, format? }) Ink on a page → png or svg (typed text is not drawn)
upload({ name, dataBase64, parent?, fileType? }) Put a PDF or EPUB on the tablet
mkdir / move / rename / remove Folders and trash
createNotebook / addPage / removePage Notebooks and pages
writeInk({ notebook, strokes, page? }) Pen / highlighter strokes
writeMermaid({ notebook, mermaid, page? }) Mermaid → ink (flowchart, sequence, state, class, ER, xychart)
writeText({ notebook, text?, style?, checked?, blocks?, page?, newPage?, replace? }) Native Type Folio: title heading body bullet checkbox. Stacks unless replace.
tag({ notebook, tag, remove?, page? }) / tags() Notebook or page tags
refresh() Restart xochitl

Configuration

Flags and env vars are interchangeable (--host ≡ REMARKABLE_HOST).

Tablet Default
REMARKABLE_HOST / --host 10.11.99.1 SSH host (USB default)
REMARKABLE_USER / --user root SSH user
REMARKABLE_PORT / --port 22 SSH port
REMARKABLE_PASSWORD / --password Password
REMARKABLE_KEY / --key ~/.ssh/id_ed25519, then id_rsa Key path or PEM
Server Default
--http / MCP_HTTP=1 off Streamable HTTP instead of stdio
MCP_HTTP_HOST / --http-host 127.0.0.1 Bind address (0.0.0.0 in Docker)
MCP_HTTP_PORT / PORT / --http-port 8080 HTTP port
--fake / REMARKABLE_FAKE=1 off In-memory tablet (tests, no device)
--fake-dir / REMARKABLE_FAKE_DIR Local directory treated as a xochitl tree

Agent skill

Installable with skills.sh:

npx skills add lukaisailovic/remarkable-mcp

The skill lives at skills/remarkable-mcp/SKILL.md.


Develop

pnpm test
pnpm lint
pnpm fmt
pnpm build
pnpm exec tsx src/index.ts --fake
pnpm exec tsx src/index.ts --fake --http --http-port 8080

Tests use a fake tablet filesystem. A live device is never required.

Inspired by sammorrowdrums/remarkable-mcp and itsfabioroma/remarkable-cli.

MIT. See LICENSE.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured