SELF-HOSTED

Tortoise on your own infrastructure

Your data, your ops — the same epistemic memory graph, fully self-managed.
Prefer zero-ops? Try hosted →

What you get: a multi-writer-safe FalkorDB graph (AOF on the sidecar) behind the daemon, the MCP server, and the same Tortoise onboarding instructions your agent reads. The MCP tool names are identical to hosted — only the transport differs (self-hosted HTTP vs Streamable HTTP).

1Install

Clone the repo (Docker is the recommended path — no local Python needed):

git clone https://github.com/daniel-ospina/tortoise.git && cd tortoise

No Docker? pip install tortoise-graph (or pip install -e . from the repo) — Python 3.12+ — and use the embedded path below, which is single-agent eval only.

2Run the daemon (Docker, recommended)

The repo's docker-compose.yml starts the daemon plus a FalkorDB sidecar (AOF on, named volume, healthcheck) — the multi-writer path for teams and production:

docker compose up -d

✔ daemon ready → http://localhost:8000 (MCP at /mcp)
✔ FalkorDB sidecar healthy (127.0.0.1:6379, requirepass)

Set a strong TORTOISE_API_KEY in docker-compose.yml before exposing beyond localhost. Host-side tools can reach the sidecar directly with TORTOISE_DB_URI=docker://:falkordb@localhost:6379/tortoise.

Durability, plainly: AOF on the sidecar survives a process or container crash (≤1 s of lost writes) — it does not survive losing the volume or the host. Durability is the store's persistence plus an off-box copy, so the off-box backup target is a setup decision, not a silent default: in docker-compose.yml, fill all five of R2_ACCOUNT_ID / R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY / R2_BUCKET / TORTOISE_BACKUP_KEY to declare a target, or set TORTOISE_OFFBOX_BACKUP_DECLINED=1 to decline one explicitly. Leave both unset and the daemon still serves — and reports the single local copy loudly at startup. The full posture, with what has actually been verified: docs/durability-posture.md.

⚠️ Declaring the complete target arms the daemon's off-box backup driver: it sweeps this deployment's graph to that target every hour (configurable) with the read-back-verified logical dump, and logs every failed run. The first archive appears after the first interval, and the posture doc states the recovery path's verification status — read it before relying on the target.

3Onboard (5 steps)

Run tortoise onboard from your repo — it chains init → index → demo → doctor automatically (resolves the same DB target as your daemon):

tortoise onboard

Step 1/5: Ensure Tortoise SDK is installed
  ✅ Tortoise installed
Step 2/5: Initialize graph
  ✅ graph ready
Step 3/5: Index repository
  Found 42 markdown files. Indexing…
Step 4/5: First memory demo
  ✅ demo points created
Step 5/5: Health check
  ✅ doctor OK

Onboarding complete.
Next: connect your agent (step 4)
      tortoise setup  — configure per-role memory

Idempotent — re-running skips already-done steps. When it finishes, it prints the served onboarding instructions URL — hand that document to your agent to complete setup.

4Connect your agent (MCP)

Docker path (recommended): point your agent at the daemon:

claude mcp add --transport http tortoise http://localhost:8000/mcp   # writes local scope (~/.claude.json, private); or the project-scope .mcp.json block — committable, no key here (a local daemon needs none), and it stays Pending approval until you start claude in the project and allow the prompt (or run /mcp)

Stdio path (same durable sidecar): if you prefer stdio transport, point the harness at the sidecar (requires the Docker sidecar from step 2 running):


    
    

No Docker / single-agent eval: run python -m tortoise.mcp_server with TORTOISE_DB_PATH set — embedded FalkorDBLite is single-writer, eval only; concurrent writers lose data, so one agent only.

5Role memory (optional)

Configure how Tortoise filters memory per role:

tortoise setup --role developer   # researcher | strategist | developer

Or run tortoise setup interactively — it walks through episodic / epistemic / semantic / procedural / working memory per role.

6Which path should I use?

You are…Use…Why
One agent, experimenting / laptop evalEmbedded (no Docker, tortoise init)Zero deps, single-writer only — safe for one agent
A team / multiple agentsDocker compose sidecar (step 2)Multi-writer: verified to 5 concurrent writer processes with no lost writes
Production / HADocker compose or managed CloudAOF + a declared off-box target + ops; embedded is eval only

Embedded FalkorDBLite is AOF-durable for a single process since #915, but concurrent writers lose data — that is the boundary, and it is not negotiable for team deployments.

7Capacity and limits

What each path actually sustains — write concurrency, request rate limits, graph-size caps, retrieval latency, storage footprint per element, and belief-propagation cost. Every published number names the committed artifact or code symbol it comes from.

Measured today: the Docker path is verified to 5 concurrent writer processes on one graph with no lost writes; embedded is single-writer; the hosted per-key limit is 100 requests/min. The full page, with sources: docs/capacity.md.

Onboarding instructions: after setup, give your agent the Tortoise onboarding instructions — they self-adjudicate your harness, connect the MCP server, verify with tortoise_health, and report the harness-connected checkpoint. Read them at app.premiselabs.co/skills/tortoise-onboarding/SKILL.md (they are a document your agent reads — never an installed skill; the archived onboarding prompt was superseded by this document, M8) or run tortoise onboard and copy the URL it prints.
Hosted (zero-ops) → GitHub →