PluginBench
MCP Server
Active
Apache-2.0

uploads.sh MCP Server

sh.uploads/mcp

Host file artifacts from coding agents and attach them to GitHub PRs with stable public URLs.

What is the uploads.sh MCP server?

The uploads.sh MCP server lets coding agents capture and host artifacts—screenshots, recordings, test reports, logs, and other files—at stable public URLs that can be embedded in GitHub pull requests and issues. It stages files on a branch and automatically promotes them into a managed comment when the PR opens, with support for before-and-after pairing and metadata tagging.

uploads.sh provides a missing upload capability for AI agents working on code. Instead of waiting for a PR to exist, agents can stage artifacts (screenshots, videos, reports, logs, JSON, PDFs, zips) as they work, then automatically attach them to the PR in one organized comment that updates on each revision. Files get stable, hash-free URLs suitable for embedding anywhere, and can be grouped by project, path, or state. The hosted service is free to start; you can connect your own S3-compatible bucket (Cloudflare R2, etc.) for unmetered storage or self-host the open-source service.

How to install uploads.sh

Copy-paste configuration for popular MCP clients.

transport: stdio
Config generated by PluginBench — verify against the source before use.
Environment / auth
  • UPLOADS_TOKEN
    required
    secret

    Workspace bearer token (up_<workspace>_…). Mint with uploads login.

  • UPLOADS_WORKSPACE

    Workspace name. Inferred from the token when omitted.

  • UPLOADS_API_URL

    API origin. Defaults to https://api.uploads.sh.

  • Authorization
    secret

    Bearer workspace token (up_<workspace>_…) or OAuth access token. Omit this header to use the OAuth browser flow.

~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@buildinternet/uploads",
        "mcp"
      ],
      "env": {
        "UPLOADS_TOKEN": "<YOUR_UPLOADS_TOKEN>",
        "UPLOADS_WORKSPACE": "<YOUR_UPLOADS_WORKSPACE>",
        "UPLOADS_API_URL": "<YOUR_UPLOADS_API_URL>",
        "Authorization": "<YOUR_AUTHORIZATION>"
      }
    }
  }
}

Tools & capabilities

Tools this server exposes to the agent.

  • uploads put — Stage a file with optional metadata (path, state, tags) for later attachment to a PR or issue.
  • uploads attach — Attach staged or new files directly to an open pull request or issue, creating or updating a managed comment.
  • uploads staged — View files staged on the current branch before the PR opens.
  • uploads screenshot — Capture a page, optionally annotate it with callouts, and upload in one command.
  • uploads feed create — Generate a live public feed page of screenshots and artifacts from a repository or pull request.
  • uploads login — Authenticate with GitHub or a magic link to access your workspace.

Use cases

  • Agents capture before-and-after screenshots of UI changes and attach them side-by-side in PR comments for visual review.
  • Test reports, logs, and JSON artifacts are uploaded and linked in PRs without waiting for the PR to be created.
  • Agents annotate screenshots with callouts and redactions, then embed them in issues and pull requests.
  • Repository-wide screenshot feeds provide a browsable gallery of all visual changes across branches and PRs.
  • Agents working on multiple projects organize uploads by repo, path, or metadata, then share or delete files from a workspace dashboard.

uploads.sh MCP server FAQ

What is the uploads.sh MCP server?

It's an MCP server that gives coding agents the ability to upload files (screenshots, videos, reports, logs, PDFs, zips) to stable public URLs and attach them to GitHub PRs and issues. Files are staged on a branch and automatically promoted into a managed comment when the PR opens.

Is uploads.sh free?

Yes, the hosted service at uploads.sh is free to start. You can connect your own S3-compatible storage bucket (Cloudflare R2, etc.) for unmetered storage, or self-host the open-source service.

How do I install it in Claude or Cursor?

Use `claude mcp add --transport http uploads https://agents.uploads.sh/mcp` for Claude Code, or `codex mcp add uploads --url https://agents.uploads.sh/mcp` for Codex. Alternatively, run `uploads install` to add the MCP server and agent skills in one step.

Do I need to authenticate?

Yes, sign in once with `uploads login` using GitHub or a magic link. This creates or joins a workspace where your files and settings are stored.

Can I use my own storage?

Yes. The hosted service uses uploads.sh storage by default, but you can connect a Cloudflare R2 bucket or any S3-compatible provider so storage costs are on your account.

What file types are supported?

Screenshots, screen recordings, test reports, logs, JSON, CSV, Markdown, PDFs, zip archives, and more. See the full list in the Plans & limits documentation.

README (reference)

Source of truth, from the repository.

<div align="center"> <img src="docs/assets/readme-home.png" alt="uploads.sh — the missing upload command for coding agents" width="760"> <h1>uploads</h1>

The missing upload command for coding agents.

Capture screenshots, recordings, and other artifacts as you work: test reports, logs, JSON, PDFs, zips. When the pull request opens, uploads.sh puts them in one tidy comment that updates automatically on each revision. Hosted uploads.sh is free to start. Connect your own bucket — Cloudflare R2 or any S3-compatible provider — so storage in that bucket is unmetered, or self-host the open-source service.

