The pinky-mcp MCP server

pinky-mcp is how an agent uses the brain: it exposes memory as tools over MCP via stdio. The agent searches and saves knowledge without grepping or reading files by hand; it shares the same index (brain.db) as the pinky CLI.

  • It is not a daemon and does not listen on a port: it is a stdio process that the MCP client (Claude Code or another) launches and talks to over stdin/stdout.
  • Protocol: JSON-RPC 2.0, JSON messages delimited by line. Protocol version 2024-11-05. Methods: initialize, tools/list, tools/call, ping.
  • All logging goes to stderr (PINKY_LOG/RUST_LOG), never to stdout, so as not to pollute the JSON-RPC channel.

The three tools

brain_search — search knowledge

Hybrid search (BM25 full-text + semantic vector, RRF fusion) over the brain. Records usage telemetry (what gets retrieved).

ArgumentTypeReq.DefaultWhat it does
querystringWhat to search for. Max. 2,000 characters.
limitinteger10Max. results (1100).
scopestringNarrows by scope: global or project:<name>.
projectstringNarrows to a project (equivalent to scope: project:<name>).
typestringA single type: gotcha | pattern | decision | diary | guide | note.
tagsstring[]Only entries that have all these tags.
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
  "params": { "name": "brain_search",
    "arguments": { "query": "timeout al cerrar el pool de postgres",
                   "type": "gotcha", "project": "sgsvp", "limit": 5 } } }

brain_save — save new knowledge

Writes the source-of-truth .md (in PINKY_SAVE_DIR) and indexes it on the fly. Use it when the agent discovers something reusable worth remembering.

ArgumentTypeReq.DefaultWhat it does
titlestringShort, descriptive title. Max. 300 characters.
bodystringContent in markdown. Max. 100,000 characters.
typestringnotegotcha | pattern | decision | diary | guide | note.
tagsstring[]Tags to filter/retrieve. Max. 32.
projectstringProject (scope) of the entry.

The scope of the saved entry comes from the project argument or, if omitted, from the PINKY_PROJECT env var; with neither, it defaults to global.

{ "jsonrpc": "2.0", "id": 2, "method": "tools/call",
  "params": { "name": "brain_save",
    "arguments": { "type": "gotcha", "title": "El pool de PG se cuelga al apagar",
                   "body": "Usar pool.close(timeout=…) antes de salir…",
                   "tags": ["postgres", "pool"] } } }

brain_stats — index size

No arguments. Returns the number of indexed entries and chunks.

{ "jsonrpc": "2.0", "id": 3, "method": "tools/call",
  "params": { "name": "brain_stats", "arguments": {} } }
Each tool responds with a content: [{ "type": "text", "text": … }]. On an error (invalid input, missing index) it responds with the same shape plus "isError": true — it does not drop the connection.

Configuration (environment variables)

pinky-mcp takes no flags: it is configured through the environment. See also CONFIGURATION.md.

VariableDefaultWhat it does
PINKY_DBbrain.dbPath to the SQLite index. Set it the same as in the CLI so that pinky reindex and the agent see the same database.
PINKY_SAVE_DIRdocumentationFolder where brain_save writes the .md files.
PINKY_PROJECT(global)If set, saved entries land in the project:<value> scope.
PINKY_HASH_EMBED(unset)Uses the deterministic embedder (without downloading the ONNX model). Ideal for airgapped/CI.
PINKY_LOG / RUST_LOGwarnLogging level (to stderr).

Registering it in Claude Code

Prepares the project and writes .mcp.json with relative paths (relocatable across machines/clones), preserving other servers already defined:

pinky init

It leaves something like this:

{
  "mcpServers": {
    "pinky": {
      "command": "pinky-mcp",
      "env": {
        "PINKY_DB": "brain.db",
        "PINKY_SAVE_DIR": "documentation"
      }
    }
  }
}

PINKY_DB=brain.db matches the CLI default (pinky --db brain.db), so pinky reindex documentation and the agent share an index. Reopen the project in Claude Code and the pinky MCP is available.

Option B — claude mcp add (machine-global registration)

claude mcp add pinky --env PINKY_DB="$PWD/brain.db" -- pinky-mcp
# o, desde el repo de pinky_brain:
make mcp-register

Other MCP clients

Any client that speaks MCP over stdio works: point it at the pinky-mcp binary (on the PATH) as command, with the env vars above. The core is agnostic — only the hooks are specific to Claude Code.


Testing it by hand (debug)

Since it speaks JSON-RPC line by line, you can exercise it without a client:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"brain_stats","arguments":{}}}' \
  | PINKY_DB=brain.db pinky-mcp

You should see the serverInfo ("name":"pinky-brain"), the listing of the three tools and the index stats.


The three pieces share the same index: MCP pinky-mcp (this, for the agent), CLI pinky (CLI.md, for you/scripts) and hooks pinky-hooks (Claude Code). Full overview in HOW-IT-WORKS.md.