Bidirectional sync between reMarkable tablets and an Obsidian knowledge base with intelligent note processing. Exposes MCP tools to trigger sync, search notes, manage actions, and interact with the reMarkable vault.
The server defines 8 tools with complete naming, descriptions, and input schemas visible in src/mcp/server.py. Naming follows verb_noun convention (remarkable_sync_now, remarkable_search, remarkable_get_actions, etc.), which is solid. Descriptions are present and range from 54-184 characters, mostly within the 10-1024 baseline but several are sparse. All tools have input schemas with proper type definitions. However, critical gaps emerge: (1) NO output schemas are documented, LLMs cannot infer what fields to expect from responses, forcing them to guess downstream tool inputs; (2) Parameter descriptions lack detail on constraints, valid values, and expected formats, e.g., 'status' in remarkable_get_actions only says 'Filter: open, all' but should explicitly state these are the only valid enums; (3) No error handling guidance visible, tools do not document how to handle failures or what to do if a note path is invalid; (4) No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear read vs. write semantics; (5) Pagination not visible for list tools, remarkable_list_notes and remarkable_search return all results with no limit/offset params; (6) remarkable_ask and remarkable_generate_response have moderate complexity but parameter descriptions lack examples of valid formats. The schema definitions are structurally sound (all use 'type', 'properties', 'required' correctly), but lack the richness needed for robust agent reasoning.
Ask a natural-language question against your synced notes. Uses semantic search to find relevant passages and optionally synthesizes a grounded answer with wiki-link citations.
Generate a response document (PDF or native notebook) for a specific synced note and push it back to the reMarkable tablet. Optionally uses the configured LLM to answer questions found in the note.
List all extracted action items, optionally filtered by status
Read the full content of a specific note from the vault
List all synced notes from reMarkable
Search across all synced notes in the Obsidian vault
No output schemas documented for any tool. LLMs cannot infer response structure, forcing them to guess what fields exist and what downstream tools accept. This violates the 'Document the output schema' pattern.
Parameter 'status' in remarkable_get_actions lacks enum constraint. Description says 'Filter: open, all' but this is free-form text, not an enum. Should be declared as enum: ['open', 'all'] to prevent hallucinated values.
Parameter 'format' in remarkable_generate_response correctly uses enum ['pdf', 'notebook'], but the description is vague. Should explain: 'Format for the response document. PDF is suitable for sharing; notebook integrates natively with reMarkable tablets.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
Get current sync status: last sync time, pending items, errors, stats
Trigger an immediate sync cycle with the reMarkable Cloud
remarkable_list_notes and remarkable_search have no pagination parameters (limit, offset, cursor). They will return all results, risking context window exhaustion. Should add limit (default 20, max 100) and cursor/offset for agent iteration.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). remarkable_sync_now and remarkable_generate_response are clearly destructive/write operations; remarkable_search, remarkable_get_note, etc. are read-only. Annotations enable agent safety and optimization.
No error handling guidance visible in tool definitions. If remarkable_get_note is called with an invalid path, what error is returned? What should the agent do? Examples: should it call remarkable_list_notes to discover valid paths, or try a corrected path?
Parameter descriptions lack constraint documentation. E.g., 'top_k' in remarkable_ask has no stated range, can it be 0, 1, 1000? Should state: 'Number of source chunks to retrieve (1-100, default 5)'. Current description is only 34 chars; baseline is 72.