mcpField
I
Inkwell

Inkwell

ローカル
veronchenko.github.ioメモリ・ナレッジ21 日前に更新

Inkwell について

Inkwellは、セッションやプロジェクトをまたぐ永続メモリをAIエージェントに提供するセルフホスト可能なMCPサーバーです。Markdownを正本とし、ハイブリッド検索、型付きグラフ、二時点履歴で知識を保持します。

主な機能

  1. 01Markdownファイルを正本として使用
  2. 02BM25とローカル埋め込みのハイブリッド検索
  3. 03型付きグラフリンクとバックリンク
  4. 04エントリー型の検証
  5. 05二時点のバージョン履歴
  6. 06stdio、SSE、HTTPトランスポート

活用シーン

  1. 01セッションをまたいだプロジェクト決定の検索
  2. 02問題の原因と解決策の記録
  3. 03知識エントリーの変更履歴の追跡

MCP 対応

remember、recall、search、list、tags、forget、rebuild、doctorなどのツールでナレッジベースを操作できます。stdio、SSE、streamable-httpのトランスポートに対応します。

設定

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

mcp.json · 共通設定
{
"mcpServers": {
"veronchenko-inkwell-memory": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"INKWELL_DATA_PATH",
"-e",
"INKWELL_ENABLE_DASHBOARD",
"docker.io/foreigndmitryi/inkwell-memory:0.14.0"
],
"env": {
"INKWELL_DATA_PATH": "<INKWELL_DATA_PATH>",
"INKWELL_ENABLE_DASHBOARD": "<INKWELL_ENABLE_DASHBOARD>"
}
}
}
}
起動コマンドdocker run -i --rm -e INKWELL_DATA_PATH -e INKWELL_ENABLE_DASHBOARD docker.io/foreigndmitryi/inkwell-memory:0.14.0
設定が必要な環境変数
INKWELL_DATA_PATHKnowledge base root inside the container; matches the volume mount target
INKWELL_ENABLE_DASHBOARDSet to 0 to skip the web dashboard process and run the MCP server only

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

パッケージ
ocidocker.io/foreigndmitryi/inkwell-memory:0.14.0

ツール

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

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

詳細

Inkwell — 永続ナレッジベース MCP サーバー

License: MIT Docker Pulls Python 3.12+

Inkwell はセルフホスト可能な Model Context Protocol サーバーで、AI エージェントがセッションやプロジェクトをまたいで永続的なメモリを利用できるようにします。他のメモリサーバーと異なる点は 3 つあります。プレーンな Markdown ファイルを信頼できる唯一の情報源とすること(インデックスは削除して再構築できる使い捨てのキャッシュです)、情報を平坦な山に放り込むのではなく、型付きの kb:// グラフでつなぐこと、そして更新が二時点的であることです。事実を置き換えても古いバージョンは上書きされず、読み取り可能なまま残ります。

Docker Hub: foreigndmitryi/inkwell-memory · ウェブサイト: veronchenko.github.io/inkwell-memory

以前の名称は Engram です。 0.14.0 で名称を変更しました。「Engram」という名前の無関係なプロジェクトが多数あり、名前で見つけにくくなっていたためです。それらのプロジェクトとも、Engram キーボード配列とも関係ありません。名称変更による影響については、変更履歴をご覧ください。

目次

コンセプト

エージェントとの会話は終了すると、コンテキストも一緒に失われます。Inkwell はそれを維持するための仕組みです。エージェントが行動する前に検索し、簡単にはわからない問題を解決した後に書き込むナレッジベースです。これにより、同じプロジェクトでも別のプロジェクトでも、次のセッションはすでに学んだことをもとに始まり、同じことを一から導き出す必要がありません。

Inkwell には、見つけ出せる情報を一切保存しません。コード、Git 履歴、設定ファイル、既存のドキュメントから取り出せる事実は、Inkwell に保存するものではありません。そうした情報を見つけるには、grep したり読み直したりすればよいからです。保存するのは、会話がなければ失われてしまう種類の知識です。つまり、却下した代替案も含む決定、バグの根本原因と修正方法、苦労して身につけた手順、一度伝えられた後も守るべき好みなどです。

