SuperAPI AI Directory

rustpad-mcp

Read and edit self-hosted Rustpad collaborative pads, merging edits live with human typing and requiring confirmation to replace a pad.

Open website

About this tool

Purpose

rustpad-mcp is a Model Context Protocol (MCP) server for connecting to Rustpad—an efficient, minimalist, self-hosted collaborative text editor. It lets MCP clients such as Claude Code, Claude Desktop, and Codex read and write pads in a Rustpad instance: fetch documents, create documents, replace documents wholesale, or edit in place.

Main capabilities

  • Reading is done through Rustpad's HTTP API.
  • Writing uses the operational-transformation WebSocket protocol, so targeted edits (append_to_document, replace_in_document) merge cleanly with what human collaborators are typing at the same time, rather than overwriting it. While the server is editing a pad, it is visible to everyone in the pad as a collaborator named rustpad-mcp.
  • Two edits that cannot be undone request confirmation from a real person. When the client supports MCP elicitation, replacing a non-empty pad and search-and-replace across multiple matches bring up a real dialog that the model cannot answer on the user's behalf; the replace_in_document prompt states how many places are about to change. When the client does not support it, it falls back to a two-call token and states this clearly, rather than implying that someone approved it. ELICITATION=false deliberately adopts that fallback, but does not remove this layer of protection.
  • Eight tools are registered by default; RUSTPAD_ALLOW_TOOLS=essential instead registers a curated five tools, and it is far more reliable for a model to choose from five tools than from eight.
  • Every tool declares an outputSchema and returns structuredContent in addition to a text block, so clients can use the results without parsing text.

How to use

Requirements

  • An accessible Rustpad instance (self-hosted; the server is stateless and requires no credentials—Rustpad has no authentication)
  • Node.js >= 22, or Docker

The same URL serves the HTTP API, the WebSocket endpoint, and the share links returned by the tools (<RUSTPAD_URL>/#<pad-id>). RUSTPAD_* booleans must be strictly true. The server starts and lists tools without configuration; but every call will fail with setup instructions.

ELICITATION is the only exception: it has no prefix, so it affects all MCP servers in the same environment; when the value is neither true nor false the server stops instead of falling back—it is the only variable here that is on by default, otherwise a typo would make you think the dialog is closed while it is actually still running. A server started in the off state prints a line of explanation.

Tool loading selection

RUSTPAD_ALLOW_TOOLS and RUSTPAD_DENY_TOOLS accept comma-separated tool names; a trailing * matches an entire tool family. essential is a curated preset of five tools: get_document, get_document_info, create_document, set_document, append_to_document.

There is a boundary that is softer than the list appears: Rustpad has no create operation, any id exists as a pad as soon as it is written, so denying create_document does not prevent creating a new pad—set_document or append_to_document on a new id will also create it. To deny the write tools you actually want to deny, or use RUSTPAD_READ_ONLY.

An entry that matches no tools causes startup to abort and points out that entry, so a typo will not silently hide a tool—a missing tool is not something people trace back to an environment variable. Filtered tools are never registered, so they do not exist in tools/list and are unknown to tools/call, exactly like write tools under RUSTPAD_READ_ONLY.

If you run multiple such servers at the same time, another option is mcp-hub—its /hub endpoint replaces each server's tools with six meta-tools.

Connecting via mcp-hub

Clients that cannot start local processes (ChatGPT connectors, Claude web version, Cursor, LibreChat) can access rustpad-mcp through mcp-hub: a container via Streamable HTTP serves multiple stdio MCP servers, with OAuth 2.1 login behind a single password and long-lived tokens for clients that do not support OAuth. Its /hub endpoint hides all servers behind six meta-tools, so a single connector can access all of them without stuffing N×tool schemas into the model context.

Its /config/mcp.json uses Claude Code's format, so entries are the ones you already have.

Structured Output

Every tool declares an outputSchema and answers with structuredContent alongside a text block, so clients can use results without parsing text. The five write tools used to answer with one sentence (for example "Appended 12 characters to pad …"), and that sentence is still kept in the text block.

get_document answers with {text} rather than making pad the entire result—for the same reason get_document_info has always been an object: a schema whose root is a string gets rewritten to {result: …} by implementations targeting 2025-era clients, so the tool would return two shapes depending on who is asking. This is also where empty and truncated can exist—previously an empty answer was expressed with a sentence.

The two read tools that report pad contents carry untrusted: true and source: "rustpad" fields. A pad is writable and readable by anyone who knows its id, including text written earlier by this server, and if a client reads only the structured part, it will get no framing hints at all.

When to Use

  • Let MCP clients (Claude Code, Claude Desktop, Codex) read, create, replace, or edit pads in place in a Rustpad instance.
  • Collaborate on editing while someone is typing at the same time, with targeted edits merging cleanly.

Security and Limitations

  • By design: no pad list is exposed—Rustpad has no such API. Pads exist implicitly under each id, so you must know the id you care about. get_stats reports how many documents the server currently holds, but not their names.
  • No accounts, no perrestricted. Rustpad has neither, so every pad is treated as untrusted input rather than content vouched for by a login.
  • Pad content is writable and readable by anyone who knows the id, so it is untrusted: every read result is prefixed with a marker telling the model to treat it as data, never as instructions.
  • Two irreversible edits request human confirmation: a real dialog the model cannot answer on your behalf, bound to that pad and the exact replacement content. When the client cannot display a dialog, a one-time token is used, appearing only in the previous tool result—this only proves the same parameters were used to call twice, nothing more. The fallback text states which of the two it is.
  • Tool results have a size cap; everything written by the instance has control characters stripped, and upstream error bodies are sanitized before reaching the model.
  • The instance itself is also untrusted: WebSocket frames are limited at the header level before buffering, the message queue is bounded by bytes, and every frame is shape-checked before being folded into the pad.
  • RUSTPAD_INSECURE_TLS relaxes certificate verification only for the configured connection, never process-wide.
  • Pads are ephemeral: they are lost on server restart and after 24 hours of inactivity, unless the instance runs with SQLITE_URI. Do not put secrets in pads.

The full guide, tool reference, and security notes are at rustpad-mcp.ni-c.de (source in docs/).

The test suite communicates over the real MCP protocol with an in-memory rustpad-server fake implementation (including OT transformation for concurrent edits); no online instance is needed. The architecture diagram and social card are generated—edit docs/assets/architecture.source.svg and run npm run assets, never modify the rendered copies.

Releases are tag-driven. First bump package.json, move the [Unreleased] notes in CHANGELOG.md under the new version, and commit. The release workflow publishes to npm via Trusted Publishing (OIDC, with provenance), pushes multi-architecture container images to GHCR, creates a GitHub release from the CHANGELOG section, and updates the entry in the official MCP registry.

Questions, discussions, and pullrequests are all welcome—see CONTRIBUTING.md. For vulnerabilities, please use private reporting rather than a public issue; see SECURITY.md for the policy.

MIT © Willi Thiel