Project routing

Codename Kumo (雲 — “cloud” in Japanese). The codename is inferred from the same-week kumo todos note in the inbox (2026-05-13), whose three implementation items — wider-file-type embedding with pre-compression, embedding-progress indicator surfaced to API + clients, “rich presence multiplayer” — line up directly with the embedding pipeline, multi-client API, and shared-org member model below. If the codename refers to a different project, this hub can be renamed; the design doc body is unchanged.

Agent-Native Cloud File Storage

Core Premise

Cloud file storage built natively for AI agents. Not a legacy storage provider with an API bolted on — built from the ground up so that agents are the primary interface, with human browsability as a secondary feature. Dropbox/Google Drive are human-first. This is agent-first.

Two Pillars

1. Great Agent Integration

First-class connectors that make it trivial to plug any agent into the storage:

  • MCP server — exposes filesystem-like tools modeled after what coding agents already use locally: read, write, edit, grep, glob, find. Agents interact with cloud files the same way they’d interact with a local codebase.
  • CLI — command-line access for scripting, automation, and agent toolchains.
  • Pre-built skills — ready-made skills that agents can load (e.g., for Claude Code, ChatGPT, etc.) so setup is not just “here’s an API” but “here’s a working integration in 2 minutes.”
  • REST API — standard API for custom integrations.

2. Fine-Grained Agent Access Controls

Agents use the same auth system as humans (see Orgs & Users). Provisioning an agent is the same flow as inviting a human, with the same scope/permission UI — only the credential type at the end differs (API key vs. email invite).

Configurable per agent:

  • Path scope — which files and folders the agent can see. A personal agent might get full access. A work agent might only see /work/. A shared agent gets read-only on /shared/.
  • Action permissions — what the agent can do within its scope. Read-only, read-write, read-write-delete, etc.
  • Per-agent credential — each agent gets its own API key with its own scope. Revoking one doesn’t break others.

This means a user can safely connect multiple agents with different trust levels to the same storage. The vault owner stays in control.

Orgs & Users

Even solo users operate inside an org (“Default” by default). Humans and agents share one auth system — only the credential type differs.

  • Org — top-level container. Owns the storage. All members (humans + agents) are scoped to an org.
  • Member types (single members list in the UI; user_type distinguishes them visually):
    • Human — invited via email (sent through Resend), completes signup, logs in with credentials.
    • Agent — provisioned by a human, no login credentials, authenticates via API key.
  • Permission tiers (apply to both humans and agents):
    • Owner — full control, billing, can delete the org. Humans only.
    • Unrestricted — admin-level access to all files and settings. For an agent, this is equivalent to an unrestricted API key.
    • Scoped — restricted to specific files/folders and specific actions. For an agent, this is a scoped API key.

Inviting a human and provisioning an agent are the same flow with the same scope UI; the only branch is at the end: emit an email invite (Resend) or emit an API key. A “scoped human” and a “scoped agent” are the same concept at the auth layer.

Public share links are not in the MVP — every accessor (human or agent) is an org member.

Open question: abstraction layer for the credential split. Lean toward a single members table with user_type (human/agent) and auth_type (password+session / api_key) columns, rather than separate users and agents tables joined via a view. Keeps the auth middleware uniform: resolve any incoming request to a member_id + scope, regardless of credential type.

Product Shape

Clients split by audience:

  • Web UI (v1) — human client. Browse files, manage folder structure, manage org/members, invite humans, provision agents, configure scopes and permissions. Not a document editor — just file management and browsing.
  • MCP serveragent client. Filesystem-like tools (read, write, edit, grep, glob, find).
  • CLIagent client. Same surface as MCP, scriptable for agent toolchains.
  • Mobile / Desktop app — future human clients. Lightweight input (memos, photos, quick notes) and browsing.

All clients — UI, MCP, CLI — talk to the API server only. The API server is the single source of truth: it owns all reads/writes to Postgres, Redis, and S3. No client talks to S3 (or any backing service) directly — not even via presigned URLs. This keeps permission checks, audit logs, and embedding pipelines impossible to bypass.

