mcpField
T
tether

tether

ローカル
github.comメモリ・ナレッジ17 週間前に更新

tether について

tetherは、SQLiteに永続メモを保存する、個人向けのローカル優先MCPメモリーサーバーです。プロジェクトを考慮した検索と任意のデバイス間同期に対応し、追加機能が使えない場合もキーワード検索に切り替わります。

主な機能

  1. 01メモの記憶・検索・関連付け・削除
  2. 02SQLite保存と任意のデバイス同期
  3. 03キーワードとセマンティック検索の併用
  4. 04使用グラフによる連想検索
  5. 05プロジェクト対応の起動インデックス

活用シーン

  1. 01エージェントのセッション間で個人設定を引き継ぐ
  2. 02libSQLまたはTursoでデバイス間のメモを共有する
  3. 03コーディング中に関連するプロジェクトメモを探す

MCP 対応

MCP対応エージェントに、記憶・検索・関連付け・削除の操作を提供します。自動読み込みされる起動インデックスも、簡潔なメモリー情報を提示します。

設定

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

mcp.json · 共通設定
{
"mcpServers": {
"sidyellur-tether": {
"command": "uvx",
"args": [
"tether-memory"
],
"env": {
"TETHER_DB": "<TETHER_DB>",
"TETHER_SEMANTIC": "<TETHER_SEMANTIC>",
"TETHER_SYNC_URL": "<TETHER_SYNC_URL>",
"TETHER_SYNC_TOKEN": "<TETHER_SYNC_TOKEN>"
}
}
}
}
起動コマンドuvx tether-memory
設定が必要な環境変数
TETHER_DBPath to the SQLite memory file. Defaults to the platform data dir (e.g. ~/.local/share/tether/memory.db).
TETHER_SEMANTICSet to 0 to force keyword-only recall. Semantic recall needs the [semantic] extra and is on by default when available.
TETHER_SYNC_URLOptional libSQL/Turso primary URL to sync memory across devices. Leave unset for local-only.
TETHER_SYNC_TOKENシークレットAuth token for TETHER_SYNC_URL.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypitether-memory0.6.1

ツール

4

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
bodystringはい
tagsstringいいえ
typestringはい
linksanyいいえ
titlestringはい
crystallizesanyいいえ

詳細

tether

デバイスをまたいで、個人エージェントが共有するメモリレイヤーです。 tether は、ローカルの SQLite ファイルを基盤とする MCP サーバーです。MCP 互換のエージェントであれば、remember、recall、link、forget を使って、あなたやプロジェクト、好みに関する情報を永続的なメモとして保存できます。これにより、コンテキストはセッションごとに失われず、あなたについてきます。

設定不要で、ローカルのみで動作します。 ホスト型の libSQL/Turso プライマリに接続すると、同じファイルが組み込みレプリカになり、すべてのデバイス間でメモリをほぼリアルタイムに同期します。

なぜ必要なのか

近い将来、エージェントはノート PC、デスクトップ、スマートフォンなど、多くのデバイスで使われるようになります。それらを記憶のない別々のアシスタントではなく、1つのアシスタントのように感じられるようにするには、メモリがあなたについてくる基盤でなければなりません。単一のツールの中に閉じ込められるのではなく、あらゆるデバイスやエージェントから読み書きできる必要があります。

tether は、そのための基盤です。意図的に利便性レイヤーとして設計されており、利用できるときはエージェントをより便利にし、機能が低下してもエージェントの作業を妨げることはありません。

ステータス

v0.6.1。 中核機能(4つのメモリ操作 + ブートインデックス + FTS5)は v0.1 でリリースされました。その後、リコールには意味検索機能、統合、連想利用グラフ、自己整理型ストア、オプトイン方式の結晶化が追加されました。いずれも機能を追加するものであり、低下時には通常のキーワード検索に支障なく戻ります。以下の機能はすべて実装済みです。

設計とその根拠については docs/superpowers/specs/2026-07-03-tether-design.md から確認できます。連想機能の中核、シード優先のリコール、自己整理型ストア(Tier B1)、結晶化(Tier B2)には、それぞれ docs/superpowers/specs/ 以下に個別の設計ドキュメントがあり、対応する計画は docs/superpowers/plans/ にあります。

