aim-init について
aim-initは、リポジトリをai-memoryインスタンスに接続するエージェントスキルです。プロジェクトのメモリを設定・更新するチームや開発者向けに、診断、導入、qmdからの移行、CLIとフックの更新を案内します。
主な機能
- 01読み取り専用の設定診断
- 02ai-memoryの新規設定
- 03qmdからの移行
- 04CLIとフックの更新
- 05プロジェクトのルーティング設定
活用シーン
- 01リポジトリの移行要否を確認
- 02セッションの自動記録を有効化
- 03qmdリポジトリをai-memoryへ移行
- 04ローカルCLIとエージェントフックを更新
MCP 対応
対応クライアントがai-memoryインスタンスに接続できるよう、MCPサーバー項目を設定します。プロジェクト範囲のメモリ検索にもai-memory MCPを利用します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ djalmajr/ skills --skill aim-initインストール後、Claude Code で/aim-initを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/usage.mdscripts/dev-setup-hooks.ps1dev-setup-hooks.shkc-create-device-client.shtemplates/ai-memory.toml.exampleai-memory.toml.tmplmcp-entry.json.tmplrouting-snippet.md.tmpl詳細
aim-init
リポジトリを ai-memory に接続し、セッションを自動でキャプチャして、エージェントが長期的に役立つ知識を呼び出せるようにします。新規リポジトリでも既存リポジトリでも利用でき、古い qmd/wiki/ スタックからの移行にも対応します。
ai-memory は、qmd の
wiki/とローカルインデックスのスタックを置き換えます。知識はリポジトリごとのwiki/フォルダーではなく、ai-memory インスタンスのサーバー側に保存され、MCP 経由で呼び出されます。 利用モデルの全容は references/usage.md を参照してください。 サーバー側(新しいインスタンスのインストール、エンジンのアップグレード、プロバイダー、コンシューマーキー、バックアップ/復元)については aim-ops を参照してください。このスキルではクライアントの接続のみを設定します。
ルートの意図
- 「調子はどう?」「移行が必要?」「doctor」(PT:「como está?」「preciso migrar?」も同様)→ doctor を実行します(読み取り専用の診断)。
- 「ここで ai-memory をセットアップして」「キャプチャを有効にして」「init」(PT:「configura ai-memory aqui」「liga a captura」も同様)→ install(新規導入)。
- 「qmd から移行して」「qmd を外して ai-memory を使って」(PT:「migra do qmd」「tira o qmd e põe ai-memory」も同様)→ migrate(既存環境からの移行)。
- 「CLI を更新/ペアリングして」「フックを更新して」「古いバージョンを使っている」「upgrade」(PT:「atualiza/pareia o CLI」「refresca os hooks」「tá numa versão velha」も同様)→ refresh (環境を検出し、ローカルの CLI とフックをサーバーと同じ状態にします。マーカー/スニペット/MCP の変更はありません)。
何かを書き込む前に、3 つのルーティングパラメーターをユーザーに確認してください。複数の ai-memory インスタンス(例:個人用の memory.example.dev と、別の組織用インスタンス)が存在する可能性があるため、エンドポイントをハードコードしてはいけません。
- MCP エンドポイント — ai-memory インスタンスの URL(例:
https://memory.example.dev/mcp)と、登録時に使用するサーバー名(例:memory-personal、memory-acme)です。このリポジトリが接続するインスタンスを確認してください。 - ワークスペース — 個人用なら
default、組織のリポジトリなら専用のワークスペース(例:acmecorp)を指定します。 - プロジェクト — 既定ではリポジトリのベース名です。ユーザーが上書きできるようにしてください。
ここで選択したエンドポイントが、後で aim-query/aim-write がターゲットにする先になります(サーバー名で指定)。
CLI の前提条件(デフォルトでは Docker ラッパーを使用しません)
aim-init では、MCP エントリのインストール、フックのインストール、ルーティングスニペットの更新に ai-memory CLI が必要です。Docker ラッパーよりもネイティブ CLI バイナリを優先してください。
ai-memoryがすでにPATHにある場合は、ai-memory --versionを実行し、最新の上流リリース(gh release view -R akitaonrails/ai-memory --json tagName -q .tagName、またはリリースの最新ページ)と比較してください。最近のリリースであればそのまま使用します。それより古い CLI では、新しいサブコマンド(例:auto-improve、pending-writes、curator)やフックの修正が利用できないため、アップグレードしてください(更新を参照)。サーバーの正確な.versionはGET /admin/statusで確認できますが、これには管理者トークンが必要です(ユーザーの OIDC/JWT では401が返ります)。そのため、実用上は最新リリースをバージョン一致の目安とし、接続された MCP クライアントもinitializeハンドシェイクからサーバーのバージョンを取得します。- 見つからない場合や古い場合は、まず最新の上流リリースを確認してください。
https://github.com/akitaonrails/ai-memory/releases/latest- Linux:対応する
ai-memory-linux-<arch>.tar.gzアセットをダウンロードし、.sha256を検証して、バイナリを~/.local/bin/ai-memory(またはユーザーが所有する別のPATHディレクトリ)にインストールします。 - Windows:
ai-memory-windows-x86_64.zipをダウンロードし、.sha256を検証して、同梱の Windows ドキュメントに従います。 - macOS/Darwin:対応する
ai-memory-macos-<arch>.tar.gzアセットをダウンロードします(Apple Silicon ではai-memory-macos-aarch64.tar.gz、Intel では-x86_64)。.sha256を検証し、バイナリを~/.local/bin/ai-memoryにインストールします。お使いのアーキテクチャ向けのアセットがない場合に限り、代わりにcargo install --git https://github.com/akitaonrails/ai-memory --tag <latest-tag>を実行します。
- Linux:対応する
- Docker ラッパー(
bin/ai-memoryまたは GitHub のクイックスタートラッパー)は、ユーザーが明示的に Docker を希望する場合に限って使用してください。macOS のデフォルトのローカル CLI として、またはユーザーが Docker を使わない構成を求めている場合に、これを提案してはいけません。
インストール後、次のコマンドで確認してください。
command -v ai-memory
ai-memory --version
AI_MEMORY_SERVER_URL=https://memory.example.dev AI_MEMORY_AUTH_TOKEN=<token-or-env> ai-memory status --json
設定済みリポジトリの構成
-
リポジトリのルートにある
.ai-memory.toml— キャプチャとリコールをワークスペース/プロジェクトにルーティングするための、安定した非シークレット設定と、(任意で)このリポジトリのオンボーディング先となる Keycloak/OIDC インスタンスを指定します。追跡ポリシーは状況に応じて決めるもので、自動ではありません。- ルーティングを共有するプライベート/チームリポジトリ: クローン時にすべての開発者が同じワークスペース/プロジェクトとオンボーディングプロファイルを使えるように、コミットします。これらの値はインスタンス設定であり、認証情報ではありません。また、通常はセットアップ後に変更しません。
- パブリックリポジトリ、個人フォーク、またはオペレーターごとのルーティング: リポジトリローカルの
.git/info/excludeを使って、ローカルに保持します。 グローバルなcore.excludesfileに追加してはいけません。また、ユーザーがローカル限定のルーティングを明示的に選択しない限り、git rm --cached .ai-memory.tomlを実行してはいけません。
workspace = "default" project = "<repo-name>" # Optional routing/policy (defaults shown; uncomment to change — commented = no-op): # project_strategy = "repo-root" # collapse worktrees/subdirs to the git root (default: basename) # drop_subagent_captures = "true" # accept-but-don't-store THIS project's subagent captures (default: off) # Optional: Keycloak/OIDC onboarding profile the agent reads to wire hooks # WITHOUT asking (see "Keycloak-gated instance"). Non-secret. The native hook # reads the routing/policy keys above but NOT this [instance] block, so the # block is inert at runtime — it exists purely so `aim-init` can self-serve # the device-flow setup. [instance] issuer = "https://kc.example/auth/realms/<realm>" server_url = "https://memory.example.dev/wiki" # ai-memory URL incl. base path client_id = "ai-memory-cli" # device-flow client agents = ["claude-code"] # agents to wire hooks for -
CLAUDE.mdとAGENTS.mdのルーティングスニペット —…end -->ブロックです。セッション中のプロアクティブなリコールを実行します。このブロックのテキストはこのスキルではなく ai-memory バイナリが管理します。現在の正規ブロックをソースから取得し、マーカー間に書き込んでください。ここにコピーを手作業で管理してはいけません(バイナリとの不整合が生じます)。- エージェント:
memory_install_self_routing(Write/Edit ツール用のブロックを返します)。 - CLI:
ai-memory install-instructions(CLAUDE.mdに書き込みます。--target AGENTS.md)。 正規のブロックはすでに汎用的です(ワークスペース/プロジェクト/サーバー名もページパスも含みません。.ai-memory.tomlマーカーが想起の範囲を限定し、MCP が自動的に範囲を設定します)。そのため、公開リポジトリでも安心してコミットできます。どのような場合でも、コミット済みのブロックを、ナレッジベースの内容を列挙する「情報の配置場所」マップに拡張しないでください。プロジェクト内部の情報アーキテクチャが漏洩します。スコープをまたぐ設定や共有ルールの配線は、リポジトリごとのブロックではなく、オペレーターのグローバル設定(~/.claude/CLAUDE.md)に記述します。
- エージェント:
-
.mcp.json(Claude)、opencode.json(OpenCode)、.codex/config.toml(Codex)内のMCP サーバーエントリー — ai-memory インスタンスを指定します(テンプレート:templates/mcp-entry.json.tmpl)。 各エージェントにネイティブなグローバル設定を適用するため、CLI インストーラーを使うことをおすすめします。ai-memory install-mcp --client codex --server-url https://memory.example.dev/mcp --name memory-personal --apply ai-memory install-mcp --client open-code --server-url https://memory.example.dev/mcp --name memory-personal --apply ai-memory install-mcp --client claude-code --server-url https://memory.example.dev/mcp --name memory-personal --applyMCP 定義にサーバー名/URL だけが含まれ、認証情報が含まれていない場合は、安定したリポジトリ設定として扱えます。プライベート/チームリポジトリでは、クローン時にすべてのエージェントが同じ MCP エンドポイントを検出できるよう、
.mcp.jsonをコミットしてもかまいません。個人用エンドポイントや認証情報を含むエントリー(たとえばAuthorizationヘッダー、ベアラートークン、ユーザーごとのシークレット)は、エージェントのグローバル/ユーザー設定に置くか、.git/info/excludeを使ってローカル限定の.mcp.jsonにしてください。.mcp.jsonをグローバルなcore.excludesfileに追加しないでください。また、既存の.mcp.jsonを自動的に追跡対象から外すこともしないでください。ユーザーがローカル限定の MCP 設定を明示的に選択した場合に限り、git rm --cached .mcp.jsonを実行してください。 -
自動キャプチャフックはグローバルです(Claude の設定、Codex の
~/.codex/hooks.json、OpenCode のプラグイン設定に加え、プラットフォームのデータディレクトリ内に配置するフックスクリプト:Linux では~/.local/share/ai-memory/hooks/、macOS では~/Library/Application Support/ai-memory/hooks/、Windows では%LOCALAPPDATA%\ai-memory\hooks\)。フックはマーカーの有無を条件として実行されるため、.ai-memory.tomlがあるリポジトリであればどこでも動作します。リポジトリごとのフックスクリプトは不要で、マーカーだけで十分です。エージェントごとに、/mcpURL ではなくキャプチャ用のベース URL を指定してインストールまたは更新してください。 フックの認証 — サーバーに合った方式を選んでください。サイレントなキャプチャ失敗の最大の原因は、方式の選択ミスです。誤った方式では、すべてのドレイン処理が 401 となり、スプールがいっぱいになってキャプチャが失われます。 方式は 4 つあります。- 認証なしのフックルート(
/hookと/handoffに認証がない)→--auth-tokenなしでインストールします。 - 静的ベアラー — サーバーが
/hookと/handoffで共有トークン/ユーザーごとのトークンを受け付けます(例:シングルテナントエンジンのAI_MEMORY_AUTH_TOKEN、またはai-memory user addで取得したトークン)。→--auth-tokenで渡します。各エージェントのフック設定に埋め込まれるため、そのファイルは機密情報として扱ってください(chmod 600)。 - コンシューマーキー(
amk_、キーのみのゲートウェイ) —mcp-authサイドカーは ID プロバイダーなしで実行され、コンシューマーごとのキーをローカルで解決します(KEYS_DB)。各エージェント/CLI には専用のキーを付与します(adminスコープのキーでPOST /keysを実行。aim-ops keysで発行)。スコープはread,writeに設定し、フックには--auth-tokenで、MCP にはAuthorizationヘッダーで渡します。帰属情報にはキーのactor_userが使われます。管理者以外のキーでは/admin/*に対して 403 が返されます。これは仕様であり、サーバーの障害ではありません。ローテーションする場合は、新しいキーを発行してから古いキーを失効させます。 - OIDC/Keycloak ゲートウェイ — forwardAuth サイドカー(
mcp-auth)が JWT を検証し、401 WWW-Authenticate: Bearer resource_metadata=…(RFC 9728)を返します。静的な 16 進数トークンはここでは拒否されます(401)。ゲートウェイが受け付けるのは Keycloak JWT のみであり、エンジンの上流ベアラーはプロキシによって注入されるため、クライアントから送信できません。開発者ごとの OIDC デバイストークンを使用してください。ai-memory auth login oidc-device --issuer <oidc-issuer> --client-id <public-device-client>を一度だけ実行し(ブラウザーで承認)、その後--auth-tokenなしでフックをインストールします。フックのresolve_bearerがauth.jsonからトークンを読み込み、ヘッドレスで更新します。詳しい手順は、下記の「Second / custom instance」を参照してください。 サーバーがどのモードで動作しているかを簡単に確認できます:curl -sI <server>/hook→WWW-Authenticate: Bearer resource_metadata=ヘッダーを伴う401は、OIDC/Keycloak(デバイスフロー)を意味します。このヘッダーを伴わない通常の401/200は、static-bearer/open を意味します。GET <server>/keys/whoami→{identity, can_issue}を伴う200は、keys-only ゲートウェイ(consumer keys)が存在することを意味します。404は、サイドカーにKEYS_DBが設定されていないことを意味します。
バイナリが同梱スクリプトを見つけられない場合(例:
cargo installによるビルド)は、--hooks-dir <ai-memory/hooks>を追加します:# static-bearer server: TOKEN=<HOOK_AUTH_TOKEN> ai-memory install-hooks --apply --agent claude-code --server-url https://memory.example.dev --auth-token "$TOKEN" # OIDC/Keycloak server (after `auth login oidc-device`) OR open server — NO --auth-token: ai-memory install-hooks --apply --agent claude-code --server-url https://memory.example.dev ai-memory install-hooks --apply --agent codex --server-url https://memory.example.dev ai-memory install-hooks --apply --agent open-code --server-url https://memory.example.dev現行の
install-hooksは、シェルスクリプトではなくネイティブフック(ai-memory hook --event …でバイナリを直接呼び出すもの)を設定します。バイナリはエージェントごとに適切な標準出力の形式を出力します(例:引き継ぎの注入に使う、Claude Code のhookSpecificOutput.additionalContextJSON ラッパー)。そのため、手動で修正したフックスクリプトが古くなっていくことはありません。認証用にカスタムの_lib.shオーバーレイ(例:Keycloak トークンの発行処理を先頭に追加するもの)を手動で保守しないでください。サポート対象の方法は、--auth-token(static-bearer サーバーの場合)、またはauth login oidc-deviceを実行して--auth-tokenを指定しない方法(OIDC/Keycloak サーバーの場合)です。デバイストークンはイベントごとに発行されるのではなく、auth.jsonに一度保存され、ドレイン時にヘッドレスで更新されます。 Codex では、~/.codex/hooks.jsonに ai-memory のライフサイクルフックが含まれていることを確認し、次回起動時に Codex が確認を求めたら、新しいフックコマンドを信頼してください。Grok Build CLI(~/.grok/hooks/*.json)は、まだサポート対象の--agentではありません。手動で統合し、SessionStartはフックの標準出力を無視する点に注意してください(引き継ぎの注入は行われません。代わりに MCP のmemory_handoff_acceptを使用してください)。旧式の qmd リポジトリにはリポジトリごとのwiki-reindexフックがありますが、移行時に削除されます。 - 認証なしのフックルート(
フック設定 — プラットフォームごとのパスと配信モデル(macOS / Linux / Windows)
install-hooks と auth login oidc-device はどちらも、デフォルトでプラットフォームのデータディレクトリ
(dirs::data_local_dir())を使用します。ここに auth.json、hook-spool/、ステージングされたフックスクリプトが
保存されるため、OIDC デバイストークンはフックが参照する場所に格納されます。3 つの OS で同じフローを使い、異なるのは
パスだけです。
| OS | データディレクトリ(auth.json、hook-spool/、hooks/) | Claude Code の設定 |
|---|---|---|
| macOS | ~/Library/Application Support/ai-memory | ~/.claude/settings.json |
| Linux | ~/.local/share/ai-memory | ~/.claude/settings.json |
| Windows | %LOCALAPPDATA%\ai-memory | %USERPROFILE%\.claude\settings.json |
フックはネイティブです(ai-memory hook --event … はバイナリを直接呼び出します。シェルは起動しません。
Windows では、同じスプールと OIDC トークンへのフォールバックを使う WindowsNative 設定を使用します)。Codex →
~/.codex/hooks.json、OpenCode → そのプラグイン設定を使用します。バイナリが同梱スクリプトを見つけられない場合
(たとえば cargo install でビルドした場合)は、--hooks-dir <data_dir>/hooks を渡してください。auth.json は
機密情報を含むため、POSIX では chmod 600 が必要です(CLI はそのように書き込みます)。
配信はイベントごとではなく、セッション境界でまとめて行われます。 イベントごとのフック
(user-prompt-submit、pre/post-tool-use、pre-compact、stop)は
<data_dir>/hook-spool にキューイングするだけです(即時処理、結果を待たずに実行)。スプールは
session-start(前のセッションの未処理分を消去)と**session-end**(主な配信タイミング)で
排出されます。そのため、「キャプチャがすぐに表示されない」のは正常です。次の境界で送信されます。
排出時の resolve_bearer では、明示的な --auth-token があればそれを優先します(静的トークン)。なければ
auth.json の OIDC トークンを使用し(有効期限が近ければ更新)、それもなければ匿名で処理します。スプールは
8 回の失敗、または 7 日経過後にエントリを削除し、ファイル数は 10000 件を上限とします。誤った認証モードの症状:
Keycloak ゲートウェイに対して静的トークンを使い、401 が永久に返されることで、auth_mode: static のエントリが
hook-spool に蓄積して 10000 件に近づきます → デバイスフローに切り替え、処理されない滞留分を消去してください。
トークンの有効期間(デバイスフロー):アクセストークンは自動更新されます。リフレッシュトークンは、発行元の
オフラインセッションのアイドル期間が続く限り有効です。長期間利用していなかった場合は、auth login oidc-device を再実行してください。ai-memory auth status でいつでも状態を確認できます。
Keycloak で保護されたインスタンス — エージェントがオンボーディングを進めます(macOS/Linux/Windows)
開発者がセットアップスクリプトを手動で実行する必要はありません。Keycloak/OIDC インスタンスでフックのキャプチャが必要になったら、あなた(エージェント)が手順を進めます。入力を集め、デバイスクライアントを確認・作成し、マシンごとのセットアップを実行して、動作を確認します。開発者が行うのは、いくつかの質問への回答と、ブラウザーのプロンプトを一度承認することだけです。scripts/ は、クロスプラットフォームの標準コマンドリファレンスです(macOS/Linux 用の *.sh、Windows 用の *.ps1)。これらを呼び出すか、同等の ai-memory コマンドを直接実行してください。
必要な入力 — まず、リポジトリの .ai-memory.toml の [instance] ブロックから読み取ってください
(issuer/server_url/client_id/agents。「配線済みリポジトリとは」を参照)。そのブロックがない場合にのみ、開発者に尋ねるか、オペレーターのグローバル設定を参照してください。
ISSUER— レルムの URL。例:https://kc.example/auth/realms/<realm>。SERVER_URL— ai-memory サーバーの URL。ベースパスがある場合はそれも含めます。例:https://memory.example.devまたはhttps://memory.example.dev/wiki。CLIENT_ID— デバイスフローのクライアント(デフォルトはai-memory-cli)。- 開発者が使用する
AGENTS(claude-code、codex、open-codeなど)。
[instance] ブロックがある場合(非公開のチームリポジトリにコミットされている場合など)、エージェントはその内容を使用し、質問はしません。次の開発者は git clone と aim-init だけですぐに使い始められます。
1. デバイスフローのクライアントが存在することを確認する(読み取り専用):
GET <ISSUER>/.well-known/openid-configuration を実行して device_authorization_endpoint を確認し、そのエンドポイントに client_id=<CLIENT_ID>&scope=openid を POST します。device_code が返れば準備完了です。invalid_client(クライアントが存在しない)または unauthorized_client … device flow is disabled が返る場合は、レルムにクライアントが必要です(ステップ 2)。ブラウザー/MCP クライアントには PKCE が必須であり、Missing parameter: code_challenge_method によって 400 エラーになるため、再利用できません。そのため、専用クライアントが用意されています。
2. クライアントがない場合に作成する — レルムごとに一度だけ必要で、Keycloak の管理者権限が必要です。
Keycloak の管理者権限がある場合は、scripts/kc-create-device-client.sh を使用してください(冪等。パブリック、デバイス専用、PKCE なし)。コンテナー化された Keycloak では、ポッド内で実行してください(OS にかかわらず、内部で sh を実行します)。ポッド自身の管理者環境変数を再利用するため、シークレットがクラスター外に出ることはありません。
# macOS/Linux/WSL:
kubectl exec -i <keycloak-pod> -- sh -c \
'CLIENT_ID=ai-memory-cli KC_SERVER=http://localhost:8080/auth KC_REALM=<realm> \
KC_ADMIN_USER="$KEYCLOAK_ADMIN" KC_ADMIN_PASS="$KEYCLOAK_ADMIN_PASSWORD" sh -s' \
< scripts/kc-create-device-client.sh
# Windows PowerShell: Get-Content scripts/kc-create-device-client.sh | kubectl exec -i <pod> -- sh -c '…'
レルムの KC_HTTP_RELATIVE_PATH に応じて、KC_SERVER を …:8080 または …:8080/auth に調整してください。ログイン時に 404 Not Found が発生する場合は、切り替えてください。管理者権限がない場合は、オペレーターに一度実行してもらってから、手順を再開してください。
3. マシンごとのセットアップを自分で実行する — 開発者にスクリプトを実行させないでください。開発者の OS に応じて実行します。
- macOS/Linux:
ISSUER=… SERVER_URL=… CLIENT_ID=… AGENTS="…" sh scripts/dev-setup-hooks.sh - Windows:
pwsh scripts/dev-setup-hooks.ps1 -Issuer … -ServerUrl … -Agents "…" - どちらの場合も、まず
ai-memory auth login oidc-device --issuer <ISSUER> --client-id <CLIENT_ID>を実行します(開発者は表示された URL をブラウザーで一度承認します)。次にai-memory install-hooks --apply --agent <each> --server-url <SERVER_URL>を実行します(--auth-tokenは使用しません)。
4. 確認: ai-memory auth status の結果が oidc-device: logged in であること。開発者には、サーバーが確認するレルムロール(mcp:read/mcp:write)が必要です。これは MCP ログインですでに必要となるロールと同じです。
各インスタンスの ISSUER/SERVER_URL/CLIENT_ID はオペレーターのグローバル設定(~/.claude/CLAUDE.md または非公開の運用手順書)に記録し、このスキルには記録しないでください。スクリプトは汎用のままにし、これらのエンドポイントはオペレーター/インスタンス固有の情報として扱います。
2つ目/カスタムインスタンス(例:クライアントの Keycloak インスタンス)
一部のリポジトリでは、個人用とクライアント/組織用の 2つの ai-memory インスタンスを使用します。後者は、静的なベアラーに代わって、またはそれに加えて OAuth/OIDC(Keycloak、RFC 9728)で認証します。どちらも読み取り+書き込みに対応しています。両者を同期し、個人用インスタンスを上位集合として維持します(カスタムインスタンスにあるすべての情報が個人用インスタンスに蓄積されます)。
- フックによるキャプチャは、OAuth/Keycloak インスタンスでも動作します。 フックはヘッドレスであり、イベントごとに対話型の OAuth PKCE フローを実行できないため、保存済みの OIDC デバイスフロートークンを使用します。
ai-memory auth login oidc-device --issuer <oidc-issuer> --client-id <public-device-client>を一度実行し(ブラウザーで承認)、フック(resolve_bearer)がauth.jsonからトークンを読み込み、ヘッドレスで更新します。その後、--auth-tokenを指定せずにinstall-hooksを実行します。- forwardAuth-JWT のみのゲートウェイは静的ベアラーを拒否します。 ゲートウェイが
401 WWW-Authenticate: Bearer resource_metadata=…(RFC 9728)を返す場合、静的な 16 進トークンは 401 になります。上流のベアラーはプロキシによって挿入されるもので、クライアントから送信できません。そのため、ここではデバイスフローが唯一のヘッドレスでの選択肢です。--auth-tokenを渡すのは、インスタンスが/hookで静的なHOOK_AUTH_TOKENを実際に受け入れる場合に限ります。 - デバイスフローのクライアント要件(issuer 側): デバイス認可グラントが有効で、PKCE 強制が無効のパブリッククライアントが必要です(デバイスグラントに PKCE は適用されません。リダイレクトがないためです。PKCE を強制するブラウザー/DCR/MCP クライアントは、弱体化させずに済むよう、別のクライアントとして維持してください)。ユーザーには、サーバーが確認するレルムロール(例:
mcp:read/mcp:write)が必要です。これらはスコープではなく、レルムロールマッパーを介して JWT に含まれます。
- forwardAuth-JWT のみのゲートウェイは静的ベアラーを拒否します。 ゲートウェイが
- 二重キャプチャ: グローバルフック → 個人用インスタンス、プロジェクトレベルのフック(
.claude/settings.local.json)→ クライアントインスタンス。それぞれの接続では、対象インスタンスの認証方式(静的ベアラーまたは OIDC デバイストークン)を使用します。認証は互いに独立しています。両方を設定すると、すべてのライフサイクルイベントが両方にキャプチャされます(または、一方だけにキャプチャして同期で調整します)。 - 永続ページの二重書き込み: 2つのインスタンスを使うプロジェクトで
memory_write_pageを実行すると、同じ(workspace, project)で両方の MCP に書き込まれます。 - クライアントインスタンスで想起/書き込みを行う際は、明示的に
workspaceとprojectを渡してください。per_actorとスコープ漏洩をフェイルクローズする修正により、スコープを指定しない呼び出しは、そのインスタンスに組み込まれたデフォルト値に適用されます。.ai-memory.tomlマーカーには正規のスコープが設定されています。 - 同期を維持(オンデマンドの双方向同期):個人用インスタンスを、すべてを含む上位集合として維持します。
(workspace, project)を保持しながら、両方向の差異を調整します。
このオペレーター固有のデュアルインスタンス設定は、コミット対象のリポジトリごとの CLAUDE.md にある ai-memory ブロックではなく、オペレーターのグローバル設定(~/.claude/CLAUDE.md または共有メモリルール)に置いてください。このブロックは汎用でバイナリが管理するものであり、共有リポジトリ/クライアントリポジトリに置くと、デュアルインスタンス/キャプチャ設定とプロジェクトの情報アーキテクチャが漏洩します。
doctor(読み取り専用)
書き込みは行わず、以下を報告してください。
ai-memoryCLI がPATH上にあるか。バージョンはいくつか。見つからない、または古い場合は、最新のアップストリームリリースからネイティブインストールする方法を報告してください。ai-memory-<os>-<arch>.tar.gzアセットをダウンロードします(macOS にはai-memory-macos-aarch64/-x86_64、Linux にはai-memory-linux-aarch64/-x86_64が含まれています)。その.sha256を検証してください。お使いのアーキテクチャ用のアセットがない場合に限り、cargo installを使用してください。ユーザーが Docker を希望しない限り、Docker ラッパーにはフォールバックしないでください。- CLI が選択したサーバーに接続できるか(適切な
AI_MEMORY_SERVER_URL/認証環境変数またはフラグを設定したai-memory status --json)。 - CLI のバージョンが最新と一致しているか。
ai-memory --version(ローカル)と最新のアップストリームリリース(gh release view -R akitaonrails/ai-memory --json tagName -q .tagName)を比較してください。CLI が古い場合は、その CLI に新しいサブコマンド(auto-improve、pending-writes、curator)やフックの修正が含まれていないことを指摘し、**更新**を推奨してください。(サーバーの正確な.versionは/admin/statusで管理者のみ確認できます。ユーザーの OIDC/JWT では401になるため、サーバーに対するai-memory statusで確認しようとしないでください。確認可能な基準は最新リリースであり、MCP のinitialize` ハンドシェイクにもバージョンが含まれます。) .ai-memory.tomlがあるか。どのワークスペース/プロジェクトか。トラッキングポリシーは意図的なものか(安定したルーティングを共有するためにコミットするのか、ローカル専用として無視するのか)。- CLAUDE.md/AGENTS.md にルーティングのスニペットがあるか。
- スニペットで検索戦略を説明しているか。 現在のプロジェクトで見つからなかった場合に検索範囲を広げる指針がない古いスニペット、つまり
scopes/兄弟プロジェクトへの言及がない、またはmemory_queryがページ本文全体ではなく抜粋を返すという注意がないものを指摘してください。現在のテンプレートを再インストールすると、以下の内容が補完されます。memory_queryにはグローバル検索がないため重要です。現在のプロジェクトだけを検索して打ち切るエージェントは、兄弟プロジェクト(infra/ops)にある、複数プロジェクトにまたがる知識を見落とします。 - ai-memory MCP エントリがあるか。まずエージェントのグローバル設定を確認してください。MCP は通常そこにインストールされます(
~/.claude.jsonのトップレベルmcpServers、例:memory-personal、~/.codex/config.toml、OpenCode のグローバル設定)。その後でリポジトリ単位の.mcp.json/opencode.jsonを確認してください。リポジトリ単位の.mcp.jsonが空だからといって、「記憶の呼び出しがない」と判断しないでください。グローバルエントリはすべてのリポジトリに適用されます。リポジトリ単位の.mcp.jsonを使用している場合は、安定した非シークレット定義のみが含まれているか、それとも認証情報も含まれているかを調べ、トラッキングポリシーがリポジトリの慣例と一致していることを確認してください。共有 MCP を使うプライベート/チームリポジトリでは、.mcp.jsonをトラッキングしても問題ありません。 - Codex の場合、
~/.codex/hooks.jsonにグローバルな ai-memory フック(SessionStart、UserPromptSubmit、PreToolUse、PostToolUse、PreCompact、Stop)があり、ステージングされたスクリプトがプラットフォームの ai-memory フックディレクトリに存在するか。 - フックはネイティブで、認証済みか。 バイナリの
ai-memory hook --event …形式ではなく、カスタムオーバーレイ配下の手作業でパッチを当てたシェルスクリプト(例:Keycloak トークンを取得する_lib.shを読み込む~/.config/ai-memory/hooks/)を呼び出しているエージェントがあれば指摘してください。これらはアップストリームの修正(例:ハンドオフの挿入に必要なhookSpecificOutputJSON ラッパーとタブエスケープの修正)に追随できず、修正も反映されません。サーバーが/hook//handoffを保護している場合、フックがそのサーバーモードに適した認証情報を保持しているか確認してください(そうでない場合、CLI はローカルにスプールし、常に{}を返すため、キャプチャ時の 401 は気づかれないままになります)。static-bearer サーバーには--auth-tokenが必要です。OIDC/Keycloak ゲートウェイ(401 WWW-Authenticate: Bearer resource_metadata=…)にはデバイスフローのトークン(auth login oidc-device)が必要で、フックは--auth-tokenなしでインストールする必要があります。静的トークンはそこで拒否されます。オーバーレイへの依存を移行して解消するには、モードに応じて--auth-tokenの有無を切り替え、install-hooks --applyを再実行してください。 - 上限の 10000 件に達している、または近づいている
hook-spool:原因は異なる 2 種類です。いくつかのエントリのauth_mode/attempts/last_errorを確認し、原因を見分けてください。- 認証の誤り(修正可能):Keycloak/JWT ゲートウェイに対して
auth_mode: staticになっている状態です。attemptsが増加し、last_errorに 401 が表示され、8 回の試行後にエントリが削除されます。修正方法:デバイスフロー(auth login oidc-device)を使い、--auth-tokenなしでinstall-hooks --applyを実行し、滞留しているエントリをクリアします。 - 排出頻度の問題(認証の問題ではありません):
auth_mode: oidc(正しい)、attempts: 0、last_error: nullの状態です。配信は機能していますが、排出はsession-start/session-endでのみ実行されるため、長時間のセッションでは終了前にMAX_SPOOL_FILES(10000)を超え、最も古いエントリが破棄されます。境界で排出する(新しいセッションを開始する、またはsession-startフックを手動で実行して排出する)か、セッションを短くして対処してください。恒久的な修正はセッション中の段階的な排出です(アップストリームの対応事項です。hook-spool の配信信頼性改善作業を追跡してください)。同じデータディレクトリを使うすべてのエージェントでスプールは共有されるため、並行する長時間セッションのデータが一緒に蓄積されます。
- 認証の誤り(修正可能):Keycloak/JWT ゲートウェイに対して
- **MCP 認証(DCR):**エージェントの MCP ログインで Keycloak の 「Client not found」 が表示された場合、キャッシュされた Dynamic-Client-Registration ID が孤立しています(レルムの再作成/移行が原因です)。エージェントの MCP 認証キャッシュ(例:OpenCode の
~/.local/share/opencode/mcp-auth.json)から古いエントリを削除して再認証し、新しい DCR を強制してください。 - **MCP OAuth の検出失敗:**クライアントの
reauthでCould not discover OAuth endpoints from server responseというエラーが発生する場合(RFC 9728 → 8414 の検出をたどらない場合。OMP のネイティブ MCP クライアントで確認されています)、クライアント自身の Git 管理対象外設定でnpx -y mcp-remote <url> <port>を使ってリモートをstdioサーバーとしてブリッジし、コミット済みの.mcp.jsonは移植可能なtype: httpのままにしてください。検出と認可は成功するものの、トークン POST が 404 になる場合は、SDK がドメインルートの認可サーバーメタデータを検索し、パスベースの発行者の/<base>/realms/<realm>を落としています。ネイティブクライアント(Claude Code)は発行者相対の OIDC を通じて接続するため、エンドポイントが無効なのではなく、mcp-remoteのバージョンやフラグでは修正できません。サーバー側で、ルートの.well-known/oauth-authorization-server(およびopenid-configuration)をレルムにエイリアスするか、ネイティブクライアントを使ってください。詳しい手順はreferences/usage.mdの §MCP OAuth compatibility を参照してください。 - 2 インスタンス(例:クライアントの Keycloak)のリポジトリか。リポジトリに 2 つ目の MCP(クライアント/組織インスタンス)が登録されている場合、両方が読み取りと書き込みの両方に対応し、個人用インスタンスがより広い範囲をカバーしていることを確認してください。永続化する書き込みは両方に書き込みます。クライアントインスタンスへの自動キャプチャが必要な場合、プロジェクトレベルのフックは静的な
HOOK_AUTH_TOKENまたは保存済み OIDC デバイスフローのトークン(ai-memory auth login oidc-device …→resolve_bearerがヘッドレスで更新)を使ってそのインスタンスを参照します。キャプチャは可能であり、「不可能」ではありません。想起/書き込みではworkspaceとprojectを明示的に渡し(per_actorでフェイルクローズ)、その動作を確認してください。この 2 インスタンス構成/キャプチャ設定をハードコードした CLAUDE.md がコミットされている場合は指摘してください。これは共有のリポジトリ単位ブロックではなく、オペレーターのグローバル設定に含めるものです。 - **旧式の qmd か。**以下のいずれかがあれば指摘してください。
qmdMCP エントリ、CONVENTIONS.mdを含むwiki/ディレクトリ、リポジトリ単位の*/hooks/wiki-reindex.sh、CLAUDE.md/AGENTS.md の「Wiki (wiki/)」ブロック、.wiki-guardrails.yml。
インストール(新規プロジェクト)
- ワークスペースとプロジェクトをユーザーに確認します。
- ネイティブの
ai-memoryCLI がインストール済みで、正常に動作することを確認します(上記の「CLI の前提条件」を参照)。 上流のリリースアセットからインストール/アップグレードします(macOS ではai-memory-macos-<arch>.tar.gz、 Linux ではai-memory-linux-<arch>.tar.gzが提供されています。.sha256を検証してください)。対象アーキテクチャ向けのアセットがない場合に限り、cargo install/ソースからのビルドを使用します。明示的に依頼されない限り、Docker ラッパーは使用しないでください。 - リポジトリの状況とユーザーの入力に基づいて、
.ai-memory.tomlの追跡ポリシーを決定します。共有ルーティングが安定している プライベート/チームリポジトリの場合は、ファイルを作成し、追跡対象としてコミット可能な状態にします。 パブリックリポジトリ、個人のフォーク、またはオペレーターごとのルーティングの場合は、リポジトリローカルの.git/info/excludeに追加します。グローバルなcore.excludesfileは使用せず、ユーザーがローカルのみのルーティングを明示的に選択しない限り、 既存のマーカーを追跡対象から外さないでください。 - バイナリから正規のルーティングブロックを取得し(
memory_install_self_routingまたはai-memory install-instructions)、それをCLAUDE.mdとAGENTS.mdに書き込みます(冪等に処理し、/マーカーの間に配置し、すでに存在する場合は置き換えます)。手作業で管理したコピーを貼り付けないでください。 - リポジトリで使用するエージェントの設定に ai-memory MCP エントリを追加します。エントリが安定していて、
認証情報を含まない場合は、リポジトリで追跡する
.mcp.jsonに配置できます。個人用または認証情報を含む場合は、 エージェントのグローバル/ユーザー設定にインストールするか、.git/info/excludeを使ってローカルのみの状態にします。ユーザーがローカルのみの MCP 設定を明示的に依頼しない限り、git rm --cached .mcp.jsonを実行しないでください。 Codex の場合は、ai-memory install-mcp --client codex ... --applyを優先し、サーバーが~/.codex/config.tomlに配置されるようにします。 - アクティブなエージェントにグローバルな自動キャプチャフックがインストールされていることを確認します。Codex の場合は、
ai-memory install-hooks --agent codex --server-url https://memory.example.dev --applyを実行し、~/.codex/hooks.jsonとステージされたai-memory/hooks/codexスクリプトを確認します。 - 自動キャプチャが有効になったこと(グローバルフックと新しいマーカー)をユーザーに伝えます。想起は、 セッション開始時の引き継ぎとルーティングスニペットを通じて行われます。
migrate(brownfield:qmd → ai-memory)
まず doctor を実行し、その後、ユーザーの確認を得てから次の手順を実行します。
- Marker —
.ai-memory.toml(ワークスペース/プロジェクト)を書き込み、トラッキングポリシーを維持または選択します。プライベート/チームのリポジトリでは安定した共有ルーティングをコミットし、個人用/公開リポジトリでは.git/info/excludeを使ってルーティングをローカルのみにします。 - MCP —
.mcp.json/opencode.json/.codex/config.tomlで、qmdサーバーエントリーを ai-memory エントリーに置き換えます。リポジトリの既存のトラッキングポリシーを維持します。リポジトリで MCP を意図的に共有する場合は、安定した機密情報を含まないサーバー定義をコミットし、認証情報を含むエンドポイントや個人用エンドポイントはローカルまたはグローバルに保持します。 - CLAUDE.md/AGENTS.md — 「Wiki(
wiki/)」/qmd-MCP のブロックをルーティングスニペットに置き換えます。エージェントにqmdへの問い合わせやwiki/の管理を指示する項目は削除します。 - qmd 時代のアーティファクトをすべて削除します。 旧 qmd/wiki の設定ではフック以外にも多数のものがインストールされます。すべてを列挙して削除します。
.wiki-guardrails.yml(ガードレールの設定)。- フック —
.claude/hooks/wiki-*.sh(policy-check、reindex、drift-audit、suggest-ingest);.codex/hooks/wiki-*.sh(policy-check、reindex、drift-audit、consider)および.codex/hooks.json;.opencode/hooks/wiki-*.shおよび.opencode/plugins/wiki-guardrails.js。.claude/settings.jsonから該当するフックエントリーを削除し、.codex/config.tomlから[features] codex_hooks = trueも削除します(これは Codex の wiki フックを有効にするためだけに存在していました)。 opencode.jsonのpermission.skill."wiki-*"("aim-*"に置き換えるか、削除します)。- ANTIGRAVITY(リポジトリで使用している場合)— 管理対象の指示ブロックと
.antigravity*フック/設定を削除します。 - 自動キャプチャは ai-memory のグローバルフックから行われるようになったため、リポジトリごとのフックスクリプトは不要です。
- グローバル QMD チェックアウト/ラッパー(リポジトリ外のオペレーター側)— プロジェクトごとのラッパー(
~/.local/share/skills/qmd/wrappers/<project>-qmd、または以前の~/.local/share/essential-skills/qmd/...)と、管理対象のqmdチェックアウト/キャッシュは不要になっています。ラッパーを削除します。共有チェックアウトは、qmd を引き続き使用するリポジトリがほかにない場合にのみ削除します。 wiki/のコンテンツ — デフォルトでは履歴として残します。ユーザーが ai-memory への移行を希望する場合は、選択したワークスペース/プロジェクトに Markdown を取り込み(ファイルごとに 1 ページとし、リテラルのシークレットをすべて伏せます)、その後でwiki/を削除できます。明示的な確認なしにwiki/を削除しないでください。- doctor を再実行して、次の項目を確認します。マーカーが存在し、トラッキングポリシーが意図どおりであること、CLAUDE/AGENTS にスニペットがあること、ai-memory MCP が接続され、シークレットがコミットされていないこと、そして qmd の残存物がないこと(
.wiki-guardrails.yml、wiki-*フック/プラグイン、qmd MCP エントリー、codex_hooks/wiki-*の権限設定の残りがないこと)。
refresh(CLI をアップグレードし、フックを再ステージングして同等の状態にする)
すでに接続済みの環境がサーバーと異なる状態になった場合に使用します。CLI が古い場合や、サーバーのアップグレード後が対象です。マーカー/スニペット/MCP の変更は行わず、インストール済みの内容を検出して同等の状態にします。
- 現在の状態を検出します(読み取り専用)。ローカルの
ai-memory --versionと最新の上流リリースを比較します(gh release view -R akitaonrails/ai-memory --json tagName -q .tagName。サーバー自身の.versionは/admin/statusで管理者のみアクセス可能であり、一般ユーザーには401が返るため、リリースを確認可能な目標とします)。ai-memory フックを使用しているエージェントを確認します。ai-memory install-hooks --helpには、サポート対象の正式なエージェントが一覧表示されます(古い一部のエージェントを固定で指定しないでください):claude-code(~/.claude/settings.json)、codex(~/.codex/hooks.json)、gemini-cli(~/.gemini/settings.json)、antigravity-cli /agy(~/.gemini/config/hooks.json)、grok(~/.grok/hooks/ai-memory.json)、cursor(~/.cursor/hooks.json)、open-code(~/.config/opencode/plugins/)、omp(~/.omp/agent/extensions/)、openclaw。また、ai-memory auth statusで OIDC デバイストークンが有効か確認します。 - 最新リリースより古い場合は、CLI をアップグレードします(「CLI の前提条件」を参照)。
ai-memory-<os>-<arch>.tar.gzアセットをダウンロードし、その.sha256を検証して、現在のバイナリをバックアップしてから~/.local/bin/ai-memoryに上書きインストールします。ai-memory --versionがサーバーのバージョン以上になったことを確認します。 - 検出されたすべてのエージェントのフックを再ステージングします:
ai-memory install-hooks --apply --agent <agent> --server-url <capture-url>(OIDC/Keycloak サーバーの場合は--auth-tokenを指定しません。静的ベアラーの場合は--auth-tokenを指定します)。ステージングしたスクリプトを再検証し、エージェントの設定を更新します(バックアップを作成します)。ネイティブフック(ai-memory hook --event …)は新しいバイナリを自動的に使用します。この操作では、設定とステージング済みのフォールバックスクリプトが更新され、古い_lib.shオーバーレイが削除されます。 - 検証します:
ai-memory --versionがサーバーと一致していること、ai-memory auth statusでログイン済みと表示されること、エージェントの設定が引き続きai-memory hook --eventをネイティブに呼び出していること、<data_dir>/hook-spoolが上限の 10000 を大幅に下回っていることを確認します。 - ≥ 2.0 の注意事項:
install-hooks --applyはベアラーを<data_dir>/auth-token(0600)に保存するようになり、生成される TypeScript インテグレーションにresolveToken()ヘルパーを生成します。管理対象の Agent Skills が変更されたため、memory_install_self_routing(またはai-memory install-instructions)で更新してください。Codex は次回起動時に Hooks need review と確認を求めます。信頼してください。CLI ≥ 2.0 は、フックに関して 1.3x のサーバーと問題なく通信できます(/hook/batchに変更はありません)。ただし、同じ日にまずサーバーをアップグレード(aim-ops upgrade)してから、クライアントをアップグレードしてください。
refresh はマーカー、ルーティングスニペット、MCP エントリには触れません(バージョンに依存せず、スニペットはバイナリが管理するため)。これらを更新するには install / migrate を実行してください。フックはグローバル(すべてのエージェントで 1 つのデータディレクトリを共有)なので、一度更新すれば、現在のリポジトリだけでなく、接続済みのすべてのリポジトリが更新されます。
検証
git check-ignore .ai-memory.toml→ 無視される(コミットされない)。- ルーティングスニペットが CLAUDE.md と AGENTS.md のマーカー間に 1 回だけ存在する。
qmdMCP エントリ/wiki-reindexフックが残っていない(migrate の場合)。- キャプチャが一往復すること:リポジトリ内の実際のエージェントセッションによって、選択したワークスペース/プロジェクトの下にページが作成される(
aim-status/memory_statusまたは/api/v1/projectsで確認)。
マルチユーザーモード(任意)
上記の手順は、単一オペレーターの場合(1 人の人間、1 つの ai-memory インスタンス)を対象としています。複数の人間で 1 つのインスタンスを共有する場合、または 1 人のオペレーターが複数の Claude Code ウィンドウ間でリポジトリを厳密に分離したい場合は、エンジンをマルチユーザーモードに切り替え、各ユーザーを明示的にオンボーディングしてください。このワークフローは ai-memory CLI に組み込まれています。
**前提条件:**エンジンで [auth].token_pepper が設定されている必要があります(ai-memory init によって自動生成されます。設定されていない場合、マルチユーザー管理エンドポイントは 503 を返します)。curl <endpoint>/admin/status または ai-memory status で確認してください。
ユーザーごとのセットアップ(標準:1 人につき 1 つの ID)
-
エンジンにユーザーを作成します(root token が必要です)。トークンは一度だけ表示されます。
ai-memory user add --username alice --email alice@home # → {"id": "...", "username": "alice", "token": "<COPY-THIS-NOW>"}ライフサイクルのサブコマンド:
user list(トークンは表示されません)、user expire/revive、user rotate-token(新しい平文トークンを一度だけ発行します)。 -
そのユーザーのベアラーを設定したフックをインストールします。その人が使用するエージェント CLI ごとに 1 つのコマンドを実行します (
claude-code、codex、cursor、gemini-cli、open-code、omp、openclaw、antigravity-cli)。ai-memory install-hooks --apply \ --agent codex \ --as-user alice \ --auth-token <alice-token>これらのハーネスでは、
--agent claude-codeまたは--agent open-codeを使用します。--applyはエージェントの設定をその場で変更します(冪等で、タイムスタンプ付きのバックアップを書き込みます)。 デフォルトではグローバルなフック設定(~/.claude/settings.json、~/.codex/hooks.json、 OpenCode プラグイン設定など)を対象にします。 代わりにプロジェクトレベルの設定を対象にするには、--config-file ./.claude/settings.jsonを渡します (下記の「コンテキストごとのトークン」を参照)。 -
フックと同じユーザーとして MCP ツール呼び出しを認証できるよう、MCP エントリーにベアラーを設定します。
{ "mcpServers": { "memory-personal": { "type": "http", "url": "https://memory.example.dev/mcp", "httpHeaders": { "Authorization": "Bearer <alice-token>" } } } }ai-memory install-mcp --apply --auth-token <alice-token>を実行すると、このエントリーが自動的に書き込まれます。 -
エンジンを
per_actorモードで実行します(チャート設定:aiMemory.autoScope.mode: per_actor)。 アクティブなプロジェクトのマップは(user, session_id)をキーにし、ユーザーのみを使うフォールバックもあります。 セッション ID のないプローブで Alice が Bob の最後のプロジェクトを引き継ぐことはなく、Alice の書き込みが Bob のスロットに公開されることもありません。
コンテキストごとのトークン(エージェントフックを使わずに並行セッションを分離)
同じ人が異なるリポジトリで Claude Code のウィンドウを 2 つ同時に開いている場合、MCP ツール呼び出しではフックの
session_id が転送されないため、エンジンは両方のウィンドウを 1 つのユーザー専用スロットにまとめます。回避策として、各リポジトリを個別の論理ユーザーとして扱います。
ai-memory user add --username alice-foo --email [email protected] # token T-foo
ai-memory user add --username alice-bar --email [email protected] # token T-bar
各リポジトリのプロジェクトレベルの .claude/settings.json(Claude Code はプロジェクトレベルの設定を
グローバル設定とマージします)で、個別のトークンを指定します。
{
"mcpServers": {
"memory-personal": {
"type": "http",
"url": "https://memory.example.dev/mcp",
"httpHeaders": { "Authorization": "Bearer <T-foo>" }
}
}
}
同じスコープでフックをインストールします。
cd ~/repo-foo && ai-memory install-hooks --apply \
--as-user alice-foo --auth-token T-foo \
--config-file ./.claude/settings.json
これで 2 つのウィンドウはエンジンに別々のユーザーとして認証され、per_actor のキー設定によって
それぞれのスロットが自動的に分離されます。運用コストは、実際のユーザー 1 人あたり N 個のトークン × 分離が必要な M 個のリポジトリです。このトレードオフは、並行セッションの分離が本当に必要な場合には許容できます。それ以外の場合は、上記のユーザーごとのセットアップで十分です。
サーバー側のスコープガード(多層防御)
エンジンにはアドミッション Webhook チェーンが組み込まれています。運用チャートには、ユーザーごとの書き込み範囲を適用する
オプションの scope-guard Webhook が含まれています。これは user → [(workspace pattern, project pattern), …] 形式の ACL です。
トークンが誤った .ai-memory.toml や MCP 設定に貼り付けられた場合でも、エンジンはアドミッション時に書き込みを拒否します。
# values.yaml
webhooks:
scopeGuard:
enabled: true
rules:
alice: [{ workspace: "alice|shared", project: ".*" }]
client-x: [{ workspace: "client-x|shared", project: ".*" }]
scope-guard を有効にする場合、ACL ですべての書き込みが拒否されないよう、書き込みの actor が空であってはなりません。 ACL は ActorContext.user をキーにします。OIDC クライアントは JWT(preferred_username)にユーザー情報を含めるため、複数ユーザーのインスタンスでもルールに自然に一致します。一方、静的な HOOK_AUTH_TOKEN でフックを認証するクライアントでは、mcpAuth.hookAuth.username(→ HOOK_AUTH_USERNAME。フックトークンによるリクエストに mcp-auth が設定するユーザー名)も、ACL で許可されたユーザーに設定しない限り、actor が空になります。設定を忘れると、静的トークンによるフックのキャプチャはすべてアドミッション時にサイレントに 403 で拒否され、エンジンログにしか現れません(scope-guard: user '' not allowed to write_page …)。aiMemory.rootUsername ではこの問題を解決できないことに注意してください。この設定が適用されるのは階層 1/MCP パスであり、フックパスではありません。そのため、scopeGuard を有効にする単一オペレーターの静的トークンインスタンスでは、mcpAuth.hookAuth.username(=ACL のユーザー)を設定する必要があります。複数ユーザーのインスタンスでは、代わりに OIDC を使用してください(フックユーザー名を共有しないでください)。
読み取りはゲートされません。エンジンには読み取り側のアドミッションチェーンがありません。実際の読み取りプライバシー(悪意あるユーザーへの対策)が必要な場合は、信頼境界ごとに ai-memory のインスタンスを分けて実行してください。
マルチユーザー向けの Doctor チェック
上記のシングルユーザー向けチェックに加え、マルチユーザー構成の doctor では、以下を報告する必要があります。
- エンジンで
[auth].token_pepperが設定されていること ai-memory user listが想定されるユーザーを返すこと- エージェントの MCP 設定(
~/.claude/settings.json、~/.codex/config.toml、OpenCode の設定、またはプロジェクトレベルの同等の設定)にAuthorization: Bearer …が含まれていること - アクティブなフック設定に
--as-userが指定されていること(すべてのフック呼び出しで、ルートトークンではなくユーザーの Bearer トークンを使用します) - autoscope が
per_sessionで、MCP クライアントがsession_idを転送しない場合、モードが警告なく単一スロットに縮退していることを警告し、代わりにper_actorを推奨すること
リコールモデル(プロジェクトごとの引き継ぎ、自動キャプチャ、MCP ツール)については、references/usage.md をご覧ください。手動でのリコール/書き込みについては、aim-query / aim-write をご覧ください。