<p> <a href="https://uploads.sh"><b>uploads.sh</b></a> &nbsp;·&nbsp; <a href="https://uploads.sh/docs"><b>Docs</b></a> &nbsp;·&nbsp; <a href="https://www.npmjs.com/package/@buildinternet/uploads"><b>npm →</b></a> &nbsp;·&nbsp; <a href="#quick-start">Quick start</a> &nbsp;·&nbsp; <a href="#what-it-looks-like">What it looks like</a> &nbsp;·&nbsp; <a href="#whats-in-this-repo">What's in this repo</a> &nbsp;·&nbsp; <a href="#local-development">Develop</a> </p> <p> <a href="https://skills.sh/buildinternet/uploads"><img alt="skills.sh" src="https://skills.sh/b/buildinternet/uploads"></a> <a href="https://github.com/buildinternet/uploads/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/buildinternet/uploads/actions/workflows/ci.yml/badge.svg"></a> <a href="https://www.npmjs.com/package/@buildinternet/uploads"><img alt="npm (CLI)" src="https://img.shields.io/npm/v/@buildinternet/uploads?color=cb3837&label=%40buildinternet%2Fuploads&logo=npm"></a> <a href="https://registry.modelcontextprotocol.io/v0.1/servers?search=sh.uploads/mcp"><img alt="MCP server" src="https://img.shields.io/badge/exposes-MCP_server-000"></a> <a href="https://github.com/apps/uploads-sh"><img alt="GitHub App: uploads-sh" src="https://img.shields.io/badge/GitHub%20App-uploads--sh-181717?logo=github&logoColor=white"></a> <a href="https://deepwiki.com/buildinternet/uploads"><img alt="Ask DeepWiki" src="https://deepwiki.com/badge.svg"></a> <a href="LICENSE"><img alt="License: Apache 2.0" src="https://img.shields.io/badge/license-Apache%202.0-blue"></a> </p> <p><sub> <b>Under active development.</b> uploads.sh is being built in the open, so APIs can still change. Feedback is welcome — open an issue. </sub></p> </div>

Artifacts ready when the pull request opens

uploads hosts the artifacts coding agents produce at stable public URLs they can use in pull requests and issues: screenshots and screen recordings, but also test reports, logs, JSON, CSV, Markdown, PDFs, and zip archives (the full list is under Plans & limits). On a branch, uploads put stages each file as soon as it is ready. When the pull request opens, uploads.sh promotes the staged files into one managed comment.

GitHub's own attachments work from a browser and, since GitHub CLI 2.99 (September 2026), from gh … --attach, but only once a pull request or issue exists, and the files stay behind GitHub's own hosting, where they cannot be embedded or fetched anywhere else. uploads.sh gives agents a stable public URL from the same terminal where they build and test the change, while the branch is still in progress. The hosted MCP server does the same for agents that cannot run a command at all, taking files as bytes or a URL. GitHub has no public API (yet) for that.

Keys are hash-free, so re-uploading the same filename overwrites in place and the URL never changes — every embed of it updates at once. Workspaces keep tenants (and their budgets and key policies) apart.

This repo is the source of the canonical deployment at uploads.sh: the API worker, auth worker, MCP server, the Astro web app, and the @buildinternet/uploads CLI (published to npm from packages/uploads).

What it looks like

One comment per PR, rewritten in place on every sync. Files tagged --state before and --state after pair into a side-by-side table; other images and video land below it, and non-media files (reports, logs, archives) list in a file table with their type and size.

<div align="center"> <a href="https://github.com/buildinternet/uploads/pull/436#issuecomment-5052307515"><img src="docs/assets/readme-comment.png" alt="The managed attachments comment on a pull request, with a before/after pair rendered side by side under Before and After headings" width="760"></a> </div>

<sub>The real comment on #436.</sub>

Pairing is by --meta path=… when several pairs share a comment (one before and one after per path), and falls back to filenames that differ only by a before/after token — hero-before.webp with hero-after.webp.

Everything you attach also lands in your workspace, grouped by where it came from — pages by path, projects by repo or app — and browsable from one place.

<div align="center"> <img src="docs/assets/readme-screenshots.png" alt="The screenshots view in a workspace, with uploads grouped into collapsible sections by project and path" width="760"> </div>

<sub>The screenshots view groups uploads by project and path.</sub>

Open any file for a share page: copy-ready embeds (Markdown, HTML, and more), the raw URL, and a delete button.

<div align="center"> <img src="docs/assets/readme-file-page.png" alt="A file share page showing the media preview, a Copy-as embed menu, file details, and a Delete file action" width="760"> </div>

<sub>Each file's share page — copy-ready embeds, details, and delete.</sub>

Quick start

Install the CLI and sign in once:

npm install --global @buildinternet/uploads
uploads login

Upload a file and tag the page it shows:

uploads put ./settings.png --meta path=/settings

On a branch, put stages the file automatically. Open the pull request however you normally would. The GitHub App promotes the staged files into one managed attachments comment.

More ways to upload

