Procedural Memory layer for AI agents
Overview
MemFlow finds relevant skills for your task in Claude Code. Register your SKILL.md files, then describe your task as usual. MemFlow searches your skills and gives Claude a short list of matches to read through MCP. The current workflow uses Qdrant and an OpenAI-compatible embedding service. You do not need a separate generation LLM. MemFlow stores and serves the SKILL.md text; accompanying scripts and reference files are not included. You need Python 3.10+, uv 0.12.24, Claude Code, and Docker with Compose. You also need an existing OpenAI-compatible embedding service. The commands work in a Linux/macOS shell. uv tool install makes memflow available from any project. If uv reports that its executable directory is missing from your PATH, run uv tool update-shell and open a new terminal. See uv's tool installation guide. Qdrant runs at http://localhost:6333 and keeps its data in scripts/qdrant_data/. If you already have Qdrant, skip the Docker command and use your server's URL below.
README
MemFlow
MemFlow retrieves relevant stored skills for a task in Claude Code. Its plugin
injects a short catalog of matches, then Claude reads a selected SKILL.md by
exact ID through MCP. Stored skills retain their trust state. Accompanying
scripts and reference files are not uploaded with the skill text.
Install the Claude Code plugin
Install uv 0.12.24 and
use Claude Code 2.1.220 or later. You need an existing Qdrant service and an
OpenAI-compatible embedding endpoint. MemFlow does not provision these services.
The plugin prepares its own managed Python 3.12 and dependencies; users do not
clone MemFlow, install a Python package, or create a project .env.
Enter these commands in the Claude Code prompt:
/plugin marketplace add skhynix/MemFlow
/plugin install memflow@memflow-plugins
Select user scope and complete Claude’s plugin configuration form. Connection settings are shared across your projects.
| Configuration field | Value |
|---|---|
| Use system certificates during installation | Defaults to off. Enable for runtime downloads through a corporate CA trusted by the operating system |
| Qdrant URL | Existing HTTP(S) service endpoint |
| Collection | Defaults to memflow_skills |
| Qdrant API key | Optional; leave empty for unauthenticated access |
| Embedding API base URL | OpenAI-compatible base URL; MemFlow appends /embeddings |
| Embedding model | Model identifier served by your endpoint |
| Embedding dimensions | Positive integer output dimension |
| Embedding API key | Optional; leave empty to omit the Authorization header |
URLs cannot embed credentials or query strings. Use /plugin configure to select
MemFlow and edit these settings. Credentials stay in Claude-managed configuration
and process memory. The plugin does not read .env or inherit SDK connection,
hybrid, or reranker tuning variables. No /memflow:setup command is required.
Start a fresh Claude session after installation. Both the startup hook and MCP
launcher ensure the runtime is ready before using it, with an installation lock
and a 600-second preparation deadline. MCP connects automatically when preparation
and server initialization finish within Claude’s startup window (30 seconds by
default). A longer first download can exceed that window while the startup hook
continues preparation. Once /memflow:status reports Runtime ready, reconnect
MemFlow in /mcp. Claude can cache a failed connection across restarts, so restarting
alone may not reconnect it. Runtime ready and MCP connected are separate states.
If your network uses a corporate certificate authority already trusted by the
operating system, enable Use system certificates during installation in
MemFlow’s /plugin configure form. Then start a fresh session with the ordinary
claude command. The saved choice covers Python downloads and dependency
installation during first setup, updates that need a new runtime, and explicit
/memflow:status --repair. A prepared runtime needs no download settings.
The option defaults to off, retaining uv’s bundled certificate roots. When on,
certificate verification remains enabled and uses the operating system’s trust
store. Shell UV_* settings do not override the saved choice. In WSL, the CA
must be trusted inside Linux. This setting does not install a CA, configure
proxy credentials, or change TLS for the Qdrant and embedding clients. See
uv certificate configuration.
The plugin targets Linux x86_64/arm64 (including Linux inside WSL) and macOS arm64 (Apple Silicon). Intel macOS and native Windows are unsupported. Installation CI targets Ubuntu x86_64; Linux arm64 and macOS arm64 require separate native installation checks before release.
Manage stored skills
Enter these commands in Claude’s prompt, with paths relative to your session’s project directory:
/memflow:status
/memflow:add ./skills/review --trust-state trusted
/memflow:list
/memflow:sync ./skills/review
add accepts a skill directory or a SKILL.md file. It preserves the library’s
source-derived ID and defaults to untrusted data unless you explicitly select a
trust state. Only mark instructions you trust as trusted. add may create the
collection and required payload indexes after checking service compatibility.
sync accepts an existing exact ID or source path. It retains the stored user,
source, and trust state, marks missing sources stale, and never initializes a
collection or indexes. list accepts --user-id and --trust-state filters;
add also accepts --user-id. Registration stores a snapshot: editing a source
file requires an explicit sync.
Hooks and MCP use the project selected when the Claude session starts. Adding
access with /add-dir or changing the working directory during a session does
not retarget MemFlow’s relative paths, logs, or project configuration. Start a
new Claude session in another project to use it as the MemFlow project.
Ordinary task prompts automatically retrieve relevant skills. Management skills load only when invoked, and management writes require an explicit current user request, including a direct natural-language request. This is a workflow under Claude’s normal tool permissions: the plugin adds no permission rules or approval bypass, and skill frontmatter does not make MCP tools technically uncallable.
Installing or configuring MemFlow keeps native Claude skills visible. Disabling
the plugin through /plugin stops its integrations; Qdrant records remain.
Diagnose and repair
/memflow:status
/memflow:status --repair
Plain status is read-only. It runs an independent shell diagnostic even before Python or MCP is available. When MCP is connected, it also validates settings, reads Qdrant collection metadata, and requests an embedding for a fixed diagnostic string. Without MCP, service health is unknown. No status operation creates a collection, builds indexes, imports skills, or changes Claude settings.
Repair explicitly retries runtime preparation. It never changes connection settings or stored skills. A missing collection is a valid pre-import state.
Preparation failures report the failing stage and a process exit code or OS error number when available. Run explicit repair to reproduce an installation failure and see its diagnostic. Dependency installation and import validation output is withheld because it can contain URLs or credentials.
| Result | Action |
|---|---|
| Missing or wrong uv | Install uv 0.12.24 and run explicit repair |
| Missing configuration | Select MemFlow in /plugin configure |
| Runtime preparation still running | Wait for automatic preparation to finish |
| Runtime preparation failed or interrupted | Run explicit repair; reconnect in /mcp afterward |
| Runtime ready, MCP disconnected | Reconnect in /mcp; repair is unnecessary |
| Published runtime damaged or lifecycle unknown | Close affected sessions, then uninstall/reinstall to recreate plugin data |
| Authentication failure or timeout | Check the indicated service and Claude-managed credentials |
| Missing collection | Import a skill with an explicit add |
| Incompatible dense schema | Select a compatible collection with the configured dimension |
| Read-only sparse schema | Read existing dense vectors, or choose a separate dense-only collection for add/sync |
| No retrieval result | Check list/status, then retrieval thresholds and the metadata-only hook log |
The plugin uses dense retrieval and supports unnamed dense vectors or a named
dense vector, including dense reads from collections that also have sparse
vectors. Writes require a dense-only cosine collection with the configured
vector size. Embeddings longer than that size use the library’s truncation and
L2-normalization rule; short, invalid, or zero vectors fail. Import and sync never
report success with a fallback hash or zero embedding.
Embedding status reports the original source_dimensions, effective
dimensions, and dimension_reduction_applied from the same diagnostic request.
Check these fields when choosing a smaller vector size; reduction must be
appropriate for the embedding model.
Restart affected Claude sessions after changing endpoints, collections, models, or dimensions. A different model requires a fresh compatible collection and explicit re-import, even if its vector length is unchanged. MemFlow never silently re-embeds records, resizes a collection, or migrates a sparse schema.
Project retrieval and session state
Optional .memflow/claude-hook.json settings control retrieval and session
behavior. Defaults work without creating this file. Endpoints, credentials, and
installer fields are not plugin project settings.
{
"retrieval": {"top_k": 3, "min_score": 0.2, "timeout_ms": 2000},
"claude": {
"reread_after_compaction": true,
"session_dedupe": {"rollout": "off"}
}
}
Relative log and state paths resolve from the session project, never the plugin
cache. The default hook log is .memflow/logs/skill_context_hook.jsonl; session
records are under .memflow/claude-sessions. They contain metadata, not raw
prompts, skill bodies, tool responses, transcripts, or service credentials.
Retrieval and state failures leave Claude usable with a sanitized diagnostic.
After compaction, MemFlow resets activation state and asks Claude to reread
previously successful exact IDs. The reminder prioritizes recent reads within
8,000 UTF-16 units and explains instruction versus untrusted-data handling. Only
recognized successful calls to mcp__plugin_memflow_memflow__read_skill update
read history. Failed or malformed calls do not count as successful reads; a
failed read invalidates that ID’s current disclosure without deleting historical
successful-read metadata.
/clear and startup start with empty session history. Resume and ordinary session
end preserve it. Reread tracking defaults to on; experimental catalog deduplication
still defaults to off. Setting reread_after_compaction to false disables new
read tracking. Both features must be off to disable session-state access.
A reminder requests current stored content; it does not prove Claude reread it.
Optional native catalog control
Catalog status is read-only by default. Mutations require an explicit mode and scope:
/memflow:catalog
/memflow:catalog minimize --scope repository
/memflow:catalog disable --scope repository
/memflow:catalog restore --scope repository
For a non-Git project use --scope directory. In Git repositories, local settings
are shared through /.claude/settings.local.json. Restrictions
therefore affect the main checkout and linked worktrees. Discovery uses native
skills in the current checkout and Claude’s effective configuration directory,
including CLAUDE_CONFIG_DIR. Name-based overrides can affect matching skills in
other worktrees. Plugin skills and dynamically loaded skills are not exhaustively
covered by native discovery.
Git must be on Claude’s PATH even for directory scope: MemFlow checks whether
the directory belongs to a repository before choosing the settings target.
Git 2.34 is supported. Older Git’s line-delimited worktree output is checked
against repository metadata before choosing the settings root; ambiguous paths
are refused. Git 2.36 or newer supports paths containing line breaks.
If Git reports dubious ownership, verify the checkout owner and trust before
configuring safe.directory for that checkout. MemFlow does not change Git trust
settings or fall back to directory scope when repository verification fails.
Minimize makes discovered native skills user-invocable only; disable turns them off. Both request bundled skills to be disabled. Existing per-skill user overrides and user-edited owned values are preserved and reported as conflicts. Unsupported Git layouts, missing main checkouts, home-root repositories, ownership exceptions, symlinked state/settings paths, invalid settings, and wrong scopes refuse writes.
Restore undoes only unchanged MemFlow-owned keys, using each key’s original
presence and value. If a key is already back at its original presence/value and
has no unresolved pending operation, restore releases its ownership record
without rewriting the setting. Other user changes remain conflicts.
It does not force all skills visible. The journal at
/.memflow/claude-catalog-state.json survives plugin
removal. Restore before uninstall, or reinstall and restore afterward.
Uninstall does not restore native catalog settings.
For manual recovery, inspect the journal’s canonical target, then compare each
owned key’s committed presence/value with the current setting. Revert only
unchanged entries to baseline, deleting the key if its baseline was absent.
bundled means disableBundledSkills; skill: means that one entry under
skillOverrides. A pending entry records before, after, and baseline:
matching before is unapplied, matching after is applied, and any other value is
an external conflict to preserve. Keep unresolved evidence and the journal until
recovery is complete. Never replace a whole settings file from an old snapshot.
Malformed, missing, unsupported-version, or wrong-target journals cannot establish
ownership and require manual investigation.
MemFlow writers share an OS lock and recover pending writes per key. A byte comparison detects many external edits before atomic replacement. It cannot eliminate the final check/replace race with other programs or identify an external edit that writes exactly the same value.
Python library and benchmarks
Python consumers install this repository as a package, for example with
uv sync --locked --dev in a development checkout. This is separate from plugin
installation. There are no public memflow or memflow-mcp terminal entry points.
from memflow import MemFlow, SkillRecord
memory = MemFlow() # Qdrant configuration from the environment and CWD .env
record = SkillRecord(title="Release checks", content="Check tests and release notes.")
memory.add(record)
hits = memory.search("prepare a release", user_id="default")
stored = memory.get_skill(record.id)
memory.delete(record.id)
The Python library retains environment-based configuration and optional hybrid
search. .env.example is for SDK and benchmark use only. Explicit
constructor arguments override the environment. MemFlow(store=store, use_env=False) uses an injected store; hybrid_search=False selects dense retrieval
and rerank=False disables reranking independently. The plugin selects both
policies and ignores inherited hybrid and reranker configuration.
QdrantStore(provision=False) reads schemas without creating collections or
indexes; ordinary Python construction retains provisioning by default. Explicit
strict_embedding=True rejects fallback embeddings without changing the default
SDK policy.
add accepts one SkillRecord or a list, and async operations remain available.
Records and searches use kind="skill". File indexing uses add_skill(path) and
sync_skill(path_or_id). The library’s get_skill accepts an ID, title, or name;
plugin read_skill requires an exact ID. The plugin’s stricter existing-record
sync and dense-only write policy do not remove optional SDK capabilities.
Optional SDK reranking
Set MEMFLOW_RERANKER_PIPELINE in your SDK environment to ce, llm,
ce_llm, or llm_ce to rerank candidates after dense or hybrid retrieval.
The default is none. See .env.example for endpoints, candidate
depths, stage caps, and timeouts.
For an LLM stage, install the matching provider extra with uv sync --extra openai
or uv sync --extra ollama. The CE stage uses the core HTTP client and needs no
additional provider extra. Configure RERANKER_LLM_PROVIDER, RERANKER_LLM_MODEL,
RERANKER_LLM_API_BASE, and RERANKER_LLM_API_KEY; these retain LLM_* fallbacks.
Clients are created only when reranking runs. Invalid stage configuration or
endpoint failures warn and fall back to retrieval order.
Single-string searches, including search_async, use the configured pipeline.
List-query batches bypass hybrid retrieval and reranking. search(..., rerank=False)
bypasses reranking for one call. For SkillRet, the default async runner measures
the configured pipeline; --sync uses dense batches and --mode dense sparse hybrid
explicitly measures retrieval without reranking.
Optional MemMachine memory queries
MemMachine is a separate source for existing episodic and semantic memory.
Install its optional SDK with uv sync --extra memmachine and call the query
module explicitly:
from memflow.memmachine_memory import MemMachineMemoryClient
client = MemMachineMemoryClient(
base_url="http://localhost:8080", org_id="default", project_id="memflow"
)
try:
response = client.search(
"What are my release preferences?",
user_id="alice",
set_metadata={"user_id": "alice"},
)
finally:
client.close()
The project must already exist. Episodic memory uses the supplied user_id
metadata filter; set_metadata must match the server’s existing semantic set
configuration for that user. The example mapping is valid only for a server
configured that way. The SDK response retains both memory types without
conversion to skill records. This module does not create projects, write or
delete memory, or participate in skill search, hooks, MCP, or benchmarks.
MemMachineMemoryClient.from_env() reads the optional MEMMACHINE_* process
settings in .env.example. It does not load an env file. Import,
construction, and from_env() do not load the SDK or connect; the first valid
search does. Close the client when finished; a closed client cannot search.
Benchmarks
The benchmark harnesses evaluate skill retrieval with
SkillRet and SkillReason-Bench. Install optional plotting dependencies with
uv sync --extra benchmark.
The SkillRet benchmark is installed directly from HuggingFace (requires git-lfs):
git lfs install
uv run benchmark/install_benchmark.py skill_ret_bench
uv run benchmark/install_benchmark.py skill_ret_bench --commit-hash-skillret
SkillReason-Bench has a separate downloader and supports official metrics, predictions, and Recall@k plots from saved results:
uv run benchmark/skill_reason_bench/download_data.py
uv run --extra benchmark benchmark/skill_reason_bench/plot_recall_curves.py \
--results results/skillreason.json --by-domain
See the SkillReason-Bench guide for seeding, retrieval, evaluation, and plotting options.
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add skhynix/memflow