diff --git a/site/src/config/navigation.yml b/site/src/config/navigation.yml
index 52b0edae50..1080ad9d8f 100644
--- a/site/src/config/navigation.yml
+++ b/site/src/config/navigation.yml
@@ -87,6 +87,7 @@ sidebar:
items:
- label: "Overview"
slug: docs/user-guide/concepts/memory/overview
+ - docs/user-guide/concepts/memory/test-memory-store
- docs/user-guide/concepts/memory/bedrock-knowledge-base
- docs/user-guide/concepts/agents/retry-strategies
- label: Sandbox
diff --git a/site/src/content/docs/user-guide/concepts/memory/overview.mdx b/site/src/content/docs/user-guide/concepts/memory/overview.mdx
index d051b14bdc..94089a3fc6 100644
--- a/site/src/content/docs/user-guide/concepts/memory/overview.mdx
+++ b/site/src/content/docs/user-guide/concepts/memory/overview.mdx
@@ -15,7 +15,7 @@ sidebar:
By default a Strands agent starts every conversation from zero: it cannot recall a user's preferences, past decisions, or anything it learned in an earlier session. The `MemoryManager` gives an agent long-term memory that persists across sessions.
-It works through **memory stores**, the backends that hold the memories. A store can be a vector database, a managed service like [Amazon Bedrock Knowledge Bases](./bedrock-knowledge-base), or [your own implementation](#custom-stores). The manager handles three jobs across the stores you give it:
+It works through **memory stores**, the backends that hold the memories. A store can be the built-in zero-setup [test store](./test-memory-store), a managed service like [Amazon Bedrock Knowledge Bases](./bedrock-knowledge-base), or [your own implementation](#custom-stores). The manager handles three jobs across the stores you give it:
1. **Recall** - the agent searches stored knowledge on demand through a tool.
2. **Injection** - the manager folds relevant knowledge into the prompt automatically, before the model runs.
@@ -25,7 +25,7 @@ Recall and injection are enabled by default when you attach a store. Extraction
## Getting Started
-Attach a memory manager to an agent through the parameter. The examples below use a `store`, a `MemoryStore` you provide; see [Bedrock Knowledge Base](./bedrock-knowledge-base) for a managed backend or [Custom Stores](#custom-stores) to create your own.
+Attach a memory manager to an agent through the parameter. The [test store](./test-memory-store) below needs no cloud account and persists to disk by default, so this agent remembers across restarts with no setup. For a managed backend see [Bedrock Knowledge Base](./bedrock-knowledge-base), or [Custom Stores](#custom-stores) to create your own.
@@ -33,6 +33,10 @@ Attach a memory manager to an agent through the
+
+
+```python
+from strands import Agent
+from strands.memory import MemoryManager
+from strands.vended_memory_stores.test_memory_store import TestMemoryStore
+
+# Persists to ~/.strands/memory/notes.json by default. Survives restarts.
+store = TestMemoryStore(name="notes")
+
+agent = Agent(memory_manager=MemoryManager(stores=[store]))
+```
+
+
+
+```typescript
+--8<-- "user-guide/concepts/memory/test-memory-store_imports.ts:basic_imports"
+
+--8<-- "user-guide/concepts/memory/test-memory-store.ts:basic"
+```
+
+
+
+The store is writable by default, unlike a read-only managed store. So the [`add_memory`
+tool](./overview#memory-tools) and [automatic extraction](./overview#automatic-extraction)
+work as soon as you enable them, with no data source to set up first.
+
+It suits prototyping and tests, not a production corpus: each write rewrites the whole
+file and recall is keyword matching rather than semantic. For a production backend, use
+the [Bedrock Knowledge Base store](./bedrock-knowledge-base).
+
+## Persistence and location
+
+The store writes to `~/.strands/memory/.json`, deriving the filename from
+`name`. Give it an explicit `path` to control where the file lands, or turn persistence
+off for a store that lives only in memory:
+
+
+
+
+```python
+from strands.vended_memory_stores.test_memory_store import TestMemoryStore
+
+# Ephemeral: nothing is written to disk, and a fresh instance forgets everything.
+scratch = TestMemoryStore(name="notes", persist=False)
+
+# Explicit file location instead of the default under ~/.strands/memory/.
+project = TestMemoryStore(name="notes", path="./notes.json")
+```
+
+
+
+```typescript
+--8<-- "user-guide/concepts/memory/test-memory-store_imports.ts:persistence_imports"
+
+--8<-- "user-guide/concepts/memory/test-memory-store.ts:persistence"
+```
+
+
+
+Reach for `persist=False` in tests and throwaway runs where you want recall and ranking
+without leaving a file behind. The default (persist to disk) is what demonstrates the
+feature: memory that survives a restart.
+
+The on-disk format is shared between the Python and TypeScript SDKs. Records use the same
+keys and timestamp shape, so a file written by one SDK reads in the other.
+
+## Configuration
+
+`TestMemoryStore` takes the [shared `MemoryStore` fields](./overview#stores) (`name`,
+`description`, , `writable`,
+`extraction`) plus two of its own:
+
+| Field | Purpose |
+|-------|---------|
+| `persist` | Whether to write entries to disk. `True` (default) flushes to `path`; `False` keeps entries in memory only, lost when the process exits. |
+| `path` | Full path to the backing JSON file. Defaults to `~/.strands/memory/.json`. Ignored when `persist` is `False`. |
+
+`writable` defaults to `True` here. Construction rejects an empty `name`, an empty `path`,
+or a below `1`.
+
+## Recall
+
+`search` ranks entries by lexical overlap: it counts how many distinct words from the
+query appear in each entry's content, and returns the highest scorers first, breaking ties
+toward the most recent entry. Each result carries the count under a reserved
+`_relevanceScore` metadata key. A query with no usable words returns nothing.
+
+:::note
+Recall is keyword matching, not semantic search. A query word matches only the same word,
+not a synonym, so "seat" does not find an entry about "chair." For embedding-based
+semantic search over a managed vector store, use the [Bedrock Knowledge Base
+store](./bedrock-knowledge-base).
+:::
+
+## Writing memories
+
+`add` stores a single piece of content and returns its id. Identical content is
+deduplicated: a repeat write returns the existing record's id instead of storing a second
+copy, so the at-least-once retries that extraction may perform never accumulate
+duplicates.
+
+
+
+
+```python
+from strands.vended_memory_stores.test_memory_store import TestMemoryStore
+
+store = TestMemoryStore(name="notes")
+
+# add returns the id of the stored (or already-present, on dedup) record.
+result = await store.add("User prefers aisle seats", {"category": "travel"})
+print(result.id)
+
+results = await store.search("what seat does the user prefer?")
+for entry in results:
+ print(entry.content, entry.metadata.get("_relevanceScore"))
+```
+
+
+
+```typescript
+--8<-- "user-guide/concepts/memory/test-memory-store_imports.ts:search_and_add_imports"
+
+--8<-- "user-guide/concepts/memory/test-memory-store.ts:search_and_add"
+```
+
+
+
+Writing to a store constructed with ,
+or adding empty content, raises. When the backing directory is unreachable or not
+writable, the write raises with the target path.
+
+## Extraction
+
+Enable [automatic extraction](./overview#automatic-extraction) to capture memories from
+the conversation without the agent calling a tool:
+
+
+
+
+```python
+from strands.vended_memory_stores.test_memory_store import TestMemoryStore
+
+store = TestMemoryStore(
+ name="notes",
+ extraction=True, # distill facts from the conversation, every 5 turns
+)
+```
+
+
+
+```typescript
+--8<-- "user-guide/concepts/memory/test-memory-store_imports.ts:extraction_imports"
+
+--8<-- "user-guide/concepts/memory/test-memory-store.ts:extraction"
+```
+
+
+
+The store implements but not , so extraction runs client-side: a `ModelExtractor` distills facts
+from the conversation and writes each through `add`. To change the cadence or swap the
+extractor, see [Automatic Extraction](./overview#automatic-extraction) on the Memory page.
+
+## Scale and limitations
+
+The store keeps every entry in memory and rewrites the whole file on each `add`, using an
+atomic write so a crash mid-write never leaves a partial file. That design suits
+prototyping and personal memory, hundreds to low thousands of entries, not a production
+corpus. For large or high-throughput workloads, use a managed store like the [Bedrock
+Knowledge Base store](./bedrock-knowledge-base).
+
+Writes within a single process are serialized, so concurrent `add` calls can't clobber one
+another. Writers across separate processes are not coordinated, so avoid pointing two
+processes at the same file. A corrupt or wrong-shaped backing file raises with the path so
+the problem is visible; a missing file starts empty.
+
+## Related
+
+- [Memory](./overview) - the `MemoryManager` concept this store plugs into, including the
+ tools, extraction, and injection it enables.
+- [Bedrock Knowledge Base store](./bedrock-knowledge-base) - the managed `MemoryStore`
+ with semantic search, for production workloads.
diff --git a/site/src/content/docs/user-guide/concepts/memory/test-memory-store.ts b/site/src/content/docs/user-guide/concepts/memory/test-memory-store.ts
new file mode 100644
index 0000000000..2b33a358cd
--- /dev/null
+++ b/site/src/content/docs/user-guide/concepts/memory/test-memory-store.ts
@@ -0,0 +1,76 @@
+import { Agent, BedrockModel } from '@strands-agents/sdk'
+import { TestMemoryStore } from '@strands-agents/sdk/vended-memory-stores/test-memory-store'
+
+// =====================
+// Basic: persists to disk by default
+// =====================
+
+function basic() {
+ // --8<-- [start:basic]
+ // Persists to ~/.strands/memory/notes.json by default. Survives restarts.
+ const store = new TestMemoryStore({ name: 'notes' })
+
+ const agent = new Agent({
+ model: new BedrockModel(),
+ memoryManager: { stores: [store] },
+ })
+ // --8<-- [end:basic]
+
+ void agent
+}
+void basic
+
+// =====================
+// Persistence: ephemeral and explicit path
+// =====================
+
+function persistence() {
+ // --8<-- [start:persistence]
+ // Ephemeral: nothing is written to disk, and a fresh instance forgets everything.
+ const scratch = new TestMemoryStore({ name: 'notes', persist: false })
+
+ // Explicit file location instead of the default under ~/.strands/memory/.
+ const project = new TestMemoryStore({ name: 'notes', path: './notes.json' })
+ // --8<-- [end:persistence]
+
+ void scratch
+ void project
+}
+void persistence
+
+// =====================
+// Search and add
+// =====================
+
+async function searchAndAdd() {
+ // --8<-- [start:search_and_add]
+ const store = new TestMemoryStore({ name: 'notes' })
+
+ // add returns the id of the stored (or already-present, on dedup) record.
+ const { id } = await store.add('User prefers aisle seats', { category: 'travel' })
+
+ const results = await store.search('what seat does the user prefer?')
+ for (const entry of results) {
+ console.log(entry.content, entry.metadata?._relevanceScore)
+ }
+ // --8<-- [end:search_and_add]
+
+ void id
+}
+void searchAndAdd
+
+// =====================
+// Extraction
+// =====================
+
+function extraction() {
+ // --8<-- [start:extraction]
+ const store = new TestMemoryStore({
+ name: 'notes',
+ extraction: true, // distill facts from the conversation, every 5 turns
+ })
+ // --8<-- [end:extraction]
+
+ void store
+}
+void extraction
diff --git a/site/src/content/docs/user-guide/concepts/memory/test-memory-store_imports.ts b/site/src/content/docs/user-guide/concepts/memory/test-memory-store_imports.ts
new file mode 100644
index 0000000000..8c62fe7d9d
--- /dev/null
+++ b/site/src/content/docs/user-guide/concepts/memory/test-memory-store_imports.ts
@@ -0,0 +1,18 @@
+// @ts-nocheck
+
+// --8<-- [start:basic_imports]
+import { Agent, BedrockModel } from '@strands-agents/sdk'
+import { TestMemoryStore } from '@strands-agents/sdk/vended-memory-stores/test-memory-store'
+// --8<-- [end:basic_imports]
+
+// --8<-- [start:persistence_imports]
+import { TestMemoryStore } from '@strands-agents/sdk/vended-memory-stores/test-memory-store'
+// --8<-- [end:persistence_imports]
+
+// --8<-- [start:search_and_add_imports]
+import { TestMemoryStore } from '@strands-agents/sdk/vended-memory-stores/test-memory-store'
+// --8<-- [end:search_and_add_imports]
+
+// --8<-- [start:extraction_imports]
+import { TestMemoryStore } from '@strands-agents/sdk/vended-memory-stores/test-memory-store'
+// --8<-- [end:extraction_imports]