UNPKG

@futurelab-studio/latest-science-mcp

Version:

MCP Server for Scientific Paper Harvesting from arXiv and OpenAlex

428 lines (334 loc) 11.8 kB
# Scientific Paper Harvester MCP Server A Model Context Protocol (MCP) server that provides LLMs with real-time access to scientific papers from arXiv and OpenAlex. ## Features - **Paper Fetching**: Get latest papers from arXiv and OpenAlex by category/concept - **Text Extraction**: Full text content extraction from HTML sources (arXiv and OpenAlex) - **Citation Analysis**: Find top cited papers from OpenAlex since a specific date - **Paper Lookup**: Retrieve full metadata for specific papers by ID - **Category Listing**: Browse available categories from arXiv and OpenAlex - **Rate Limiting**: Respectful API usage with per-source rate limiting (5 req/min arXiv, 10 req/min OpenAlex) - **Dual Interface**: Both MCP protocol and CLI access - **TypeScript**: Full type safety with ESM modules ## Installation ```bash npm install npm run build ``` ## MCP Client Configuration To use this server with an MCP client (like Claude Desktop), add the following to your MCP client configuration: ### For published package (available on npm): **Option 1: Using npx (simplest)** ```json { "mcpServers": { "scientific-papers": { "command": "npx", "args": [ "-y", "@futurelab-studio/latest-science-mcp" ] } } } ``` **Option 2: Global installation** ```bash npm install -g @futurelab-studio/latest-science-mcp ``` Then configure: ```json { "mcpServers": { "scientific-papers": { "command": "latest-science-mcp" } } } ``` **Option 3: For Windows/NVM users (if npx doesn't work)** Find your global npm path: ```bash npm root -g ``` Then use absolute paths: ```json { "mcpServers": { "scientific-papers": { "command": "node", "args": [ "C:/path/to/node_modules/@futurelab-studio/latest-science-mcp/dist/server.js" ] } } } ``` ### For local development: ```json { "mcpServers": { "scientific-papers": { "command": "node", "args": [ "dist/server.js" ], "cwd": "/path/to/your/MCP-tutorial" } } } ``` **Note:** Replace `/path/to/your/MCP-tutorial` with the actual path to your project directory. ## Usage ### CLI Interface #### List Categories ```bash # List arXiv categories node dist/cli.js list-categories --source=arxiv # List OpenAlex concepts node dist/cli.js list-categories --source=openalex ``` #### Fetch Latest Papers ```bash # Get latest 10 AI papers from arXiv node dist/cli.js fetch-latest --source=arxiv --category=cs.AI --count=10 # Get latest 5 computer science papers from OpenAlex node dist/cli.js fetch-latest --source=openalex --category=C41008148 --count=5 # Search by concept name (OpenAlex) node dist/cli.js fetch-latest --source=openalex --category="machine learning" --count=3 ``` #### Fetch Top Cited Papers ```bash # Get top 20 cited papers in machine learning since 2024 node dist/cli.js fetch-top-cited --concept="machine learning" --since=2024-01-01 --count=20 # Get top cited papers by concept ID node dist/cli.js fetch-top-cited --concept=C41008148 --since=2023-06-01 --count=10 ``` #### Fetch Specific Paper ```bash # Get arXiv paper by ID node dist/cli.js fetch-content --source=arxiv --id=2401.12345 # Get OpenAlex paper by Work ID node dist/cli.js fetch-content --source=openalex --id=W2741809807 # Show text content with preview node dist/cli.js fetch-content --source=arxiv --id=2401.12345 --show-text --text-preview=500 # Show full text content node dist/cli.js fetch-latest --source=arxiv --category=cs.AI --count=2 --show-text ``` #### CLI Text Display Options ```bash # Show text extraction status (default) node dist/cli.js fetch-latest --source=arxiv --category=cs.AI --count=3 # Display full text content node dist/cli.js fetch-latest --source=arxiv --category=cs.AI --count=2 --show-text # Display text preview (first 500 characters) node dist/cli.js fetch-content --source=arxiv --id=2401.12345 --show-text --text-preview=500 ``` ### MCP Server Start the MCP server: ```bash node dist/server.js ``` The server accepts MCP protocol calls via stdio transport. ## Available Tools ### `list_categories` Lists available categories/concepts from a data source. **Parameters:** - `source`: `"arxiv"` or `"openalex"` **Returns:** - Array of category objects with `id`, `name`, and optional `description` **Example:** ```json { "name": "list_categories", "arguments": { "source": "arxiv" } } ``` ### `fetch_latest` Fetches the latest papers from arXiv or OpenAlex for a given category with **metadata only** (no text extraction). **Parameters:** - `source`: `"arxiv"` or `"openalex"` - `category`: Category ID (e.g., "cs.AI" for arXiv, "C41008148" for OpenAlex) or concept name - `count`: Number of papers to fetch (default: 50, max: 200) **Returns:** - Array of paper objects with metadata (id, title, authors, date, pdf_url) - **Text field**: Empty string (`text: ""`) - use `fetch_content` for full text **Workflow:** This tool is designed for browsing and discovery. Use it to find interesting papers, then call `fetch_content` for specific papers you want to read in full. **Examples:** ```json { "name": "fetch_latest", "arguments": { "source": "arxiv", "category": "cs.AI", "count": 10 } } ``` ```json { "name": "fetch_latest", "arguments": { "source": "openalex", "category": "artificial intelligence", "count": 5 } } ``` ### `fetch_top_cited` Fetches the top cited papers from OpenAlex for a given concept since a specific date with **metadata only** (no text extraction). **Parameters:** - `concept`: Concept name or OpenAlex concept ID (e.g., "machine learning", "C41008148") - `since`: Start date in YYYY-MM-DD format - `count`: Number of papers to fetch (default: 50, max: 200) **Returns:** - Array of paper objects sorted by citation count (descending) with metadata only - **Text field**: Empty string (`text: ""`) - use `fetch_content` for full text **Workflow:** Use this to discover influential papers by citation count, then call `fetch_content` for papers you want to read. **Example:** ```json { "name": "fetch_top_cited", "arguments": { "concept": "machine learning", "since": "2024-01-01", "count": 20 } } ``` ### `fetch_content` Fetches full metadata and text content for a specific paper by ID from arXiv or OpenAlex with **complete text extraction**. **Parameters:** - `source`: `"arxiv"` or `"openalex"` - `id`: Paper ID (arXiv ID like "2401.12345" or OpenAlex Work ID like "W2741809807") - **Flexible ID Format**: Accepts both strings and numbers - **Auto-normalization**: Numeric IDs are automatically converted to proper format (e.g., `2741809807` → `"W2741809807"` for OpenAlex) **Returns:** - Single paper object with full metadata and extracted text content **Text Extraction:** - **arXiv**: Extracts text from HTML version at `arxiv.org/html/{id}` with fallback to `ar5iv.labs.arxiv.org` - **OpenAlex**: Extracts text from HTML sources when `source_type="html"` is available - **Graceful degradation**: Returns metadata even if text extraction fails **Examples:** ```json { "name": "fetch_content", "arguments": { "source": "arxiv", "id": "2401.12345" } } ``` ```json { "name": "fetch_content", "arguments": { "source": "openalex", "id": "W2741809807" } } ``` ```json { "name": "fetch_content", "arguments": { "source": "openalex", "id": 2741809807 } } ``` ## Paper Metadata Format All tools return paper objects with the following structure: ```typescript { id: string; // Paper ID title: string; // Paper title authors: string[]; // List of author names date: string; // Publication date (ISO format) pdf_url?: string; // PDF URL (if available) text: string; // Extracted full text content textTruncated?: boolean; // Warning: text was truncated due to size limits textExtractionFailed?: boolean; // Warning: text extraction failed } ``` ### Text Extraction Details - **Text Content**: The `text` field contains the full extracted text from HTML sources - **Size Limits**: Text is limited to 6MB to fit within 8MB response limits - **Truncation**: When text exceeds limits, it's truncated at word boundaries with `textTruncated: true` - **Extraction Failures**: When text extraction fails, `textExtractionFailed: true` is set and `text` is empty - **Graceful Degradation**: Papers are always returned with metadata even if text extraction fails ## Development ### Build ```bash npm run build ``` ### Test ```bash # Test CLI commands node dist/cli.js list-categories --source=arxiv node dist/cli.js fetch-latest --source=arxiv --category=cs.AI --count=3 node dist/cli.js fetch-top-cited --concept="artificial intelligence" --since=2024-01-01 --count=5 node dist/cli.js fetch-content --source=arxiv --id=2401.12345 # Test MCP server node test-mcp.js ``` ### Exploratory Testing Test the MCP server with the proxy: ```bash npx @srbhptl39/mcp-superassistant-proxy@latest --config ./mcpconfig.json ``` ## Architecture - **TypeScript + ESM**: Modern JavaScript with full type safety - **Text Extraction Pipeline**: HTML parsing and cleaning using cheerio with fallback mechanisms - **Rate Limiting**: Token bucket algorithm per data source (5 req/min arXiv, 10 req/min OpenAlex) - **Modular Design**: Clean separation between drivers, extractors, tools, and core services - **Error Handling**: Structured error responses with actionable suggestions - **Graceful Degradation**: Always returns metadata even when text extraction fails - **Response Size Management**: Automatic truncation and warnings for large content ## API Sources - **arXiv**: Papers and categories from arXiv API - Search by category (e.g., cs.AI, physics.gen-ph) - Sorted by submission date (latest first) - Individual paper lookup by arXiv ID - **OpenAlex**: Papers and concepts from OpenAlex API - Search by concept ID or name - Citation data and sorting by citation count - Individual paper lookup by Work ID - Rich metadata including author affiliations ## Text Extraction Sources ### arXiv Text Extraction - **Primary Source**: `https://arxiv.org/html/{paper_id}` - **Fallback Source**: `https://ar5iv.labs.arxiv.org/html/{paper_id}` (when primary fails) - **Content**: LaTeX-rendered HTML with mathematical formulas and structured content - **Success Rate**: ~90% for papers with HTML versions available - **Limitations**: Some older papers may not have HTML versions ### OpenAlex Text Extraction - **Source**: Papers with `primary_location.source_type == "html"` - **Content**: Full-text HTML from publisher websites and repositories - **Success Rate**: Varies by publisher and access policies - **Limitations**: - Only extracts from HTML sources (PDF extraction not included in MVP) - Depends on publisher providing HTML access - Some papers may be behind paywalls ### Text Processing - **HTML Cleaning**: Removes navigation, headers, footers, and non-content elements - **Text Normalization**: Standardizes whitespace, line breaks, and formatting - **Content Extraction**: Focuses on main article content using academic paper selectors - **Size Management**: Automatic truncation at 6MB with word boundary preservation ## Rate Limiting The server implements respectful rate limiting: - **arXiv**: 5 requests per minute (per arXiv guidelines) - **OpenAlex**: 10 requests per minute (conservative limit) Rate limits are enforced per source and shared across all tools. ## Error Handling The server provides detailed error messages for common issues: - Invalid paper IDs - Rate limiting (with retry-after information) - API timeouts and server errors - Invalid date formats - Missing required parameters ## License MIT