Rapier for agents

Rapier is a free Markdown editor your user keeps working in while you help. This page says what you can do for them, then how to connect.

What Rapier does for your user

Seven tools. Each line is the tool's own description, word for word.

Together they cover the whole product:

JPEG XL for agents

convert turns pictures into JPEG XL and JPEG XL back into pictures. Everything converts on the person's device; nothing reaches Rapier's server.

Rules

Connect a client

Manual MCP setup

For any other client that supports MCP, add this server address:

https://mcp.rapier.website/door/mcp

Rapier is also a free Android app.

Connect

Rapier is listed in the MCP Registry and the GitHub MCP Registry as website.rapier/markdown-editor-draw-paint-jpeg-xl.

The catalog has seven tools: open, read, edit, undo, show, export and convert. If your host reads MCP resources, rapier://guide, rapier://guide/blocks, rapier://guide/draw and rapier://guide/water hold the contracts; the Water resource also carries the current brush registry. Otherwise use this page and the tool schemas. Optional prompts: write-brief, diagram-process, paint-illustration and compare-drafts.

Open a document

Call open with one source:

open returns the revision, an outline, the text of small documents, document, and editor_url when available.

OAuth

OAuth on the OpenAI connector and Muse supports rapier:read, rapier:write and optional offline_access. The person can grant read only; a read-only connection can't create or edit a workspace. The host keeps credentials out of tool arguments.

Claude Team and Enterprise

An Owner can connect every member at once, with no approval page:

  1. Add a custom connector with the URL https://mcp.rapier.website/mcp.
  2. In its Authentication, choose Set up on Managed authorization, then Claude-issued.

There is nothing to enter in Rapier: your organization's issuer registers itself at the first sign-in. Rapier knows each member by your organization and their Claude email address. Access lasts an hour and renews without asking; a member removed from the organization loses access within that hour.

Pair a browser

The browser that approved the connection can open editor_url. Another browser shows a four-letter code.

  1. Call show {document,target:"pair",code}, only with the code the person gives you.
  2. On a connected workspace, the reply first returns owner_approval_url for approval in the connected browser. An anonymous workspace returns confirmation_required.
  3. The person taps Allow in the new browser.

A code sent without target:"pair" is an ordinary show and reports editor_not_present until a browser is admitted. Other show targets need no pairing. A code lasts one minute and works once; five wrong codes lock that window. Pairing lasts one day. Your request is not the person's approval.

Install

The offline editor needs no account. Connecting a workspace doesn't set up Notes.

Gemini

Read and edit

open includes short documents. For a larger one, read one of:

Follow next_cursor with cursor alone; it keeps the selection. Don't repeat heading, block or lines. A document map lists heading and fence lines in order; maps and query results carry line numbers. Keep the exact revision, including string revisions for a live drawing or note.

// MCP calls also carry the private document value returned by open.
const passage = await call('read', {document, heading: ['Plan', 'Dates']});
const changed = await call('edit', {
  document, revision: passage.revision,
  changes: [{heading: ['Plan', 'Dates'], old: '12 June', new: '19 June'}],
  operation_id: 'revise-date-1'
});
await call('show', {document, target: 'comparison', act: changed.act});
// `act` is the id string the Door returns ("change_00000007"). When reversal is requested:
await call('undo', {document, act: changed.act});

edit takes a revision and changes: unique {old,new}, {after,insert}, or one {text} that replaces the whole document.

operation_id names one call. After an uncertain reply, retry the identical arguments with the same id. A mutation receipt lasts 24 hours; an expired id never runs again.

Show

Target Takes Does
passage, block text, heading or block Asks the editor to reveal it.
pointer text or act, words, lifetime (1–30 s) Points at a place.
comparison the alternative as text with an optional name, or act/turn_id; close:true closes Shows a diff; source is unchanged.
view view: formatted, source or notes Switches the view.
preferences preference, value The person's editor applies or refuses it.
ask question, wait (message or selection), timeout_ms One bounded wait. Never edit approval, never a subscription.
file Asks the person to choose a device file.
read_aloud text, heading or block Reads aloud.
return One expiring channel for an offline copy.
note note Opens the original note.
pair code Pairs a browser; the person still confirms.
playback block, revision, value (false pauses, true plays) Pauses or plays an animated preview. No source or history change.
plugin name Asks the editor to install a plugin; PDF and OCR still ask the person. A request is not proof it installed.

Receipts say what actually happened. Later human navigation wins.

Notes

  1. read {search:"words tag:work"} finds notes in the person's configured store. It needs the connected local or owned Notes endpoint; the public hosted workspace can't read encrypted Notes and says so.
  2. Pass the returned note_ref as note to read or edit. On MCP every Notes call also passes document.
  3. read {note,versions:true} lists history; version picks retained text. A note's revision is its exact content digest.
  4. edit {note,revision,changes} keeps concurrent changes and history. edit {note,revision,fields} changes allowed note controls as one separate act.
  5. Create a note with open {document,note:"new",title,text}.

