# PlainMote > PlainMote keeps and shares configs, logs, notes and other files, byte for byte as given. Every save keeps a version; each recipient or machine gets a link of its own, with its own expiry and use limit, revocable on its own, and every access through it is recorded. It works from a browser, a terminal, an HTTP API and an MCP server for AI apps. Source code (AGPL-3.0): https://github.com/xwvike/plainmote ## Quick share (no account) Send text or a file and get a link back, on one line: ``` cmd | curl -F 'content=<-' https://plainmote.link/paste curl -F content=@app.log https://plainmote.link/paste curl --data-binary @app.log 'https://plainmote.link/paste?ttl=1d&filename=app.log' ``` - `ttl`: how long the link works: `10m`, `1h`, `1d`, `7d` or `30d`. Default `1h`. - `filename`: the name at the end of the link. A form field, or a query parameter with `--data-binary`. - At most 10 MiB, stored byte for byte. UTF-8 text is served as `text/plain; charset=utf-8`; an image, audio or video (recognised by its bytes) as its own type; anything else as `application/octet-stream`, for download. - Success is `201` with the link; a refusal is `400` with a one-line reason. - `curl https://plainmote.link/paste` prints this usage. ## Share links - A link looks like `https://plainmote.link/d//`. The token is the credential: anyone holding the link can fetch the content while the link is valid, with no sign-in. A plain GET returns the raw bytes. - Responses carry an `ETag` (and `Last-Modified` for stored content): a client that polls a link can send `If-None-Match` and gets `304` with no body while the content is unchanged. `HEAD` is answered too. Every request answered, `304` and `HEAD` included, counts as one use of the link and is recorded. - A link to end-to-end encrypted content carries its key after `#`, which is never sent to the server, or is opened with a four-character code. A GET returns only ciphertext, as `application/vnd.plainmote.sealed`; a browser opening the full link decrypts it. ## Accounts - Sign-in is with Google or GitHub; the service sets no sign-in password of its own. - An account keeps resources up to 10 MiB each. A save that changes the content keeps the version it replaced, to compare or restore. Resources can carry tags: free text of at most 24 characters, one spelling per account whatever the case. - Each recipient gets a separate link with its own expiry and use limit, revoked on its own; the owner reads every access. - End-to-end encryption is optional, under a master password only the owner knows. Encrypted content, with its name and filename, is encrypted on the client; the server stores ciphertext and keys it cannot unwrap. ## Command line `plainmote` lists, reads, edits and uploads an account's resources from a terminal or a script. The install script points it at this server. ``` curl -fsSL https://plainmote.link/cli | sh # macOS, Linux irm https://plainmote.link/cli.ps1 | iex # Windows PowerShell ``` - `plainmote login` signs the device in: it prints a code, which the account owner enters at `https://plainmote.link/cli/device` in a signed-in browser. `--read-only` asks for a token that cannot write. `PLAINMOTE_TOKEN` takes the place of the saved sign-in. - `plainmote ls [keyword] [--tag ]`, `cat `, `edit `, `push [--to ] [--tag ]`, `tag ...`, `untag ...`, `tags`, `share [--ttl 10m|1h|1d|7d|30d]` (a quick share; prints its link). A `` is an ID, an ID prefix of at least six characters, or an exact name or filename. - `push` and `share` take `--encrypt`. Encrypted resources are opened with the master password, asked for at the terminal or read from `PLAINMOTE_MASTER_PASSWORD`; the command line keeps no key. - `plainmote help` lists every command and option. ## HTTP API - Base `https://plainmote.link/api/v1/`. JSON, except resource content, which is raw bytes. Errors are `{"error": "", "message": "..."}`. - Authentication is a personal access token (`pmt_...`) in `Authorization: Bearer`, obtained by device authorization (RFC 8628): `POST /api/v1/device/code` with `{"scope": "read"|"write", "device": "..."}`, the owner approves the user code at `https://plainmote.link/cli/device`, then poll `POST /api/v1/device/token` with `{"device_code": "..."}`. A token lasts 90 days; the owner can revoke it under Settings › Authorized apps. - Reading: `GET /me`; `GET /resources?q=&tag=` lists, `GET /resources/{id}` describes, `GET /resources/{id}/content` returns the raw bytes; `GET /tags` lists the account's tags with their counts. - Writing, with a `write` token: `PUT /resources/{id}/content` with `If-Match: "v"` saves a new version (`412` on a conflict); `POST /resources` creates one from a multipart `content` file, with `tag` fields to tag it; `PATCH /resources/{id}/tags` with `{"add": [...], "remove": [...]}` changes its tags; `POST /quick-shares` with `content` and optional `filename` and `ttl` makes a quick share and returns `share_url`. - The API cannot delete resources, manage share links or read access records. Encrypted content is returned as ciphertext, for the client to decrypt. - `https://plainmote.link/developers/cli` and `https://plainmote.link/developers/api` present the command line and the API to people. ## MCP server - `https://plainmote.link/mcp` is a remote MCP server over Streamable HTTP, for AI apps such as Claude, ChatGPT and Cursor. An app connecting to it is sent through OAuth authorization: the account owner signs in on this site and allows or denies it. An authorization covers every tool; none deletes anything. Apps register dynamically or by a client ID metadata document. - Tools: `list_resources`, `list_tags`, `read_resource`, `list_versions` and `diff_versions` (read); `create_resource`, `edit_resource`, `update_resource` and `tag_resource` (write; an edit replaces parts of the text, an update the whole of it, and both name the version they were based on and are refused if the resource has moved on); `share_resource` and `unshare_resource` (share). - Encrypted resources appear only as placeholders: no tool decrypts them or asks for the master password. Unencrypted content an app reads is sent to that app and its model provider. - An authorization lasts until it goes unused for 30 days, and the owner can revoke it at any time. `https://plainmote.link/developers/mcp` explains how to add the server to each app. ## Pages - [About](https://plainmote.link/about): what the service is - [Privacy Policy](https://plainmote.link/privacy): what is collected and kept - [Terms of Service](https://plainmote.link/terms): conditions and acceptable use - [Contact](https://plainmote.link/contact): questions, abuse reports and data requests