Inkwell について
Inkwellは、セッションやプロジェクトをまたぐ永続メモリをAIエージェントに提供するセルフホスト可能なMCPサーバーです。Markdownを正本とし、ハイブリッド検索、型付きグラフ、二時点履歴で知識を保持します。
主な機能
- 01Markdownファイルを正本として使用
- 02BM25とローカル埋め込みのハイブリッド検索
- 03型付きグラフリンクとバックリンク
- 04エントリー型の検証
- 05二時点のバージョン履歴
- 06stdio、SSE、HTTPトランスポート
活用シーン
- 01セッションをまたいだプロジェクト決定の検索
- 02問題の原因と解決策の記録
- 03知識エントリーの変更履歴の追跡
MCP 対応
remember、recall、search、list、tags、forget、rebuild、doctorなどのツールでナレッジベースを操作できます。stdio、SSE、streamable-httpのトランスポートに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e INKWELL_DATA_PATH -e INKWELL_ENABLE_DASHBOARD docker.io/foreigndmitryi/inkwell-memory:0.14.0INKWELL_DATA_PATHKnowledge base root inside the container; matches the volume mount targetINKWELL_ENABLE_DASHBOARDSet to 0 to skip the web dashboard process and run the MCP server onlyローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Inkwell — 永続ナレッジベース MCP サーバー
Inkwell はセルフホスト可能な Model Context Protocol サーバーで、AI エージェントがセッションやプロジェクトをまたいで永続的なメモリを利用できるようにします。他のメモリサーバーと異なる点は 3 つあります。プレーンな Markdown ファイルを信頼できる唯一の情報源とすること(インデックスは削除して再構築できる使い捨てのキャッシュです)、情報を平坦な山に放り込むのではなく、型付きの kb:// グラフでつなぐこと、そして更新が二時点的であることです。事実を置き換えても古いバージョンは上書きされず、読み取り可能なまま残ります。
Docker Hub: foreigndmitryi/inkwell-memory · ウェブサイト: veronchenko.github.io/inkwell-memory
以前の名称は Engram です。 0.14.0 で名称を変更しました。「Engram」という名前の無関係なプロジェクトが多数あり、名前で見つけにくくなっていたためです。それらのプロジェクトとも、Engram キーボード配列とも関係ありません。名称変更による影響については、変更履歴をご覧ください。
目次
- コンセプト
- 機能
- 比較
- プレーンな Markdown Wiki との実測比較
- 設計パターン
- アーキテクチャ
- クイックスタート
- 検索
- ツール
- ダッシュボード
- グラフの関係
- 使用例
- エージェントへのプロンプト
- 設定
- ストレージ形式
- 開発
- ライセンス
コンセプト
エージェントとの会話は終了すると、コンテキストも一緒に失われます。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しても、データが失われることはありません
比較
| Inkwell | Mem0 | Zep / Graphiti | LangMem | |
|---|---|---|---|---|
| 信頼できる唯一の情報源 | ディスク上の 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 が使用したものは次のとおりです。
| Inkwell | Wiki | 改善率 | |
|---|---|---|---|
| ツール呼び出し回数 | 104 | 186 | -44% |
| 合計トークン数 | 3.87M | 5.91M | -35% |
| コスト | $1.31 | $1.62 | -19% |
| 経過時間(合計) | 577s | 760s | -24% |
| ファクト率 | 1.000 | 0.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_typeenum に変換するローダー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 |
rebuild | Markdown ファイルから検索インデックスを再構築し、doctor も実行します | — |
doctor | schema.json に照らしてすべてのエントリーを確認します:リンク先が存在しない/置き換え済みの kb:// ターゲット、未宣言のタイプ、必須のフロントマターやテンプレート本文フィールドの不足、スーパーノード、タグとタイプの衝突 | — |
エントリースキーマ
エントリーの分類とタイプごとのルールは Python ではなく schema.json に記述されています。各タイプに必要なフロントマターフィールド、含めるべきテンプレート本文フィールド、使用状況に応じて検索順位を上げられるかどうか、recall がバックリンクをダイジェストするかどうかを定義します。entry_type は、このスキーマから構築された列挙型として MCP クライアントに公開されるため、未宣言のタイプはサーバーに呼び出しが届く前に拒否されます。
解決順序は先に見つかったものが優先されます:<data-path>/schema.json、次にパッケージに含まれる src/schema.json です。ユーザーファイルを指定すると、パッケージ版は完全に置き換えられます。両者がマージされることはないため、デフォルトをコピーして編集してください。スキーマは起動時に一度だけ読み込まれるため、編集するにはサーバーを再起動する必要があります。手動で作成したエントリーには未宣言のタイプを設定できますが、doctor がそれらを報告します。
ダッシュボード
MCP ツールが使用するナレッジベースを視覚的に探索し、直接編集できる Web UI です。プロトコルを重複させず、すべての操作は KnowledgeBase を通じて実行されます。
- すべてのエントリと
kb://リレーションを表示する力学モデルグラフ — ノードをクリックすると内容を確認でき、凡例のチップをクリックするとタイプで絞り込めます(一致するものは明るく表示され、その他は暗く表示されます) searchMCP ツールと同じ 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-path | INKWELL_DATA_PATH | /knowledge | ナレッジデータのルートパス |
--transport | INKWELL_TRANSPORT | stdio | MCP トランスポート |
--host | INKWELL_HOST | 0.0.0.0 | リッスンアドレス(SSE/HTTP) |
--port | INKWELL_PORT | 8192 | リッスンポート(SSE/HTTP) |
--embedding-model | INKWELL_EMBEDDING_MODEL | minishlab/potion-multilingual-128M | セマンティック検索用の Model2Vec モデル |
| — | INKWELL_ENABLE_DASHBOARD | 未設定(オフ) | 真偽値として評価される値(1/true/yes)を設定すると、MCP サーバーと並行してダッシュボードを別プロセスとして起動します |
--host(ダッシュボード) | INKWELL_DASHBOARD_HOST | 0.0.0.0 | ダッシュボードのリッスンアドレス |
--port(ダッシュボード) | INKWELL_DASHBOARD_PORT | 8193 | ダッシュボードのリッスンポート(このポート以上で最初に空いているポートが使用されます) |
| — | 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
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。