On first setup, the user is guided to provision an agent and plug it into their existing agent runtime via MCP or CLI.

What This Is Not

  • Not a knowledge management system — no built-in reconcile loop, no opinionated structure. The user (or their agent) brings the workflow.
  • Not an AI product — no inference, no chat, no LLM costs. Pure storage + tooling.
  • Not offline-capable — online-only, server is the single source of truth. No sync conflicts.

Selling Point

“Cloud storage your agent can actually use.” Every agent today can read/write local files. None of them have a good cloud storage layer with proper access controls. This fills that gap.

Tech Stack

Decisions based on research (May 2026). Keryx was considered but rejected — right idea (one action = HTTP + MCP + CLI), but months-old single-maintainer Bun rewrite with no production users. Assemble the same value from mature parts instead.

LayerChoiceWhy
RuntimeNode.js 22 LTSBoring, works. Bun optional later.
HTTP frameworkHono 4.xTS-first, runs on Node/Bun/Edge. @hono/mcp middleware for MCP Streamable HTTP with OAuth helpers.
MCP@modelcontextprotocol/sdk + @hono/mcpOfficial SDK + Hono middleware. Single app.all('/mcp', …) handler.
AuthBetter Auth + @better-auth/api-keySelf-hosted in own Postgres, no per-MAU billing. API keys carry { files: ["read","write"], paths: ["/acme/*"] }. Custom path-glob verifier ~30 LOC.
ORMDrizzle ORM v1SQL-transparent, first-class pgvector vector() type. No codegen.
DatabasePostgres 17 + pgvector 0.8+Metadata, org/user/permissions, and embeddings in one DB. HNSW index. Good to ~10M vectors.
EmbeddingsGemini Embedding 2 (GA April 2026)Multimodal — text, images, video, audio, PDFs in one vector space. 3072 dims, Matryoshka-truncatable to 768. $0.20/M text tokens.
Blob storageS3-compatible — R2 (prod), MinIO (dev)R2: $15/TB/mo, free egress. MinIO in Docker Compose for dev only (AGPL). Endpoint, bucket, credentials all configurable via .env. Only the API server holds S3 credentials — clients never touch S3.
EmailResendInvite emails for human members.
Job queueBullMQ (Redis-backed)Async embedding on upload. Same Redis for sessions/rate limits. MIT.
Cache / rate limitsRedisSessions, rate limiting, BullMQ broker.
Reverse proxyCaddy 2Removed — Dokploy (or k8s) handles TLS termination and routing.
CLICommander.jsThin client calling REST API. Same Zod schemas as routes.
DeployDokploy (primary) or k8s (alternative)Dokploy: self-hosted PaaS with built-in TLS, deploy previews, Docker Compose support. k8s if scaling demands it later.
ObservabilityOpenTelemetry + Grafana Cloud free tierHono and BullMQ both have OTel adapters.
Config.env fileAll config via env vars.

Architecture (Docker Compose, single machine)

UI (browser) ─┐
MCP client ───┼─► hono-api (REST + /mcp; sole entry point, TLS via Dokploy/k8s)
CLI ──────────┘      │
                               ├─► postgres (pgvector)
                               ├─► redis (sessions, rate limits, BullMQ)
                               └─► S3 (R2 / MinIO) — credentials held by API only

bullmq-worker ─► redis ──► gemini-embedding-2 API
                       └─► postgres (write embeddings)

resend ◄── hono-api (invite emails)

API server is the source of truth. No client talks to S3 directly — no presigned URLs, no direct PUT/GET. All blob bytes stream through the API server so permission checks, audit logging, and embedding-job enqueue can’t be bypassed.

  • Upload flow: client → POST /files (streamed body) → API streams to S3 → on commit, enqueue embedding job → return file metadata.
  • Download flow: client → GET /files/:path → API checks scope → streams from S3 to client.

Auth flow

Unified for humans and agents — same scope/permission API, different credential at the end.

