mcpField
M
Memora

Memora

ローカル
github.com/agentic-mcp-toolsメモリ・ナレッジ7461 日前に更新

Memora について

Memora は、複数セッションにまたがるコンテキストが必要なワークフロー向けに、構造化ストレージ、セマンティック検索、グラフ関係を備える AI エージェント用の共有メモリレイヤーです。情報を重複排除とバージョン系譜で整理し、トピックに関連する記憶、TODO、ソースをまとめて取得できます。

主な機能

  1. 01永続ストレージと複数データベースのルーティング
  2. 02情報の取り込みと重複・更新の検出
  3. 03置き換えられた記憶の系譜を保持
  4. 04セマンティック・全文・ハイブリッド検索
  5. 05ドキュメント断片、TODO、課題の管理
  6. 06インタラクティブなナレッジグラフとメモリ分析

活用シーン

  1. 01セッションをまたいでエージェントの文脈を保持
  2. 02トピック関連の記憶、TODO、ソースを取得
  3. 03知識の更新と履歴を管理
  4. 04ドキュメント断片を検索して記憶の関係を確認

MCP 対応

Memora は MCP サーバーとして、記憶の保存、取り込み、検索、ダイジェスト、管理用ツールをクライアントに公開します。ローカル stdio または HTTP トランスポートで実行できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

インストール方法は未掲載です

このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。

リポジトリ

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

Memoraのロゴ Memora

「その瞬間が思い出になるまで、その価値に気づくことはありません。」

AI エージェントに、永続的な共有メモリを提供します
エージェント向けの MCP メモリレイヤーです。構造化ストレージ、セマンティック検索、グラフリレーション、ソースに基づくセッションをまたいだコンテキストを提供します。

バージョン ライセンス Awesome Claude Codeで紹介

Memoraの吸収・要約フロー

エージェントの作業を永続的なグラフメモリに取り込み、memory_digest(topic)を使って、関連するメモリ、TODO/課題、関連エッジ、ソースIDを取得します。

機能 · プレビュー · インストール · 使い方 · 設定 · 複数データベース · コンテナー · ライブグラフ · クラウドグラフ · チャット · セマンティック検索 · ドキュメント · LLMによる重複排除 · リンク · Neovim

## 特長

コアストレージ

  • 💾 永続ストレージ - オプションのクラウド同期(S3、R2、D1)に対応した SQLite
  • 🗄️ マルチデータベースルーティング - 1つのプロセスで複数のストアを提供し、各ワークスペースは /mcp/<name> から自身のストアにアクセスします(マルチデータベースルーティングを参照)
  • 📂 階層的な整理 - セクション/サブセクション構造と階層の自動割り当て
  • 📦 エクスポート/インポート - マージ戦略によるバックアップと復元

取り込みと系譜

  • 🧬 取り込み - ファクトを入力すると、LLM がストアの内容と照らして各ファクトを分類します(重複/更新/矛盾/関連/新規)。重複をスキップし、関連をリンクして、関連するファクトを統合します。dry_run によるプレビューにも対応しています
  • 🌱 置き換えの系譜 - 知識を削除せず、更新によって古い知識を置き換えます。デフォルトでは、検索時にチェーンをたどって現行バージョンを取得します(follow モード:active、latest、full_history)
    • いずれかのバージョンを削除すると、系譜全体が無効になります(削除されたファクトが古いバージョンとして再表示されることはありません)。follow=latest/active ではすべてのバージョンが非表示になり、そのうちの1つに対する memory_get は削除内容を示す retired: true と「#N を削除したことで無効になりました」を伴う not_found を返します。follow=all では引き続き読み取ることができ、無効化された ID に supersedes エッジを追加しても復元されません。
    • memory_absorb は項目レコード(metadata.kind = "item-record" またはタグ item-record)を置き換えません。ファクトは書き込まれ、代わりに related_to としてリンクされます。Todo と issue は型の境界によって保護されており、通常のファクトが型付きデータを置き換えることはありません。
  • 🗞️ トピックダイジェスト - memory_digest(topic) は、関連するメモリ、未完了の TODO/issue、関連エッジ、ソース ID を1つの検索結果にまとめます

検索とインテリジェンス

  • 🔍 セマンティック検索 - ベクトル埋め込み(TF-IDF、sentence-transformers、OpenAI)
  • 🎯 高度なクエリ - 全文検索、日付範囲、タグフィルター(AND/OR/NOT)、ハイブリッド検索
  • 🔀 相互参照 - 類似度に基づいて関連メモリを自動リンク
  • 🤖 LLM による重複排除 - AI を活用した比較で重複を検出し、統合
  • 🔗 メモリのリンク - 型付きエッジ、重要度の引き上げ、クラスター検出

ドキュメントストレージ

  • 📄 構造化ドキュメント - Markdown ドキュメントを、検索可能なフラグメントツリー(主張、計画項目、参照、リスク)として保存
  • 🔒 フラグメントの完全性 - ドキュメントフラグメントの誤削除、誤マージ、誤取り込みを防止
  • 🔍 詳細検索 - 個々の主張や調査結果をセマンティック検索でき、ドキュメント全体もひとまとまりで取得できます

ツールと可視化

  • ⚡ メモリの自動化 - TODO、issue、セクション向けの構造化ツール
  • 🕸️ ナレッジグラフ - Mermaid による描画とクラスターのオーバーレイに対応したインタラクティブな可視化
  • 🌐 ライブグラフサーバー - クラウドホスト型オプション(D1/Pages)を備えた組み込み HTTP サーバー
  • 💬 メモリとのチャット - LLM のツール呼び出しを活用する RAG チャットパネルから、ストリーミングチャットでメモリを検索、作成、更新、削除
  • 📡 イベント通知 - エージェント間通信のためのポーリング方式システム
  • 📊 統計と分析 - タグの使用状況、傾向、接続に関する分析
  • 🧠 メモリインサイト - アクティビティの要約、古いメモリの検出、統合の提案、LLM を活用したパターン分析
  • 📜 操作履歴 - すべてのメモリ操作(作成、更新、削除、マージ、重要度の引き上げ、リンク)を、グループ化されたタイムライン表示で追跡

JSON API(/api/v1)

サーバーは、/api/v1/<store>/{health,search,absorb} にプレーンな JSON API を公開できます (ワイヤーコントラクトは contracts/memora-api/v1/ です)。MEMORA_API_TOKENS_FILE に絶対パスが設定されていない場合は無効です。変数が未設定の状態は意図されたもので、ERROR ではなく INFO としてログに記録されます(issue 1131)。

このファイルにはトークンではなく、sha256 ダイジェストが格納されます。サーバーはファイルを O_RDONLY | O_NOFOLLOW | O_CLOEXEC で開き、通常ファイルであること、グループおよびその他のユーザーに対する権限ビットが設定されていないこと、サイズが 4 KiB 以下であること、サーバーのユーザーが所有していること、親ディレクトリがシンボリックリンクではなく、グループまたは全ユーザーが書き込み可能でないことを要求します。読み取り専用マウント(たとえば、rootful docker がオペレーターのファイルを root として読み込み、statvfs が ST_RDONLY を報告する、デプロイ時の読み取り専用シークレットマウント)では、ファイルおよび読み取り専用の親ディレクトリの所有者が一致している必要はありません。それ以外のチェックはすべて適用されます。再読み込みに失敗した場合は、最後に正常に読み込まれたトークンセットが維持されます。

