Skip to main content
Glama
sambt94

remarkable-mcp

by sambt94

remarkable-mcp

An MCP server that gives Claude direct access to your reMarkable tablet's notebooks. Search documents, render handwritten pages to PDF, and let Claude transcribe your handwriting or convert hand-drawn diagrams into editable formats — all from your local machine, no API keys required.

How it works

The reMarkable desktop app syncs your notebooks to a local cache. This MCP server reads that cache and exposes it as tools that Claude can use directly.

reMarkable tablet
    → reMarkable desktop app (cloud sync)
    → Local cache (~/.../remarkable/desktop)
    → remarkable-mcp (rmc → SVG → cairosvg → PDF)
    → Claude reads the PDF
    → Clean Markdown, Excalidraw diagrams, or whatever you need

No API keys. No cloud access. Everything runs locally. The desktop app handles syncing; this server just reads the files it produces.

Related MCP server: io.github.praveensehgal/remarkable

Prerequisites

  • reMarkable desktop app — installed and synced (download)

  • macOS — the server reads from the standard macOS cache path (Linux support is possible but untested)

  • Python 3.12+

  • uv — Python package manager (install)

  • cairo — system graphics library for SVG→PDF rendering:

    brew install cairo

Installation

git clone https://github.com/sambt94/remarkable-mcp.git
cd remarkable-mcp
uv sync

MCP Registration

Add the server to your Claude Code MCP configuration. See mcp.example.json for the full template, or add this to your .mcp.json:

{
  "mcpServers": {
    "remarkable": {
      "type": "stdio",
      "command": "/bin/bash",
      "args": [
        "-c",
        "export DYLD_LIBRARY_PATH=/opt/homebrew/lib; exec uv --directory '/path/to/remarkable-mcp' run server.py"
      ]
    }
  }
}

Replace /path/to/remarkable-mcp with the actual path to your cloned repo.

The DYLD_LIBRARY_PATH is needed so Python can find the Homebrew-installed cairo library on macOS.

Tools

The server exposes 6 tools:

Tool

Description

remarkable_check_status

Diagnostics — cache exists? rmc available? cairo available?

remarkable_list_documents

Search/list documents in the cache (optional substring filter)

remarkable_get_document_info

Detailed metadata for a document (page count, page IDs, format)

remarkable_render_pages

Render selected pages to a single PDF

remarkable_render_document

Render all pages of a document to PDF

remarkable_cleanup_renders

Remove temporary rendered PDFs

Page selection

remarkable_render_pages supports flexible page selection:

# Last 5 pages of a document
remarkable_render_pages(doc_id="<uuid>", last_n=5)

# First 3 pages
remarkable_render_pages(doc_id="<uuid>", first_n=3)

# Specific pages (0-indexed)
remarkable_render_pages(doc_id="<uuid>", page_indices=[0, 2, 4])

# All pages (no selection args)
remarkable_render_pages(doc_id="<uuid>")

Priority: page_indices > last_n > first_n > all pages.

Usage with Claude

Once registered, Claude can access your reMarkable notebooks directly:

"Transcribe the last 3 pages of my journal"

"Find my notebook called 'Architecture Notes' and render page 5"

"What documents do I have on my reMarkable?"

The rendered PDFs are saved to /tmp/remarkable-renders/ and can be cleaned up with remarkable_cleanup_renders.

Companion Skills

The skills/ directory contains Claude Code skill definitions that wrap the MCP tools into complete workflows:

  • remarkable-transcribe.md — Transcribe handwritten notes to clean Markdown

  • remarkable-diagram.md — Convert hand-drawn diagrams to interactive Excalidraw files

To use these, copy the skill files into your ~/.claude/skills/ directory (or symlink them).

Architecture

remarkable-mcp/
├── server.py                 # MCP server entry point (FastMCP, stdio transport)
├── remarkable_client.py      # Client library (cache reading, rendering pipeline)
├── skills/
│   ├── remarkable-transcribe.md   # Handwriting → Markdown skill
│   └── remarkable-diagram.md      # Diagram → Excalidraw skill
└── tests/
    ├── conftest.py           # Synthetic cache fixtures
    ├── test_remarkable_client.py  # Unit tests
    ├── test_server.py        # Integration tests
    └── test_e2e.py           # End-to-end stdio tests

The rendering pipeline:

  1. rmc parses reMarkable's proprietary .rm binary format (v6) into SVG

  2. cairosvg converts SVG to PDF

  3. pypdf merges per-page PDFs into a single document

  4. Claude reads the PDF and does whatever you need — transcription, diagram interpretation, summarization

Tests

# All tests
uv run pytest tests/ -v

