<!-- Markdown twin of https://pixelvault.dev/blog/mcp-image-hosting -->

[← Back to blog](/blog)

By [PixelVault](/about) July 6, 2026

# MCP image hosting

Your agent can generate a chart, take a screenshot, or fetch an image — and then it's stuck holding bytes with nowhere to put them. PixelVault runs a remote MCP server, so any Model Context Protocol client can host an image as a native tool call and get a permanent CDN URL back. No custom glue code per project.

The Model Context Protocol gives agents a standard way to call tools. But most useful actions still need _you_ to build the tool — wire an endpoint, handle auth, wrap it in a schema. Image hosting is a perfect example: an agent produces an image constantly (a generated asset, a rendered chart, a failing-test screenshot) and just as constantly has nowhere durable to put it.

PixelVault closes that gap by running the tool for you. There are two ways in: a **remote** MCP server on Cloudflare's edge — nothing to install, nothing to host — and a **local** one you run beside your agent for images that live on your own disk. Both expose image hosting as tools any MCP-capable agent can call.

## Connect it in one command

For Claude Code, add the server with its hosted URL and your API key as a Bearer token:

Claude Code Config JSON

\# Add PixelVault's MCP server to Claude Code:  
claude mcp add \--transport http pixelvault \\  
  https://mcp.pixelvault.dev/mcp \\  
  \--header "Authorization: Bearer pv\_live\_xxx"  
  
\# That's it. The upload\_image, list\_images, get\_image, and  
\# delete\_image tools are now available to the agent.

The endpoint is `https://mcp.pixelvault.dev/mcp` over the `streamable-http` transport, so the same config works in Cursor or any client that speaks it. Get an API key by [registering with a single API call](/docs) — no browser signup required.

## The eight tools

Once connected, the agent sees these tools and can call them on its own:

-   **`upload_image`** — upload from a public `source_url` or raw base64 `data`, and get an instant CDN URL. Optionally pass `expires_in` for an auto-expiring image.
-   **`transform_image`** — build an on-the-fly transform URL (resize, crop, format, AI background removal, effects, watermark) from an image `url` or `id`.
-   **`list_images`** — list your images, paginated.
-   **`get_image`** — fetch metadata and the CDN URL for one image.
-   **`upload_batch`** — upload 1–50 images in one call, grouped into a collection. Partial-failure tolerant.
-   **`sign_url`** — mint a time-limited signed URL for a private image by `id`.
-   **`delete_image`** — delete one image.
-   **`rescue_imgur`** — scan a page for hotlinked Imgur images and get a rescue URL for each (no API key needed).

## What an upload looks like

You don't write any of this by hand — the agent picks the tool and fills the arguments. When you say "host this screenshot" or a step in a chain produces an image, it calls `upload_image` and gets a durable URL it can paste into a PR, a doc, or the next tool's input:

// The agent invokes the upload\_image tool — from a public URL...  
{ "tool": "upload\_image",  
  "arguments": { "source\_url": "https://oaidalleapi.../gen.png" } }  
  
// ...or from raw base64 it already has in context:  
{ "tool": "upload\_image",  
  "arguments": { "data": "iVBORw0KGgoAAAANS...", "filename": "chart.png" } }  
  
// → a permanent CDN URL comes back:  
{ "url": "https://img.pixelvault.dev/proj\_abc/img\_xyz.png",  
  "id": "img\_xyz", "mime\_type": "image/png", "size": 20481 }

Because `upload_image` accepts a `source_url`, an agent can re-host a temporary link — like a [DALL·E or GPT Image URL that expires in an hour](/blog/host-ai-generated-images) — without downloading the bytes itself. Hand it the URL, get a permanent one back.

## Local files: the one thing a remote server can't do

There's a real limit to the hosted server, and it's worth naming plainly: it runs on Cloudflare's edge, so it **cannot read your filesystem**. Give it a `source_url` and it fetches the image itself. But when the image is a screenshot your agent just took, or a file sitting in the repo, the only way to get it through a remote tool is to inline it as base64 — which pushes the whole image through the model's context and falls over on anything but small files.

So there's a second server that runs locally over stdio, published as [@pixelvault-dev/local-mcp](https://www.npmjs.com/package/@pixelvault-dev/local-mcp). It carries six of those eight — everything except `upload_batch` and `rescue_imgur` — and its `upload_image` also accepts a **`path`**:

Add it Upload by path

\# The local server runs next to your agent, over stdio:  
claude mcp add pixelvault-local \\  
  \--env PIXELVAULT\_API\_KEY=pv\_live\_xxx \\  
  -- npx -y @pixelvault-dev/local-mcp  
  
\# Nothing to install ahead of time — npx fetches it on first run.

It reads the file off disk and streams the bytes to the API, so nothing large ever enters the conversation. Auth works the same way the [CLI](/blog/host-images-with-your-coding-agent) does — `PIXELVAULT_API_KEY` from the environment, or `~/.pixelvault/config.json`. The source is [on GitHub](https://github.com/pixelvault-dev/mcp-local) under MIT.

Which one to run: take the **remote** server if your agent works from URLs, or if you'd rather not run anything locally. Take the **local** one if it works with files on disk. Running both is fine — they're separate entries in your MCP config.

## Why MCP instead of a raw API call

You could always POST to the [REST API](/image-hosting-api) directly, and for scripts that's often the right move. The MCP server earns its place when an _agent_ is the one deciding to host an image:

-   **No per-project glue.** The tool schema is discovered at connect time — you don't hand-write an upload function and describe it to the model in every repo.
-   **Portable across clients.** The same server works in Claude, Cursor, and anything else that speaks MCP. Switch clients, keep the tool.
-   **Autonomous by design.** Paired with PixelVault's [llms.txt](/llms.txt) and OpenAPI spec, an agent can discover the service, register, and start hosting images with no human wiring anything up.

## No MCP client? Plain HTTP still works

MCP is the ergonomic path for agents, not a requirement. Every tool maps to a plain endpoint — `upload_image` is a `POST /v1/images` (a multipart file upload, so you fetch or decode the bytes yourself), and the rest follow. If you're scripting outside an agent, the [HTTP API](/docs) is right there.

## Free to start

The free tier includes 200 MB storage, 500 uploads/month, and 1 GB bandwidth — no credit card, no trial expiry. Connect the MCP server, register for a key, and your agent can host images in the next turn — the first few uploads work straight away, and a one-time email verification lifts the cap for the rest of the free tier. Paid plans start at [$9/month](/pricing).

[Read the MCP docs →](/docs#mcp)
