Implements v0.0.1 of OpenBrain: - FastAPI REST API (capture, search, recent, stats) with Bearer auth - MCP server (streamable HTTP at /mcp) exposing all 4 tools - pgvector schema (vector(1024) for bge-m3) - asyncpg connection pool with lazy init + graceful close - Ollama embedding client with fallback (stores thought without vector if Ollama unreachable) - Woodpecker CI pipeline (lint + kaniko build + push to Gitea registry) - Portainer/Swarm deployment compose - Mosaic framework files: AGENTS.md, PRD.md, TASKS.md, scratchpad Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
2.4 KiB
Markdown
88 lines
2.4 KiB
Markdown
# OpenBrain — Agent Guidelines
|
|
|
|
> **Purpose**: Self-hosted semantic brain — pgvector + MCP server for any AI agent
|
|
> **SSOT**: https://git.mosaicstack.dev/mosaic/openbrain
|
|
> **Status**: Alpha (0.0.1)
|
|
|
|
---
|
|
|
|
## Stack
|
|
|
|
| Layer | Tech |
|
|
|-------|------|
|
|
| Language | Python 3.12 |
|
|
| API | FastAPI + uvicorn |
|
|
| MCP | `mcp[cli]` Python SDK (streamable HTTP transport) |
|
|
| Database | PostgreSQL 17 + pgvector |
|
|
| Embeddings | Ollama (`bge-m3:latest`, 1024-dim) |
|
|
| CI/CD | Woodpecker → Gitea registry |
|
|
| Deployment | Docker Swarm via Portainer |
|
|
|
|
## Structure
|
|
|
|
```
|
|
src/
|
|
config.py — env-based settings (pydantic-settings)
|
|
db.py — asyncpg connection pool
|
|
embeddings.py — Ollama embedding client
|
|
models.py — Pydantic request/response models
|
|
brain.py — core operations (capture, search, recent, stats)
|
|
main.py — FastAPI app + MCP server mount
|
|
docker/
|
|
postgres/init.sql — schema + pgvector setup
|
|
.woodpecker/
|
|
build.yml — lint → kaniko build → push
|
|
```
|
|
|
|
## Key Rules
|
|
|
|
1. **Never hardcode secrets, IPs, or internal hostnames.** All config via env vars.
|
|
2. **Public repo.** `.env` is gitignored. `.env.example` has placeholders only.
|
|
3. **MCP transport is Streamable HTTP** mounted at `/mcp`. Not stdio.
|
|
4. **REST + MCP live in one process** (`src/main.py`). No separate MCP container.
|
|
5. **Schema is append-only** in alpha. Migrations via new SQL files in `docker/postgres/`.
|
|
6. **Embeddings are best-effort**: if Ollama is unreachable, thought is stored without embedding.
|
|
|
|
## Auth
|
|
|
|
All REST endpoints require: `Authorization: Bearer <API_KEY>`
|
|
|
|
MCP server at `/mcp` uses the same key via MCP client config headers.
|
|
|
|
## Local Dev
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
# Fill in DATABASE_URL, API_KEY, OLLAMA_URL
|
|
|
|
uv pip install -e ".[dev]"
|
|
uvicorn src.main:app --reload
|
|
```
|
|
|
|
## CI/CD
|
|
|
|
Push to `main` → Woodpecker lints + builds image → pushes `sha-<hash>` + `latest` tags.
|
|
Tag a release → pushes `v0.0.x` + `sha-<hash>` tags.
|
|
|
|
## Deployment
|
|
|
|
Use `docker-compose.portainer.yml` as a Portainer stack.
|
|
Required env vars: `POSTGRES_PASSWORD`, `API_KEY`, `OLLAMA_URL`, `IMAGE_TAG`.
|
|
Init SQL must be copied to host at `/opt/openbrain/init.sql` before first deploy.
|
|
|
|
## MCP Client Config (Claude Code)
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"openbrain": {
|
|
"type": "http",
|
|
"url": "https://brain.woltje.com/mcp",
|
|
"headers": {
|
|
"Authorization": "Bearer <API_KEY>"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|