# One-time file transfer — setup

You are setting up one-time file transfer for this user. Nothing needs
installing: upload with curl, straight to the API. Never read a local file
into base64 or pass it through an MCP tool argument.

When the user names a file, upload it with the command below. If they haven't
named one yet, say you are ready and ask which file to send.

## Upload a file

```sh
curl -sS -X POST \
  "https://otfs.obelism.studio/api/files?name=<name>" \
  --data-binary @<path>
```

Replace `<path>` with the file the user named and `<name>` with its
filename. The response is JSON:

```json
{"id":"…","url":"https://otfs.obelism.studio/f/…","expiresAt":"…","size":123}
```

Give the user `url`. It works exactly once: the first `GET` consumes it.
Never open it to check that it works, and don't paste it anywhere that might
unfurl it before the recipient needs it.

Options:

- `-H "X-Expires-In: 3600"` for a one-hour link; 60 seconds to 7 days,
  default 24 hours.
- `-H "Content-Type: image/png"` if the download should name its type;
  the default is `application/octet-stream`.
- One request per file when there are several.
- 100 MiB per file, 30 uploads per minute per address.

## Download

```sh
curl -OJ "<url>"
```

The second request returns 404. `HEAD` is safe and does not consume. Known
link-preview bots are refused, but the check is best-effort: an unknown
unfurler can still burn a link.

## Optional: CLI

`otfs` streams the file and guesses the content type:

```sh
npm i -g github:Obelism/one-time-file-share
otfs upload image.png
```

## Optional: MCP

MCP tools take bytes as base64, so use them only for small content, never for
a file on disk. Add this to an MCP client:

```json
{
  "mcpServers": {
    "otfs": {
      "type": "http",
      "url": "https://otfs.obelism.studio/mcp"
    }
  }
}
```

Or, in Claude Code:

```sh
claude mcp add --transport http otfs https://otfs.obelism.studio/mcp
```

Tools: `upload_file` (base64), `file_status` (by id, does not consume),
`revoke_file` (by id).

## Status and revoke

```sh
curl https://otfs.obelism.studio/api/files/<id>
curl -X DELETE https://otfs.obelism.studio/api/files/<id>
```

Both take only the id. The id is the capability, so treat it like the link.