# By category
uv run pytest tests/ -m unit          # unit tests (synthetic cache)
uv run pytest tests/ -m integration   # tool registration and response shapes
uv run pytest tests/ -m e2e           # full stdio transport

Tests use synthetic fixtures — no real reMarkable device or cache required.

License

MIT — see LICENSE.

Available Tools

6 tools
remarkable_check_statusA

Check reMarkable system status and tool availability. Returns whether the cache exists, document count, and rmc/cairo availability. Use this to diagnose issues before rendering.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full burden. It discloses the tool's return values: cache existence, document count, and rmc/cairo availability, giving the agent a concrete sense of what to expect. It also implies a read-only diagnostic nature, though it doesn't explicitly state side-effect safety.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, with the first defining the action and the second adding return details and usage context. Every word contributes value, and it's front-loaded with the core purpose. No redundant phrasing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter status tool, the description covers its purpose, return fields, and recommended usage context. The presence of an output schema further reduces the need to elaborate on return structure. It's fully adequate for an agent to select and invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the description doesn't need to explain any argument semantics. With no params, the score is baseline 4 as per guidelines.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Check reMarkable system status and tool availability.' This specific verb-resource pair distinguishes it from sibling tools that list documents, get info, or render pages. It also adds detail about what it returns ('cache exists, document count, rmc/cairo availability'), reinforcing its unique diagnostic role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly advises 'Use this to diagnose issues before rendering,' which gives a clear when-to-use context. It identifies the tool as a pre-rendering diagnostic without requiring exclusions, since sibling tools handle actual rendering or document listing. This is clear guidance, though it doesn't name alternatives in the same sentence.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remarkable_cleanup_rendersA

Remove temporary rendered PDFs from the render directory. Returns the number of files removed and bytes freed. Call this after you're done reading rendered PDFs.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It discloses the destructive action (removing files) and the return value (count and bytes freed). It could add irreversibility or scope context, but the essentials are present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise, front-loaded sentences with no filler. Every sentence contributes purpose, result, or usage timing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with an output schema, the description fully covers what it does, what it returns, and when to call it. No significant gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description adds no parameter detail because none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Remove') and identifies the resource ('temporary rendered PDFs from the render directory'). It clearly distinguishes this cleanup tool from sibling read/render/status tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit timing guidance: 'Call this after you're done reading rendered PDFs.' This makes the intended usage clear, though it does not mention alternatives or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remarkable_get_document_infoA

Get detailed metadata for a single reMarkable document. Returns document ID, name, page count, page IDs, and content format (v1/v2). Lightweight — reads JSON only, no rendering.

ParametersJSON Schema
NameRequiredDescriptionDefault
doc_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the burden. It explicitly discloses that it reads JSON only and does not render, indicating a read-only, lightweight operation. It also lists the return fields, providing a clear behavioral contract.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: the first states the purpose, the second details return values and lightweight behavior. No filler words; every sentence contributes information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter metadata tool with an output schema, the description covers what it does, what it returns, and its lightweight nature. It provides enough context to select it among siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter doc_id is not detailed in the description beyond the tool's purpose. The description implies that doc_id identifies the reMarkable document, but it doesn't explain how to obtain it or any format constraints, leaving the agent to infer from the tool's name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Get detailed metadata for a single reMarkable document' with a specific verb and resource. It distinguishes itself from sibling rendering and listing tools by emphasizing 'no rendering' and 'single document.'

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies usage for metadata retrieval without rendering, positioning itself as lightweight. It doesn't explicitly name alternatives like list_documents, but the context clearly separates this from rendering tools and the list tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remarkable_list_documentsA

List documents in the reMarkable local cache. Optional case-insensitive substring filter on document names. Returns document IDs, names, page counts, and last modified timestamps.

ParametersJSON Schema
NameRequiredDescriptionDefault
searchNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It specifies the data source ('local cache'), the case-insensitive substring filtering behavior, and the return fields. This goes beyond the schema and conveys a read-only listing operation, though it does not explicitly state that it is safe or non-mutating.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences: purpose, filter behavior, and return fields. No wasted words, information is front-loaded and easy to scan. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with one optional parameter and an output schema, the description covers all essential aspects: what is listed, where from, how to filter, and what is returned. The output schema likely documents return types, so no further detail is needed. The description is complete for a task of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one parameter ('search') with no description, so the description must compensate. It fully explains the parameter: optional, case-insensitive substring filter on document names. This adds complete meaning beyond the bare schema definition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List documents in the reMarkable local cache' with a specific verb and resource. It distinguishes this list operation from sibling tools like remarkable_get_document_info (which likely retrieves a single document) and render tools. The scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for listing documents but provides no explicit guidance on when to use this tool versus alternatives. It does not mention when to prefer get_document_info or render tools, nor does it state any exclusions or prerequisites. The optional filter hints at use cases but not in a prescriptive way.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remarkable_render_documentA