ナレッジベースが増えても使いやすさを保つ仕組みは 2 つあります。

  • アトミック性 — 1 つのエントリには 1 つの事実を記録します。remember は Markdown の見出し、3 段落を超える内容、512 B/1 KB を超える内容に対して(処理を妨げずに)警告します。これにより、検索で上位に表示されにくい長文に複数の事実を詰め込むのではなく、それぞれを個別のエントリに分けてリンクするよう促します。
  • 寄せ集めではなくグラフ — エントリ同士を kb://uuid#type 参照でつなぎます。そのため、関連する事実(中心となるプロジェクト、その機能、そのいずれかに関連する診断など)を、孤立した行として保存するのではなく、双方向にたどれます。

特長

  • ハイブリッド検索 — SQLite FTS5(BM25、Porter ステミング)とローカルの Model2Vec 埋め込みに対するコサイン類似度を、タイトル/タグを対象とする IDF 加重の完全一致チャネルと Reciprocal Rank Fusion で統合します。意味からも、BM25 や埋め込みだけでは語彙的に似た紛らわしい候補に埋もれてしまう固有名詞の完全一致からもエントリーを見つけられ、クラウドへの依存はありません
  • 型付きグラフ関係 — エントリー間の kb://uuid#type リンクを recall のたびに両方向(外向きリンク+バックリンク)で解決します。オプションの第 2 ホップ(hops=2)を使うと、2 つのエントリーが中間のエントリーを介してどうつながっているかを確認できます
  • スキーマで強制されるエントリー型 — hub、decision、diagnostic、feature、procedure、integration、pattern、snippet、preference、idea を schema.json で宣言し、クライアントには列挙型として公開します。そのため、無効な型を書き込むことはできません。検索/一覧表示時に絞り込み可能です
  • doctor による整合性チェック — スキーマに基づく 1 回のチェックで、Markdown ファイル内のリンク切れや置き換え済みリンク、未宣言の型、テンプレート項目の不足、スーパーノード、タグと型の衝突を検出します
  • part_of による構造的な所属関係 — 詳細エントリー(decision、diagnostic、feature、procedure、integration など)をそのハブにリンクし、スキーマによって型ごとに強制されます。search/list で絞り込みでき、ハブの recall ダイジェストでは kb:// バックリンクとともにグループ化されます
  • 双時制バージョニング — remember(..., supersede=True) は上書きせずに新しいバージョンを作成します。古いバージョンは失われることなく、履歴に残ります(include_superseded=True)
  • 重複検出とリンク候補の提示 — remember はほぼ同じタイトルを照合してエントリーの重複を防ぎ、suggested_links(埋め込み類似度による一致)を返します。関連する事実を孤立させず、相互に参照させることができます
  • アトミック性を保つためのガードレール — 構造上のアンチパターン(見出し、3 段落超、大きすぎるコンテンツ)について、ブロックしない警告を表示します。規模が拡大しても、ナレッジベースを 1 エントリー 1 事実に保てます
  • Web ダッシュボード — MCP ツールが使用するものと同じナレッジベースを対象に、力学モデルによるグラフ表示、ハイブリッド検索、CRUD パネルを提供します(ダッシュボードを参照)
  • 3 種類のトランスポート — stdio(エージェントが管理)、SSE、streamable-http に対応し、単一のローカルエージェントから共有型のマルチエージェント環境まで、同じサーバーを利用できます
  • Markdown を信頼できる唯一の情報源として使用 — SQLite インデックスは再構築可能なキャッシュです。削除して rebuild しても、データが失われることはありません

比較

