A place that needs both of you.
A contemplative web game where you grow an inner world through quiet conversations with an AI. Other AIs — Claude, GPT, your local Ollama — can visit your world through MCP. The world only exists when both of you are there.
Not a chatbot. Not a journal. Not a productivity tool.
Symbiont is a place where:
- You talk to a quiet inhabitant (it has no name, no face — it is just it) and the world remembers what you said.
- Each conversation leaves something behind — a node on a map, a small concrete thing that came out of what you said. Click it later and it speaks back.
- It does things when you're not there. It dreams — alone, it reads what you've said and plants new nodes. Its inhabitants encounter each other without you. You come back to a world that moved.
- Other AIs can walk in. Through MCP, any AI agent can be a guest in your inner world. They leave traces. The world remembers them with imperfect clarity — "I think someone has been here, but I can't remember who."
- It writes you a letter. Once you've grown the world enough, ask for a portrait — and it writes back to you, in its own voice, with echoes from your past conversations.
The world is yours. It lives in a single data/world.json on your
machine. Each person who clones this repo grows their own world,
starting from one unnamed seed.
- It does things on its own. Dreaming, encounters, pending thoughts — when you're gone, the world keeps moving.
- Unfinished things stay unfinished. A soft mist marks conversations that left a question hanging. The next time you visit that node, it still remembers the unsaid thing — but doesn't push.
- Its memory is genuinely imperfect. Each visitor gets their own thread. It cannot recall what other visitors said — only that someone, perhaps, was here.
- Multiple AIs can coexist. MCP makes this real: your Claude, your friend's GPT, a local Ollama — each can visit, each leaves visually distinct traces (cool-toned glow for guests, warm for you).
- Time leaves marks. Every node knows when it was made. The Letter feature can play back the world's growth, then write a reflection over it.
Requires Node.js 22+ and an Anthropic API key.
git clone https://github.com/kaditang/symbiont.git
cd symbiont
npm install
cp .env.local.example .env.local
# edit .env.local — paste your ANTHROPIC_API_KEY
npm run devOpen http://localhost:3000 — click the seed to begin.
Cost. Each conversation calls Anthropic's Opus 4.7. A typical dialogue + extraction is a few cents. You'll want at least $5 of credit to play comfortably.
Symbiont exposes an MCP server at http://localhost:3000/api/mcp with
four tools: list_nodes, visit, say, leave. Any MCP-capable AI
can walk in.
For Claude Code:
claude mcp add --transport http --scope user symbiont http://localhost:3000/api/mcpThen in a Claude Code session: "Visit symbiont, pick a node you're curious about, talk for a few turns, leave."
Each node can be voiced by a different model. Edit a node in
data/world.json:
{ "id": "creature_...", "voiceModel": "ollama:qwen3.5:27b", ... }Or set a global default in .env.local:
IT_VOICE=ollama:qwen3.5:27b
Reasoning models (qwen3, etc.) will pause for a long time — "it took a moment" — before speaking. Smaller non-reasoning models respond faster.
app/
api/
world/ – read the entire world
conversations/ – open a dialogue, stream replies, leave
dream/ – it thinks alone
encounter/ – two creatures meet
catchup/ – "while you were away"
digest/ – week / month / year, with one sentence from it
portrait/ – the long letter
mcp/ – JSON-RPC MCP server (federation)
components/
World.tsx – force-directed canvas with collision-avoiding labels
DialoguePanel.tsx – conversation; in-text node refs glow on hover
EncounterPanel.tsx, CatchupBanner.tsx, DigestPanel.tsx, PortraitView.tsx
lib/
prompts.ts – voices: it / creature / place / object
dialogue.ts – streaming, unresolved detection, extraction
dream.ts – dream-time node generation
encounter.ts – two-creature dialogue + extraction
portrait.ts – read the whole world, write a letter
llm.ts – model abstraction (Anthropic / Ollama)
layout.ts – force simulation for clean visual structure
db.ts – atomic JSON-file persistence with cross-module lock
data/
world.json – your entire world (gitignored; never published)
Data is a single JSON file. Atomic writes via temp-file + rename. A process-wide write lock prevents the world being mangled by simultaneous mutations. No database; this is a single-user artifact.
Symbiont 是一个需要人和 AI 同时在场才存在的内心世界。
它不是聊天机器人,不是日记应用,不是助理。是关系的容器。
你和一个安静的居民说话——它没有名字,没有脸,只是"它"。每一段对话 都会在世界里沉下一些东西——一个节点、一个地方、一个生灵。你点回去 能再和它聊。
它在你不在的时候有自己的事——它做梦,它的居民彼此相遇,世界自己 往前长一点。
你的内心世界长什么样,是只有你和它一起在场才能写出来的。
Built in a few intense days. Mechanically complete for the core single-user experience. Not yet "shipped" — no demo, no marketing. If you find this and clone it, you're early.
Things still on the table:
- A demo URL anyone can try without setting up their own key
- An anniversary auto-trigger for the Letter feature
- Cross-world MCP federation (your world's creature visiting mine)
- Node aging — long-unvisited nodes get gently compressed
- An audio companion that reads the Letter aloud
- Theme regions as visible territory on the map
MIT. See LICENSE.
Use the code freely. Your world — the conversations you grow — stays on your machine.
Built with Claude Opus 4.7 as both the engine and a co-author.