skills/mem0-cli/references/workflows.md
Practical recipes for using the mem0 CLI in scripts, pipelines, and agent loops.
The CLI reads from stdin when no text argument is provided and input is piped (not a TTY). This works with add, search, and update.
Stdin detection method:
not sys.stdin.isatty()!process.stdin.isTTYecho "I prefer dark mode" | mem0 add --user-id alice
cat <<EOF | mem0 add --user-id alice
The user prefers dark mode in all applications.
They also like monospace fonts for code editing.
EOF
git log --oneline -5 | mem0 add --user-id ci-bot --metadata '{"source":"git"}'
echo "preferences" | mem0 search --user-id alice
echo "Updated: prefers dark mode AND high contrast" | mem0 update abc-123-def-456
Use mem0 import to bulk-load memories from a JSON file.
mem0 import memories.json --user-id alice
The file should be a JSON array where each item has a memory, text, or content field:
[
{ "memory": "Prefers dark mode" },
{ "text": "Allergic to nuts", "metadata": { "source": "intake-form" } },
{ "content": "Uses VS Code", "user_id": "bob" }
]
CLI-provided --user-id overrides per-item user_id values.
mem0 import data.json --user-id alice -o json
Output:
{
"status": "success",
"command": "import",
"data": { "added": 42, "failed": 0, "duration_s": 3.14 },
"duration_ms": 3140
}
Use --json or --agent to get structured JSON output suitable for LLM tool calling or agent frameworks. Spinners and progress always go to stderr, keeping stdout clean.
mem0 search "preferences" --user-id alice --agent
Output (stdout):
{
"status": "success",
"command": "search",
"duration_ms": 187,
"scope": { "user_id": "alice" },
"count": 2,
"error": null,
"data": [
{ "id": "mem-abc", "memory": "User prefers dark mode", "score": 0.95, "created_at": "2025-01-15T10:00:00Z", "categories": ["preferences"] },
{ "id": "mem-def", "memory": "User likes monospace fonts", "score": 0.82, "created_at": "2025-01-15T10:01:00Z", "categories": ["preferences"] }
]
}
mem0 add "Uses Python 3.12" --user-id alice --json
Errors also return valid JSON with "status": "error":
mem0 search "test" --user-id alice --api-key invalid --agent
Output:
{
"status": "error",
"command": "search",
"error": "Authentication failed. Your API key may be invalid or expired.",
"data": null
}
Use --output json (or -o json) for raw JSON output, then pipe to jq for processing.
mem0 list --user-id alice --output json | jq '.[] | .memory'
mem0 list --user-id alice -o json | jq '.[].id'
mem0 list --user-id alice -o json | jq 'length'
mem0 list --user-id alice -o json | jq '[.[] | select(.categories[]? == "preferences")]'
mem0 search "tools" --user-id alice -o json | jq '.[] | {memory, score}'
# Get IDs, then delete each one
mem0 list --user-id alice -o json | jq -r '.[].id' | while read id; do
mem0 delete "$id" --force
done
while IFS= read -r line; do
mem0 add "$line" --user-id alice
done < memories.txt
mem0 list --user-id alice -o json | jq -r '.[].memory' | while IFS= read -r mem; do
mem0 add "$mem" --user-id bob
done
mem0 list --user-id alice -o json > alice_memories.json
page=1
while true; do
result=$(mem0 list --user-id alice -o json --page "$page" --page-size 100)
count=$(echo "$result" | jq 'length')
if [ "$count" -eq 0 ]; then
break
fi
echo "$result"
page=$((page + 1))
done
mem0 add "Build #${BUILD_NUMBER} deployed ${APP_VERSION} to ${ENVIRONMENT} at $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--agent-id "ci-bot" \
--metadata "{\"build_number\":\"${BUILD_NUMBER}\",\"version\":\"${APP_VERSION}\",\"env\":\"${ENVIRONMENT}\"}"
mem0 search "deployment to production" --agent-id ci-bot -o json -k 10
if mem0 status -o json | jq -e '.data.connected' > /dev/null 2>&1; then
echo "mem0 is connected"
else
echo "mem0 connection failed" >&2
exit 1
fi
mem0 init --api-key "$MEM0_API_KEY" --user-id ci-bot --force
Or simply use the environment variable (no init needed):
export MEM0_API_KEY="$MEM0_API_KEY"
mem0 add "CI run started" --user-id ci-bot
test_summary=$(cat test-results.txt | head -20)
mem0 add "$test_summary" --agent-id ci-bot --metadata '{"type":"test-results"}' --categories "ci,testing"
The CLI reads from stdin only when ALL of these conditions are met:
add: no --messages and no --file flag.update: no --metadata flag.This means:
mem0 add --user-id alice in an interactive terminal will NOT hang waiting for input. It will print a usage error.echo "text" | mem0 add --user-id alice will read "text" from stdin.mem0 add "explicit text" --user-id alice will use the explicit text, even if stdin is piped.Reading method:
sys.stdin.read().strip()fs.readFileSync(0, "utf-8").trim()set -e # Exit on error
# This will exit the script if the API key is invalid
mem0 status > /dev/null 2>&1
# Add with error check
if mem0 add "test memory" --user-id alice 2>/dev/null; then
echo "Memory added successfully"
else
echo "Failed to add memory" >&2
exit 1
fi
# Use agent mode to get structured output
result=$(mem0 add "new fact" --user-id alice --agent 2>/dev/null)
memory_id=$(echo "$result" | jq -r '.data[0].id // empty')
if [ -n "$memory_id" ]; then
echo "Created memory: $memory_id"
fi
# Only add if search returns no results
count=$(mem0 search "dark mode" --user-id alice --agent 2>/dev/null | jq '.count // 0')
if [ "$count" -eq 0 ]; then
mem0 add "User prefers dark mode" --user-id alice
fi
# Suppress all output except errors
mem0 add "background note" --user-id alice --output quiet 2>/dev/null
mem0 delete --all --user-id temp-user --force --output quiet 2>/dev/null
export MEM0_USER_ID="alice"
export MEM0_API_KEY="m0-xxx"
# All commands now default to user alice, no --user-id needed
mem0 add "prefers dark mode"
mem0 search "preferences"
mem0 list
The CLI uses a 30-second timeout for all API requests. For long-running scripts, handle timeouts:
if ! mem0 search "query" --user-id alice -o json 2>/dev/null; then
echo "Request failed or timed out" >&2
fi
Memories are processed asynchronously after mem0 add. If you need to search for a newly added memory immediately, add a short delay:
mem0 add "new preference" --user-id alice
sleep 3
mem0 search "new preference" --user-id alice
Or use the event system to poll for completion:
# Add and capture event ID from agent output
result=$(mem0 add "new preference" --user-id alice --agent 2>/dev/null)
event_id=$(echo "$result" | jq -r '.data[0].event_id // empty')
if [ -n "$event_id" ]; then
# Poll until processing completes
while true; do
status=$(mem0 event status "$event_id" --agent 2>/dev/null | jq -r '.data.status')
if [ "$status" = "SUCCEEDED" ] || [ "$status" = "FAILED" ]; then
break
fi
sleep 1
done
fi
For AI agents managing memories across multiple users:
#!/bin/bash
# agent_memory.sh -- manage memories for the current conversation
USER_ID="$1"
ACTION="$2"
shift 2
case "$ACTION" in
recall)
mem0 search "$*" --user-id "$USER_ID" --agent 2>/dev/null
;;
remember)
mem0 add "$*" --user-id "$USER_ID" --agent 2>/dev/null
;;
forget)
mem0 delete --all --user-id "$USER_ID" --force --agent 2>/dev/null
;;
history)
mem0 list --user-id "$USER_ID" --agent 2>/dev/null
;;
*)
echo '{"status":"error","error":"Unknown action: '"$ACTION"'"}' >&2
exit 1
;;
esac
Usage:
./agent_memory.sh alice recall "dietary preferences"
./agent_memory.sh alice remember "allergic to shellfish"
./agent_memory.sh alice history