Skip to main content
Glama
fileseal

fileseal-send

Official
by fileseal
README.md
# fileseal-send (MCP server)

A standalone [Model Context Protocol](https://modelcontextprotocol.io) stdio
server that wraps the FileSeal **Secure Send API** (`/v1/sends`). It encrypts
files client-side (AES-GCM-256) before they ever reach FileSeal and exposes
three tools to an MCP client (e.g. Claude).

This package is self-contained: it does **not** import from the FileSeal Next
app. Its crypto (`crypto.mjs`) mirrors FileSeal's server-side attachment format
byte-for-byte — a 12-byte IV followed by AES-GCM ciphertext, with the key
base64url-encoded in the link fragment — so that ciphertext it produces
decrypts on the FileSeal `/receive/[id]` page. That page fixes the format: a
changed `crypto.mjs` produces links that will not open.

## Tools

- **`secure_send`** — encrypt a file and create a send.
  - Inputs: `filePath` *or* (`fileBase64` + `filename` + `mimeType`),
    `recipientEmail?`, `deliveryMode` (`'link'` default | `'email'`),
    `expiryHours?` (1-168, default 48), `message?`, `senderName?`.
  - **link** mode (default, zero-knowledge for the file): the AES key is never
    sent to FileSeal; the tool returns the full share link with the key in its
    `#k=` fragment.
  - **email** mode: FileSeal emails the recipient a working link and stores the
    key server-side. Requires `recipientEmail`. Pass `senderName` too: without
    it the email says the files are from "Someone".
  - **Not encrypted, in either mode:** the file name, `senderName` and
    `message`. FileSeal stores them as plain text and anyone with the link can
    read them, so keep secrets out of `message`.
  - **Limits:** one file per call, up to 3 MB. The file travels inline as
    base64 in the request body, which is what caps it; FileSeal's own 10 MB per
    file is not reachable through this tool. Types: PDF, DOC, DOCX, TXT, JPG,
    PNG.
- **`send_status`** — `{ id }` → status, expiry, download count, audit events.
  Only sends created with the same API key are visible.
- **`revoke_send`** — `{ id }` → the link stops working immediately, and
  FileSeal attempts to delete the encrypted files from its servers.

## Environment variables

| Variable | Required | Default | Purpose |
| --- | --- | --- | --- |
| `FILESEAL_API_KEY` | yes | — | Bearer token sent as `Authorization: Bearer <key>` on every call. The server exits at startup if unset. |
| `FILESEAL_API_BASE_URL` | yes, in practice | `http://localhost:3000` | API origin: set it to `https://fileseal.uk`. The localhost default only suits developing FileSeal itself. Routes are `<base>/v1/sends`. |

## Running

No install needed — `npx` fetches and runs the latest published version:

```bash
FILESEAL_API_KEY=fsk_... \
FILESEAL_API_BASE_URL=https://fileseal.uk \
npx -y @fileseal/send
```

The server speaks MCP over stdio, so it's normally launched by an MCP client
rather than run by hand.

<details>
<summary>Run from source</summary>

```bash
# from this package's directory
npm install
FILESEAL_API_KEY=fsk_... \
FILESEAL_API_BASE_URL=https://fileseal.uk \
node index.mjs
```
</details>

## Wiring into Claude (`.mcp.json`)

```json
{
  "mcpServers": {
    "fileseal-send": {
      "command": "npx",
      "args": ["-y", "@fileseal/send"],
      "env": {
        "FILESEAL_API_KEY": "fsk_your_api_key_here",
        "FILESEAL_API_BASE_URL": "https://fileseal.uk"
      }
    }
  }
}
```

The `"fileseal-send"` key is just the local server label; the npm package is
`@fileseal/send`. To run a local checkout instead, point `command`/`args` at
your copy of `index.mjs`.