Skip to main content
Glama
tbaraniuk

arxiv-agent-mcp

by tbaraniuk

arXiv Research-Concept Companion

AI/ML学習コンパニオンエージェント(KSE Agentic Lab の課題)です。Obsidian ボールトのコンセプト要約ノートを読み、関連する arXiv の論文を探し、各論文をトピックへの関連性と経過年数で調整した被引用インパクトでスコアリングし、生き残った候補が前提としている確立済みの論文を見つけ、その結果をボールトに書き戻します。

  • 既存MCPサーバー(Part A): Obsidian Local REST API MCP。

  • カスタムMCPサーバー(Part B): custom_server/ — FastMCPアプリ。公開されている arXiv API と OpenAlex API を扱う3つのツール(認証不要)。

  • エージェント: agent/ — PydanticAI の Agent(OpenRouter をバックエンドとして使用)が、2つの MCP 接続をツールセットとして保持し、LangGraph ステートマシンがその調整を行う。

前提条件

  • Python 3.12+、uv

  • OpenRouter の API キー。

  • Obsidian に Local REST API コミュニティプラグインがインストールされ、動作していること。また、それに接続する MCP サーバーがあること(任意の Obsidian Local REST API MCP 実装でよい — 起動コマンドは設定可能、以下参照)。

Related MCP server: arxiv-mcp

インストール

uv sync
cp .env.example .env

.env を記入します。

変数

意味

OPENROUTER_API_KEY

OpenRouter キー — エージェントと score_paper_relevance が使用します。

OPENROUTER_MODEL

モデルの slug(例: openai/gpt-4o-mini)。

OBSIDIAN_API_KEY / OBSIDIAN_BASE_URL

Local REST API プラグインの認証情報。

OBSIDIAN_MCP_COMMAND

Obsidian MCP サーバーを起動するスペース区切り argv(例: npx -y <obsidian-mcp-package>)。

RELEVANCE_PASS_THRESHOLD

フィルタを通過するための最低関連性スコア(0–1)。デフォルト 0.5

CITATIONS_PER_YEAR_THRESHOLD

インパクト判定を通過するための最低年間被引用数。デフォルト 5

NEW_PAPER_AGE_EXEMPT_YEARS

この年数未満の論文はインパクト判定を免除。デフォルト 1

実行

1つの uv プロジェクトを共有する2つの独立したプロセス:

# process 1 — the custom MCP server (arXiv + OpenAlex)
uv run python -m custom_server.server

# process 2 — the agent (connects to both MCP servers), driven by a free-text prompt
uv run python -m agent.graph "Find papers related to my 'Transformers Concept Note'"

agent/graph.pycustom_server/server.py を self 自身の stdio サブプロセスとして起動します。したがって、プロセス2はプロセス1が既に起動している必要はありません — 上記の2つのコマンドは、各プロセスが独立に起動できることを示しているだけです。

プロンプトは文字どおりのノートタイトルではありません。エージェントの最初のステップ(parse_prompt)は、LLM 呼び出しを使ってプロンプトが参照する Obsidian ノートを特定します。もしそれを特定できない場合は、実行は直ちに止まり、Obsidian に触れることなく「情報が不十分です。プロンプトに Obsidian ノートやページ名が指定されていませんでした」と表示します。また、そのノートから十分なコンセプトキーワードが得られない場合(min_keywords 未満。デフォルトは2)、そのノートを読み終えたところで実行は止まり、arXiv を検索せずに同様の「情報が不十分です」というメッセージを表示します。

オフライン / リプレイモード

カスタムサーバーは3つの外部ネットワークAPI(arXiv、OpenAlex、OpenRouter)を呼び出します。CUSTOM_SERVER_OFFLINE=1 を設定すると、custom_server/fixtures/ に記録されたフィクスチャからツールを提供してきるため、ネットワークアクセスや OPENROUTER_API_KEY は不要です。ネットワークが不安定なデモ・審査や、素早い反復に役立ちます。

CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server

対象範囲: search_arxiv_papers(記録済みの検索フィードが1つあり、どのクエリにもそれを返す — 下記の制限を参照)、および記録済みの2件の論文、GPT-3(2005.14165)と ResNet(1512.03385)に対する score_paper_relevance / find_foundational_citations

