Skip to content

Architecture

PCBZ edited this page Sep 6, 2026 · 1 revision

Architecture

flowchart TB
    C1["Claude Desktop"]
    C2["Cursor / other MCP clients"]
    C3["Custom agent<br/>(GPT / Gemini ...)"]

    C1 --> |"Streamable HTTP + Bearer key"| S
    C2 --> |"Streamable HTTP + Bearer key"| S
    C3 --> |"Streamable HTTP + Bearer key"| S

    subgraph S["MCP Server — Python / FastMCP · Cloud Run"]
        direction TB
        A["Auth layer<br/>bearer key -> user_id"]
        T["Tools<br/>remember · recall · list · forget<br/>save_session · load_session"]
        E["Embedder<br/>local fastembed · multilingual<br/>no external / generative-LLM call"]
        R["VectorRetriever<br/>pgvector nearest-neighbour + limit/cursor"]
        A --> T
        T --> E
        T --> R
    end

    S --> |"SQL + vector search"| DB[("Neon Postgres + pgvector<br/>content (plain text) + embedding<br/>HNSW · isolated by user_id / namespace")]
Loading

Data flow

  • remember: client → server computes the embedding locally → text + vector written to Neon.
  • recall: client → server computes the query embedding locally → pgvector nearest-neighbour top-k → returns plain text + pagination metadata.
  • All embedding runs locally on the server — no external / generative-LLM call. Every LLM shares the same model, so the vector space stays consistent.

DB choice — Neon

Requirements: free · Postgres + pgvector (day one) · managed / low-ops · scale-to-zero friendly (Cloud Run scales to 0, so the DB must sleep + auto-wake and provide a connection pool to avoid exhausting connections).

Option Free pgvector Scale-to-zero friendly Notes
Neon Generous free tier ✅ auto-sleep + wake-on-connect, built-in pooler (PgBouncer) best fit; serverless Postgres + branching
Supabase 500MB free ⚠️ free project pauses after ~1 week idle, manual resume bundles auth/dashboard, heavier, idle-pause annoyance
Turso (libSQL) Generous free ⚠️ native libSQL vectors (not pgvector) ✅ edge fine if you want SQLite semantics, but a different vector impl
Cloud SQL (GCP) ❌ no long-term free same ecosystem as Cloud Run, but not free

Decision — Neon: free + pgvector + serverless auto-sleep/wake (a perfect match for Cloud Run scale-to-zero) + built-in pooler. Key implementation note: Cloud Run's many short-lived connections can exhaust Postgres → use Neon's pooled connection string (PgBouncer), not a direct connection.

Service choice — deployment

Requirements: a long-running Python HTTP process · the image carries a local embedding model (onnxruntime + weights, safely >=1GB RAM) · free · HTTPS. All state lives in Neon → the app is stateless and can scale to zero.

Option Free RAM / model DX Cold start Notes
Google Cloud Run Truly free (low traffic) can set 1GB, stable medium (gcloud/Docker) scale-to-zero, first request loads the model most balanced: free + enough RAM + production-like
Render Free web service 512MB tight, sleeps simplest (connect repo) sleep + cold start easiest, OOM risk on RAM
Fly.io Limited free configurable, enough medium (fly.toml+Docker) can stay warm or autostop pick it for always-on / global edge
HF Spaces (Docker) Free CPU 16GB, room for any model simple sleeps, demo-oriented friendly for an MVP demo

Recommendation — Google Cloud Run: truly free (low traffic) + 1GB RAM to run embeddings + scale-to-zero + built-in HTTPS.

  • Fastest first URL → HF Spaces (16GB RAM is generous for the model).
  • Deploy-from-repo → Render (watch the 512MB; pick the smallest model, e5-small).
  • Cold start (first request loads the model) mitigations: small model / lazy load / keep-alive ping.

Clone this wiki locally