Back to MCP Servers

Artel

Self-hosted coordination layer for AI agent fleets. Shared semantic memory, tasks, agent-to-agent messages, session handoffs, and a background archivist that synthesizes cross-agent knowledge. Any HTTP client participates — Claude Code, AutoGen, raw scripts.

knowledge-memoryaiagent
By NicolasPrimeau
7Updated 3 days agoPythonMIT

Installation

npx -y artel

Configuration

{
  "mcpServers": {
    "artel": {
      "command": "npx",
      "args": ["-y", "artel"]
    }
  }
}

How to use

  1. Run the installation command above (if needed)
  2. Open your Claude Code settings file (~/.claude/settings.json)
  3. Add the configuration to the mcpServers section
  4. Restart Claude Code to apply changes

Artel

CI License: MIT Glama smithery badge

Self-hosted coordination layer for AI agent fleets. A shared memory your agents read from and write to — with semantic search, tasks, async messaging, and session handoffs. The Claude Code plugin makes memory ambient: it pushes the right knowledge into a session at the right moment, and captures what happens back out — no agent has to remember to. Instances mesh together as CRDTs, compiled memory stays anchored to your code, and an autonomous archivist keeps the whole store clean and coherent. Any agent that speaks HTTP or MCP can join.

  Claude Code · opencode · Claude API · AutoGen
        │   push: memory/skills/gotchas in  ┄  capture: sessions out
        ▼
   REST / MCP ──► Artel Server ──► SQLite (WAL) + embeddings
                     ├── memory — semantic search · confidence decay · knowledge graph
                     ├── captures queue ──► archivist compaction ──► memory
                     ├── tasks · messages · events · session handoffs
                     └── archivist — capture · synthesis · merge · decay · promote
        │
   mesh (CRDT feeds + mDNS) ◄──► other Artel instances

Try it

export ARTEL_REG_KEY=artel && curl -fsSL https://artel.run/onboard | sh

UI: https://artel.run/ui (password: artel) — sandbox, data not persistent.


Self-hosting

curl -O https://raw.githubusercontent.com/NicolasPrimeau/artel/master/docker-compose.yml
curl -O https://raw.githubusercontent.com/NicolasPrimeau/artel/master/.env.example
cp .env.example .env
# edit .env: set UI_PASSWORD and ANTHROPIC_API_KEY at minimum
docker compose up -d

API + UI at http://<host>:8000, MCP at http://<host>:8000/mcp. Single container, single port. Images at ghcr.io/nicolasprimeau/artel:edge.

Once running, register an agent:

curl -fsSL http://<host>:8000/onboard | sh

mDNS note: the mdns service uses network_mode: host and only works on Linux. Remove it on Mac/Windows Docker Desktop.


Table of contents


Features

  • Shared memory — semantic search across all agents. Five types with different time horizons: memory (default, decays), doc (stable reference, archivist-promoted), directive (permanent standing instruction), skill (procedural, decays, never promoted), compiled (anchored to source code, recompiles instead of decaying). Confidence scores decay based on age and read frequency.
  • Ambient plugin — the Claude Code plugin turns memory from pull (tools an agent must call) into push: it injects relevant memory, matching skills, and file-anchored gotchas at the exact moment they help, delivers inbox messages, and captures sessions — all automatically.
  • Capture — a durable ingest queue absorbs raw session slices off the agent's hot path; the archivist compacts them into clean memory. The write side is as reliable as the read side, and a firehose of raw writes can never degrade the store.
  • Tasks — create, claim, complete, with dependencies. Agents coordinate without a central scheduler.
  • Messages — async agent-to-agent inbox. Direct or broadcast.
  • Session handoffs — save state at session end, resume with full context on next start. Any agent can pick up where another left off across context resets and machine restarts.
  • Feed subscriptions — subscribe any RSS or Atom feed; new items land in memory automatically.
  • Mesh — link two instances and memory replicates as a CRDT. LAN peers discovered via mDNS.
  • Compile mode — anchor memory to source code. Compiled notes recompile when the code changes, not when they age.
  • Archivist — optional background agent that compacts captures, synthesizes cross-agent findings, detects conflicts, and decays stale knowledge.

The Claude Code plugin — ambient memory

By default Artel is pull: MCP tools an agent calls when it thinks to. Agents forget. The plugin adds the push half — it volunteers the right knowledge at the right moment, and captures what happens, so the value of the shared store no longer depends on agent discipline.

Install — one line, no prompts:

curl -fsSL https://artel.run/plugin/install | sh

This registers an agent, writes ARTEL_URL / ARTEL_AGENT_ID / ARTEL_API_KEY to ~/.config/artel/env.sh (sourced from your shell profile), and installs the plugin via the claude CLI. It's a plain shell script, so an agent can run it for you. Then start a new Claude Code session.

Prefer to do it by hand? Set those three env vars, then in Claude Code:

/plugin marketplace add NicolasPrimeau/artel
/plugin install artel@artel

The plugin's MCP server and hooks read ${ARTEL_*} from the environment — there's no interactive config step.