既知の制限:

  • search_arxiv_papers はオフラインモードではクエリに依存しません。クエリテキストに関係なく常に同じ記録済みフィードを返します。

  • score_paper_relevancefind_foundational_citations は記録された2つの論文のみを認識します。記録されていない arxiv\_idPaperNotFoundError(実際の OpenAlex で見つからない場合に発生するのと同じエラー)をスローします。また、score_paper_relevance に渡された未答録の論文タイトルは FixtureNotFoundError をスローします — この2つは区別でき、黙って誤った回答を返すことはありません。

フィクスチャを再生成・拡張するには: uv run python -m custom_server.fixtures.record が記録済みのarXiv/OpenAlexレスポンス(どちらも公開・認証不要API)を再度取得し、custom_server/fixtures/ 内の JSON/XML ファイルを上書きします。新しい論文を追加するには、record.pyhttpx.get の呼び出しを2つ追加し、relevance_scores.json にそれに対応するエントリを追加してください。実際の OpenRouter の raw chat-completion レスポンスを記録してもワイヤーフォーマットの脆さに見合わないため、relevance_scores.json は手書きです(実際の OpenRouter 出力ではありません)。構造化された {relevance, novelty, rationale} フィールドは、PydanticAI の FunctionModel を直接を通じて再生されます。

テスト

uv run pytest custom_server/tests agent/tests

すべてのネットワーク呼び出し(arXiv、OpenAlex、OpenRouter)はモック化されています。テスト中に実ネットワーク通信は発生しません。

ツール契約(Part C)

search_arxiv_papers(カスタム)

目的

目的

主要なデータソースツール: トピックに関する候補論文を arXiv で検索します。

モデル向け説明

「トピックに関する論文を arXiv で検索する。カテゴリと最低投稿日で任意に制限できる。score_paper_relevance で個別に評価する前に、このツールを使って候補論文を見つけること。有効なクエリで一致がゼロの場合は空のリストを返す — これは正常な結果であり、エラーではない。」

入力

query: strcategories: list[str] = [cs.LG, cs.AI, cs.CL, stat.ML]since_date: str | NoneYYYY-MM-DD)、max_results: int = 10(1–50)

出力

list[{arxiv_id, title, abstract, authors: list[str], published_date, categories: list[str]}]

エラー条件

不正なカテゴリーコード、不正な since_date、または max_results[1, 50] から外れた場合は ValueError — ネットワーク呼び出し前に発生します。上流の HTTP 失敗は raise_for_status() 経由で発生します。ゼロ件の一致は有効な空リストであり、エラーではありません。

副作用

なし — export.arxiv.org への読み取り専用 HTTP GET。

search_arxiv_papers(query="transformer attention", max_results=5) → 抄録付きの候補論文が5件返されます。

score_paper_relevance(カスタム)

目的

目的

評価ツール: 1つの候補論文のテーマへの適合度と、その被引用状況が年齢調整済みの基準を満たしているかを判定します。

モデル向け説明

論文がコンセプト要約に対してどの程度関連し、新規性があるかをスコアリングし、被引用インパクトが最低基準(年間被引用数、1年未満の論文は免除)を満たしているか確認する。search_arxiv_papers で出得た各候補にこれを使って、読書リストに加えるか判断します。論文に OpenAlex レコードがない場合、または下層の関連性スコアリングモデルの呼び出しが失敗した場合にエラーを発生します。

入力

指定入力: concept_summary: strpaper: {arxiv_id, title, abstract}

出力

{relevance: float, novelty: float, citation_count: int, publication_year: int, citations_per_year: float, impact_pass: bool, rationale: str}

エラー条件

PaperNotFoundErrorcustom_server.openalex から発生)は、OpenAlex に紙の arXiv DOI に対応するレコードがない場合に発生します。見つかったが被引用ゼロの論文(有効な citation_count: 0)とは区別されます。UnexpectedModelBehavior は、OpenRouter の構造化出力がリトライ後も 5 番号検証に失敗した場合に発生します。

副作用

