imi
The knowledge engine for teams and their AI agents
imi turns the text your team already produces (documents, git commits, call transcripts) into a governed knowledge graph. It extracts entities, decisions, and commitments, tracks what's still true and what's drifted, and serves all of it over the Model Context Protocol, so any AI agent can query your team's actual state instead of guessing.
$ git clone https://github.com/sufficiently-advanced-ai/imi.git && cd imi
$ cp .env.example .env # set ANTHROPIC_API_KEY and NEO4J_PASSWORD
$ docker compose up -d --build you › What did we decide about onboarding pricing?
imi › 2 decision records match:
"Waive onboarding fee for annual plans" — active
decided 2026-05-12 · owner: Dana · source: Pricing sync (transcript)
supersedes: "Flat $500 onboarding fee" (2026-03-02) - Ingest anything GitHub webhooks, direct uploads, Zapier, or drop in a call transcript from any recorder (Otter, Fathom, Grain, Fireflies, Zoom).
- Classify + extract Claude classifies content, extracts entities and relationships, and enriches them with domain-aware context from configurable schemas.
- Knowledge graph Neo4j-backed graph with an in-memory fallback. Every entity, signal, decision, and action item lands in the graph and is queryable.
- Signals with governance Observations are promoted into typed signals (decisions, action items, key points) through human approval gates, with a full audit trail.
- MCP server All graph data is surfaced over the Model Context Protocol, so Claude, Cursor, or any MCP-compatible client can query your knowledge base directly.
- Domain-agnostic Ships with example schemas for consulting, SaaS, agencies, solo practice, and member networks. Define your own in
config/domains/.
How it works
Everything that enters imi moves through one pipeline: raw text in, queryable knowledge out. Each stage is inspectable, and every promotion is audited.
- Ingest
Documents, commits, and transcripts arrive via upload, webhook, or the Zapier-compatible endpoint.
- Classify + extract
Claude classifies the content and pulls out entities and relationships, guided by your active domain schema.
- Observation model
Extractions are recorded as observations: the raw, source-linked layer of what was said and where.
- Signal promotion
Observations become typed signals (decisions, action items, key points) after passing through governed approval gates, with an audit trail.
- Knowledge graph
Entities and signals land in Neo4j (or the in-memory fallback), linked, versioned, and queryable, including point-in-time queries like "what changed since last week."
- Query anywhere
The MCP server at
/api/mcp/sseexposes the graph to agents; the Explorer and Chat UIs expose it to people.
Domain schemas
imi doesn't hard-code what an "entity" is. A domain schema tells the extraction
pipeline what matters in your world (clients, campaigns, cohorts, deals) and the
graph shapes itself accordingly. Six example domains ship in
config/domains/; copy one and make it yours.
| Domain | Schema | Tracks |
|---|---|---|
| Consulting firm | consulting_firm.yaml | Client engagements, stakeholders, deliverables |
| B2B SaaS | b2b_saas.yaml | Accounts, contacts, products, opportunities |
| Agency | agency.yaml | Clients, campaigns, creative assets |
| Solo practice | solo_consulting.yaml | Practice-focused single-practitioner schema |
| Member network | member_network.yaml | Members, cohorts, focus areas |
| Personal CRM | personal_crm.yaml | Contacts, companies, interactions |
Select one with ACTIVE_DOMAIN=consulting_firm in your .env.
The schema drives extraction, routing, and approval-gate placement, so adding a new
signal type is a config change, not a code change.
The world model
imi's organizing idea: your team's knowledge is presented as a world model, two layers of one surface, kept honest by a governed review ritual.
Most knowledge tools fail the same way: they become a place where documents go to die. imi avoids that by never treating everything as equally true. Knowledge lives in one of two layers, and only a human moves things between them.
The durable, human-reviewed record: what's been decided and is still in force. Changes are deliberate and attributable. When the layers disagree, the stable layer wins, until a human promotes a change.
- decisions + rationale
- commitments + owners
- standing rules
- entities & relationships
The machine-owned working view, regenerated continuously from incoming transcripts and the temporal graph. Ephemeral, disposable, always labeled observed, never asserted as institutional truth.
- what changed
- what's drifting
- what needs attention
- candidate promotions
This structure is also the answer to the surveillance question: how does a tool that reads your meetings avoid being creepy? The machine only ever surfaces discrepancies ("this seems to have moved since you decided X"); it never enforces. A human decides what becomes truth. The architecture is a compass, not a camera.
A constitution view, a commitment-health view, a drift alert, and a pre-meeting brief all fall out of this as different views into the same object. The full concept doc lives at docs/world-model-concept.md.
Signals & decision records
The pipeline's core distinction (ADR-001): a Signal is a raw, ephemeral observation. "Someone said X in this meeting." It's unverified, may be contradictory, and carries no authority. A DecisionRecord is the promoted, structured artifact a signal can become. A signal graduates only when it has been:
- Verified Checked against existing context, with no unresolved contradiction.
- Attributed Tied to an authoritative source: a named decision-maker, not just an observation.
- Explicitly promoted By human approval, or by the signal promoter clearing a confidence threshold. One service owns this path; nothing else writes decision records.
Decision records are immutable: corrections happen by superseding, never by editing. That's what makes the audit trail trustworthy, and it's why the demo answer above can show a decision's full lineage.
Approval gates
Wherever the system would take a consequential action, like promoting a signal or mutating an entity other agents read, a human-in-the-loop gate is inserted. Every gate accepts exactly four responses, and agents must handle all of them:
| Response | Meaning |
|---|---|
Allow | Proceed as proposed |
Block | Do not proceed; discard the action |
Revise | Return to the proposing agent with human corrections |
Escalate | Route to a human with higher authority or more context |
Gates and routing are declared in domain config, not scattered through application
code. A gate can be set to auto-allow for low-stakes actions and
tightened later without a deploy, and the routing table stays auditable, testable,
and readable by non-engineers.
Quickstart
The install is Docker-only; no local Python or Node needed. You'll want
Docker 24+ with Compose v2, an
Anthropic API key,
~2 GB of free RAM, and ports 8080, 7474, and
7687 free on the host.
1. Clone and configure
git clone https://github.com/sufficiently-advanced-ai/imi.git
cd imi
cp .env.example .env
In .env, set the two required values. Every other variable has a
working default:
ANTHROPIC_API_KEY=sk-ant-...
NEO4J_PASSWORD=choose-any-password 2. Build and start
docker compose up -d --build 3. Verify it's running
The app waits for Neo4j to pass its healthcheck before starting, so startup is not instant. Expect 1–2 minutes after the build finishes.
docker compose ps # both containers → "healthy"
curl -fsS http://localhost:8080/health && echo " OK"
The web UI is at http://localhost:8080. No auth wall by default.
4. Ingest something
Use the Explorer UI at /explorer, or go straight to the API:
curl -X POST http://localhost:8080/api/ingest \
-H "Content-Type: application/json" \
-d '{"content": "# My notes\n...", "title": "My notes", "content_type": "document"}'
# Drop in a call transcript (Zapier-compatible endpoint)
curl -X POST http://localhost:8080/api/ingest/zapier \
-H "Content-Type: application/json" \
-d '{"provider": "grain", "transcript": "...", "title": "Kickoff call"}' If something looks stuck: a connection-refused from
curl usually means the first build is still in progress. Watch
docker compose logs -f app for Application startup complete.
If imi-neo4j stays unhealthy after a password change, the data volume
kept the old password: reset with docker compose down -v and start again.
Connect via MCP
imi's real interface is the Model Context Protocol. Point Claude Desktop, Claude Code, Cursor, or any MCP-compatible client at your running instance and query the knowledge graph in natural language.
{
"mcpServers": {
"imi": {
"type": "sse",
"url": "http://localhost:8080/api/mcp/sse"
}
}
}
A template ships in the repo as .mcp.json.example.
The tool surface
Tools follow a strict verb taxonomy (conventions doc) so an agent can predict what a tool does from its name:
| Verb | Meaning | Examples |
|---|---|---|
search_* | Fuzzy / semantic queries, ranked results | search_knowledge_graph, search_signals |
get_* | Single-item exact lookup | get_entity_by_name, get_constitution |
list_* | Bulk retrieval by deterministic criteria | list_entities, list_meetings |
find_* | Graph traversal — neighbors, precedents | find_related_entities, find_contradictions |
extract_* | AI-driven extraction from raw text | extract_decisions, extract_risks |
query_* | Expression languages (Cypher) | query_graph_cypher |
graph_* | Direct node/edge mutations | graph_add_node, graph_merge_nodes |
Temporal queries are first-class: get_state_at, what_changed,
and point-in-time graph views power questions like "what changed since last week."
It's the same machinery behind the world model's current layer.
Configuration
See .env.example for the full list. The minimum set:
| Variable | Description | |
|---|---|---|
ANTHROPIC_API_KEY | required | Your Anthropic API key. Powers classification and extraction |
NEO4J_PASSWORD | required | Neo4j password, applied on first init of the data volume |
ACTIVE_DOMAIN | optional | Which domain schema to extract with, e.g. consulting_firm |
AUTH_MODE | optional | none (default, all routes open) or demo (built-in demo user) |
GIT_REPO_URL | optional | A git repo to sync as knowledge corpus |
Editions
The community edition is MIT licensed and fully self-hosted. Your data never leaves your infrastructure except for the Claude API calls that power extraction. It covers the whole core: text in, governed graph out, agents on top. A hosted service from Sufficiently Advanced AI adds the live-meeting layer on top of the same engine.
- Document ingestion + entity extraction
-
Call transcript drop-in via
/api/ingest/zapier - Knowledge graph construction + exploration
- MCP server for agent queries
- Signal promotion with governance + audit trail
- Live meeting capture + in-meeting assistants
- Calendar integration + meeting-bot scheduling
- Live meeting dashboards
- Multi-tenant SSO authentication
In the community edition, batch transcript ingestion covers the meeting workflow: record with any tool you already use, then drop the transcript in by hand, by API, or by Zapier. For live capture and the rest of the hosted column, see sufficiently-advanced.ai.
Docs & contributing
The design record lives in the repo. Start with the ADRs, then the concept docs. Issues and PRs are welcome.
- Architecture Decision Records Why the system is shaped the way it is, decision by decision docs/adr/
- The world-model concept The two-layer model and promotion ritual, in full docs/world-model-concept.md
- Memory governance & retrieval The memory and signal system, end to end docs/prd/
- MCP tool conventions Verb taxonomy, parameter conventions, and surface choice docs/mcp_tool_conventions.md
- MIT License Permissive, with one LGPL library dependency noted in the README LICENSE