Agent walkthrough

How to get agents to upload screenshots & video to GitHub

Claude Code, CI jobs, review bots, plain scripts: anything without a browser.

The problem: no drag-and-drop from a terminal #

You put a screenshot on a pull request by dragging the file into the comment box. GitHub then hosts it at github.com/user-attachments/…. That only works in a signed-in browser. There is no gh command and no API for it.

So an agent that just changed your UI can't show its work. The usual workarounds all hurt:

  • Committing images to the repo bloats it forever, for a screenshot that matters once.
  • Random image hosts give you random URLs, expiring links, or need a browser anyway.
  • A hand-rolled S3 script works fine until you want stable URLs, image optimization, and comment cleanup.

The fix: host the file at a public URL the agent can create itself, then write plain Markdown. That's what uploads.sh does.

Step 1: install the CLI and sign in (once) #

npm install -g @buildinternet/uploads
uploads login

uploads login opens a browser sign-in and saves a workspace token. You do this once per machine. Sign in with GitHub or a magic link, then create your own workspace or accept an invite into one. Check your setup with uploads doctor.

Step 2: teach your agent #

One command sets up Claude Code:

uploads install
  • The agent skills teach when to attach screenshots (and when to annotate them with callouts or redactions), plus the full CLI reference.
  • The MCP server offers the same tools (put, attach, list, delete, …) for runtimes that prefer MCP.

Or set up each piece yourself, for other agent runtimes:

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

Step 3: the agent attaches media with one command #

From a branch with an open pull request, attach only needs the files. It finds the PR through gh, uploads each file to a stable URL, and keeps one managed comment:

uploads attach ./before.png ./after.png
# optimizes each image, then keeps one comment on the PR up to date
>> uploading ./before.png
>> uploading ./after.png
>> attachments comment updated

Not on a PR branch? Point it somewhere:

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

Want to place the image yourself, in a PR description or README? --no-comment prints the URL and Markdown without posting anything. uploads put gives full control over naming and output.

Why the URLs matter

Attachments get stable keys, like gh/owner/repo/pull/123/shot.webp. Upload the same filename again and the PR shows the new image at the same URL within a minute. No stale screenshots.

Video and everything else #

A short screen recording is often the best proof that a change works. MP4, WebM, GIFs, zips, logs all upload as-is:

uploads attach ./demo.mp4 # linked from the comment

One caveat: GitHub only plays videos it hosts itself. Outside video shows up as a link, not a player. GIFs embed like images.

Images are optimized by default: re-encoded to WebP, size capped, and EXIF stripped so they load fast and leak nothing. Opt out with --no-optimize or --keep-exif. Add device chrome with --frame phone|browser|iphone-16-pro.

FAQ #

Why can't my agent upload images to GitHub directly?
GitHub's own image hosting (github.com/user-attachments) only works when you drag a file into the comment box in a signed-in browser. There is no gh command or API for it. So any image an agent puts in a comment must already live at a public URL.
Do the image URLs change when I re-upload a screenshot?
No. PR and issue attachments get stable keys like gh/owner/repo/pull/123/shot.webp. Upload the same filename again and every embed shows the new image within about a minute.
Can agents upload video to GitHub pull requests?
Yes. MP4, WebM, and other files upload as-is and get a stable public URL. GitHub only plays videos it hosts itself, so the comment links the file instead of embedding a player.
How do I set up Claude Code to attach screenshots to its pull requests?
Run `uploads install` once. It installs the agent skills (attach workflow, CLI reference, and annotations) and registers the hosted MCP server with Claude Code. After that, the agent runs `uploads attach <files>` on its own when it changes something visual.
Can I mark up a screenshot before attaching it?
Yes. `uploads screenshot --annotate` bakes boxes, arrows, labels, freeform strokes, and redactions into a capture (CSS selectors on a live page). `uploads annotate` does the same on an existing image with pixel coordinates. See the Attach & share docs and the annotate-screenshots skill.
Are uploaded files private?
No. Files are public to anyone with the URL, even media attached to private repos. Don't upload secrets or sensitive UI — use a solid redaction (`uploads annotate` / `screenshot --annotate`) when a capture shows credentials. Uploading itself requires an invite-issued workspace token.

Every command and flag is in the docs. Agents can read /llms.txt or the one-file /llms-full.txt. If this saved you a hand-rolled upload script, a star on GitHub helps others find it.