Skip to main content
Glama
tbaraniuk

arxiv-agent-mcp

by tbaraniuk

arXiv Research-Concept Companion

Ein AI/ML-Studienbegleiter-Agent (KSE Agentic Lab-Aufgabe). Er liest eine Konzeptzusammenfassungs-Notiz aus Ihrer Obsidian-Vault, findet verwandte arXiv-Paper, bewertet jedes nach thematischer Relevanz und altersangepasstem Zitationsimpact, findet die etablierten Paper, auf denen ein überlebender Kandidat aufbaut, und schreibt die Ergebnisse zurück in die Vault.

  • Vorhandener MCP-Server (Teil A): Obsidian Local REST API MCP.

  • Eigener MCP-Server (Teil B): custom_server/ — FastMCP-Anwendung, 3 Tools über die öffentlichen arXiv- und OpenAlex-APIs (ohne Authentifizierung).

  • Agent: agent/ — ein PydanticAI-Agent (OpenRouter-gestützt), der beide MCP-Verbindungen als Toolsets hält, orchestriert von einem LangGraph-Zustandsgraph.

Voraussetzungen

  • Python 3.12+, uv.

  • Ein OpenRouter-API-Schlüssel.

  • Obsidian mit installiertem und laufendem Local-REST-API-Community-Plugin und einem MCP-Server, der damit spricht (eine beliebige Obsidian-Local-REST-API-MCP-Implementierung — der Startbefehl ist konfigurierbar, siehe unten).

Related MCP server: arxiv-mcp

Installation

uv sync
cp .env.example .env

Füllen Sie .env aus:

Variable

Bedeutung

OPENROUTER_API_KEY

OpenRouter-Schlüssel — wird vom Agenten und von score_paper_relevance verwendet.

OPENROUTER_MODEL

Modell-Slug, z. B. openai/gpt-4o-mini.

OBSIDIAN_API_KEY / OBSIDIAN_BASE_URL

Zugangsdaten des Local-REST-API-Plugins.

OBSIDIAN_MCP_COMMAND

Durch Leerzeichen getrennte argv zum Starten des Obsidian-MCP-Servers, z. B. npx -y <obsidian-mcp-package>.

RELEVANCE_PASS_THRESHOLD

Mindest-Relevanzwert (0–1) zum Bestehen des Filters. Standard 0,5.

CITATIONS_PER_YEAR_THRESHOLD

Mindestzitate pro Jahr, um den Impact-Check zu bestehen. Standard 5.

NEW_PAPER_AGE_EXEMPT_YEARS

Paper jünger als dieser Wert sind von der Impact-Prüfung ausgenommen. Standard 1.

Ausführung

Zwei unabhängige Prozesse, die sich ein uv-Projekt teilen:

# 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.py startet custom_server/server.py selbst als Stdio-Subprozess, daher muss Prozess 2 nicht schon laufen, damit Prozess 1 läuft — die beiden Befehle oben zeigen nur, dass jeder der Prozesse unabhängig startbar ist.

Der Prompt ist kein wörtlicher Notiztitel — der erste Schritt des Agenten (parse_prompt) verwendet einen LLM-Aufruf, um zu identifizieren, auf welche Obsidian-Notiz sich der Prompt bezieht. Wenn er keine identifizieren kann, stoppt der Lauf sofort und gibt „Not enough information: no Obsidian note or page was named in the prompt." aus, ohne Obsidian zu berühren. Wenn die gefundene Notiz nicht genügend Konzept-Keywords liefert (weniger als min_keywords, Standard 2), stoppt der Lauf nach dem Lesen und gibt eine entsprechende „not enough information"-Meldung aus, statt arXiv zu durchsuchen.

Offline-/Replay-Modus

Der benutzerdefinierte Server ruft drei Live-Netz-APIs auf (arXiv, OpenAlex, OpenRouter). Durch Setzen von CUSTOM_SERVER_OFFLINE=1 werden seine Tools aus aufgezeichneten Fixtures in custom_server/fixtures/ bedient — ohne Netzwerkzugriff und ohne OPENROUTER_API_KEY. Das ist nützlich für eine Demo/Verteidigung ohne zuverlässiges Netzwerk oder für schnelles Iterieren.

CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server

Was abgedeckt ist: search_arxiv_papers (ein aufgezeichneter Such-Feed, der unabhängig von der Suchanfrage geliefert wird — siehe Einschränkung unten) sowie score_paper_relevance / find_foundational_citations für die zwei aufgezeichneten Paper GPT-3 (2005.14165) und ResNet (1512.03385).

