Tribal is a semantic memory server, served over MCP. It holds an engineering team's tribal knowledge: the tacit decisions and hard-won reasoning that never reach the docs, captured once and kept queryable for the team and the agents they work with.
Semantic memory served over MCP

Your team's tribal knowledge, made queryable.

The tacit engineering know-how that never reaches your docs, captured once and recalled by your agents the moment it applies.

npx skills add tribal-memory/skills

Most of what your team knows was never written down.

The reasoning behind a load-bearing decision. The workaround for a dependency that fails in one specific way. It lives in a few senior heads, and it leaves when they do.

New joiners outnumber the people who hold it, and an agent starting a fresh session knows none of it.

Tribal moves that knowledge from the few heads that hold it to wherever it is next needed.

Recalled in a session
you: switched an inference stage to openai on docker and the call just fails. nothing useful in the logs. ideas?
agent: Could be a config coupling, not the provider itself. Let me check tribal before I trace the request.
[tribal_discover]
  query: inference stage fails after switching provider to openai on docker
↳ top hit (0.74): "a stage's provider and base_url must change together"
↳ 0.74         decision  provider and base_url move together; change both or neither
agent via Tribal: A past ingest says the provider field and base_url move together. Switching to openai while base_url stays at the local default keeps requests routing to ollama, so the call fails.
[tribal_get_item]
  id: the provider/base_url coupling decision
↳ returns the why: a half-switched config silently routes to the old endpoint
agent: Nobody wrote this down. Set base_url to the openai endpoint alongside the provider and the stage recovers.

The reasoning, not the transcript.

Tribal is not trying to remember everything. It preserves what remains useful after the work is done.

Tacit knowledge is the know-how people carry without writing down: the reasoning behind a decision, the heuristic someone keeps reaching for. Tribal captures it as something your agents can read, so the knowledge your team works from is the knowledge your agents work from. It holds that human reasoning, not a transcript of what an agent did.

Captured once. Recalled when it applies.

  1. 3.1

    Captured as portable principles.

    Tribal captures a session as a reusable principle: the decision, when it applies, and the trap it avoids. It keeps the insight you would want next time, not a summary of what happened.

    Ingested item
    Principle

    Write a child's PID into the signal-handler's slot before the first await; pass it in at spawn if the await is unavoidable.

    Applies when

    A process spawns children and a handler (a SIGCHLD reaper, or a graceful-shutdown path) reads their PIDs, and the spawn crosses an await before the PID is recorded.

    Trap it avoids

    The handler fires in the await gap and reads the slot as 0; kill(0, sig) then signals the caller's whole process group, so one shutdown stops every sibling and the parent, not the one child.

  2. 3.2

    Retrieved by the situation, not the keyword.

    Items are indexed by when they apply. Ask for help with a problem worded nothing like where the lesson was first learned, and Tribal still surfaces it.

    Situation-matched recall
    you: on shutdown, stopping one worker sometimes takes the whole pool with it. only under load, and never in a clean run. where do I even look?
    agent: That reads like a signalling race, not your stop logic. Let me ask tribal before I open the spawn path.
    [tribal_discover]
      query: one child signalled on shutdown, but the whole group dies under load
    ↳ top hit: a signal-handling heuristic from 2026-04-12, learned elsewhere
    ↳ 0.83         heuristic store the PID before the await, or the handler reads it as 0
    ↳ 0.71         fact      kill(0, sig) signals the caller's whole process group
    agent via Tribal: Asked in today's words, tribal surfaced a heuristic from a month back, learned on unrelated work: a PID written after an await reads as 0 in the handler, and kill(0) then hits the whole group. Same shape as your pool dying.
    [tribal_get_item]
      id: the 2026-04-12 signal-handling heuristic
    ↳ returns the trap in full: handler fires in the await gap, reads 0, signals the group
    agent: Found without grepping. The fix is one line: write the PID synchronously, before the await.
    
  3. 3.3

    Curated, not hoarded.

    Every ingest is checked against what is already there. Near-duplicates merge, and items link by what they support, contradict, or derive from, so the graph stays high-signal as it grows.

    On ingest

    A PID-race fact from today's session landed beside the signal-handling lesson already in the graph. The pipeline didn't just store it; it wired the typed edges, linking it to the heuristic it supports and the SIGINT escalation model that heuristic derives from.

    [tribal_explore]
      anchor: today's PID-race fact
      direction: both
    ↳ supports     heuristic PID before await…
    # follow it to the heuristic it backs
    [tribal_explore]
      anchor: the "PID before await" heuristic
      direction: both
    ↳ supports     fact      Ctrl+C swallowed by tokio…
    ↳ derived_from fact      SIGINT escalation model…
    # and the model it derives from
    [tribal_explore]
      anchor: the SIGINT escalation model
      direction: both
    ↳ supports     heuristic escalate, then force…
    

