Skip to main content
Glama
ulrich-johannes

datastore-mcp

datastore-mcp

A remote MCP server that gives an AI assistant a durable, named key/value store — backed by S3-compatible object storage, with each entry stored as an Open Knowledge Format (OKF) document, fronted by an OAuth 2.1 authorization server.

See datastore-mcp-brief-s3-okf.md (the design brief this implements) for the full rationale. This README covers what's needed to run it.

Tools

state_create, state_get, state_update, state_delete, state_list — see the brief's §4 for exact argument/behavior tables.

Related MCP server: S3 MCP Server

Decisions made while implementing (brief §9)

The brief left six items open. This implementation resolves them as follows:

  1. S3 provider / conditional writes — provider-agnostic; state_create's conflict check uses the universally-supported read-then-write pattern (GET the metadata key first), not a conditional PUT. Works on any S3-compatible provider, at the cost of a narrow single-user race window (brief §8).

  2. type field — caller-supplied optional argument on state_create, defaulting to "mcp-state" when omitted.

  3. Binary response size threshold — 256 KiB (BINARY_INLINE_THRESHOLD_BYTES in src/store.ts). Below it, state_get inlines binary content as base64; at or above it, a presigned URL (1 hour TTL) is returned instead.

  4. Orphaned binary payload cleanup — left indefinitely, matching the soft-delete philosophy. No sweep/lifecycle job is implemented.

  5. Bucket versioning — not enabled by this codebase; left as a bucket-level choice for whoever provisions it. If you do enable it, pair it with a lifecycle rule expiring noncurrent versions (brief §0) — this app's access pattern is frequent overwrite, so unversioned storage grows unboundedly otherwise.

  6. var_name validation^[A-Za-z0-9_-]{1,200}$ (see assertValidVarName in src/store.ts). No separators are allowed at all, which incidentally rules out ../leading-slash/empty-segment path traversal by construction rather than by explicit denylist.

Local development

cp .env.example .env   # fill in S3 + OAuth credentials
npm install
npm run dev

npm run dev runs src/index.ts directly via tsx watch. npm run build && npm start runs the compiled dist/ output, matching what the Docker image runs.

Configuration

See .env.example and src/config.ts for the full list of environment variables and validation rules (brief §7). All required variables are validated eagerly at boot; missing or malformed values fail fast with a specific error message.

Deployment

Two-stage Docker build (Dockerfile), single Fly.io Machine pinned to ams (fly.toml) — see the file for why (in-memory OAuth state, brief §5/§6).

fly launch --no-deploy   # first time only, review fly.toml
fly secrets set S3_ENDPOINT=... S3_REGION=... S3_BUCKET=... \
  S3_ACCESS_KEY_ID=... S3_SECRET_ACCESS_KEY=... \
  OAUTH_USERNAME=... OAUTH_PASSWORD=... PUBLIC_URL=https://<app>.fly.dev
fly deploy

/health performs a live HeadBucket check against the configured bucket — point Fly's health check at it (already configured in fly.toml).

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables interaction with S3-compatible storage services like AWS S3 and Cloudflare R2, supporting bucket management, object listing, reading, uploading, and deletion operations.
    5
    240 npm
    ISC
  • A
    license
    Not graded
    quality
    D
    maintenance
    It Integration for MinIO / S3-compatible object storage, providing AI assistants with direct access to bucket management, object CRUD, presigned URLs, policies, lifecycle rules, and storage analytics.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI clients to read and write to a user-owned markdown bucket via S3-compatible storage, providing a persistent shared context layer across different AI tools.
    32,548 npm
    3
    MIT