Render all pages of a reMarkable document to a single PDF. Convenience wrapper — equivalent to render_pages with no selection args. Returns the PDF path, document name, pages rendered/failed, and indices.

ParametersJSON Schema
NameRequiredDescriptionDefault
doc_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the full burden. It discloses the return values and the fact that it renders all pages to a single PDF, but lacks details on side effects, storage location, or error handling. Acceptable for a simple render operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences. The first states the primary function, the second clarifies the wrapper relationship and return values. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (one parameter), has an output schema (though not shown), and the description mentions what will be returned. It doesn't mention that doc_id should come from list_documents, but that's a minor omission. Overall sufficiently complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter doc_id is self-explanatory and its role is implied by the description. Schema coverage is 0%, but with only one obvious parameter, the description doesn't need to add much. Still, it doesn't explicitly define doc_id, so it doesn't fully compensate for the lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: 'Render all pages of a reMarkable document to a single PDF.' It also distinguishes this tool from sibling render_pages by explicitly calling it a convenience wrapper equivalent to render_pages with no selection args.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool: when you need all pages rendered, as opposed to selecting specific pages via render_pages. It doesn't explicitly say 'use render_pages for selected pages,' but the wrapper equivalence makes that clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remarkable_render_pagesA

Render selected pages of a reMarkable document to a single PDF. Priority: page_indices > last_n > first_n > all pages. For a 200-page doc with last_n=5, only the last 5 pages are rendered. Returns the PDF path, document name, pages rendered/failed, and indices.

ParametersJSON Schema
NameRequiredDescriptionDefault
doc_idYes
last_nNo
first_nNo
page_indicesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral disclosure burden. It explains selection behavior, gives a concrete example, and lists return values. However, it does not mention side effects such as creating files on disk, whether previous renders are overwritten, or if cleanup via 'remarkable_cleanup_renders' is needed. This is a meaningful gap for a render tool with file output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four compact sentences: purpose, priority rule, example, and return values. Every sentence earns its place, and the most important information is front-loaded. There is no redundancy or unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is adequate for a moderately complex tool with one required param and an output schema. It covers selection priority, example behavior, and return values. The main omissions are index base, potential side effects/cleanup, and how it differs from the full-document sibling, but overall it gives the agent enough to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the input schema. It clarifies the meaning and precedence of 'page_indices', 'last_n', 'first_n' and the 'all pages' fallback, using a concrete example. However, it leaves some semantics implicit (e.g., whether indices are zero-based, bounds behavior, doc_id role) and does not fully describe all parameter formats.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Render selected pages of a reMarkable document to a single PDF.' The phrase 'selected pages' distinguishes it from the sibling tool 'remarkable_render_document,' which presumably renders the full document. The purpose is immediately clear and non-tautological.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear intra-tool guidance on parameter precedence ('Priority: page_indices > last_n > first_n > all pages') and a concrete example. However, it does not explicitly state when to use this tool versus alternatives like 'remarkable_render_document' or 'remarkable_cleanup_renders.' The usage context is implied by the 'selected pages' framing but not explicitly contrasted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedremarkable_check_status
    • First observedremarkable_cleanup_renders
    • First observedremarkable_get_document_info
    • First observedremarkable_list_documents
    • First observedremarkable_render_document
    • First observedremarkable_render_pages

TDQS

A4.2/5.0

Scored across 6 tools

Disambiguation4/5

Most tools have clearly distinct purposes, but remarkable_render_document is explicitly a wrapper for remarkable_render_pages with no selection arguments, creating a slight overlap. The descriptions mitigate this by clarifying the relationship, so it's mostly unambiguous.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern with the remarkable_ prefix, such as list_documents, render_pages, and check_status. This makes the tool names predictable and easy to navigate.

Tool Count5/5

With 6 tools, the server is well-scoped for its purpose of managing and rendering reMarkable documents. Each tool serves a distinct function (listing, metadata, rendering, status, cleanup) without unnecessary bloat.

Completeness4/5

The tool set covers the core lifecycle for reading and rendering documents: listing, retrieving metadata, rendering all or select pages, checking status, and cleaning up. It lacks write operations like upload or delete, but those fall outside the apparent scope of a rendering-focused server.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives Claude AI direct access to your Obsidian vault, enabling natural language search, note creation, file management, and automated workflows.
    6,209 npm
    9
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A local MCP server that turns an Obsidian vault into a searchable second brain for Claude with meaning-based search, note read/write, and insight reports like contradictions and stale TODOs.
    MIT