Skip to main content
Glama
jmlon

pydantic-zotero-mcp

by jmlon

pydantic-zotero-mcp

AIエージェントにZoteroライブラリへの読み取りアクセスを提供するMCPサーバーです。検索、アイテムのメタデータ、コレクション、タグ、研究者自身のノート、添付PDFのインデックス化された全文テキストにアクセスできます。

要件は PRD.md を参照してください。

ステータス: M1(読み取りコア)+ M2(全文)を実装済み。 引用フォーマットとエクスポート(M3)、プロンプト(M4)、書き込みツール(M5)はまだ未実装です — 未実装 を参照してください。

インストール

ツールとして(pipx

zotero-mcp コマンドを専用の分離環境にインストールします:

pipx install pydantic-zotero-mcp        # or: pipx install /path/to/checkout
zotero-mcp --help

別のプロジェクトの環境へ

uv add pydantic-zotero-mcp              # or: uv pip install pydantic-zotero-mcp

このサーバーの開発用

git clone https://github.com/jmlon/pydantic-zotero-mcp
cd pydantic-zotero-mcp
uv sync           # creates ./.venv from this project's own lock file
uv run pytest
uv run ruff check

Related MCP server: zotero-cli-cc

設定

https://www.zotero.org/settings/keys から読み取り専用のAPIキーと数値のユーザーIDを取得してください。ライブラリIDはユーザー名ではなく数値です。

export ZOTERO_API_KEY=...
export ZOTERO_LIBRARY_ID=123456      # numeric
export ZOTERO_LIBRARY_TYPE=user      # or group

変数

デフォルト

目的

ZOTERO_API_KEY

Web APIキー(ZOTERO_LOCAL=true でない限り必須)

ZOTERO_LIBRARY_ID

数値のユーザーIDまたはグループID

ZOTERO_LIBRARY_TYPE

user

user または group

ZOTERO_LOCAL

false

代わりにZotero 7デスクトップAPIを読み取る: キー不要、レート制限なし、読み取り専用

ZOTERO_ALLOW_WRITES

false

M5用に予約済み。書き込みツールはまだ存在しない

ZOTERO_FULLTEXT_MAX_CHARS

100000

全文テキストのデフォルト上限。呼び出しごとの max_chars がこれを上書きする

ZOTERO_DEFAULT_STYLE

chicago-note-bibliography

M3用に予約済み

ZOTERO_MAX_CONCURRENCY

4

上流へのリクエスト上限(Zoteroは≤4を推奨)

ZOTERO_MCP_TRANSPORT

stdio

stdio または http

ZOTERO_MCP_HOST

127.0.0.1

HTTPバインドアドレス

ZOTERO_MCP_PORT

8000

HTTPポート

ZOTERO_MCP_PATH

/mcp

HTTPマウントパス

ZOTERO_MCP_AUTH_TOKEN

Bearerトークン。HTTPでは必須

CLIフラグは環境変数を上書きします。

実行

インストール後は、zotero-mcp がエントリポイントになります。インタープリタのパスも python -m も、正しい作業ディレクトリの指定も不要です。これはMCPクライアントの command: が求めるものです:

# stdio (default) — an agent launches this as a subprocess
zotero-mcp

# streamable HTTP — requires ZOTERO_MCP_AUTH_TOKEN
ZOTERO_MCP_AUTH_TOKEN=secret zotero-mcp --transport http --port 8000

# read the Zotero desktop app instead of the web API
zotero-mcp --local

チェックアウトから、インストールせずに python -m zotero_mcp でも動作します:

uv run python -m zotero_mcp

--transport http でトークンなしで起動すると、未認証のまま提供するのではなく終了コード2で終了します。これは個人ライブラリへの読み取りチャネルだからです。

インメモリ(エージェントプロセスに埋め込む)

サブプロセスもソケットもありません。設定は注入されるため、ホストは環境変数を必要としません:

from fastmcp import Client
from zotero_mcp import ZoteroSettings, create_server

server = create_server(
    ZoteroSettings(
        api_key=key,
        library_id="123456",
        library_type="user",
    )
)

async with Client(server) as client:  # lifespan opens here
    result = await client.call_tool("search_items", {"query": "attention"})
    print(result.structured_content["items"])  # dict; result.data is a model

zotero_mcp のインポートには副作用がありません。設定の読み取りも、クライアントの構築も、ネットワークアクセスもありません。これが埋め込みを可能にしています。これを検証するテストもあります。

エントリポイントによる検出

Pythonのエントリポイントを通じてバンドルされたMCPサーバーを検出するホストアプリケーション向けに、このパッケージは deep_research.mcp_servers グループにエントリポイントを宣言しています:

[project.entry-points."deep_research.mcp_servers"]
zotero = "zotero_mcp:build_server"

build_server() は引数を取らず、環境から設定を取得します。このパッケージをホストの環境にインストールすると、ホストは設定ファイルからパスで何かをインポートすることなく、zotero という名前でサーバーを解決し、プロセス内で実行できます。

自動化ホスト向けのチューニングメモ: このサーバーのデフォルトの全文上限は100,000文字(単一get_item_fulltext 呼び出しで約25〜30kトークン)です。インタラクティブ利用には十分すぎるほどですが、トークン予算内で多数の呼び出しを行うエージェントには大きすぎます。呼び出しごとに小さめの max_chars を渡すか、ZOTERO_FULLTEXT_MAX_CHARS を下げてください。

ツール

ツール

目的

get_library_info

サイズ、モード、権限。低コストな方向確認用呼び出し — 最初に使うこと

search_items

主要なエントリポイント。mode="metadata" または "fulltext"(PDFテキストを検索)

list_recent_items

最近追加されたアイテムを新しい順に一覧表示

find_item_by_identifier

DOI、ISBN、arXiv ID、またはキーで「これはもう持っているか?」を確認

get_item

完全なメタデータ。include_children=True で添付ファイルとノートも一覧表示

get_item_children

添付ファイルとノート。添付ファイルごとに may_have_fulltext 付き

get_item_notes

研究者自身のノート。HTMLは除去済み

get_item_fulltext

インデックス化された添付ファイルのテキスト。親 → 添付ファイルを解決

list_collections

入れ子になったコレクションツリー

list_collection_items

1つのコレクション内のアイテム

list_tags

タグの語彙。オプションでプレフィックスフィルタリング

リソース: zotero://library/infozotero://collectionszotero://items/{key}zotero://items/{key}/fulltextzotero://collections/{key}/itemszotero://schema/item-typeszotero://schema/item-types/{type}/fields

設計メモ

要点はプロジェクションです。 生のZotero JSONは、linkslibrarymeta、空の型フィールドを含めてアイテムあたり約1KBあります。zotero_mcp/projection.py は、25アイテムのページを推定トークン約6,100から約2,400(生の39%)に削減し、PRDの4,000予算を下回ります。Nullフィールドは CompactModel によってシリアライズ時に削除されます。

pyzoteroは同期型でステートフルです。 Zotero.requestZotero.links は呼び出しのたびに上書きされ、Total-Results はその後インスタンスから読み戻されます。そのため、共有クライアントを同時に使うと、別の呼び出しの合計値が報告される可能性があります。gateway.py は最大 ZOTERO_MAX_CONCURRENCY 個のクライアントのプールを保持し、操作ごとに1つをチェックアウトし、そのクライアントを保持する同じワーカースレッド内でレスポンスメタデータを読み取ります。すべての呼び出しは anyio.to_thread.run_sync を経由するため、イベントループがブロックされることはありません。

バックオフはpyzoteroの役割です。 pyzotero ≥ 1.13 はすでに Backoff / Retry-After を尊重し、429を内部的にリトライするため、ゲートウェイはそれを再実装しません。ゲートウェイは、一時的なトランスポート障害と5xxエラーのみに対して、上限付きの3回リトライを追加します。

何も黙って切り詰められません。 検索は total_matchedtruncatednext_start を報告し、全文は total_charstruncated を報告します。

結果は判定ではなく候補です(PRD D3)。find_item_by_identifiermatched_onkey / doi / title / identifier / none)に加えて、信頼度とすべての妥当な候補を返します。プレプリントとその公開版の両方が残ります。フィルタリングは呼び出し側が行います。

