Skip to content
Pilotoo
v0.1

Embed it in a host

Brain is four packages. A host takes the ones it needs and supplies the rest through ports, so Brain can sit inside an existing NestJS app with its own sign-in.

Package Holds
@pilotoo/memory-protocol The zod schemas of the HTTP API and the MCP tools. Depends on zod only.
@pilotoo/memory-core The domain: createBrain, services and ports. No Nest, no pg, no model SDK.
@pilotoo/memory-server The Nest pieces: PostgreSQL and pgvector stores, REST and MCP controllers, model and embedding adapters, BrainKnowledgeSource.
@pilotoo/web-auth Optional: Google sign-in the standalone service uses.

The packages are not on a registry yet; install them as described in Installation.

ensureBrainSchema creates the tables and the vector extension. It is idempotent and takes an advisory lock, so several instances may boot together. The database needs PostgreSQL with the pgvector extension available.

src/database.ts
import { ensureBrainSchema } from '@pilotoo/memory-server';
import { Pool } from 'pg';
export async function openBrainPool(databaseUrl: string): Promise<Pool> {
const pool = new Pool({ connectionString: databaseUrl });
await ensureBrainSchema(pool, { schema: 'pilotoo_brain', embeddingDimensions: 1024 });
return pool;
}

embeddingDimensions fixes the width of the embedding column when the schema is first created. Pass the same value to brainProviders afterwards; without it the column takes vectors of any size.

src/app.module.ts
import { Module } from '@nestjs/common';
import { brainControllers, brainProviders } from '@pilotoo/memory-server';
@Module({
controllers: brainControllers,
providers: brainProviders({
pool,
schema: 'pilotoo_brain',
embeddingDimensions: 1024,
ports: { directory },
}),
})
export class AppModule {}

brainProviders provides BRAIN (the Brain object from createBrain) and an exception filter that gives every failure the shape {error: {code, message}}. The only required port is directory, a PeopleDirectory with get(userIds) that returns name, email and picture for the people Brain shows. The clock, ids and token hashing default to the system’s.

The controllers read who is calling from the request. Your identity guard fills BrainRequest:

  • brainViewer: {userId, isWorkspaceAdmin} for a signed-in person.
  • brainPrincipal: for a route marked AgentRoute (the MCP endpoint), the principal of an agent token. authenticateAgent(brain, directory, secret) returns it for a pb_ secret, or null.

A request with neither is answered 401. Reject an agent token on every route that is not marked AgentRoute: its per-memory grants are honoured only by the agent service.

All model ports are optional. Add the ones you want to ports:

Port Adapter Notes
extractor createTextExtractor() Text from plain text, Markdown, CSV, HTML and PDF uploads.
embedder createBedrockTitanEmbedder({region, apiKey, dimensions}) Titan Text Embeddings V2 through Bedrock, with a Bedrock API key. model defaults to amazon.titan-embed-text-v2:0.
embedder createOpenAiEmbedder({baseUrl?, apiKey, model, dimensions?}) Any OpenAI-compatible /embeddings endpoint; omit baseUrl for OpenAI.
pageCompiler, answerer, labelSuggester createPageCompiler(model), createAnswerer(model), createLabelSuggester(model) Take a LangChain chat model, for example one resolved through the provider registry of @pilotoo/agent-runtime.
src/models.ts
import { createProviderRegistry } from '@pilotoo/agent-runtime';
import { createAnswerer, createBedrockTitanEmbedder, createLabelSuggester, createPageCompiler, createTextExtractor } from '@pilotoo/memory-server';
const model = createProviderRegistry({ 'anthropic-bedrock': { region: 'eu-central-1', apiKey } }).resolveModel(
{ provider: 'anthropic-bedrock', modelId: 'eu.anthropic.claude-haiku-5-5' },
{ maxTokens: 4096 },
);
export const modelPorts = {
extractor: createTextExtractor(),
embedder: createBedrockTitanEmbedder({ region: 'eu-north-1', apiKey, dimensions: 1024 }),
pageCompiler: createPageCompiler(model),
answerer: createAnswerer(model),
labelSuggester: createLabelSuggester(model),
};

brain.capabilities reports which of these are present: semanticSearch, answers, pageCompilation, labelSuggestions and fileExtraction.

BrainKnowledgeSource implements the KnowledgeSource of @pilotoo/agent-runtime. An agent that declares memory slugs as its knowledge retrieves passages from them, and each search runs as the person making the run.

src/knowledge.ts
import { BrainKnowledgeSource } from '@pilotoo/memory-server';
export const knowledge = new BrainKnowledgeSource({
brain,
limit: 5,
viewerOf: (caller) => ({ userId: caller.identity.subject, isWorkspaceAdmin: false }),
});
Option Default Meaning
brainProviders({pool}) required The pool of a database where ensureBrainSchema has run.
brainProviders({schema}) pilotoo_brain Schema the tables live in.
brainProviders({embeddingDimensions}) none Must match the width the schema was created with.
brainProviders({ports}) directory required Everything the host decides: directory, and optionally clock, ids, tokenSecrets, embedder, extractor, pageCompiler, answerer, labelSuggester.