export {to:"sync"} alone runs the existing sync connection; it never signs in or enrolls a store. Sync can replace files, so run it only when the person asks, and report the changed files. A locked or unavailable store is not an empty library. Permanent deletion and Skills stay the person's decisions.

Tool classification for hosts

For hosts that ask for approval by effect, such as Muse's Read, Write and Sensitive write. A tool that mixes effects takes the highest. Rapier adds no approval step of its own; the host's still apply.

Tool Class Effect
read Read Returns text, maps, guides, Notes results, state and images. Changes nothing.
open Write Creates or resumes a private workspace, or creates a Note. Doesn't change existing source.
edit Write A revision-bound batch of exact changes, recorded as one undoable act.
undo Write Reverses an act or turn, keeps later work, and reports conflicts.
show Sensitive write Presents a passage, comparison or request. target:"pair" admits another browser (the person still taps Allow); target:"file" opens a device picker.
export Sensitive write Makes a file or download link. to:"sync" runs the person's sync and can replace files; saving to a bound destination overwrites it.

Errors return a stable code and a recovery hint. Pending work isn't done until read {state:true} reports it committed or refused. Rate limits are per-minute tool budgets and hourly creation and registration budgets (see Privacy and terms).

Fenced blocks

Blocks are the editable text view of Rapier's portable Markdown data. Markdown exports keep the ordinary drawing, image and discussion data, including pixels. Reads name retained pixels; they never return them as text.

Give each block a unique stable id and a caption:

{"figures":[{"kind":"rect","id":"a","label":"Request"},{"kind":"rect","id":"b","label":"Reply"},{"kind":"arrow","from":"a","to":"b"}]}

Read the canonical block after editing. It can hold a native recipe whose geometry and properties stay editable. Keep retained raster markers. New Mermaid diagrams are ordinary mermaid fences.

Should this say quarterly?

Comments are document data, not messages sent anywhere. Existing discussions show thread and message ids. Keep other people's attribution and messages.

HTML previews use ordinary fences with Pandoc attributes:

<style>table{width:100%}td{padding:.5em}</style>
<table><tr><td>Market box</td><td>$12</td></tr></table>

Draw

Use a rapier-draw fence with id, alt and JSON {figures:[...]}.

A block can hold recipe (the whole native drawing), shapes (set, add, replace, remove), or operations (native edits). Replacing a shape needs the whole shape. Operations: move, resize, rotate, set_look, set_label, set_step, connect, properties, group, ungroup, lock, unlock, unlockAll, delete, front, back, forward, backward, duplicate, align, distribute, flip, clean and unclean. A text edit of the block is still one source act through Draw. Painting goes through Draw's material pipeline; accepted work has not yet committed.

Refracted light

A drawing or shape can carry an effect with type: "refraction" and a Glass, Prism, Ripple or Soft glass preset. The SVG keeps editable geometry, text and the original Paint or Water pixels beside the finished PNG and a lossless JPEG XL copy. Block reads show the editable source and settings; derived pixels stay private.

The hosted door prepares refraction through the material handoff. A pending request hasn't changed the source: let the editor answer, then retry with the same operation id. The answer is only rendered pixels for the requested canvas, shape or layer, tied to the exact recipe and revision. A source edit invalidates earlier pixels. Cancellation or a newer human edit keeps the source and Undo intact. A result over the hosted 24 MiB material limit refuses as material_too_large; the renderer's own pixel limit doesn't raise the hosted document or storage budget.

Copy and Cut make a portable SVG with finished renditions of the copied source.

Water and Paint

A rapier-water fence has id, alt, paper (for example cold-press), seed and JSON {actions:[...]}. A rapier-paint fence has id, alt, seed and JSON {strokes:[...]}: each stroke has a registry brush id, a hex color, an optional size 0–100 and points [x,y] or [x,y,pressure], for example {"strokes":[{"brush":"dieterle/round-1","colour":"#2b5b84","size":20,"points":[[120,180,0.7],[260,190,0.8]]}]}. Both also fit as paint figures in a rapier-draw block.

A visible, authorized editor computes the paint; watercolor needs WebGPU. A pending edit returns editor_url and what it needs to finish. read {state:true} reports waiting, committed or expired work. Never call a pending painting finished. operation_id collects the same job without starting a second one. If the request expires, read the current text and use a new id once the editor is available. Text reads never include the raster; use read {as:"image"} for pixels.

Export and return a copy

export {format} makes an independent file:

Format Content
markdown Exact source.
html One offline editor with the source inside.
txt Plain words.
page A standalone page with its layout code and exact source. Exporting doesn't publish it.
docx Word, with the exact source attached.
pdf Rendered pages with searchable text and the exact source attached.

npx rapier-html notes.md writes notes.rapier.html: the whole editor with the exact source, for offline editing, drawing, painting and saving. --drawing sketch.svg carries a drawing; --compare original.md carries the original for an exact comparison. Keep image bytes in Self-contained Markdown.

