Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

A lightweight MCP data broker that stores large binary payloads under a UUID, enabling MCP clients and agents to exchange massive results without flooding the LLM context window.

README.md

Blob Storage Service

A lightweight MCP data broker that stores large binary payloads under a UUID, enabling MCP clients and agents to exchange massive results without flooding the LLM context window.

Architecture

MCP Client / LLM Agent
        │
        │  tool call (large result)
        ▼
   MCP Server  ──store_blob──▶  Blob Storage Service  ──▶  SQLite + local files
        │                              │
        │  returns UUID                │  retrieve_blob(uuid)
        ◀──────────────────────────────┘

The agent only ever sees a UUID token — not the raw bytes.

Project Structure

src/blob_storage/
├── __init__.py       # package metadata
├── config.py         # pydantic-settings (env / .env)
├── models.py         # SQLAlchemy ORM + Pydantic schemas
├── database.py       # async engine, session factory, init_db()
├── storage.py        # StorageBackend ABC + LocalFileBackend
├── service.py        # BlobService (orchestration)
├── api.py            # FastAPI REST API
└── mcp_server.py     # MCP server (HTTP Streamable, /mcp)

tests/
├── conftest.py       # shared fixtures
├── test_api.py       # API integration tests
└── test_service.py   # service unit tests

Quickstart

Install dependencies

uv sync

Start the REST API

uv run blob-api                            # defaults from config / .env
uv run blob-api --host 0.0.0.0 --port 9000 # override at runtime

Interactive docs available at http://<host>:<port>/docs.

Start the MCP server

uv run blob-mcp                            # defaults: 0.0.0.0:8001
uv run blob-mcp --host 0.0.0.0 --port 9001

The MCP endpoint is served at http://<host>:<port>/mcp.

Configuration

Settings are read from environment variables or a .env file in the project root.

| Variable | Default | Description | |---|---|---| | STORAGE_DIR | ./data/blobs | Directory for blob files | | DATABASE_URL | sqlite+aiosqlite:///./data/metadata.db | SQLAlchemy async DB URL | | DEFAULT_TTL_SECONDS | 7776000 | Default TTL — 90 days. Use 0 for no expiry. | | MAX_BLOB_SIZE_BYTES | 524288000 | Max upload size (500 MB) | | API_HOST | 0.0.0.0 | REST API bind address | | API_PORT | 8000 | REST API port | | MCP_HOST | 0.0.0.0 | MCP server bind address | | MCP_PORT | 8001 | MCP server port | | MCP_API_BASE_URL | http://127.0.0.1:8000 | REST API URL used internally by the MCP server | | SWEEP_INTERVAL_SECONDS | 3600 | How often the TTL cleanup job runs |

CLI flags (--host, --port) take precedence over config/env for the respective server.

REST API Reference

| Method | Path | Description | |---|---|---| | GET | /health | Liveness check | | POST | /blobs | Store a blob | | GET | /blobs/{uuid} | Download a blob | | GET | /blobs/{uuid}/meta | Metadata only (no payload) | | DELETE | /blobs/{uuid} | Delete a blob |

Store a blob

Pass metadata as custom request headers:

| Header | Default | Description | |---|---|---| | X-Mime-Type | application/octet-stream | MIME type of the payload | | X-Ttl-Seconds | config default | Override TTL; 0 = never expires | | X-Origin | — | Free-form source identifier | | X-Tags | — | JSON object for arbitrary labels |

curl -X POST http://localhost:8000/blobs \
  -H "Content-Type: application/octet-stream" \
  -H "X-Mime-Type: application/json" \
  -H "X-Origin: my-mcp-server" \
  --data-binary '{"key": "value"}'

Response: ``json { "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "expires_at": "2026-05-30T16:42:07Z", "size_bytes": 16 } ``

MCP Integration

The MCP server uses the Streamable HTTP transport. Configure your MCP host to connect over HTTP rather than spawning a subprocess:

{
  "mcpServers": {
    "blob-storage": {
      "type": "http",
      "url": "http://127.0.0.1:8001/mcp"
    }
  }
}

Available tools

| Tool | Input | Output | |---|---|---| | store_blob | data_b64, mime_type, ttl_seconds?, origin?, tags? | { uuid, expires_at, size_bytes } | | retrieve_blob | uuid | { uuid, mime_type, data_b64 } | | get_blob_meta | uuid | metadata JSON | | delete_blob | uuid | { deleted: uuid } |

All binary data is base64-encoded in MCP tool calls (MCP messages are JSON/text).

Running Tests

uv run pytest tests/ -v

Extending the Storage Backend

To use S3 or MinIO in production, implement the StorageBackend abstract class in storage.py:

from blob_storage.storage import StorageBackend

class S3Backend(StorageBackend):
    async def store(self, blob_uuid: str, data: bytes) -> None: ...
    async def retrieve(self, blob_uuid: str) -> bytes: ...
    async def delete(self, blob_uuid: str) -> None: ...

Then inject it into BlobService and the _backend singleton in api.py.

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Vector & Memory servers.