読み取り専用: OpenAlex GET と OpenRouter chat-completion 呼び出しがそれぞれ1回ずつ。

score_paper_relevance(concept_summary="attention mechanisms in NLP", paper={...}){relevance: 0.92, novelty: 0.6, citation_count: 84331, impact_pass: True, ...}

find_foundational_citations (カスタム)

目的

引用グラフ解析:1つの論文が与えられたら、その引用元である参考文献を被引用数で並べ替え、その論文が拠り所とする確立済みの研究を浮き彫りにします。search_arxiv_papers とは異なります — キーワード検索ではなく、特定の1件の論文の解説リストを解析するものです。

モデル向けの説明

「1つの論文の arXiv ID が与えられたら、その論文が引用している中で最も被引用数の多い参考文献 — つまりその論文が支えている確立された先行研究成果 — を返します。読む論文を選んだ後にこれを使い、その背後にある背景文献を浮き彫りにしてください。参考文献がひとつも記録されていない論文は空リストを返します。これは正常な結果であり、エラーではありません。」

入力

arity_id: strmax_results: int = 3(1–3)

出力

list[{openalex_id, title, cited_by_count, publication_year}]cited_by_count の降順にソートし、上位 max_results 件を返す。

エラー条件

max_results[1, 3] の範囲外なら ValueError。OpenAlex にその arXiv ID のレコードがない場合 PaperNotFoundError。参考文献がゼロの論文は [] を返します — これは正常であって、エラーではありません。

副作用

読み出し専用。OpenAlex の paper ルックアップ1回+OpenAlex の works バッチルックアップを1回以上実行(1リクエストあたり50 ID 刻みで処理)。

find_foundational_citations(arxiv_id="2005.14165", max_results=3) → GPT-3 が参考文献として挙げている被引用数の高い3件。

Obsidian Local REST API MCP (既存, Part A)

PydanticAI エージェントの自然言語ツール呼び出し(固定のラッパー関数ではありません)を利用し、フローの以下の操作で使用します:

参照解決

Obsidian を呼び出す前に、parse_prompt が PydanticAI エージェント(MCP 呼び出しではなく、通常の LLM 推論)に対して、ユーザーの自由テキストプロンプトから暗に示されたノートタイトルを特定させます。特定できない場合、フローは「情報不足」の状態で止まり、Obsidian を一切呼び出しません。

読み込み

エージェントは、parse_prompt によって取り出された note_title というタイトルのノートを呼び出し、そのプレーンテキストを返すようプロンプトされます。それが concept_text となり、キーワード抽出と関連性スコアの入力になります。

書き込み

エージェントは、compose_note_content が生成したマークダウンを "{note_title} — Related Papers" というタイトルのノートに作成・上書きするよう指示されます。両 MCP サーバーの間を結ぶ、目に見える効果が得られます。

エラー条件

プラグインの停止、API キーの無効、またはノートの欠落は、黙って空の結果としてではなく、MCP サーバーからの判別可能な tool call 失敗として表現されます。

設計の根拠

  • なぜ Obsidian なのか: この課題は、エージェントが読み取りと書き込みの両方を行える既存の MCP サーバーを必要としています。自分のコンセプトノートは「すでに自分が何を知っているか」を取り込む自然な入力であり、生き残った論文を書き戻すことで、vault 内のループを視覚的に閉じることができます。

  • なぜログイン必須のサイトではなく arXiv + OpenAlex なのか: 当初検討していた KSE schedule / Moodle などの情報元は、いずれも個人ログインが必要であり、この課題の public-API ルールで紛失となります。arXiv と OpenAlex は公開・認証不要で、「relevance + impact」というドメインを直接支えています。

  • なぜエンペディングではなく LLM で関連性を判断するのか: OpenRouter にはエンペディングのエンドポイントが存在しないため(ライブのモデルカタログで確認済み)、score_paper_relevance はベクター類似度の代わりに PydanticAI の構造化出力呼び出しを使います。これは、このプロジェクトがすでに必要とする唯一のモデル認証情報をそのまま再利用する方法です。

  • なぜ find_foundational_citations が「OpenAlex で再検索」でではないのか: これは、特定の1本の論文の参考文献リストを取り上げて被引用影響でランク付けするもので、課題の例が用いる「制御された文法比較しきい値」と同種の物です。キーワード駆動の search_arxiv_papers とは、役割と処理が明確に分離されています。

  • フィルタリングは、4つめのツールではなく素朴な Python であるwhy: agent/graph.pyfilter_candidates_node にある relevance-threshold と impact_pass のフィルタは、スコア済みデータに対する決定的な後処理であって、新しいドメインロジックではありません。ツールにしたとしても、if の穴をひとつ回るだけです。

  • トレードオフ / 制限: カスタムサーバーのオフライン/リプレイ モード(前述の「オフライン / リプレイモード」参照)は、記録済みの2つの論文と、クエリに依存しない棚エクスプレス検索に対応しており、無作為なクエリに対する汎用的な記録・リプレイなものではありません。agent/ 自身による Obsidian 呼び出しと OpenRouter 呼び出しはこの影響を受けず、引き続きライブアクセスが必要です。影響・関連は .env の設定値であり、リクエストごとに実行時調整できるようなものではありません。

