fulltext-article-downloader について
fulltext-article-downloaderは、DOI、arXiv、PMC、OpenReviewの識別子から論文全文を取得します。研究者やAIエージェントがPython API、コマンドライン、MCPサーバーで利用でき、複数の取得元を試して論文情報とファイルを照合します。
主な機能
- 01複数の論文ソースからダウンロード
- 02取得方法の自動フォールバック
- 03論文タイトルによるPDF照合
- 04並行処理による一括ダウンロード
- 05補足ファイルの取得に対応
活用シーン
- 01DOIやリポジトリIDから論文を取得
- 02論文を一括ダウンロードして記録
- 03AIエージェントに論文取得ツールを提供
MCP 対応
オプションのfulltext-mcpサーバーは、CLIと同じ認証情報を使い、MCPクライアントにget_paperとget_papersツールを公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx fulltext-article-downloaderUNPAYWALL_EMAILContact email for Unpaywall and CrossrefFULLTEXT_OUTPUT_DIRFolder for downloaded files (default ./papers)WILEY_API_KEYシークレットWiley TDM tokenELSEVIER_API_KEYシークレットElsevier API keySPRINGER_API_KEYシークレットSpringer Nature API keySEMANTIC_SCHOLAR_API_KEYシークレットSemantic Scholar API keyローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| tools | any | いいえ | |
| identifier | string | はい | |
| output_dir | string | いいえ | |
| supplements | boolean | いいえ |
詳細
fulltext-article-downloader
fulltext-article-downloader は、DOI、arXiv ID、PubMed Central ID、または OpenReview ID から研究論文の全文をプログラムでダウンロードするための Python パッケージです。出版社の API、オープンアクセスインデックス、リポジトリをフォールバックの順序で連鎖させ、返ってきたものが本当に要求した論文であるかを確認し、Python から、コマンドラインから、または MCP サーバーや Claude Code スキルを通じて AI エージェントから利用できます。
ビデオチュートリアル: https://youtu.be/fTtc4QWMYzE
機能
- 複数の取得方法 – Elsevier、Wiley、Springer Nature の API、CrossRef TDM リンク、Unpaywall、Europe PMC、OSTI(DOE 資金による論文の受理済み原稿)、Semantic Scholar のオープンアクセスインデックス、arXiv、ChemRxiv、bioRxiv/medRxiv、Zenodo、MDPI の CDN、および簡単な API を持たない出版社(PLOS、eLife、Cambridge、APS)向けの直接スクレイピング。
- 自動フォールバックロジック – パッケージは DOI の出版社に基づいて最適な方法を選択し、失敗した場合は次の方法が自動的に試されます。
- 検証 – すべての PDF は論文のタイトルと照合してチェックされ、補足情報ファイルや抄録のみのレコードは拒否されるため、返されるファイルは要求した論文そのものです。
- 誠実な結果 – 各ダウンロードはどの経路でファイルが取得されたかを報告し、出版社の最終版ではなくプレプリントや受理済み原稿である場合は注記が付きます。
- ツール順序の設定が可能 – 出版社ごとの方法の順序は設定可能で、デフォルトは主要な出版社とプレプリントサーバーのほとんどをカバーしています。
- バッチダウンロード – 出版社のレート制限を守った並列ダウンロード、
tqdmプログレスバー、どのツールが成功したか、またはなぜ識別子が失敗したかを記録するファイルログ。 - 簡単な API キー管理 – 環境変数または対話式の
fulltext-configスクリプトで認証情報を保存できます。 - 4 つのエントリポイント、1 つのエンジン – Python API、
fulltext-downloadCLI、あらゆる MCP クライアント向けのfulltext-mcpサーバー、およびすぐに使えるスキルを備えた Claude Code プラグイン。
1. インストール
pip install fulltext-article-downloader
オプションの追加機能により、追加の経路と MCP サーバーが有効になります:
| 追加機能 | 追加されるもの |
|---|---|
mcp | fulltext-mcp サーバー(fastmcp) |
tls | 素の HTTPS クライアントを拒否するホスト向けの Chrome TLS フィンガープリントフォールバック(curl-cffi) |
springer | Springer Nature オープンアクセス XML 経路(sprynger) |
preprints | paperscraper による bioRxiv/medRxiv のダウンロード |
aps | ブラウザのログイン Cookie を再利用する APS 経路(browser-cookie3) |
all | 上記のすべて |
tls と aps はどちらも、リクエストをスクリプトではなくあなた自身のブラウザのように見せることで機能します。tls は素の HTTPS クライアントを拒否するホスト向けに Chrome の TLS フィンガープリントを一致させ、aps はすでにサインインしている APS のセッション Cookie を再利用します。どちらもライセンスを受けていないものを開くことはありませんが、どちらも素の API クライアントより一歩踏み込むため、有効にする前に所属機関の契約と照らし合わせて確認する価値があります。デフォルトのインストールにはどちらも含まれません。all には含まれます。
pip install "fulltext-article-downloader[mcp,tls]"
開発の場合は、リポジトリをクローンして pip install -e ".[dev,all]" を実行してください。その後、必ずインストールを設定してください(次のセクションを参照)。
2. 設定 (API キーとメールアドレス)
認証情報はすべて任意であり、それぞれが特定の経路を有効にします。キーがない場合、かつキャンパス外では、オープンアクセスの論文、プレプリント、DOE 資金提供の原稿は取得できると想定されますが、ほとんどのペイウォール記事は失敗します。
| サービス | 環境変数 | キーの取得先 |
|---|---|---|
| Unpaywall と Crossref の連絡先メールアドレス (ご自身のアドレス) | UNPAYWALL_EMAIL | (メールアドレスを入力してください) |
| Elsevier API | ELSEVIER_API_KEY | https://dev.elsevier.com |
| Wiley TDM API | WILEY_API_KEY | https://onlinelibrary.wiley.com/library-info/resources/text-and-datamining |
| Springer Open Access API | SPRINGER_API_KEY | https://dev.springernature.com |
| Semantic Scholar (任意。レート制限が緩和され、DOI レコードに PDF がない論文の arXiv コピーを見つけるタイトル検索が有効になります) | SEMANTIC_SCHOLAR_API_KEY | https://www.semanticscholar.org/product/api (無料、数日以内にメールで承認されます) |
UNPAYWALL_EMAIL は Unpaywall と Crossref にのみ送信されます。これらは API 利用者に連絡先アドレスを求めており、Crossref は連絡先を含むリクエストをより高速な「polite」プールから処理します。キーとメールアドレスはお使いのマシン上に留まります。
これらの環境変数を設定するか、対話型ヘルパーを実行してください:
fulltext-config
このスクリプトはキーを ~/.fulltext_keys に保存し、インポート時に自動的に読み込まれます。必要なキーが欠けている場合、対応するツールはスキップされ、ダウンローダーは他の方法にフォールバックします。出版社のキーは、そのキーまたはネットワークが権限を持つ場合にのみペイウォールコンテンツを返します。パッケージは切り詰められた応答や要約のみの応答を検出し、次に進みます。
3. 使用方法
識別子
識別子が期待される場所では、以下のどの形式でも受け付けられます:
- DOI:
10.1021/jacs.3c13302、https://doi.org/10.1021/jacs.3c13302、doi:10.1021/jacs.3c13302 - arXiv:
2310.19377、arXiv:2310.19377、https://arxiv.org/abs/2310.19377、cond-mat/9712061、10.48550/arXiv.2310.19377 - PubMed Central:
PMC6561843 - OpenReview:
fNyXCCZ0g6
コマンドラインインターフェース (CLI)
fulltext-download <ID> [<ID> ...] [-o DIR] [--tools a,b,c] [--workers N] [--no-check] [--log-file FILE]
fulltext-download 10.1371/journal.pone.0171501 -o papers
fulltext-download 10.1021/jacs.3c13302 arXiv:1710.10324 PMC6561843 -o papers --workers 4
このコマンドは識別子ごとに 1 つの JSON オブジェクトを出力し、すべてのダウンロードが成功した場合にのみ終了コード 0 で終了します:
[
{
"identifier": "10.1021/jacs.3c13302",
"success": true,
"path": "papers/10.1021_jacs.3c13302.pdf",
"source": "osti",
"note": "OSTI accepted manuscript, not the publisher's version of record",
"error": null,
"attempts": [],
"supplements": []
}
]
元の形式 fulltext-download <DOI> <OUTPUT_DIR> [<FILENAME>] も引き続き動作します。
Python API
fetch は CLI が出力するのと同じ構造を返し、fetch_many はリストを並行してダウンロードします:
from fulltext_article_downloader import fetch, fetch_many
r = fetch("10.1371/journal.pone.0171501", "papers")
if r["success"]:
print(r["path"], r["source"], r["note"])
else:
print(r["error"]) # every route tried, with its reason
rs = fetch_many(["10.1002/advs.201900808", "10.48550/arXiv.2207.03928"], "papers", workers=4)
以前の関数は変更されていません: download_article(doi, output_dir, ...) はパスを返すか例外を送出し、bulk_download_articles(dois, output_dir, log_file=..., sleep=..., workers=...) はパスの辞書、または "ERROR: ..." 文字列の辞書をプログレスバー付きで返します。
これらすべてに共通するオプション: output_filename (単一ダウンロード)、tools (出版社のデフォルトを上書きする経路名のリスト)、log_file (ダウンロードログを追記)、そして fetch ではさらに check=False で検証をスキップ、skip_existing=False で既に存在するファイルを再ダウンロードします。
補足ファイル
fetch(..., supplements=True)、fetch_many(..., supplements=True)、fulltext-download --supplements、および MCP ツールの supplements=true は、記事の補足ファイル (サポート情報、データテーブル、動画) も取得します。これらは別々の場所にある別々のファイルであるため、記事の隣に <name>_si1.pdf、<name>_si2.xlsx、... として保存され、結果の supplements に一覧表示されます。取得元: ChemRxiv と Elsevier の API、PMC 記事の場合は Europe PMC の補足バンドル、それ以外の場合は記事のランディングページ (Springer Nature、Wiley、bioRxiv、ACS、RSC、PLOS などがそこでリンクしています。ほとんどの出版社は補足ファイルを購読なしで配信します)。記事ごとに 1 回余分なリクエストが発生するため、デフォルトではオフです。補足ファイルの欠落がダウンロードを失敗させることはありません。
MCP サーバー(エージェント向け)
fulltext-mcp は get_paper(identifier, output_dir="", tools=None, supplements=False) と get_papers(identifiers, output_dir="", max_workers=4, supplements=False) の 2 つのツールを公開し、上記の構造を返します。mcp エクストラが必要で、CLI と同じキーを読み取ります。FULLTEXT_OUTPUT_DIR は、呼び出しで出力ディレクトリが指定されなかった場合にファイルの保存先を設定します(デフォルトは ./papers)。
Claude Code:
claude mcp add fulltext-article-downloader -- uvx --from "fulltext-article-downloader[mcp]" fulltext-mcp
その他の MCP クライアントでは、そのサーバー設定に以下を記述します:
{
"mcpServers": {
"fulltext-article-downloader": {
"command": "uvx",
"args": ["--from", "fulltext-article-downloader[mcp]", "fulltext-mcp"],
"env": { "UNPAYWALL_EMAIL": "[email protected]", "FULLTEXT_OUTPUT_DIR": "/abs/path/papers" }
}
}
}
uvx は初回使用時に PyPI からパッケージを取得して分離された環境にインストールするため、事前に何もインストールする必要はありません。このサーバーは公式 MCP レジストリにも io.github.computron/fulltext-article-downloader として登録されています。
Claude Code プラグインとスキル
このリポジトリは Claude Code プラグインでもあります。Claude に fulltext-download をいつどのように使うかを教えるスキルと、上記の MCP サーバーをインストールします:
/plugin marketplace add computron/fulltext-article-downloader
/plugin install fulltext-article-downloader@fulltext-article-downloader
Claude Code 内ではスキルだけ(MCP なし)で十分です。スキルは CLI を実行して JSON を読み取ります。MCP サーバーは、シェルコマンドを実行できないクライアントや、その他のエージェントフレームワーク向けです。
4. 失敗とツール
失敗の例
多くの論文はオープンアクセスではなく、出版社はテキストおよびデータマイニングを明示的に制限または推奨していません。次の例は FAIL になることが想定されています:
fulltext-download 10.1109/GROUP4.2007.4347715 -o papers
error フィールドには、試行されたすべての経路とその失敗理由が一覧表示されます。失敗はほとんどの場合、その論文がペイウォールの背後にありオープンアクセスのコピーが存在しないか、ホストが自動アクセスをブロックしたことを意味します。
Failed to load APS cookies のようなエラーが表示される場合は、フルディスクアクセス権を持つアプリケーションで Python を実行していることを確認してください。
検証
%PDF- で始まるファイルは何の証明にもなりません。オープンアクセスのインデックスが DOI を無関係な文書にマッピングしてしまうことがあり、サポート情報のファイルが論文のタイトルを持つこともあります。パッケージはすべての経路の後に最初の 2 ページを抽出し、Crossref のタイトルがそこにあることを確認し、Supporting Information の見出しで始まるファイルを拒否し、本文テキストを含まない Elsevier XML レコードを拒否します。拒否されたファイルは削除され、次の経路が試行されます。--no-check / check=False でこれを無効にできます。
方法とフォールバックロジック
このツールは、さまざまな出版社をサポートするために複数のサブツールで構成されています。ツールの順序は出版社によって異なります。
| 出版社 / ソース | デフォルトのツール順序 |
|---|---|
| Elsevier | unpaywall → elsevier (権利がある場合は PDF、それ以外は XML) → europepmc → osti → semantic |
| Springer / Nature | springerpdf (nature.com, SpringerLink) → unpaywall → europepmc → springeropen (XML) → osti → semantic |
| Wiley | wiley → unpaywall → europepmc → osti → semantic |
| APS | aps → unpaywall → crossref_tdm → europepmc → osti → semantic |
| ACS, RSC, AIP | unpaywall → europepmc → crossref_tdm → osti → semantic |
| PLOS | plos → unpaywall |
| eLife | elife → unpaywall |
| Cambridge | cambridge → unpaywall → europepmc → osti → semantic |
| arXiv | arxiv → unpaywall |
| ChemRxiv | chemrxiv → paperscraper → unpaywall |
| bioRxiv, medRxiv | biorxiv → unpaywall → paperscraper |
| MDPI | mdpi → unpaywall → europepmc → semantic |
| Zenodo | zenodo |
| その他 | unpaywall → europepmc → crossref_tdm → osti → semantic → elsevier |
arXiv、PMC、OpenReview の ID はそのまま arxiv、pmc、openreview に渡されます(OpenReview は現在、自動リクエストに対してチャレンジで応答します。その場合、ルートはその旨を報告します)。pmc は Europe PMC の PDF レンダリングを取得し、そのエンドポイントが拒否した場合(多数の記事を連続して要求するホストをスロットリングします)には、Europe PMC の REST サービスまたは NCBI の efetch から全文 JATS XML を取得します。efetch は著者稿も提供します(NCBI_API_KEY は任意で、NCBI のレート制限を引き上げます)。 |
あまり明確でないツールの動作:
elsevierはまず PDF を要求し、API キーが全文 PDF の権利を持つ場合にのみそれを保持します。それ以外の場合、Elsevier は HTTP 200 と記事の 1 ページ目のみを含む PDF で応答するため、ツールはそれを破棄し、代わりに全文 XML を取得し、その隣に markdown レンダリングを書き込みます。要約のみの XML は拒否されます。返されるパスには、実際に書き込まれた形式の拡張子が常に付きます。crossref_tdmは Crossref に登録されたすべての全文リンクを試します。これには APS、ACS、RSC が使用するunspecifiedcontent-type リンクも含まれます。これらは権利のあるネットワーク上で PDF を返します。europepmcは PMC がホストするオープンアクセス記事と、DOI の Europe PMC レコードに記載されたリポジトリコピー(通常は著者稿)をダウンロードします。レコードが記事の全文が PMC にあると示している場合(資金提供者の義務に基づいて寄託された著者稿)、PMC コピーを取得します。PDF レンダリング、またはそのエンドポイントが拒否した場合は JATS XML です。ostiは DOI について OSTI API に問い合わせ、DOE 資金の記事が出版から約 1 年後に osti.gov で受け取る受理済み原稿をダウンロードします。認証情報は不要です。まだエンバーゴ中のレコードには全文がなく、ツールは次に進みます。semanticは Semantic Scholar が DOI についてインデックスしたオープンアクセス PDF(主に arXiv および購読記事の機関リポジトリコピー)をダウンロードします。unpaywallとsemanticはリポジトリのランディングページも受け付けます。インデックスがファイルではなくページを記載している場合(HAL、DSpace、Columbia Academic Commons)、ツールはそのページが Google Scholar 用に持つcitation_pdf_urlタグを読み取り、それをダウンロードします。chemrxivは Cambridge Open Engage API を経由します。これは chemrxiv.org 自体がブロックするホストからでも動作します。API はアイテムの最新バージョンの DOI のみを解決するため、ベース DOI または古いバージョンはバージョン接尾辞を付けて再試行されます。biorxivは bioRxiv API に問い合わせ、どのサーバー(bioRxiv または medRxiv)が DOI を保持しているか、どのバージョンが最新かを確認し、その PDF を取得します。リクエストは間隔を空けて行われ(サイトはバースト後に 100 秒の Retry-After 付きで 429 を返します)、返される一時的な 503 は再試行されます。API 自体がスロットリングしている場合、現在のバージョンにリダイレクトするバージョンなし URL が両方のサーバーで試されます。mdpiは Crossref レコードから MDPI の CDN(mdpi-res.com)上に記事のパスを構築します。www.mdpi.com 自体はクラウドプロバイダーのアドレス範囲からのリクエストを拒否します。zenodoは Zenodo レコード(10.5281 DOI)に添付された PDF をダウンロードします。コンセプト DOI は最新バージョンに解決されます。wileyは Wiley Online Library でホストされる学会誌(AGU など)にも使用されます。Crossref は wiley.com 上のそれらの全文リンクを記載し、TDM API がそれらを提供します。同様に、Crossref リンクが Elsevier を指す雑誌にはelsevierが追加されます。そしてそれはデフォルトリストを締めくくります。Elsevier の API は、それが配信する学会誌(ASH の Blood)を独自の出版社名で提供するからです。Elsevier 以外の DOI は 1 回の迅速な 404 で済みます。semanticはまた、レコードが PDF を記載していない場合、レコードのexternalIdsに記載された arXiv バージョンをダウンロードし、SEMANTIC_SCHOLAR_API_KEYがある場合は同じ論文の 2 番目のレコードをタイトルで検索します(検索エンドポイントはキーなしでは 429 を返します)。リクエストは 1 秒間隔で行われ、これは Semantic Scholar の制限です。 ダウンロードはブラウザの User-Agent を送信し、PDF を非ブラウザクライアントにのみ配信するリポジトリ向けにプレーンな User-Agent で再試行し、tls拡張機能があれば Chrome の TLS フィンガープリントでもう一度試行します。Wiley へのリクエストは 10 分あたり 30 件にペース調整され(公表されている制限は 60 件ですが、API は約 35 件から HTTP 500 を返します)、Crossref へのリクエストは polite pool の制限に従い、一時的な 429/5xx レスポンスは 1 回再試行されます。
プレプリントや受理済み原稿を返すルート(arxiv、chemrxiv、biorxiv、osti、semantic、unpaywall および europepmc からのリポジトリコピー)は、結果に note を設定します。downloader.py の PUBLISHER_TOOL_MAP を参照してください。
ヒント – スクレイピングベースの手法(
springerpdf、elife、cambridgeなど)は、サイトのレイアウト変更やアクセス制限により壊れる可能性があります。大規模なダウンロードには公式 API と Unpaywall を優先してください。
リグレッションセット
benchmark/ には、既知の結果を持つ 178 個の識別子と、リリース候補をチェックするためのランナーが含まれています。
python benchmark/run_regression.py は、known_good、needs_institution、expected_fail の各識別子のうち何件がダウンロードされたかを出力し、known_good の 1 件が失敗した場合に非ゼロで終了します。benchmark/README.md を参照してください。
ツールシーケンスのカスタマイズ
from fulltext_article_downloader import fetch
fetch("10.1017/S0885715624000484", "papers", tools=["unpaywall", "cambridge"]) # override default order
実行時のオーバーライド:
from fulltext_article_downloader import PUBLISHER_TOOL_MAP
PUBLISHER_TOOL_MAP["Elsevier BV"] = ["elsevier", "unpaywall"]
5. ライセンスと免責事項
BSD 3-Clause です。LICENSE ファイルを参照してください。
このツールは、合法的にアクセスする権利があるコンテンツにのみ使用してください。出版社の利用規約および著作権法を遵守してください。Sci-Hub や同様のサイトは使用せず、あなた自身の購読、API キー、オープンアクセスライセンスがすでに許可しているもののみを取得します。オプションの tls および aps ルートは、インストールのセクションで説明されているとおり、ブラウザと同様にリクエストを送信します。作者は不正使用に対して責任を負いません。
computron によって vibes(ChatGPT 4.0)とカフェインでスピードコーディングされ、Xu Huang によって Claude で拡張されました。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。