Linkwarden について
Linkwarden は、セルフホスト可能でページを保存するブックマーク管理サービス Linkwarden 用の MCP サーバーです。保存済み記事の本文を取得でき、更新時には既存データをマージして無関係な項目の上書きを防ぎます。
主な機能
- 01ブックマークの検索と整理
- 02保存済み記事本文の取得
- 03コレクションとタグの管理
- 04既存データを保つ更新マージ
- 05ツールの絞り込みと読み取り専用設定
活用シーン
- 01保存したリンクの検索と確認
- 02アーカイブページの要約や引用
- 03コレクションとタグによる整理
MCP 対応
Linkwarden の検索、読み取り、ブックマーク管理機能を MCP クライアントに公開します。書き込みの無効化やツールの絞り込みが可能で、一部の破壊的操作には MCP elicitation または単回の確認トークンが必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y linkwarden-mcpLINKWARDEN_URLBase URL of the Linkwarden instance, e.g. https://links.example.net (without /api/v1)LINKWARDEN_TOKENシークレットAccess token from Settings -> Access TokensLINKWARDEN_READ_ONLYSet to true to register only the 11 read tools and no write toolsLINKWARDEN_ALLOW_TOOLSComma-separated tool names or list_* prefixes to register; 'essential' selects a curated preset (default: all tools)LINKWARDEN_DENY_TOOLSComma-separated tool names or list_* prefixes to remove from whatever LINKWARDEN_ALLOW_TOOLS leftLINKWARDEN_INSECURE_TLSSet to true to accept self-signed certificates for this connection onlyローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
28掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| sort | enum | いいえ | 並び順。デフォルトは date_newestdate_newest | date_oldest | name_az | name_za |
| query | string | いいえ | 検索クエリ。構文は上記を参照してください。省略するとリンクを一覧表示します。 |
| cursor | integer | いいえ | 不透明なページネーションカーソルです。以前の結果の "next_cursor" 値をそのまま渡してください。計算や増分は行わないでください。インスタンスで Meilisearch が実行されているかどうかにより、行オフセットまたは最後に確認した ID のいずれかになります。 |
| tag_id | integer | いいえ | 結果をこのタグに限定します |
| pinned_only | boolean | いいえ | 認証済みアカウントがピン留めしたリンクのみを返します |
| collection_id | integer | いいえ | 結果をこのコレクションに限定します |
詳細
linkwarden-mcp
Linkwarden 向けの Model Context Protocol(MCP)サーバーです。Linkwarden は、保存したすべてのページの永久コピーを保持するセルフホスト可能なブックマークマネージャーです。
Claude Code、Claude Desktop、Codex などの MCP クライアントから、ブックマークコレクションの検索、コレクションやタグへの整理、さらに保存したページの保管済み記事テキストの読み取りができます。そのため、アーカイブ済みのリンクを、ライブサイトを再取得せずに要約したり引用したりできます。
ツールは28個が上限であり、最低数ではありません。LINKWARDEN_ALLOW_TOOLS=essential を設定すると、厳選された8個だけが登録されます。モデルは28個よりも8個の中から適切なツールをはるかに確実に選べます。詳しくは読み込むツールの選択をご覧ください。

