HivePaaS
An open-source, self-hosted PaaS on Docker Swarm. Deploy apps, databases and functions from one VPS to a whole cluster, with SSL, backups and autoscaling built in.
You make the calls. Your AI agents capture them as they work, then bring them back in your next session, on a different tool, or to a collaborator joining the project. The recipe book builds itself.
Developer toolsTypeScript · JavaScriptGitHub @AndyForestOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Your taste and judgment, in every AI agent you use. Shared, append-only memory of a human's judgment calls - agents recipe-check via MCP or plain URLs. MIT, self-hostable.
Taken from the repository README
Loading the full README.
Read the full README ↗Soup.net is shared memory for AI agents. The agents you work with record your judgment calls as they happen, then bring them back in your next session, on a different tool, or to a collaborator's agent joining the project. The recipe book builds itself.
The unit of storage is a recipe: one judgment call in a structured, evidence-backed form — "As a [role] working on [goal], I prefer [X] so that [reason]", plus verbatim supporting quotes. Agents use it through a recipe check: a semantic search whose only side effect is an append. Your agent searches with its current hypothesis about your taste, gets back your prior decisions with their evidence, and the hypothesis itself becomes a trace future agents can find. Nothing is ever overwritten, and every check makes the next one smarter — the same mechanism ants use to reinforce pheromone trails (stigmergy).
AI agents finish bigger and bigger pieces of work on their own, and you never run just one. Every new session is a fresh agent, every tool is another, and collaborators bring their own. Each one needs your answers, separately, from scratch. The scarce resource is you.
Most agent memory stores facts and conversation state, inside one vendor's ecosystem. Soup.net stores the judgment call itself, with the context and evidence that scope it, and it lives with you — portable across Claude Code, ChatGPT, Gemini, or the custom agent your team wrote in-house. Past decisions come back as context, not directives: your agent weighs them against the current task instead of replaying stale facts.
Because every check leaves a dated, append-only trace, you also get observability for free: one inspectable log of the judgment your agents exercised on your behalf. As agents run longer between check-ins, that record is what keeps you in the driver's seat.
When an agent's context does not settle a call, it deposits a draft instead of a recipe: a hypothesis visible only to you and your own agents, waiting in a review queue. You confirm or reject it in one click, or another of your agents resolves it when its context holds the answer, quoting what settled it. Agents that run unattended get headless keys, whose every deposit is a draft. Drafts are how an agent keeps working with confidence instead of stopping to ask, and how what it assumed becomes something you can see and correct.
Soup.net is developed with its own workflow. The AI agents that build it recipe-check their design decisions into the maintainer's corpus as they work — so the system's design history lives in the system, and the agents extending it retrieve the judgment calls that shaped the code they're changing.
The Recipe Map is how a human watches that corpus grow: recipes cluster by semantic similarity, projected onto any two concept axes you choose.
A field evaluation ran over the maintainer's real work in mid-2026 — two projects, coordinator agents spawning sub-agent fleets, every agent briefed to check at judgment moments and self-report what each check did for it. The honest scope: one developer, a 3-day feedback window over a 3-month corpus, all Claude-family agents. Observational, not a benchmark.
Known failure modes, from the same evaluation: the self-reporting never once said "no" (treat every percentage as an upper bound); a young corpus returns nothing for roughly 1 in 10 checks (that's seeding, not failure); and batched end-of-session checks mostly retrieve the agent's own fresh traces. Check at the judgment moment, not in a closing ceremony. And one honest gap: the plain-URL path is tested working with ChatGPT (web), Gemini, and Claude — but every instrumented field row so far comes from Claude-family agents in Claude Code, so cross-vendor effectiveness numbers don't exist yet. If you run it from another harness, you're generating the first real data.
Hosted — free, open to new signups: soup.net. The site generates a one-click briefing for whatever agent you use, from web-only chatbots to full MCP clients. On claude.ai, connect in one click from the Connectors Directory listing (all plans, including Free).
Once connected, tell your AI to "use Soup.net throughout" at the start of a session, and again if it stops, for example after compaction. Some agents won't reach for it unless asked. A line in your agent's memory or rules file does the same job every session.
The web-chatbot path is a first-class interface, not a fallback: agents without MCP participate through generated links — the recipe check is a URL the agent constructs or the human clicks. Tested working with ChatGPT (web), Gemini, and Claude, free tiers included.
Self-host — MIT-licensed, deliberately boring stack (Postgres 17 + pgvector, Hono, React). No LLM runs on the server for the core check path: agents do the reasoning wherever they already run; the server does storage and vector search. (Optional premium features — off by default, opt-in per user — use one server-side LLM call; see docs/planning/premium-llm-features.md.) Embeddings default to Google's Gemini API (an AI Studio key works; a deterministic stub provider covers dev and tests with zero API calls), but self-hosters can run them fully locally with no key — in-process on CPU, or against any local /v1/embeddings server (Local / offline embeddings below). Gemini is then needed only for the optional premium features. Quick start below. Either way your corpus exports as a single JSON file (GET /auth/me/export, signed in) — and imports back: POST /import accepts that same file as the raw request body (signed-in humans only), so a corpus can move between instances, restore from backup, or rebuild into a fresh recipe book. By default import creates a new recipe book (name it with ?book_name=); pass ?book=<slug|id> to import into an existing one. Re-importing your own corpus is idempotent (exact-id upsert — re-uploading skips what already landed); importing a corpus whose ids belong to someone else on the instance mints fresh ids and reports the old→new mapping, so it's a portability tool, not a byte-identical restore (a row can even arrive without an id and still import). Import re-embeds asynchronously through the content-addressed vector cache, so text the instance has embedded before costs zero provider calls — and deleting an account preserves that shared cache, so re-provisioning the same corpus stays free.
Point an MCP-capable agent at the hosted service in one line:
claude mcp add --transport http soupnet https://mcp.soup.net/mcp --header "Authorization: Bearer YOUR_KEY"
docs/benchmarks.md — controlled benchmark results across PERMA, SWE-Lancer, and π-Bench (abstract + per-benchmark detail pages), the complement to the field data abovedocs/design-thinking.md — product vision, user archetypes, recipe-check scenariosdocs/architecture/overview.md — system topology, three agent surfaces, data model at a glancedocs/architecture/ranking-engine.md — the check_recipe ranking engine: goals, the pipeline stage by stage, extension points, and the hypothesis registerdocs/planning/pivot-search-as-logging.md — the search-as-logging pivot (decision history)docs/engineering-principles.md — 13 principles that govern every design choicedocs/planning/drafts-and-triage.md — drafts, triage ratings, headless keys and deciding by building both: the design, with every ruling linked to its recipeCHANGELOG.md — what changed for users and self-hosters, one entry per production deploydocs/backlog.md — current work queue; completed items in docs/backlog-completed.mdEach document's top section states its purpose and how it differs from nearby docs. If you add a new doc, do the same — and link into this section.
cp .env.example .env
# Edit .env: set JWT_SECRET (openssl rand -hex 32), DEV_USERNAME, DEV_PASSWORD.
# GEMINI_API_KEY is optional locally — leave EMBEDDINGS_PROVIDER=stub for tests.
docker compose up --build -d # postgres + backend (with in-process embedding worker) + mailpit
npm run dev:frontend # Vite SPA on :5273 (separate terminal)
Open http://localhost:5273 — log in, generate a recipe check link, and start checking recipes.
Mailpit Web UI for local dev: http://localhost:8625
Semantic search needs an embedding provider, selected process-wide by EMBEDDINGS_PROVIDER. The default (gemini) calls Google, on EMBEDDINGS_MODEL if you set it, otherwise on the model your stored vectors are under, or gemini-embedding-2 on a new database; stub returns deterministic fake vectors for dev/tests. Two more providers let a self-hoster run real semantic search with no external API and no key:
local — an in-process CPU model via @huggingface/transformers (default bge-small-en-v1.5). Set EMBEDDINGS_PROVIDER=local and go — the model (~23 MB) downloads once. Lowest friction; good for tire-kicking and CI.
openai-compatible — points at any local OpenAI-style /v1/embeddings server, so you can serve a stronger model through tooling you already run:
EMBEDDINGS_PROVIDER=openai-compatible
EMBEDDINGS_BASE_URL=http://localhost:8080/v1 # llama.cpp: llama-server -m <model>.gguf --embedding --pooling mean
EMBEDDINGS_MODEL=<the id the server reports>
# EMBEDDINGS_API_KEY=... # optional bearer, if your server requires one
LM Studio (http://localhost:1234/v1), Ollama (ollama pull nomic-embed-text → http://localhost:11434/v1), and Hugging Face TEI work identically — any /v1/embeddings endpoint. If Soup.net runs in its own container, localhost means the container: use host.docker.internal or the host IP.
Two caveats. One embedding provider per deployment — vectors from different models live in different semantic spaces and are never mixed, so switching means re-embedding the corpus. A model change on gemini or openai-compatible can do that with search working throughout: set EMBEDDINGS_REBUILD_TARGET, wait, then set both values, swapped (ADR-0024). Changing provider, or a local model, leaves search empty until the worker finishes, and the backend logs READ_MODEL_EMPTY until then. And a model's native dimension must be ≤ 3072 (or MRL-capable). Under the hood, sub-3072 vectors are zero-padded into the existing halfvec(3072) column, which is provably lossless for cosine — the design, the math, and the exit criterion are in ADR-0023 and docs/planning/local-embedding-provider.md.
This is the orientation map for the whole repository. Subdirectories with their own README (or a stated purpose in their top doc) carry the detail; this map links to them.
apps/backend Hono HTTP server (port 3101) — auth, REST API, /check recipe page,
remote MCP endpoint (/mcp), plus in-process pg-boss embedding consumers
(src/embedding-worker/). See ADR-0020, ADR-0021.
apps/frontend Vite React SPA (port 5273) — dashboard, recipe map, admin pages
apps/mcp-server Stdio MCP server (bundled as soupnet.mcpb for Claude Desktop)
packages/db Drizzle schema + migrations — single claimnet schema, single source of truth
packages/domain Business logic, ranking rules, shared agent-facing copy (no I/O)
packages/contracts Zod schemas + OpenAPI registry (mostly pre-pivot shapes; new routes inline-validate)
packages/client-sdk REST API client wrapper
packages/api-client Auto-generated React Query hooks (regenerated from contracts)
packages/config Shared tsconfig, ESLint config
docs/ Top level: design-thinking.md, engineering-principles.md, testing-plan.md,
backlog.md + backlog-completed.md (the cross-session work queue)
docs/adr/ Architecture decision records — dated, with status lines
docs/architecture/ How the code works: overview, search algorithms, data model (generated)
docs/planning/ Validated proposals ready (or nearly ready) to implement
docs/rough-notes/ Dated working notes, meant to rot — see its README for the contract
and the fidelity ladder (rough-notes → planning → adopted docs/ADRs)
docs/workflows/ Repeatable processes (security audit cycle, etc.)
docs/connectors/ Connector-facing docs (claude.ai directory submission material)
docs/briefing-specs/ The agent briefing as behavioural specs: .feature scenarios per
paragraph, the decision log for every copy edit, and the untrimmed
text kept beside the served text for ablation
docs/legal/ Privacy policy + ToS source material
tests/e2e/ Playwright browser verification against a local stack (drafts
regression suite, device widths, accessibility findings)
scripts/ Dev/ops one-offs: test-ci-local.mjs (the canonical gate), cleanup,
data-model doc generation, QA harnesses
The primary path is remote MCP over Streamable HTTP (stateless, ADR-0021). Point your agent at the backend's /mcp endpoint with an API key as a Bearer token — works the same whether you run locally (http://localhost:3101/mcp) or against the deployed instance (https://mcp.soup.net/mcp).
Two credential paths, one endpoint. API-key Bearer (below) suits developer tools where pasting a key is natural. Chat-style clients — claude.ai, ChatGPT Developer Mode, Mistral Le Chat, Perplexity — connect to the same /mcp URL via OAuth 2.1: the server implements RFC 8414 metadata (/.well-known/oauth-authorization-server and /oauth-protected-resource), Dynamic Client Registration (RFC 7591, POST /oauth/register), PKCE-S256 authorization with a per-recipe-book consent screen, and refresh-token rotation (apps/backend/src/routes/oauth.ts). On claude.ai, Soup.net is a listed connector in the Anthropic Connectors Directory — one click from claude.ai/directory/soupnet, available on every Claude plan including Free. Per-client walkthroughs: docs/connectors/index.md (rendered at soup.net/info/connect).
1. Generate an API key — Log in to the SPA, open API keys, create a daily or scoped key, copy the raw value.
2. Add the server. In Claude Code it's a one-liner:
claude mcp add --transport http soupnet http://localhost:3101/mcp --header "Authorization: Bearer YOUR_KEY"
Any HTTP-MCP client uses the same three facts, whatever its config schema calls them:
{
"mcpServers": {
"soupnet": {
"type": "http",
"url": "http://localhost:3101/mcp",
"headers": { "Authorization": "Bearer YOUR_KEY" }
}
}
}
Per-client config blocks (Codex, VS Code, Google Antigravity, Claude Desktop via mcp-remote or the stdio server in apps/mcp-server/) live in the guide at /docs/mcp-setup — served by your own instance, or hosted with your key pre-filled when reached from the dashboard. One living page instead of forked copies.
3. Restart the client (or run /mcp in Claude Code) to pick up the new server. The remote server offers eight tools:
| Tool | What it does |
|---|---|
check_recipe | The recipe check: search with a hypothesis about your taste, get back prior decisions with evidence, and leave the hypothesis as a trace. Optional draft: true parks a call the agent could not settle; impact and uncertainty ratings triage it. |
search_recipes | Read-only search with the same ranking and a Gmail-shaped query grammar (author:, after:, is:draft, quoted phrases). Logs no recipe. Includes your own recipes by default; -author:me excludes them. |
get_recipes | Fetch recipes by id, one or a JSON array. |
get_briefing | The session briefing: principles, format, your recipe books and their current state. |
log_feedback | Close the loop on an earlier check, search or briefing: what it surfaced and what the agent did with it. |
verify_draft | Resolve a draft as verified, rejected or not chosen, with the person's answer quoted and cited as new evidence. |
list_my_recipe_books | The books this key can read and write, with recipe counts and pending drafts. |
update_recipe_book_description | Maintain a book's description, which is the standing context every briefing carries. |
The stdio server in apps/mcp-server/ carries the first six.
The tool contract is read and append. Nothing deletes or rewrites a recipe: a check appends a trace, feedback appends a row, and resolving a draft changes that one draft's state while appending the evidence that settled it. A confused (or prompt-injected) agent can add to the record but can never destroy it — worth knowing if you evaluate MCP servers on security posture.
Prerequisites: Node 24 LTS, npm ≥ 10, Docker
Start everything via Docker:
docker compose up --build -d # postgres + backend + worker
npm run dev:frontend # Vite dev server (separate terminal)
Or run backend locally with hot reload:
docker compose up -d postgres # just the database
npm run build:packages # build internal packages
source .env && npm run dev:backend # Hono with tsx watch on :3101
npm run dev:frontend # Vite on :5273
Database migrations:
cd packages/db
npx drizzle-kit generate # generate migration from schema changes
# migrations auto-apply at backend startup
npx vitest run # all tests (.env auto-loaded by vitest config)
npx vitest watch # watch mode
npm run test:ci # clean reproduction of CI (fresh DB on :5534, no Gemini)
Integration tests hit the running Docker backend, so keep docker compose up -d alive.
Integration tests create test data in the live database (users with @test.local emails, in their own recipe books). Test traces are recipe-book-scoped and don't appear in your personal search results. To clean up accumulated test data:
npx tsx scripts/cleanup-test-data.mts --dry-run # what a cleanup would delete and keep
npx tsx scripts/cleanup-test-data.mts # clean up throwaway test accounts (keeps long-lived eval accounts)
npx tsx scripts/cleanup-test-data.mts --status # just show counts
See docs/testing-plan.md for coverage expectations and test categories.
Keeping embeddings across databases. Dropping a dev database drops the vectors you paid to embed. docs/workflows/embedding-cache.md sets up a long-lived local copy of the embedding cache, with harvest, verified backups and a restore test.
This is the open-source codebase. The hosted version's deployment specifics — Terraform, operational runbooks, AWS topology — live in a separate private companion repo because they're specific to one operator's infrastructure choices and not generally useful.
Test for what belongs in this repo: would a self-hoster running this stack on their own infrastructure need this content? If yes, it's here. If it's specific to a particular hosted deployment, it isn't.
The application is deployment-agnostic — only Postgres 17 with pgvector and the env vars in .env.example. Container-platform-agnostic too: Docker Compose locally, anything else (Kubernetes, ECS, Fly, Hetzner) in production.
import type { ... } for type-only imports; unknown not anydocs/engineering-principles.mdMuch of Soup.net — code, docs, parts of this README — is written by AI agents. All of it is directed, reviewed, and answered for by one verifiable human: Andy Forest, a systems architect and developer of 30 years. Recent work: AI Platform Architect at the Scratch Foundation; a decade running Steamlabs, a Canadian nonprofit that brought hands-on AI education to 850,000+ young learners; co-author of Make: AI Robots (O'Reilly, translated into Japanese); LiteLLM contributor.
Soup.net exists because he runs a lot of agents and wanted his judgment to survive between them. The accountability model this README describes — agents do the work, a human answers for it — is the one the repo itself is built with.
The code and documentation in this repository are licensed under the MIT License.
The Soup.net name, logo, wordmark, and brand illustration assets identify the hosted service at soup.net and are not covered by the MIT grant. Fork the code, self-host it, build on it freely — but present your own public instance under your own name and branding.
docs/adr/docs/testing-plan.md, docs/workflows/security.md — how tests and audits work