Cairn

Created By
jasondostal4 months ago
Persistent memory for agents and humans. Semantic, episodic and frictionless via an automated three tier capture.
Overview

Cairn — persistent memory for agents and humans

Release License MCP PostgreSQL


Yet another MCP, right? Yeah, it's that. But here's why this one exists.

I'm a t-shaped engineer. PMP, SAFe Agilist, Certified Product Owner. But before any of that, I'm a systems person. Data centers, orchestration, automation. The kind of work that crosses 13 disciplines and stretches back to something you last touched 10 years ago.

I built Cairn for my workflow. At 1am, when I'm deep in something and I know the answer exists somewhere in the last three weeks of work but I don't want to spend 30 minutes digging and correlating. That emergency call, the panicked user coming to you as their only hope, and it's an issue buried in 6 systems you last touched in 2014.

Cairn is there.

"Where did I put that singularity again? Let me just spawn a couple..."

Sure, dedicated tools will probably beat a given Cairn feature when it's all they do. Cairn isn't built for single-purpose depth — but it still scores 81.6% on LoCoMo. It's built for the systems person. The curious. The t-shaped. The ones who need a memory that works the way they do, across everything, all at once.

It's a self-hosted memory and orchestration layer for AI agents and humans. Store something once, find it later, across sessions, across projects. Four containers. docker compose up. Done.

Cairn chat creating work items with agent dispatch
Chat creates a work item. Agent breaks it into subtasks. You review from your phone.

Quick Start

1. Pull and run

curl -O https://raw.githubusercontent.com/jasondostal/cairn-mcp/main/docker-compose.yml
docker compose up -d

Four containers start:

  • cairn on port 8000 (MCP server + REST API)
  • cairn-ui on port 3000 (web dashboard)
  • cairn-db (PostgreSQL 16 + pgvector)
  • cairn-graph (Neo4j 5, knowledge graph)

Migrations run on first boot. Ready in about a minute.

2. Connect your IDE

Add this to your MCP config:

{
  "mcpServers": {
    "cairn": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}

Where that goes:

IDEConfig file
Claude Code.mcp.json in your project root
Cursor.cursor/mcp.json
Windsurf.windsurf/mcp.json
ClineMCP settings panel in VS Code
Continue.continue/config.yaml

Or run the setup script:

git clone https://github.com/jasondostal/cairn-mcp.git && ./cairn-mcp/scripts/setup.sh

3. Use it

Tell your agent to remember something:

"Remember that we chose PostgreSQL for storage because it handles hybrid search without a separate vector DB."

Search for it later:

"What did we decide about the storage layer?"

That's it. 20 tools available. The ones you'll use most:

ToolWhat it does
storeSave a memory with auto-enrichment
searchFind memories (vector + keyword + recency + tags)
recallGet full content for specific memory IDs
orientBoot a session with rules, recent activity, and open work
rulesLoad behavioral guardrails (global or per-project)
work_itemsCreate, claim, and complete tasks with dependencies and gates
projectsManage project docs (briefs, PRDs, plans)
code_indexParse a codebase with tree-sitter, build a code graph in Neo4j
code_queryStructural queries: dependents, impact, hotspots, cross-project search
code_describeGenerate NL descriptions of code symbols for semantic search
arch_checkValidate architecture boundary rules against imports

The rest: modify, insights, tasks, think, status, consolidate, drift_check, ingest, dispatch.

What's in the box

Memory that persists across sessions. Your agent makes a decision at 2am. Next morning, different session, it finds that decision. That's the core.

Search that fuses signals. Vector similarity, recency, keyword matching, and tag overlap blended via Reciprocal Rank Fusion. Filter by project, type, or time range.

Knowledge graph. With Neo4j enabled, entities and facts get extracted into a graph that connects memories through shared people, places, projects, and concepts. Optional, but powerful when you're working across domains.

Work management. Hierarchical work items, dependency tracking, a dispatch queue for agents, and gates that pause for human decisions. For when you have agents that need to coordinate.

Web dashboard. Browse memories, explore the knowledge graph, view analytics, manage work items, chat with your memory. Port 3000.

Cairn dashboard with memory growth and token usage
Memory growth by type, token usage tracking, and the full nav.

Code intelligence. Index any codebase with tree-sitter (Python, TypeScript/TSX). Ask structural questions — "what depends on this file?", "what's the blast radius?" — and get answers from the code graph. Enforce architecture boundaries with YAML rules. Search code by natural language description. Works across projects.

Session capture. IDE hooks (Claude Code, Cursor, Cline, Windsurf) log every tool call. Next session boots warm. See examples/hooks/README.md.

Do I need an LLM?

No. Store, search, recall, and rules work without one. You lose auto-enrichment (summaries, tags, importance scoring), knowledge extraction, and chat.

If you want enrichment:

BackendSetup
Ollama (default)Install Ollama, pull a model. Cairn connects to host.docker.internal:11434.
AWS BedrockSet CAIRN_LLM_BACKEND=bedrock, export AWS creds.
Google GeminiSet CAIRN_LLM_BACKEND=gemini, add CAIRN_GEMINI_API_KEY. Free tier available.
OpenAI-compatibleSet CAIRN_LLM_BACKEND=openai, add key. Works with OpenAI, Groq, Together, LM Studio, vLLM.

Configuration

All via environment variables. The ones that matter:

VariableDefaultWhat it does
CAIRN_LLM_BACKENDollamaLLM provider: ollama, bedrock, gemini, openai
CAIRN_DB_PASScairn-dev-passwordDatabase password. Change this for anything beyond local.
CAIRN_AUTH_ENABLEDfalseAPI key auth on /api routes
CAIRN_API_KEY(empty)The API key when auth is enabled
CAIRN_GRAPH_BACKEND(disabled)Set to neo4j to enable knowledge graph
CAIRN_KNOWLEDGE_EXTRACTIONfalseEntity/statement extraction on store
CAIRN_EMBEDDING_BACKENDlocallocal (MiniLM, 384-dim) or bedrock (Titan V2, 1024-dim)

Full reference is in docker-compose.yml. Every variable has a sensible default.

Architecture

MCP clients (Claude Code, Cursor, etc.)     REST clients (curl, web UI, hooks)
        |                                            |
        | MCP (stdio or HTTP)                        | REST API
        |                                            |
+-------v--------------------------------------------v--------+
|  cairn.server (MCP tools)     cairn.api (FastAPI endpoints) |
|                                                             |
|  core: memory, search, enrichment, extraction, clustering   |
|        work items, projects, tasks, thinking, code intel    |
|                                                             |
|  graph: Neo4j (entities, statements, triples, code graph)   |
|  embedding: local (MiniLM) or Bedrock (Titan V2)            |
|  llm: Ollama, Bedrock, Gemini, OpenAI-compatible            |
+------+----------------------------------------------+-------+
       |                                              |
       v                                              v
  PostgreSQL 16 + pgvector                    Neo4j 5 (optional)

Benchmark

Tested against LoCoMo, a long-conversation memory benchmark with 1,986 questions across five categories.

SystemScoreLLM
Cairn81.6%Llama-3.3-70B
Human baseline87.9%
Letta/MemGPT74.0%GPT-4o-mini
Mem066.9%GPT-4o

Test configuration: Titan V2 embeddings (Bedrock, 1024-dim), episodic ingestion (raw turns + two-pass fact extraction), Search V2 with graph-primary retrieval, type routing, cross-encoder reranking, LLM-as-judge evaluation. Full results and methodology in eval/.

Development

git clone https://github.com/jasondostal/cairn-mcp.git
cd cairn-mcp
cp .env.example .env
docker compose up -d --build

Status

Cairn is under active development. It's a real system used daily in production, and it's evolving as I learn what actually works for agent memory. Migrations handle schema changes. If something breaks, open an issue.

License

GNU General Public License v3.0

Server Config

{
  "mcpServers": {
    "cairn": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}
Project Info
Created At
4 months ago
Updated At
3 months ago
Author Name
jasondostal
Star
-
Language
-
License
-
Category
Tags

Recommend Servers

View All
GovQL
@Alex Stout

# govql-mcp-server An MCP (Model Context Protocol) server for [GovQL](https://govql.us) — gives AI clients like Claude Desktop, Claude Code, and Cursor direct access to the US Congressional GraphQL API at [api.govql.us/graphql](https://api.govql.us/graphql) without bespoke HTTP wiring. For the design rationale (why FastMCP-Python, the passthrough+curated philosophy, roadmap through v0.4), see [design.md](https://github.com/govql/govql/blob/main/mcp-server/docs/design.md). ## What you can do with it Ask an agent questions like: - *"How did Vermont's two senators vote on the most recent nomination?"* - *"Which legislators in the 118th Congress switched parties during their service?"* - *"Compare Senator Sanders' voting record to Senator Murkowski's on cloture votes in the most recent Congress."* The agent picks the right tool, writes the GraphQL query against the live schema, and parses the response — no manual API wrangling. ## Install The server runs as a per-client subprocess over stdio. Pick your client: ### Claude Desktop Edit `claude_desktop_config.json` (Settings → Developer → Edit Config): ```json { "mcpServers": { "govql": { "command": "uvx", "args": ["govql-mcp-server"] } } } ``` Restart Claude Desktop. The `govql` tools appear in the tools panel. ### Claude Code Add to `.mcp.json` in your project (or `~/.mcp.json` for global): ```json { "mcpServers": { "govql": { "command": "uvx", "args": ["govql-mcp-server"] } } } ``` ### Cursor Settings → MCP → Add Server. Use the same `command` / `args` as above. ### Other clients Any MCP-compatible client that supports stdio servers will work. The command is `uvx govql-mcp-server` with no required arguments. ## Tools | Tool | Purpose | |---|---| | `execute_graphql` | Run any GraphQL query against the GovQL endpoint. Returns the result plus an `last_ingest` timestamp so the agent can reason about data freshness. | | `list_types` | Returns the names and kinds of every type in the GovQL schema. Optional `kind` filter (`"OBJECT"`, `"INPUT_OBJECT"`, `"ENUM"`, etc.) to narrow further. Start here when you don't know what's queryable. | | `describe_type` | Returns one type's full details — fields, arg signatures, input fields, enum values. Call after `list_types` to learn the shape of a specific type before writing a query. | ## Configuration All env vars are optional — the package is zero-config for end users. | Env var | Default | Purpose | |---|---|---| | `GOVQL_ENDPOINT` | `https://api.govql.us/graphql` | Endpoint to query. Override to point at a local dev stack. | | `GOVQL_TIMEOUT_MS` | `30000` | Per-request HTTP timeout. | | `LOG_LEVEL` | `INFO` | Logging level. Logs go to stderr only (stdout is reserved for the MCP transport). | ## Limits (enforced by the upstream API) - Max query depth: 10 - Max query complexity: ~10 billion points (`first: N` multiplies child cost by N — keep page sizes reasonable on deeply nested queries) - Rate limit: 100 requests / 60 s per source IP A depth or complexity violation surfaces as a GraphQL `errors` entry in the tool response so the agent can adjust and retry. ## Data freshness Every `execute_graphql` response includes a `last_ingest` ISO timestamp. Vote data refreshes hourly; legislator data refreshes daily. ## Status Version 0.1.0 ships three foundational tools: a GraphQL passthrough (`execute_graphql`) and two narrow schema-discovery tools (`list_types`, `describe_type`). Curated higher-level tools (`find_legislator`, `get_voting_record`, `compare_voters`, etc.) are planned for subsequent releases — see [design.md](https://github.com/govql/govql/blob/main/mcp-server/docs/design.md) for the roadmap. ## Links - [GovQL project site](https://govql.us) - [GraphQL API](https://api.govql.us/graphql) - [Source / issues](https://github.com/govql/govql)

2 days ago
Tavily Mcp
@tavily-ai

JavaScript
a year ago