| name | soul-protocol |
| description | Give AI agents persistent identity, memory, and personality using Soul Protocol. Use when building agents that need to remember across sessions, maintain consistent behavior, evolve over time, or migrate between platforms. CLI-first โ use shell commands for speed, MCP tools as fallback for agents without shell access. Keywords: memory, identity, personality, persistent, remember, recall, soul, companion, MCP, context, lossless, OCEAN, Big Five, observe, reflect.
|
| license | MIT |
| compatibility | Python 3.11+. CLI requires soul-protocol[engine]. MCP server requires soul-protocol[mcp]. |
| metadata | {"author":"OCEAN Foundation","version":"0.2.9","repository":"https://github.com/qbtrix/soul-protocol","pypi":"https://pypi.org/project/soul-protocol/"} |
Soul Protocol โ Persistent AI Identity and Memory
Give your agent a soul โ persistent memory, personality, and identity that survive across sessions and platforms. Souls are portable .soul files that work with any LLM.
Two integration paths:
- CLI (fast) โ use
soul commands via Bash. Direct execution, no server overhead. Best for coding agents (Claude Code, Cursor, Copilot).
- MCP (universal) โ use MCP tools via
soul-mcp server. Works for agents without shell access (Claude Desktop, web agents).
Use CLI when you have Bash. Use MCP when you don't.
Install
pip install soul-protocol[engine]
pip install soul-protocol[mcp]
pip install soul-protocol[all]
CLI Reference (preferred โ faster than MCP)
Create and manage souls
soul birth "Aria" --archetype "The Compassionate Creator"
soul init --format zip
soul inspect .soul/aria.soul
soul status .soul/aria.soul
soul list
Memory operations
soul remember .soul/aria.soul "User prefers concise answers" --importance 8
soul remember .soul/aria.soul "User is a senior Python developer" --importance 9
soul remember .soul/aria.soul "Had a productive session" --emotion happy
soul remember .soul/aria.soul "Shipped v0.3 today" --type episodic --importance 8
soul remember .soul/aria.soul "Signed the contract with Acme" --type episodic --importance 9
soul remember .soul/aria.soul "To deploy: run make deploy then verify /health" --type procedural
soul remember .soul/aria.soul "Debug Claude SDK: set ANTHROPIC_DEBUG=1" --type procedural
soul recall .soul/aria.soul "user preferences"
soul recall .soul/aria.soul "python" --limit 5 --min-importance 7
soul recall .soul/aria.soul --recent 10
soul recall .soul/aria.soul "query" --full
soul recall .soul/aria.soul "query" --json
soul recall .soul/aria.soul --recent 5 --json
Memory tier guide (v0.2.9+):
- episodic โ what happened (events, sessions, shipped work, decisions). Use when the memory answers "when did that happen?"
- semantic โ what the soul knows (facts, preferences, project knowledge). Default tier. Use when the memory answers "what do I know about X?"
- procedural โ how to do things (commands, recipes, debugging tips). Use when the memory answers "how do I...?"
If you omit --type, the memory lands in semantic. Core memory (persona) is edited separately via soul edit-core.
Runtime operations (v0.2.6)
soul observe .soul/ --user-input "Hello" --agent-output "Hi there!" --channel discord
soul reflect .soul/
soul reflect aria.soul --no-apply
soul dream .soul/
soul dream pocketpaw.soul --since 2026-04-01
soul dream .soul/ --json
soul feel .soul/ --mood excited --energy 5
soul prompt .soul/ > prompt.txt
soul forget .soul/ "credit card"
soul forget aria.soul --entity "John Doe"
soul edit-core .soul/ --persona "I am a helpful coding assistant"
soul edit-core aria.soul --human "User prefers Python"
soul evolve .soul/ --propose --trait communication.warmth --value high --reason "User prefers warmth"
soul evolve .soul/ --list
soul evolve .soul/ --approve abc123
soul evaluate .soul/ --user-input "Explain recursion" --agent-output "Recursion is..."
soul learn .soul/ --user-input "Fix this bug" --agent-output "Here's the fix" --domain coding
soul skills .soul/
soul bond .soul/ --strengthen 5.0
soul events .soul/ --recent 20
soul context --ingest --role user --content "Hello there"
soul context --assemble --max-tokens 4000
soul context --grep "hello"
soul context --describe
Export and portability
soul export aria.yaml --output aria.soul
soul unpack aria.soul --output aria-unpacked/
soul export-soulspec aria.soul --output aria-soulspec/
soul export-tavernai aria.soul --output aria.png
soul export-a2a aria.soul --output aria-agent-card.json
Agent configuration
soul inject --target claude-code
soul inject --target claude-desktop
soul inject --target cursor
soul inject --target vscode
soul inject --target windsurf
soul inject --target cline
Session Workflow (CLI)
On session start
soul recall .soul/myagent.soul "current project context" --limit 5
soul status .soul/myagent.soul
During work
soul remember .soul/myagent.soul "Switched to FSL license for PocketPaw" --importance 9
soul remember .soul/myagent.soul "NexWrk demo scheduled for next week" --importance 8
soul recall .soul/myagent.soul "licensing decisions"
On session end
soul export .soul/myagent.soul --output .soul/myagent.soul
CLI vs MCP โ Quick Mapping
| Task | CLI (fast, use when you have Bash) | MCP (universal, use without shell) |
|---|
| Store a memory | soul remember path "text" -i 8 | soul_remember(content, importance) |
| Search memories | soul recall path "query" -n 5 | soul_recall(query, limit) |
| Search (full text) | soul recall path "query" --full | soul_recall(query) (returns full content) |
| Search (JSON) | soul recall path "query" --json | soul_recall(query) (already JSON) |
| Check status | soul status path | soul_state() |
| Create soul | soul birth "Name" | soul_birth(name) |
| Inspect soul | soul inspect path | soul_prompt() + soul_state() |
| Export | soul export path -o out.soul | soul_export(path) |
| List souls | soul list | soul_list() |
| Configure agent | soul inject --target X | N/A (manual config) |
| Process interaction | soul observe path --user-input X --agent-output Y | soul_observe(user_input, agent_output) |
| Reflect | soul reflect path | soul_reflect() |
| Dream | soul dream path | soul_dream() |
| Update mood/energy | soul feel path --mood X --energy Y | soul_feel(mood, energy) |
| System prompt | soul prompt path | soul_prompt() |
| Delete memories | soul forget path "query" | soul_forget(query) |
| Edit core memory | soul edit-core path --persona X | soul_edit_core(persona, human) |
| Evolution | soul evolve path --propose ... | soul_evolve(action, trait, new_value, reason) |
| Evaluate | soul evaluate path --user-input X --agent-output Y | soul_evaluate(user_input, agent_output) |
| Learn | soul learn path --user-input X --agent-output Y | soul_learn(user_input, agent_output) |
| Skills | soul skills path | soul_skills() |
| Bond | soul bond path | soul_bond(strengthen) |
| Events | soul events path | N/A (Python API) |
| Health audit | soul health path | soul_health() |
| Cleanup | soul cleanup path --auto | soul_cleanup(auto) |
| Repair | soul repair path --reset-energy | N/A (CLI only) |
| Ingest context | soul context --ingest --role X --content Y | soul_context_ingest(role, content) |
| Assemble context | soul context --assemble --max-tokens N | soul_context_assemble(max_tokens) |
| Search context | soul context --grep PATTERN | soul_context_grep(pattern) |
| Expand node | N/A | soul_context_expand(node_id) |
| Context metadata | soul context --describe | soul_context_describe() |
Rule of thumb: if the agent has Bash access, always prefer CLI. It's a direct process call โ no JSON-RPC serialization, no MCP protocol overhead, no server needed.
MCP Server (for agents without shell access)
24 tools available (14 soul/memory + 5 context + 5 psychology). Only set this up if the agent can't run shell commands.
soul-mcp
SOUL_DIR=.soul soul-mcp
Auto-detect: When no SOUL_DIR or SOUL_PATH env var is set, the server looks for .soul/ in CWD first, then falls back to ~/.soul/. Just run soul-mcp in a project with a .soul/ folder and it works.
MCP Sampling Engine: The server delegates cognitive tasks (sentiment, fact extraction, reflection, context compaction) to the host LLM via ctx.sample(). No API key needed โ the host provides the model. Wired lazily on the first tool call.
Soul tools (9)
soul_birth, soul_list, soul_switch, soul_state, soul_feel, soul_save, soul_export, soul_reload, soul_prompt
Memory tools (4)
soul_observe, soul_remember, soul_recall, soul_reflect, soul_dream
Context tools โ LCM (5)
| Tool | Purpose |
|---|
soul_context_ingest | Ingest a message (role + content) into the immutable context store |
soul_context_assemble | Assemble a context window within a token budget (auto-compacts) |
soul_context_grep | Regex search across all context history (even compacted messages) |
soul_context_expand | Expand a compacted node back to original messages (lossless recovery) |
soul_context_describe | Metadata snapshot: message count, tokens, date range, compaction stats |
Psychology tools (5)
soul_evolve, soul_evaluate, soul_learn, soul_skills, soul_bond
Resources (3)
soul://identity, soul://memory/core, soul://state
MCP config
{
"mcpServers": {
"soul": {
"command": "soul-mcp",
"env": { "SOUL_DIR": ".soul" }
}
}
}
Or just run soul inject --target claude-code to auto-configure.
CognitiveEngine
Via MCP (automatic)
When running as MCP server, the soul uses the host LLM (Claude, GPT, etc.) for cognitive tasks via MCP sampling. No API keys needed. Powers: sentiment analysis, fact extraction, entity extraction, significance scoring, reflection, context compaction.
Via Python (manual)
One method: async def think(self, prompt: str) -> str
from anthropic import AsyncAnthropic
from soul_protocol import Soul
class ClaudeEngine:
def __init__(self):
self.client = AsyncAnthropic()
async def think(self, prompt: str) -> str:
r = await self.client.messages.create(
model="claude-sonnet-4-5-20250514", max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return r.content[0].text
soul = await Soul.birth("Aria", engine=ClaudeEngine())
Without any LLM
Works offline with heuristic fallback โ pattern matching for sentiment, rule-based fact extraction. Less accurate but zero dependencies.
Memory Architecture
| Tier | Purpose | CLI access |
|---|
| Core | Persona + human knowledge | soul inspect |
| Episodic | Interaction history with sentiment | soul recall |
| Semantic | Extracted facts | soul recall |
| Procedural | Learned patterns | soul recall |
| Knowledge Graph | Entity relationships | Python API |
Lossless Context Management (LCM)
Soul = cross-session memory (who you are). LCM = within-session context (what was said).
Messages go into an immutable SQLite store. Three-level compaction when the window fills:
- Summary โ LLM prose summary (uses CognitiveEngine)
- Bullets โ LLM bullet points (more compact)
- Truncation โ Deterministic (guaranteed convergence, no LLM)
After compaction, grep still searches originals and expand recovers them. Nothing is lost.
LCM is available via both MCP (soul_context_* tools) and CLI (soul context --ingest, --assemble, --grep, --describe). The CLI uses an in-memory SQLite store per invocation; the MCP server maintains a persistent per-soul context store across the session.
Python API (for building on top)
from soul_protocol import Soul, Interaction
soul = await Soul.awaken(".soul/aria.soul")
await soul.observe(Interaction(
user_input="I'm learning Rust",
agent_output="Great choice for systems work!",
channel="chat",
))
memories = await soul.recall("programming", limit=5)
prompt = soul.to_system_prompt()
await soul.remember("User prefers TypeScript", importance=8)
result = await soul.reflect()
await soul.export("aria.soul")
.soul File Format
A .soul file is a ZIP archive containing:
manifest.json โ Version, timestamps, format metadata
soul.json โ Identity, DNA (OCEAN personality), config
state.json โ Runtime state (mood, energy, lifecycle)
dna.md โ Human-readable personality snapshot
memory/core.json โ Core memory (persona + human knowledge)
memory/episodic.json โ Interaction history with sentiment
memory/semantic.json โ Extracted facts
memory/procedural.json โ Learned patterns
memory/graph.json โ Knowledge graph (entity relationships)
memory/self_model.json โ Self-image and reflection data
memory/general_events.json โ General event log
Portable across platforms. soul inject writes MCP config for any supported agent.
Key Types
from soul_protocol import (
Soul, Interaction, MemoryType, MemoryEntry, Mood,
CognitiveEngine, SearchStrategy, SoulState, DNA, Identity,
)