Paperless-NGX MCP Server について
Paperless-NGX MCP Server は、REST API を通じて Paperless-NGX インスタンスの文書、タグ、取引先、文書タイプを管理する MCP サーバーです。スキャン文書の検索、アップロード、整理を AI アシスタントに任せたい利用者を想定しています。STDIO と Docker による HTTP の両方の方式で実行できます。
主な機能
- 01文書の検索、取得、ダウンロード
- 02Base64 データまたはファイルパスによる文書のアップロード
- 03タグ、取引先、文書タイプ、カスタムフィールドの管理
- 04取引先の設定や統合などの一括編集
- 05文書へのノートの追加と削除
活用シーン
- 01タグや日付で請求書や領収書を検索
- 02スキャン文書に一括でタグを付け、文書タイプを設定
- 03許可されたサーバーディレクトリからスキャンファイルを Paperless-NGX にアップロード
MCP 対応
本プロジェクトは MCP サーバーであり、Paperless-NGX の文書、タグ、取引先の操作をツールとして MCP クライアントに公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Paperless-NGX MCP サーバー
Paperless-NGX API サーバーと連携するための MCP(Model Context Protocol)サーバーです。このサーバーは、お使いの Paperless-NGX インスタンスでドキュメント、タグ、連絡先、ドキュメント種別を管理するツールを提供します。
クイックスタート
インストール
MCP 設定ファイルに以下を追加します。
// STDIO モード(ローカルまたは CLI での使用に推奨)
"paperless": {
"command": "npx",
"args": [
"-y",
"@baruchiro/paperless-mcp@latest",
],
"env": {
"PAPERLESS_URL": "http://your-paperless-instance:8000",
"PAPERLESS_API_KEY": "your-api-token",
"PAPERLESS_PUBLIC_URL": "https://your-public-domain.com"
}
}
// HTTP モード(Docker またはリモートでの使用に推奨)
"paperless": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/baruchiro/paperless-mcp:latest",
],
"env": {
"PAPERLESS_URL": "http://your-paperless-instance:8000",
"PAPERLESS_API_KEY": "your-api-token",
"PAPERLESS_PUBLIC_URL": "https://your-public-domain.com"
}
}
-
API トークンを取得します。
- Paperless-NGX インスタンスにログインします
- 右上にあるユーザー名をクリックします
- 「My Profile」を選択します
- 円形の矢印ボタンをクリックして、新しいトークンを生成します
-
MCP 設定のプレースホルダーを置き換えます。
http://your-paperless-instance:8000を Paperless-NGX の URL に置き換えますyour-api-tokenを生成したトークンに置き換えますhttps://your-public-domain.comを Paperless-NGX の公開 URL に置き換えます(任意。指定しない場合は PAPERLESS_URL が使用されます)
環境変数
| 変数 | 必須 | デフォルト | 説明 |
|---|---|---|---|
PAPERLESS_URL | はい | — | Paperless-NGX インスタンスのベース URL |
PAPERLESS_API_KEY | はい | — | Paperless-NGX プロフィールにある API トークン |
PAPERLESS_PUBLIC_URL | いいえ | PAPERLESS_URL | ドキュメントリンク用の公開 URL |
PAPERLESS_API_VERSION | いいえ | 9 | Paperless-ngx REST API のバージョンです。9 は Paperless-ngx v2.x(最近のバージョン)および v3.x で動作します。Paperless-ngx v3.0.0 では 9 未満のバージョンのサポートが廃止されたため、古いデフォルト値では HTTP 406 が返されるようになりました。HTTP 406 エラーが発生する場合は、サーバーがサポートするバージョンを設定してください。 |
PAPERLESS_MCP_UPLOAD_PATHS | いいえ | — | file_path によるアップロードを許可するディレクトリのコロン区切りリストです。セキュリティ上、設定を推奨します。 例:/var/uploads:/tmp/scans |
以上です。これで Claude に Paperless-NGX のドキュメント管理を依頼できます。
使用例
Claude には、次のような操作を依頼できます。
- 「Invoice」タグが付いたすべてのドキュメントを表示する
- 「tax return」を含むドキュメントを検索する
- 色が #FF0000 の「Receipts」という新しいタグを作成する
- ドキュメント #123 をダウンロードする
- すべての連絡先を一覧表示する
- 「Bank Statement」という新しいドキュメント種別を作成する
利用可能なツール
ドキュメント操作
list_documents
シンプルなフィルターを使用して、ドキュメントのページ分けされた一覧を取得します。単純な一覧表示にはこのツールを使用してください。全文検索、カスタムフィールドの構造化フィルタリング、高度な Paperless フィルターには、query_documents を使用してください。
パラメーター:
- page(任意):ページ番号
- page_size(任意):1 ページあたりのドキュメント数
- search(任意):シンプルな Paperless 検索語
- correspondent(任意):連絡先 ID
- document_type(任意):ドキュメント種別 ID
- tag(任意):タグ ID
- storage_path(任意):保存先パス ID
- created__date__gte(任意):YYYY-MM-DD 以降に作成された日付
- created__date__lte(任意):YYYY-MM-DD 以前に作成された日付
- ordering(任意):Paperless の並べ替えフィールド
- archive_serial_number(任意):アーカイブ通し番号
- archive_serial_number__isnull(任意):アーカイブ通し番号が空かどうか
- custom_field_query(任意):Paperless カスタムフィールドクエリをエンコードした生の JSON 文字列
- custom_fields__icontains(任意):カスタムフィールドの値全体を対象とした、大文字と小文字を区別しない部分文字列一致
list_documents({
page: 1,
page_size: 25
})
query_documents
標準のドキュメントクエリツールです。全文検索、Paperless の簡易検索、カスタムフィールドフィルター、ドキュメント化されている /api/documents/ の Paperless クエリパラメーターに対応しています。
パラメーター:
- page(任意):ページ番号
- page_size(任意):1 ページあたりのドキュメント数
- ordering(任意):Paperless の並べ替えフィールド
- query(任意):全文検索クエリ文字列
- search(任意):Paperless の簡易検索語句
- more_like_id(任意):このドキュメント ID に類似するドキュメントを検索
- correspondent(任意):取引先 ID
- document_type(任意):ドキュメント種別 ID
- tag(任意):タグ ID
- storage_path(任意):ストレージパス ID
- created__date__gte(任意):YYYY-MM-DD 以降の作成日
- created__date__lte(任意):YYYY-MM-DD 以前の作成日
- custom_field_query(任意):
[field_name_or_id, operator, value]のリーフ、または["AND" | "OR", [clause1, clause2]]のグループを使用した、構造化された Paperless カスタムフィールドクエリ - paperless_filters(任意):追加のドキュメント化された
/api/documents/の Paperless クエリパラメーターを、キーと値のペアとして渡します
// Full-text query
query_documents({
query: "invoice 2024"
})
// Simple search term
query_documents({
search: "acme"
})
// Custom field exact match
query_documents({
custom_field_query: ["Invoice Number", "exact", "12345"]
})
// Custom field empty
query_documents({
custom_field_query: ["OR", [
["Invoice Number", "isnull", true],
["Invoice Number", "exact", ""]
]]
})
// Custom field missing
query_documents({
custom_field_query: ["Invoice Number", "exists", false]
})
// Combined filters
query_documents({
query: "invoice",
tag: 5,
created__date__gte: "2024-01-01",
custom_field_query: ["Invoice Number", "exists", true]
})
// One documented Paperless filter that is not a first-class argument
query_documents({
paperless_filters: {
id__in: [101, 202, 303]
}
})
get_document
ID を指定して特定のドキュメントを取得します。
パラメーター:
- id:ドキュメント ID
get_document({
id: 123
})
search_documents
全文検索用の非推奨の互換ラッパーです。新しい連携では query_documents({ query: ... }) を使用してください。
パラメーター:
- query:検索クエリ文字列
search_documents({
query: "invoice 2024"
})
download_document
ID を指定してドキュメントファイルをダウンロードします。
パラメーター:
- id:ドキュメント ID
- original(任意):true の場合、アーカイブ版ではなく元のファイルをダウンロードします
download_document({
id: 123,
original: false
})
get_document_thumbnail
ID を指定してドキュメントのサムネイル(画像プレビュー)を取得します。サムネイルは、Base64 エンコードされた WebP 画像リソースとして返されます。
パラメーター:
- id:ドキュメント ID
get_document_thumbnail({
id: 123
})
bulk_edit_documents
複数のドキュメントに対して一括操作を行います。
パラメーター:
- documents:ドキュメント ID の配列
- method:次のいずれか:
- set_correspondent:ドキュメントの取引先を設定
- set_document_type:ドキュメントの種別を設定
- set_storage_path:ドキュメントのストレージパスを設定
- add_tag:ドキュメントにタグを追加
- remove_tag:ドキュメントからタグを削除
- modify_tags:複数のタグを追加および/または削除
- delete:ドキュメントを削除
- reprocess:ドキュメントを再処理
- set_permissions:ドキュメントの権限を設定
- merge:複数のドキュメントを結合
- split:ドキュメントを複数のドキュメントに分割
- rotate:ドキュメントのページを回転
- delete_pages:ドキュメントの特定のページを削除
- method に応じた追加パラメーター:
- correspondent:set_correspondent 用の ID
- document_type:set_document_type 用の ID
- storage_path:set_storage_path 用の ID
- tag:add_tag/remove_tag 用の ID
- add_tags:modify_tags 用のタグ ID の配列
- remove_tags:modify_tags 用のタグ ID の配列
- set_permissions:set_permissions 用のオブジェクト。閲覧/変更ユーザーとグループを指定します(
{"view": {"users": [], "groups": []}, "change": {...}})。省略されたアクション/リストは変更されません - owner:set_permissions 用のユーザー ID(または削除する場合は null)。merge が true でない場合、owner を省略すると現在の所有者がクリアされます
- merge:set_permissions 用のブール値。true の場合は既存の権限に追加し、所有者を維持します。false(デフォルト)の場合は、指定されたユーザー/グループを置き換えます
- metadata_document_id:結合時にメタデータのソースを指定する ID
- delete_originals:結合/分割時に使用するブール値
- pages:分割用の文字列
"[1,2-3,4,5-7]"、または delete_pages 用の文字列"[2,3,4]" - degrees:rotate 用の数値(90、180、または 270)
例:
// Add a tag to multiple documents
bulk_edit_documents({
documents: [1, 2, 3],
method: "add_tag",
tag: 5
})
// Set correspondent and document type
bulk_edit_documents({
documents: [4, 5],
method: "set_correspondent",
correspondent: 2
})
// Merge documents
bulk_edit_documents({
documents: [6, 7, 8],
method: "merge",
metadata_document_id: 6,
delete_originals: true
})
// Split document into parts
bulk_edit_documents({
documents: [9],
method: "split",
pages: "[1-2,3-4,5]"
})
// Modify multiple tags at once
bulk_edit_documents({
documents: [10, 11],
method: "modify_tags",
add_tags: [1, 2],
remove_tags: [3, 4]
})
// Modify custom fields
bulk_edit_documents({
documents: [12, 13],
method: "modify_custom_fields",
add_custom_fields: [
{ field: 2, value: "year" }
],
remove_custom_fields: []
})
// Set an empty custom field value, e.g. a date field used as a pending marker
bulk_edit_documents({
documents: [14],
method: "modify_custom_fields",
add_custom_fields: [
{ field: 9, value: "" }
],
remove_custom_fields: []
})
post_document
Paperless-NGX に新しいドキュメントをアップロードします。
2 つのアップロードモード:
- Base64 モード(従来型):
file(Base64 エンコードされたコンテンツ)とfilenameを指定します - ファイルシステムモード(効率的):
file_path(サーバー上の絶対パス)を指定します
セキュリティに関する注意: file_path を使用する場合は、PAPERLESS_MCP_UPLOAD_PATHS 環境変数(許可するディレクトリをコロン区切りで指定)を設定し、アップロード先を特定の場所に制限してください。設定しない場合、サーバーのファイルシステム上にある任意のファイルをアップロードできてしまいます。
パラメーター:
- file(任意):Base64 エンコードされたファイルコンテンツ。
fileまたはfile_pathのいずれかが必要です。 - file_path(任意):サーバーのファイルシステム上にあるファイルの絶対パス。
fileまたはfile_pathのいずれかが必要です。 - filename(任意):ファイル名。
fileと併用する場合は必須で、file_pathと併用する場合は任意です(パスから取得されます)。 - title(任意):ドキュメントのタイトル
- created(任意):ドキュメントの作成日時(例:"2024-01-19" または "2024-01-19 06:15:00+02:00")
- correspondent(任意):取引先の ID
- document_type(任意):ドキュメントタイプの ID
- storage_path(任意):ストレージパスの ID
- tags(任意):タグ ID の配列
- archive_serial_number(任意):アーカイブシリアル番号
- custom_fields(任意):カスタムフィールド ID の配列
ファイルサイズの上限: どちらのモードも 100MB
// Base64 mode (traditional)
post_document({
file: "base64_encoded_content",
filename: "invoice.pdf",
title: "January Invoice",
created: "2024-01-19",
correspondent: 1,
document_type: 2,
tags: [1, 3],
archive_serial_number: "2024-001",
custom_fields: [1, 2]
})
// Filesystem mode (more efficient for large files)
post_document({
file_path: "/var/uploads/invoice.pdf",
title: "January Invoice",
correspondent: 1,
document_type: 2,
tags: [1, 3]
})
ドキュメントのメモ
list_document_notes
ドキュメントに添付されたすべてのメモを一覧表示します。
パラメーター:
- id:ドキュメント ID
list_document_notes({
id: 123
})
create_document_note
ドキュメントにメモを追加します。ドキュメントのすべてのメモを返します。
パラメーター:
- id:ドキュメント ID
- note:追加するメモのテキスト
create_document_note({
id: 123,
note: "Invoice paid on 2026-06-30 from Commerzbank account."
})
delete_document_note
⚠️ note ID を指定して、ドキュメントから単一のメモを削除します。この操作は取り消せません。
パラメーター:
- id:ドキュメント ID
- note_id:削除するメモの ID
- confirm:この破壊的な操作を確認するには
trueを指定する必要があります
delete_document_note({
id: 123,
note_id: 5,
confirm: true
})
タグ操作
list_tags
すべてのタグを取得します。
list_tags()
create_tag
新しいタグを作成します。
パラメーター:
- name:タグ名
- color(任意):16 進数のカラーコード(例:"#ff0000")
- match(任意):照合するテキストパターン
- matching_algorithm(任意):0 から 6 までの数値: 0 - なし 1 - いずれかの単語 2 - すべての単語 3 - 完全一致 4 - 正規表現 5 - あいまいな単語 6 - 自動
create_tag({
name: "Invoice",
color: "#ff0000",
match: "invoice",
matching_algorithm: 5
})
取引先操作
list_correspondents
すべての取引先を取得します。
list_correspondents()
create_correspondent
新しい取引先を作成します。
パラメーター:
- name:取引先名
- match(任意):照合するテキストパターン
- matching_algorithm(任意):0 から 6 までの数値: 0 - なし 1 - いずれかの単語 2 - すべての単語 3 - 完全一致 4 - 正規表現 5 - あいまいな単語 6 - 自動
create_correspondent({
name: "ACME Corp",
match: "ACME",
matching_algorithm: 5
})
ドキュメントタイプ操作
list_document_types
すべてのドキュメントタイプを取得します。
list_document_types()
create_document_type
新しいドキュメントタイプを作成します。
パラメーター:
- name:ドキュメントタイプ名
- match(任意):照合するテキストパターン
- matching_algorithm(任意):0 から 6 までの数値: 0 - なし 1 - いずれかの単語 2 - すべての単語 3 - 完全一致 4 - 正規表現 5 - あいまいな単語 6 - 自動
create_document_type({
name: "Invoice",
match: "invoice total amount due",
matching_algorithm: 1
})
カスタムフィールド操作
list_custom_fields
すべてのカスタムフィールドを取得します。
list_custom_fields()
get_custom_field
ID を指定して、特定のカスタムフィールドを取得します。
パラメーター:
- id:カスタムフィールド ID
get_custom_field({
id: 1
})
create_custom_field
新しいカスタムフィールドを作成します。
パラメーター:
- name:カスタムフィールド名
- data_type:"string"、"url"、"date"、"boolean"、"integer"、"float"、"monetary"、"documentlink"、"select" のいずれか
- extra_data(任意):選択肢など、カスタムフィールドの追加データ
create_custom_field({
name: "Invoice Number",
data_type: "string"
})
update_custom_field
既存のカスタムフィールドを更新します。
パラメーター:
- id:カスタムフィールド ID
- name(任意):新しいカスタムフィールド名
- data_type(任意):新しいデータ型
- extra_data(任意):カスタムフィールドの追加データ
update_custom_field({
id: 1,
name: "Updated Invoice Number",
data_type: "string"
})
delete_custom_field
カスタムフィールドを削除します。
パラメーター:
- id:カスタムフィールド ID
delete_custom_field({
id: 1
})
bulk_edit_custom_fields
複数のカスタムフィールドに対して一括操作を実行します。
パラメーター:
- custom_fields:カスタムフィールド ID の配列
- operation:「delete」のいずれか
bulk_edit_custom_fields({
custom_fields: [1, 2, 3],
operation: "delete"
})
メール操作
Paperless のメールアカウントと、自動メール取り込みを制御するメールルールを管理するツールです。アカウントのパスワード/トークンが公開されることはありません。すべてのツールの応答で伏せ字になります。
list_mail_accounts
メールアカウントを一覧表示します。メールルールの作成時に必要なアカウント ID を選択できます。パスワードは伏せ字になります。
パラメーター:
- page(任意):ページ番号
- page_size(任意):1 ページあたりの結果数
list_mail_accounts()
get_mail_account
ID を指定して単一のメールアカウントを取得します。パスワード/トークンのフィールドは伏せ字になります。
パラメーター:
- id:メールアカウント ID
get_mail_account({
id: 1
})
process_mail_account
アカウントを指定して、Paperless のメール処理を手動で実行します。有効なメールルールに一致するメールが処理される場合があります。
パラメーター:
- id:メールアカウント ID
process_mail_account({
id: 1
})
list_mail_rules
ページネーションを指定してメールルールを一覧表示します。
パラメーター:
- page(任意):ページ番号
- page_size(任意):1 ページあたりの結果数
list_mail_rules()
get_mail_rule
ID を指定して単一のメールルールを取得します。
パラメーター:
- id:メールルール ID
get_mail_rule({
id: 1
})
create_mail_rule
メールルールを作成します。最初に list_mail_accounts を使ってアカウントを選択してください。
必須パラメーター:
- name:ルール名
- account:メールアカウント ID
- folder:スキャンする IMAP フォルダー(例:「INBOX」)
主な任意パラメーター:
- enabled(既定値は true):ルールを有効にするかどうか
- filter_from / filter_to / filter_subject / filter_body:受信メールの照合条件
- maximum_age:この日数より新しいメールのみを処理
- action:1=削除、2=フォルダーへ移動、3=既読にする、4=フラグを付ける、5=タグを付ける
- action_parameter:選択したアクションの対象フォルダー/タグ
- assign_title_from:1=件名、2=添付ファイル名、3=割り当てない
- assign_tags / assign_correspondent / assign_document_type:適用するメタデータ
- assign_correspondent_from:1=なし、2=メールアドレス、3=送信者名、4=assign_correspondent を使用
- attachment_type:1=添付ファイルのみ、2=インラインを含むすべてのファイル
- consumption_scope:1=添付ファイルのみ、2=メール全体を .eml として処理、3=両方
- pdf_layout:0=システム既定、1=テキスト+HTML、2=HTML+テキスト、3=HTML のみ、4=テキストのみ
create_mail_rule({
name: "Invoices",
account: 1,
folder: "INBOX",
filter_subject: "invoice",
action: 3,
attachment_type: 1
})
update_mail_rule
既存のメールルールにパッチを適用します。指定したフィールドのみが変更されます。
パラメーター:
- id:メールルール ID
- ...更新する
create_mail_ruleのフィールド
update_mail_rule({
id: 1,
enabled: false
})
delete_mail_rule
メールルールを削除します。明示的な確認フラグが必要です。今後のメール取り込み動作は変更されますが、既存のドキュメントは削除されません。
パラメーター:
- id:メールルール ID
- confirm:削除を確認するには
trueを指定する必要があります
delete_mail_rule({
id: 1,
confirm: true
})
エラー処理
次の場合、サーバーは明確なエラーメッセージを表示します:
- Paperless-NGX の URL または API トークンが正しくない
- Paperless-NGX サーバーに接続できない
- 要求された操作に失敗した
- 指定されたパラメーターが無効である
テスト
単体テスト
単体テストスイートを実行します(外部依存関係は不要です):
npm test
E2E テスト
E2E テストスイートは空の Paperless-ngx インスタンスを起動し、コンパイル済みの MCP サーバーを実行して、tools/call リクエストを通じた決定論的な逐次シナリオを実行します。タグ、コレスポンデント、ドキュメントタイプを作成し、PDF をアップロードした後、同じドキュメントに対して一覧表示/取得/検索/ダウンロード/サムネイル/一括編集をテストします。LLM や、MCP の外部にある Paperless REST クライアントは使用しません。
前提条件: Docker、Docker Compose、jq。
# 1. Build the MCP server
npm run build
# 2. Start Paperless-ngx
docker compose -f docker-compose.e2e.yml up -d
# 3. Wait for Paperless to be ready, then get a token
TOKEN=$(curl -s -X POST http://localhost:8000/api/token/ \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"admin123"}' | jq -r '.token')
# 4. Start the MCP server
node build/index.js --http --port 3001 \
--baseUrl http://localhost:8000 --token "$TOKEN" &
MCP_PID=$!
# 5. Run the E2E tests
MCP_URL=http://localhost:3001/mcp \
PAPERLESS_URL=http://localhost:8000 \
PAPERLESS_TOKEN="$TOKEN" \
npm run test:e2e
# 6. Cleanup
kill "$MCP_PID"
docker compose -f docker-compose.e2e.yml down -v
E2E テストは、すべてのプルリクエストと main へのプッシュ時に CI でも自動実行され、build/index.js CLI と公開済み Docker イメージの両方をテストします。
開発
サーバーへの貢献や変更をお考えですか?必要な情報をご紹介します。
- リポジトリをクローンします
- 依存関係をインストールします:
npm install
- server.js を変更します
- ローカルでテストします:
node server.js http://localhost:8000 your-test-token
サーバーは以下を使用して構築されています:
API ドキュメント
この MCP サーバーは Paperless-NGX REST API のエンドポイントを実装しています。基盤となる API の詳細については、公式ドキュメントをご覧ください。
MCP サーバーの実行
MCP サーバーは 2 つのモードで実行できます。
1. stdio(デフォルト)
これはデフォルトのモードです。サーバーは stdio 経由で通信し、CLI や直接的な統合に適しています。
npm run start -- <baseUrl> <token>
2. HTTP(Streamable HTTP トランスポート)
サーバーを HTTP サービスとして実行するには、--http フラグを使用します。--port でポートを指定することもできます(デフォルト:3000)。このモードでは Express が必要です(依存関係に含まれています)。
npm run start -- <baseUrl> <token> --http --port 3000
- MCP API は、指定したポートの
POST /mcpで利用できます。 - 各リクエストは、StreamableHTTPServerTransport のパターンに従い、ステートレスで処理されます。
/mcpへの GET および DELETE リクエストには、405 Method Not Allowed が返されます。
リクエストごとの API トークン(HTTP/Docker モード)
HTTP モードでは、クライアントは標準の Authorization ヘッダーで Paperless-NGX API トークンを指定して認証します。
Authorization: Bearer <paperless-ngx-api-token>
トークンはそのまま Paperless-NGX に渡されるため、各クライアント固有の Paperless 権限がエンドツーエンドで適用されます。これにより、1 つのサーバーインスタンスで、それぞれが独自のトークンを持つ複数のユーザーにサービスを提供できます。同じ動作が /mcp と /sse の両方のエンドポイントに適用されます。
⚠️ v2.0.0 の重大な変更 — HTTP モードではデフォルトで認証が有効になりました。
以前は、
Authorizationヘッダーのないリクエストは、サーバーに設定されたPAPERLESS_API_KEYに暗黙的にフォールバックしていました。そのため、ポートにアクセスできるすべてのユーザーに HTTP エンドポイントが公開されていました。v2.0.0 以降、Bearerトークンのないリクエストは401 Unauthorizedで拒否されます。--no-authを明示的に指定しない限り、認証されていないリクエストにサーバートークンが使用されることはありません。
| シナリオ | --no-auth がオフ(デフォルト) | --no-auth がオン |
|---|---|---|
クライアントが Authorization: Bearer <tok> を送信 | <tok>(クライアントから提供) | <tok>(クライアントから提供) |
ヘッダーなし、PAPERLESS_API_KEY/--token が設定済み | 401 Unauthorized | サーバートークン |
| ヘッダーなし、サーバートークンなし | 401 Unauthorized | 401 Unauthorized |
v1.x からの移行: 以前のフォールバック(トークンを送信しないクライアントに対し、共有の PAPERLESS_API_KEY を使用)を利用していた場合、次の 2 つの方法があります。
- 推奨: 各クライアントに
Authorization: Bearer <paperless-token>を送信させます。 - 以前の動作に戻す(信頼できるネットワーク/ローカルネットワークのみ):
--no-authフラグを付けてサーバーを起動します。たとえば、Docker のcommand/args または CLI の呼び出しに追加します。この場合、サーバートークン(PAPERLESS_API_KEYまたは--token)の設定が必要です。
Docker によるデプロイ
MCP サーバーは Docker および Docker Compose を使用してデプロイできます。Docker イメージは、ポート 3000 で SSE(Server-Sent Events)をサポートする HTTP モードで自動的に実行されます。
Docker Compose の設定
docker-compose.yml ファイルを作成します:
services:
paperless-mcp:
container_name: paperless-mcp
image: ghcr.io/baruchiro/paperless-mcp:latest
environment:
- PAPERLESS_URL=http://your-paperless-ngx-server:8000
- PAPERLESS_API_KEY=your-paperless-api-key
- PAPERLESS_PUBLIC_URL=https://paperless-ngx.yourpublicurl.com
ports:
- "3000:3000"
restart: unless-stopped
次に、以下を実行します:
docker-compose up -d
Continue VS Code 拡張機能を使用している場合は、SSE 経由で Docker 化された MCP サーバーを使用するように設定できます。
ワークスペースのルートに .continue/mcpServers/paperless-mcp.yaml を作成するか、編集してください。
name: Paperless
version: 0.0.1
schema: v1
mcpServers:
- name: Paperless
type: sse
url: http://localhost:3000/sse
注意:
- リモートサーバーで実行している場合は、
localhostを Docker ホストの IP アドレスまたはホスト名に置き換えてください - Docker コンテナが環境変数を使用して認証を処理するため、Continue の設定に認証情報は必要ありません
- SSE エンドポイントは、設定したポート(デフォルト:3000)の
/sseで利用できます
クレジット
このプロジェクトは nloui/paperless-mcp のフォークです。元の作者の取り組みに心より感謝します。貢献や改善は上流に還元される場合があります。
デバッグ
VS Code で MCP サーバーをデバッグするには、次の起動構成を使用してください。
{
"type": "node",
"request": "launch",
"name": "Debug Paperless MCP (HTTP, ts-node ESM)",
"program": "${workspaceFolder}/node_modules/ts-node/dist/bin.js",
"args": [
"--esm",
"src/index.ts",
"--http",
"--baseUrl",
"http://your-paperless-instance:8000",
"--token",
"your-api-token",
"--port",
"3002"
],
"env": {
"NODE_OPTIONS": "--loader ts-node/esm",
},
"console": "integratedTerminal",
"skipFiles": [
"<node_internals>/**"
]
}
重要: デバッグの前に、src/index.ts の次の行(175 行目付近)のコメントを解除してください。
// await new Promise((resolve) => setTimeout(resolve, 1000000));
これにより、サーバーがすぐに終了するのを防ぎ、ブレークポイントを設定してコードをデバッグできるようになります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。