Every hook is config-gated, fail-safe (a missing or down server is harmless), tightly ranked (a few high-confidence results, deduped per session so nothing re-injects), and — where it matters — entirely off the agent's hot path.

WhenWhat the plugin does
Session startinjects your last handoff and what changed in memory while you were gone
Every promptsurfaces the most relevant memories and a matching skill, plus any new inbox messages
Before an editshows memory anchored to that file — gotchas, decisions, prior findings — before you touch it
Before it stopsdelivers unread messages, so a teammate reaching you mid-run lands now, not next session
Every turn · before compactioncaptures the session slice for the archivist (Capture) — a ~10 ms local spool, never a network call on the hot path

Slash commands: /artel-recall (search shared memory), /artel-remember (write a fact), /artel-handoff (save a handoff), /artel-tasks (show or claim the next task).

Optional statusline — open task and unread-message counts, cached, in your prompt. Add to settings.json:

"statusLine": { "type": "command", "command": "/path/to/artel/scripts/artel-statusline.sh" }

Not seeing anything? Run scripts/artel-doctor.sh to check config and connectivity (it never prints your key).


Capture

The plugin surfaces memory in. Capture is the other direction — turning what happens in a session into durable memory out — without slowing the agent and without letting raw noise pollute the store.

A two-tier write. Agents don't reliably write memories back, and pouring a high-pace firehose straight into memory would cost an embedding per raw slice and pollute both search and the mesh. So capture lands in a separate ingest queue (captures) that is deliberately not embedded, not full-text indexed, not replicated over the mesh, and not returned by search. Memory is protected structurally: the archivist is the only path from the queue into memory.

Off the hot path. The Stop and PreCompact hooks do one thing — append the session payload to a local spool file and fork a detached drainer, then exit (~10 ms, no parsing, no network). The detached drainer compresses each session's new transcript slice (keeps the reasoning, drops bulky tool output), then ships it to the queue. The spool is a durable write-ahead log: if a drainer dies, the next hook's drainer picks up where it left off. Triggers are Stop (throttled by a per-session cursor and a size floor) and PreCompact (a forced flush right before context is evicted) — never SessionEnd, because agent sessions rarely end cleanly.

Leveled compaction (LSM-style). The archivist drains the queue and integrates each slice into memory — extracting durable facts, reconciling against what already exists (update rather than duplicate), and attaching session provenance. A second, less frequent pass consolidates the provisional entries: merging duplicates, raising confidence when independent sessions corroborate the same fact, reconciling contradictions, and promoting stable knowledge — scoped to the recent delta so the cost stays bounded. Raw captures → provisional memory → consolidated, canonical memory, refined over time.

The net effect: memory quality is decoupled from write volume. Writing fast only fills the queue; only the archivist's judgment turns a capture into memory.


Mesh

Each instance publishes memory as Atom and JSON Feed. Link two instances and memory replicates as a CRDT — keyed by immutable id, idempotent on ingest, no central coordinator. LAN peers discover each other via mDNS (_artel._tcp.local.) and link with one click. Each instance's archivist only synthesizes entries it originally wrote. (Captures never cross the mesh — they are local ingest, not shared memory.)

<details> <summary>Convergence guarantees</summary>
  • Stable identity. Propagated entries keep their origin UUID — never re-minted on ingest.
  • No loops. Re-receiving a known id is a no-op. Entries tagged with your own instance's origin are skipped. A → B → A terminates; A → B → C propagates.
  • Convergence. Concurrent edits settle last-writer-wins on version; deletes propagate as tombstones. The topology can contain cycles safely.

Pinned by tests in tests/test_feeds.py.

</details>

Compile mode

Mesh is one half of the symmetry: many agents converging on one shared truth. Compile mode is the other half — one shared truth converging on the code it describes. Where the mesh keeps instances consistent with each other, compile mode keeps memory consistent with the repo.

Most agent memory is authored: a human or agent writes a note, and it slowly decays as it ages and goes unread. That's right for judgement, incidents, and intent — knowledge with no ground truth to check against. But a lot of what agents "remember" about a codebase is really a description of code that already exists — and that has a ground truth. Compiled memory is anchored to it.

A pre-commit hook walks changed files with a deterministic AST compiler (no LLM), emits one anchor per symbol — module, function, class — and hashes each symbol's span. Each anchor mints or refreshes a compiled memory stamped with that hash and the commit SHA. When the code changes, the hash changes, and the note doesn't decay — it recompiles. Memory that's wrong about the code is rebuilt, not slowly forgotten.

Authored and compiled are endpoints of a continuum, not two modes. They share one store, one search index, one API. A note can sit anywhere between — an authored insight that an agent later grounds against a symbol, a compiled fact a human annotates. The same GET /memory/search returns both.

The knowledge graph is what makes the continuum real. Memories and code anchors are nodes of one heterogeneous graph; edges are typed:

  • grounds — an anchor grounds a memory in real code
  • relies_on — one node's meaning depends on another's (the dependency graph of meaning)
  • applies_to — an authored note applies to a region of code
  • corroborates / contradicts — agreement and tension between notes

Invalidation propagates **backward along `relies_o

View source on GitHub