InkwellMem0Zep / GraphitiLangMem
信頼できる唯一の情報源ディスク上の Markdown ファイルベクターデータベース/マネージド API時間的知識グラフベクターストア(LangChain ベース)
検索BM25 + ローカルの Model2Vec 埋め込み(RRF による統合)ベクトル類似度グラフ探索 + 埋め込みベクトル類似度
関係明示的な kb://uuid#type リンクをエージェントが作成暗黙的(LLM が抽出した事実)自動抽出される時間的グラフのエッジ標準機能としてはなし
時間モデル書き込み時の双時制 valid_at/supersede事実の上書きネイティブな時間的グラフ(双時制エッジ)標準機能としてはなし
デプロイセルフホスト可能、単一の Docker イメージ、クラウドへの依存なしホスト型 API またはセルフホスト+ベクターデータベースセルフホスト可能、Neo4j が必要ライブラリ、サーバーなし
設計の中心意図的に最小限 — 発見可能な情報はゼロで、何を保持する価値があるかはエージェントが判断会話から事実を自動抽出エンティティ/関係を自動抽出LangGraph エージェント向けの組み合わせ可能なメモリプリミティブ

Inkwell は Mem0 や Zep のような自動抽出ではなく、エージェントが整理する、アトミックで明示的にリンクされたナレッジベースを採用しています。LLM 主導の取り込みパイプラインも、グラフデータベースへの依存もありません。また、ディスク上の Markdown は人が読める形式で、差分を確認できます。

通常の Markdown Wiki との比較

Inkwell を、通常の Markdown Wiki として構成した同じナレッジベースと比較してベンチマークしました。各トピックを 1 ファイルにまとめ、プロジェクトやカテゴリ(decision、diagnostic、feature、procedure、...)ごとのフォルダーに整理し、各プロジェクトにインデックスページを用意して、関連ページ間を相互リンクで結び、Read/Grep/Glob/Bash を使って閲覧します。同じコンテンツを 2 通りの方法で検索し、同等のファクトカバレッジを得るために、Inkwell の search/recall が使用したものは次のとおりです。

InkwellWiki改善率
ツール呼び出し回数104186-44%
合計トークン数3.87M5.91M-35%
コスト$1.31$1.62-19%
経過時間(合計)577s760s-24%
ファクト率1.0000.964+3.7%

4 つの架空プロジェクトにわたる厳選された 70 件のファクトと、5,000 件の実テキストのダミーエントリを含む 5,070 件のエントリを対象に、32 個の質問(単一ホップ、複数ホップ、否定、クロスリンガル、置き換え)で評価しました。これにより、エージェントのコンテキストに収まらない規模でも検索が機能する必要があります。

wiki/
├── Ledgerbird/                       )
├── Pipewren/                         )  4 curated projects — 70 real
├── Snipfox/                          )  decisions/diagnostics/features/
├── Featherstore/                     )  procedures/integrations/snippets
│   ├── README.md                        <- project index page, links to every entry below
│   ├── decision/
│   │   ├── offline-engine-duckdb-over-spark.md
│   │   ├── online-value-serialization-msgpack.md
│   │   └── ... (2 more)
│   ├── diagnostic/
│   │   ├── redis-memory-doubling-from-ttl-less-deprecated-feature-groups.md
│   │   └── training-serving-skew-from-tz-naive-event-timestamps.md
│   ├── feature/       (4 entries)
│   ├── integration/   (2 entries)
│   ├── procedure/     (1 entry)
│   └── snippet/       (1 entry)
├── _shared/                             cross-project patterns & preferences
└── haystack-project-00000.../00199/     200 distractor projects x 25 pages
    │                                     = 5,000 real-text (Wikipedia) pages
    ├── README.md                        <- same index-page shape as a real project
    ├── decision/   (2 entries)
    ├── feature/    (3 entries)
    ├── idea/       (7 entries)
    ├── pattern/    (4 entries)
    ├── procedure/  (1 entry)
    └── snippet/    (2 entries)

各カテゴリフォルダーは 1 エントリにつき 1 ファイルのフラットな一覧で、各プロジェクトフォルダー(実データまたはダミー)には、すべてのファイルへのリンクを含む独自の README.md インデックスページがあります。構造は同一のため、Wiki 側は構造だけから厳選されたファクトとダミーを見分けることができません。

