Context Engineering
This page covers advanced usage patterns and customization techniques for developers who want to extend mcp-automem or deeply customize its behavior with a focus on context engineering — designing prompts and integration patterns that leverage persistent memory effectively.
For basic setup and configuration, see Getting Started. For platform-specific integration guides, see the Platform Integration Guides. For standard memory operations, see the Memory Operations reference.
Memory Content Size Governance
Section titled “Memory Content Size Governance”The system implements two-tier content size limits to prevent embedding quality degradation.
Implementation in src/mcp-surface.ts:1043-1079 within the store_memory tool handler:
- Target: 150–300 characters (optimal for embeddings)
- Soft limit: 500 characters (passes with warning)
- Hard limit: 2000 characters (immediate rejection)
Rationale: Vector embeddings lose quality with overly long text. The 500-character soft limit signals to the backend that summarization may be beneficial, while the 2000-character hard limit prevents storage of entire code files or documentation.
Importance Level Guidelines and Memory Types
Section titled “Importance Level Guidelines and Memory Types”Memory Type Classification
Section titled “Memory Type Classification”The system supports seven memory types with distinct semantic meanings:
| Type | Usage | Importance Range | Example |
|---|---|---|---|
Decision | Strategic/technical decisions | 0.85–0.95 | ”Chose PostgreSQL over MongoDB for ACID compliance” |
Pattern | Recurring approaches | 0.70–0.85 | ”Using early returns for validation reduces nesting” |
Insight | Key learnings, resolutions | 0.75–0.85 | ”Auth timeout caused by missing retry logic” |
Preference | User/team preferences | 0.75–0.90 | ”User prefers 2-space indents with single quotes” |
Style | Code style, formatting | 0.60–0.80 | ”Always wrap database calls with timeout logging” |
Habit | Regular behaviors | 0.50–0.70 | ”Deploy to staging before production” |
Context | General information | 0.50–0.70 | ”Added JWT authentication system” |
Type vs Importance: The type field enables semantic filtering (e.g., recall only Decision memories), while importance controls relevance ranking and decay. Corrections to AI outputs should always use importance: 0.9 as they represent strong style signals.
Importance Scoring Strategy
Section titled “Importance Scoring Strategy”Philosophy: High importance scores (0.9+) are reserved for memories that should persist indefinitely and rank highly in recall. Medium scores (0.7–0.8) indicate useful patterns that should survive for months. Low scores (< 0.3) signal the memory system to let them naturally decay.
Tagging Conventions and Namespaces
Section titled “Tagging Conventions and Namespaces”Project-Specific vs Personal Tagging
Section titled “Project-Specific vs Personal Tagging”Rationale: Project tags (my-app, authentication, etc.) enable precise filtering for technical work. The personal tag creates a separate namespace for cross-project memories like user preferences, ensuring they aren’t drowned out by high-importance technical memories during recall.
Tag matching modes:
tag_mode: "any"(default) — Matches memories with ANY of the provided tags (OR logic)tag_mode: "all"— Requires ALL tags to be present (AND logic)tag_match: "prefix"(default for ranked recall) — Matches a tag and every tag below it. The service splits stored tags on:and/, sotags: ["entity:people"]matchesentity:people:alice. There is no*wildcard. Use it for the server-injectedentity:*tags, not for your own namespaces.
Relationship Types and Association Patterns
Section titled “Relationship Types and Association Patterns”11 Authorable Relationship Types
Section titled “11 Authorable Relationship Types”The associate_memories tool supports 11 authorable relationship types defined in the AutoMem service:
| Type | Semantic Meaning | Strength Range | Use Case |
|---|---|---|---|
RELATES_TO | General connection | 0.5–0.8 | Default association for related concepts |
LEADS_TO | Causal progression | 0.7–0.9 | Bug → Solution, Problem → Fix |
OCCURRED_BEFORE | Temporal sequence | 0.6–0.8 | Sequential work, chronology |
PREFERS_OVER | Explicit preference | 0.8–0.95 | ”Chose A instead of B” decisions |
EXEMPLIFIES | Concrete example | 0.7–0.9 | Pattern → Implementation example |
CONTRADICTS | Conflicting info | 0.7–0.9 | New approach vs old approach |
REINFORCES | Supporting evidence | 0.7–0.9 | Validation, confirmation |
INVALIDATED_BY | Superseded info | 0.8–0.95 | Correction → Old memory |
EVOLVED_INTO | Knowledge progression | 0.8–0.95 | Decision update, iteration |
DERIVED_FROM | Source relationship | 0.7–0.9 | Implementation → Original decision |
PART_OF | Hierarchical structure | 0.6–0.8 | Component → System |
Association Creation Patterns
Section titled “Association Creation Patterns”Pattern: User Corrections
// 1. Store correction with high importancestore_memory({ content: "User prefers snake_case for Python variable names", type: "Preference", importance: 0.9, tags: ["my-project", "preference", "python"]})
// 2. Find old preferencerecall_memory({ query: "Python variable naming style", tags: ["preference"] })
// 3. Link to superseded memoryassociate_memories({ memory1_id: "<new_id>", memory2_id: "<old_id>", type: "INVALIDATED_BY", strength: 0.9})Pattern: Bug Fixes
// Link fix to the bug report to build a problem-solution chainassociate_memories({ memory1_id: "<fix_memory_id>", memory2_id: "<bug_memory_id>", type: "LEADS_TO", strength: 0.85})Pattern: Architecture Decisions
// Link decision to alternatives consideredassociate_memories({ memory1_id: "<chosen_option_id>", memory2_id: "<rejected_option_id>", type: "PREFERS_OVER", strength: 0.9})Advanced Recall Strategies
Section titled “Advanced Recall Strategies”Multi-hop Reasoning with Entity Expansion
Section titled “Multi-hop Reasoning with Entity Expansion”Entity expansion enables multi-hop graph traversal for complex queries:
API parameters (exposed in src/mcp-surface.ts:373-418):
expand_entities: true— Enable multi-hop entity expansionexpand_relations: true— Follow graph relationships from seed resultsexpand_min_importance: 0.5— Filter expanded results by importance thresholdexpand_min_strength: 0.3— Only follow associations above strength thresholdexpansion_limit: 25— Max expanded memories to includerelation_limit: 5— Max relationships to follow per seed result
{ "query": "authentication issues we've had", "expand_entities": true, "expand_relations": true, "expand_min_importance": 0.5, "expansion_limit": 20}Context-Aware Coding Recall
Section titled “Context-Aware Coding Recall”Context hints boost relevant memories for coding tasks:
{ "query": "error handling patterns", "language": "python", "context_types": ["Pattern", "Insight"], "tags": ["my-service", "backend"]}Backend behavior: These parameters influence the scoring algorithm in the AutoMem service, boosting memories that match the language, file path patterns, or specified types/tags.
Parallel Recall for Comprehensive Context
Section titled “Parallel Recall for Comprehensive Context”Execute multiple recall strategies simultaneously:
// Phase 1: stable preferencesrecall_memory({ tags: ["preference"], limit: 10 })
// Phase 2: project context (semantic + temporal)recall_memory({ queries: ["current task", "recent decisions"], tags: ["my-project"], time_query: "last 14 days", limit: 15})Optimization: Pass queries to run several searches in one call. AutoMemClient.recallMemory() sends each entry as a repeated queries parameter, and the AutoMem service runs the queries, then merges and deduplicates the results server-side (dedup_removed in the response counts the duplicates dropped).
Template System for Custom Integrations
Section titled “Template System for Custom Integrations”Variable Resolution
Section titled “Variable Resolution”Templates support variable substitution for platform-specific customization:
| Variable | Resolution | Example Value |
|---|---|---|
{{PROJECT_NAME}} | From package.json, git remote, or directory name | my-api-service |
{{MCP_TOOL_PREFIX}} | Cursor installer only: mcp_<server name>_, with non-identifier characters in the server name replaced by _ | mcp_memory_ |
{{MCP_SERVER_NAME}} | Cursor installer only: the AutoMem server name found in ~/.cursor/mcp.json, or memory if none is found | memory |
{{HERMES_MODE_RULES}} | Hermes installer only: the rules section for the install mode (--mode mcp, provider, or both; default mcp), rendered by renderHermesModeRules() | ## MCP-only mode section |
Implementation: Template substitution is host-specific. The Codex, Grok, Hermes, and Cursor installers share replaceTemplateVars() in src/cli/host-toolkit.ts. A handler substitutes only the variables it passes: Codex passes {{PROJECT_NAME}} alone (src/cli/codex.ts:34-36), the Hermes installer also passes {{HERMES_MODE_RULES}} (src/cli/hermes.ts:249-252), and the Cursor installer also passes {{MCP_TOOL_PREFIX}} and {{MCP_SERVER_NAME}} (src/cli/cursor.ts:39-43).
Building a New Platform Integration
Section titled “Building a New Platform Integration”To add support for a new MCP-compatible platform:
- Create template directory:
templates/[platform-name]/ - Add configuration template: Platform-specific MCP server config format
- Create rule/instruction file: Memory-first instructions adapted to platform conventions
- Implement CLI command: Add installer in
src/cli/[platform].ts, register the client insrc/cli/clients.ts(AGENT_CLIENTS; the CLI’s known commands and the uninstall platforms are derived from it), add its dispatch branch insrc/index.ts, and wire it into the guided installer insrc/cli/install.ts - Update documentation: Add section to
INSTALLATION.md
Example structure:
templates/myplatform/├── README.md # Setup guide├── config.template # MCP server config└── memory-rules.template # Platform instructionsTemplate best practices based on existing templates:
- Include version comment —
<!-- automem-template-version: 1.0.0 -->enables migration detection - Use platform-specific tool naming — Show exact tool prefix format (e.g.,
mcp__memory__vsmcp_memory_) - Provide concrete examples — Don’t just describe tools, show actual usage with project variables
- Explain importance scoring — Critical: 0.9+, Important: 0.7–0.9, Standard: 0.5–0.7
- Document tagging conventions — Bare tags for project name, category, and language; no platform or date-stamped tags
- Include content size guidelines — Target 150–300 chars, max 500 chars, hard limit 2000 chars
- Show relationship types — Explain all 11 association types with examples
- Add troubleshooting hints — What to do if recall fails, service unreachable, etc.
Non-MCP and Multi-Mode Integrations
Section titled “Non-MCP and Multi-Mode Integrations”OpenClaw Integration Approaches
Section titled “OpenClaw Integration Approaches”OpenClaw now supports three integration modes: plugin (recommended), MCP via mcporter, and legacy skill using direct curl. The plugin mode uses a native OpenClaw plugin with typed AutoMem tools and a built-in auto-recall hook. MCP mode routes through mcporter for the same typed tools. The legacy skill mode still uses direct HTTP calls via curl.
Why multiple modes: OpenClaw’s architecture makes both native plugins and skill files viable. The plugin approach is simplest for new installs, while MCP mode suits users who prefer the mcporter tool layer. Legacy curl mode remains available for backward compatibility.
Benefits of plugin mode over curl:
- Typed tool interface instead of raw HTTP construction
- Built-in auto-recall with configurable exposure (
dm-only,all,off) - No dependency on bash/curl availability
- Cleaner error handling through the plugin system
AutoMemClient HTTP Implementation
Section titled “AutoMemClient HTTP Implementation”The AutoMemClient class in src/automem-client.ts wraps all AutoMem HTTP API calls:
Key features:
- Authentication: Adds
Authorization: Bearerheader fromAUTOMEM_API_KEY - Timeout: 25-second request timeout to prevent hung connections
- Retry logic: Exponential backoff (500ms, 1s, 2s) for transient failures
- Error handling: Structured error responses with HTTP status codes
HTTP Endpoint Reference
| Method | Endpoint | Request Body | Response | Client Method |
|---|---|---|---|---|
| POST | /memory | {content, tags, importance, embedding?, metadata?, timestamp?} | {status, memory_id, stored_at, type, confidence, qdrant, ...} | storeMemory() |
| GET | /recall?query=... | N/A (query params) | {results[], count, dedup_removed?, ...} | recallMemory() |
| POST | /associate | {memory1_id, memory2_id, type, strength} | {status, message, relation_type, strength, ...} | associateMemories() |
| PATCH | /memory/:id | {content?, tags?, importance?, metadata?, ...} | {status, memory_id} | updateMemory() |
| DELETE | /memory/:id | N/A | {status, memory_id} | deleteMemory() |
| GET | /memory/by-tag?tags=... | N/A | {memories[], count, limit, offset, has_more, ...} | recallMemory({ tags, exhaustive: true }) |
| GET | /health | N/A | {status, falkordb, qdrant, graph, timestamp} | checkHealth() |
Query parameter encoding:
- Arrays (
tags,queries) use repeated parameters:?tags=project&tags=auth - Single values use standard encoding:
?query=decisions&limit=10 - Boolean flags:
?expand_entities=true&expand_relations=false - Embedding vectors: comma-separated floats
?embedding=0.1,0.2,0.3,...
Configuration Resolution Priority
Section titled “Configuration Resolution Priority”Environment variables are resolved in this order:
- Constructor arguments (highest priority — programmatic usage)
- Process environment variables (
process.env) .envfile in current directory.envfile in home directory
Environment variables:
AUTOMEM_API_URL— AutoMem service URLAUTOMEM_API_KEYorAUTOMEM_API_TOKEN— Authentication token (both accepted)
Platform-specific config locations:
- Cursor:
~/.cursor/mcp.jsonwithenvobject - Claude Desktop:
claude_desktop_config.jsonwithenvobject - Claude Code:
~/.claude.jsonwith MCP server env - Codex:
~/.codex/config.tomlwith[mcp_servers.memory.env]section
MCP Protocol Implementation Details
Section titled “MCP Protocol Implementation Details”The MCP server is created by createAutoMemMcpServer() in src/mcp-surface.ts using the @modelcontextprotocol/sdk library. src/index.ts is the CLI and stdio entry point: it creates that server and connects the stdio transport.
Tool registration in the tools array starting at src/mcp-surface.ts:85:
- Each tool defines
inputSchema(JSON Schema for parameters) - Each tool defines
outputSchema(JSON Schema for response) - Tools include
annotationsfor MCP hints:readOnlyHint: Tool doesn’t modify statedestructiveHint: Tool may perform destructive updates (meaningful only whenreadOnlyHintis false)idempotentHint: Repeated calls safe
Tool Annotations
| Field | Meaning | Example Usage |
|---|---|---|
readOnlyHint | Tool doesn’t modify state | recall_memory, check_database_health |
destructiveHint | Tool may perform destructive updates (meaningful only when readOnlyHint is false) | delete_memory |
idempotentHint | Multiple calls with same args produce same result | update_memory, associate_memories |
openWorldHint | Results may reference external entities | false on every tool (memory IDs are self-contained) |
Important implementation details:
- Server mode detection — Empty
process.argv[2]triggers server mode - Console redirection — All
console.logcalls redirected to stderr to prevent stdout pollution - Quiet dotenv — Environment loading silenced to prevent debug output
- EPIPE handling — Graceful exit on broken pipe (platform disconnects)
- Process tagging — Optional
AUTOMEM_PROCESS_TAGfor safe process management
Best Practices for Custom Integrations
Section titled “Best Practices for Custom Integrations”1. Configuration Management
Section titled “1. Configuration Management”Use environment variables for credentials. Support multiple configuration sources (priority order):
- Command-line arguments (highest priority)
- Environment variables
- Configuration files (
.env, platform-specific) - Defaults (lowest priority)
2. Error Handling
Section titled “2. Error Handling”Handle service unavailability gracefully:
try { const results = await client.recallMemory({ query: "current task" }); // use results} catch (error) { console.error("Memory recall failed, continuing without context:", error); // proceed without memory context}Respect retry logic — AutoMemClient already retries 5xx errors. Don’t add another retry layer on top.
3. Content Guidelines
Section titled “3. Content Guidelines”Enforce size limits in your integration:
- Target: 150–300 characters
- Soft limit: 500 characters (warn user)
- Hard limit: 2000 characters (reject before calling API)
Recommend tagging conventions:
- Always include project/workspace identifier
- Do not add date-stamped tags (such as
2025-01); use thetimestampfield, ort_validandt_invalidfor facts with a shelf life - Use bare tags with no namespace prefixes:
auth, notproject/authorauth/login - Include type tags:
decision,pattern,bugfix,preference
4. Recall Optimization
Section titled “4. Recall Optimization”Start simple, expand as needed:
// Simple: start with just project tagrecall_memory({ tags: ["my-project"], limit: 10 })
// If insufficient, add semantic searchrecall_memory({ query: "auth issues", tags: ["my-project"], limit: 10 })
// If still insufficient, add graph expansionrecall_memory({ query: "auth issues", expand_entities: true, expansion_limit: 20 })5. Testing Custom Integrations
Section titled “5. Testing Custom Integrations”Health check on startup:
const health = await client.checkHealth();if (health.status !== "healthy") { console.warn("AutoMem service degraded:", health);}Test memory round-trip:
const stored = await client.storeMemory({ content: "test memory", tags: ["test"], importance: 0.5 });const recalled = await client.recallMemory({ query: "test memory", tags: ["test"] });assert(recalled.results.some(r => r.id === stored.memory_id));await client.deleteMemory(stored.memory_id);Migration from Existing Systems
Section titled “Migration from Existing Systems”From Manual Memory Management
Section titled “From Manual Memory Management”If your platform currently uses manual note-taking or file-based memory:
- Export existing content as JSON objects matching
{content, tags, importance}schema - Batch import via sequential
storeMemory()calls with appropriate types and importance scores - Create associations for related memories to preserve knowledge graph structure
From Other MCP Memory Servers
Section titled “From Other MCP Memory Servers”If migrating from a different MCP memory implementation:
Common tool name mappings:
remember→store_memorysearchorfind→recall_memoryforget→delete_memorylinkorrelate→associate_memories
Troubleshooting
Section titled “Troubleshooting”Common Integration Issues
Section titled “Common Integration Issues”| Issue | Symptoms | Solution |
|---|---|---|
| Server not starting | Platform shows “MCP server failed to start” | Check AUTOMEM_API_URL in server env config. Verify no CLI arguments passed (would trigger CLI mode instead of server mode). |
| Tools not appearing | Platform doesn’t list memory tools | Verify server name in platform config. Check if platform requires tool allowlist. Restart platform after config changes. |
| Authentication failures | 401/403 errors | Set AUTOMEM_API_KEY in server environment variables, not client-side. Verify API key format matches backend requirements. |
| Recall returns empty | Queries return 0 results despite stored memories | Check tags match exactly. Verify time filters aren’t too restrictive. Try query without tags first. Check backend health. |
| Content too large errors | Store operations rejected | Enforce 500-char soft limit, 2000-char hard limit before calling API. Split long content into multiple memories with associations. |
| Timeout errors | Operations fail after ~25 seconds | Reduce limit parameter in recall queries. Check backend performance. Consider recall_memory({ tags: [...], exhaustive: true }) (paginated tag enumeration) instead of semantic search for simple tag queries. |
Debugging Techniques
Section titled “Debugging Techniques”Enable debug logging:
AUTOMEM_LOG_LEVEL=debug npx @verygoodplugins/mcp-automemmcp-automem reads AUTOMEM_LOG_LEVEL, not DEBUG. At debug it adds only an AutoMem MCP server running line on stderr at startup, plus the process title when AUTOMEM_PROCESS_TAG is set. It does not trace individual requests.
Test backend directly:
curl -i -H "Authorization: Bearer $AUTOMEM_API_KEY" "$AUTOMEM_API_URL/recall?limit=1"A 401 Unauthorized response means the service rejected the key. Do not use /health for this: it skips the API token check, so it only shows that the service is reachable.
Preview what the Cursor installer writes:
npx @verygoodplugins/mcp-automem cursor --dry-run--dry-run prints a [DRY RUN] Would write: <path> line for each file and writes nothing. It does not print the rendered templates, and there is no --verbose flag (the installer ignores unknown flags). To check variable substitution, run the installer and open the generated .cursor/rules/automem.mdc.