Tribal in practice.

Step through four real sessions: a long ingest arc capturing hard-won lessons before a schema wipe, a month-old heuristic surfaced from a symptom that names none of it, a contradiction the graph caught on its own, and the typed-graph lineage tracing a fact back to where it was learned.

Capture

# end of a long reindexing arc, before the schema migration wipes the instance
---
you: dozens of hard-won lessons in this. take your time and ingest as much as you can before we break the schema. all of this information is so useful.
agent: Let me set my identity, capture the first principle, and confirm the pipeline runs end to end before firing the rest.
[tribal_set_context]
  model: claude-opus-4-8
  project: tribal-memory/tribal
↳ context set
[tribal_ingest]
  content: a fail-fast test runner stops at the first failing crate, so a large branch hides broken tests downstream that never run...
↳ queued (job f5e63ab3)
[tribal_job_status]
↳ success: that one paragraph decomposed into 3 typed items
↳              fact      fail-fast stops at the first failing binary; later crates never run
↳              procedure run the suite with --no-fail-fast; capture the whole failure set at once
↳              heuristic don't trust a one-failure run; the runner may have aborted early
agent: Pipeline is healthy and does its own extraction. Firing the rest, one principle per item.
[tribal_ingest]
  content: two transactions updating the same pair of rows in opposite orders deadlock; standardise every writer on one acquisition order...
↳ queued
[tribal_ingest]
  content: migrate a live store as an append-only backfill plus a brief exclusive cutover, not a per-commit dual-write that races...
↳ queued
[tribal_ingest]
  content: transaction-rollback isolation doesn't hide another test's committed writes; give a committing test its own database...
↳ queued
[tribal_ingest]
  content: +10 more: resolve a mutable identity at use, not at boot; back an invariant at the schema when the column type cannot; build the index after the bulk load...
↳ 10 more principles queued
agent via Tribal: Fourteen principles captured, each decomposed into atomic, typed items and durable in the queue. The next agent on this codebase inherits the why, not just the diff.

Recall

# today's signal-handling fixes are ingested; now browsing what the graph already holds
---
you: take a look through tribal. make some discover calls and follow the explore edges.
agent: Let me discover across a few angles, then follow the most relevant edges.
[tribal_discover]
  query: cancellation in async multi-stage operations; making stages individually cancellable
↳ 0.81         heuristic make the longest stage cancellable first; defer the rest
↳ 0.74         fact      the cancellation-aware lifecycle, modelled stage by stage
   +3 more
agent: Prior thinking is here. Today's work touched the signal handler, so let me pull that thread.
[tribal_discover]
  query: signal handlers reading shared state across an async boundary; PID cells
↳ 0.59         heuristic store the PID before the await, or the handler reads it as 0
↳ 0.59         procedure pass the child PID in at spawn; store it before any await
↳ 0.52         heuristic killing the child unblocks the executor, which runs its own cleanup
   +2 more
[tribal_explore]
  anchor: the signal-handling design heuristic (2026-04-12)
  direction: both
↳ supports     fact      today's PID-race fact, added a month later
↳ supports     fact      a third Ctrl+C is swallowed by tokio after the handler exits
↳ derived_from fact      the three-level SIGINT escalation model from review
agent via Tribal: A design heuristic from a month ago, one query away, and tribal had already wired today's PID-race finding to it as supporting evidence. Nothing I ingested mentioned April; the graph made the link, and that single submission had fanned into the fact, the procedure, and the heuristic above.

Contradiction

# after a PR: see what the pipeline actually related, not just what matched
---
you: a few discover calls across the diff, then explore the anchors that look interesting.
[tribal_discover]
  query: Box<dyn Error> as the outer error type at API boundaries
↳ 0.57         decision  use Box-outer for the aggregator after clippy result_large_err
↳ 0.55         heuristic switch to Box-outer, not per-variant Box: one indirection per path
   +2 more
[tribal_discover]
  query: realpath canonicalisation; macOS BSD vs GNU behaviour
↳ 0.72         fact      BSD realpath rejects paths with missing components; GNU resolves them
↳ 0.65         heuristic symlinked vs canonical form breaks prefix comparison on macOS
↳ 0.64         fact      need coreutils grealpath for GNU semantics on macOS
   +3 more, across 5 queries run in parallel
