Developer documentation

Give your agents
institutional memory.

Connect company knowledge, retrieve the right evidence, and compile it into a context envelope your agents can trust — from the browser, the terminal, or any agent runtime.

01 / Quickstart

From zero to source-backed context.

Everything runs from one repository. Docker is the default path; both surfaces also run natively.

Docker (recommended)
# 1. Configure once — every provider key is optional.
cp .env.example .env

# 2. Start everything: ArcadeDB, API, workspace, MCP server.
make memoryworks

# API       http://localhost:8000   (docs at /docs, health at /api/health)
# Workspace http://localhost:3000
# MCP       http://localhost:8001   (streamable HTTP)
Native, without Docker
# No Docker? Run the two surfaces natively and use the in-process graph.
export GRAPH_BACKEND=memory

make backend    # uvicorn app.main:app --reload --port 8000
make frontend   # next dev on port 3000

# Optional: seed a sample organization to explore:
curl -X POST http://localhost:8000/api/org/scenario/seed \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"reset": false}'
Demo data
# Load or reset a realistic demo organization inside Docker:
make demo     # load demo data
make reset    # wipe back to a clean workspace
Default servicesAPI at http://localhost:8000 · Workspace at http://localhost:3000 · Graph check via make graph-check
First sign-inOpen http://localhost:3000/login. With AUTH_DEV_MODE=true (the default in .env.example) a local development login is offered; GitHub, Google, and email sign-in activate as soon as their credentials below are set.
02 / Run in production

Same repo, two services.