Bekannte Einschränkungen:

  • search_arxiv_papers ist im Offline-Modus abfragen-unabhängig — es gibt unabhängig vom Abfrage-Code immer denselben aufgezeichneten Feed zurück.

  • score_paper_relevance und find_foundational_citations erkennen nur die zwei oben genannten aufgezeichneten Paper. Eine nicht aufgezeichnete arxiv_id erzeugt einen PaperNotFoundError (derselbe Fehler, den ein echter OpenAlex-Trefferausfall erzeugen würde); ein nicht aufgezeichneter Paper-Titel, der an score_paper_relevance übergeben wird, erzeugt einen FixtureNotFoundError — unterscheidbar, keine stille falsche Antwort.

Um die Fixtures zu regenerieren oder zu erweitern: uv run python -m custom_server.fixtures.record ruft die aufgezeichneten arXiv/OpenAlex-Antworten erneut ab (beide sind öffentliche, unauthentifizierte APIs) und überschreibt die JSON/XML-Dateien in custom_server/fixtures/. Um ein neues Paper hinzuzufügen, fügen Sie dessen beiden httpx.get-Aufrufe zu record.py sowie einen passenden Eintrag zu relevance_scores.json hinzu — dies ist handgeschrieben, keine echte OpenRouter-Ausgabe, da das Aufzeichnen der rohen Chat-Complete-Antwort die Fragilität des Wire-Formats nicht wert wäre; die strukturierten Felder {relevance, novelty, rationale} werden direkt über ein PydanticAI-FunctionModel ausgespielt.

Tests

uv run pytest custom_server/tests agent/tests

Alle Netzwerk-Handlungen (arXiv, OpenAlex, OpenRouter) sind gesimuliert; bei den Tests läuft kein Live-Verkehr.

Tool-Verträge (Teil C)

search_arxiv_papers (benutzerdefiniert)

Zweck

Primäres Datenquellen-Tool: Sucht auf arXiv nach thematischen Kandidaten-Papern.

Beschreibung für das Modell

„Suche auf arXiv nach Papern zu einem Thema, optional eingeschränkt auf Kategorien und ein Mindestdatum der Einreichung. Nutze dies, um Kandidaten-Paper zu finden, bevor Du sie einzeln mit score_paper_relevance auswertest. Eine gültige Abfrage, die nichts findet, liefert eine leere Liste — das ist ein normales Ergebnis, kein Fehler."

Eingabe

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

Ausgabe

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

Fehlerbedingungen

ValueError bei ungültigem Kategoriecode, fehlerhaftem since_date oder max_results außerhalb von [1, 50] — ausgelöst vor einem Netzaufruf. Ein übergeordneter HTTP-Fehlschlag wird über raise_for_status() ausgelöst. Null Treffer ist eine gültige leere Liste, kein Fehler.

Nebeneffekte

Keine — ausschließlich lesender HTTP-GET an export.arxiv.org.

Beispiel

search_arxiv_papers(query="transformer attention", max_results=5) → 5 Kandidaten-Paper mit Zusammenfassungen.

score_paper_relevance (benutzerdefiniert)

Zweck

Bewertungswerkzeug: beurteilt die thematische Eignung eines Kandidaten und ob sein Zitationsprofil eine altersangepasste Hürde überwindet.

Beschreibung für das Modell

„Bewerte, wie relevant und wie neuartig ein Paper zu einer Konzeptzusammenfassung ist, und prüfe, ob seine Zitationswirkung eine Mindesthürde erfüllt (Zitationen pro Jahr; jüngere als ein Jahr sind ausgenommen). Nutze dies für jeden Kandidaten aus einem search_paper_relevance, um zu entscheiden, ob er in eine Leseliste gehört. Wirft einen Fehler, wenn es keinen OpenAlex-Datensatz für das Paper gibt oder wenn der zugrunde liegende Modell-Aufruf zur Relevanzbewertung scheitert."

Eingabe

concept_summary: str, paper: {arxiv_id, title, abstract}

Ausgabe

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

Fehlerbedingungen

