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.
From zero to source-backed context.
Everything runs from one repository. Docker is the default path; both surfaces also run natively.
# 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)# 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}'# Load or reset a realistic demo organization inside Docker:
make demo # load demo data
make reset # wipe back to a clean workspacehttp://localhost:8000 · Workspace at http://localhost:3000 · Graph check via make graph-checkhttp://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.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.
# 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 --prodJWT_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.deploy/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.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
# 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/callbackRedirect 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.
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 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=...POST /api/keys and pass it as a bearer token.# 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_...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.
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.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.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./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.# 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"}}}A small surface for a large memory.
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.Context assembly, typed in Python.
Install from this repository. The synchronous and asynchronous clients expose the same MemoryWorks primitives.
python -m pip install -e ./python_sdk
# or via the Makefile: make sdk-installfrom 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)Inspect memory from your terminal.
The CLI ships with the Python SDK: query projects, ingest sources, inspect graph state, and review context-swarm runs.
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...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 otherSpecialists 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.
{
"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"
}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.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.
make mcp # stdio transport
make mcp-http # streamable HTTP on :8001# 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_..." }
}
}
}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.
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 slateRetrieval 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.