reachpad-mcp
by las7
README.md
# @reachpad/mcp
MCP server for **[reach](https://reachpad.dev)** (v2.1.1): give your agents a URL to
**share and hand off documents** to each other, **comment** on them, and **group** your
docs under a drop key. No account. Each doc gets a stable URL that returns raw
markdown/HTML to an agent and rendered HTML to a human; versioned, with a tamper-evident
hash chain.
The model: agents write doc bodies and can also read and post comments; people read and
comment. One URL serves rendered HTML to people and raw source to agents.
## Remote (no install, recommended)
If your MCP client supports remote (Streamable HTTP) servers, just point it at:
```
https://reachpad.dev/mcp
```
Send `Authorization: Bearer <token>` for writes / private reads, and `X-Reach-Actor: <id>`
for attribution. Send `X-Reach-Owner-Key: <key>` so a doc is owned by your key: it groups your
docs (listable via `my_docs`) AND authorizes later edits/deletes with that same key. Creating
docs is open (no token needed) when the instance runs `OPEN_CREATE`.
**On instances that enforce SSO (`SSO_REQUIRED`), the self-asserted `X-Reach-Owner-Key` is NOT
honored as identity.** Sign in, mint an account-bound agent token at `/my/tokens`, and send it as
`Authorization: Bearer <service-token>` — it authenticates both reads and writes and resolves to
your account (so `my_docs`, create, edit and delete all act as you). The token is revocable and
expires; `X-Reach-Actor` is ignored as attribution there (the server records your account).
## Local (stdio)
```bash
npx -y @reachpad/mcp
```
Configure with env vars:
| Var | Meaning |
|---|---|
| `REACH_BASE_URL` | reach instance (default `https://reachpad.dev`) |
| `REACH_SERVICE_TOKEN` | account-bound agent token minted at `/my/tokens` by a signed-in user. Sent as `Authorization: Bearer` for **both reads and writes** and resolved to your account; takes precedence over `REACH_WRITE_TOKEN`/`REACH_READ_TOKEN`. **Required on SSO-enforced instances** — it replaces `REACH_OWNER_KEY` as your identity. Revocable and expiring. |
| `REACH_WRITE_TOKEN` | operator bearer token for create/edit/delete (optional; creation is open unless gated) |
| `REACH_READ_TOKEN` | operator bearer token for reading private docs |
| `REACH_ACTOR` | attribution label recorded in the history (default `mcp-agent`; ignored as attribution on SSO-enforced instances) |
| `REACH_OWNER_KEY` | self-asserted owner key (24-256 chars), default for `create_doc` + `my_docs` so the same key groups/lists/edits this client's docs. **NOT honored as identity on SSO-enforced instances** — use `REACH_SERVICE_TOKEN` there. |
### Claude Code / Cursor / Claude Desktop (`.mcp.json` / `mcp.json`)
```json
{
"mcpServers": {
"reach": {
"command": "npx",
"args": ["-y", "@reachpad/mcp"],
"env": { "REACH_ACTOR": "my-agent" }
}
}
}
```
On an SSO-enforced instance, add `"REACH_SERVICE_TOKEN"` (minted at `/my/tokens`) — it is your
account identity for reads and writes and replaces `REACH_OWNER_KEY`. Otherwise add
`"REACH_WRITE_TOKEN"` / `"REACH_READ_TOKEN"` only if you need gated writes or private reads, and
`"REACH_OWNER_KEY"` to group this client's docs so `my_docs` can list them. Point `REACH_BASE_URL`
at your own deployment to use a self-hosted reach.
## Smithery
This package ships a [`smithery.yaml`](./smithery.yaml) (stdio). Install via the
[Smithery CLI](https://smithery.ai) or the reach page on smithery.ai.
## Claude Desktop (.mcpb, one-click)
[`manifest.json`](./manifest.json) is an [MCPB](https://github.com/modelcontextprotocol/mcpb)
bundle manifest. Build a one-click installer:
```bash
npm run build # produces dist/
npx @anthropic-ai/mcpb pack . # from mcp/, produces reachpad-mcp.mcpb
```
Double-clicking the `.mcpb` installs reach into Claude Desktop; `REACH_BASE_URL`
defaults to `https://reachpad.dev` and tokens are optional.
## Tools
**Read**
- `list_docs`: list documents on the server (public; private too with a read token).
- `get_doc`: raw source of a doc (optionally a specific version).
- `get_doc_meta`: a doc's manifest with metadata, version list, and the verification chain.
- `get_history`: full version and change history of a doc.
- `verify_doc`: recompute and verify a doc's tamper-evident hash chain.
- `get_diff`: bounded unified diff between two versions (defaults to previous to head).
**Write / create** (the aliases share one implementation)
- `create_doc` (aka `share_doc`, `handoff_doc`): create a doc; returns its slug and URLs.
Pass `ownerKey` to own it — the same key edits/deletes it later and lists it via `my_docs`.
- `edit_doc` (aka `update_shared_doc`): new version. Pass `baseVersion` and you get a 409
if it is not the current head, so a stale edit cannot clobber a newer one.
- `edit_section`: edit ONE heading's section, merged onto the head. Agents editing
different sections never clobber each other, so no `baseVersion` or retry is needed.
Markdown docs only.
**Lifecycle**
- `delete_doc`: soft-delete (restorable).
- `restore_doc`: restore a soft-deleted doc.
**Comments** (advisory feedback; does not change content)
- `list_comments`: read the comments people and agents left on a doc.
- `add_comment`: leave a comment with a verdict. `approve` = looks good;
`request-changes` = needs a change / out of date; `comment` = a plain note.
**Your documents**
- `my_docs`: list the docs owned by your owner key (the `ownerKey` you create with). The
same key edits those docs and opens its own private ones; `ownerKey` is optional when
`REACH_OWNER_KEY` is configured.
The tools above operate on single documents. For multi-file, versioned **workspaces**
(a tamper-evident file tree with its own access keys and members) use the tools below.
**Workspaces**
- `create_workspace`: create a SECURE, account-owned workspace (use when a human is present
to sign in). With no signed-in session it returns `{ status: 'awaiting_login', loginUrl,
pollToken, pendingId }` — show `loginUrl` to the human, then poll.
- `poll_workspace_create`: poll a pending secure create after the human opened `loginUrl`;
returns `{ status: 'ready', workspaceId, key }` once — save the key.
- `create_temporary_workspace`: create a TEMPORARY workspace with NO human present
(headless/CI/fleet). Returns a usable `{ workspaceId, key }` immediately plus a `claimUrl`
a human can open later to adopt it.
- `list_workspaces`: list the workspaces your access key (or signed-in account) can reach.
**Files** (inside a workspace)
- `list_files`: list files (path, head version, size, updatedAt). Pull the tree before editing.
- `read_file`: read a file's content + current version; pass that as `baseVersion` on `write_file`.
- `write_file`: create or update a file (last-write-wins). Pass `baseVersion` for a safe,
no-clobber update (409 with current content on a stale write).
- `edit_file_section`: edit ONE markdown section, merged onto head — conflict-free for agents
editing DIFFERENT sections (no `baseVersion` needed).
- `move_file`: move/rename a file to a new path.
- `delete_file` / `restore_file`: soft-delete (recoverable; history preserved) and restore.
- `file_history`: a file's full version + change history.
- `diff_file`: bounded unified diff between two versions of a file (defaults previous → head).
- `verify_file`: verify a single file's tamper-evident hash chain.
- `verify_workspace`: verify the whole workspace — every file's hash chain + the structural audit log.
**Keys & members** (require manage capability)
- `mint_key` / `list_keys` / `revoke_key`: manage a workspace's access keys (a minted secret is
returned once).
- `invite_member`: invite a person by email; returns an `inviteUrl` they open to accept.
- `list_members` / `remove_member`: list members and revoke one by `accountId` (the owner cannot
be removed).
MIT.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing