arxiv-agent-mcp
arXiv Research-Concept Companion
Un agente de estudio-compañero de IA/ML (tarea de KSE Agentic Lab). Lee una nota de resumen de conceptos de tu bóveda de Obsidian, encuentra artículos relacionados de arXiv, puntúa cada uno según su relevancia temática e impacto de citas ajustado por edad, encuentra los artículos bien establecidos en los que se basa un candidato superviviente y escribe los hallazgos de vuelta en la bóveda.
Servidor MCP existente (Parte A): Obsidian Local REST API MCP.
Servidor MCP personalizado (Parte B):
custom_server/— aplicación FastMCP, 3 herramientas sobre las APIs públicas de arXiv y OpenAlex (sin autenticación).Agente:
agent/— unAgentde PydanticAI (respaldado por OpenRouter) que mantiene ambas conexiones MCP como conjuntos de herramientas, orquestado por una máquina de estados de LangGraph.
Requisitos previos
Python 3.12+,
uv.Una clave de API de OpenRouter.
Obsidian con el plugin de la comunidad Local REST API instalado y en ejecución, y un servidor MCP que se comunique con él (cualquier implementación de MCP de Obsidian Local REST API — el comando de lanzamiento es configurable, ver más abajo).
Related MCP server: arxiv-mcp
Instalación
uv sync
cp .env.example .envRellena .env:
Variable | Significado |
| Clave de OpenRouter — utilizada por el agente y por |
| Slug del modelo, p. ej. |
| Credenciales del plugin Local REST API. |
| argv separado por espacios para lanzar tu servidor MCP de Obsidian, p. ej. |
| Puntuación mínima de relevancia (0–1) para superar el filtro. Por defecto |
| Citas mínimas por año para superar la comprobación de impacto. Por defecto |
| Los artículos más recientes que esta edad están exentos de la comprobación de impacto. Por defecto |
Ejecución
Dos procesos independientes, que comparten un proyecto uv:
# 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 lanza custom_server/server.py como subproceso stdio, por lo que el proceso 2 no necesita que el proceso 1 ya esté en ejecución — los dos comandos anteriores solo demuestran que cada uno se puede iniciar de forma independiente.
El prompt no es un título de nota literal — el primer paso del agente (parse_prompt) utiliza una llamada LLM para identificar a qué nota de Obsidian se refiere el prompt. Si no puede identificar una, la ejecución se detiene inmediatamente e imprime "Información insuficiente: no se nombró ninguna nota o página de Obsidian en el prompt." sin tocar Obsidian. Si la nota que encuentra no produce suficientes palabras clave de concepto (menos de min_keywords, por defecto 2), la ejecución se detiene después de leerla e imprime un mensaje similar de "información insuficiente" en lugar de buscar en arXiv.
Modo sin conexión / reproducción
El servidor personalizado llama a tres APIs de red en vivo (arXiv, OpenAlex, OpenRouter). Al establecer CUSTOM_SERVER_OFFLINE=1, sus herramientas se sirven desde fixtures grabados en custom_server/fixtures/ en su lugar — no se requiere acceso a la red ni OPENROUTER_API_KEY. Útil para una demo/defensa sin red fiable, o para iteración rápida.
CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.serverLo que está cubierto: search_arxiv_papers (un feed de búsqueda grabado, servido para cualquier consulta — ver limitación abajo), y score_paper_relevance / find_foundational_citations para dos artículos grabados, GPT-3 (2005.14165) y ResNet (1512.03385).
Limitaciones conocidas:
search_arxiv_paperses agnóstico a la consulta en modo sin conexión — siempre devuelve el mismo feed grabado independientemente del texto de la consulta.score_paper_relevanceyfind_foundational_citationssolo reconocen los dos artículos grabados anteriores. Un arxiv_id no grabado lanzaPaperNotFoundError(el mismo error que produciría un fallo real de OpenAlex); un título de artículo no grabado pasado ascore_paper_relevancelanzaFixtureNotFoundError— distinguible, no una respuesta incorrecta silenciosa.
Para regenerar o ampliar los fixtures: uv run python -m custom_server.fixtures.record vuelve a obtener las respuestas grabadas de arXiv/OpenAlex (ambas APIs públicas, sin autenticación) y sobrescribe los archivos JSON/XML en custom_server/fixtures/. Para añadir un nuevo artículo, añade sus dos llamadas httpx.get a record.py y una entrada correspondiente a relevance_scores.json (escrita a mano — no es salida real de OpenRouter, ya que grabar su respuesta cruda de chat-completion no vale la pena por la fragilidad del formato de cable; los campos estructurados {relevance, novelty, rationale} se reproducen directamente a través de un FunctionModel de PydanticAI).
Pruebas
uv run pytest custom_server/tests agent/testsTodas las llamadas de red (arXiv, OpenAlex, OpenRouter) están simuladas; no hay tráfico en vivo durante las pruebas.
Contratos de herramientas (Parte C)
search_arxiv_papers (personalizado)
Propósito | Herramienta principal de fuente de datos: busca en arXiv artículos candidatos sobre un tema. |
Descripción para el modelo | "Busca en arXiv artículos sobre un tema, opcionalmente restringido a categorías y una fecha mínima de envío. Usa esto para encontrar artículos candidatos antes de evaluarlos individualmente con score_paper_relevance. Una consulta válida que no coincide con nada devuelve una lista vacía — eso es un resultado normal, no un error." |
Entrada |
|
Salida |
|
Condiciones de error |
|
Efectos secundarios | Ninguno — GET HTTP de solo lectura a |
Ejemplo |
|
score_paper_relevance (personalizado)
Propósito | Herramienta evaluativa: juzga el ajuste temático de un candidato y si su registro de citas supera un umbral ajustado por edad. |
Descripción para el modelo | "Puntúa cuán relevante y novedoso es un artículo para un resumen de concepto, y comprueba si su impacto de citas supera un umbral mínimo (citas por año, eximiendo artículos de menos de un año). Usa esto en cada candidato de search_arxiv_papers para decidir si pertenece a una lista de lectura. Lanza un error si el artículo no tiene registro en OpenAlex, o si la llamada subyacente al modelo de puntuación de relevancia falla." |
Entrada |
|
Salida |
|
Condiciones de error |
|
Efectos secundarios | Solo lectura: una GET a OpenAlex, una llamada de chat-completion a OpenRouter. |
Ejemplo |
|
find_foundational_citations (personalizado)
Propósito | Análisis de grafo de citas: dado un artículo, ordena sus propias referencias por número de citas para destacar el trabajo consolidado sobre el que se basa. Se distingue de |
Descripción orientada al modelo | "Dado el ID de arXiv de un artículo, devuelve sus referencias más citadas — el trabajo previo consolidado sobre el que se basa. Úsalo después de seleccionar un artículo para leer, para sacar a la luz la literatura de fondo que hay detrás. Un artículo sin referencias registradas devuelve una lista vacía — eso es un resultado normal, no un error." |
Entrada |
|
Salida |
|
Condiciones de error |
|
Efectos secundarios | Solo lectura: una consulta de artículo en OpenAlex + una o más consultas por lotes de obras de OpenAlex (divididas en bloques de 50 IDs por solicitud). |
Ejemplo |
|
Obsidian Local REST API MCP (existente, Parte A)
Se usa mediante las llamadas a herramientas en lenguaje natural del agente PydanticAI (no una función envoltorio fija) para dos operaciones en el flujo:
Resolución de referencias | Antes de cualquier llamada a Obsidian, |
Lectura | Se pide al agente que lea la nota titulada |
Escritura | Se pide al agente que cree/sobrescriba una nota titulada |
Condiciones de error | Plugin detenido, clave API inválida o una nota inexistente se manifiestan como un fallo distinguible de llamada a herramienta desde el servidor MCP, no como un resultado vacío silencioso. |
Justificación del diseño
Por qué Obsidian: la tarea necesita un servidor MCP existente del que el agente tanto lea como escriba. Las notas de conceptos propias de un estudiante son una entrada natural de "lo que ya sé", y escribir los supervivientes de vuelta cierra el bucle visiblemente en la bóveda.
Por qué arXiv + OpenAlex en lugar de un sitio con muro de inicio de sesión: las fuentes consideradas originalmente (horario KSE/Moodle) requieren ambas inicio de sesión personal, lo que la regla de API pública de la tarea descarta. arXiv y OpenAlex son públicos, sin autenticación, y respaldan directamente el dominio de "relevancia + impacto".
Por qué la relevancia la juzga un LLM, no embeddings: OpenRouter no tiene endpoint de embeddings (verificado contra su catálogo de modelos en vivo), por lo que
score_paper_relevanceusa una llamada de salida estructurada de PydanticAI en lugar de similitud vectorial — reutilizando la única credencial de modelo que el proyecto ya necesita.Por qué
find_foundational_citationsno es "buscar de nuevo con OpenAlex": toma la lista de referencias de un artículo específico y la ordena por impacto de citas, el mismo tipo de comparación de indicadores controlada que usan los ejemplos de la propia tarea — responsabilidad y procesamiento distintos de la búsqueda por palabras clavesearch_arxiv_papers.El filtrado es Python simple, no una 4ª herramienta: el umbral de relevancia + filtro
impact_passenfilter_candidates_nodedeagent/graph.pyes post-procesamiento determinista sobre datos ya puntuados, no lógica de dominio nueva — una herramienta sería solo indirección alrededor de unif.Compensaciones / limitaciones: el modo offline/replay del servidor personalizado (ver "Modo offline / replay" más arriba) cubre dos artículos registrados y una búsqueda de arXiv independiente de la consulta — no una grabación/reproducción general de consultas arbitrarias. Las llamadas propias de
agent/a Obsidian y OpenRouter no se ven afectadas por él y siguen requiriendo acceso en vivo. Los umbrales de impacto/relevancia son valores de.env, no ajustables en tiempo de ejecución por solicitud.
Diferido (marcado, no descartado)
Exponer los umbrales codificados como configuración de ejecución más rica más allá de
.env.
Lista de verificación para demostración / defensa
uv run python -m custom_server.serverse inicia de forma independiente; un cliente MCP crudo conlist_toolsmuestra las 3 herramientas.uv run pytest custom_server/tests agent/tests— todo en verde, red simulada.CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.serverse inicia y sirve las 3 llamadas a herramientas sin red en vivo ni claves API requeridas (ver "Modo offline / replay").Siembra una nota de demostración en la bóveda con un resumen de concepto (p. ej. "mecanismos de atención"), titulada p. ej. "Nota de concepto sobre Transformers".
uv run python -m agent.graph "Find papers related to my 'Transformers Concept Note'"— ejecución completa en vivo: resuelve la referencia de la nota, lee la nota, busca en arXiv, puntúa candidatos, filtra, encuentra citas fundacionales, escribe"<nota> — Related Papers"de vuelta en la bóveda.Muestra ambas conexiones MCP alimentando la salida final: la nota de escritura cita tanto datos de arXiv/OpenAlex (servidor personalizado) como el contenido de la nota de concepto original (Obsidian).
Demostración de información insuficiente: ejecuta con una consulta que no nombre ninguna nota (p. ej.
"What's a transformer?") — muestra que el agente se detiene e imprime "Not enough information..." sin llamar a Obsidian. Luego ejecuta contra una nota con contenido casi vacío — muestra que se detiene después de leer la nota, antes de llamar a arXiv.Demostración de fallo, Obsidian: detén el plugin Local REST API (o usa una
OBSIDIAN_API_KEYincorrecta / un título de nota inexistente) — muestra que el agente presenta un error distinguible, no un resultado vacío silencioso.Demostración de fallo, servidor personalizado: llama a
search_arxiv_paperscon una categoría inválida, o afind_foundational_citationscon un ID de arXiv ausente en OpenAlex — muestraValueError/PaperNotFoundErrorrespectivamente, distinto de un resultado vacío válido.
Available Tools
3 toolsfind_foundational_citationsA
Given one paper's arXiv ID, return its most-cited references — the well-established prior work it builds on.
Use this after selecting a paper to read, to surface the background literature behind it. A paper with no recorded references returns an empty list — that is a normal result, not an error.
| Name | Required | Description | Default |
|---|---|---|---|
| arxiv_id | Yes | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose one important behavioral fact: an empty list is normal, not an error. It also implies a read-only operation. Yet it does not explain truncation behavior related to max_results or what the output format contains, though an output schema is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with meaningful information: what the tool returns, when to use it, and an important normalization about empty results. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description tells the agent what input is expected, when to invoke it, and how to interpret an empty result. Since an output schema exists, return-value details are covered. The main remaining gap is clarifying max_results, but the schema's default and name largely bridge that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies what arxiv_id represents (the paper's identifier), but it does not explain max_results, which limits the number of references returned. The name max_results is somewhat self-explanatory, and its default of 3 helps, but the description could have explicitly connected it to the 'most-cited' behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (return references) and resource (most-cited references for a given arXiv ID). It also conveys the purpose (surface well-established prior work), but it does not explicitly distinguish itself from sibling tools such as search_arxiv_papers or score_paper_relevance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use the tool after selecting a paper to read, which gives a clear context. However, it does not mention when not to use it or point to alternative sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
score_paper_relevanceA
Score how relevant and novel a paper is to a concept summary, and check whether its citation impact clears a minimum bar (citations per year, exempting papers younger than one year).
Use this on each candidate from search_arxiv_papers to decide whether it belongs in a reading list. Raises if the paper has no OpenAlex record, or if the underlying relevance-scoring model call fails.
| Name | Required | Description | Default |
|---|---|---|---|
| paper | Yes | ||
| concept_summary | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the behavioral burden. It discloses two error conditions (missing OpenAlex record and underlying model failure) and explains the citation-impact filtering rule, including the one-year exemption. This goes well beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries necessary content: the scoring criterion, the usage context, and the failure behavior. There is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with an output schema and sibling context, the description covers its need: why to call it, what to pass, how it decides, and what to expect when it errors.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Since schema description coverage is 0%, the description has to convey parameter meaning. It explains concept_summary as the reference for scoring and clarifies that paper is a candidate from search_arxiv_papers. It does not detail paper field internals, but those are inherited from that tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: score a paper's relevance and novelty against a concept summary, and check its citation impact. This clearly distinguishes it from search_arxiv_papers (retrieval) and find_foundational_citations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states the intended use: apply this tool to each candidate from search_arxiv_papers to decide reading-list membership. It does not explicitly name alternatives or exclusions, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_arxiv_papersA
Search arXiv for papers on a topic, optionally restricted to categories and a minimum submission date.
Use this to find candidate papers before evaluating them individually with score_paper_relevance. A valid query that matches nothing returns an empty list — that is a normal result, not an error.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| categories | No | ||
| since_date | No | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the behavioral burden. It usefully discloses that an empty result is a normal outcome, not an error. However, it adds little about other behaviors such as result ordering, matching semantics, rate limits, or external API behavior, beyond what is essentially implied by a 'Search' operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning their place: the first states the operation and optional filters, the second gives pipeline guidance, and the third normalizes an empty result. It is front-loaded and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, return values are covered. The missing context is input format guidance for categories and since_date and the behavior of max_results. The description is adequate for a basic search call but not fully self-sufficient for an agent invoking an external API it has no prior knowledge about.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate. It maps 'query' to topic, 'categories' to category restrictions, and 'since_date' to a minimum submission date. However, it does not explain expected formats for categories or since_date, and 'max_results' is never addressed, even though its name and default make its role partially inferable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Search arXiv for papers on a topic.' It also names the optional scope (categories, minimum submission date) and differentiates from the sibling by framing this as the discovery step before score_paper_relevance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs when to use it: 'Use this to find candidate papers before evaluating them individually with score_paper_relevance.' This gives a clear pipeline context. It does not explicitly mention when not to use it or how it relates to the other sibling, find_foundational_citations, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
find_foundational_citations - First observed
score_paper_relevance - First observed
search_arxiv_papers
TDQS
Scored across 3 tools
The three tools have clearly distinct roles: searching arXiv, scoring a candidate paper, and tracing foundational references. There is no meaningful overlap between discovery, evaluation, and citation expansion.
All tool names follow a clean verb_noun snake_case pattern: search_arxiv_papers, score_paper_relevance, find_foundational_citations. The naming style is predictable and signals the action clearly.
Three tools is a well-scoped size for a focused arXiv triage workflow. Each tool covers a necessary step without redundant or filler tools.
The set covers the core pipeline: find candidate papers, evaluate relevance and citation impact, then discover foundational references. Minor omissions like retrieving full paper metadata or listing available arXiv categories could be useful but do not create dead ends.
Maintenance
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
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceThis 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.3Apache 2.0
- FlicenseAqualityDmaintenanceA streamlined MCP server that connects AI assistants to arXiv's vast collection of academic papers, enabling search, retrieval, and analysis of research papers.71-
- FlicenseNot gradedqualityDmaintenanceAn 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.2-
- FlicenseNot gradedqualityCmaintenanceAn MCP server that enables AI assistants to search arXiv papers, retrieve metadata, and access PDFs.-