---
name: tshare
description: >-
  Move files between the person you work with and this machine through
  share.cobanov.dev, a temporary file drop: random uuid links, self-deleting
  after 24h (up to 7d), no accounts. Use when the user pastes a
  share.cobanov.dev link ("look at this", "fetch this", "bu fotoğrafa bak",
  "şu linki indir"), when you need a screenshot or file from their other
  device, or when you must hand a file back to them as a link (a report, a
  rendered image, a log, a build). Also the way to upload from a headless box
  where drag-and-drop is impossible. Triggers: share.cobanov.dev, tshare,
  "share this file", "send me a link", "dosyayı linkle ver", "linki at".
---

# tshare: temporary file drop for agents

`https://share.cobanov.dev` stores a file under a random uuid4 name (or a
custom name you pick) and deletes it when its lifetime ends. Default 24h,
maximum 7d, 100 MB per file. Whoever has the link can fetch it; there is no
login and no listing. The link is the only lock.

Two directions, both one command.

## Receive a file the user shared (most common)

The user pastes something like `https://share.cobanov.dev/8b1c2f3e-….png`.

```sh
curl -fsSLo /tmp/shot.png https://share.cobanov.dev/<id>.png
```

- Keep the extension from the URL; it is the file's real type. Then read the
  local copy with your file or image tool.
- `curl -OJ <url>` keeps the original filename from `Content-Disposition`.
- HTTP 404 means it never existed or already expired. Say so and ask for a
  fresh link; do not retry in a loop.
- `curl -sI <url>` shows `Content-Type`, `Content-Length`, `X-Expires-At`
  before you download.

If the `tshare` MCP tools are available, prefer them: `view` returns an
image inline, `download` saves any file and returns the local path, `info`
checks a link. MCP writes only beneath `TSHARE_DOWNLOAD_DIR` (default
`~/.tshare/downloads`), refuses symlink escapes, and never overwrites existing
files. Use a relative `dest` inside that directory. CLI downloads refuse
existing files unless the person deliberately requests `--overwrite`.

## Send a file to the user

```sh
curl -sT ./report.pdf https://share.cobanov.dev/
```

Prints one line: the URL. Give the user that URL and when it expires.

Options go in headers:

```sh
curl -sT ./report.pdf -H "X-TTL: 3d" -H "X-Slug: q3-report" https://share.cobanov.dev/
```

- `X-TTL`: `30m`, `6h`, `24h`, `3d`, `7d` (above 7d is clamped, below 1m
  rejected).
- `X-Preview`: `private` (default generic card) or `public` (file name and image thumbnail). This changes chat metadata, not who can download.
- `X-Slug`: custom name, 2 to 64 chars of `A-Z a-z 0-9 . _ -`. Guessable, so
  leave it off for anything the user would not want found.
- Add `-i` (or `-D -`) to see the response headers: `X-Delete-Token` lets
  you remove the file early, `X-Expires-At` is the deadline.
- Want JSON instead of the bare URL: `-H "Accept: application/json"` returns
  `{url, key, name, size, content_type, expires_at, delete_token}`.

MCP: `upload` with a local `path` does the same and returns the fields
above. When the user says they copied a screenshot rather than saved it,
`paste` (MCP) or `tshare paste` (CLI) uploads the image straight off this
machine's clipboard, no file needed.

## Delete early

```sh
curl -X DELETE -H "X-Delete-Token: <token>" https://share.cobanov.dev/<id>.png
```

## Rules

1. Never upload secrets: `.env`, private keys, tokens, customer data. Anyone
   with the link can read the file until it expires. The MCP `upload` tool
   refuses credential-shaped paths (`.ssh/`, `.env`, `*.pem`, `.aws/`, ...);
   if you hit that refusal, tell the person rather than copying the file
   somewhere else to get around it.
2. Always tell the user the expiry when you hand over a link.
3. One file per upload. Zip a directory first.
4. Limits: 100 MB per file, 60 uploads per hour per IP, two concurrent uploads
   per IP, ten minutes per upload body. A `429` or `503` includes Retry-After;
   a `408` means the upload timed out. A `507` means the
   server's disk is full; tell the user rather than retrying.
5. Uploaded HTML, SVG and XML are shown as escaped source in a browser or
   downloaded, never executed.
6. TTL deletes the server copy. Downloads and chat app caches may survive.
   Private cards do not add access control.

## Reference

| Method | Path | Notes |
|---|---|---|
| `PUT` | `/<filename>` | body = file; headers `X-Slug`, `X-TTL`, `X-Preview`; reply = URL (or JSON with `Accept: application/json`) |
| `POST` | `/` | multipart `file`, `slug`, `ttl`, `preview` |
| `GET` / `HEAD` | `/<key>` | key = uuid, `uuid.ext`, or slug; supports `Range` |
| `DELETE` | `/<key>` | `X-Delete-Token` required |
| `GET` | `/api/config` | limits, whether an upload token is required |
| `GET` | `/skill.md` | this file |

## Setup (once per machine, optional)

The installer resolves a versioned release and requires its checksum to match
before installing the binary, this skill, and the MCP server:

```sh
curl -fsSL https://share.cobanov.dev/install.sh | sh
```

The installed binary already points at this server, so `tshare up file.png`,
`tshare get <link>` and the MCP tools work with no environment variables.

Tools: `upload(path, slug?, ttl?, preview?)`, `paste(slug?, ttl?, preview?)`,
`download(url, dest?)`, `view(url)`, `info(url)`, `delete(url, delete_token)`.