PaperNotFoundError (aus custom_server.openalex), wenn OpenAlex keinen Datensatz für die arXiv-DOI des Papers hat — abgegrenzt zu einem gefundenen, aber nicht zitierten Paper, das eine gültige citation_count: 0 hat. UnexpectedModelBehavior, wenn die strukturierte Ausgabe des OpenRouter-Aufrufs nach Wiederholungen die Schema-Validierung nicht besteht.

Nebeneffekte

Nur lesend: ein OpenAlex-GET und ein OpenRouter-Chat-Completion-Aufruf.

Beispiel

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 (benutzerdefiniert)

Zweck

Zitationsgraph-Analyse: Gegeben ein Paper, ordne seine eigenen Referenzen nach Zitationszahl, um die etablierten Arbeiten hervorzuheben, auf denen es aufbaut. Unterscheidet sich von search_arxiv_papers – es analysiert die Referenzliste eines bestimmten Papers, nicht eine Stichwortsuche.

Modellbeschreibung

"Gegeben die arXiv-ID eines Papers, gib seine am häufigsten zitierten Referenzen zurück – die etablierten Vorarbeiten, auf denen es aufbaut. Verwende dies, nachdem du ein Paper zum Lesen ausgewählt hast, um die Hintergrundliteratur dahinter sichtbar zu machen. Ein Paper ohne aufgezeichnete Referenzen gibt eine leere Liste zurück – das ist ein normales Ergebnis, kein Fehler."

Eingabe

arxiv_id: str, max_results: int = 3 (1–3)

Ausgabe

list[{openalex_id, title, cited_by_count, publication_year}], sortiert nach cited_by_count absteigend, die obersten max_results

Fehlerbedingungen

ValueError, wenn max_results außerhalb von [1, 3] liegt. PaperNotFoundError, wenn OpenAlex keinen Eintrag für die arXiv-ID hat. Ein Paper mit null Referenzen gibt [] zurück – gültig, kein Fehler.

Nebenwirkungen

Nur lesend: eine OpenAlex-Paper-Abfrage + eine oder mehrere gebündelte OpenAlex-Works-Abfragen (in Blöcken von 50 IDs pro Anfrage).

Beispiel

find_foundational_citations(arxiv_id="2005.14165", max_results=3) → die 3 am häufigsten zitierten Paper, die GPT-3 referenziert.

Obsidian Local REST API MCP (bestehend, Teil A)

Verwendet über die natürlichsprachlichen Tool-Aufrufe des PydanticAI-Agenten (keine feste Wrapper-Funktion) für zwei Operationen im Ablauf:

Referenzauflösung

Vor jedem Obsidian-Aufruf fordert parse_prompt den PydanticAI-Agenten (reine LLM-Argumentation, kein MCP-Aufruf) auf, den Notiztitel zu identifizieren, der durch die Freitext-Eingabe des Benutzers impliziert wird. Wenn keiner identifizierbar ist, stoppt der Ablauf mit einem Status „unzureichende Informationen“ und ruft Obsidian nie auf.

Lesen

Der Agent wird aufgefordert, die Notiz mit dem Titel note_title (aus parse_prompt) zu lesen und ihren Klartext-Inhalt zurückzugeben – speist concept_text, die Eingabe für Stichwortextraktion und Relevanzbewertung.

Schreiben

Der Agent wird aufgefordert, eine Notiz mit dem Titel "{note_title} — Related Papers" mit dem von compose_note_content erzeugten Markdown zu erstellen/überschreiben – der sichtbare Effekt, der die Schleife zwischen beiden MCP-Servern schließt.

Fehlerbedingungen

Gestopptes Plugin, ungültiger API-Schlüssel oder eine fehlende Notiz erscheinen als unterscheidbarer Tool-Aufruf-Fehler vom MCP-Server, nicht als stilles leeres Ergebnis.