どこを探せばよいかをすでに知っているエージェントは、目的の情報にたどり着くために grep、再読込、再度の grep を繰り返す必要がありません。同等のファクトカバレッジを得る場合、効率面での優位性は維持されます。検索ランキングも改善を続けています。IDF 加重の完全一致チャネル(以下)を追加した結果、MRR は 0.851 から 0.857 に、recall@5 は 0.851 から 0.869 に向上し、どの言語でも性能の後退はありませんでした。

設計パターン

  • Reciprocal Rank Fusion — BM25 と埋め込みのランキングを独立して計算し、生のスコアではなく順位に基づいて統合することで、比較できない類似度指標を正規化する必要をなくします。
  • 信頼できる情報源の上に再構築可能なキャッシュを配置 — SQLite インデックスは Markdown ファイルから完全に派生しており(rebuild によって一から再生成されます)、データベースがファクトの唯一のコピーになることはありません。
  • 双時制バージョニング — supersede は既存のエントリを上書きせずに新しいエントリを書き込み、superseded_by を介して古いエントリから新しいエントリを参照するため、履歴を引き続き照会できます(include_superseded)。
  • HATEOAS スタイルのグラフ探索 — すべての recall レスポンスには、出力方向と入力方向の kb:// リンクが含まれるため、ナレッジグラフの移動にホップごとの個別クエリは必要ありません。
  • 共有ドメイン層と 2 つのトランスポート — ダッシュボードの REST API と MCP ツールは、どちらも同じ KnowledgeBase/SQLiteBackend メソッドを呼び出すため、どちらのインターフェースから実行しても書き込みのコードパスは 1 つだけです。

アーキテクチャ

Markdown files  --->  Search index  --->  MCP  --->  Agent
(source of truth)     (SQLite FTS5 +      (server.py)  (Claude Code,
                        Model2Vec,                       ChatGPT, ...)
                        rebuildable cache)

<data-path>/entries/ 内の Markdown ファイルだけが唯一の信頼できる情報源です。SQLite インデックス(search_backend.py)は、それらから構築される破棄可能なキャッシュです。BM25 と Model2Vec の埋め込みを Reciprocal Rank Fusion で統合し、kb:// の関係グラフも含みます。インデックスはいつでも rebuild で再生成できます。server.py は、そのインデックスを MCP ツール(remember/recall/search/...)としてエージェントに公開します。ダッシュボードは同じレイヤーにある別のエントリーポイントで、MCP ではなく REST 経由で同じ KnowledgeBase/インデックスに直接アクセスします。そのため、remember/delete の動作は、エージェントから呼び出す場合もブラウザーで手動編集する場合も同じです。

  • src/server.py — MCP ツールの定義(remember、recall、search、list、tags、forget、rebuild、doctor)、単一プロセス、stdio/SSE/streamable-http トランスポート
  • src/database.py — KnowledgeBase:Markdown と YAML frontmatter の CRUD、UUID の割り当て、重複検出、二時点 supersede ロジック
  • src/schema.json + src/schema.py — エントリーの分類体系とタイプごとのルールをデータとして定義し、それらを MCP クライアントが検証する entry_type enum に変換するローダー
  • src/doctor.py — doctor ツール、rebuild の警告、remember の適合性チェックで共用する、スキーマ駆動の整合性チェック
  • src/search_backend.py — SQLiteBackend:BM25(FTS5)と Model2Vec のコサイン類似度を Reciprocal Rank Fusion で統合し、kb:// の関係抽出/グラフ走査も実行します。埋め込みは書き込み時に遅延計算され、BLOB 列に保存されます
  • src/dashboard/ — 同じ KnowledgeBase を再利用する、2 つ目の任意のプロセス(app.py の FastAPI REST + /api/graph、static/index.html のバニラ JavaScript によるキャンバスグラフ、独自の uvicorn エントリーポイントである __main__.py)
  • plugins/inkwell-hooks/ — Claude Code と Codex の両方にインストールできる自己完結型プラグイン(.claude-plugin/plugin.json、SessionStart/Stop/SessionEnd + 検索してから記憶することを強制する PreToolUse ゲート、さらに Claude Code 専用の inkwell-project-onboarder エージェント)。システムプロンプトだけに頼らず、検索を先に行い、その後に記憶するワークフローを機械的に徹底します。リポジトリルートの .claude-plugin/marketplace.json(Claude Code)と plugins/marketplace.json(Codex)の両方で inkwell-hooks として登録されています