設計の概要

  • 4つのメモリ操作:remember · recall · link · forget。(結晶化を有効にすると、振り返りを制御するツール dismiss_cluster が追加されます。これはメモリ操作ではありません。)
  • 書き込み時にアップサートするため、ストアに似た内容の重複が増えません。
  • 豊富なリコール情報(id、type、title、body、tags、updated_at に加え、各結果が表示された理由を示す via レシート)により、エージェントは情報の古さを判断し、更新内容の出典を示せます。body はメモリ全体ではなく、クエリに沿った抜粋です。詳しくは抜粋をご覧ください。
  • 自動読み込みされるブートインデックス — メモリごとに1行でまとめたリストを各セッションでエージェントに表示するため、エージェントが検索を思いつかなくてもメモリが役立ちます。
  • ローカル優先、同期は任意 — バックエンドが設定されていなければ、ローカルのパスには手を加えません。機能の低下時に例外が発生することもありません。
  • ハイブリッド検索と連想検索の追加 — FTS5 のキーワード検索結果とローカルの静的埋め込みを統合した後、利用グラフ(明示的なリンク、学習された共起検索、意味的に近い項目)を使って関連するメモリを取り込みます。各レイヤーは機能を追加するものであり、低下時には通常のキーワード検索に戻ります。
  • ツールの並列呼び出しにも安全 — エージェントが複数の remember/recall 呼び出しを同時に実行しても、結果はアトミックに処理され、正確に報告されます。詳しくはパフォーマンスと耐久性をご覧ください。

インストール

Linux、macOS、Windows で Python ≥3.10 が必要です。

uv を使って Claude Code に登録します:

claude mcp add tether -- uvx tether-memory

…または、先にインストールします:

pip install tether-memory
claude mcp add tether -- tether-memory

(PyPI 上のパッケージ名は tether-memory です。tether は一般的なブランド名としてすでに予約されていたためです。claude mcp add tether -- ... の tether は、Claude Code がこのサーバーを参照するために使うラベルにすぎず、インストール済みのコマンド名と一致させる必要はありません。)

また、Claude Code プラグインとして追加することもできます(このリポジトリは単一プラグインのマーケットプレイスも兼ねています。プラグインは uvx --from 'tether-memory[semantic]' を実行するため、セマンティック想起も利用できます):

/plugin marketplace add sidyellur/tether
/plugin install tether@tether

MCP Registry にも mcp-name: io.github.sidyellur/tether として登録されています。

デフォルトでは、メモリはローカルの SQLite ファイル ~/.local/share/tether/memory.db に保存されます。Windows では %LOCALAPPDATA%\tether\memory.db です(どちらも TETHER_DB で変更するか、すべてのプラットフォームで適用される XDG_DATA_HOME を設定してください)。アカウントもネットワーク接続も不要です。これは単一のマシンで使うためのツールです。

プロジェクトの認識

tether は、どのプロジェクトにサービスを提供しているかを認識します。Claude Code はすべての MCP サーバーの環境に CLAUDE_PROJECT_DIR を設定し、tether はそのディレクトリ名をプロジェクト名として使います(TETHER_PROJECT で変更または無効化できます)。これにより、設定不要で次の 3 つの動作が実現します。

  • 起動時のインデックスでは、このプロジェクトが先頭に表示されます。 自動読み込みされるインデックスは、# This project (<name>) セクションから始まり、その後に # Everything else が続きます。そのため、エージェントはどこで最後に作業したかではなく、現在のリポジトリに関する決定事項や注意点を確認した状態でセッションを開始できます。
  • 作業に関するメモリには、自動でタグが付与されます。 project、feedback、reference のメモリには、エージェントが proj: タグを渡さない限り、proj:<name> タグが付与されます。user メモリは作業ではなくあなた自身に関するものなので、グローバルなままです。このタグは通常のタグです。recall(tags="proj:<name>") を使うと、プロジェクトのメモリを確実に一覧表示できます。
  • 想起では、ほぼ同等の候補があればこのプロジェクトが優先されます。 現在のプロジェクトのタグが付いた候補は、別のプロジェクトの同程度に良い候補より数段階上位にランク付けされます。ただし、明らかに優れた候補を上回ることはなく、タグのないメモリが優遇されたり不利になったりすることもありません。
