uploads.sh

Docs

Put screenshots and other media on GitHub — PRs, issues, code reviews — with one command.

What it does #

Getting an image into a GitHub comment is easy for a person — you drag it in. For an agent or a script, there is no drag-and-drop. uploads.sh fills that gap: it hosts your file at a stable public URL and posts it to the right place on GitHub for you.

The everyday flow is two commands:

uploads attach ./before.png ./after.png
>> uploading ./before.png
>> optimized 421337 → 96412 bytes (before.webp)
>> uploading ./after.png
>> optimized 407190 → 91205 bytes (after.webp)
URL: https://storage.uploads.sh/gh/you/app/pull/123/before.webp
MARKDOWN: ![before.png](https://storage.uploads.sh/gh/you/app/pull/123/before.webp)
URL: https://storage.uploads.sh/gh/you/app/pull/123/after.webp
MARKDOWN: ![after.png](https://storage.uploads.sh/gh/you/app/pull/123/after.webp)
>> attachments comment updated

That's it. The CLI figures out which repo and pull request you're on, uploads the files, and keeps one tidy "📎 Attachments" comment on the PR up to date.

Setting up a coding agent to do this end to end? There's a dedicated walkthrough: how to get agents to upload screenshots & video to GitHub.

Install & sign in #

Install the CLI globally, then sign in once:

npm install -g @buildinternet/uploads
uploads login

uploads login opens a browser so you can approve the sign-in (GitHub or a magic link). Access is by invitation — an uploads.sh administrator invites your email to a workspace first. Once approved, the CLI mints a workspace token and saves it, so you only do this once per machine.

Prefer not to install anything? Every command works as a one-off with npx:

npx @buildinternet/uploads attach ./after.png

To check that everything is wired up:

uploads doctor

Attach files to a PR #

attach is the command you'll use most. From a checked-out branch with an open pull request, it needs no arguments beyond the files:

uploads attach ./screenshot.png

…which lands on the pull request as one managed comment:

Run attach again with new files and this same comment updates in place — your PR doesn't collect a trail of stale screenshot comments.

It uses the gh CLI to find the current repo and PR. If you're not on a PR branch — or you want a different target — say so explicitly:

uploads attach ./shot.png --pr 123
uploads attach ./shot.png --issue 45
uploads attach ./shot.png --repo owner/name --pr 123

Want the URLs and ready-to-paste Markdown without touching any GitHub comment — say, to drop an image into a PR description yourself?

uploads attach ./shot.png --no-comment

Get a URL for any file #

put is the simpler building block: upload one file, get back a public URL and Markdown you can paste anywhere.

uploads put ./shot.png
>> uploading ./shot.png
>> optimized 421337 → 96412 bytes (shot.webp)
>> key: screenshots/app/2026-07-12/shot-9f2c1a.webp

URL: https://storage.uploads.sh/screenshots/app/2026-07-12/shot-9f2c1a.webp
MARKDOWN: ![shot.png](https://storage.uploads.sh/screenshots/app/2026-07-12/shot-9f2c1a.webp)

A few useful variations:

uploads put ./shot.png --pr 123 --comment # also post to the PR
uploads put ./shot.png --no-optimize # upload the original bytes
uploads put ./mobile.png --frame phone # add device chrome

By default, images are re-encoded to WebP (capped size, high quality) so GitHub embeds stay fast, and EXIF metadata is stripped. Use --keep-exif to keep metadata, or --no-optimize to skip all processing.

Set up your agent #

If you use Claude Code or another agent runtime, one command installs both the agent skill and the hosted MCP server:

uploads install

Or set up each piece yourself:

npx skills add buildinternet/uploads --skill uploads-cli
claude mcp add --transport http uploads https://agents.uploads.sh/mcp

The skill teaches the agent when and how to use the CLI — for example, attaching before/after screenshots to the PR it just opened. The MCP server gives agents the same tools (put, attach, list, delete, and more) over HTTP, using the same token as the CLI. There's also a local stdio variant if you prefer:

claude mcp add uploads -- uploads mcp

Manage what you uploaded #

uploads list # see your files
uploads delete <key> # remove a file
uploads usage # storage used by your workspace
uploads --help # everything else

Good to know #

Looking for deeper material — the REST API, enrollment internals, self-hosting, or operator docs? It all lives in the GitHub repository. Agents can also read /llms.txt for a machine-friendly index.