Documentation
Everything you need to know to install, configure and get the most out of Zé Papagaio — a persistent memory stack for Claude Code.
Quick Start
Prerequisites
- Node.js 18+ (LTS recommended)
- Docker Engine running (or Docker Desktop)
- An OpenAI API key (for embeddings)
- Claude Code installed and working
Install
npx zepapagaio initThe installer asks 3 questions: your OpenAI API key, the path to your Obsidian vault (or where to create one), and whether to enable the optional Obsidian MCP. After that it pulls Docker images, seeds initial memory files, and registers MCP servers in your Claude config.
First commands to try
# Check everything is running
ze status
# Remember something
ze lembra "We decided to use Convex as the backend"
# Search your memory
ze puxa "what backend are we using"If ze status shows all green, you are ready. If something is red, jump to the Troubleshooting section.
Architecture
Zé Papagaio is composed of three core layers (Phase 1) and four optional components added in Phase 2. Everything runs locally on your machine via Docker containers exposed only on loopback (127.0.0.1).
Core layers (Phase 1)
- Vault — Markdown files on disk, versioned in git, serving as the single source of truth.
- RAG (vault-rag) — OpenAI embeddings + sqlite-vec for semantic search across all notes.
- Graph (vault-graph) — Neo4j knowledge graph with auto-extracted entities and relationships.
Phase 2 components
- Cache — Redis for caching repeated tool calls and RAG queries.
- Storage — MinIO for persistent file storage (images, test artifacts, attachments).
- Multimodal — Image indexing pipeline: screenshot to description to RAG-indexed note.
- Testing — Robot Framework + Playwright in isolated containers for automated UI testing.
Vault & Memory
The vault is a directory of Markdown files — typically an Obsidian vault, but any directory works. Each file is a "memory note" that Claude can read, write, and search. The Zé installer creates an initial set of seed notes to bootstrap memory.
Frontmatter conventions
Every memory note should have YAML frontmatter with these fields:
---
name: project_aiox_overview
description: "Overview of the aiox project — URL shortener SaaS"
type: project
project: aiox
---| Field | Required | Description |
|---|---|---|
| name | Yes | Unique identifier, snake_case, used as filename |
| description | Yes | One-line summary for MEMORY.md index |
| type | Yes | One of: user, feedback, project, reference |
| project | If type=project | Project slug this note belongs to |
Memory types
| Type | Prefix | Purpose | Example |
|---|---|---|---|
| user | — | Personal preferences, general knowledge | preferred_language.md |
| feedback | feedback_ | Corrections, learned behaviors | feedback_smoke_test_mandatory_ui.md |
| project | project_ | Project-specific context and decisions | project_aiox_decisions.md |
| reference | reference_ | Reference material, how-tos | reference_multipass_disposable_vm.md |
MEMORY.md
The file MEMORY.md is the index — a Markdown list linking to every note with its description. Claude reads this file first to understand what memory is available. The autocommit hook keeps it in sync when notes are added or modified.
RAG (semantic search)
The RAG (Retrieval-Augmented Generation) component provides semantic search over your entire vault. Instead of keyword matching, it understands meaning — so searching for "which database do we use" finds a note that says "we chose Convex as the backend".
How it works
- Each note is split into paragraph-sized chunks (~300 tokens each).
- Each chunk is embedded using OpenAI
text-embedding-3-small(1536 dimensions). - Vectors are stored in sqlite-vec, a SQLite extension for vector similarity search.
- At query time, your question is embedded and compared against all chunks using cosine similarity.
- Top-k results are returned with the source note path and the matching text.
MCP tools
| Tool | Description | When to use |
|---|---|---|
| rag_search | Semantic search across the vault | Finding context by meaning, not exact keywords |
| rag_reindex | Re-index all notes (or a specific path) | After bulk edits or manual file changes |
| rag_stats | Show index stats (note count, chunk count, last indexed) | Debugging, checking if index is stale |
RAG vs. direct read
Use RAG when you don't know which file has the answer. Use direct file read (via Obsidian MCP or the Read tool) when you know exactly which note you need. RAG is for discovery; direct read is for precision.
# RAG search — finds relevant chunks across all notes
rag_search("what deployment platform do we use")
# Direct read — you already know the file
obsidian_get_file_contents("project_aiox_decisions.md")Knowledge Graph (Neo4j)
The knowledge graph stores structured relationships between entities in your vault. While RAG finds text by similarity, the graph answers questions like "which stories are blocked?" or "what decisions does project X depend on?".
Node types
| Label | Description | Example |
|---|---|---|
| Nota | Any memory note in the vault | project_aiox_overview |
| Projeto | A project entity | aiox, zepapagaio |
| Decisao | An architectural or product decision | Use Convex as backend |
| Story | A user story or task | Implement URL shortening |
| Pendencia | A pending item or blocker | Test WSL2 compatibility |
| Conceito | A concept or technology | RAG, Neo4j, MCP |
Relationship types
| Relationship | Direction | Meaning |
|---|---|---|
| SOBRE | Nota -> Projeto | Note is about a project |
| MENCIONA | Nota -> Conceito | Note mentions a concept |
| DEPENDE_DE | Story -> Decisao | Story depends on a decision |
| BLOQUEADA_POR | Story -> Pendencia | Story is blocked by a pending item |
MCP tools
| Tool | Description |
|---|---|
| graph_query | Run a Cypher query against the graph |
| graph_neighbors | Get all nodes connected to a given node (1-hop) |
| graph_stats | Show node/relationship counts and labels |
Auto-extraction via hooks
When you save a memory note (via Claude's Write/Edit tools), a PostToolUse hook automatically extracts entities and relationships from the note content and upserts them into the graph. You don't need to manually maintain the graph — it stays in sync with your vault.
# Example Cypher query — find all stories blocked by something
graph_query("MATCH (s:Story)-[:BLOQUEADA_POR]->(p:Pendencia) RETURN s.name, p.name")
# Get everything connected to a project
graph_neighbors("zepapagaio")Obsidian MCP
The Obsidian MCP server gives Claude direct read/write/search access to your Obsidian vault through the Local REST API plugin. This is optional — the vault-rag and vault-graph MCPs work independently of Obsidian.
When you need it
- You want Claude to read/write notes without going through the filesystem directly.
- You want to use Obsidian's search capabilities (full-text, tag search, etc.).
- You have Obsidian open and want Claude to interact with the same vault instance.
When you don't need it
- You are using the vault purely as a file directory (no Obsidian app).
- Obsidian is not installed or you prefer not to keep it open.
- RAG search is sufficient for your workflow.
Setup
- Install the Local REST API plugin in Obsidian (Community Plugins → search "Local REST API").
- Enable the plugin and note the API key from its settings.
- The Zé installer detects Obsidian and registers the MCP server automatically if you opt in.
Available tools
The Obsidian MCP exposes tools like obsidian_get_file_contents, obsidian_append_content, obsidian_simple_search, obsidian_complex_search, and more. These all operate on the currently open vault.
Cache (Redis)
The cache layer uses a local Redis instance to avoid redundant API calls and speed up repeated operations. It caches tool call results, RAG queries, and GitHub API responses.
Key namespacing
| Prefix | What it caches | Default TTL |
|---|---|---|
| tool:* | MCP tool call results | 5 min |
| rag:* | RAG search results (query hash → chunks) | 15 min |
| gh:* | GitHub API responses (issues, PRs) | 10 min |
| session:* | Session-level context (current project, etc.) | 1 hour |
CLI commands
# Show cache stats (hit rate, key count, memory usage)
ze cache status
# Clear all cached entries
ze cache limpa
# Clear only RAG cache (useful after reindex)
ze cache limpa ragCache keys are hashed from the input parameters, so identical queries return cached results instantly. The cache automatically invalidates when underlying data changes (e.g., a note edit triggers RAG cache eviction for that note).
Storage (MinIO)
MinIO provides S3-compatible object storage running locally. Files that used to disappear into chat history now get persistent URLs.
Buckets
| Bucket | Purpose | TTL |
|---|---|---|
| chat-images | Screenshots and images from chat | 30 days |
| robot-artifacts | Test execution reports and screenshots | No expiry |
| vault-attachments | Binary files referenced by vault notes | No expiry |
CLI commands
# List images in storage
ze imagem lista
# Upload an image
ze imagem salva screenshot.png
# Get a presigned URL for an image
ze imagem url screenshot.pngMinIO runs on port 9000 (API) and 9001 (console), bound to 127.0.0.1 only. Credentials are auto-generated during install and stored in ~/.config/zepapagaio/env.
Multimodal
The multimodal pipeline lets Zé "see" images. It takes a screenshot or diagram, generates a text description, saves it as a Markdown note, and indexes it in RAG. After indexing, you can find images by their content using semantic search.
How it works
- You provide an image (file path or URL).
- GPT-4o-mini (default) or GPT-4o generates a structured description.
- The description is saved as a Markdown note in the vault with metadata (source path, timestamp, model used).
- The note is automatically indexed by the RAG pipeline.
- The original image is stored in MinIO (chat-images bucket).
Cost per image
| Model | Cost per image | Best for |
|---|---|---|
| gpt-4o-mini (default) | ~$0.0015 (~R$0.008) | Most screenshots, UI, text-heavy images |
| gpt-4o | ~$0.01 (~R$0.05) | Dense charts, complex diagrams, tiny text |
Usage
# Index a screenshot (saves to vault + RAG)
ze imagem indexa ./screenshot.png
# Index with GPT-4o for better quality on complex images
ze imagem indexa ./dense-chart.png --model gpt-4o
# Later, find it by content
ze puxa "the chart showing MRR drop in March"The auto-index hook can also trigger automatically when Claude reads or receives a relevant image during conversation.
Testing
Zé includes an automated testing layer using Robot Framework with a headless Playwright browser, running inside an isolated Docker container. This lets Claude run UI smoke tests without dumping thousands of tokens of browser output into the conversation.
How it works
- Test files are Robot Framework
.robotfiles with Playwright keywords. - Tests run inside a container with a headless Chromium browser.
- Results (pass/fail, screenshots, logs) are stored in MinIO (robot-artifacts bucket).
- Only a summary is returned to Claude — not the full browser output.
CLI commands
# Run a specific test
ze testa my-story
# Run all tests
ze testa
# Run with visible browser (debugging)
ze testa my-story --headedShared keywords
Zé ships with a library of shared Robot Framework keywords for common actions (login flows, navigation, form filling). These are available in ~/.config/zepapagaio/robot/keywords/.
Skills & Self-programming
The skill system gives Claude specialized abilities that load on demand. Instead of one massive system prompt, Claude activates the right skill for the task at hand — API design, debugging, Next.js patterns, security review, and so on.
How skills work
- Skills are Markdown files with structured instructions, stored in the skill library.
- Each skill has a trigger condition (when to activate) and instructions (how to behave).
- Claude loads skills dynamically based on the current task context.
- Multiple skills can be active simultaneously.
Autopilot
The skill autopilot runs silently in the background. When it detects a gap — you are working with a framework or tool that no active skill covers — it searches the library, promotes the best match, or creates a new skill from scratch. You do not need to ask for this; it happens automatically.
Creating custom skills
# A skill is a Markdown file with this structure:
---
name: my-custom-skill
description: "Expert at X framework"
trigger: "code imports X or user asks about X"
---
## Instructions
When activated, follow these patterns:
1. Always check for ...
2. Prefer X over Y because ...
3. Common pitfalls: ...Place custom skills in your vault's skill library directory. The autopilot will discover and promote them when relevant.
Zé CLI
The ze CLI is the main way to interact with the memory stack from your terminal. All commands are available after running npx zepapagaio init.
| Command | Description |
|---|---|
| ze status | Show status of all services (Neo4j, Redis, MinIO, RAG index) |
| ze lembra <text> | Create a memory note from a text snippet |
| ze puxa <query> | Semantic search across the vault (uses RAG) |
| ze grafo <query> | Query the knowledge graph (Cypher or natural language) |
| ze cache status | Show cache hit rate, key count, memory usage |
| ze cache limpa [prefix] | Clear cache (all or by prefix: rag, tool, gh, session) |
| ze imagem indexa <path> | Index an image (describe → vault note → RAG) |
| ze imagem lista | List indexed images |
| ze imagem url <name> | Get presigned URL for a stored image |
| ze testa [story] | Run Robot Framework tests (all or specific story) |
| ze parar | Stop all Docker containers |
| ze voltar | Start all Docker containers back up |
| ze desinstala | Uninstall Zé (removes containers, keeps vault) |
| ze doctor | Diagnose common issues (ports, services, keys) |
All ze commands accept --help for usage details. The CLI is deliberately minimal — most of the heavy lifting happens through Claude's MCP tools, not through direct CLI usage.
Troubleshooting
Start with ze doctor — it checks all services and reports what is wrong. Below are the most common issues and fixes.
Docker not running
# Symptom: ze status shows all services as "down"
# Fix: start Docker
sudo systemctl start docker # Linux
open -a Docker # macOSOpenAI key expired or invalid
# Symptom: rag_search returns authentication errors
# Fix: update the key
nano ~/.config/zepapagaio/env
# Change OPENAI_API_KEY=sk-... to your new key
# Then restart:
ze parar && ze voltarNeo4j not responding
# Symptom: graph_query times out or returns connection refused
# Check if the container is running:
docker ps | grep neo4j
# If not running:
ze voltar
# If running but not responding, check logs:
docker logs zepapagaio-neo4j --tail 50
# Common cause: not enough memory. Neo4j needs ~512MB.Obsidian not open (MCP connection refused)
# Symptom: obsidian_* tools fail with ECONNREFUSED
# Fix: open Obsidian and make sure Local REST API plugin is enabled.
# Alternatively, if you don't use Obsidian, you can ignore this —
# vault-rag and vault-graph work independently.Port conflicts
| Service | Default port | How to change |
|---|---|---|
| Neo4j Bolt | 7687 | NEO4J_BOLT_PORT in ~/.config/zepapagaio/env |
| Neo4j HTTP | 7474 | NEO4J_HTTP_PORT in ~/.config/zepapagaio/env |
| Redis | 6379 | REDIS_PORT in ~/.config/zepapagaio/env |
| MinIO API | 9000 | MINIO_API_PORT in ~/.config/zepapagaio/env |
| MinIO Console | 9001 | MINIO_CONSOLE_PORT in ~/.config/zepapagaio/env |
After changing ports, run ze parar && ze voltar to restart with the new configuration.
RAG index is empty or stale
# Check index status:
ze status # look at "RAG index" line
# Force a full reindex:
rag_reindex()
# or from CLI:
ze puxa --reindexGeneral debugging
# Full diagnostic report
ze doctor
# Check all container logs
docker compose -f ~/.config/zepapagaio/compose.yml logs --tail 20