変数デフォルト効果
TETHER_PROJECTCLAUDE_PROJECT_DIR のベース名プロジェクト名を明示します。off を指定するとプロジェクト認識が無効になります

作業ディレクトリへのフォールバックはありません。Claude Code の外部で使用する場合(または TETHER_PROJECT=off の場合)、tether はこれまでとまったく同じように動作します。

デバイス間の同期(任意)

Turso/libSQL データベースを tether に指定すると、ローカルファイルが埋め込みレプリカになり、ローカルと同等の速度で読み込み、書き込みはほかのデバイスに反映されます。追加パッケージをインストールし、2 つの環境変数を設定します。

pip install 'tether-memory[sync]'
export TETHER_SYNC_URL='libsql://<your-db>.turso.io'
export TETHER_SYNC_TOKEN='<your-auth-token>'

バックエンドに接続できない場合、tether は sync offline とログに記録し、ローカルファイルを使って動作し続けます。同期は単一プライマリ方式です。すべての書き込みはホストされたプライマリに送られ、レプリカはプルのみを行います。そのため、単にオフラインだったデバイスは次回のプル時に(forget によるトゥームストーンも含めて)最新状態になり、ほかのデバイスが忘れたメモリーを復活させることはありません。唯一の例外は、動作が低下した状態で行った書き込みです。そのデバイスのローカルファイルにのみ保存され、あとからマージされません(調整については #99 で追跡しています)。

書き込みはすぐにプッシュされます。読み込み時にもプルが行われますが、TETHER_SYNC_READ_INTERVAL 秒あたり最大 1 回(デフォルトは 30 秒)に制限されています。これにより、何かを尋ねるだけのデバイスでも、起動時の状態のまま更新されずにとどまることなく、ほかのデバイスの書き込みを確認できます。読み込み時のプルは、書き込み時のプルよりも大幅に厳しく制限されています。バックエンドの応答が遅い場合、リコールはローカルのデータを返し、プルの結果は次回の読み込みに反映されるため、待たされることはありません。

変数デフォルト効果
TETHER_SYNC_READ_INTERVAL30読み込み時のプルの間隔(秒)。0 = 書き込み時のみ同期
TETHER_DEVICE_IDhostname各メモリーに記録されるデバイス ID(およびデフォルトの TETHER_AUTHOR)

レプリカについて知っておくべき点があります。libSQL はすべての書き込みをホストされたプライマリに転送します。また、連想グラフが有効な場合(デフォルト)、recall による書き込みも転送されます。これは、一緒にリコールされた内容を記録し、時間とともにメモリー同士を関連付けるためです。レプリカでは、ローカル検索に加えて、リコールのたびに複数回のネットワーク通信が発生します。学習された関連付けよりもこの点を重視する場合は、TETHER_ASSOC=0 にすると、リコールを再び読み取り専用にできます。

キーワード検索

キーワード検索には、タイトル、本文、タグを対象とし、bm25 で順位付けする SQLite FTS5 を使用します。自然な言葉で尋ねてください。クエリの単語をいくつか含むメモリーがヒットし、より多く含むものほど上位になります。そのため、「統合テストはどう実行しますか?」と尋ねると、「pytest でテストを実行する」と書かれたメモが見つかります(一般的な機能語は無視されます)。インデックスでは英単語の語幹処理が行われるため、tests は test に、deciding は decided に一致します。語幹処理は英語のみを対象としています。ほかの言語のストアでは無効にしてください。tether は次回の起動時にインデックスを再構築します。

変数デフォルト効果
TETHER_FTS_STEMMINGon0/false/off を設定すると、単語を書かれたとおりにインデックス化します

LoCoMo の長い会話のベンチマーク(対話の各ターンにつきメモリー 1 件、質問数 1,536 件、「回答となるターンがリコールされたか」を上位 10 件で判定)では、キーワード検索だけで質問の 61%について根拠を見つけます。同じテキストを対象とした標準的な BM25 では 54%です。この評価用ハーネスはリポジトリに含まれています。ベンチマークをご覧ください。

セマンティック検索(任意)

デフォルトでは、recall はハイブリッド検索です。キーワード(FTS5)の結果とセマンティック(ベクトル)検索の結果を組み合わせるため、正確な単語が異なっていても関連するメモリーを見つけられます(「automobile」と検索すると、「car」についてのメモをリコールします)。セマンティック検索では、小型の静的埋め込みモデルをローカルで実行します。ネットワーク接続も API キーも不要で、動作が不安定になる要因もありません。追加パッケージをインストールします。

pip install 'tether-memory[semantic]'

追加パッケージがない場合(または TETHER_SEMANTIC=0 の場合)、tether はキーワードのみの FTS5 検索を実行します。セマンティック検索は純粋な追加機能であり、必須ではありません。初回の実行時に既存のメモリーを一度だけ埋め込みます(一度限りのバックフィル)。以降は差分のみを処理します。

環境変数:

変数デフォルト効果
TETHER_SEMANTICon0/false/off を設定すると、キーワードのみのリコールを強制します
TETHER_EMBEDDING_MODELminishlab/potion-base-8Mローカルの静的モデルを指定します

統合(任意)

tether は置き換えられた事実を上書きせず、保持します。記憶が置き換えられると、古い記憶は現行ではないものとしてマークされ(履歴として保持されます)、recall とブートインデックスから除外されます。また、recall ではより新しい事実が適度に優先されます。オプトインの動作を有効にすると、さらに次のようになります。

変数デフォルト効果
TETHER_CONSOLIDATEoffon(1/true)にすると、書き込み時にほぼ重複する記憶を統合します。ストアが断片化する代わりに、古い事実を置き換えます([semantic] エクストラが必要です)
TETHER_DEDUP_THRESHOLD0.922 つの事実を重複とみなすために必要なコサイン類似度
TETHER_DECAY_HALF_LIFE_DAYSoff正の数を設定すると、recall で古い事実の順位を指数関数的に下げます
TETHER_AUTHORデバイス ID各記憶に記録される帰属情報

統合によって削除されることはありません。forget は論理削除を行い(ツールを参照)、永久削除できるのは管理用 CLI の purge のみです。[semantic] エクストラがない場合、これらの機能はすべて通常のキーワード検索に切り替わります。

連想検索(任意)

recall はキーワードやセマンティック検索に一致する記憶を返すだけではなく、使用グラフをたどって関連する記憶も探すため、ある事柄について尋ねると、それにつながるコンテキストも見つかります。グラフのエッジは、ローカルで決定論的な次の 3 つの情報源から作られます。LLM もネットワークも使用しません。

  • semantic — 埋め込みによる最近傍([semantic] エクストラが必要です)
  • explicit — link() 動詞
  • hebbian — 一緒に想起した記憶が、時間とともに結び付けられます

各検索結果には、表示された理由(直接一致か、たどったエッジ)を示す via レシートが付与されます。また、2 つの任意の recall 引数で動作を調整できます。

引数/変数デフォルト効果
budget(呼び出しごと)TETHER_RECALL_BUDGET関連付けをたどる範囲。0 は直接一致のみ
session(呼び出しごと)時間単位で区分関連する検索結果をグループ化し、互いに活性化するようにします
TETHER_ASSOCon0/false/off に設定すると、通常のキーワード検索とセマンティック検索になります
TETHER_RECALL_BUDGET8関連付けのデフォルトの探索幅
TETHER_PROTECT_HEAD8関連付けより上位に固定する、直接一致の上位件数
TETHER_SEED_FLOOR0.35セマンティック検索結果が連想探索の起点となるために必要な最小コサイン類似度。この値を下回る記憶は、エッジ経由でのみ到達できます。0 にすると下限が無効になります

連想検索は起点を優先します。直接一致の上位結果は固定され、関連付けはその下の枠だけを埋めます。そのため、関連付けを有効にしても、キーワード検索やセマンティック検索で上位にランク付けされた結果の順位が下がることはありません。

TETHER_ASSOC=0(または budget=0、あるいはグラフが空の場合)、recall は以前とまったく同じように動作します。連想検索は純粋に結果を追加する機能であり、検索を壊すことはありません。

ストアの自己整理(任意)

ストアが大きくなると、tether は同じ使用グラフを使って、見通しを保ちます。

  • ハブを軸に整理されたブートインデックス。 自動読み込みされるメモリインデックスは、TETHER_BOOT_INDEX_CAP(デフォルトは 50)を超えると上限が適用されます。上限は常に適用されるため、大きなストアでもインデックスが無制限に増えることはありません。グラフがある場合、上限を超えると、ラベル付きの 2 つのまとまりが表示されます。行動面で重要な次数(explicit リンク+学習された共想起が対象で、単なる類似性は対象外)が最も高いメモリと、最も新しいメモリです。これにより、インデックスを小さく保ちながら、本当に重要なものを示します。グラフがない場合(TETHER_ASSOC=0)は、ハブ/新しさで分けず、最新のものから N 件を並べたリストに切り替わります。上限未満の場合は、どちらの場合も新しい順の全件リストになります。
  • 接続解除による忘却(オプトイン、TETHER_FORGET)。TETHER_FORGET_INTERVAL 回の書き込みごとに、上限付きの一括処理が実行され、古く(TETHER_FORGET_AGE_DAYS、デフォルトは 90 日)、かつ行動面で孤立している(explicit/hebbian エッジがない。意味的類似性は対象外)メモリがソフトアーカイブされます。アーカイブされたメモリは想起とブートインデックスから除外されますが、保持され、元に戻すこともできます(統合と同じ無効化マークの仕組みを再利用するため、何も削除されません)。安全策として、行動グラフが有効でない場合、メモリが 2 × CAP 未満の場合、または 1 回の処理で TETHER_FORGET_MAX_PER_SWEEP(デフォルトは 10)を超える場合は実行されません。
varデフォルト効果
TETHER_BOOT_INDEX_CAP50このサイズを超えたブートインデックスを整理する
TETHER_FORGEToff忘却処理を有効にする
TETHER_FORGET_AGE_DAYS90古くなる処理の対象となる最低経過日数
TETHER_FORGET_INTERVAL20処理の間に行う書き込み回数
TETHER_FORGET_MAX_PER_SWEEP101 回の処理でアーカイブできる最大数

TETHER_FORGET がオフ(デフォルト)で、ストアのサイズが通常の範囲であれば、想起とブートインデックスの動作はこれまでとまったく同じです。

結晶化(任意、デフォルトではオフ)

TETHER_CRYSTALLIZE=1 の場合、tether は振り返りを行い、関連するメモリが密集したクラスターを検出して、名前を付ける候補として提示します。振り返りの際に tether://crystallization を読み込むと、候補クラスターを取得できます(これはプル専用で、自動読み込みされることはありません)。remember(..., crystallizes=[source_ids]) で実際の原則に名前を付けると、その原則が書き込まれ、元となるメモリにリンクされます。または、dismiss_cluster(id_a, id_b) で候補を却下できます。クラスターは明示的なリンク+使用状況を基に構成されます(意味的類似性はメンバーの補完に使われるため、単なる話題の類似性ではなく、*「これらは一緒にまとまる」*という構造を見つけられます)。構造を見つけるのは tether で、言葉を与えるのはエージェントです。

結晶化された原則はブートインデックスのハブとなり、想起時には元となるメモリからたどれるようになります。注:「名前が付いている」ことは、「使われている」「リンクされている」と並ぶ 3 つ目の重要性シグナルになります。エージェントが何かを原則に値すると判断することは強いシグナルであるため、意図的な設計です。

ツール

ツール機能
remember(type, title, body, tags?, links?, crystallizes?)メモリを保存します。type+title が一致すると更新するため、事実を重複させずに洗練できます。crystallizes=[ids] は、その情報源をもとに原則として記録します(TETHER_CRYSTALLIZE が必要です)
recall(query?, type?, limit?, budget?, session?, tags?, id?, full?)キーワード検索とセマンティック検索を組み合わせ、使用グラフをたどって関連するメモリを取得します。id/type/title/body/tags/updated_at と via の記録を返します。body は クエリを中心とした抜粋 です。抜粋を参照してください。id=N を指定すると、1 件のメモリ全体を取得します。tags は完全一致のフィルターです(メモリは指定したタグをすべて持つ必要があります)。query と組み合わせるか、query を省略すると、指定タグに一致するすべてのメモリを確実に取得できます
link(id_a, id_b)2 件のメモリを双方向にリンクします
forget(id)メモリを論理削除します。行を削除するのではなく、統合と同じ取り消し可能な valid_to の仕組みを使って、現在有効ではないものとしてマークします(recall/起動インデックスから除外されます)。完全に削除する方法については、エクスポートと完全削除を参照してください
dismiss_cluster(id_a, id_b)リフレクション制御(結晶化):ピークエッジ (id_a, id_b) を起点とする候補クラスターを破棄し、再提示されないようにします。メモリ操作ではなく、TETHER_CRYSTALLIZE が有効な場合にのみ関係します

加えて、3 つのリソースがあります。各セッションで表示される、自動読み込みの tether://memory-index(メモリごとに1行の簡潔なインデックス)、プル専用の tether://status(セマンティック検索/同期の状態、メモリ数とエッジ数、DB パスなど、実際に有効な機能をデバッグするためのランタイム設定)、そして TETHER_CRYSTALLIZE が有効な場合のプル専用 tether://crystallization(リフレクション処理用の候補クラスター)です。

抜粋

recall は、各メモリの本文全体ではなく、関連性を中心とした抜粋を返します。表示範囲は、クエリの語が最初に現れる位置を中心とするため、冒頭部分だけでなく、メモリが一致した理由を確認できます。途中で切り詰められた検索結果には truncated: true と実際の長さを示す body_chars も含まれます。必要なメモリを全文で取得するには、recall(id=N) を使います。

これは検索エンジン型の形式です。結果リストは関連性を判断するのに十分なテキストを含むポインターのインデックスであり、ドキュメント本体ではありません。メモリは大きくなることがあるため、この点は重要です。44KB のジャーナルメモリが1件あるだけで、無関係なクエリでも取得処理自体は1ミリ秒未満なのに、呼び出しごとに約57~67KBのコストが発生していました。問題はエンジンではなく、応答が大きすぎることでした。

クエリ全文抜粋
seed dominance57.0KB1.4KB
hebbian edges66.9KB2.0KB
cold start latency66.9KB2.0KB

抜粋の幅より短いメモリは、以前とまったく同じように、マークなしで全文が返されます。

変数/引数デフォルト効果
TETHER_EXCERPT_CHARS500抜粋の幅。0 にすると全文を返します
id(呼び出しごと)—このメモリだけを全文で取得します
full(呼び出しごと)falseすべての検索結果を全文で返します。全ペイロード分のコストがかかるため、id= の使用を推奨します

パフォーマンスと耐久性

tether はエージェントのループ内で意識されないことを目指しているため、ホットパスを測定し、ストアの成長に伴って遅くならないようにしています。以下の数値は、セマンティック層と連想層を有効にした、単一プロセスのローカル SQLite ストアで測定したものです。

memoriesrememberrecall(まれな用語)recall(ほとんどのメモリに含まれる用語)
5001.6 ms1.8 ms3.7 ms
2,0001.8 ms2.5 ms7.7 ms
8,0003.4 ms1.0 ms19 ms

このパフォーマンスを維持する要因をいくつか紹介します。

  • 書き込み処理はストアのサイズに左右されません。 セマンティック検索と近傍の接続に使う埋め込み行列はメモリ上に保持され、SQLite から読み直すのではなく、書き込みのたびに行単位で更新されます。ベクトルが一括で変更された場合(モデル変更やバックフィル)、または別のプロセスがファイルに書き込んだ場合(CLI の purge、2 つ目のサーバー、同期によるプル)にのみ再構築されます。この変更は SQLite の data_version カウンターで検出します。
  • 並列のツール呼び出しは直列化されます。 MCP は各ツール呼び出しを個別のスレッドで実行し、エージェントは並列に呼び出しを行います。すべての Store 操作で同じロックを使うため、recall と remember が同時に到着しても、それぞれがアトミックに実行されます。トランザクションが交錯したり、書き込みが中途半端にコミットされたりすることはなく、action は常に正確です。
  • コミット時に fsync は行いません。 ローカル接続では synchronous=NORMAL の WAL を使用します。破損に対しては引き続き安全ですが、チェックポイントの前に マシン の電源が落ちると、直近の数件のトランザクションが失われる可能性があります(アプリケーションがクラッシュしても何も失われません)。remember は毎回コミットし、グラフを有効にしている場合は recall も毎回コミットするため、呼び出しごとにディスク同期を 1 回省けます。
  • 検索のコストは低く抑えられます。 ベクトル検索は、メモリ上の行列に対する numpy の単一の行列積です。メモリが数千件あっても 1 ミリ秒を大きく下回るため、インストールが必要なベクトルインデックス拡張はありません。キーワード検索のコストは FTS5 に依存し、クエリに一致するメモリの数に比例します。

一度だけ発生するコストにもご注意ください。[semantic] エクストラのインストール後(またはモデルの変更後)の初回起動では、既存のすべてのメモリを埋め込み、近傍を接続します。数千件あたり 1〜2 秒かかります。ブートインデックスとタグのみの検索では、呼び出しのたびにストアをスキャンします。一般的な規模ではどちらも高速(2,000 件で 10 ms 未満)で、次にキャッシュする予定の項目です。

ベンチマーク

bench/ には 2 つのハーネスがあり、どちらも API キーなしで実行できます。

  • python -m bench.locomo — LoCoMo を使った検索のみの評価です。約 1,500 件の質問があり、各質問の回答となる対話ターンがラベル付けされた、10 件の長い複数セッションの会話を使います。各ターンをメモリにし、recall(question) が該当するターンを返すかどうかを条件ごとに測定します(recall@k、MRR)。条件はキーワードのみ、キーワード + セマンティック、連想検索の全経路で、教科書的な BM25 ベースラインと比較します。LLM は関与しないため、メモリ層が制御する唯一の要素、つまりエージェントに正しい事実を渡せたかどうかを測定します。同じデータセットについてメモリベンダーが公開している、LLM による判定を用いた「正確さ」の数値とは比較できません。データ(約 1.5 MB)は初回実行時にダウンロードされます。実際のモデルを使ってセマンティック検索と連想検索の条件を測定するには、[semantic] エクストラをインストールしてください。
  • python -m bench.run — tether 独自の連想想起評価です。共に使用されるタスクのメンバーからなる制御されたコーパスを使い、使用をシミュレーションした後、キーワード + セマンティック検索に対して使用グラフが何を追加するかを測定します。[semantic] エクストラが必要です。

エクスポートと完全削除

forget はデータを削除しません。統合と同様に、論理削除します。エージェントが実行できないよう、MCP ツールとしては意図的に公開していない 2 つの管理操作を、シンプルな CLI で利用できます。

tether export                    # dump all current memories to JSON (stdout)
tether export -o backup.json     # ...or to a file
tether import backup.json        # merge an export back into the store
tether restore <id>              # un-forget a soft-deleted memory
tether purge <id> --yes          # permanently delete a memory (bypasses forget)

import は通常の書き込み経路でレコードを再生するため、remember と同様に type+title でアップサートします。空でないストアにインポートすると、重複を作らずにマージされます。ID は保持されません(ファイル内の ID が、ここでは別の ID に対応する場合があります)。リンクはそれに応じて再マッピングされ、ファイル外を指すリンクは、誤ったメモリを指すのではなく削除されます。レポートには結果が示されます:{"created", "updated", "skipped", "linked", "dropped_links"}。

restore は valid_to をクリアし、forget(または統合、忘却処理)を取り消します。その後、より新しいメモリが同じ type+title を持つようになった場合は、何も説明せずに失敗するのではなく、競合するメモリを示して処理を拒否します。

purge は --yes を指定しないと実行できません。すべてのコマンドで、サーバーと同じ TETHER_DB/TETHER_SYNC_* 環境変数が使用されます。

ライセンス

MIT

コメント

MCP は初めてですか?

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

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