scripts/mint_api_token.sh は、新しい 0600 ファイルにトークンを発行し、そのダイジェストを api-tokens.json に追加します。scripts/deploy-memora-all.sh は、そのファイルがシークレットディレクトリにある場合に MEMORA_API_TOKENS_FILE を設定します。リクエストの動作(401/403/404)とローテーションについては、コントラクトを参照してください。

プレビュー

Memora のメモリーグラフのデモ Memora のメモリー操作のデモ

インストール

方法は 2 つあります。pip は、クライアントが起動するローカルの stdio 子プロセスです。コンテナは、up で起動するデタッチされた HTTP サービスです。MEMORA_DATABASES を指定すると、1 つのプロセスで複数のストアを提供できます。LaunchAgent が監視するのはプロキシであり、コンテナではありません。そのため、ホストの再起動後、リスナーが再起動しても、アップストリームは停止したままの場合があります。memora をサービスとして実行する場合は、コンテナの方法がそのままインストール方法です。

pip(ローカル / stdio)
pip install memora-mcp

PyPI パッケージ名は memora-mcp です(PyPI の memora は無関係な別プロジェクトです)。クラウドストレージ(S3/R2)と OpenAI のエンベディングが最初から含まれています。

# Optional: local embeddings (offline, ~2GB for PyTorch)
pip install "memora-mcp[local]"

# Latest development version straight from git
pip install "git+https://github.com/agentic-box/memora.git"

その後、.mcp.json から "command": "memora-server" を指定して起動します(設定を参照してください)。

コンテナ(HTTP サービス)

デフォルトのランタイムは Apple の container CLI です。scripts/memora-instance.sh が実行するすべてのコンテナ操作(build、up、status、logs、down)では、$MEMORA_CONTAINER_BIN(デフォルトは container)を使用します。生成されるプロキシプロセスはこれを使用せず、container list をハードコードしています。

最初の build の前に:

  1. Apple の container CLI(GitHub のリリースから署名済み pkg)をインストールします。Apple silicon を搭載し、macOS 26 を実行している Mac が必要です。Apple は container について、それより古い macOS バージョンをサポートしていません。

  2. ランタイムを起動します。以下は Apple がドキュメントで案内している最初のコマンドで、カーネルが設定されていない場合はカーネルもインストールします。

    container system start
    
  3. このリポジトリをクローンし、そのディレクトリに cd で移動します。

    git clone https://github.com/agentic-box/memora.git
    cd memora
    
  4. インスタンステンプレートをコピーします。INSTANCE=myinstance が設定されているため、名前を変更しなくても後続の build/up/proxy の行と一致します。PORT とバックエンド(STORAGE_URI、VOLUME、または MEMORA_DATABASES)を編集します。

    cp instances/example.env instances/myinstance.env
    
  5. 認証情報ファイルを作成し、LaunchAgent が実行するプロキシをインストールします。cred_args() は、mcpServers.memora.env に CLOUDFLARE_API_TOKEN(D1 アクセス用)と埋め込み/LLM キーを含む .mcp.json を必要とします。このファイルがないと up は失敗します。インスタンスファイルで CRED_SOURCE に別のパスを指定しない限り、スクリプトは ~/.config/memora/credentials.mcp.json を探します。ほかにフォールバックはありません。別途、proxy は、実行ファイルが $MEMORA_PROXY_BIN(デフォルトは ~/.local/libexec/memora/memora_proxy.py)、ログの保存先が $MEMORA_LOG_DIR(デフォルトは ~/.local/var/log)となる plist を生成します。新しいクローンでは、どちらも自動作成されません。

    mkdir -p ~/.config/memora ~/.local/libexec/memora ~/.local/var/log
    cp scripts/memora_proxy.py ~/.local/libexec/memora/
    # real values; any key is fine, an absent file is not
    # the default umask is permissive -- chmod 600 keeps other local accounts out
    cat > ~/.config/memora/credentials.mcp.json <<'JSON'
    {"mcpServers":{"memora":{"env":{"CLOUDFLARE_API_TOKEN":"REPLACE","OPENAI_API_KEY":"REPLACE"}}}}
    JSON
    chmod 600 ~/.config/memora/credentials.mcp.json
    

    この JSON は最小限かつ正しい設定です。LLM と埋め込みの両方で、実際の OpenAI キーを使ってデフォルトの OpenAI ホストに接続します。埋め込みに記載されている埋め込み用のペアキーを設定せずに、OpenRouter を指す OPENAI_BASE_URL を追加しないでください。OpenRouter には埋め込みエンドポイントがないため、すべての埋め込み呼び出しが 404 になり、memora は正常に動作しているように見えながら、TF-IDF のキーワードバッグにひそかにフォールバックします。

次に、以下を実行します。

./scripts/memora-instance.sh build myinstance   # tags IMAGE from myinstance.env (memora-pilot if IMAGE is unset)
./scripts/memora-instance.sh up      myinstance # runs that same IMAGE
./scripts/memora-instance.sh proxy   myinstance # render the LaunchAgent; run the printed launchctl

up はホストポートを公開しません。ワークスペースが接続するリスナーはプロキシです。proxy は macOS の LaunchAgent を生成するだけで、launchctl コマンドを表示します。サービスは読み込みません。表示されたコマンドを実行してください。

表示されるワークスペース URL は常に http://127.0.0.1:<PORT>/mcp(レジストリのデフォルト)です。デフォルト以外のストアの場合は、自分で /<name> を追加してください。レジストリで /mcp のみを指定すると、MEMORA_DEFAULT_DB にひそかにバインドされます。

{"mcpServers": {"memora": {"type": "http", "url": "http://127.0.0.1:<PORT>/mcp/<store>"}}}

プロキシの仕組み、認証情報、インスタンスファイル、MEMORA_CONTAINER_BIN については、コンテナデプロイを参照してください。

使い方

Claude Code で設定すると、サーバーは自動的に実行されます。手動で実行する場合:

# Default (stdio mode for MCP)
memora-server

# With graph visualization server
memora-server --graph-port 8765

# HTTP transport (alternative to stdio)
memora-server --transport streamable-http --host 127.0.0.1 --port 8080
設定
Claude Code

プロジェクトのルートにある .mcp.json に追加します。

ローカル DB:

{
  "mcpServers": {
    "memora": {
      "command": "memora-server",
      "args": [],
      "env": {
        "MEMORA_DB_PATH": "~/.local/share/memora/memories.db",
        "MEMORA_ALLOW_ANY_TAG": "1",
        "MEMORA_GRAPH_PORT": "8765"
      }
    }
  }
}

クラウド DB(Cloudflare D1)— 推奨:

{
  "mcpServers": {
    "memora": {
      "command": "memora-server",
      "args": ["--no-graph"],
      "env": {
        "MEMORA_STORAGE_URI": "d1://<account-id>/<database-id>",
        "CLOUDFLARE_API_TOKEN": "<your-api-token>",
        "MEMORA_ALLOW_ANY_TAG": "1"
      }
    }
  }
}

D1 では、ローカルの可視化サーバーを無効にするため --no-graph を使用します。代わりに、Cloudflare Pages の URL でホストされているグラフを使用してください(クラウドグラフを参照)。

