English | 简体中文
You hold the helm; it reads the stars — you share the same chart.
This is MindMap X: a self-hosted mind map — you edit it in the browser, agents edit the same map through one API, and changes are visible to both sides in real time.
Powered by NexusX
Focus drill-down (breadcrumb navigation)
"AI generates a mind map in one click" tools are everywhere — but the AI walks away after generating. This project answers a different question: what if the mind map were a shared workspace for humans and agents?
- Two-way sync — what you edit, the agent sees on its next turn; what the agent edits is highlighted on your canvas right away. Both sides are always looking at the same map, never drifting apart
- Bring any agent — the service itself is an MCP server: Claude Code, Cursor, or any MCP client connects with one command, and the built-in chat uses the same interface
cp .env.example .env # optional: model config for the in-page agent; skip to use canvas-only
docker compose up -d # → http://localhost:8740- All state (SQLite / chat archives / agent sessions) lives in the
mindmap-varnamed volume:downkeeps it,down -vwipes it; - The image builds the frontend and runs DB migrations on startup — pull a newer image, restart, and the schema upgrades itself;
- If pulling base images times out (e.g. on restricted networks), build via a mirror:
NODE_IMAGE=docker.m.daocloud.io/library/node:22-alpine \
BASE_IMAGE=ghcr.m.daocloud.io/astral-sh/uv:python3.12-bookworm-slim \
docker compose buildRequirements: Python ≥ 3.12, Node ^20.19 || ≥22.12 (to build the frontend).
./scripts/start.sh # deps → DB migration → frontend build (if missing) → start
./scripts/start.sh --seed # optional on first run: load sample mapsPORT=9000 ./scripts/start.sh changes the port; Ctrl+C stops the server and cleans up the port. Frontend dev mode (hot reload):
cd fe && npm run dev # port 5173, proxies /api /ws /mcp /voyager to 8740Grab the latest MindMapX-macOS-arm64.dmg from Releases, open it, drag MindMapX into Applications, and strip the quarantine flag (the build is unsigned):
xattr -cr /Applications/MindMapX.app # or right-click → Open the first time- Data lives in
~/Library/Application Support/MindMapX/—mindmap.db, chat sessions/archives, anddesktop.log(the only log channel for the GUI build) - Model config: click the gray chat button and fill in the gateway right in the app (saved to
provider.jsonin the data directory, no restart needed);.envin that data directory works as a fallback (same variables as server mode) - Agent access: the app serves MCP on a local port — read it from the window title (
MindMap X — MCP :8740) and connect withclaude mcp add --transport http mindmap http://127.0.0.1:8740/mcp. Port 8740 is preferred; if taken, a random free port is used - Known limits: macOS arm64 only; unsigned (hence the
xattrstep)
Grab MindMapX-Windows-x64.zip from Releases, unzip anywhere, and run MindMapX\MindMapX.exe. The build is unsigned — SmartScreen will warn on first launch, click More info → Run anyway.
- Win 11 only (WebView2 ships with the OS); no installer, no registry writes
- Slow first-time unzip? That's Defender scanning ~3000 files one by one — use 7-Zip, or add the folder to Defender exclusions. No manual
Unblock-Fileneeded: the app clears the download mark (MOTW) itself at startup - Data lives in
%APPDATA%\MindMapX\— same layout as macOS (mindmap.db, sessions,desktop.log) - Everything else (model config, MCP port in the window title) matches the macOS notes above
# MCP (Claude Code; Cursor and other MCP clients work the same way)
claude mcp add --transport http mindmap http://localhost:8740/mcp
# CLI
uv run python -m src.cli mindmap-service get_tree --map-id 1
uv run python -m src.cli mindmap-service apply_outline --map-id 1 \
--outline "- [id:1] Root
- [id:2] Branch
- New node" --mode merge
# REST
curl -X POST localhost:8740/api/mindmap_service/get_tree \
-H 'Content-Type: application/json' -d '{"map_id": 1}'The in-page agent gets automatic change awareness: writes from every other party — your canvas edits and external agents working via MCP/CLI/REST — are injected into its context as <external_changes> before its next reply, grouped by origin ("the user edited on the canvas" / "an external agent made changes"), so everyone stays on the same map.
The in-page agent's own writes never appear in that list — it already knows them from its tool results, and echoing them back would be noise. It is recognized by an X-Mindmap-Source: page-agent header it sends on its loopback MCP calls, which the server maps to a dedicated actor and exempts from the feed.
External agents (MCP / CLI / REST) have no such channel — MCP is request/response; the server cannot push changes into the model's context. When humans and an external agent edit in parallel, the external agent should re-pull the full tree (get_tree) before every write and confirm the structure before acting, to avoid overwriting your edits from a stale view.
The browser chat panel is backed by an embedded strands agents agent: it operates the map through the app's own MCP (loopback streamable-http, the same interface external Claude Code uses). The model gateway is configured in the UI — click the gray chat button (or the gear icon in the chat panel), pick a provider preset (OpenAI / Anthropic / DeepSeek / GLM / Kimi / Ollama) or custom, fill in base URL / API key / model, and save: the server probes the gateway with those exact credentials before persisting them (a bad URL or key is rejected with the reason). Config lives in var/provider.json (gitignored) and takes effect on the very next message — no restart.
Environment variables still work as a deployment-level fallback (OPENAI_BASE_URL / OPENAI_API_KEY / AGENT_MODEL, plus AGENT_PROVIDER=anthropic for Anthropic-style APIs; see .env.example); UI config always wins over env, and clearing it in the dialog falls back to env.
When no model gateway is configured anywhere, the agent chat button stays visible but grayed out: clicking it opens the config dialog directly; a gateway failure mid-session shows an explicit banner inside the panel (with a shortcut to reopen the config).
While the agent is running, the send button turns into a stop button: one click and the agent halts gracefully at the next safe checkpoint (typically sub-second) — completed edits are kept, half-streamed output is discarded, and the session history stays consistent for the next turn. Timeouts and dropped connections cut the running agent at a checkpoint too — no orphan thread keeps editing your map in the background.
- Single-user by design; no multi-user real-time collaboration
- SQLite single-process storage (
var/mindmap.db) - No XMind / OPML import-export — the outline text protocol is the only exchange format today
- Import/export: XMind / OPML / FreeMind
- One-command Docker deployment (
docker compose up -d) - Multi-user collaboration (tree-level OT / CRDT)
Business Source License 1.1 — source-available: free for learning, modification, and internal business use; offering it to third parties as a product, service, or hosted offering requires a commercial license (allmonday@126.com). Each release automatically converts to Apache-2.0 four years after publication.
Versions published before 2026-08-30 were released under MIT and remain MIT-licensed.