Designentscheidungen

  • Warum Obsidian: Die Aufgabe benötigt einen bestehenden MCP-Server, von dem der Agent liest und in den er schreibt. Die eigenen Konzeptnotizen eines Studenten sind eine natürliche Eingabe für „Was weiß ich schon“, und das Zurückschreiben der überlebenden Paper schließt die Schleife sichtbar im Vault.

  • Warum arXiv + OpenAlex statt einer anmeldepflichtigen Website: Die ursprünglich in Betracht gezogenen KSE-Plan-/Moodle-Quellen erfordern beide einen persönlichen Login, was die Public-API-Regel der Aufgabe ausschließt. arXiv und OpenAlex sind öffentlich, ohne Authentifizierung und unterstützen direkt den Bereich „Relevanz + Impact“.

  • Warum Relevanz per LLM bewertet wird, nicht per Embeddings: OpenRouter hat keinen Embeddings-Endpunkt (gegen den Live-Modellkatalog verifiziert), daher verwendet score_paper_relevance einen PydanticAI-Structured-Output-Aufruf anstelle von Vektorähnlichkeit – und nutzt dabei die eine Modellberechtigung, die das Projekt bereits benötigt.

  • Warum find_foundational_citations nicht „erneut mit OpenAlex suchen“ ist: Es nimmt die Referenzliste eines bestimmten Papers und ordnet sie nach Zitations-Impact, dieselbe Art von kontrolliertem Indikatorvergleich, den die eigenen Beispiele der Aufgabe verwenden – eine eigene Verantwortung und Verarbeitung, getrennt von der stichwortgesteuerten search_arxiv_papers.

  • Filterung ist einfaches Python, kein 4. Tool: Der Relevanz-Schwellenwert + impact_pass-Filter in agent/graph.py's filter_candidates_node ist deterministische Nachbearbeitung bereits bewerteter Daten, keine neue Domänenlogik – ein Tool wäre nur eine Indirektion um ein if.

  • Abwägungen / Einschränkungen: Der Offline-/Replay-Modus des benutzerdefinierten Servers (siehe „Offline / Replay-Modus“ oben) deckt zwei aufgezeichnete Paper und eine abfrageunabhängige arXiv-Suche ab – keine allgemeine Aufzeichnung/Wiedergabe beliebiger Abfragen. Die eigenen Obsidian- und OpenRouter-Aufrufe von agent/ sind davon nicht betroffen und erfordern weiterhin Live-Zugriff. Impact-/Relevanz-Schwellenwerte sind .env-Werte, nicht pro Anfrage zur Laufzeit einstellbar.

Zurückgestellt (markiert, nicht verworfen)

  • Die hartcodierten Schwellenwerte als umfangreichere Laufzeitkonfiguration über .env hinaus verfügbar machen.

Demo / Verteidigungs-Checkliste

  • uv run python -m custom_server.server startet eigenständig; ein roher MCP-Client zeigt mit list_tools alle 3 Tools.

  • uv run pytest custom_server/tests agent/tests – alles grün, Netzwerk gemockt.

  • CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server startet und bedient alle 3 Tool-Aufrufe ohne Live-Netzwerk oder API-Schlüssel (siehe „Offline / Replay-Modus“).

  • Lege eine Demo-Vault-Notiz mit einer Konzeptzusammenfassung an (z. B. „attention mechanisms“), mit einem Titel wie z. B. „Transformers Concept Note“.

  • uv run python -m agent.graph "Find papers related to my 'Transformers Concept Note'" – vollständiger Live-Lauf: löst die Notizreferenz auf, liest die Notiz, durchsucht arXiv, bewertet Kandidaten, filtert, findet grundlegende Zitationen, schreibt "<note> — Related Papers" zurück in den Vault.

  • Zeige beide MCP-Verbindungen, die in die endgültige Ausgabe einfließen: Die zurückgeschriebene Notiz zitiert sowohl arXiv/OpenAlex-Daten (benutzerdefinierter Server) als auch den Inhalt der ursprünglichen Konzeptnotiz (Obsidian).

  • Demo unzureichender Informationen: Führe mit einer Eingabe aus, die keine Notiz nennt (z. B. "What's a transformer?") – zeige, dass der Agent anhält und „Not enough information...“ ausgibt, ohne Obsidian aufzurufen. Führe dann mit einer Notiz mit fast leerem Inhalt aus – zeige, dass er nach dem Lesen der Notiz anhält, bevor er arXiv aufruft.

  • Fehlerdemo, Obsidian: Stoppe das Local-REST-API-Plugin (oder verwende einen falschen OBSIDIAN_API_KEY / einen nicht existierenden Notiztitel) – zeige, dass der Agent einen unterscheidbaren Fehler ausgibt, kein stilles leeres Ergebnis.

  • Fehlerdemo, benutzerdefinierter Server: Rufe search_arxiv_papers mit einer ungültigen Kategorie auf, oder find_foundational_citations mit einer arXiv-ID, die in OpenAlex nicht vorhanden ist – zeige entsprechend ValueError / PaperNotFoundError, unterschieden von einem gültigen leeren Ergebnis.

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