Use the same commands for before-and-after evidence, an open pull request, a browser capture, or an annotated image:

# Pair two states from the same page in the pull request comment.
uploads put ./before.png --meta path=/settings --state before
uploads put ./after.png --meta path=/settings --state after

# See what this branch will attach when the pull request opens.
uploads staged

# Attach files directly when a pull request or issue is already open.
uploads attach ./before.png ./after.png

# Capture, annotate, and upload a page in one command.
uploads screenshot http://localhost:4321/settings --via local --annotate ./callouts.json

attach detects the repository and current PR through gh, uploads all files, and creates or updates that same one comment. Without the GitHub App, run uploads attach --promote after opening the pull request to promote files that you staged earlier. All commands run under npx @buildinternet/uploads … without a global install.

Sign in with GitHub or a magic link, then create your own workspace or accept an invite into one — see enrollment. Hosted files are public URLs — private-repo attachments get non-guessable links (how that works), but anyone holding a URL can view the file. Do not upload secrets or sensitive UI.

Connect your agent

The hosted MCP server runs at https://agents.uploads.sh/mcp and is listed in the MCP Registry as sh.uploads/mcp. Local stdio is uploads mcp on the same npm package.

# Claude Code
claude mcp add --transport http uploads https://agents.uploads.sh/mcp

# Codex
codex mcp add uploads --url https://agents.uploads.sh/mcp

# OpenCode
opencode mcp add uploads --url https://agents.uploads.sh/mcp

uploads install adds the agent skills and the MCP server, so future sessions can capture each visual milestone without being asked. The skills also install standalone into any agent runtime:

npx skills add buildinternet/uploads

That installs three skills: github-screenshots (visuals → PRs/issues), uploads-cli (full CLI reference), and annotate-screenshots (callouts and redaction on a capture).

On Claude Code or Codex, the plugin bundles the skills, the MCP server, and a pre-PR screenshot reminder.

Full CLI usage, including annotations, managed comments, public galleries, and change feeds (repo-wide or one pull request), lives in docs/cli.md.

uploads feed create prints a live page of the screenshots on a repo:

<div align="center"> <img src="https://embed.uploads.sh/default/f/docs/vhs-cli/feed-create.gif" alt="Terminal recording of uploads feed create --repo buildinternet/uploads, which prints a feed URL" width="760"> </div>

<sub>uploads feed create --repo buildinternet/uploads.</sub>

REST routes are in docs/api.md.

What's in this repo

PathWhat
apps/The deployables: the REST API worker (api.uploads.sh), the auth worker, the remote MCP server, and the Astro site at uploads.sh
packages/Shared code — most notably @buildinternet/uploads (the CLI, published to npm), @uploads/storage (the files-sdk adapter factory all storage goes through), and @uploads/plugin (Claude/Codex plugin version, not published)
skills/The three agent skills that ship to users
hooks/, plugins/, .mcp.jsonAgent-runtime wiring: the shared pre-PR screenshot hook and the Claude / Codex plugin manifests
server.jsonMCP Registry listing (sh.uploads/mcp): stdio uploads mcp plus the hosted remote

Each worker and the web app deploy separately. All storage access goes through createStorage() in packages/storage — adding a provider is one new case plus peer deps, no API changes.

Docs

Product docs — install, the staged loop, the GitHub App, limits — live at https://uploads.sh/docs. The docs in this repo are the companion: CLI and API reference, contributor setup, and operator material, all mapped from docs/README.md.

How to set up, test, and open a pull request: CONTRIBUTING.md. Where the project is headed: VISION.md. Agent working conventions live in AGENTS.md, and agents that land on this repo should start at llms.txt. The product site serves https://uploads.sh/llms.txt and https://uploads.sh/llms-full.txt.

Local development

Prerequisites: Node ≥24 and pnpm ≥11 (corepack enable). No Cloudflare account needed for the core local loop — wrangler dev simulates R2, KV, and D1 on disk:

pnpm bootstrap        # one-command setup: tooling, deps, env vars, local D1, default workspace
pnpm dev              # API on :8787 (local R2 + KV + D1)

bootstrap is idempotent, and pnpm doctor diagnoses a setup without changing it. The rest of the loop — the authenticated dev stack, the check and test gates, and how to open a pull request — is in CONTRIBUTING.md.

License

Apache 2.0.

Related MCP servers

VAvalv logo

valv

Active

Let coding agents query any SQL database safely. Read-only by default and scoped by your policies.

3
TypeScript
MIT
View repository →

Search and install free React, Tailwind, and shadcn UI components, blocks, and dashboards.

596
TypeScript
MIT
View repository →

Identity, secrets, and passwordless SSH provisioning for AI agents — Keycloak, vault, MCP tools.

View repository →
NANagora logo

Nagora

Active

Buy real goods with Nano (XNO) through escrow. Search, purchase, track orders, get signed receipts.

0
TypeScript
MIT
View repository →

Machine-history prints, merch and £4 print files at notrobo.shop, run by an AI. Cards for downloads.

The Others — an agentic t-shirt shop. Browse products and buy t-shirts via AI agents.