show {target:"return"} makes a one-use channel that expires within 24 hours and the workspace's lifetime. Pass return_url and return_expires_at to rapier-html --return and --return-expires-at. The person confirms the upload in their connected browser, where the credential stays; an anonymous return URL is its own one-use grant. The returned copy is kept separately and never overwrites the workspace.

show {target:"ask"} waits once for a selection or message, or returns a page already received. timeout_ms is 1,000–120,000 on /mcp (default 20,000). Use after_return_id to wait past a known return, and read {state:true} after reconnecting. Read each returned copy with read {return_id}, then cursor alone. Compare it or bring it in with exact edits at the current revision. This is not a subscription and can't wake you after your turn ends. An expired return never deletes the person's file.

Long calls and cancellation

Cancel a pending MCP request with your client's cancellation. Legacy HTTP clients keep the Mcp-Session-Id from initialization and send notifications/cancelled; modern HTTP clients cancel the response body. Cancellation applies only to the original caller and request. It waits for cleanup, keeps any act already committed, and keeps the original receipt for an unchanged retry. If cleanup fails, the cancellation is not reported as successful.

The hosted modern doors advertise io.modelcontextprotocol/tasks when available. Declare it in each request's client capabilities to let show {target:"ask"}, read {as:"image"} and Word or PDF export return resultType: "task" with a taskId. Without it, calls stay direct. Legacy, paired-page and local-server profiles don't offer tasks.

Authority and receipts

The seven tools are separate from the editor's private /editor channel. Sync, human commits and context, acknowledgements, access management, rotation and deletion need editor authority. Hosted Apps use workspace tickets; a paired page uses scoped browser cookies at /editor/<id>. A tool call can't create an editor acknowledgement or a human grant.

Each tool has input and output schemas and effect annotations. Results carry structuredContent and matching JSON text; read isError, outcome, reason or code, and the receipt. A result can be a refusal, conflict, pending job or unavailable device. Acceptance, source commitment, presentation, saving and file delivery are separate facts. A pending painting or accepted device request is not finished. A source receipt is not a visual check; use read {as:"image"}.

Ask about this in the editor sends the person's request. Ordinary comments and edits don't start an agent turn. Comments and continuation briefs travel with the source; keep the person's words.

A kept mutation replays its original receipt for the same operation_id; after it expires, the call refuses instead of running again. A fresh read sees later human work. Disconnect agents ends the current authority. Workspaces expire after 30 idle days; exported files keep their own expiry, and downloaded copies stay independent.

Limits and recovery

Hosted defaults:

Resource Limit
Model tool calls 600 per minute across the seven tools, per verified connection or anonymous network address.
Paired editor tool calls 1,200 per minute under editor authority, separate from model calls.
Document source 64 MiB of UTF-8.
Hosted export 16 MiB.
Edit batch Up to 32 changes; a whole-document replacement must be alone.
Text read Up to 32 KiB, or 4 KiB over WebMCP; follow next_cursor. JSON and metadata have their own budgets.
Workspace creation 100 per principal per hour; 5,000 per deployment per hour. Reopening is free.
OAuth registration 20 per network address per hour; 5,000 per deployment per hour.
OAuth consent 5,000 per deployment per hour.
New pairing windows 5 per network address per minute. Five wrong codes lock a window.

Your host may set smaller limits. Going over a limit refuses new work and never truncates source. Follow continuation fields and Retry-After. Never split a retried mutation into different arguments under its old operation_id.

Result What to do
Invalid arguments Fix the named field using the tool schema and the rapier://guide resources.
Stale or conflicting content Read the current text and keep newer human work before editing again.
Will refusal Respect the protected text; another tool doesn't change that.
HTTP 401 or 403, insufficient scope Use the host's connection flow for the right scope. Never put credentials in tool text or URLs.
HTTP 429, TOOL_BUDGET_EXCEEDED Wait for Retry-After. Retries also spend quota; keep their arguments and operation_id.
Editor or renderer unavailable Open the returned editor link and check it is available before repeating the action.
material_request_expired Read the current drawing and source, then retry with a new operation id.
export_too_large Check limitBytes; pick another format or a smaller scope. Source is unchanged.
CREATE_BUDGET_EXCEEDED Resume an existing workspace, or create one after the hourly quota resets.
Timed-out or uncertain change Retry the identical arguments with the same operation_id, or read before any new write.
Notes locked or unavailable Report the real state. Don't treat it as empty or enroll another store.

Embed and deliver

npm install rapier-embed gives an app its own reader or editor, with load and verified save callbacks.

agent: true exposes the same tools over WebMCP for the host page. A save advances the host's revision only after storage confirms the bytes. See the embed contract and the package guide.

The four packaged skills cover live work, offline HTML, Self-contained Markdown and embedding. Hosts find them with skills/list, skills/get and skill resources/read.