PRDからの逸脱

実装中に行った判断であるため、知っておく価値があります:

  1. モジュールレベルの mcp オブジェクトはありません。 PRD 7.2は、モジュールレベルの mcp = create_server() とインポート時の副作用がないことの両方を要求していました。これらは矛盾します。サーバーの構築は設定を検証するため、モジュールレベルのインスタンスはZoteroの環境変数がないマシンでは ImportError を発生させ、サポートするはずだったインメモリパスを壊します。存在するのは create_server() / build_default_server() のみです。

  2. 書き込みツールは enabled=False ではなく、条件付きで登録されます。 PRD 5.5は @mcp.tool(enabled=False) を指定していましたが、FastMCP 3.xには enabled キーワード引数がなく、無効でも一覧に載るツールはコンテキストを消費します。M5が実装されたら、書き込みツールは ZOTERO_ALLOW_WRITES=true の場合を除いて単に登録されません。

    このサーバーは FastMCP 3.x を対象としています。ここでのコードを形作る3.x固有の点が2つあります: デコレータから enabled がなくなったことと、result.data が生成されたpydanticモデルである一方、result.structured_content はプレーンなdictであることです。テストは後者を検証しており、これによりワイヤー上でのnull省略も確認されます。

  3. has_fulltext は3値です。 PRD 6では bool と型指定されていましたが、親アイテムについてそれを判定するにはアイテムごとに別途childrenリクエストが必要になり、25アイテムの検索が26リクエストになってしまいます。アイテムに子がまったくない場合は False、添付ファイルおよび get_item(include_children=True) の後は True/False、未確定の場合は null(省略)です。ItemSummary.num_children が低コストなシグナルを提供します。

  4. find_item_by_identifierItemSummary | None ではなく CitationMatch を返します。 D3に従ったものです。以前のシグネチャは、その決定がクライアントに移したまさに同一性の呼び出しを行っていました。

  5. matched_on には keyidentifier が追加されました。 PRDの4つの値に加えて、正確なキーの一致と弱い検索の一致を区別するためです。

  6. list_recent_items(since_days=...) はローカルでフィルタリングします。 Zoteroにはサーバーサイドの日付フィルタがないため、狭い期間では limit より少ないアイテムが返されることがあります。レスポンスの hint がその発生を示します。

