# Brains

A personal second-brain HTTP API and MCP (Model Context Protocol) server backed by Supabase Storage with Postgres full-text search. Designed for ChatGPT Actions, Claude integrations, and any MCP-compatible agent.

---

## Quickstart: init a project

Run this once per project from any MCP-connected agent:

```
init_project({
  projectSlug: "my-project",
  projectName: "My Project",
  platform: "claude",
  execute: true
})
```

This single call idempotently:

1. Creates `projects/my-project/readme.md` (project registry page).
2. Generates and saves `projects/my-project/instructions/claude.md` (platform-specific instruction file).
3. Seeds the three foundation pages (`instructions/agent-instruction-schema-v1.md`, `instructions/agent-instruction-template-v1.md`, `instructions/brain-routing.md`) if they are missing.
4. Creates stub cross-project tracking pages at the brain root (`active-open-loops.md`, `active-unanswered-questions.md`, `active-next-actions.md`, `decisions/core-decisions-log.md`) if they are missing. Wikis that already carry the pre-#455 copies at `projects/active-*.md` keep using those — no duplicate is created.

The response includes two artifacts:
- `instructionMarkdown` — the full wiki instruction file saved to `projects/my-project/instructions/claude.md`. This is the canonical reference document an agent reads at session start.
- `systemPromptMarkdown` — a short pointer block to paste into your Claude Project system prompt (or `CLAUDE.md`). It contains the identity, brain-first rule, activation gate, and a single boot sequence that ends with "read `projects/my-project/instructions/claude.md` and follow it."

Paste `systemPromptMarkdown` into your system prompt. The instruction file handles all domain context and write-back rules — keep the system prompt short.

### Preview before applying

```
init_project({
  projectSlug: "my-project",
  projectName: "My Project",
  execute: false
})
```

Returns the full operation plan with no writes.

---

> **Why not `pull_wiki`?** It returns a base64-encoded ZIP inline in the tool response, which overflows MCP tool-result token caps at modest scale (~30 pages). `pull_session_bundle` returns plain text sized to fit in a single response and paginates via `nextCursor`. `pull_wiki` remains available for filesystem-equipped clients (e.g. Claude Desktop with filesystem access) and full-archive backup workflows.

---

## Architecture

- **HTTP server** (`src/httpServer.ts`) — REST API with OAuth 2.0, designed for ChatGPT Actions and Claude integrations.
- **MCP server** (`src/server.ts`) — MCP tool registry over stdio or HTTP transport.
- **Storage** (`src/storage/client.ts`) — Local filesystem or Supabase Storage backend.
- **Search** (`src/search/postgresIndex.ts`) — Postgres full-text search index (Supabase) or local scan fallback.

See [API-FIRST-ARCHITECTURE.md](./API-FIRST-ARCHITECTURE.md), [STORAGE.md](./STORAGE.md), and [WIKI-SCHEMA.md](./WIKI-SCHEMA.md) for deeper documentation.

---

## Observability

Every HTTP response carries an `X-Response-Time` header (e.g. `X-Response-Time: 43ms`) indicating server-side processing time. Every request also emits a single log line to stdout:

**Plain format (default):**
```
[req] GET /api/v1/search 200 43ms backend=sqlite-fts queryMs=12
[req] POST /api/v1/pages 200 11ms
[req] GET /api/v1/search 200 8ms zero-results=true
```

**Structured JSON (`LOG_FORMAT=json`):**
```json
{"ts":"2026-04-17T10:00:00.000Z","method":"GET","path":"/api/v1/search","status":200,"durationMs":43,"backend":"sqlite-fts","queryMs":12}
```

Set `LOG_FORMAT=json` to enable structured logging for log-shipping (e.g. Datadog, Logtail). Search requests additionally log `backend` and `queryMs` when available, and `zero-results=true` when a search returns no results.

---


```bash
npm install
npm run build
npm start
```

Set `BRAINS_TRANSPORT=stdio` to run as an MCP stdio server.

## Testing

```bash
npm test
```
