Skip to main content
Glama
shgsousa
by shgsousa

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.

Related MCP server: Forgetful

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:

{
  "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.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Store and retrieve data objects for free. Temporary cloud storage for agents. Two hour expiry. Works with any format and flow. Example use cases include: * Manage large datasets across different sessions * Generate shareable links for intermediate results * Streamline complex workflows by bridging information between multiple contexts
    2
    49 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A storage and retrieval MCP server for AI agents using FastMCP, enabling persistent knowledge base with semantic search and automatic linking.
    3
    299
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides AI agents with persistent knowledge storage, enabling them to store, search, and retrieve text, documents, and files using semantic and keyword search via MCP tools.
    32
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Lightweight object storage with S3, HTTP, and MCP interfaces, enabling AI agents to store and retrieve files via structured tool definitions.
    4
    Do What The F*ck You Want To Public