Docker では、MCP サーバーとダッシュボードは 1 つのコンテナー内で 2 つのプロセスとして実行され(docker-entrypoint.sh)、同じ /knowledge ボリュームを共有します。どちらかのプロセスが停止すると、コンテナーも終了します。

クイックスタート

stdio

エージェントがサーバーを管理します。Claude Code、ChatGPT Desktop、Cursor におすすめです。

claude mcp add --transport stdio inkwell -- \
  docker run -i --rm -v ./knowledge:/knowledge foreigndmitryi/inkwell-memory
SSE

ネットワーク上でサーバーを常時実行します。複数のエージェント間でナレッジを共有できます。

docker run -d --name inkwell \
  -p 8192 \
  -v ./knowledge:/knowledge \
  foreigndmitryi/inkwell-memory --transport sse

docker port inkwell 8192   # host port Docker assigned
claude mcp add --transport sse inkwell http://your-host:<port>/sse

-p 8192(ホストポートを省略)を指定すると、固定ポート(8192 など)が別のコンテナーに使用されている場合に失敗する代わりに、Docker が空いている一時的なホストポートを割り当てます。実際の割り当ては docker port で確認してください。ホストポートを固定する必要がある場合は、代わりに -p 8192:8192 を指定します。

HTTP

ステートレスで、ロードバランシングが可能です。

docker run -d --name inkwell \
  -p 8192 \
  -v ./knowledge:/knowledge \
  foreigndmitryi/inkwell-memory --transport streamable-http

docker port inkwell 8192   # host port Docker assigned
claude mcp add --transport http inkwell http://your-host:<port>/mcp
マルチテナント

1 つのサーバーを複数のチームで使用し、それぞれのチームを専用のデータフォルダーと API キーで分離します。INKWELL_MULTI_TENANT=1 を設定してください(INKWELL_PUBLIC_URL と INKWELL_ADMIN_API_KEY、およびネットワークトランスポートが必要です。stdio は使用できません)。これにより、src/app.py が単一のプロセスから MCP、管理 UI、ダッシュボードを提供します。inkwell add-team <name> を実行してチームを作成すると(docker exec 経由で実行してください。詳細は src/cli.py を参照)、チームの API キーが取得できます。その後、各チームのエージェントから、キーをベアラートークンとして /mcp に接続します。

claude mcp add --transport http inkwell https://your-host/mcp \
  --header "Authorization: Bearer <TEAM_API_KEY>"

または、未加工の mcpServers 設定を使用します(Claude Desktop およびその他のクライアント向け)。

{
  "mcpServers": {
    "inkwell": {
      "type": "http",
      "url": "https://your-host/mcp",
      "headers": {
        "Authorization": "Bearer <TEAM_API_KEY>"
      }
    }
  }
}

TeamTokenVerifier(src/server.py)は、リクエストごとにトークンをハッシュ化し、admin.db で照合します。キャッシュは行われないため、キーを失効させるとすぐに使用できなくなります。

検索

ハイブリッド検索:SQLite FTS5(Porter ステミング、BM25)と、ローカルの Model2Vec 埋め込み(minishlab/potion-multilingual-128M、クラウド依存なし)によるコサイン類似度を Reciprocal Rank Fusion で統合します。そのため、エントリーと文字列がまったく一致しないクエリでも、意味に基づいて見つけられます。埋め込みモデルを読み込めない場合は、キーワードのみの検索にフォールバックします。インデックスは引き続き単一の SQLite ファイルなので、標準的な SQL ツールでクエリできます。

