Skip to main content
Glama

arXiv MCP Server

by 1Dark134
client.pyβ€’7.06 kB
import asyncio import json import logging from typing import Any, Dict, List, Optional, Sequence from urllib.parse import quote_plus import xml.etree.ElementTree as ET import httpx from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from mcp.types import ( CallToolRequest, GetPromptRequest, ListPromptsRequest, ListResourcesRequest, ListToolsRequest, ReadResourceRequest, Resource, TextContent, Tool, ) # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class ArxivMCPClient: """MCP Client for interacting with arXiv API""" def __init__(self): self.session: Optional[ClientSession] = None self.http_client = httpx.AsyncClient(timeout=30.0) self.base_url = "https://export.arxiv.org/api/query" #"http://export.arxiv.org/api/query" async def connect(self, server_script_path: str): """Connect to the MCP server""" server_params = StdioServerParameters( command="python", args=[server_script_path] ) stdio_transport = await stdio_client(server_params) self.session = ClientSession(stdio_transport[0], stdio_transport[1]) # Initialize the session await self.session.initialize() logger.info("Connected to arXiv MCP server") async def list_tools(self) -> List[Tool]: """List available tools from the MCP server""" if not self.session: raise RuntimeError("Not connected to server") response = await self.session.list_tools(ListToolsRequest()) return response.tools async def search_papers(self, query: str, max_results: int = 10) -> Dict[str, Any]: """Search for papers on arXiv""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="search_arxiv", arguments={ "query": query, "max_results": max_results } ) response = await self.session.call_tool(request) return json.loads(response.content[0].text) if response.content else {} async def get_paper_details(self, arxiv_id: str) -> Dict[str, Any]: """Get detailed information about a specific paper""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="get_paper", arguments={"arxiv_id": arxiv_id} ) response = await self.session.call_tool(request) return json.loads(response.content[0].text) if response.content else {} async def get_paper_summary(self, arxiv_id: str) -> str: """Get a formatted summary of a paper""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="summarize_paper", arguments={"arxiv_id": arxiv_id} ) response = await self.session.call_tool(request) return response.content[0].text if response.content else "" async def search_by_author(self, author_name: str, max_results: int = 20) -> Dict[str, Any]: """Search for papers by a specific author""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="search_by_author", arguments={"author_name": author_name, "max_results": max_results} ) response = await self.session.call_tool(request) return json.loads(response.content[0].text) if response.content else {} async def search_by_category(self, category: str, max_results: int = 20, sort_by: str = "submittedDate") -> Dict[str, Any]: """Search for papers in a specific category""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="search_by_category", arguments={"category": category, "max_results": max_results, "sort_by": sort_by} ) response = await self.session.call_tool(request) return json.loads(response.content[0].text) if response.content else {} async def get_recent_papers(self, category: str = "", days_back: int = 7, max_results: int = 15) -> Dict[str, Any]: """Get recent papers""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="get_recent_papers", arguments={"category": category, "days_back": days_back, "max_results": max_results} ) response = await self.session.call_tool(request) return json.loads(response.content[0].text) if response.content else {} async def compare_papers(self, arxiv_ids: List[str], comparison_fields: List[str] = None) -> str: """Compare multiple papers""" if not self.session: raise RuntimeError("Not connected to server") if comparison_fields is None: comparison_fields = ["authors", "categories", "abstract", "published"] request = CallToolRequest( name="compare_papers", arguments={"arxiv_ids": arxiv_ids, "comparison_fields": comparison_fields} ) response = await self.session.call_tool(request) return response.content[0].text if response.content else "" async def find_related_papers(self, arxiv_id: str, max_results: int = 10) -> Dict[str, Any]: """Find papers related to a given paper""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="find_related_papers", arguments={"arxiv_id": arxiv_id, "max_results": max_results} ) response = await self.session.call_tool(request) return json.loads(response.content[0].text) if response.content else {} async def export_papers(self, arxiv_ids: List[str], format: str = "bibtex", include_abstract: bool = True) -> str: """Export papers in various formats""" if not self.session: raise RuntimeError("Not connected to server") request = CallToolRequest( name="export_papers", arguments={"arxiv_ids": arxiv_ids, "format": format, "include_abstract": include_abstract} ) response = await self.session.call_tool(request) return response.content[0].text if response.content else "" async def list_resources(self) -> List[Resource]: """List available resources""" if not self.session: raise RuntimeError("Not connected to server") response = await self.session.list_resources(ListResourcesRequest()) return response.resources async def close(self): """Close the connection""" if self.http_client: await self.http_client.aclose() if self.session: await self.session.close()

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/1Dark134/arxiv-mcp-server'

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