identity-storage-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@identity-storage-mcpstore that my favorite color is blue"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
identity-storage
Portable, auditable long-term memory for AI agents. Runs as a local MCP server backed by a single SQLite file. Agents recall memories through MCP tools; a Stop hook stores session transcripts automatically — no agent discipline required.
Why
Agents like Claude Code are stateless between sessions. identity-storage
gives them a memory that survives restarts and stays fully inspectable — no
ORM, no migration framework, no hidden state. Point sqlite3 at the file and
read everything.
Related MCP server: recollect
Install
The package is not on PyPI yet. Install directly from GitHub:
pip install git+https://github.com/MikSkrzyp/identity-storage-mcp.gitOr run it without installing:
uvx --from git+https://github.com/MikSkrzyp/identity-storage-mcp.git identity-storage-mcpThis installs one console script:
identity-storage-mcp— the MCP server (agent calls tools through it)
Configure Claude Code
1. Add the MCP server
claude mcp add identity-storage -s user -- uvx --from git+https://github.com/MikSkrzyp/identity-storage-mcp identity-storage-mcp2. Add memory instructions to CLAUDE.md
Add this to ~/.claude/CLAUDE.md (global, all projects) or your project's
CLAUDE.md:
# Memory — MANDATORY
identity-storage MCP is connected. Follow these rules EVERY session:
1. SEARCH: Call memory_search when the user references past work or you need
context from previous sessions. Pass the user's prompt as query.
2. STORE: Call memory_store after every non-trivial turn:
- episodic: events/actions (fixed bug, refactored module, user asked for X)
- semantic: durable facts (user preferences, project info, tech stack)
- procedural: how-tos (commands, steps, procedures)
One memory per distinct thing. Skip idle chat.
3. SESSION END: When the user says exit/quit, store anything not yet saved.
Forgetting to store = permanent loss of the session.
Forgetting to search = working blind.Configure opencode
1. Add the MCP server
Add to ~/.config/opencode/opencode.jsonc:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"identity-storage": {
"type": "local",
"command": [
"uvx",
"--from",
"git+https://github.com/MikSkrzyp/identity-storage-mcp",
"identity-storage-mcp"
]
}
}
}2. Add memory instructions to AGENTS.md
Add the same memory instructions (from the Claude Code section above) to
~/.config/opencode/AGENTS.md (global) or your project's AGENTS.md.
Tools
The agent sees three tools, each scoped by memory_type (episodic,
semantic, procedural, personality, emotional):
Tool | Purpose |
| Full-text search via FTS5 — when the user references past work |
| Store a memory with type classification (episodic/semantic/procedural) |
| Browse by type, tags, and time window (newest first) |
See docs/usage.md for the full input/output schemas.
Configuration
Env var | Default | Purpose |
|
| SQLite database file path |
The parent directory is created on first run. The schema is applied idempotently on every start, so pointing at a fresh path is safe.
Audit
The database is a regular SQLite file. Read it while the server runs (WAL mode allows concurrent reads):
sqlite3 ~/.identity-storage/memory.dbSELECT id, created_at, content FROM memory
WHERE type='episodic'
ORDER BY created_at DESC;
SELECT * FROM memory
WHERE EXISTS (SELECT 1 FROM json_each(tags) WHERE value='auth');
SELECT m.*
FROM memory m
JOIN memory_fts f ON f.rowid = m.rowid
WHERE f.content MATCH 'auth bug'
ORDER BY rank;The schema lives in schemas/schema.sql
and is the single source of truth. Run .schema in the sqlite3 CLI to see
exactly what is in the file.
Other clients
Claude Code and opencode are supported. Both use the same MCP server and
the same memory database. For other MCP-compatible clients (Codex, Cursor,
etc.), add the MCP server per their docs and add the memory instructions to
their equivalent of CLAUDE.md (e.g. .cursorrules for Cursor).
Documentation
docs/architecture.md — layers, design decisions, how to add a memory type or a backend
docs/api.md — full API reference
docs/usage.md — install snippets, tool schemas, auditing
docs/development.md — dev setup, commands, conventions
Status
Alpha. The MCP contract and the SQLite schema are stable for the episodic case. Semantic memory, procedural memory, consolidation, and embeddings are planned — see docs/architecture.md for the roadmap shape.
License
MIT
Available Tools
3 toolsmemory_recallA
Browse memories of one type, newest first. Filter by tags and time window. Use for 'what did I do recently' or 'what happened in this session'. Not for per-turn recall — use memory_search for that.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| records | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses that the tool browses memories, returns newest first, and supports filtering. It does not explicitly state it is read-only, but that is implied by 'browse'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no superfluous text. The purpose and guidance are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values are covered. The description provides core usage and differentiation. Missing details on pagination or ordering beyond 'newest first' are minor given schema richness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description mentions 'filter by tags and time window', which adds some context beyond the schema. However, it does not explain the 'limit' or 'memory_type' parameters beyond 'of one type'. With schema description coverage reported as 0%, the description should compensate more.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the verb 'browse' with the resource 'memories of one type' and specifies ordering ('newest first'). It clearly differentiates from the sibling 'memory_search' by stating this tool is for browsing and not for per-turn recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: use for 'what did I do recently' or 'what happened in this session', and a direct exclusion: 'Not for per-turn recall — use memory_search for that.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_searchA
Search past memories by content. Call this when the user references past work ('do you remember', 'last time', 'previously') or when you need context from a previous session. Pass the user's prompt as query. Returns ranked results from FTS5. If empty, no memory is needed for this turn. For browsing by tags or time window, use memory_recall.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| records | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries the burden. It reveals the internal search engine (FTS5) and result interpretation ('If empty, no memory needed'). Could mention that it is read-only, but the description sufficiently conveys search behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each serving a purpose: purpose, when to use, result interpretation, alternative tool. No filler, front-loaded with key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers main use case, alternatives, and result interpretation. However, does not mention the memory_type parameter, which is required and important for correct usage. Output schema exists, so return details are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover all parameters (query, memory_type, limit) but the tool description adds only that the user's prompt should be passed as 'query'. With schema descriptions presumably high, the description adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search past memories by content' and distinguishes from sibling memory_recall by specifying that it is for content search, while memory_recall is for browsing by tags or time window.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to call (user references past work, examples given), what to do with the query ('Pass the user's prompt as query'), and provides a condition for interpreting empty results. Also specifies when not to use and points to alternative memory_recall.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_storeA
Store a memory. You MUST call this after every non-trivial turn. Choose the type based on what you are saving:
episodic: an event that happened — 'fixed the login bug in auth.py', 'user asked for a tic-tac-toe game', 'refactored auth module to use JWT'. Concrete actions and outcomes.
semantic: a durable fact that stays true — 'user prefers Python 3.12', 'project uses pytest', 'auth uses JWT', 'user communicates in Polish'. Knowledge about the user or project.
procedural: a how-to with steps — 'run tests with pytest -x', 'deploy via npm run build && rsync', 'start dev server: python -m backend.main'. Steps to accomplish something.
Set confidence below 1.0 for inferences, assumptions, or guesses. Use tags for filtering (e.g. project name, topic). Episodic payload keys: session_id, agent, task, outcome, parent_id, metadata. Store one memory per distinct thing. ALWAYS skip idle chat, greetings, and trivial responses. Forgetting to store = permanent loss of the session.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| created_at | Yes | |
| memory_type | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description reveals important behavior: storing one memory per distinct thing, the consequence of forgetting ('permanent loss'), and specific payload keys for episodic type. It does not mention rate limits or auth, but covers key operational traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear lead sentence and bullet points for types. It is somewhat lengthy but every sentence adds value, avoiding redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the nested input schema and the presence of an output schema, the description is fairly complete. It explains the types, usage rules, and key parameters. It could briefly mention the return value, but the output schema likely covers that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite the context listing 0% schema description coverage (which seems contradicted by the schema itself), the description adds significant meaning: explaining each memory type, when to set confidence below 1.0, and the role of tags. This goes beyond the schema's brief descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Store a memory.' and explains when to call it ('after every non-trivial turn'). It distinguishes between memory types (episodic, semantic, procedural) with concrete examples, differentiating from sibling tools like memory_recall and memory_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool ('after every non-trivial turn'), what types to use, and what to skip ('idle chat, greetings, and trivial responses'). It does not explicitly mention alternatives, but the sibling context is provided separately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
memory_recall - First observed
memory_search - First observed
memory_store
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: memory_recall for browsing by tags/time, memory_search for content search, and memory_store for saving memories. No ambiguity between them.
All tools follow a consistent 'memory_' prefix with a verb (recall, search, store), making the tool names predictable and easy to understand.
With 3 tools, the set feels slightly minimal but appropriate for a targeted memory storage and retrieval system. The count is reasonable for the scope.
The tool surface covers storing and two retrieval methods, but lacks delete or update operations, which are notable gaps for a complete memory lifecycle.
Maintenance
Related MCP Connectors
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
Persistent memory for AI agents — log and recall conversation context over MCP.
Persistent memory for AI agents across Claude, ChatGPT and any MCP client.
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceSQLite-backed memory storage for MCP agents with optional semantic search via OpenAI embeddings, enabling agents to remember, recall, and manage contextual information across sessions.4 npmMIT
- AlicenseNot gradedqualityCmaintenanceLocal, cross-agent memory for AI coding agents using a single SQLite file, enabling persistent sessions and durable facts shared across multiple MCP-compatible tools.8 npmMIT
- AlicenseNot gradedqualityFmaintenanceLocal-first, auditable memory for AI agents. Provides durable context for MCP hosts with SQLite storage, CLI, and MCP tools for memory management.2Apache 2.0
- AlicenseNot gradedqualityAmaintenanceProvides persistent, cooperative memory for LLMs via MCP, with SQLite storage and tools for capturing, recalling, consolidating, crystallizing, and forgetting memories across sessions.3MIT