はじめに¶
対象: CPersona 2.6.x。 このページがインストールとセットアップの正本です。 README は PyPI のプロジェクトページも兼ねるため同じ手順の短縮版を持ちます。食い違う場合はこのページが優先されます。
翻訳について: 正本は英語版です。日本語版が古い場合は英語版を参照してください。
CPersona は MCP サーバーです。インストールして
MCP クライアントを向ければ、クライアントのエージェントはセッションをまたいで生き残る store / recall ツールを得ます。それ以外のスタックは何も変わりません。
エージェントに任せる¶
Claude Code か Codex に、公式サイトのセットアップ用プロンプトを貼り付けてください。プロンプトはエージェントにこのガイドを読ませ、各手順を先に見せ、コマンドの実行・インストール・ファイルの変更の前にあなたの承認を待つよう指示します。始めるのに必要なのはエージェントだけです。下の手順に要るもの (Python 3.11 以上や uv など) はエージェントが提案し、承認するまで何もインストールしません。
このページの残りは、同じセットアップを自分で進めるための手順です。
前提条件¶
自分で進める場合:
- Python 3.11 以上
- ワンコマンド経路を使うなら uv (任意 —
pipでも可) - MCP クライアント: Claude Desktop、Claude Code、Codex CLI、Cursor、VS Code、またはその他の MCP ホスト — 手順 3 に各クライアントのエントリがあります
Agent Skill を入れる (Claude Code)¶
このリポジトリと、公開されている wheel の両方に Agent Skill が同梱されています。この skill は Claude Code にインストール手順を案内し、その後いつ store / recall / archive すべきかを教えます。インストールするには:
# PyPI からインストール済みなら、skill は wheel の中にあります (clone 不要):
python -c "import cpersona,pathlib,shutil; s=pathlib.Path(cpersona.__file__).parent/'skills'/'cpersona-memory'; shutil.copytree(s, pathlib.Path.home()/'.claude/skills/cpersona-memory', dirs_exist_ok=True)"
# uvx (隔離環境) で動かしている、またはまだ入れていない場合:
git clone --depth 1 https://github.com/Cloto-dev/cpersona.git /tmp/cpersona
mkdir -p ~/.claude/skills && cp -r /tmp/cpersona/skills/cpersona-memory ~/.claude/skills/
あとは Claude Code にこう言うだけです: 「CPersona をセットアップして。永続記憶がほしい」。以下の手動手順は、それ以外のクライアント向け、および手で設定したい人向けです。手順 5 は本来 skill が代行する部分です。記憶のトリガーを、頼まれなくても発火させるための設定にあたります。
1. CPersona をインストールする¶
uvx cpersona # インストール不要、直接実行
# または
pip install cpersona # 以後 `cpersona` コマンドが PATH に入ります
ソースから (開発用)
git clone https://github.com/Cloto-dev/cpersona.git
cd cpersona
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install .
コンテナで動かす
git clone https://github.com/Cloto-dev/cpersona.git
cd cpersona
docker build -t cpersona .
docker volume create cpersona-data
docker run -d --name cpersona -p 8402:8402 \
-e CPERSONA_AUTH_TOKEN="$(openssl rand -hex 32)" \
-v cpersona-data:/data cpersona
embedding サーバーごとコンテナで動かす
このリポジトリの `compose.yaml` は CPersona と CEmbedding を互いに繋いだ状態で起動します。ベクトル検索を使うのに 2 つ目のセットアップは要りません:export CPERSONA_AUTH_TOKEN=$(openssl rand -hex 32)
docker compose run --rm embedding cembedding-download-model --model jina-v5-nano
docker compose up -d
サーバーは起動時に pypi.org へ新しいリリースの有無を問い合わせます。結果は recall
と check_health を通じて呼び出し側のエージェントに伝わり、check_update でも照会できます。確認自体を止めるには CPERSONA_UPDATE_CHECK=false を設定します。更新が自動で行われることはありません。明示的な check_update(apply=true) と再起動が必要です。
2. 埋め込みサーバーを立てる (推奨)¶
契約を満たす埋め込みサーバーに接続してください。埋め込みバックエンド無しでの実行は fallback としてサポートされますが、通常運用では推奨されません。
ベクトル検索は 3 つの検索層の中で最も強く、外部プロセスを必要とする唯一の層です。無くても CPersona は FTS5 + キーワード検索で動き、その旨を毎回の recall で伝えます。
CEmbedding は参照実装のバックエンドです。下記の契約を満たす他の埋め込みサーバーも同等にサポートされます。どれを選ぶかは利用者の自由です。
契約¶
CPersona は埋め込みサーバーを選びません。CPERSONA_EMBEDDING_URL を、次を実装する任意の HTTP エンドポイントに向けてください:
POST /embed
リクエスト: { "texts": ["string", ...] } # 空でない配列
レスポンス: { "embeddings": [[float, ...], ...], "dimensions": <int> }
CPersona が読むのは embeddings だけです。dimensions はリファレンスサーバーの応答に含まれますが、クライアントは無視します。返さないバックエンドでも動きます。CPersona が 1 リクエストで送るのは最大 64 件 (記録の文の区切りを作る時。それ以外は 32 件) で、リファレンス実装が受け付ける上限は 100 件です。この範囲のバッチ上限は考慮する必要がありません。
見落としやすく、いずれもランキングを静かに劣化させる要件が 3 つあります:
- 埋め込みは L2 正規化されていなければなりません。 CPersona は類似度を素の内積で計算するため、正規化されていないベクトルを返すバックエンドは、ベクトルの大きさでランキングを歪めます。サポート対象のバックエンド (クライアントの
apiモードと全 CEmbedding プロバイダ) はすべて正規化済みです。 - 契約はロールを持ちません。 クエリと文書は同じ呼び出しを通り、指示プレフィックスは付きません。プレフィックス前提のモデル (e5 系、prompted bge) はこの契約の下では性能が出ません。対称型または retrieval 統合型のモデル (jina-v5-nano、bge-m3、MiniLM) が想定される適合先です。
- 同じ URL の裏でモデルを差し替えるとコーパスが無効化されます。
/embedの契約はモデル同一性を運びません。GET /capabilitiesにも答えるバックエンド (CEmbedding 0.9.0 以降) は指紋で自分を名乗り、2.6.3 からは保存するベクトルにその指紋のラベルが付くので、別のモデルが書いたベクトルをcheck_healthが数えます (embedding_model_mismatch)。その報告が無いバックエンド (古い版や別の実装) では、CPersona が差し替えに気づけるのは埋め込みの次元が変わったときだけで、同じ次元の別モデルへの差し替えは検出できません。2.6.3 より前に保存したベクトルにはラベルが無く、数えられません。
気づけても修復はされません。check_health(fix=true) が再埋め込みするのは
blob が NULL の行で、次元チェックは長さの違う blob だけを NULL 化します。同一次元での差し替え後は全 blob が期待どおりの大きさなので、何も NULL 化されず、何も再埋め込みされません。既に blob を持つ行を強制的に再埋め込みするツールはありません。コーパスを再構築するまでの間は、CPERSONA_EMBEDDING_MODEL_MODE=reject
で古いベクトルを問いと比べないようにできます。そのとき該当する行はキーワードでだけ見つかります。
復旧手段はコーパスの再構築です。delete_agent_data の後、再構築パターン のとおりに再
store し、最後に calibrate_threshold を実行してください。
リファレンス実装¶
CEmbedding (MIT) は jina-v5-nano をオンデバイス (CPU) で動かし、まさにこのエンドポイントを公開します:
# モデルを ./data/models にダウンロード
uvx --from "cembedding[onnx]" cembedding-download-model --model jina-v5-nano
# サーバーを起動 (カレントディレクトリの ./data/models を読みます)
EMBEDDING_PROVIDER=onnx_jina_v5_nano uvx --from "cembedding[onnx]" cembedding
pip install "cembedding[onnx]" で PATH に入れて
cembedding-download-model --model jina-v5-nano → cembedding としても同じです。ソースチェックアウトからなら、同じ 2 手順は
python -m cembedding.download_model --model jina-v5-nano と
python -m cembedding です。
いずれの場合も
HTTP embedding endpoint started on http://127.0.0.1:8401/embed
と表示されるはずです。CPersona を繋ぐ前に確認してください:
curl -s http://127.0.0.1:8401/embed \
-H 'content-type: application/json' \
-d '{"texts":["hello world"]}' | head -c 200
CPersona の既定値は jina-v5-nano (768 次元) に合わせて調整されています。契約を満たす他のサーバーでも動きます。実測値が公開されているモデルは
benchmarks/
にあります。
CPersona が必要とするのは URL だけです。ただし参照サーバーをどう監視下で動かすかは重要で、素直なやり方では動きません。
これはただの HTTP プロセスではなく MCP サーバーです。既定のトランスポートでは前景で stdio の MCP セッションを回し、REST /embed エンドポイントはバックグラウンドタスクとして提供します。つまりプロセスの寿命は stdin に縛られています。EOF でセッションが終わり、finally 節が HTTP タスクを cancel します。
サービスマネージャは stdin を /dev/null にしてプロセスを起動します。その形で立ち上げると、サーバーはポートを bind し HTTP embedding endpoint started をログに出したうえで、同じ秒のうちに終了コード 0 で終了します。監視側は正常終了を見て、CPersona は誰も応答しない URL を向いたまま残ります。
stdin を開いたままにしてください。サービスマネージャの下では、パイプを保持する何かを挟みます: ExecStart=/bin/sh -c 'sleep infinity | cembedding'。ターミナルでは端末が既にその役割を果たしています。
EMBEDDING_TRANSPORT=streamable-http は stdin を読まないので、監視下では素直に動きます。ただし REST /embed の代わりに MCP エンドポイントを提供するため、
/embed に POST する CPersona の http モードでは選択肢になりません。
3. MCP クライアントに登録する¶
どのクライアントも起動するプロセスは同じです。コマンド uvx、引数 cpersona、そして下に示す環境変数。違うのは、どのファイルを読み、キーを何と呼ぶかだけです。
先に絶対パスの CPERSONA_DB_PATH を決めてください。例が
/home/you/.claude/cpersona.db を使っているのは、Claude 利用者ならそのディレクトリが既にあるからです。絶対パスなら何でも構いません。
| クライアント | エントリの置き場所 | 形 | ここで確認 |
|---|---|---|---|
| Claude Code | claude mcp add-json … -s user (ユーザー設定に書く) |
JSON、type: stdio |
済 |
| Claude Desktop | claude_desktop_config.json |
JSON、mcpServers |
済 |
| Codex CLI | codex mcp add … -- uvx cpersona (~/.codex/config.toml に書く) |
TOML、[mcp_servers.cpersona] |
済 (codex-cli 0.147.0) |
| Cursor | ~/.cursor/mcp.json (グローバル) または .cursor/mcp.json (プロジェクト) |
JSON、mcpServers |
ベンダー docs |
| VS Code (Copilot) | .vscode/mcp.json (ワークスペース) またはユーザーの mcp.json |
JSON、servers |
ベンダー docs |
| その他の MCP ホスト | その stdio サーバー設定 | 同じ command / args / env の 3 つ組 | ベンダー docs |
「済」は、このページを書いた時点でメンテナのマシン上、そのクライアント自身のツールでエントリを書き、読み戻して確認したことを意味します。「ベンダーdocs」はクライアントのドキュメントから形を転記したもので、ここでは実行していません。あなたのクライアントが受け付けるものと食い違ったら、正しいのはクライアントの方です。報告してください。
Claude Desktop — claude_desktop_config.json に追加:
{
"mcpServers": {
"cpersona": {
"command": "uvx",
"args": ["cpersona"],
"env": {
"CPERSONA_DB_PATH": "/home/you/.claude/cpersona.db",
"EMBEDDING_MODE": "http",
"EMBEDDING_HTTP_URL": "http://127.0.0.1:8401/embed"
}
}
}
}
Claude Code — 1 コマンド:
/home/you は自分のホームディレクトリに書き換えてください (Windows では C:/Users/you)。埋め込みサーバーをまだ用意していない場合は (手順 2)、"EMBEDDING_MODE":"http" を "EMBEDDING_MODE":"none" に変えてください。
claude mcp add-json cpersona '{"type":"stdio","command":"uvx","args":["cpersona"],"env":{"CPERSONA_DB_PATH":"/home/you/.claude/cpersona.db","EMBEDDING_MODE":"http","EMBEDDING_HTTP_URL":"http://127.0.0.1:8401/embed"}}' -s user
Codex CLI — 1 コマンド。その後に示す TOML を ~/.codex/config.toml に書き込みます:
/home/you は自分のホームディレクトリに書き換えてください (Windows では C:/Users/you)。埋め込みサーバーをまだ用意していない場合は (手順 2)、EMBEDDING_MODE=http を EMBEDDING_MODE=none に変えてください。
codex mcp add cpersona --env CPERSONA_DB_PATH=/home/you/.claude/cpersona.db --env EMBEDDING_MODE=http --env EMBEDDING_HTTP_URL=http://127.0.0.1:8401/embed -- uvx cpersona
[mcp_servers.cpersona]
command = "uvx"
args = ["cpersona"]
[mcp_servers.cpersona.env]
CPERSONA_DB_PATH = "/home/you/.claude/cpersona.db"
EMBEDDING_HTTP_URL = "http://127.0.0.1:8401/embed"
EMBEDDING_MODE = "http"
Codex はサーバーごとにツールを拒否リストにできます (同じテーブルの
disabled_tools = ["delete_memory", …])。これはエージェントに読み取り中心のアクセスを渡す、クライアント側の方法です。全クライアントに一度に効くサーバー側の同等物はクライアント別ケイパビリティ層 です。
Cursor — ~/.cursor/mcp.json、またはプロジェクト内の .cursor/mcp.json。形は Claude Desktop と同じです:
{
"mcpServers": {
"cpersona": {
"command": "uvx",
"args": ["cpersona"],
"env": {
"CPERSONA_DB_PATH": "/home/you/.claude/cpersona.db",
"EMBEDDING_MODE": "http",
"EMBEDDING_HTTP_URL": "http://127.0.0.1:8401/embed"
}
}
}
}
VS Code (Copilot) — ワークスペースの .vscode/mcp.json、またはユーザーレベルの
mcp.json (MCP: Open User Configuration)。トップレベルのキーは mcpServers
ではなく servers です:
{
"servers": {
"cpersona": {
"command": "uvx",
"args": ["cpersona"],
"env": {
"CPERSONA_DB_PATH": "/home/you/.claude/cpersona.db",
"EMBEDDING_MODE": "http",
"EMBEDDING_HTTP_URL": "http://127.0.0.1:8401/embed"
}
}
}
}
セットアップでつまずく原因は、たいてい次の 3 点です:
CPERSONA_DB_PATHは絶対パスにしてください。 既定値data/cpersona.dbはクライアントの作業ディレクトリからの相対です。別の場所から起動されたクライアントは、別の空のデータベースを開きます。Windows ではC:/Users/you/.claude/cpersona.dbの形で書きます。- まだ埋め込みサーバーが無い?
EMBEDDING_*の 2 行を消す (またはEMBEDDING_MODE=noneを設定する) だけです。CPersona は FTS5 + キーワードで動作し、劣化している旨を報告します。 EMBEDDING_MODE/EMBEDDING_HTTP_URLはCPERSONA_EMBEDDING_MODE/CPERSONA_EMBEDDING_URLの汎用エイリアスです。両方設定された場合は接頭辞つきが優先されます。設定リファレンス は、サーバーが読む変数を既定値とともにすべて載せています。
4. 動作を確認する¶
エージェントに何かを保存させ、新しいセッションでそれを想起させてください。セッション境界を越えることこそが目的です:
「これを保存して: デプロイ手順は ops/deploy.md にある」
…そして新しいセッションで: 「デプロイ手順について何か言っていたよね?」
コーパスが実運用に入ったら、一度は走らせておきたい確認が 2 つあります:
check_health— レジストリ駆動のヘルスチェック。判定はstatus、検出項目は重大度つき (critical/warn/info) で、check_health(fix=true)が機械的なものを修復します。- recall 応答に
advisoryフィールドが出ていないか。これはベクトル検索が寄与していないという報告です。理由は重大度が区別します。hintは埋め込みが未設定 (mode=none) であること、fault は設定済みのエンドポイントが応答しなくなったことを意味します。埋め込みサーバーの死活検知 を参照してください。
5. 記憶のトリガーを毎セッション発火させる¶
登録はエージェントにツールを与えますが、頼まれなくても使うようにはしません。セッション開始時の recall、決定時の store、セッション終了時の archive。これらは、会話がたまたま一致したときだけ発火する skill ではなく、クライアントが毎セッション読み込むファイルの中に置く必要があります。どのクライアントにもそのファイルがあります:
| クライアント | 常時ロードされるファイル (ユーザーレベルの既定) | プロジェクトレベルの代替 |
|---|---|---|
| Claude Code / Claude Desktop | ~/.claude/CLAUDE.md |
./CLAUDE.md |
| Codex CLI | ~/.codex/AGENTS.md |
リポジトリルートの ./AGENTS.md |
| Cursor | User Rules (Customize → Rules — ファイルではなく設定) | alwaysApply: true の .cursor/rules/cpersona.mdc、または ./AGENTS.md |
| VS Code (Copilot) | クライアントの custom-instructions ドキュメントを参照 | .github/copilot-instructions.md、または chat.useAgentsMdFile を有効にした ./AGENTS.md |
下のブロックをそのファイルに貼り付けてください。<AGENT_ID> は、エージェントが毎回の呼び出しで使う安定した識別子 1 つ ("claude-code"、"codex"、…) に置き換えます。
マーカーは残してください。後の版のブロックは、これを手がかりに 2 つ目のコピーを積み重ねるのではなく、このブロックを見つけて置き換えます。Claude Code では
cpersona-memory skill が承認を得て貼り付けを代行します。それ以外では手で貼り付けます。
ブロックが従う規則 (同意、配置、冪等性、40 行の予算、クライアント中立) はポリシーブロック標準 にあります。ブロックの正本は skill 側にあり、このコピーは CI でそれと照合されます。
<!-- BEGIN cpersona-policy v5 (managed by the cpersona-memory skill; re-run the skill to update) -->
## CPersona memory policy
Use the CPersona MCP tools proactively with `agent_id="<AGENT_ID>"` — never wait to be asked.
**Session start** → `reconstruct(agent_id, query="<opening-topic keywords>")` before the first
substantive action; with no topic yet, `recall(agent_id, query="", limit=10)` for the latest.
`deep=true` when the first pass comes back thin. Skip only for trivial one-shot questions.
**Answering from memory** → `reconstruct(agent_id, query)`, not `recall`: 10 items by default, each
quoting the rows behind it, at fewer reader tokens per correct answer. Read an item to judge it.
**Decisions, rules, preferences, bug findings** → `store` immediately. Fire on phrases like
"let's go with X", "from now on always Y", "remember that…", "approved", "that's a bug".
Lock must-never-lose rules: `lock: true` on the `store` where it offers one, else `lock_memory`.
After a successful `git commit`, `store` a one-line record: hash, what changed, why.
**Changing an existing rule** → `update_memory`, never delete + store. If the memory is locked:
`unlock_memory` → `update_memory` → `lock_memory`.
**Session end** — fire on closing phrases ("that's all for today", "wrap it up", "good night") →
first `store` + lock any unsaved decisions, then `archive_episode(agent_id, history=<the REAL
turns>, summary=…, keywords=…, resolved=…)`, computing `summary` and `keywords` yourself.
**"Don't save this" / benchmark sessions** → `pause_persistence(ttl_seconds=1800)`;
`resume_persistence()` (or TTL expiry) restores. Reads still answer, minus the writes inside them.
**Degraded mode** — if a `recall` response carries an `advisory` field, surface it to the user
and follow its runbook. Never quietly serve keyword-only recall.
**Quality** — recall feels off → `set_recall_precision` (strict/balanced/lenient), the one policy
knob; after large corpus changes `calibrate_threshold(agent_id)`; monthly `check_health(agent_id, fix=true)`.
**If this client keeps a memory file that loads every session** (Claude Code's `MEMORY.md`), use it
as the deterministic index over this store: one line per memory — `- <slug> — <the sentence that
changes behaviour>` — with the body stored here under the id `memory-index:<slug>` and content
starting `[<slug>]`, so a line tells you what to `recall`. Recall is ranked and may not surface a
memory; the index always arrives. Its size cap fails **silently** when exceeded, so consolidate at
80%, not at the limit. Never migrate existing memories into this store without asking first.
Details, setup, and troubleshooting: the `cpersona-memory` skill.
<!-- END cpersona-policy -->
次に読むもの¶
| したいこと | 読むページ |
|---|---|
| 依存してよい挙動を知る | 挙動契約 |
| 各ツールが何をするか見る | ツール一覧 |
| 検索の仕組みを理解する | アーキテクチャ |
| 稼働中のインスタンスをバックアップ・調整・診断する | 運用 Runbook |
| 設定を調べる | 設定リファレンス |
| 複数クライアントにネットワーク越しで提供する | リモート HTTP トランスポート |