The frontend is a Next.js app; the backend is a FastAPI container.vercel.json wires / to the frontend and /api/* to the backend, so cookies stay first-party.

Vercel (CLI or Git integration)
# One repo, two services (vercel.json at the root):
#   frontend → Next.js app (root: frontend/)
#   backend  → FastAPI container (Dockerfile.vercel)

vercel link
vercel env add JWT_SECRET production          # required — signs sessions
vercel env add OPENROUTER_API_KEY production  # model for live agent sessions

# Canonical origin — every OAuth callback is derived from it:
vercel env add PUBLIC_BASE_URL production     # https://memoryworks.app
vercel env add FRONTEND_URL production        # https://memoryworks.app
vercel env add GRAPH_BACKEND production       # memory

# Vercel containers are stateless: SQLite and the in-memory graph reset when a
# new container starts. For durable data, use the single-VM deploy (deploy/server).
# PUBLIC_DEMO_MODE=true is a stricter profile for a shared, disposable demo.

# Real sign-in providers (values from GitHub / Google consoles):
vercel env add GITHUB_CLIENT_ID production
vercel env add GITHUB_CLIENT_SECRET production
vercel env add GOOGLE_CLIENT_ID production
vercel env add GOOGLE_CLIENT_SECRET production

vercel --prod
Required on the backend serviceJWT_SECRET, a model key (OPENROUTER_API_KEY at minimum), and the OAuth credentials if sign-in buttons should be live. Environment changes apply only after a redeploy.
Self-hosted alternativedeploy/server and compose.production.yml run the same stack as durable containers with persistent volumes — that profile keeps ArcadeDB-backed graph storage and long-running watches.
03 / Authentication

Work identity for people. Scoped keys for agents.

People sign in with GitHub, Google, or a passwordless email code. GitHub sign-in also requests repository access and stores it as that person's GitHub connection, so the next step is choosing repositories — not connecting GitHub again. SDK, CLI, MCP, and server-side agents use a workspace-scoped API key. The browser session is an HttpOnly cookie; SDK and CLI use bearer tokens. Nothing is stored in the browser.

Register the OAuth callbacks

Provider setup
# GitHub OAuth app → Authorization callback URL (one per app)
https://memoryworks.app/api/auth/github/callback

# Google Cloud → Credentials → OAuth client → Authorized redirect URIs
https://memoryworks.app/api/auth/google/callback

# Locally the host is derived from the request, so the defaults just work:
#   http://localhost:8000/api/auth/github/callback
#   http://localhost:8000/api/auth/google/callback

Redirect URIs are derived from the request host automatically, so a deployment needs no baked-in domain. Setting PUBLIC_BASE_URL (non-local) pins them explicitly and wins over derivation. Add both credentials to .env or your Vercel environment, then restart or redeploy — the buttons on /login activate as soon as GET /api/auth/providers reports them configured.

Browser sign-in providers
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GITHUB_REDIRECT_URI=http://localhost:8000/api/auth/github/callback

GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
GOOGLE_REDIRECT_URI=http://localhost:8000/api/auth/google/callback
Passwordless email in production
# Passwordless email codes (people sign in without an OAuth provider)
EMAIL_AUTH_ENABLED=true
EMAIL_FROM=memory@company.com
SMTP_HOST=smtp.company.com
SMTP_PORT=587
SMTP_USER=...
SMTP_PASSWORD=...
Agents and automationWorkspace-scoped API keys authenticate CLIs, SDKs, MCP clients, and server-side agents. Create one under POST /api/keys and pass it as a bearer token.
Agent configuration
# Create a workspace-scoped key in the UI (Sources → API keys),
# or with the endpoint:
curl -X POST "$ORGMEMORY_API_URL/api/keys" \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "ci-agent"}'

# Agents then authenticate as a bearer token:
export ORGMEMORY_API_URL=https://your-host
export ORGMEMORY_API_KEY=om_live_...
04 / Model providers

One company context. Your choice of model.

MemoryWorks retrieves, scopes, and compiles the evidence before a model sees it. Configure any combination of providers; the default answers free-text questions and drives the agent loop that chooses tools step by step.

Model configuration
OPENROUTER_API_KEY=...          # GLM (default)
GLM_MODEL=z-ai/glm-5.3-flash
GLM_BASE_URL=https://openrouter.ai/api/v1

OPENAI_API_KEY=...              # GPT
ANTHROPIC_API_KEY=...           # Claude
GOOGLE_API_KEY=...              # Gemini
XAI_API_KEY=...                 # Grok
KIMI_API_KEY=...                # Kimi

ORG_MEMORY_DEFAULT_MODEL_PROVIDER=glm

# With no model key at all, every agent run falls back to a deterministic
# policy that still calls the real tools — the product never hard-fails.
05 / Connectors

Make capability status explicit.

GitHub, Slack, uploads, the API, Python SDK, CLI, and MCP are live. Google Workspace, Gmail, Microsoft 365, Teams, Outlook, and Atlassian are the next adapter layer. The catalog endpoint exposes the same status shown in the workspace, so a planned integration is never presented as connected.

liveReal authorization and ingestion or delivery path.
nextPrioritized adapter; visible, but no fake connect action.
plannedRoadmap source with a defined memory contract.
source_and_channelCan ingest a conversation and return an approved reply.
06 / Agent API

The cross-space operations Agent mode runs on.

Every agent step maps to one HTTP route under /api/org. Reads execute immediately. Writes only ever create a plan that waits for a person — there is deliberately no route an agent can use to approve its own change.

GET/api/org/spacesList the spaces (projects) the caller can see.
GET/api/org/contextCross-space state: decisions, open work, blockers, next best action.
GET/api/org/readinessLaunch checklist computed from the dependency graph.
GET/api/org/blockersRoot causes of a stall only — not every open item.
GET/api/org/conflictsTracked state vs. newer contradicting records, with a drafted resolution.
GET/api/org/reasoning-chainThe recorded chain behind a decision, walked by graph edges.
GET/api/org/provenance/:idSources and relationships behind one memory.
GET/api/org/dependency-graphWork items and REQUIRED_FOR edges across spaces.
POST/api/org/ask/streamRun a model-driven agent session; NDJSON steps stream back.
POST/api/org/followupsDraft the next questions from what a session found.
POST/api/org/plansPropose changes. Nothing applies until a person approves.
POST/api/org/plans/:id/approveHuman approval — the only write path to apply.
POST/api/org/watchesStanding checks (blockers, conflicts, staleness) on an interval.
POST/api/org/scenario/seedLoad the seven-space demo organization.
Streaming protocol/api/org/ask/stream answers a free-text question by letting the model choose tools one at a time and returns NDJSON events: start, step (tool, arguments, thought, summary), ping keepalives, then done or error. A proposal ends the run — approving it is always a person's action.
Streaming agent session
# Agent mode in the chat streams one real, model-driven session. Every step
# is a tool call against the workspace; changes stop at a plan for a person.

curl -N -X POST "https://your-host/api/org/ask/stream" \
  -H "Content-Type: application/json" -b "session cookie" \
  -d '{"question": "Are we ready to launch?", "space_ids": []}'

# One NDJSON event per line:
{"type":"start","id":"agtsess_…","model":"glm"}
{"type":"step","step":{"tool":"get_orgmemory_readiness","thought":"…","summary":"NOT READY — 1 blocker."}}
{"type":"done","session":{…,"answer":"…","proposal":{"status":"pending_approval"}}}
07 / Core API

A small surface for a large memory.

Ask with HTTP
curl -X POST "https://your-host/api/ask" \
  -H "Authorization: Bearer $ORGMEMORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "prj_platform",
    "query": "What changed in checkout, and why?",
    "token_budget": 8000
  }'
GET/api/healthCheck API and dependency health.
GET/api/auth/meThe signed-in principal and workspaces.
GET/api/projectsList projects visible to the caller.
POST/api/projectsCreate a project memory boundary.
POST/api/ingest/uploadAdd a document or source payload.
POST/api/askCompile evidence and answer a question.
GET/api/modelsList GLM, GPT, Claude, Gemini, Grok, and Kimi readiness.
GET/api/keysList workspace API keys.
POST/api/keysIssue a workspace-scoped agent key.
GET/api/connectors/catalogList live and planned company-memory sources.
GET/api/memory/unitsInspect retrievable memory units.
GET/api/memory/graph/summaryInspect the organizational graph.
GET/api/memory/context/:idRead a compiled context envelope.
GET/api/memory/swarm/:runIdInspect a context-swarm trace.
08 / Python SDK

Context assembly, typed in Python.

Install from this repository. The synchronous and asynchronous clients expose the same MemoryWorks primitives.

Install
python -m pip install -e ./python_sdk
# or via the Makefile: make sdk-install
agent.py
from orgmemory import MemoryWorks

memory = MemoryWorks(
    base_url="http://localhost:8000",
    api_key="om_live_...",
)

context = memory.ask(
    project_id="prj_platform",
    query="What changed in checkout, and why?",
)

print(context.answer)
print(context.compiled_context)

# Pass the source-backed context to any model or agent.
agent.run(context.compiled_context)
09 / CLI

Inspect memory from your terminal.

The CLI ships with the Python SDK: query projects, ingest sources, inspect graph state, and review context-swarm runs.

Query
export ORGMEMORY_API_URL=http://localhost:8000
export ORGMEMORY_API_KEY=om_live_...

orgmemory health
orgmemory projects
orgmemory project-create --name "Checkout platform"
orgmemory ask prj_platform "What changed in checkout, and why?"
orgmemory memories prj_platform
orgmemory graph prj_platform
orgmemory swarm swarm_01J...
Ingest
orgmemory ingest prj_platform \
  --file ./incident-review.md \
  --source-type doc \
  --title "Checkout incident review"

# Or send inline content
orgmemory ingest prj_platform \
  --content "Release 48 moved checkout to the new ledger." \
  --source-type other
10 / Context swarm

Specialists forage. One compiler decides.

A query activates a small ecosystem of retrieval specialists. Each searches a different memory surface — semantic candidates, graph relationships, and temporal state. A compiler agent deduplicates their findings, applies scope, and emits one bounded context envelope.

Query→ActivationGraphTemporal→Compiler
Swarm trace
{
  "run_id": "swarm_01J...",
  "status": "completed",
  "specialists": {
    "activation": "ranked candidate memories",
    "graph": "traversed related entities and decisions",
    "temporal": "resolved what was true at query time"
  },
  "compiler": "deduplicated, scoped context with evidence"
}
11 / Context envelopes

The answer is not the artifact.

Every ask returns an answer plus its compiled context, evidence, retrieval diagnostics, and a durable context-envelope identifier. Your agent consumes the context while your product keeps the provenance.

answerGrounded synthesis for the current query.
compiled_contextBounded context ready for a model call.
evidenceSource references and relevance metadata.
context_envelope.idDurable handle for replay and inspection.
12 / MCP server

Memory for tool-using agents outside the browser.

The same memory surface is exposed over MCP for assistants that are not browser-native: stdio for local clients, streamable HTTP for remote ones, with MCP OAuth for client registration.

Run the server
make mcp        # stdio transport
make mcp-http   # streamable HTTP on :8001
Client configuration
# Claude Desktop / any MCP client (stdio):
{
  "mcpServers": {
    "memoryworks": {
      "command": "mcp_server/.venv/bin/python",
      "args": ["mcp_server/server.py", "--transport", "stdio"],
      "env": { "MEMORYWORKS_API_URL": "http://localhost:8000",
               "MEMORYWORKS_API_KEY": "om_live_..." }
    }
  }
}
13 / Testing and CI

Every behavior above is under test.

The suite covers the org tools, the approval boundary, the agent runner with scripted models (no network), OAuth round trips, browser tool registration, and the SDK contract.

Quality gates
make test    # backend pytest + frontend tests + SDK tests
make lint    # ruff + black + tsc --noEmit
make ci      # test + lint + production build
make reset   # reset local data to a clean slate
14 / Security

Retrieval respects the caller.

Project boundaries, bearer authentication, and source metadata travel through retrieval. Keep API keys server-side, use a separate key per environment, and put the API behind TLS outside local development. Browser agents never receive credentials — they borrow the page's session, inside its permission boundary.

✓ Scope before synthesis✓ Evidence on every answer✓ Writes stop at a person✓ Inspectable swarm traces✓ Durable context envelopes