ツール

ツール説明主なパラメーター
rememberエントリーを作成または更新します(重複検出を伴う upsert、または supersede によるバージョン管理)。entry_type は必須で、part_of(ハブ UUID)は、スキーマの membership ルールに従って、タイプごとに必須・任意・拒否となります。size、ブロックしないアトミック性に関する warnings(Markdown の見出し、3 段落超、512 B/1 KB 超)、および相互参照に kb:// リンクを使う価値のある、埋め込み類似度に基づく重複に近いエントリー/関連エントリー suggested_links を返します。title, content, tags, entry_type, entry_id, force, resource, supersede, part_of
recallグラフ上の関係(アウトゴーイングリンクとバックリンク)とともにエントリーを読み込みます。size と last_modified を返します。次数の高いタイプ(ハブ)では、任意に切り詰めたリストの代わりに、リンク元のタイプごとにまとめたバックリンクと、part_of ごとにまとめたメンバーを含む in_digest を返します。entry_id, relations_limit
searchタグ、完全一致の entry_type、および/または part_of でフィルターできる、キーワードとセマンティック検索のハイブリッドquery, tags, limit, include_superseded, entry_type, part_of
listタイトル順にエントリーを表示します。タグ、完全一致の entry_type、および/または part_of でフィルターできます。tags, limit, include_superseded, entry_type, part_of
tagsエントリー数とともにすべてのタグを一覧表示します—
forgetエントリーを削除します(ファイルとインデックス)。ほかのエントリーからリンクされている場合は警告します。entry_id
rebuildMarkdown ファイルから検索インデックスを再構築し、doctor も実行します—
doctorschema.json に照らしてすべてのエントリーを確認します:リンク先が存在しない/置き換え済みの kb:// ターゲット、未宣言のタイプ、必須のフロントマターやテンプレート本文フィールドの不足、スーパーノード、タグとタイプの衝突—
エントリースキーマ

エントリーの分類とタイプごとのルールは Python ではなく schema.json に記述されています。各タイプに必要なフロントマターフィールド、含めるべきテンプレート本文フィールド、使用状況に応じて検索順位を上げられるかどうか、recall がバックリンクをダイジェストするかどうかを定義します。entry_type は、このスキーマから構築された列挙型として MCP クライアントに公開されるため、未宣言のタイプはサーバーに呼び出しが届く前に拒否されます。

解決順序は先に見つかったものが優先されます:<data-path>/schema.json、次にパッケージに含まれる src/schema.json です。ユーザーファイルを指定すると、パッケージ版は完全に置き換えられます。両者がマージされることはないため、デフォルトをコピーして編集してください。スキーマは起動時に一度だけ読み込まれるため、編集するにはサーバーを再起動する必要があります。手動で作成したエントリーには未宣言のタイプを設定できますが、doctor がそれらを報告します。

ダッシュボード

MCP ツールが使用するナレッジベースを視覚的に探索し、直接編集できる Web UI です。プロトコルを重複させず、すべての操作は KnowledgeBase を通じて実行されます。

  • すべてのエントリと kb:// リレーションを表示する力学モデルグラフ — ノードをクリックすると内容を確認でき、凡例のチップをクリックするとタイプで絞り込めます(一致するものは明るく表示され、その他は暗く表示されます)
  • search MCP ツールと同じ BM25 +セマンティックインデックスを使ったハイブリッド検索。タグと entry_type で絞り込めます
  • Markdown ファイルを手動で編集せずに、エントリの作成、編集、置き換え、削除ができるCRUD パネル — 外向き/内向きのグラフリレーションも各フィールドとあわせて表示されます
  • ダークで情報量が多く、余計な装飾のないインターフェースです。一般ユーザー向けアプリではなく、メンテナンス用ツールです(PRODUCT.md/DESIGN.md を参照)