d1:// をプライマリに指定すると、そのデータベースの読み取りレプリケーションが無効になっていない限り、起動に失敗します(読み取りレプリケーションが有効な間は、セッションブックマークによる REST の読み取り後書き込みが機能しません)。MEMORA_D1_ALLOW_READ_REPLICATION=1 を設定すると、警告をログに記録して起動します。

クラウド DB(S3/R2)— 同期モード:

{
  "mcpServers": {
    "memora": {
      "command": "memora-server",
      "args": [],
      "env": {
        "AWS_PROFILE": "memora",
        "AWS_ENDPOINT_URL": "https://<account-id>.r2.cloudflarestorage.com",
        "MEMORA_STORAGE_URI": "s3://memories/memories.db",
        "MEMORA_CLOUD_ENCRYPT": "true",
        "MEMORA_ALLOW_ANY_TAG": "1",
        "MEMORA_GRAPH_PORT": "8765"
      }
    }
  }
}
Codex CLI

~/.codex/config.toml に追加します。

[mcp_servers.memora]
  command = "memora-server"  # or full path: /path/to/bin/memora-server
  args = ["--no-graph"]
  env = {
    AWS_PROFILE = "memora",
    AWS_ENDPOINT_URL = "https://<account-id>.r2.cloudflarestorage.com",
    MEMORA_STORAGE_URI = "s3://memories/memories.db",
    MEMORA_CLOUD_ENCRYPT = "true",
    MEMORA_ALLOW_ANY_TAG = "1",
  }