テスト

uv run pytest      # 80 passed

テストスイートは、pyzoteroのインスタンスからメタデータを読み取る動作を再現する FakeZotero に対して、FastMCPのインメモリトランスポートを使用します。ネットワークもサブプロセスも実際の認証情報もありません。カバレッジ: スキーマ表面、プロジェクションとトークン予算、ページネーションと切り詰めの報告、全文上限と親の解決、マッチ再現率(プレプリント/公開版のペアが両方返されること)、エラーメッセージの品質、トラバーサル試行を含むリソーステンプレート検証、設定検証、CLIの優先順位、ゲートウェイのリトライ/キャッシュ、そしてパッケージのインポートがネットワークに触れると失敗するインポート純度チェック。

Not yet implemented

  • M3format_citationformat_bibliographyexport_items

  • M4 — 4つのプロンプト(literature_reviewfind_related_workcheck_citationssummarize_reading)、Logfireインストルメンテーション

  • M5 — 書き込みツール(create_itemupdate_item_fieldsadd_item_tagsadd_items_to_collectioncreate_note)。バージョンチェック付きPATCHセマンティクス。削除は恒久的にスコープ外。

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    A lightweight MCP server that connects AI agents to a local Zotero library for paper management and metadata retrieval. It enables users to search titles and abstracts, browse collections, and automatically ingest papers via arXiv ID or DOI with PDF attachments.
    8
    15
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server that exposes 45 tools for Zotero reference management, enabling AI agents to read/write items, search, extract PDF text, and manage workspaces via the Zotero CLI.
    198
    AGPL 3.0

View all related MCP servers

Related MCP Connectors

  • Remote MCP server for full read/write access to a Zotero library

  • Agentic search over your Dewey document collections from any MCP-compatible client.

  • An MCP server that gives your AI access to the source code and docs of all public github repos

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jmlon/pydantic-zotero-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server