Invite human:

  1. Owner/admin in web UI: POST /members/invite{ email, permissions: { files: [...], paths: [...] } }.
  2. API sends invite email via Resend with signup link.
  3. Invitee completes Better Auth signup, joins org as a human member with the configured scope.

Provision agent:

  1. Owner/admin in web UI: POST /members/agents{ name: "Claude", permissions: { files: ["read"], paths: ["/projects/acme/*"] }, expiresIn: 2592000 }.
  2. Prefixed API key issued (agt_live_…). Human pastes into agent MCP/CLI config.
  3. Agent joins org as an agent member, visible in the same members list with a distinguishing icon.

Auth on requests (UI / MCP / CLI all hit the same API):

  • Human: session cookie from Better Auth.
  • Agent: Authorization: Bearer agt_live_….
  • Middleware resolves either credential to a member_id + scope; same path-glob verifier applies.
  • All actions logged: (member_id, user_type, tool, path, outcome).

Public share links are out of scope for MVP — every accessor is an org member.

Dev environment

  • MinIO container in Docker Compose for local S3.
  • S3 endpoint + bucket + credentials configurable via .env — same code path for MinIO (dev) and R2 (prod).

Graduation paths

WhenDo
Permissions get complexAdd Ory Keto (Zanzibar/ReBAC) sidecar
Vector search >100ms p99Migrate to Qdrant sidecar
Multi-machine deployMigrate from Dokploy to k8s
Multi-step async workflowsTrigger.dev v4 instead of BullMQ

Open Questions

  • Permission DSL — keep Unix-style globs + deny-by-default. Don’t invent a policy language.
  • File format — format-agnostic or opinionated toward text/markdown?
  • Pricing model — per-storage, per-API-call, flat subscription?
  • Embedding strategy — Gemini for everything, or Gemini multimodal + cheaper Voyage-3-lite for text-only?

Active todos

Running implementation list — see todos.

Memos

  • Projects — parent index; Kumo registered under “In progress”.
  • Hibi — sister project (same developer, same Claude-Code build pattern, different domain).
  • Agent-Native Software Architecture — the orchestrator/sub-agent/skills/MCP pattern this implements at the storage layer; Kumo’s MCP + skills story is exactly the “MCP / CLI tools = APIs / SDKs” row of that table.
  • Open-Source Model-Agnostic AI Platform — sibling platform-level idea: same self-host-vs-managed-SaaS framing, different layer of the stack (compute/agents vs. storage).
  • OpenClaw for PKM — adjacent project: PKM-style use cases that Kumo’s filesystem-like agent tools could host as the storage layer, while OpenClaw owns the reconcile loop.
  • 2026-05-06-Standalone PKM app - yjs CRDT sync stack — overlapping stack decisions (assistant-ui + Claude Code SDK in that proposal; here the inverse — pure storage with no AI built-in). Useful tradeoff comparison.
  • 2026-05-06-Standalone PKM app - cons of Obsidian setup, sync, UI focus — names the cloud-routines / sync pain points that motivate a cloud storage layer designed for agents.
  • AI Native PKMs — earlier framing of AI-first knowledge tooling; Kumo is the storage substrate that would sit under such an app.
  • There is no main js — essay context on agent-native software; Kumo’s MCP-first surface is the storage-layer instance of that pattern.
  • Idea – Inbox Prompt Types — adjacent: an inbox-style storage layer agents can drop instructions into; Kumo’s per-agent path-scope makes that pattern enforceable at the storage tier.
  • Ideas — Apps section; cross-referenced as the cloud-storage entry for the agent-native ecosystem.
  • This Vault as an Example — points back to this vault as an instance of agent-native software; Kumo proposes hosting that pattern in the cloud.
  • 2026-05-19-Distill app review - AI-native PKM with local-only limits — comparable PKM at the app tier; its biggest dealbreaker (local-only MCP, no HTTP MCP) is exactly the gap Kumo’s MCP + REST surface fills for the storage tier above it.