Motion Memory Core
AI agents that remember.
Every time you open a new conversation with Claude Code or Cursor, the agent starts from zero. It doesn’t know you corrected it last week. It doesn’t know you’re under a merge freeze. It doesn’t know you hate mocks in tests.
Motion Memory Core fixes that with two tiers. Local Memory is a structured, file-based system that lives in your repo — typed, versioned, and loaded by the configured client at session start. The MCP Memory Server is one Railway-hosted Stash memory shared across every AI client you use — not just one repo. It learns from explicit outcomes without rewriting the underlying facts.
2
Memory tiers
4
Memory types
1
Memory, every client
∞
Durable, governed context
The Problem
Context windows close. Work doesn’t.
⊗ Without memory
- Agent asks the same clarifying questions each session
- You re-explain preferences you already stated
- Corrected mistakes resurface in new conversations
- Context about WHY things were built gets lost
- Every session starts from zero
⊕ With Memory Core
- Agent reads your profile, preferences, and corrections first
- Project context loads automatically — deadlines, decisions, WHY
- Feedback accumulates: mistakes corrected once stay corrected
- References to external systems are always at hand
- Relevant context is available
Two Tiers
Pick one. Or use both.
They don’t compete — they answer different questions. Local Memory is scoped to a repo; the MCP Memory Server is scoped to you, everywhere.
Tier 1 — this page, sections below
Local Memory
"What should this agent know while working in this repo?"
Tier 2 — see below
MCP Memory Server
"What should I remember, everywhere, forever?"
Local Memory — Architecture
Three tiers. One agent.
Local Memory works across three persistence tiers within a repo. The agent reads from all three at session start. The most specific tier wins when there’s a conflict.
One conversation
Session Memory
The context window. Everything the agent knows right now, in this conversation. Cleared when the session ends.
This repository
Project Memory
Structured markdown files in .claude/projects/{path}/memory/. Loaded at the start of each session via MEMORY.md. Persists across restarts.
All repositories
Cross-project Memory
Client-configured cross-project guidance shared across repositories. For user preferences and working style that transcend any single repo; exact loading paths vary by client.
Session start flow
Memory Types
Four types. All typed.
Every memory file carries a type field. The agent uses the type to understand what the memory is for — and when to load, apply, or update it.
type: user
User
Who you are working with
Role, expertise, preferences, and communication style. How the agent should calibrate its answers for this person.
Examples
- senior backend engineer, new to React
- prefers terse responses
- data scientist focused on observability
type: feedback
Feedback
How to approach the work
Corrections and confirmed approaches. The agent never asks the same question twice or repeats a mistake you already corrected.
Examples
- no mocks in integration tests — past incident burned us
- prefer bundled PRs for refactors
- always pass commit messages via HEREDOC
type: project
Project
Context behind the work
Ongoing goals, decisions, deadlines, and the WHY behind the work. Context that isn't derivable from reading the code.
Examples
- auth rewrite is legal-driven, not tech debt
- merge freeze begins 2026-03-05
- token routing MVP ships before Q3
type: reference
Reference
Where to look things up
Pointers to external systems: where bugs are tracked, which Slack channel owns what, which dashboard to monitor.
Examples
- pipeline bugs → Linear project INGEST
- oncall dashboard → grafana.internal/d/api-latency
- design tokens → Figma /design-system
Local Memory — Schema
A memory file looks like this.
.claude/projects/{path}/memory/feedback_no-db-mocks.md
--- name: no-db-mocks description: integration tests must hit a real database — not mocks metadata: type: feedback --- Never mock the database in integration tests. **Why:** Q3 incident — mock tests passed but the production migration failed. Real-world divergence caused an outage. **How to apply:** Any time tests are written for database operations, use a real test database. No exceptions unless the user explicitly requests. Related: [[test-strategy]], [[deploy-checklist]]
.claude/projects/{path}/memory/MEMORY.md
# Project Memory Index ## User - [User Profile](user_profile.md) — senior backend eng, new to React; prefers terse responses with no trailing summaries ## Feedback - [No DB Mocks](feedback_no-db-mocks.md) — integration tests must hit a real database - [PR Style](feedback_pr-style.md) — bundled PRs for refactors, one small PR per bug fix ## Project - [Auth Rewrite](project_auth-rewrite.md) — legal/compliance driver, not tech debt; ship before 2026-04-01 ## Reference - [Bug Tracking](ref_linear.md) — pipeline bugs → Linear project INGEST - [Dashboards](ref_grafana.md) — oncall dashboard at grafana.internal/d/api-latency
name
string
Short kebab-case slug. Used for [[wikilink]] references between memories.
description
string
One-line summary used to decide relevance. Loaded in MEMORY.md. Be specific — this is what the agent reads first.
metadata.type
user | feedback | project | reference
The memory type. Controls when the agent applies it and how it structures the body.
Local Memory — Setup
Set up in four steps.
Local Memory works with Claude Code, Cursor, and any agent that reads a CLAUDE.md or system prompt. The whole system is markdown — no new tooling required.
Create the memory directory
mkdir -p .claude/projects/$(pwd | sed 's|/|-|g')/memoryOr let the agent create it — Claude Code initializes this automatically if memory is enabled in CLAUDE.md.
Create MEMORY.md (the index)
touch .claude/projects/{path}/memory/MEMORY.mdThe index is loaded in every session. Keep each entry to one line (~150 chars). Never write memory content here — only pointers.
Write your first memory file
Each memory is a markdown file with frontmatter (name, description, type). See the schema below.
Add the memory prompt to CLAUDE.md
Tell the agent to read and write memory. Paste the prompt from the section below into your CLAUDE.md.
Step 04 — paste this into your CLAUDE.md
# Memory
You have a persistent, file-based memory system at
`.claude/projects/{path}/memory/`. Write to it directly
with the Write tool — do not check for its existence first.
Build this memory over time so future conversations have
a complete picture of who the user is, how they like to
collaborate, what behaviors to avoid or repeat, and the
context behind the work they give you.
## When to save memories
- **User** — any time you learn about their role,
expertise, or communication preferences
- **Feedback** — when they correct your approach OR
confirm an unusual choice worked (save BOTH)
- **Project** — when you learn WHY something is being
built, by when, or by whom
- **Reference** — when you learn where to find things
in external systems
## Memory file format
```markdown
---
name: short-kebab-slug
description: one-line summary (shown in MEMORY.md index)
metadata:
type: user | feedback | project | reference
---
Body content here. For feedback/project types, include
a **Why:** line and a **How to apply:** line.
Link related memories with [[their-name]].
```
## The index
After writing a memory, add a one-line pointer to MEMORY.md:
`- [Title](file.md) — one-line hook (~150 chars)`
MEMORY.md is always loaded. Keep it under 200 lines.
Never write memory content directly into MEMORY.md.MCP Memory Server — Tier 2
One memory. Every client.
Local Memory is scoped to a repo. The MCP Memory Server is scoped to you — a shared Stash memory service that BoltAI, Claude Desktop, Cursor, Claude Code, and any MCP client connect to over the native Streamable HTTP transport. Remember once, from any tool. Recall everywhere.
Architecture
Local reproducible stack
git clone \ https://github.com/tolowa-studio/stash.git cd stash cp .env.example .env # local development only docker compose up -d
Connect any client
Endpoint: https://<your-host>/mcp Auth: Authorization: Bearer <STASH_TOKEN> Works with BoltAI, Claude Desktop, Cursor, Claude Code — over Streamable HTTP (SSE also served for legacy clients).
You own it
Railway hosts the canonical Stash service. Private operator configuration holds deployment settings and client on-ramps; secrets never belong in the distribution repo.
Real memory, not a note file
Stash turns raw episodes into facts, relationships, causal links, patterns, goals, failures, and hypotheses. Bounded, checkpointed batches keep provider work predictable.
Modern transport, no bridge
Streamable HTTP at /mcp is primary. Legacy SSE remains available for older clients; reconnect clients after tool-schema changes.
Outcome-aware retrieval
Memory gets better with use.
Recall is a feedback loop, not a silent rewrite of truth. Each recall produces an impression identifier. A client can mark a result helpful, harmful, or neutral; Stash uses that signal to adjust a bounded retrieval-utility score. Fact confidence and canonical content remain separate. Raw queries are hashed, feedback is idempotent, and duplicate votes cannot amplify a result.
01
Recall
Search the scoped Stash namespace and return ranked results plus an impression.
02
Respond
The client uses the result in real work and observes whether it helped.
03
Feedback
Record helpful, harmful, or neutral once per impression/result pair.
04
Improve
Apply a small bounded utility adjustment while preserving factual confidence.
Cost-aware routing
Embeddings and reasoning are independently configurable. The current operator pattern keeps embeddings on OpenRouter and routes consolidation reasoning to an approved ClinePass lane. Authentication and quota failures fail closed, with no automatic metered-provider fallback.
Reliable consolidation
Episodes become structured knowledge through namespace locks, bounded batches, and checkpoints that advance only after successful writes. Expired facts are excluded, and malformed or weakly grounded model output is rejected instead of stored.
Distribution
A reference layer and a private kit.
The public reference materials explain the model. The operational distribution is a private, invitation-only kit containing client on-ramps, deployment runbooks, pinned Stash compatibility, verification steps, and environment-variable documentation without secrets. This keeps the public page useful while keeping production topology and credentials private.
memory-kit / (private)
memory-kit/ ← private distribution
├── README.md ← operator handoff
├── docs/
│ ├── client-onramp.md ← Cursor · Claude · Codex
│ ├── operations.md ← Railway + Stash runbook
│ └── verification.md ← smoke and release gates
├── config/
│ └── env.example ← names only; no secrets
└── scripts/
└── verify-stash-pin.shInside MotionOS
Memory is the intelligence layer.
MOTION is Tolowa Studio’s internal delivery method and technical engine. Memory is how agents and operators preserve decisions, project truth, and working context across sessions, models, and machines. It supports client delivery; it is not the front-door offer.
Business OS
Memory Core stores strategic decisions, lifecycle stage, and venture context — so agents never ask what phase you're in.
Learn more →
GTM OS
ICP, channel decisions, attribution taxonomy, and pipeline state persist across every pipeline triage and outbound session.
Learn more →
Web OS
Deploy workflows, component decisions, hosting architecture, and QA preferences carry forward session to session.
Learn more →
Questions
Common questions.
Does this work with Cursor?
Yes. Cursor reads .cursorrules and CURSOR.md, which you can wire the same prompt into. The file structure is identical — only the loading mechanism differs slightly.
Where should local memory live?
Use the convention your client and repository already support: repo-local instruction files and a reviewable memory directory. The exact loader is client-specific. Shared cross-repo memory belongs in the configured Stash MCP namespace, not in a client-specific global path.
What should NOT be saved to memory?
Code patterns, file paths, architecture decisions derivable from the code — git history and git blame own those. Ephemeral task details, current conversation context, or anything already in CLAUDE.md. Memory is for what is surprising, non-obvious, or can't be recovered by reading the repo.
How do I handle stale memories?
The agent is instructed to verify memory before acting on it — if a file path or function named in a memory no longer exists, it checks first. If a memory conflicts with current code, trust what you observe now and update or remove the stale memory.
Can the agent create memories autonomously?
Agents can write durable memory through the configured local convention or Stash MCP tools, but the safe protocol is scoped and source-aware: verify first, save only durable signal, and keep canonical source systems authoritative.
Is this the same as CLAUDE.md?
No. CLAUDE.md is project-wide instructions — static, same for everyone. Memory Core is dynamic, personal context that accumulates and evolves across sessions. They complement each other: CLAUDE.md sets the rules, Memory Core carries the context.
Do I need the MCP server, or is Local Memory enough?
Local Memory is enough if you only care about one repo at a time — it needs no infrastructure. Add the MCP server when you want the same memory to follow you into other repos, other machines, or other AI clients (BoltAI, Claude Desktop, Cursor) — not just the one you’re in right now.
Need the technical
architecture?
Explore how memory, source of truth, routing, and verification fit together.