title: Migration plans — round 2 date: 2026-05-24 host: ONE (10.10.1.120) parent: suggestions-1.md scope: 4 concrete migrations + 1 enablement
Focused execution paths for the four migrations identified in round 1. Ordered by expected ROI for effort, not alphabetically.
| # | Migration | Effort | Payoff | Reversibility |
|---|---|---|---|---|
| 1 | Wire Graphiti MCP into Claude (already running!) | ~15 min | High — replaces ⅔ of cognee value immediately | Trivial |
| 2 | Stand up LiteLLM proxy on :4001 |
~45 min | Medium-High — fixes cognee max_tokens, unifies providers | Trivial |
| 3 | Stand up Komodo | ~1 hr | Medium — central control of 25+ stacks | Easy (just docker compose down) |
| 4 | Evaluate Quartz v4 on a vault subtree | ~2 hr | Medium-High — fixes 13-day-unhealthy publish + wikilinks | Run alongside MkDocs |
| 5 | Migrate cognee corpus → Graphiti | ~half day | High — eliminates cognee operational tax | Keep cognee until Graphiti proven |
Status discovered: graphiti-mcp container is up 13 days healthy, exposed on
0.0.0.0:8089, backed by falkordb (also 12 days healthy). Image is
zepai/knowledge-graph-mcp — official Zep Graphiti MCP. Currently configured
to use Ollama at http://ollama:11434/v1 (OPENAI_API_KEY=ollama).
Why it's a quick win: - All infrastructure already running - Graphiti has a temporal knowledge graph model (episode-based) that's fundamentally cleaner than cognee's pipeline-based approach - Falkordb has stronger Cypher support than cognee's backend
Steps:
Probe the MCP endpoint:
bash
curl -sS http://10.10.1.120:8089/sse | head -20
curl -sS -X POST http://10.10.1.120:8089/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{}}' | jq
Add to ~/.claude.json mcpServers:
json
"graphiti": {
"type": "http",
"url": "http://127.0.0.1:8089/mcp"
}
(If 8089 needs sse, use "type":"sse" and /sse instead — probe step 1
tells you which.)
Reload MCPs and test with one graphiti.add_episode + graphiti.search
roundtrip from Claude.
Decide on model backend. Current Ollama backing is fine for low-cost ingestion but slow for extraction. If you want Gemini quality, swap the container env to point at LiteLLM (after Migration 2) instead of ollama directly — gives you provider flexibility without container changes later.
Risks:
- Graphiti's data model is episode-based; you can't just dump 483 markdown
files. Each note → episode with name, episode_body, source metadata.
Need an importer script (analogous to your vault-import.sh for cognee).
- Don't pollute the existing falkordb if it has other consumers; check with
redis-cli -p 6379 INFO keyspace inside the container first.
:4001Why now: Multiple cognee failures (#3589 Gemini max_tokens truncation,
layer that does:
- Automatic chunking when max_tokens would truncate
- Fallback (Gemini → Ollama → Anthropic) on rate-limit/truncation
- Single OpenAI-compatible endpoint that cognee, graphiti, open-webui, and
any future MCP can all point at
Port choice: :4001 (4000 is owned by silverbullet-mcp). Verified free
via ss -tlnp.
Steps:
Create /root/litellm/docker-compose.yml:
yaml
services:
litellm:
image: ghcr.io/berriai/litellm:main-latest
ports: ["4001:4000"]
volumes:
- ./config.yaml:/app/config.yaml
environment:
GEMINI_API_KEY: ${GEMINI_API_KEY}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
command: --config /app/config.yaml --port 4000
restart: unless-stopped
config.yaml with model fallback chain:
```yaml
model_list:
Point cognee at it: edit cognee's .env to set LLM_API_ENDPOINT=http://10.10.1.120:4001/v1 and LLM_MODEL=graph-extract. Restart backend.
Point graphiti-mcp at it: docker compose env update from
http://ollama:11434/v1 → http://host.docker.internal:4001/v1.
Validation: Run a cognify pass that previously failed with max_tokens truncation; LiteLLM should chunk + retry transparently.
Pain caveats:
- LiteLLM has had breaking changes between minor versions; pin to a known-good
tag rather than main-latest once you find one (e.g. v1.51.x).
- Its admin UI adds another dashboard (the thing round 1 warned against). Skip
the UI flag; CLI/file config only.
Why: You have 25+ docker stacks across /root and /opt. Each is
maintained ad-hoc. Komodo gives you:
- Single dashboard for stack status, logs, recreate-pending
- GitOps mode (compose lives in git, Komodo deploys)
- Periphery agents on other hosts (zeus, ajax-proxmox) for multi-node view
- Catches drift between intended and running state
The compose file is already at /opt/komo/docker-compose.yml. Just needs
.env populated and docker compose up.
Steps:
Read existing compose to understand required env vars:
bash
grep -E '^\s*[A-Z_]+:\s*\${' /opt/komo/docker-compose.yml
Create /opt/komo/.env:
KOMODO_DATABASE_USERNAME=komodo
KOMODO_DATABASE_PASSWORD=<generate>
KOMODO_PASSKEY=<generate>
KOMODO_HOST=http://10.10.1.120:9120 # pick an unused port
Pick a port (avoid the busy set). :9120 is likely free — verify with
ss -tlnp | grep 9120.
cd /opt/komo && docker compose up -d.
Add periphery agents on zeus + ajax-proxmox later (optional; single-node value is already significant on ONE alone).
Register your existing stacks in Komodo by pointing it at each
docker-compose.yml path. Do not let Komodo recreate them initially —
register in "observe-only" mode, then incrementally bring under management.
Migration risk: Komodo wants to own lifecycle. Stacks that aren't aware of it (your existing 25) may get recreated unexpectedly if you click "deploy" on them without first syncing the running container state into Komodo's model. Hence: observe-only first, then per-stack opt-in.
Why now: vault-site container has been unhealthy for 13 days (wget
healthcheck refused). Either the service is genuinely down or the healthcheck
is misconfigured — either way the existing pipeline is in an unknown state.
Good time to evaluate the alternative rather than just patch.
Quartz advantages relevant to you:
- Native Obsidian wikilink resolution (your custom resolver work goes away)
- Shiki for syntax highlighting (sidesteps pygments crash on SilverBullet
code blocks → no need for --delete-excluded shenanigans)
- Built-in search, graph view, backlinks panel
- Static output → can serve via nginx exactly like MkDocs
Steps:
Pick a small vault subtree to start (e.g., Knowledge/Hardware/).
Create /root/quartz-eval/ with Quartz v4:
bash
git clone https://github.com/jackyzha0/quartz /root/quartz-eval
cd /root/quartz-eval
npm install
Symlink the test subtree into content/:
bash
ln -s /CC/vault/Knowledge/Hardware /root/quartz-eval/content/Hardware
npx quartz build and inspect output. Check that:
- Wikilinks resolve (incl. path-syntax [[Projects/dts/Overview|dts]])
- Tags render
- Frontmatter is parsed
- Code blocks render (the pygments crash class)
If output looks right, expand to full vault and serve on a separate port
(e.g., :1235) alongside MkDocs :1234 for A/B comparison.
Once happy, retire MkDocs vault-site container, repoint NPM/DNS to Quartz.
Don't do yet:
- The full migration. Run both in parallel for at least a week.
- Touch /srv/vault-site until Quartz has been validated end-to-end.
Separate side-task: diagnose why vault-site is unhealthy. Could be a
30-second fix that lets MkDocs limp along during the Quartz evaluation:
docker logs vault-site --tail 50
docker exec vault-site wget -qO- http://localhost/ | head
Prerequisites: - Migration 1 complete (Graphiti MCP wired into Claude) - Migration 2 complete (LiteLLM in front so Graphiti uses Gemini reliably) - Confidence from a week+ of dual-running
Why this is last: Cognee currently works (1.5GB ingested, queries respond). The pain is operational (3 processes, 3s MCP timeout, fragile cognify runs), not functional. Don't migrate until the replacement is demonstrably better on your data.
Steps:
Build a Graphiti importer (analogous to your vault-import.sh):
- Walk /CC/vault/**/*.md
- Skip _checkpoints/, Library/, Repositories/
- For each note: extract frontmatter as metadata, body as episode content
- Use graphiti.add_episode with name=<relative-path>, source=text
Run on a small batch first (10 notes), inspect the resulting graph in
falkordb via:
bash
docker exec falkordb redis-cli GRAPH.QUERY graphiti "MATCH (n) RETURN n LIMIT 10"
Compare against same queries you ran on cognee. Quality benchmark: - "homelab network topology and key hosts" (your earlier cognee test) - "what containers run on ONE" - "which IPs front *.qoop.au"
If Graphiti answers ≥ cognee quality, bulk-import full vault.
Decommission cognee only after:
- Graphiti has been authoritative for ≥ 2 weeks
- You've snapshotted /root/.cognee/ to cold storage (don't delete the
1.5GB outright — it took a long Gemini run to build)
- You've migrated the cognee-vault-import memory note to point at
Graphiti's dataset
Cleanup at the end:
# After 2 weeks of Graphiti as primary
systemctl stop cognee-mcp.service # if you set this up
docker stop cognee-backend cognee-ui # whichever applies
mv /root/.cognee /root/.cognee.archived-$(date +%Y%m%d)
Then remove cognee MCP from ~/.claude.json.
Day 1 (15 min): Migration 1 — wire Graphiti MCP
Day 1 (45 min): Migration 2 — LiteLLM proxy
Day 1 (1 hr): Migration 3 — Komodo up + observe-mode
Day 2-3 (2 hr): Migration 4 — Quartz subtree eval
Week 2: Migration 5 — start cognee→Graphiti import
Week 4: Decommission cognee + retire MkDocs (if Quartz wins)
Day 1 alone gets you: - A second knowledge graph backend ready to A/B against cognee - A model proxy that fixes the recurring Gemini truncation pain - Visibility into all 25 docker stacks
That's ~2 hours of work for ~70% of the round-1 pain points resolved.
http://10.10.1.145:1234/? If no, the 13-day-unhealthy state is low-stakes
and Quartz can take its time.