docs/public/usage/search-tools.mdx
Claude-mem provides persistent memory across sessions through 4 MCP tools that follow a token-efficient 3-layer workflow pattern.
Instead of fetching all historical data upfront (expensive), claude-mem uses a progressive disclosure approach:
This achieves ~10x token savings compared to traditional RAG approaches.
Start by searching to get a lightweight index of results:
search(query="authentication bug", type="bugfix", limit=10)
Returns: Compact table with IDs, titles, dates, types Cost: ~50-100 tokens per result Purpose: Survey what exists before fetching details
Get chronological context around specific observations:
timeline(anchor=<observation_id>, depth_before=3, depth_after=3)
Or search and get timeline in one step:
timeline(query="authentication", depth_before=2, depth_after=2)
Returns: Chronological view showing what was happening before/after Cost: Variable, depends on depth Purpose: Understand narrative arc and context
Fetch full details only for relevant observations:
get_observations(ids=[123, 456, 789])
Returns: Complete observation details (narrative, facts, files, concepts) Cost: ~500-1000 tokens per observation Purpose: Deep dive on specific, validated items
Traditional Approach:
3-Layer Approach:
__IMPORTANT - Workflow DocumentationAlways visible reminder of the 3-layer workflow pattern. Helps Claude understand how to use the search tools efficiently.
Usage: Automatically shown, no need to invoke
search - Search Memory IndexSearch your memory and get a compact index with IDs.
Parameters:
query - Full-text search query (supports AND, OR, NOT, phrase searches)limit - Maximum results (default: 20)offset - Skip first N results for paginationtype - Filter by observation type (bugfix, feature, decision, discovery, refactor, change)obs_type - Filter by record type (observation, session, prompt)project - Filter by project namedateStart - Filter by start date (YYYY-MM-DD)dateEnd - Filter by end date (YYYY-MM-DD)orderBy - Sort order (date_desc, date_asc, relevance)Returns: Compact index table with IDs, titles, dates, types
Example:
search(query="database migration", type="bugfix", limit=5, orderBy="date_desc")
timeline - Get Chronological ContextGet a chronological view of observations around a specific point or query.
Parameters:
anchor - Observation ID to center timeline around (optional if query provided)query - Search query to find anchor automatically (optional if anchor provided)depth_before - Number of observations before anchor (default: 3)depth_after - Number of observations after anchor (default: 3)project - Filter by project nameReturns: Chronological list showing what happened before/during/after
Example:
timeline(anchor=12345, depth_before=5, depth_after=5)
Or search-based:
timeline(query="implemented JWT auth", depth_before=3, depth_after=3)
get_observations - Fetch Full DetailsFetch complete observation details by IDs. Always batch multiple IDs in a single call for efficiency.
Parameters:
ids - Array of observation IDs (required)orderBy - Sort order (date_desc, date_asc)limit - Maximum observations to returnproject - Filter by project nameReturns: Complete observation details including narrative, facts, files, concepts
Example:
get_observations(ids=[123, 456, 789, 1011])
Important: Always batch IDs instead of making separate calls per observation.
Scenario: Find what went wrong with database connections
Step 1: search(query="error database connection", type="bugfix", limit=10)
→ Review index, identify observations #245, #312, #489
Step 2: timeline(anchor=312, depth_before=3, depth_after=3)
→ See what was happening around the fix
Step 3: get_observations(ids=[312, 489])
→ Get full details on relevant fixes
Scenario: Review architectural choices about authentication
Step 1: search(query="authentication", type="decision", limit=5)
→ Find decision observations
Step 2: get_observations(ids=[<relevant_ids>])
→ Get full decision rationale, trade-offs, facts
Scenario: Find when a specific file was modified
Step 1: search(query="worker-service.ts", limit=20)
→ Get all observations mentioning that file
Step 2: timeline(query="worker-service.ts refactor", depth_before=2, depth_after=2)
→ See what led to and followed from the refactor
Step 3: get_observations(ids=[<specific_observation_ids>])
→ Get implementation details
Scenario: Track how a feature evolved
Step 1: search(query="dark mode", type="feature", orderBy="date_asc")
→ Chronological view of feature work
Step 2: timeline(anchor=<first_observation_id>, depth_after=10)
→ See the full development timeline
Step 3: get_observations(ids=[<key_milestones>])
→ Deep dive on critical implementation points
Scenario: Review refactoring patterns
Step 1: search(type="refactor", limit=10, orderBy="date_desc")
→ Recent refactoring work
Step 2: get_observations(ids=[<interesting_ids>])
→ Study the patterns and approaches used
Scenario: Restore context after time away from project
Step 1: search(query="project-name", limit=10, orderBy="date_desc")
→ See recent work
Step 2: timeline(anchor=<most_recent_id>, depth_before=10)
→ Understand what led to current state
Step 3: get_observations(ids=[<critical_observations>])
→ Refresh memory on key decisions
The query parameter supports SQLite FTS5 full-text search syntax:
query="authentication AND JWT" # Both terms must appear
query="OAuth OR JWT" # Either term can appear
query="security NOT deprecated" # Exclude deprecated items
query='"database migration"' # Exact phrase match
query="title:authentication" # Search in title only
query="content:database" # Search in content only
query="concepts:security" # Search in concepts only
query='"user auth" AND (JWT OR session) NOT deprecated'
| Operation | Tokens per Result |
|---|---|
| search (index) | 50-100 |
| timeline (per observation) | 100-200 |
| get_observations (full details) | 500-1,000 |
Example Comparison:
Inefficient:
# Fetching 20 full observations upfront: 10,000-20,000 tokens
get_observations(ids=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20])
Efficient:
# Search index: ~1,000 tokens
search(query="bug fix", limit=20)
# Review IDs, identify 3 relevant observations
# Fetch only relevant: ~1,500-3,000 tokens
get_observations(ids=[5, 12, 18])
# Total: 2,500-4,000 tokens (vs 10,000-20,000)
search(
query="performance optimization",
dateStart="2025-10-01",
dateEnd="2025-10-31"
)
For observations of multiple types, make multiple searches or use broader query:
search(query="database", type="bugfix", limit=10)
search(query="database", type="feature", limit=10)
search(query="API", project="my-app", limit=15)
# First page
search(query="refactor", limit=10, offset=0)
# Second page
search(query="refactor", limit=10, offset=10)
# Third page
search(query="refactor", limit=10, offset=20)
All observations include rich metadata:
Broaden your search:
# Too specific
search(query="JWT authentication implementation with RS256")
# Better
search(query="authentication")
Check database has data:
curl "http://localhost:37777/api/search?query=test"
Try without filters:
# Remove type/date filters to see if data exists
search(query="your-search-term")
Error: "Observation IDs not found: [123, 456]"
Causes:
project parameter)Solution:
# Verify IDs exist
search(query="<related-search>")
# Use correct project filter
get_observations(ids=[123, 456], project="correct-project-name")
Error: Response exceeds token limits
Solution: Use the 3-layer workflow to reduce upfront costs:
# Instead of fetching 50 full observations:
# get_observations(ids=[1,2,3,...,50]) # 25,000-50,000 tokens!
# Do this:
search(query="<your-query>", limit=50) # ~2,500-5,000 tokens
# Review index, identify 5 relevant observations
get_observations(ids=[<5-most-relevant>]) # ~2,500-5,000 tokens
# Total: 5,000-10,000 tokens (50-80% savings)
If searches seem slow:
Architecture: MCP tools are a thin wrapper over the Worker HTTP API (localhost:37777). The MCP server translates tool calls into HTTP requests to the worker service, which handles all business logic, database queries, and Chroma vector search.
MCP Server: Located at ~/.claude/plugins/marketplaces/thedotmack/plugin/scripts/mcp-server.cjs
Worker Service: Express API on port 37777, managed by Bun
Database: SQLite FTS5 full-text search on ~/.claude-mem/claude-mem.db
Vector Search: Chroma embeddings for semantic search (underlying implementation)