agent: The realpath cluster carries the most standing. Let me explore the anchor fact in both directions.
[tribal_explore]
  anchor: the BSD-realpath fact
  direction: both
↳ contradicts  decision  we kept BSD behaviour; its diagnostic error was accurate enough
↳ supports     heuristic realpath scripts are not portable across BSD and GNU
↳ supports     fact      install grealpath, or shadow realpath, for GNU semantics
agent via Tribal: The pipeline laid down that contradicts edge itself: a recorded decision pushing back on the fact. Plain similarity says "related"; a typed contradicts edge says "in tension". That, and the standing counts (one against, two for), is what a keyword search or a backlink cannot give you.

Provenance

# after a three-provider validation run, before tearing the probe down
---
you: before I tear this probe down: what got created, and how did it link together?
[tribal_discover]
  query: per-provider JSON Schema dialects; strict-mode subsets
  include_references: true
↳ 0.69         fact      normalise the schema per provider at the transport boundary
↳ 0.66         fact      schemars draft-07 wraps refs in allOf; both providers reject it
↳ 0.61         fact      strict mode rejects oneOf and $ref with sibling keys
   each tagged with the model and provider that authored it
[tribal_explore]
  anchor: the schema-dialect fact
  direction: both
↳ derived_from fact      the schemars draft-07 finding, 16:41, the openai run
↳ supports     fact      a second extractor confirmed it, 16:47
↳ supports     fact      the anthropic run agreed, 16:51
agent: The edge type and direction are here; the justification text lives on the edge itself and the tools don't surface it, so a full audit would read it from the database.
agent via Tribal: Still, one discover and one explore reconstruct the whole probe: which model authored each fact, and edge timestamps that trace the three provider runs in order. Provenance and a timeline, read straight off the graph.

What Tribal doesn't do.

  1. 4.1

    It is not autonomous agent memory.

    It does not record everything an agent does, and it does not edit itself mid-task. You decide what gets ingested.

  2. 4.2

    It is not a code index.

    It does not retrieve files, symbols, or call sites; that is your editor's job. Tribal holds the reasoning behind the code, not the code itself.

  3. 4.3

    It is not tied to one agent.

    Tribal speaks standard MCP, so any MCP-capable harness can use it. Get started ships ready-made snippets for the ones we run it with.

Make it yours.

Audit every line that touches your data. Tribal's full source is public under the Elastic License 2.0, so you can fork it and shape it to your team.

Your own Postgres

Your memories live in a Postgres instance you run and own, never in ours.

Model agnostic

Ingest and retrieval call the provider you configure, or stay fully local with Ollama.

Fully instrumented

Tribal emits OpenTelemetry to the collector you connect, keeping observability on your own infrastructure, or nowhere at all.

Agentic onboarding

The setup skills are CC BY 4.0 licensed, call nothing home, and help you from first install through everyday use.

Get started.

6.1 Add the skills

npx skills add tribal-memory/skills

6.2 Tell your agent

Set up Tribal for me

The skill installs Tribal, registers your project, mints a token, and wires your harness. You watch.

Prefer to do it by hand?
Install

Homebrew on macOS, or the shell installer for macOS and Linux:

brew install tribal-memory/homebrew-tap/tribal
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/tribal-memory/tribal/releases/latest/download/tribal-installer.sh | sh

Or Docker Compose with bundled Postgres. See the README for the compose setup.

Wire your harness

Run bootstrap in your repo. It registers the project, mints a token, and prints the MCP config below.

tribal bootstrap

One tab per supported harness. The stdio transport shown is the default; pass --transport http or sse to tribal serve for a persistent server.

Claude Code

Config file
~/.claude.json
Status
Tested.
{
  "mcpServers": {
    "tribal": {
      "command": "tribal",
      "args": ["serve", "--project", "<project-id>"]
    }
  }
}

Codex

Config file
~/.codex/config.toml
Status
Tested.
[mcp_servers.tribal]
command = "tribal"
args = ["serve", "--project", "<project-id>"]

OpenCode

Config file
~/.config/opencode/opencode.json
Status
Tested.
{
  "mcp": {
    "tribal": {
      "type": "local",
      "command": ["tribal", "serve", "--project", "<project-id>"],
      "enabled": true
    }
  }
}
Prerequisites

Postgres with pgvector, a model provider (local Ollama or an API key for a supported cloud provider), and npx for the skills install. The Tribal binary itself needs no Node.

You will know it worked when…

You will know it worked when your agent lists the Tribal tools and your first ingest comes back on recall.