注記: Linkwarden が公開している API リファレンスは不完全です。このサーバーは、linkwarden/linkwarden の
apps/web/pages/api/v1/**にあるルートと、packages/lib/schemaValidation.tsにあるリクエストスキーマに基づいて作成され、2026-08-17 に v2.16.0 で検証されています。ここにあるすべてのツールの信頼できる情報源は、この2つのファイルです。
特徴
Linkwarden が保管した内容を読み取ります。 Linkwarden は保存したすべてのページの永久コピーを保持します。get_link_content はその記事テキストを返すため、保存済みリンクをライブサイトから再取得せずに要約したり引用したりできます。長い記事は一度に出力せず、分割して返します。
既存の情報を壊さずに整理します。 Linkwarden の更新ルートはレコード全体を置き換えます。このサーバーは現在の状態を読み取ってマージするため、タイトルを変更してもリンクのタグやコレクションの共同編集者が知らないうちに失われることはありません。
出力は許可リスト方式です。 Linkwarden は Prisma の行全体を返しますが、ここで結果に含めるすべてのフィールドは明示的に指定されています。記事テキストは一覧結果に含まれず、コレクションメンバーの氏名やメールアドレスも除外されます。また、将来のリリースで列が追加されても、知らないうちにモデルのコンテキストへ入り込むことはありません。
要件
- Node.js ≥ 22
- 起動中の Linkwarden インスタンス
- Settings → Access Tokens で作成したアクセストークン
Linkwarden にはトークンごとのスコープがありません。トークンには、作成したアカウントのすべての権限が引き継がれます。このサーバーが参照すべきコレクションだけにアクセスできる専用アカウントを作成し、管理者トークンを渡さないでください。
設定
| 変数 | 必須 | 説明 |
|---|---|---|
LINKWARDEN_URL | はい | ベース URL。例:https://links.example.net(/api/v1 を含めない) |
LINKWARDEN_TOKEN | はい | Settings → Access Tokens のアクセストークン |
LINKWARDEN_READ_ONLY | いいえ | true にすると、読み取りツールのみを登録します |
LINKWARDEN_ALLOW_TOOLS | いいえ | カンマ区切りのツール名、list_* のプレフィックス、または厳選プリセットの essential |
LINKWARDEN_DENY_TOOLS | いいえ | 同じ構文です。LINKWARDEN_ALLOW_TOOLS で残ったものから除外します |
ELICITATION | いいえ | false にすると、承認ダイアログを 2 回呼び出すトークンに置き換えます。プレフィックスなし |
LINKWARDEN_INSECURE_TLS | いいえ | true にすると、自己署名証明書を受け入れます(この接続にのみ適用) |
https://を使用してください。 通常の http ではトークンが暗号化されずに送信されます。ホストがローカルでない限り、サーバーは警告を表示します。自己署名証明書を使う場合は、LINKWARDEN_INSECURE_TLSよりも適切な内部 CA を優先してください。
トークンは読み取り後にプロセスの環境変数から削除されるため、子プロセスや /proc/<pid>/environ から確認できません。
認証情報がなくてもサーバーは起動してツールを一覧表示するため、レジストリやインスペクターから内容を確認できます。ただし、その後のすべての呼び出しは API にアクセスせず、セットアップ手順を示して失敗します。
読み込むツールの選択
LINKWARDEN_ALLOW_TOOLS と LINKWARDEN_DENY_TOOLS には、カンマ区切りでツール名を指定します。末尾の * はファミリー全体に一致します。essential は、保存・検索・読み取りを行う 8 つのツールを厳選したプリセットで、ツールリファレンスにもその旨が記載されています。
LINKWARDEN_ALLOW_TOOLS=essential
LINKWARDEN_ALLOW_TOOLS=search_links,get_link_content,create_link
LINKWARDEN_DENY_TOOLS=bulk_*
どのツールにも一致しないエントリーがあると、その名前を示して起動が中止されます。入力ミスによってツールが気づかないうちに非表示になることはありません。存在しないツールを環境変数までさかのぼって調査することはできません。フィルタリングされたツールは登録されないため、tools/list に表示されず、tools/call でも未知のツールとして扱われます。これは LINKWARDEN_READ_ONLY 使用時の書き込みツールと同様です。
このサーバーを複数同時に実行する場合は、mcp-hub を使う方法もあります。その /hub エンドポイントを使うと、各サーバーのツールが 6 つのメタツールに置き換わります。
インストール
Claude Code
claude mcp add linkwarden -e LINKWARDEN_URL=https://links.example.net -e LINKWARDEN_TOKEN=… -- npx -y linkwarden-mcp
Claude Desktop
{
"mcpServers": {
"linkwarden": {
"command": "npx",
"args": ["-y", "linkwarden-mcp"],
"env": {
"LINKWARDEN_URL": "https://links.example.net",
"LINKWARDEN_TOKEN": "…"
}
}
}
}
Codex
[mcp_servers.linkwarden]
command = "npx"
args = ["-y", "linkwarden-mcp"]
env = { LINKWARDEN_URL = "https://links.example.net", LINKWARDEN_TOKEN = "…" }
ソースから
npm install && npm run build
LINKWARDEN_URL=https://links.example.net LINKWARDEN_TOKEN=… node dist/index.js
Docker
docker build -t linkwarden-mcp .
docker run --rm -i \
-e LINKWARDEN_URL=https://links.example.net \
-e LINKWARDEN_TOKEN=… \
linkwarden-mcp
mcp-hub 経由
ローカルプロセスを起動できないクライアント(ChatGPT connectors、Claude on the web、
Cursor、LibreChat)は、mcp-hub 経由で linkwarden-mcp に接続します。1 つの
コンテナで複数の stdio MCP サーバーを Streamable HTTP 経由で提供し、単一のパスワードでログインする OAuth 2.1 と、OAuth を利用できないクライアント向けの長期間有効なトークンを備えています。
/hub エンドポイントは、すべてのサーバーを 6 つのメタツールの背後に配置するため、モデルのコンテキストに N×個のツールスキーマを含めることなく、1 つのコネクターからすべてに接続できます。また、両方のプロトコル改訂版に対応しています。このサーバーが行う質問は、ここを経由して向こう側の人に届きます。
/config/mcp.json は Claude Code の形式を使用するため、エントリーはすでにお持ちのものと同じです。
{
"mcpServers": {
"linkwarden": {
"command": "npx",
"args": ["-y", "linkwarden-mcp"],
"env": {
"LINKWARDEN_URL": "https://links.example.net",
"LINKWARDEN_TOKEN": "…",
"LINKWARDEN_ALLOW_TOOLS": "essential"
},
"denyTools": ["bulk_*"]
}
}
}
ここでの allowTools と denyTools は、サーバーごとに設定するハブ独自のフィルターであり、env 内の *_ALLOW_TOOLS とは異なります。その違いと、そこで起こりがちな間違いについては、クライアントガイドをご覧ください。
ツール
すべてのツールは outputSchema を宣言し、テキストブロックとともに structuredContent
を返すため、クライアントは文章を解析せずに結果を利用できます。
「リンク 42 を削除しました。」のような文を返していた 7 つのツールは、現在ではフィールドも
返します。文は引き続きテキストブロックに含まれます。
読み取りツール 10 個は、フィールドとして untrusted: true と source: "linkwarden" を持ちます。ブックマークのタイトル、説明、そして何より保存された記事のテキストは、対象サイトを管理する人が記述したものです。このサーバーは常に notes にその旨を記載してきました。notes はクライアントが読める文章ですが、検証はできません。このフィールドによって検証可能になります。書き込みツールにはこのフィールドがありません。これらのツールが報告するのは、このサーバーに渡された ID と、このサーバーが算出した件数です。
予算を超えた結果では、引き続きリスト項目が削除されます。また、サイズが大きすぎる未信頼エンベロープでは、最大のフィールドから文字が削られます。どちらの場合も削れるものが残っていないときは、サイズ超過したドキュメントを文字列として含むエンベロープではなく、エラーになります。そのエンベロープは有効な JSON ではありますが、有効な応答ではありません。SDK は、結果をツールが宣言するスキーマと照合するためです。
読み取り
| ツール | 説明 |
|---|---|
search_links | ブックマークを検索または一覧表示します。Linkwarden のフィールドフィルター(tag:、collection:、before:、! など)に対応しています。 |
get_link | タグ、コレクション、保存形式の有無を含む、1 件のブックマークです。 |
get_link_content | 保存ページの記事テキストです。長い記事は分割して返します。 |
list_collections | リンク数を含む、すべてのコレクションです。parentId を使用して階層を表示します。 |
get_collection | メンバーごとの権限を含む、1 つのコレクションです。 |
list_tags | リンク数とタグごとのアーカイブ設定を含むタグです。 |
get_tag | 1 つのタグです。 |
get_dashboard | Linkwarden のダッシュボードに表示される、最近追加されたリンクとピン留めされたリンクです。 |
list_rss_subscriptions | このアカウントが登録している RSS フィードです。 |
get_current_user | トークンがどのアカウントに属するかと、そのアーカイブのデフォルト設定を返します。接続確認に適しています。 |
get_worker_stats | 保存処理と検索インデックスのキューです。管理者アカウント専用です。それ以外のアカウントには HTTP 403 が返されます。 |
書き込み
LINKWARDEN_READ_ONLY=true の場合、ツールは一切登録されません。👤 人に確認と表示されたツールは、MCP のエリシテーション(モデルに代わって回答できないダイアログ)を通じて人に確認を求めます。クライアントがダイアログを表示できない場合は、confirm_token を使う2回の呼び出しにフォールバックします。人に確認するをご覧ください。
| ツール | 説明 |
|---|---|
create_link | ブックマークを保存します。タグやコレクション(必要に応じて作成)も指定できます。 |
update_link | タイトル、説明、タグ、コレクションを変更します。👤はURLを変更する場合にのみ必要です。 |
set_link_pinned | このアカウントのリンクをピン留め、またはピン留め解除します。 |
delete_link 👤 | ブックマークと保存済みのコピーを削除します。 |
bulk_update_links 👤 | 複数のリンクに同じタグ一覧やコレクションを適用します。 |
bulk_delete_links 👤 | 複数のブックマークを一度に削除します。 |
represerve_link 👤 | 既存のアーカイブを破棄し、ページを再度保存します。 |
delete_link_preservations 👤 | ブックマークは残したまま、複数のリンクのアーカイブを破棄します。 |
create_collection | コレクションを作成します。ネストも指定できます。 |
update_collection | コレクションの名前変更、親の変更、公開を行います。👤は公開する場合にのみ必要です。 |
delete_collection 👤 | コレクションを削除します。リンクとサブコレクションも連鎖的に削除されます。 |
create_tags | タグを作成するか、アーカイブ設定を変更します(名前でアップサート)。 |
rename_tag 👤 | タグの名前を変更します。そのタグが付いたすべてのリンクにも反映されます。 |
delete_tags 👤 | タグを削除します。リンクはそのまま残ります。 |
merge_tags 👤 | 複数のタグを新しい1つのタグに統合します。 |
create_rss_subscription | RSS/Atom フィードを購読します。 |
delete_rss_subscription 👤 | フィードのポーリングを停止します。 |
意図的に公開していない機能
- アクセストークンの管理(
/tokens)。API 認証情報を発行できるツールは権限昇格の手段となり、ブックマークサーバーがそのような機能を持つべきではありません。 - ユーザー管理(
/users、アカウント削除)。対象範囲外です。 - バックアップのエクスポートとインポート(
/migration)。エクスポートではインスタンス全体がモデルのコンテキストに取り込まれ、インポートではインスタンスが破壊されるおそれがあります。 - ハイライト。作成には保存済みドキュメント内の正確な文字オフセットが必要ですが、モデルが意味のある値を生成することはできません。また、Linkwarden には既存のハイライトを一覧表示するエンドポイントがありません。
- アーカイブのアップロードと署名付きの
preservedURL。利用にはNEXT_PUBLIC_USER_CONTENT_DOMAINの設定が必要です。 - 非推奨の
GET /links一覧表示ルート。search_linksは代わりにGET /searchを使用します。こちらはLinkwarden自身が推奨している方法です。
安全性
- 破壊的な操作を行うツールは、人に確認を求めます。 クライアントが MCP のエリシテーションに対応している場合は、モデルが代わりに回答できない実際のダイアログを表示します。対応していない場合、最初の呼び出しでは、対象そのものに結び付いた短時間のみ有効なトークンが返されます。そのトークンを含む 2 回目の呼び出しで操作が実行されます。これは、同じ引数で呼び出しが 2 回行われたことだけを証明するものであり、その旨もテキストに明記されます。あるリンク、タグの組み合わせ、または変更に対して発行された承認を、別のものに使い回すことはできません。
ELICITATION=falseを設定すると、意図的にこの代替手段が使われますが、ガードがなくなることはありません。 - 何かを失うことは、削除だけではありません。 コレクションの公開、リンクの URL の変更(古いページの保存済みコピーがすべて削除されます)、そのタグが付いたすべてのリンクに反映されるタグ名の変更についても、確認を求めます。
- 確認プロンプトで Linkwarden のコンテンツを引用することはありません。 タイトル、URL、説明、コレクション名は、保存済みのページやインスタンスの他のユーザーに由来するため、モデルが読むテキストには件数と ID だけが表示されます。
- Linkwarden が URL を取得する前に、ブックマーク対象の URL を検証します。
create_link、update_link、create_rss_subscriptionは、ヘッドレスブラウザーで URL を開くサーバーに URL を渡します。さらに、get_link_contentはその結果を読み取るため、未検証の URL は Linkwarden のネットワーク内から情報を読み取る手段になり得ます。ループバックアドレスとリンクローカルアドレス(クラウドのメタデータエンドポイントとそのホスト名を含みます)は拒否されます。アドレスは数値として比較されるため、[::ffff:169.254.169.254]のような IPv4 マップ形式のリテラルも検出され、ホスト名は許可前に名前解決されます。プライベート LAN アドレスは引き続き許可されます。セルフホストのブックマーク管理ツールでルーターのインターフェースやイントラネットのページをブックマークするのは一般的な使い方であり、これは Linkwarden の隣にあるコンテナーにもアクセスできることを意味します。RSS フィード内の項目を含め、この検証で対応する範囲と対応しない範囲については、SECURITY.md に記載されています。 - 返されるコンテンツは信頼できないデータとして扱われます。 特に、対象サイトを管理する人なら誰でも書き込める保存済みの記事テキストが該当します。
- 部分更新によってフィールドが消去されることはありません。 Linkwarden の更新ルートはレコード全体を置き換えるため、このサーバーは現在の状態を読み取ってマージします。これを行わないと、更新時にリンクのタグやコレクションの共同編集者が気付かないまま削除されてしまいます。
- HTTP 200 だけでは信頼しません。 Linkwarden の複数のルートは、HTTP 200 と本文のエラーメッセージで失敗を通知します。また、使用されたメソッドに対応するハンドラーがないルートは、何も返さずに 200 を応答します。どちらも書き込みの成功ではなく、エラーとして報告されます。
- エラー本文は切り詰められ、HTML のエラーページは完全に破棄され、リダイレクトは決して追跡されません(そのため、ベアラートークンが別のホストに使い回されることはありません)。すべてのリクエストにタイムアウトが設定されています。
LINKWARDEN_READ_ONLY=trueの場合、書き込みツールは登録されません。- 残存リスク: 設定したトークンの権限範囲内であれば、破壊的な操作を求められ、ユーザーに確認されたモデルが、実際にその操作を実行する可能性は残ります。アカウントの権限を制限し、ホストレベルの権限確認を有効にしておいてください。
ドキュメント
完全なガイド、ツールリファレンス、セキュリティに関する注意事項は
linkwarden-mcp.ni-c.de(ソースは docs/)にあります。
開発
npm install
npm run build
npm test
npm run test:coverage
npm run lint
npm run format
npm run docs:tools # regenerate docs/reference/tools.md from the registered tools
docs/reference/tools.md は自動生成されます。コミット済みのファイルがコードと一致しなくなると、CI は失敗します。ドキュメントサイトは、独自の package.json とロックファイルを持つ docs/ にあります。Docker ビルドおよびテストマトリックス全体で実行されるルートのインストールに、VitePress が含まれてはなりません。
CONTRIBUTING.md を参照してください。
リリース
すべてタグによって実行され、手動で公開する手順はありません。
-
CHANGELOG.md の
[Unreleased]セクションを新しいバージョンに移動し、 日付を追加します。リリースワークフローはawkでこのセクションを抽出するため、## [x.y.z]という見出しの形式が重要です。 -
package.jsonのversionを更新します。 -
npm run lint && npm run build && npm run test:coverageを実行します。 -
コミットしてから、署名付きの注釈付きタグを作成します。
git tag -s v0.1.1 -m "v0.1.1" git push origin main v0.1.1
その後、release.yml はタグが package.json と一致することを確認し、provenance 付きで
Trusted Publishing(OIDC — 漏えいする npm トークンは存在しません)を介して npm に公開し、
両方の server.json のパッケージエントリーにバージョンを同期して、MCP レジストリに公開し、
変更履歴のセクションから GitHub リリースを作成します。ci.yml は並行して、
マルチアーキテクチャのコンテナーイメージを GHCR にプッシュします。
レジストリの手順に失敗した場合は、main で修正し、mcp-registry.yml ワークフローを
手動で実行してください。失敗したジョブを再実行することはできません。ジョブは変更できない
タグをチェックアウトするため、main の修正が反映されることはありません。
コントリビューション
イシュー、ディスカッション、プルリクエストを歓迎します。CONTRIBUTING.md をご覧ください。脆弱性については、公開イシューではなく 非公開の報告を利用してください。 ポリシーは SECURITY.md に記載されています。
ライセンス
MIT © Willi Thiel
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。