@futurelab-studio/latest-science-mcp
Version:
MCP Server for Scientific Paper Harvesting from arXiv and OpenAlex
428 lines (334 loc) • 11.8 kB
Markdown
# 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