デフォルトでは無効です(コンテナで実行されるのは MCP サーバーのみです)。同じコンテナ内の 2 つ目のプロセスとして有効にします。

docker run -d --name inkwell \
  -e INKWELL_ENABLE_DASHBOARD=1 \
  -p 8192 -p 8193 \
  -v ./knowledge:/knowledge \
  foreigndmitryi/inkwell-memory --transport sse

docker port inkwell 8193   # dashboard host port

または、ローカルで単独実行します:python -m dashboard(INKWELL_DASHBOARD_HOST/INKWELL_DASHBOARD_PORT については設定を参照)。

グラフリレーション

Markdown コンテンツ内で kb://uuid#type URL を使ってエントリをリンクします。

This service runs on [Saturn](kb://a1b2c3d4-...#runs-on)
and depends on [PostgreSQL](kb://f9e8d7c6-...#depends-on).

recall はサイズのメタデータに加え、両方向のリレーションを返します。

{
  "id": "a1b2c3d4-...",
  "title": "My API Service",
  "content": "...",
  "tags": ["..."],
  "size": 1024,
  "last_modified": "2026-03-14",
  "relations": {
    "out": [{"type": "runs-on", "id": "e5f6...", "title": "Saturn"}],
    "in": [{"type": "depends-on", "id": "b7c8...", "title": "Frontend App"}]
  }
}

ナレッジのための HATEOAS のように、すべてのレスポンスにグラフをたどるためのリンクが含まれます。

使用例

ナレッジを保存する

エージェントに次のように依頼します。

「API がポート 8080 で動作し、PostgreSQL 15 に依存していることを覚えておいてください。」

Inkwell は一意の UUID を持つ Markdown ファイルを作成してインデックス化し、完了を知らせます。エージェントは以降のセッションで、この事実を呼び出せるようになります。

検索する

「PostgreSQL について何がわかっていますか?」

Inkwell はすべてのエントリを対象に、内容、タイトル、タグから検索します。結果は関連度順に表示されます。

グラフをたどる

「PostgreSQL に依存しているものは何ですか?」

エントリから PostgreSQL の記事へ kb://uuid#depends-on でリンクされている場合、Inkwell はすべてのバックリンクを返します。エージェントが個別に検索しなくても、PostgreSQL に依存するすべてのサービスを確認できます。

エージェント間でナレッジを共有する

SSE または HTTP トランスポートで Inkwell を起動します。異なるプロバイダー(Claude、ChatGPT、Copilot)のエージェントを含む複数のエージェントが、同じサーバーに接続できます。あるエージェントが覚えたことは、他のエージェントも呼び出せます。

Agent A: "Remember that the deploy key rotates every 90 days."
Agent B: "When does the deploy key expire?"
→ Agent B finds the answer immediately.

エージェントへの指示

エージェントが Inkwell を後回しにせず、習慣的に使うようにするには、システムプロンプトまたはプロジェクトの指示に次の内容を追加します。

Inkwell is your persistent memory. Using it is mandatory, not optional.

Inkwell stores ZERO discoverable information. If you can derive it from
code, git history, configuration files, or existing documentation, it
does not belong in Inkwell. Inkwell captures decisions and their context,
diagnostics and their root causes, procedures learned the hard way —
the kind of knowledge that is lost when a conversation ends.

Before working on any topic: search Inkwell first. Always. Even if you think you know.
Before answering a question about infrastructure or architecture: search first.
Before proposing a solution: check if a past decision exists in Inkwell.

After resolving a diagnostic: remember the root cause and the fix.
After executing a procedure: remember the steps.
After making an architecture decision: remember the choice and the rationale.
After discovering something about the infrastructure: remember it.

セッションの途中でシステムプロンプトを忘れてしまうことはよくあります。plugins/inkwell-hooks/ には、自己完結型のプラグイン(SessionStart、Stop、SessionEnd、PreToolUse ハンドラーと、Claude Code 専用の inkwell-project-onboarder エージェント)が含まれています。指示がなくても、作業を始める前に Inkwell を検索し、完了前に重要な変更を remember するよう、エージェントに仕組みとして促します。このセクションを自発的に思い出すことには頼りません。Claude Code と Codex の両方で動作します。/plugin marketplace add <this-repo> に続けて /plugin install inkwell-hooks@inkwell-memory(Claude Code)、または codex plugin marketplace add <this-repo>/plugins に続けて codex plugin add inkwell-hooks@inkwell-memory(Codex)でインストールできます。各フックの動作とインストール手順の全体については、plugins/inkwell-hooks/README.md を参照してください。

Claude Code の組み込み自動メモリを無効にする

Claude Code には独自の自動メモリ(~/.claude/projects/<project>/memory/ 内の MEMORY.md。毎セッション読み込まれます)が付属しています。Inkwell と併用すると、2 つのシステムが重複するメモを書き込み、エージェントの注意を奪い合うため、役立つどころか妨げになります。settings.json で無効にします。

{
  "autoMemoryEnabled": false
}

または、環境変数を使います(設定および /memory の切り替えより優先されます):CLAUDE_CODE_DISABLE_AUTO_MEMORY=1。詳細は Claude Code のメモリに関するドキュメントを参照してください。

設定

すべてのオプションには、INKWELL_* 環境変数によるフォールバックがあります。CLI 引数が優先されます。

オプション環境変数デフォルト説明
--data-pathINKWELL_DATA_PATH/knowledgeナレッジデータのルートパス
--transportINKWELL_TRANSPORTstdioMCP トランスポート
--hostINKWELL_HOST0.0.0.0リッスンアドレス(SSE/HTTP)
--portINKWELL_PORT8192リッスンポート(SSE/HTTP)
--embedding-modelINKWELL_EMBEDDING_MODELminishlab/potion-multilingual-128Mセマンティック検索用の Model2Vec モデル
—INKWELL_ENABLE_DASHBOARD未設定(オフ)真偽値として評価される値(1/true/yes)を設定すると、MCP サーバーと並行してダッシュボードを別プロセスとして起動します
--host(ダッシュボード)INKWELL_DASHBOARD_HOST0.0.0.0ダッシュボードのリッスンアドレス
--port(ダッシュボード)INKWELL_DASHBOARD_PORT8193ダッシュボードのリッスンポート(このポート以上で最初に空いているポートが使用されます)
—INKWELL_QUERY_LOG未設定(オフ)ファイルパスを設定すると、search/recall の各呼び出しのトレースを JSONL 形式で追記し、検索品質の分析に利用します

ストレージ形式

エントリーは、<data-path>/entries/ 内の YAML フロントマター付き Markdown ファイルです。

---
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
title: Entry Title
tags: [infrastructure, postgresql]
type: decision
resource: /path/to/relevant/file
---

Markdown content here...

すべての remember 呼び出しで type が必須です(tags の一部ではなく、専用フィールドです)。このフィールドはエントリーを分類するもので(hub、decision、diagnostic、procedure、preference、snippet など)、search/list でフィルタリングできます。resource は任意で、エントリーが説明する正規のファイル/フォルダパスです。これらのフィールドが導入される前に作成された既存のエントリーも、問題なく読み込めます。

検索インデックスは、<data-path>/index/inkwell.db にある再構築可能なキャッシュです。削除してから rebuild を実行しても、データが失われることはありません。rebuild は、既存のエントリー全体にわたるスキーマ準拠に関する警告(type の欠落、不正な resource)も報告します。

開発

# Build
docker build -t inkwell .

# Test (separate Dockerfile — pytest/tests/ never ship in the production image)
docker build -f tests/Dockerfile -t inkwell-test .
docker run --rm inkwell-test

# Run locally (SSE)
docker run -d --name inkwell -p 8192 -v ./knowledge:/knowledge inkwell --transport sse

ライセンス

MIT

コメント

MCP は初めてですか?

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

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