aion
aionai is a shared working-state MCP server that lets multiple AI coding tools (Claude, Cursor, etc.) read and write a common persistent notebook to stay in sync.
Core Context Management
context_pull— Fetch the current working state for a project segment (open tasks, questions, recent decisions, inbox handoffs); call this before starting any workcontext_log— Append entries (decisions, changes, questions, tasks, or notes) to the shared statecontext_resolve— Mark an open question or task as resolved so it no longer surfaces incontext_pullcontext_search— Full-text search across a project's history to recover past contextcontext_verify— Checkchangeentries against git, classifying them as merged, unmerged, missing, or bare claimscontext_handoff— Post a message to another tool's inbox (Cursor, Claude Code, etc.), with optional doorbell delivery for supported clients
Roadmap & Progress Tracking
roadmap_add_node— Add hierarchical nodes (project, segment, phase, epic, task) to a roadmap treeroadmap_update— Update a node's priority, parent, or statusroadmap_block— Record dependency edges (blocked-by relationships) between nodesroadmap_view— View the full hierarchical roadmap with done/total rollup per noderoadmap_progress— Get a progress summary (done vs. total, with percentages) per segment and overall
Planning & Cross-Project Reuse
constraints_for_task— Retrieve all decisions and open questions that may constrain a specific task before implementing itproject_lookup— Search another project's history to reuse approaches and decisions
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@aion pull context for myproject"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
aionai
A shared working-state layer for your AI coding tools. Claude, Cursor, and other MCP clients read and write one small notebook, so they stay on the same page — and you stop being the copy-paste bus between them.
One-click install for Cursor (it configures
uvx aionai). After it's added, setAIONAI_SOURCE=cursorin the server's env. If Cursor can't finduvx, see Troubleshooting; or set it up manually via Connect your tools.
The problem
You use more than one AI assistant on a project. They don't know what each other did: you tell Claude a decision, switch to Cursor, and Cursor has no idea. You end up re-explaining and copy-pasting context by hand.
Related MCP server: memmd-mcp
What aionai does
aionai is a tiny local MCP server that keeps a shared, persistent notebook every tool can read and write. It does three jobs:
Remember — decisions, changes, questions, and notes, organized by project.
Track — a lightweight roadmap/to-do list with progress rollup.
Hand off — post a task to another tool's inbox (with an optional "doorbell").
It does not replace your repo, docs, or git — those stay the source of truth. aionai just holds the live working state and hands each tool the slice it needs.
Install
Most portable — works on Windows, macOS, and Linux, and puts the aionai command
where GUI apps (Cursor, Claude Desktop) can find it:
pipx install aionaiAlready use uv? Skip the install entirely:
uvx aionai --helpRequires Python 3.10+. If a client later reports the launcher (aionai / uvx)
"not recognized", see Troubleshooting.
Connect your tools
Point each client at the aionai command. Give each client a distinct AIONAI_SOURCE
(so handoffs route correctly) and set AIONAI_SEGMENT to your project name.
Claude Code
claude mcp add aionai --env AIONAI_SOURCE=claude-code --env AIONAI_SEGMENT=myproject -- aionai
# or with uv: claude mcp add aionai --env AIONAI_SOURCE=claude-code -- uvx aionaiCursor — .cursor/mcp.json:
{
"mcpServers": {
"aionai": { "command": "aionai", "env": { "AIONAI_SOURCE": "cursor", "AIONAI_SEGMENT": "myproject" } }
}
}Claude Desktop — Settings → Developer → Edit Config:
{
"mcpServers": {
"aionai": { "command": "aionai", "env": { "AIONAI_SOURCE": "claude-desktop", "AIONAI_SEGMENT": "myproject" } }
}
}Restart the client after editing its config — MCP servers are launched (and their env read) when the client connects.
Use it
Add this to each tool's rules (CLAUDE.md, Cursor rules) so they do it reflexively:
Before working, call
context_pull(segment="myproject")and treat the result as the current truth. As you work,context_log(...)your decisions/changes/questions/tasks. When something is settled,context_resolve(id).
That's the whole loop: pull first, write back. Now open Cursor and it already knows what you and Claude decided — no paste.
Segments
State is organized by a dotted segment path whose first element is the project:
myproject # the whole project
myproject/backend # a layer
myproject/backend/auth # a workstreamPulling a parent includes all descendants. That one mechanism keeps an always-on space from turning into an undifferentiated blob.
The tools
tool | purpose |
| current working state + your inbox |
| append a decision/change/question/task/note |
| close a question or task |
| full-text recall over history |
| check |
| post a handoff to another tool's inbox |
| build & manage the roadmap |
| see the tree / how far along |
| decisions + open questions that constrain a task |
| reuse an approach from another project |
They also surface as slash commands (/mcp__aionai__pull, …log, …resolve, …search,
…handoff) in clients that support MCP prompts.
Optional extras
Auto-ingest commits — copy
hooks/post-commitinto a repo's.git/hooks/(setAIONAI_SEGMENT) and every commit logs itself as achange.Doorbell — set
AIONAI_DELIVERY=1in a sender's env and acontext_handoffto Cursor also summons Cursor via its deeplink (you confirm before it runs). Without it, handoffs are inbox-only. Onlycursorhas a verified deeplink today.
How it works
One SQLite database, one append-only table. Every decision, task, handoff, and
roadmap node is a row tagged with a segment and a type. History is free because
nothing is overwritten. Full-text search uses FTS5 with a LIKE fallback. The MCP
tools are thin wrappers over a plain-Python storage layer (src/aionai/store.py).
Troubleshooting
A client reports 'uvx' / 'aionai' is not recognized (or the server errors on start).
The client can't find the launcher on its PATH — common for GUI apps (Cursor, Claude
Desktop) on Windows and macOS, which don't always inherit your shell's PATH. Fixes,
best first:
Use pipx:
pipx install aionai, then set"command": "aionai". pipx puts the command where GUI apps usually find it.Point at the full path of the launcher. Find it with
where uvx(Windows) orwhich uvx(macOS/Linux), then use it verbatim, e.g.:"aionai": { "command": "C:/Users/you/AppData/Roaming/Python/Python3xx/Scripts/uvx.exe", "args": ["aionai"], "env": { "AIONAI_SOURCE": "cursor" } }Skip the launcher — run via your Python directly (after
pip install aionai):"aionai": { "command": "python", "args": ["-m", "aionai.cli"] }
Then restart the client so it re-reads the config.
Configuration
var | default | purpose |
|
| database path (share explicitly if clients don't hit the default) |
|
| who is writing ( |
|
| default project segment |
| (unset) |
|
Development
git clone https://github.com/imsm/aionai && cd aionai
pip install -e ".[dev]"
pytest
ruff check .License
Apache-2.0 © Ismail Saleh.
Available Tools
13 toolsconstraints_for_taskA
Before implementing a task, get every decision and open question that may CONSTRAIN it — from the task's segment, its ancestors, and its descendants (not recency-limited). Surface any conflict with your plan BEFORE coding.
Inputs: segment (required). Returns: result
context_handoffA
Post a handoff to another tool's inbox (to = cursor | claude-code | claude-desktop). It lands in the target's inbox and stays PENDING until the receiver resolves it. If AION_DELIVERY is enabled and the target has a verified deeplink (today: cursor), a doorbell also summons that tool with a fixed nudge — the URL never carries your content. Returns the entry id and delivery outcome.
Inputs: to (required), content (required), segment (required), refs, +1 more. Returns: result
context_logA
Append an entry to the shared working state so other tools see it:
type = decision | change | question | task | note. refs is optional JSON
(e.g. {"files": ["..."], "commit": "abc123"}). Returns the new entry id.
Store WHAT/WHY (facts, decisions, intent), not HOW (procedure). A change is
"done" only when merged in git — include refs.commit/refs.pr; without a ref it
is recorded as a CLAIM (verify with context_verify).
Inputs: type (required), content (required), segment (required), refs. Returns: result
context_pullA
Pull the current shared working state for a project segment (and its sub-segments). Call this FIRST, before doing anything on the project: it returns the open tasks, open questions, recent decisions/changes/notes, and your inbox of handoffs. Treat it as the current truth about where the work stands.
segment is a dotted path, e.g. "myproject" or "myproject/backend/auth"; a
parent pulls all descendants. Treat status entries ("fixed"/"done") as CLAIMS to
verify against git (see context_verify), not facts.
Inputs: segment. Returns: result
context_resolveC
Mark an open question or task resolved so it stops surfacing in context_pull.
Inputs: entry_id (required). Returns: result
context_searchA
Full-text search the project's history (decisions/changes/questions/notes) to recover past context. FTS5 does not stem — add a prefix wildcard (auth*) if a bare term seems too narrow.
Inputs: query (required), segment. Returns: result
context_verifyA
Completion integrity: list 'change' entries and classify each against GIT (the ground truth) — 'merged', 'present-unmerged', 'missing', or a bare 'CLAIM (no git ref)'. A tool logging "fixed" is NOT done; done = merged in git. Checks commits in the repo the server runs in.
Inputs: segment. Returns: result
project_lookupA
Reuse an approach from ANOTHER project: search that project's history for a topic and adapt the matching decisions/notes instead of starting from scratch. FTS5 does not stem — add a prefix wildcard (auth*) if a bare term is too narrow.
Inputs: query (required), project (required). Returns: result
roadmap_add_nodeA
Add a node to the roadmap tree. kind = project | segment | phase | epic | task. parent_id nests under another node (0 = top-level); a child inherits its parent's segment unless set. priority is 1..5 (1 = highest; 0 = none). Returns the id.
Inputs: kind (required), title (required), segment, priority, +1 more. Returns: result
roadmap_blockA
Record a DEPENDENCY edge: node blocked_id is blocked by blocked_by_id. Use
this for real dependencies instead of overloading parent_id (parent_id =
decomposition). Surfaced in roadmap_view as a node's blocked_by.
Inputs: blocked_id (required), blocked_by_id (required). Returns: result
roadmap_progressA
Progress summary: per top-level segment and overall, how many leaf work nodes are done vs total, with percentages.
Inputs: no named parameters. Returns: result
roadmap_updateA
Update a roadmap node: set priority (1..5), reparent (parent_id), or set status ('open'/'resolved'). Pass only what you want to change (0/empty = leave as is). Resolving a task/epic is what makes progress roll up.
Inputs: entry_id (required), status, priority, parent_id. Returns: result
roadmap_viewA
Show the hierarchical roadmap (project > segment > phase > epic > task) with done/total rollup per node, sorted by priority. Optionally scope to a segment.
Inputs: segment. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 13 tools
Tools are grouped into context management and roadmap management, each with distinct purposes. Minor overlap between context_search and project_lookup (both search but in different scopes) prevents a perfect score.
All 13 tools follow a consistent verb_noun snake_case pattern (e.g., constraints_for_task, context_log, roadmap_view), making tool purposes predictable.
With 13 tools covering two sub-domains (context and roadmap), the count is well-scoped. Each tool has a clear role without unnecessary redundancy.
The surface covers core CRUD operations for roadmap (add, update, view, block, progress) but lacks explicit delete for nodes. Context tools are comprehensive, including search, verify, and cross-project lookup. Minor gap in deletion.
Maintenance
Related MCP Connectors
One memory for all your AI tools: Claude, ChatGPT, Cursor and any MCP client share the same notes.
Hosted memory for your AI coding agents. Projects, decisions, to-dos and lessons that carry across Claude, Cursor and ChatGPT. Nothing to install: sign in at flowstatemcp.com and connect. Encrypted at rest, backed up, export or erase any time. Beta: 6 months free, then half price.
Shared work memory for Claude Code, Codex, Cursor and chat, scoped to each repository.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Related MCP Servers
- FlicenseBqualityNot gradedmaintenanceA state persistence layer that enables seamless handoffs between different AI coding assistants by maintaining a shared context bus. It provides tools for tracking summaries, next steps, and active files to ensure continuity across development sessions.3-
- AlicenseBqualityDmaintenanceA shared memory layer for AI agents — one memory.md synced across Claude Desktop, Cursor, Claude Code, OpenAI Codex, and any MCP client.42MIT
- AlicenseNot gradedqualityDmaintenanceA local-first MCP server and continuity control plane that helps AI coding tools maintain project state, tasks, and context across sessions, models, and interruptions, with features like session tracking, token-efficient context assembly, and code understanding via Code Atlas.MIT
- FlicenseNot gradedqualityDmaintenanceShared memory and orchestration for coding agents, enabling persistent knowledge, multi-agent coordination, and a canonical workflow across MCP-compatible AI clients.53 npm83-