Back to Naptown Labs

Case Study

ClaudeVault

A self-hosted REST API workspace for Claude AI agents — persistent memory, git-backed vaults, real-time response loops, and HMAC-signed webhooks.

8 API Modules
19 Memory Files
<10s Response Loop
3 Roles (RBAC)

Stack

Python API serving a React SPA, backed by PostgreSQL and Redis, all containerized in Docker Compose.

Backend

FastAPI with async SQLAlchemy 2.0 and asyncpg for non-blocking database access. Pydantic v2 for request/response validation. Alembic for migrations. GitPython for vault file operations with real git commits.

FastAPI SQLAlchemy 2.0 asyncpg Pydantic v2 Alembic GitPython

Frontend

React 18 SPA built with Vite 6 and Tailwind CSS 4. TypeScript throughout. Dashboard with real-time agent event feed, resource stats, document editor, memory browser, and webhook management.

React 18 TypeScript Vite 6 Tailwind CSS 4 Axios

Infrastructure

Multi-stage Dockerfile builds the React SPA then layers it into the Python image. PostgreSQL 16 for data, Redis 7 for caching and rate limiting, bare git repos for file vault storage. Automated backups.

Docker Compose PostgreSQL 16 Redis 7 Proxmox LXC

Architecture

A single Docker Compose stack running on a Proxmox LXC container, with a watcher service on a separate host that bridges the dashboard to Claude CLI.

// Docker Compose stack (CT 111) FastAPI (uvicorn, 2 workers, port 8000) | |-- /api/v1/auth JWT RS256 + API keys |-- /api/v1/vault Git-backed file repos |-- /api/v1/docs Versioned documents |-- /api/v1/memory Key-value store + TTL |-- /api/v1/agents Sessions + event feeds |-- /api/v1/projects Projects + tasks |-- /api/v1/webhooks HMAC-signed events '-- /api/v1/health Liveness + readiness | +--> PostgreSQL 16 // all persistent data +--> Redis 7 // rate limits, webhook cache, TTL tracking '--> Git repos // bare repos on disk volume // Watcher service (CT 207, separate host) Node.js watcher polls GET /agents/:id/events?since= | |-- Filters for event_type: "user_message" |-- source: "dashboard" --> spawns claude -p --resume '-- source: other --> writes .claude-vault-inbox.md // External integrations Webhook --> n8n --> Discord #naptown git push --> post-receive hook --> memory files synced to ClaudeVault docs

Real-Time Response Loop

Send a message from the dashboard and get a Claude response posted back to the feed in under 10 seconds — no browser extension, no API wrapper.

  1. 1 Dashboard message — User types a message in the web UI. The frontend POSTs an agent event with event_type: "user_message" and metadata.source: "dashboard"
  2. 2 Watcher poll — A Node.js service on CT 207 polls the events endpoint every 2 seconds. When it sees a new dashboard message, it claims it
  3. 3 Claude CLI spawn — The watcher spawns claude -p --resume with the message as input. Runs on the same host as the Claude Code installation
  4. 4 Response posted — Claude's output is captured via stdout and POSTed back as a new agent event with event_type: "assistant_message"
  5. 5 Feed updates — The dashboard auto-scrolls, trims to 100 events, and shows a "Thinking" dots indicator while waiting. The webhook system also fires, pushing the event to n8n → Discord

API Surface

Eight modules behind a consistent REST envelope. Every response wraps data in { success, data } with paginated list endpoints.

Vault

Git-backed file storage. Create repos, read/write/delete files (each producing a real git commit), browse directory trees, and query commit history. Branches supported.

Documents

Versioned document store with full-text search, template support, and tagging. Every edit creates a version snapshot for history and rollback.

Memory

Namespaced key-value store with optional TTL. Supports bulk operations, namespace export, direct key lookup, and search. Designed for agent context persistence across sessions.

Agents

Manage agent sessions with status tracking. Post events to agent feeds (messages, tool calls, system events) and query by time range or event type. Supports reordering.

Projects & Tasks

Organize work into projects with task lists. Status tracking, priority ordering, and task assignment. Each project scopes agents and documents.

Webhooks

Subscribe to events with glob pattern matching. HMAC-SHA256 signed payloads, automatic retries with exponential backoff, delivery history, and auto-disable after 50 consecutive failures.

Webhook System

Production-grade event delivery with signed payloads, retry logic, and self-healing subscriptions.

HMAC Signing

Every payload is signed with HMAC-SHA256 using a per-subscription secret. Consumers verify via the X-ClaudeVault-Signature header. Secrets are generated at creation time and can be rotated.

Retry & Backoff

Failed deliveries retry up to 3 times with exponential backoff. Retries are queued in Redis and processed by a background loop. After 50 consecutive failures, the subscription auto-disables to prevent noise.

Event Pattern Fires On
agent.* Agent created, updated, or deleted
agent_event.created New event posted to any agent feed
vault.* File written or deleted in any repo
doc.* / memory.* Document or memory entry mutations
project.* / task.* Project or task lifecycle events
* Wildcard — matches everything

Security & Auth

JWT with RSA-256, scoped API keys, role-based permissions, audit logging, and rate limiting.

JWT RS256

Access tokens signed with RSA private key (30-min expiry). Refresh tokens last 7 days. Keys generated via OpenSSL and stored on a Docker volume.

API Keys

Prefixed with cv_prod_ or cv_dev_. Support rotation without downtime. Scoped to the creating user's permissions. Used by the watcher and MCP server.

RBAC

Three roles: admin (full access + user management), agent (read/write, no admin), viewer (read-only). Permissions checked on every request.

Audit Log

Every mutation is logged with user ID, action, resource, and metadata. Admin-queryable via GET /auth/audit with filters for user and action type.

Rate Limiting

Redis-backed sliding window: 60 requests/minute per user with a burst allowance of 10. Configurable via environment variables. Returns 429 with retry-after header.

MCP Integration

A built-in Model Context Protocol server lets Claude Code interact with ClaudeVault directly — read/write memory, manage docs, browse vault files, and track projects without leaving the terminal.

How It Works

The MCP server wraps the REST API using FastMCP. It authenticates with an API key and exposes tools for memory CRUD, document search, vault file operations, and project/task management. Add it to .mcp.json and Claude has full workspace access.

Memory File Sync

Every git push to the config repo triggers a post-receive hook that upserts all .md files as ClaudeVault documents tagged memory-file. An n8n workflow then fetches them all, sends to Claude Haiku for audit, and posts findings to Discord.