環境変数 | 変数 | 説明 | |------------------------|-----------------------------------------------------------------------------| | `MEMORA_DB_PATH` | ローカル SQLite データベースのパス(デフォルト:`~/.local/share/memora/memories.db`) | | `MEMORA_STORAGE_URI` | ストレージ URI:`d1:///`(D1)または `s3://bucket/memories.db`(S3/R2)。`MEMORA_DATABASES` が未設定の場合に使用されます。 | | `MEMORA_DATABASES` | このプロセスが提供する各ストアを対応付ける JSON オブジェクト `{name: uri}`。名前は URL パスの 1 セグメント(`/mcp/`)で、使用できるのは英字、数字、`-`、`_`、`.` のみです。キーの重複、空の値、安全でない名前、またはオブジェクト以外が指定されると、ストアを黙って選択するのではなく、起動を拒否します。未設定の場合は単一ストア(従来の動作)です。[複数データベースのルーティング](#multi-database-routing)を参照してください。 | | `MEMORA_DEFAULT_DB` | レジストリに複数のデータベースがある場合、裸の `/mcp` が使用するレジストリ名です。レジストリに名前が 1 つだけある場合は、その名前がデフォルトになります。レジストリにない値を指定すると、起動を拒否します。 | | `CLOUDFLARE_API_TOKEN` | D1(`d1://` URI)用の API トークンです。別名として `CF_API_TOKEN` も使用できます。 | | `MEMORA_D1_ALLOW_READ_REPLICATION` | 読み取りレプリケーションが有効な場合、またはそのモードを読み取れない場合に、`d1://` プライマリでの起動を許可するには `1` を設定します。それ以外の値では引き続き起動を拒否します。起動のたびに警告をログに記録します。 | | `MEMORA_CLOUD_ENCRYPT` | S3/R2 へのアップロード前にローカルファイルを暗号化します。未設定/`false`=無効、`1`/`true`/`yes`=有効です。 | | `MEMORA_CLOUD_COMPRESS`| S3/R2 へのアップロード前にローカルファイルを圧縮します。未設定/`false`=無効、`1`/`true`/`yes`=有効です。 | | `MEMORA_CACHE_DIR` | S3/R2 と同期するデータベース用のローカルキャッシュディレクトリです。未設定の場合、バックエンドがキャッシュパスを選択します。 | | `MEMORA_ALLOW_ANY_TAG` | 許可リストとの照合による検証を行わず、任意のタグを許可します(有効にするには `1` を設定) | | `MEMORA_TAG_FILE` | 許可するタグの配列を含む JSON ファイルのパスです。例:`["plan", "memora/issues"]` | | `MEMORA_TAGS` | 許可するタグをカンマ区切りで指定します | | `MEMORA_HOST` | HTTP トランスポートのバインドアドレス(デフォルト `127.0.0.1`)。`--host` で上書きできます。 | | `MEMORA_PORT` | HTTP トランスポートのバインドポート(デフォルト `8000`)。`--port` で上書きできます。 | | `MEMORA_GRAPH_PORT` | ナレッジグラフ可視化サーバーのポート(デフォルト:`8765`) | | `MEMORA_TRANSPORT` | `stdio`(デフォルト)、`sse`、または `streamable-http`。不明な **環境変数** の値は `stdio` にフォールバックしますが、`--transport` では不明な値を拒否します。複数データベースのルーティングとセッションガードは `streamable-http` でのみ実行されます。 | | `MEMORA_TOOL_PROFILE` | クライアントに公開するツールのサブセット:`full`(デフォルト、全 44 個)、`leader`(19 個)、`agent`(12 個)。未設定/空の場合は `full` です。不明な値を指定すると、起動を拒否します。[ツールプロファイル](#tool-profiles)を参照してください。 | | `MEMORA_MAX_SESSIONS` | 同時 MCP セッション数の絶対上限(デフォルト `128`)。`0` で無効になります。作成レートとアイドルタイムアウトだけでは上限になりません。セッション ID を維持するクライアントは、作成レートで際限なくセッションを増やせます。無効な値を指定すると、起動を拒否します。`streamable-http` のみ。 | | `MEMORA_MAX_INIT_PER_MIN` | 1 分あたりに受け入れる新規セッション数(デフォルト `120`)。`0` で無効になります。無効な値を指定すると、起動を拒否します。`streamable-http` のみ。 | | `MEMORA_MAX_INIT_BODY_BYTES` | 受け入れ、バッファーに格納する初期化リクエスト本文の最大サイズ(デフォルト `65536`、最小 `1024`)。これを超えるリクエストには `413` が返されます。無効な値を指定すると、起動を拒否します。`streamable-http` のみ。 | | `MEMORA_SESSION_IDLE_TIMEOUT` | 放棄された有効なセッションを削除するまでの秒数(デフォルト `1800`)。`0` で無効になります。無効な値を指定すると、起動を拒否します。`streamable-http` のみ。 | | `MEMORA_HEALTH_TOKEN` | 詳細な `/health/db` 本文(名前、件数、エラーテキスト)を取得するためのベアラートークンです。未設定の場合、ループバックの接続元にのみ詳細を表示し、それ以外には集約ステータスを返します。MCP 認証が設定されていても、FastMCP の `custom_route()` は認証されません。HTTP トランスポートのみ(`memora.health` は SSE/streamable-http 用にインポートされ、stdio 用にはインポートされません)。 | | `MEMORA_ADMIN_TOKEN` | `/admin/*` オペレータールート(`memora/admin.py`)用のベアラートークンです。32 文字以上で、`MEMORA_HEALTH_TOKEN` と異なる必要があります。そうでない場合、サーバーは起動を拒否します。未設定の場合、すべての `/admin/*` ルートは 403 を返します。ループバックの例外はありません。インスタンス起動スクリプトがトークンを生成して渡します(`~/.config/memora/.admin-token`)。HTTP トランスポートのみ。 | | `MEMORA_DATA_VOLUME` | 起動スクリプトが設定する、`/data` にマウントされたボリューム名です。データディレクトリ(`MEMORA_DATA_DIR`、デフォルト `/data`)に状態を保持するストア(その中のローカル SQLite パス、および書き込みゲートと意図ジャーナルがこのディレクトリにあるすべての `d1://` ストア)は、この値が設定され、匿名の 64 桁の 16 進数ボリューム ID ではなく、ディレクトリがマウントポイントであり、プローブファイルをそのディレクトリおよび `intent/` 内で書き込み、fsync し、削除できる場合を除き、起動を拒否されます。拒否はストアごとに行われ、`/health/db` に理由が表示されます。 | | `MEMORA_HEALTH_TTL` | 準備状態のスナップショットを更新が必要になるまで配信できる秒数(デフォルト `10`、上限 `3600`)。`> 0` である必要があります。無効な値を指定すると、起動を拒否します。HTTP トランスポートのみ。形式が不正な値でも stdio は中断されません。 | | `MEMORA_HEALTH_TIMEOUT`| 1 回の更新処理と各ストアのプローブに設定する上限時間(デフォルト `15`、上限 `300`)。`> 0` である必要があります。HTTP トランスポートのみ。 | | `MEMORA_HEALTH_REFRESH_INTERVAL` | サーバーが準備状態を自動更新する間隔(デフォルト `15`、上限 `3600`)。`0`=ポーリングのみです。これを設定しない場合、プロキシ経由のデプロイではループバックの呼び出し元が存在せず、すべてのデータベースが正常でもアラートの状態は `unknown` のままになります。定期更新が有効な場合、`interval + timeout` は `MEMORA_HEALTH_MAX_STALE` 未満である必要があります。HTTP トランスポートのみ。 | | `MEMORA_HEALTH_MAX_STALE` | キャッシュされたデータベースごとの結果を準備完了として報告できなくなるまでの経過時間(デフォルト `60`、上限 `3600`)。`MEMORA_HEALTH_TTL` 以上である必要があります。HTTP トランスポートのみ。 | | `MEMORA_STALE_DAYS` | 同じ名前に 2 つの用途、2 つのデフォルト値があります。`memory_insights` は未完了の TODO/issue を **14** 日経過後に古いものとして扱い、グラフ UI は完了した項目を **30** 日経過後にグレー表示します。この変数を設定すると、両方を上書きできます。 | | `MEMORA_EMBEDDING_MODEL` | 埋め込みバックエンド:`openai`(デフォルト)、`sentence-transformers`、または `tfidf` | | `SENTENCE_TRANSFORMERS_MODEL` | sentence-transformers 用のモデル(デフォルト:`all-MiniLM-L6-v2`) | | `MEMORA_EMBEDDING_API_KEY` | 埋め込みプロバイダーの API キー(ベース URL と一括で設定してください。以下を参照) | | `MEMORA_EMBEDDING_BASE_URL` | 埋め込みプロバイダーのベース URL(API キーと一括で設定してください。以下を参照) | | `MEMORA_EMBEDDING_STRICT` | **`1` を推奨します。** 埋め込みエラー時に、黙って TF-IDF に切り替えるのではなく、エラーで停止します。設定しない場合、エンドポイントが壊れていても応答を続ける一方で、すべてのベクトルがキーワードの寄せ集めになってしまいます(756 件のメモが気付かれないまま劣化したときのように)。 | | `OPENAI_API_KEY` | `MEMORA_EMBEDDING_*` が設定されている場合、**LLM 専用**(重複排除/チャット)です。`MEMORA_EMBEDDING_API_KEY` と `MEMORA_EMBEDDING_BASE_URL` の**両方**が未設定の場合に限り、埋め込みではこのキーにフォールバックします | | `OPENAI_BASE_URL` | **LLM** のベース URL(OpenRouter、Azure など)。キーと同じ一括フォールバックルールが適用されます。分割設定を使用する場合、埋め込み用 URL ではありません | | `OPENAI_EMBEDDING_MODEL` | openai 埋め込みバックエンド用のモデル ID です。**埋め込み**ホスト上に存在する必要があります(デフォルトの `text-embedding-3-small` は OpenAI 専用です。Cloudflare では `@cf/baai/bge-m3` などが必要です) | | `MEMORA_LLM_ENABLED` | LLM による重複排除の比較を有効にします(`true`/`1`/`yes`。デフォルト:`true`) | | `MEMORA_LLM_MODEL` | 重複排除の比較に使用するモデルです。未設定の場合は、クエリの書き換えとローカルチャットにも使用されます(デフォルト:`gpt-4o-mini`)。推論モデルではなく、通常のチャット/指示追従モデルを選んでください。推論モデルでは、`reasoning.effort`/`reasoning.max_tokens` で OpenRouter が上限を設定できない 1000~1700 個の推論トークンを生成するため、同じ呼び出しでの吸収分類に 12~17 秒かかると計測されています。一方、`gpt-4o-mini` では 3~4 秒です。 | | `MEMORA_ABSORB_CONCURRENCY` | `memory_absorb` の並列分類フェーズにおけるワーカー数(デフォルト `4`。数値以外または `<1` の場合は `4` にフォールバックし、`1` の場合はスレッドプールを無効にして順次分類します)。並列化されるのはファクトごとの LLM 分類呼び出しのみです。埋め込みと検索は順次実行されます(コストが低く、`conn` はワーカースレッドから安全に操作できません。sqlite3 接続はデフォルトでスレッドに固定され、`D1Connection` は変更可能なセッショントークンの状態を保持します)。 | | `MEMORA_LLM_TIMEOUT` | OpenAI クライアントの待機時間を秒単位で指定します(デフォルト `60`、最小 `1`)。数値以外の値を指定すると `60` にフォールバックします。 | | `MEMORA_REWRITE_MODEL` | グラフチャットパネルでの RAG クエリ書き換えに使用するモデルです。未設定/空の場合は `MEMORA_LLM_MODEL` を使用します。 | | `MEMORA_VECTOR_SCAN_PAGE_SIZE` | D1 から埋め込みを読み込む際の 1 ページあたりの行数(デフォルト `1000`。数値以外または `<1` の場合は `1000` にフォールバック。上限 `10000`)。デフォルトでは、1000 行未満のストアは**コーパス全体とすべての埋め込みを 1 回の D1 応答で返す**ため、Cloudflare の 1 リクエストあたり 30 秒の上限と競合し、`memory_absorb` が完全に失敗していました。**D1 では `100` を使用してください**(インスタンススクリプトがすでにこの値を設定します)。ページ分割は緩和策であり、根本的な解決策ではありません。吸収処理は呼び出しごとにコーパスを 1 回読み込み、DB の単調増加する `embedding_change_epoch` をキーとするプロセス内キャッシュを再利用します。 | | `MEMORA_REBUILD_CHUNK_SIZE` | `memory_rebuild_embeddings` で一括処理する行数(デフォルト `32`。数値以外または `<1` の場合は `32` にフォールバックします)。各バッチは `compute_embeddings_batch` の呼び出し 1 回と `conn.commit()` 1 回で処理されます。行ごとに埋め込み処理とコミットを行う方式と異なり、D1 ではリースのハートビートに伴う往復が行ごとの 2 回からバッチごとの 2 回になり、行ごとのコミットよりもはるかに大きな実行時間を占めていた部分を削減します(D1 の `commit()` はすでに何もしません)。 | | `CHAT_MODEL` | ローカルのグラフチャットパネル用のモデルです。未設定/空の場合は `MEMORA_LLM_MODEL` にフォールバックします。(`deepseek/deepseek-chat` のデフォルトは Cloudflare Pages の `wrangler.toml` 用であり、このプロセス用ではありません。) | | `MEMORA_CLOUD_GRAPH_ENABLED` | ホスト型グラフに書き込みを通知するには `true`/`1`/`yes` を設定します(デフォルトでは無効)。 | | `MEMORA_CLOUD_GRAPH_WORKER_URL` | これらのブロードキャストに使用する Worker のベース URL(`POST /broadcast`)です。未設定の場合、ブロードキャストはスキップされます。 | | `MEMORA_CLOUD_GRAPH_DEBOUNCE` | 連続する書き込みをまとめてブロードキャストするまでの秒数(デフォルト `1.0`)。 | | `MEMORA_CLOUD_GRAPH_SYNC_SCRIPT` | 起動時に取得するパス(デフォルト:ファイルが存在する場合は `memora-graph/scripts/sync.sh`)。現在の書き込み処理では、このスクリプトは実行されません。D1 が信頼できる唯一の情報源であり、実行されるのは Worker へのブロードキャストのみです。 | | `AWS_PROFILE` | `~/.aws/credentials` にある AWS 認証情報プロファイル(R2 で便利です) | | `AWS_ENDPOINT_URL` | R2/MinIO 用の S3 互換エンドポイント | | `R2_PUBLIC_DOMAIN` | R2 の画像 URL に使用するパブリックドメイン |
ツールプロファイル (MEMORA_TOOL_PROFILE)

44 個の MCP ツールはすべて無条件に登録されるため、ほとんどのツールが呼び出されない場合でも、すべてのエージェントセッションに約 12,700 トークンのツールスキーマ全体が注入されます。MEMORA_TOOL_PROFILE はデプロイごとにサブセットを公開するため、制限されたツールは本当に存在しなくなります — tools/list から消え、かつディスパッチも不可能になります (call_tool は隠れた実行ではなく unknown-tool を返します)。プロファイルは起動時に適用され、証明されます。アクティブなプロファイルと公開されているツール数は stderr にログ出力されます。

値ツール用途
full (デフォルト)すべての 44直接 stdio を使用する場合。既存のすべてのデプロイはバイト単位で変更されません
leader19エージェントセットに加えて memory_create_section、memory_store_document、memory_get_document、memory_tags、memory_delete、memory_digest、memory_list
agent12ワーカーエージェントが必要とする読み取り/作成サーフェス: memory_absorb、memory_semantic_search、memory_hybrid_search、memory_list_compact、memory_get、memory_related、memory_link、memory_stats、memory_create、memory_create_issue、memory_create_todo、memory_update
  • 未設定 / 空 = full。 既存のデプロイの動作は変わりません。
  • 不明な値は起動を中止します。その際、有効な値を示すメッセージが表示されます。full に暗黙的にフォールバックすることは決してありません — タイプミスによって、すべてのワーカーに破壊的なメンテナンスツール (memory_rebuild_embeddings、memory_delete_batch) が再び公開されてはなりません。フェイルクローズドです。
  • memory_list は leader に含まれますが、agent には含まれません。memory_list_compact の 0.22 秒に対して D1 ストアで 163〜174 秒かかっていた間は、両方から除外されていました。 #973 でそれが修正されました (現在は約 1.1 秒)。agent から除外されているのは、速度のためではなく、ワーカーの読み取りサーフェスが意図的に狭くされているためです。
  • leader/agent の境界は memora/tool_profile.py 内のデータ (2 つの frozenset) です。これを編集するのは 1 行であり、44 個のデコレーターを一掃する作業ではありません。
  • このプルーニングは FastMCP のプライベートな _tool_manager._tools 辞書から削除するため、memora は mcp>=1.27,<1.28 (監査済みのマイナーバージョン) を固定し、低レベルの登録済み MCP リクエストハンドラー (_mcp_server.request_handlers[ListToolsRequest] / [CallToolRequest] — 実際のクライアントリクエストが使用する実際のディスパッチ呼び出し可能オブジェクトであり、FastMCP.list_tools / call_tool という Python ヘルパーではありません) を通じて起動時の証明を実行し、インストールされている SDK がリスト/ディスパッチを別の場所にルーティングしている場合 (プライベート実装のドリフト) には起動を拒否します。固定は静的ガードであり、証明は実行時のバックストップです。上限を引き上げるには tests/test_tool_profile.py を再実行する必要があります。
  • コンテナデプロイでは、プロファイルはコンテナごとですが、ロールはエージェントごとです。あるワークスペースの leader とそのワーカーを 1 つのコンテナで提供するには leader スーパーセットが必要です。agent では leader から create_section/store_document/delete/digest/tags が剥ぎ取られてしまいます。
  • memora-server (つまり memora.server.main()) が唯一サポートされるプロファイル済みの提供パスです。memora.server.mcp をインポートして自分で mcp.run() を呼び出す直接埋め込み型は、プロファイリングを完全にバイパスします (グローバルの mcp は依然として 44 個すべてのツールを保持しています)。プロファイリングを希望する埋め込み型は、自分で apply_tool_profile を呼び出すか、main() を使用する必要があります。
# Leader deployment — exposes 19 tools
MEMORA_TOOL_PROFILE=leader memora-server

# Agent worker — exposes 12 tools
MEMORA_TOOL_PROFILE=agent memora-server

# Full (default) — all 44 tools, existing behaviour
memora-server

# Typo refuses to start:
# MEMORA_TOOL_PROFILE=agnt memora-server
# Error: unknown MEMORA_TOOL_PROFILE='agnt'; valid values: full, leader, agent
マルチデータベースルーティング

1 つの memora プロセスで、すべてのワークスペースにサービスを提供できます。MEMORA_DATABASES は {name: storage URI} の JSON レジストリであり、クライアントは /mcp/<name> で自身のストアに到達します。セレクターは .mcp.json にすでにある URL であり、ツール引数ではありません — すべてのツールにオプションの db を設けることは、忘れるチャンスが 44 回あるということであり、忘れるたびに誰か他の人のストアに書き込まれてしまいます。

MEMORA_DATABASES を未設定にすると従来の形です: MEMORA_STORAGE_URI / MEMORA_DB_PATH からの単一バックエンド、単一の /mcp。既存の stdio デプロイは変更されません。

ルーティング (streamable-http のみ):

URL解決先
/mcp/<name>そのレジストリエントリーです。不明な名前の場合は 404 {"error":"unknown database"} を返します。レスポンス本文にほかの名前は列挙されません。
/mcpMEMORA_DEFAULT_DB です。レジストリに複数のデータベースがある場合は必須です。名前が1つだけのレジストリでは、その名前が使用されます。

バインドはリクエストごとではなく、MCP セッションごとに固定されます。/mcp/alpha で開いたセッションを /mcp/beta で再利用しても、解決先は引き続き alpha です。クライアントは会話の途中でデータベースを切り替えられません。

設定に不備がある場合は起動を拒否します(従来のデータベースにはフォールバックしません)。対象となる不備は、不正な JSON、オブジェクト以外の値、重複キー、空の URI、URL パスのセグメントが1つでない名前、またはデータベースが複数列挙されている場合に MEMORA_DEFAULT_DB が未設定または不明であることです。

実行例と接続例。 これはストリーマブル HTTP リスナーであり、MCP の command エントリーではありません(command エントリーでは stdio の子プロセスが起動しますが、そのプロセスは stdio で MCP を話しません)。認証情報はサーバープロセスに保存されます。

MEMORA_DATABASES='{"memora":"d1://<account-id>/<memora-db-id>","alpha":"d1://<account-id>/<alpha-db-id>"}' \
MEMORA_DEFAULT_DB=memora \
CLOUDFLARE_API_TOKEN='<token>' \
MEMORA_VECTOR_SCAN_PAGE_SIZE=100 \
memora-server --transport streamable-http --host 127.0.0.1 --port 8000 --no-graph
{
  "mcpServers": {
    "memora": {
      "type": "http",
      "url": "http://127.0.0.1:8000/mcp/alpha"
    }
  }
}

コンテナー/プロキシ構成(このホストで通常使用するランチャー。上記のコマンドとは異なります):scripts/memora-instance.sh up myinstance は同じ HTTP サーバーをコンテナー内で起動し、scripts/memora_proxy.py を 127.0.0.1:<PORT>(memora インスタンスでは8910)で起動します。ワークスペース URL は http://127.0.0.1:8910/mcp/alpha になります。コンテナーのデプロイを参照してください。

レジストリには d1://、s3://、ローカルパスを混在させることができます。parse_backend_uri はスキームに応じて振り分けます。

memory_stats はバインドされたデータベースを報告します。 database(このセッションが実際に解決した名前)と database_source(path、 registry_default、または unconfigured)を返します。.mcp.json に有効だが誤った名前を指定しても、ほかの方法では検出できません。すべてのツールが動作し、読み取りは成功し、書き込みは別のプロジェクトのストアに気付かれずに行われます。memory_stats を呼び出し、database が意図したワークスペースと一致することを確認してください。

複数データベースプロセスのヘルスチェック:GET /health は稼働状態の確認です(データベース I/O は行いません。監視プロセスが再起動を判断する際に使用できる唯一のシグナルです)。GET /health/db はアラート用のエンドポイントです(常に HTTP 200 を返します。status は ok、degraded、unknown — まだスナップショットがない場合、更新がタイムアウトした場合、または証跡が最大許容経過時間より古い場合 — のいずれかです。レジストリ自体が使用できない場合は error です)。GET /health/db/{name} はワークスペースごとのプローブです(200 または503)。1つのストアの劣化を理由にプロセス全体を停止すると、正常なストアまで停止してしまいます。

コンテナーのデプロイ

MEMORA_DATABASES が未設定の場合、プロセスは稼働中、1つのデータベースにバインドされます(MEMORA_STORAGE_URI / MEMORA_DB_PATH)。これは従来の「1ストア、1コンテナー、1ポート」の構成です。

MEMORA_DATABASES が設定されている場合、1つのコンテナーがすべてのワークスペースを提供し、クライアントは URL パス(/mcp/<name>)でストアを選択します。複数データベースのルーティングを参照してください。scripts/memora-instance.sh では、インスタンスファイルごとに STORAGE_URI、VOLUME、MEMORA_DATABASES のいずれか1つが必要です(load() は少なくとも1つを必須とします)。複数が設定されている場合、cmd_up は MEMORA_DATABASES、STORAGE_URI、VOLUME の順に使用します。

Dockerfile は認証情報を含まないイメージをビルドします。scripts/memora-instance.sh は instances/myinstance.env(または別の名前のファイル)から1つのインスタンスをデプロイします。このスクリプトの実行時 CLI は $MEMORA_CONTAINER_BIN(デフォルトは container — Apple の CLI)です。スクリプトが実行するすべてのコンテナー操作(build、up、status、 logs、down)で、この設定が適用されます。生成される memora_proxy.py プロセスでは container list がハードコードされています。これもプロキシが存在する理由です。このランタイムでは、起動のたびにコンテナーの IP が再割り当てされます。

./scripts/memora-instance.sh build   myinstance   # build the image
./scripts/memora-instance.sh up      myinstance   # run the container
./scripts/memora-instance.sh proxy   myinstance   # render a LaunchAgent + print install commands
./scripts/memora-instance.sh status                # every instance at a glance

次に、ワークスペースをそのコンテナーに接続します。秘密情報を含まないクライアント設定全体は以下のとおりです。 レジストリインスタンスではストアをパス(/mcp/<name>)に指定する必要があります。/mcp のみの場合はレジストリのデフォルトが使用されます。

{"mcpServers": {"memora": {"type": "http", "url": "http://127.0.0.1:8910/mcp/alpha"}}}
**認証情報がイメージ、インスタンスファイル、ワークスペースの HTTP 設定に入ることはありません。** 認証情報は別の認証情報設定(`$CRED_SOURCE`。それ自体は `mcpServers.memora.env` ブロックのみを含む `.mcp.json`)から実行時に読み込まれ、`-e` で注入されます。インスタンスファイルで `CRED_SOURCE` が設定されていない場合、スクリプトは `~/.config/memora/credentials.mcp.json` を使用します(ファイルがない場合、`up` は実行を拒否します。ほかのフォールバックはありません)。一部だけを選んで渡すのではなく、そのファイルで定義されている**すべての**変数を渡してください。埋め込みキーだけで起動したコンテナでは、エラーが明示されることなく `memory_absorb` の LLM による統合機能が失われます。

プロキシが必要な理由 — 不要だと判断する前にお読みください。 デフォルトのランタイム(Apple の container)では、コンテナを再作成するときだけでなく、起動するたびにコンテナの IP アドレスが再割り当てされます。MCP クライアントは起動時に一度だけ設定を読み込むため、アドレスが変わってもエラーは発生しません。代わりに、永久に応答がない状態になります。scripts/memora_proxy.py は、変動するアドレスの前段に安定した 127.0.0.1:<PORT> を設け、接続ごとにアドレスを再解決します。

障害が発生してから知ることになった、プロキシが判別する2つの障害モード:

  • 検索が実行され、コンテナが一覧にない → 実際に停止しています。拒否します。
  • 検索を実行できなかった(ホストのメモリ逼迫時にタイムアウト)→ 新たに判明した情報はありません。最後に正常と確認されたアドレスでの提供を続けます。ただし、MEMORA_PROXY_STALE_GRACE(300s)の範囲内に限ります。この2つを区別しなかったため、コンテナが変更されていないアドレスで正常に応答していたにもかかわらず、すべてのワークスペースがオフラインになりました。

インスタンスごとに MEMORA_TOOL_PROFILE を設定してください(ツールプロファイルを参照)。プロファイルはコンテナごと、役割はエージェントごとに設定する点に注意してください。1つのコンテナでワークスペースのリーダーとワーカーに対応する場合、リーダーの機能を含むプロファイルが必要です。

デプロイ時のスクリプト変数(memora-server の環境変数ではありません。コンテナ内のプロセスには渡されません):

Variable意味
MEMORA_CONTAINER_BINmemora-instance.sh がコンテナ操作(build、up、status、logs、down)で使用する CLI(デフォルトは container)。生成される memora_proxy.py プロセスでは使用されず、container list が固定で使われます。

instances/README.md では設定項目について、launchd/README.md では監視対象のプロキシについて説明しています。ワークスペースを直接の stdio サーバーに戻す方法は REVERT.md に記載されています。

セマンティック検索と埋め込み

Memora は3種類の埋め込みバックエンドに対応しています:

Backendインストール品質速度
openai (デフォルト)同梱高品質API のレイテンシー
sentence-transformerspip install memora[local]良好、オフラインで動作中速
tfidf同梱基本的なキーワード照合高速

埋め込みと LLM は個別に設定します。

役割変数
LLM(重複排除、チャット)OPENAI_API_KEY + OPENAI_BASE_URL
埋め込みMEMORA_EMBEDDING_API_KEY + MEMORA_EMBEDDING_BASE_URL(両方を設定するか、どちらも設定しない — ペアで使用)
フォールバックMEMORA_EMBEDDING_* を両方とも設定しない場合、埋め込みでは OPENAI_* のペア全体を使用

片方の MEMORA_EMBEDDING_* だけを設定する分割構成は拒否されます。あるプロバイダーのシークレットが別のホストに送信されることはありません。

注意 — OpenRouter には埋め込みエンドポイントがありません。 OpenRouter のカタログはチャット/マルチモーダルのみで、埋め込みモデルはありません。OPENAI_BASE_URL(または MEMORA のベース URL)を使って、埋め込みの接続先を OpenRouter に設定しないでください。この設定では埋め込み呼び出しがすべて 404 になります。MEMORA_EMBEDDING_STRICT=1 が設定されていない場合、Memora は TF-IDF にフォールバックして応答を続けるため、正常に動作しているように見えながら、ストアにはキーワードの集合が蓄積されます。OpenRouter はLLMにのみ使用する場合は問題ありません。

設定例(LLM は OpenRouter、埋め込みは Cloudflare Workers AI を使用):

@cf/baai/bge-m3 は1024次元です。トークンには Workers AI の権限が必要です。エンドポイントの形式:

https://api.cloudflare.com/client/v4/accounts/<account_id>/ai/v1

{
  "env": {
    "MEMORA_EMBEDDING_MODEL": "openai",
    "OPENAI_API_KEY": "<openrouter-key>",
    "OPENAI_BASE_URL": "https://openrouter.ai/api/v1",
    "MEMORA_LLM_MODEL": "deepseek/deepseek-chat",
    "MEMORA_EMBEDDING_API_KEY": "<cloudflare-api-token-with-workers-ai>",
    "MEMORA_EMBEDDING_BASE_URL": "https://api.cloudflare.com/client/v4/accounts/<account_id>/ai/v1",
    "OPENAI_EMBEDDING_MODEL": "@cf/baai/bge-m3",
    "MEMORA_EMBEDDING_STRICT": "1"
  }
}

この修正でできること(誇張なし):埋め込みと LLM で異なるプロバイダーを使用できます。部分的な分離は拒否され、厳密モードでは暗黙の劣化が、明示的な名前付きエラーになります。

自動: memory_create、memory_update、または memory_create_batch を実行すると、埋め込みと相互参照が自動的に計算されます。

ストアのフィンガープリントが変わった場合は手動での再構築が必要です — MEMORA_EMBEDDING_MODEL だけでなく、以下も対象です。

  • 埋め込みのエンドポイント(MEMORA_EMBEDDING_BASE_URL / ホスト)
  • 実際のモデル ID(OPENAI_EMBEDDING_MODEL。例:@cf/baai/bge-m3 への切り替え)
  • ベクトルの種類または次元数(単語キー TF-IDF バッグ対高密度 1024 次元、または 384 対 1024)
  • 混在ストア(一部の行は高密度、一部はスパース) — コサイン類似度はキーが共有されている場合のみ機能するため、種類が混在すると古い行の再現率は 0.0 になります

フィンガープリントの形式:backend|model|repr(例:openai|@cf/baai/bge-m3|dense:1024)。従来のメタ値 openai のみの場合は、不一致として扱われます。

# After changing embedding model/endpoint, rebuild all embeddings
memory_rebuild_embeddings

# Then rebuild cross-references to update the knowledge graph
memory_rebuild_crossrefs
ライブグラフサーバー

組み込みの HTTP サーバーが MCP サーバーとともに自動的に起動し、インタラクティブなナレッジグラフの可視化を提供します。

詳細パネル
詳細パネル
タイムラインパネル
タイムラインパネル

ローカルでのアクセス:

http://localhost:8765/graph

SSH 経由でのリモートアクセス:

ssh -L 8765:localhost:8765 user@remote
# Then open http://localhost:8765/graph in your browser

設定:

{
  "env": {
    "MEMORA_GRAPH_PORT": "8765"
  }
}

無効にするには、MCP 設定の args に "--no-graph" を追加します。

グラフ UI の機能
  • 詳細パネル - メモリーの内容、メタデータ、タグ、関連するメモリーを表示します
  • タイムラインパネル - メモリーを時系列で表示し、クリックするとグラフ内でハイライトします
  • 履歴パネル - 連続するエントリーをまとめたすべての操作のログです。クリック可能なメモリー参照も表示されます(削除済みのメモリーには取り消し線が表示されます)
  • チャットパネル - ストリーミング応答とクリック可能な [Memory #ID] 参照に対応した、RAG を活用する LLM チャットでメモリーについて質問できます
  • タイムスライダー - 日付範囲でメモリーを絞り込み、ドラッグして履歴を確認できます
  • リアルタイム更新 - メモリーの変更時に、グラフ、タイムライン、履歴が SSE 経由で更新されます
  • フィルター - タグ/セクションのドロップダウン、ズームコントロール
  • Mermaid のレンダリング - コードブロックを図としてレンダリングします
ノードの色
  • 🟣 タグ - タグに応じた紫色の濃淡
  • 🔴 課題 - 赤(未解決)、オレンジ(進行中)、緑(解決済み)、グレー(修正しない)
  • 🔵 TODO - 青(未着手)、オレンジ(進行中)、緑(完了)、赤(ブロック中)

ノードのサイズは接続数を示します。

クラウドグラフ(D1 におすすめ)

データベースとして Cloudflare D1 を使用する場合、グラフの可視化は Cloudflare Pages でホストされるため、ローカルサーバーは必要ありません。

メリット:

  • どこからでもアクセス可能(SSH トンネリング不要)
  • WebSocket 経由でリアルタイムに更新
  • ?db= パラメーターによる複数データベースのサポート
  • Cloudflare Zero Trust による安全なアクセス

セットアップ:

  1. D1 データベースを作成:

    npx wrangler d1 create memora-graph
    npx wrangler d1 execute memora-graph --file=memora-graph/schema.sql
    
  2. Pages にデプロイ:

    cd memora-graph
    npm run deploy
    

    npm run deploy は最初に scripts/d1_write_guard.py --scope all を実行し、検出事項がある場合はデプロイを拒否します。ガードを回避してしまうため、wrangler pages deploy を直接実行しないでください(docs/local-primary-implementation.md §0 P6)。

  3. Cloudflare Dashboard でバインディングを設定:

    • Pages → memora-graph → Settings → Bindings
    • D1 を追加:DB_MEMORA → 使用するデータベース
    • R2 を追加:R2_MEMORA → 使用するバケット(画像用)
  4. D1 URI を使ってMCP を設定:

    {
      "env": {
        "MEMORA_STORAGE_URI": "d1://<account-id>/<database-id>",
        "CLOUDFLARE_API_TOKEN": "<your-token>"
      }
    }
    

アクセス先: https://memora-graph.pages.dev

Zero Trust で保護する:

  1. Cloudflare Dashboard → Zero Trust → Access → Applications
  2. memora-graph.pages.dev のアプリケーションを追加
  3. 許可するメールアドレスを指定してポリシーを作成
  4. Pages → Settings → Access Policy を有効化

詳しいセットアップ方法と複数データベースの設定については、memora-graph/ を参照してください。

記憶とチャット

グラフ UI からナレッジベースについて直接質問できます。チャットパネルでは RAG(検索拡張生成)を使用して関連する記憶を検索し、ツール呼び出しに対応した LLM の応答をストリーミングします。

  • 右下にあるフローティングチャットアイコンで切り替え
  • セマンティック検索で、コンテキストとして最も関連性の高い記憶を検索
  • クリック可能な [Memory #ID] 参照付きのストリーミング応答。クリックするとグラフ上のノードにフォーカスします
  • ツール呼び出し — LLM はチャットから直接、記憶を作成、更新、削除できます(例:「これを記憶として保存して」、「記憶 #42 を削除して」、「記憶 #10 を次の内容で更新して...」)
  • ローカルサーバーと Cloudflare Pages のデプロイの両方で動作します

チャットモデルの設定:

バックエンド変数デフォルト
ローカルサーバーCHAT_MODEL 環境変数MEMORA_LLM_MODEL にフォールバックします
Cloudflare Pageswrangler.toml 内の CHAT_MODELdeepseek/deepseek-chat

OpenAI 互換 API が必要です(ローカルでは OPENAI_API_KEY + OPENAI_BASE_URL、Cloudflare では OPENROUTER_API_KEY シークレット)。チャットモデルはツールの使用(関数呼び出し)に対応している必要があります。

LLM による重複排除

AI によるセマンティック比較を使用して、重複する記憶を見つけて統合します:

# Find potential duplicates (uses cross-refs + optional LLM analysis)
memory_find_duplicates(min_similarity=0.7, max_similarity=0.95, limit=10, use_llm=True)

# Merge duplicates (append, prepend, or replace strategies)
memory_merge(source_id=123, target_id=456, merge_strategy="append")

LLM 比較では、記憶のペアを分析し、次の内容を返します:

  • verdict: "duplicate"、"similar"、または "different"
  • confidence:0.0~1.0 のスコア
  • reasoning:簡潔な説明
  • suggested_action:"merge"、"keep_both"、または "review"

OPENAI_BASE_URL 経由で、OpenAI 互換のあらゆるチャット API(OpenAI、OpenRouter、Azure など)で動作します。この LLM 用途では OpenRouter を利用できますが、埋め込みには対応していません。埋め込みは別途設定してください(「セマンティック検索と埋め込み」を参照)。

ドキュメントストレージ

構造化ドキュメント(調査レポート、アーキテクチャの決定事項、事後分析)を、検索可能なフラグメントツリーとして保存します:

# Store a markdown document — auto-parsed into typed fragments
memory_store_document(
    content="# Research Report\n\n## Evidence Table\n| Claim | Confidence |\n...",
    document_key="research/memora-enhancements-2026-04-08",
    tags=["memora/research"]
)
# Returns: {root_id: 230, fragment_count: 100, node_map: {claim: [...], plan_item: [...], ...}}

# Retrieve the full document or specific fragment types
memory_get_document(document_key="research/memora-enhancements-2026-04-08")
memory_get_document(document_key="...", node_kinds=["claim"], content_mode="full")

# Delete a document and all its fragments
memory_delete_document(document_key="research/memora-enhancements-2026-04-08")

仕組み: パーサーは構造に基づいて Markdown を分割します。表は個々の主張に、番号付きリストは計画項目に、URL リストは参照に、リスクのセクションはリスクのフラグメントになります。各フラグメントは memory_semantic_search で個別に検索でき、ドキュメント全体は 1 つの単位として取得できます。

フラグメントの種類: claim、plan_item、reference、section_chunk、risk

整合性ガード: ドキュメントのフラグメントが誤って変更されないように保護します:

  • フラグメントを memory_delete で削除するには force=True が必要です
  • memory_merge はフラグメントの統合を拒否します
  • memory_absorb は類似性の照合からフラグメントを除外します
  • memory_find_duplicates と memory_detect_supersessions はフラグメントをスキップします
  • グラフ UI ではフラグメントを非表示にし、ドキュメントのルートノードのみを表示します
記憶の自動化ツール

一般的な記憶の種類に対応する構造化ツール:

# Create a TODO with status and priority
memory_create_todo(content="Implement feature X", status="open", priority="high", category="backend")

# Create an issue with severity
memory_create_issue(content="Bug in login flow", status="open", severity="major", component="auth")

# Create a section placeholder (hidden from graph)
memory_create_section(content="Architecture", section="docs", subsection="api")
記憶の分析情報

保存された記憶を分析し、実行可能な分析情報を提示します:

# Full analysis with LLM-powered pattern detection
memory_insights(period="7d", include_llm_analysis=True)

# Quick summary without LLM (faster, no API key needed)
memory_insights(period="1m", include_llm_analysis=False)

次の情報を返します:

  • アクティビティの概要 — 期間内に作成された記憶を、種類とタグごとに分類
  • 未完了項目 — 古い項目の検出機能付きの未完了 TODO と課題(MEMORA_STALE_DAYS で設定可能。memory_insights のデフォルトは 14、グラフ UI のデフォルトは 30 — 同じ変数を 2 つの機能で使用)
  • 統合候補 — 統合できる類似した記憶のペア
  • LLM による分析 — テーマ、重点分野、ナレッジの不足、要約(OPENAI_API_KEY が必要)
記憶のリンク

記憶間の関係を管理します:

# Create typed edges between memories
memory_link(from_id=1, to_id=2, edge_type="implements", bidirectional=True)

# Edge types: references, implements, supersedes, extends, contradicts, related_to

# Remove links
memory_unlink(from_id=1, to_id=2)

# Boost memory importance for ranking
memory_boost(memory_id=42, boost_amount=0.5)

# Detect clusters of related memories
memory_clusters(min_cluster_size=2, min_score=0.3)
ナレッジグラフのエクスポート(任意)

オフラインで閲覧するには、メモリーを静的な HTML ファイルとしてエクスポートします。

memory_export_graph(output_path="~/memories_graph.html", min_score=0.25)

これは任意です。ライブグラフサーバーでは、リアルタイム更新に対応した同じビジュアライゼーションを利用できます。

Neovim との統合

Telescope を使って、Neovim から直接メモリーを参照できます。プラグインを設定にコピーします。

# For kickstart.nvim / lazy.nvim
cp nvim/memora.lua ~/.config/nvim/lua/kickstart/plugins/

使い方: <leader>sm を押すと、あいまい検索とプレビュー機能を備えたメモリーブラウザーが開きます。

必要なもの:telescope.nvim、plenary.nvim、および Python 環境にインストールされた memora。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。