openalex-research-mcp
CLAUDE.md55 starsChanged 8 months agoMITView on GitHub
This file provides guidance for AI assistants (particularly Claude Code) when working with this codebase. An MCP (Model Context Protocol) server providing access to the OpenAlex API for literature review and research landscaping. Exposes 31 specialized tools through the MCP protocol, enabling AI assistants to search 240+ million scholarly works, analyze citations, track research trends, and map collaboration networks. CRITICAL: OpenAlex uses publication_year filter, NOT from_publication_date - Year ranges: publication_year:2020-2023 - From year: publication_year:>2019 (note: use year-1 to be inclusive)…
- Reads credentials
- Installs packages
- Commits and pushes
In this repositoryOne other file it gives its agents.
- openalexSkill
The file
Show its rules and text
We split this CLAUDE.md into the rules it gives an agent
23 rules. About 0 are common, 17 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈17
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 36
Only primary topic included
- Distinctive: line 41
ALL authors with positions (first, middle, last), institutions, ORCID IDs, corresponding author flags
- Distinctive: line 43
All topics (not just primary)
- Distinctive: line 45
Use this when detailed author information is needed (e.g., identifying PIs, corresponding authors)
- Very specific: line 107
Add to config (~/Library/Application Support/Claude/claude_desktop_config.json):
- Distinctive: line 122
Test with: "Find the most influential papers on AI safety published since 2020"
- Distinctive: line 162
When adding a new tool:
- Very specific: line 171
Use buildFilter(params) for year/filter handling
- Distinctive: line 182
Test with at least 2-3 parameter combinations
- Distinctive: line 184
Ensure OpenAlex API returns expected data
- Distinctive: line 188
Test with realistic queries
- Distinctive: line 189
Check debug logs for issues
- Distinctive: line 196
Run full test suite: before committing:
- Very specific: line 217
Grouped responses: When using groupBy, response includes group_by array instead of paginated results
- Very specific: line 219
Citation searching: Use filter cites:<work-id> to find citing works (forward citations)
- Very specific: line 220
Author filtering: Use authorships.author.id filter, not just author.id
- Distinctive: line 229
Overwriting filters: when both from_year and to_year provided
- Very specific: line 237
Not testing before release: - Always run npm test
- Distinctive: line 246
When users ask for "most influential," "seminal," or "highly-cited" papers:
- Distinctive: line 265
All are automatically picked up by the server on startup.
- Distinctive: line 271
When using with TypingMind, users may encounter:
- Distinctive: line 279
Start a new chat (clears conversation history)
- Distinctive: line 281
Use specific queries with filters
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Developer Guide for Claude Code
This file provides guidance for AI assistants (particularly Claude Code) when working with this codebase.
Project Overview
An MCP (Model Context Protocol) server providing access to the OpenAlex API for literature review and research landscaping. Exposes 31 specialized tools through the MCP protocol, enabling AI assistants to search 240+ million scholarly works, analyze citations, track research trends, and map collaboration networks.
Architecture
Module Structure
- OpenAlex Client Layer (
src/openalex-client.ts)- Handles HTTP communication with OpenAlex API (api.openalex.org)
- Manages rate limiting (10 req/s, 100K req/day) and 429 error handling with bounded retry
- Implements "polite pool" access via email parameter or API key
- Key methods:
getEntity(),searchEntities(),autocomplete(),getWorks(),getAuthors(), etc.
- MCP Server Layer (
src/index.ts)- Implements stdio transport for MCP protocol
- Defines 31 tools organized into 7 categories (see README for tool list)
- Contains tool handler switch block
- Supporting Modules
src/presets.ts— VENUE_PRESETS (9 journal/conference lists) and INSTITUTION_GROUPS (7 presets)src/formatters.ts— Response formatting:summarizeWork(),getFullWorkDetails(),reconstructAbstract(), etc.src/filter.ts—buildFilter()maps MCP tool params to OpenAlex filter format (exported for testing)src/config.ts— Configuration constants anddebug()helper (gated onOPENALEX_DEBUG)src/validation.ts— Zod schemas for input validation
Key Design Patterns
Response Optimization
- List operations (search, citations, etc.): Use
summarizeWork()to return compact summaries- Authors limited to first 5 (with
authors_truncatedflag) - Only primary topic included
- Abstracts truncated to 500 chars
- Typical response: ~1.7 KB per work (down from ~10+ KB)
- Authors limited to first 5 (with
- Single work retrieval (
get_work): UsegetFullWorkDetails()to return complete information- ALL authors with positions (first, middle, last), institutions, ORCID IDs, corresponding author flags
- Full abstract reconstructed from inverted index
- All topics (not just primary)
- Complete bibliographic data, funding, keywords
- Use this when detailed author information is needed (e.g., identifying PIs, corresponding authors)
Parameter Translation
Tool parameters (e.g., from_year) are mapped to OpenAlex API filter format (e.g., publication_year:>2019) in the buildFilter() helper.
CRITICAL: OpenAlex uses publication_year filter, NOT from_publication_date
- Year ranges:
publication_year:2020-2023 - From year:
publication_year:>2019(note: use year-1 to be inclusive) - To year:
publication_year:<2025
Naming Conventions: venue_* vs source_*
source_*parameters (source_name,source_issn,source_id) are used in generic search tools (search_works,get_top_cited_works,find_review_articles, etc.) where the venue filter is one of many optional filters.venue_*parameters (venue_name,venue_issn,venue_id) are used in venue-specific tools (search_works_in_venue,check_venue_quality) where the venue is the primary subject of the query.- Both map to the same OpenAlex
primary_location.source.*filters under the hood.
Other Patterns
- Type Assertion: Uses
const params = args as anyto handle MCP's unknown argument types - Citation Networks:
get_citation_networkcombines forward citations (via filtercites:id) and backward citations (fromreferenced_worksfield) - Collaborator Analysis:
get_author_collaboratorspaginates through author's works (up to 1000), then counts co-author occurrences across all authorships
Development Commands
# Install dependencies
npm install
# Build TypeScript
npm run build
# Run automated tests (REQUIRED before any release)
npm test
# Run comprehensive integration tests
npm run test:integration
# Run the server (after building)
npm start
# Development mode with auto-rebuild
npm run watchTesting
CRITICAL: Always run tests before releasing or making changes.
Automated Testing
# Quick smoke tests (~15 seconds, required before every release)
npm test
# Full integration tests (~20 seconds, for major changes)
npm run test:integrationTests automatically run before npm publish via prepublishOnly hook.
Manual Testing with MCP Clients
Claude Desktop:
- Build:
npm run build - Add to config (
~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"openalex": {
"command": "node",
"args": ["/absolute/path/to/openalex-research-mcp/build/index.js"],
"env": {
"OPENALEX_EMAIL": "your.email@example.com"
}
}
}
}- Restart Claude Desktop
- Test with: "Find the most influential papers on AI safety published since 2020"
TypingMind or other MCP clients: Same config format
Publishing to npm
ALWAYS follow this workflow:
# 1. Make changes and build
npm run build
# 2. Run tests (REQUIRED - also runs automatically on publish)
npm test
# 3. Manual test in MCP client (test 2-3 queries)
# 4. Update CHANGELOG.md with changes
# 5. Commit changes
git add .
git commit -m "Description of changes"
# 6. Check npm for existing versions to avoid conflicts
npm view openalex-research-mcp versions --json
# 7. Version bump (triggers tests again via prepublishOnly)
npm version patch # or minor/major
# 8. Push with tags (tag push triggers GitHub Actions npm publish via OIDC trusted publishing)
git push && git push --tags
# 9. Create GitHub release
gh release create v0.X.X --title "v0.X.X" --notes "Release notes"Publishing uses npm trusted publishing (OIDC) — no NPM_TOKEN secret needed. The CI workflow triggers on v* tag pushes.
Adding New Tools
When adding a new tool:
- Add tool definition to
toolsarray insrc/index.ts:name: Tool name (snake_case)description: What it does and when to use itinputSchema: JSON Schema for parameters
- Add case handler in the
switch(name)statement:- Extract parameters from
params(NOTargs) - Use
buildFilter(params)for year/filter handling - Build appropriate filters or search options
- Call OpenAlexClient methods
- Return JSON response in MCP format
- Extract parameters from
- Choose response format:
- For list operations: Use
summarizeWorksList(results) - For single work: Use
getFullWorkDetails(work)if full details needed - For other data: Return relevant fields directly
- For list operations: Use
- Add tests in
tests/quick-test.js:- Test with at least 2-3 parameter combinations
- Verify error handling
- Ensure OpenAlex API returns expected data
- Test manually in MCP client:
- Build:
npm run build - Test with realistic queries
- Check debug logs for issues
- Build:
- Update documentation:
- README.md (add to tool list with examples)
- CHANGELOG.md (document new feature)
- CLAUDE.md (if architecture changes)
- Run full test suite before committing:
npm test
OpenAlex API Quirks & Common Bugs
Critical Filter Format Issues
- MUST use
publication_yearfilter - NOTfrom_publication_dateorpublication_date- ✅ Correct:
filter=publication_year:>2019 - ❌ Wrong:
filter=from_publication_date:2020 - Year ranges:
publication_year:2020-2023 - From year:
publication_year:>2019(note: use year-1 to be inclusive) - To year:
publication_year:<2025
- ✅ Correct:
API Behavior
- Filter syntax: Multiple filters are AND by default, use
|for OR,!for NOT- Combine with comma:
filter=publication_year:2020,cited_by_count:>100
- Combine with comma:
- Identifier flexibility: Accepts OpenAlex IDs (W123), DOIs, ORCIDs, or full URLs
- Grouped responses: When using
groupBy, response includesgroup_byarray instead of paginated results - Related works: Stored as array of IDs in
related_worksfield, must fetch individually - Citation searching: Use filter
cites:<work-id>to find citing works (forward citations) - Author filtering: Use
authorships.author.idfilter, not justauthor.id - Rate limiting: 10 req/s, 100K req/day - tests include delays to respect this
Common Implementation Bugs to Avoid
- Using
argsinstead ofparamsin tool handlers- ✅ Correct:
buildFilter(params) - ❌ Wrong:
buildFilter(args)
- ✅ Correct:
- Overwriting filters when both from_year and to_year provided
- ✅ Use range format when both present
- ❌ Second assignment overwrites first
- Wrong date format - API expects years, not full dates
- ✅
publication_year:2020 - ❌
from_publication_date:2020-01-01
- ✅
- Not testing before release - Always run
npm test - Not filtering by citations for "influential papers" queries
- ✅ Use
get_top_cited_works(has default min_citations: 50) - ✅ Or add
cited_by_count: ">100"tosearch_works - ❌ Using
search_workswith only sorting returns many low-quality papers
- ✅ Use
Search Quality Best Practices
When users ask for "most influential," "seminal," or "highly-cited" papers:
- Prefer
get_top_cited_workstool: Automatically filters for papers with >= 50 citations by default - Use citation thresholds: For "very influential" papers, use
min_citations: 200or higher - Combine with year filters: Recent papers need lower thresholds (e.g., 50+ for 2020+, 200+ for pre-2020)
- Query specificity matters: Generic queries return many irrelevant results; use specific terms
Example queries:
- ❌ Bad:
search_works(query="AI safety", sort="cited_by_count")→ Returns 97K papers including unrelated results - ✅ Good:
get_top_cited_works(query="AI safety alignment ethics", from_year=2020)→ Returns 261 papers, all with 50+ citations - ✅ Better:
get_top_cited_works(query="AI safety alignment ethics", from_year=2020, min_citations=200)→ Returns 47 highly influential papers
Environment Variables
OPENALEX_EMAIL: Email for polite pool (better rate limits)OPENALEX_API_KEY: Premium API key (optional)MCP_DEFAULT_PAGE_SIZE: Default number of results per page (default: 10). Set to a lower value (e.g., 5) if experiencing context overflow errors in MCP clients.OPENALEX_DEBUG: Set to1ortrueto enable verbose debug logging to stderr. Off by default in production.
All are automatically picked up by the server on startup.
Known Issues
TypingMind "tool_use_id" Errors
When using with TypingMind, users may encounter:
Request failed. Error details: messages.0.content.0: unexpected `tool_use_id` found in `tool_result` blocksThis is caused by conversation history becoming too large or TypingMind's MCP adapter having protocol translation issues. See TYPINGMIND.md for detailed troubleshooting.
Quick fixes:
- Start a new chat (clears conversation history)
- Request fewer results (5-10 instead of 10-25)
- Use specific queries with filters
- Set
MCP_DEFAULT_PAGE_SIZE=5in environment
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