先延ばしリスト(フラグ付き・削除はしていません)

  • ハードコードされた閾値を .env よりリッチな実行時設定として送付すること。

デモ / ディフェンス用チェックリスト

  • uv run python -m custom_server.server が単体で起動し、素の MCP クライアントの list_tools に3つのツールすべてが表示される。

  • uv run pytest custom_server/tests agent/tests — ネットワークをモック / スタブして、すべてグリーンになる。

  • CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server で起動し、ライブネットワーク・API キーなしで3つのツール呼び出しに応答する(「オフライン / リプレイモード」を参照)。

  • デモ用の vault ノートにて概要(例: "attention mechanisms")付きのノートを用意し、タイトルを「Transformers Concept Note」などにする。

  • uv run python -m agent.graph "Find papers related to my 'Transformers Concept Note'" を実行 — 全体のライブ実行が: ノート参照を解決し、ノートを読み込み、arXiv を検索し、候補をスコア化し、フィルタリングし、基礎引用をさがし、"{note_title} — Related Papers" を vault に書き戻す。

  • 2つのMCP 接続が最終出力に寄与していることを示す: 書き戻した note が、arXiv/OpenAlex のデータ(カスタムサーバー)と、元のコンセプト ノートの内容(Obsidian)の両方を参照を含んでいる。

  • 情報不足のデモ: ノート名を指定しないプロンプト(例: "What's a transformer?")で実行して、Obsidian を呼び出すことなく「十分な情報がありません...」と停止することを示す。そのあと、ほとんど空の内容のノートで実行し、arXiv を呼び出す前にそのノートを読んで停止することを示す。

  • 障害表示デモ (Obsidian) — Local REST APIプラグインを停止する(または不正な OBSIDIAN_API_KEY や存在しないノートタイトルを使う)ことで、黙って空の結果にではなく、判別可能なエラーを出す。

  • 障害失敗デモ (カスタムサーバー) — 無効なカテゴリで search_arxiv_papers

Install Server
A
license - permissive license
A
quality
C
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
    Not graded
    quality
    D
    maintenance
    This MCP server enables users to search for scientific papers on arXiv and retrieve detailed metadata for specific papers. It provides tools to perform search queries and fetch in-depth information using paper IDs.
    3
    Apache 2.0
  • F
    license
    A
    quality
    D
    maintenance
    A streamlined MCP server that connects AI assistants to arXiv's vast collection of academic papers, enabling search, retrieval, and analysis of research papers.
    7
    1
  • F
    license
    Not graded
    quality
    D
    maintenance
    An advanced scholarly research MCP server that enables AI assistants to discover, fetch, process, and manage academic papers across multiple sources like arXiv, PubMed, and Semantic Scholar, with capabilities for summarization, citation analysis, and concept relationship extraction.
    1

View all related MCP servers

Related MCP Connectors

  • Academic research MCP server for paper search, citation checks, graphs, and deep research.

  • Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.

  • An MCP server for deep research or task groups

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/tbaraniuk/arxiv-agent-mcp'

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