Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

Access the OpenAlex academic research catalog - 270M+ publications via MCP. STDIO & HTTP.

README.md

<div align="center"> <h1>@cyanheads/openalex-mcp-server</h1> <p><b>Access the OpenAlex academic research catalog - 270M+ publications through MCP. STDIO & Streamable HTTP.</b> <div>5 Tools &bull; 2 Prompts</div> </p> </div>

<div align="center">

![Version](./CHANGELOG.md) ![License](./LICENSE) ![Docker](https://github.com/users/cyanheads/packages/container/package/openalex-mcp-server) ![MCP SDK](https://modelcontextprotocol.io/) ![npm](https://www.npmjs.com/package/@cyanheads/openalex-mcp-server) ![TypeScript](https://www.typescriptlang.org/) ![Bun](https://bun.sh/)

</div>

<div align="center">

![Install in Claude Desktop](https://github.com/cyanheads/openalex-mcp-server/releases/latest/download/openalex-mcp-server.mcpb) ![Install in Cursor](https://cursor.com/en/install-mcp?name=openalex-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvb3BlbmFsZXgtbWNwLXNlcnZlciJdfQ==) ![Install in VS Code](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22openalex-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads/openalex-mcp-server%22%5D%7D)

![Framework](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)

</div>

<div align="center">

Public Hosted Server: https://openalex.caseyjhand.com/mcp

</div>

---

Tools

Five tools for querying the OpenAlex academic research catalog:

| Tool Name | Description | |:----------|:------------| | openalex_search_entities | Search, filter, sort, or retrieve by ID across all 8 entity types. | | openalex_analyze_trends | Group-by aggregation for trend and distribution analysis. | | openalex_resolve_name | Resolve a name or an identifier (DOI, ORCID, ROR, PMID, PMCID, ISSN, OpenAlex ID) to an OpenAlex ID. | | openalex_get_citation_graph | Walk the citation graph one hop from a seed work: cites, cited_by, or related_to. | | openalex_describe_fields | List valid filter, group_by, and select field names for an entity type — call before building a query to avoid invalid-field errors. |

openalex_search_entities

Primary discovery and lookup tool. Covers all OpenAlex entity types (works, authors, sources, institutions, topics, keywords, publishers, funders).

  • Retrieve a single entity by ID (OpenAlex ID, DOI, ORCID, ROR, PMID, PMCID, ISSN). id takes precedence: search criteria passed alongside it are not applied, and the response says which ones were dropped rather than echoing them back as though they ran. The search-only validations (semantic page cap, sample with cursor, seed without sample) are skipped too — a lookup is never rejected over parameters it ignores
  • Keyword search with boolean operators, quoted phrases, wildcards, and fuzzy matching
  • Exact and AI semantic search modes
  • Rich filter syntax: AND across fields, OR within fields (us|gb), NOT (!us), ranges (2020-2024), comparisons (>100)
  • Sensible default field selection per entity type, applied to both searches and ID lookups — prevents oversized responses; pass select to choose fields, or ["*"] for the full record
  • Invalid select field names produce an error listing the valid fields for that entity type
  • Formatted MCP output is a generic markdown renderer — every returned field is surfaced without per-entity-type hard-coding
  • Cursor pagination and up to 100 results per page; sort takes a single key or a comma-separated list, with the - descending prefix applied per key
  • display_name is nullable — OpenAlex holds no title for paratext and other untitled records, which pass through instead of failing the whole page

---

openalex_analyze_trends

Aggregate entities into groups and count them for trend, distribution, and comparative analysis.

  • Group by any supported field (publication year, OA status, institution, country, topic, etc.)
  • Combine with filters to scope the population before aggregation
  • Up to 200 groups per page with cursor pagination
  • Supports include_unknown to show entities with no value for the grouped field

---

openalex_resolve_name

The front door for turning anything you have into an OpenAlex ID. Always use this before filtering by entity — names are ambiguous, IDs are not.

  • A name or partial name runs an autocomplete search: up to 10 matches with disambiguation hints, ~200ms
  • An identifier resolves deterministically to the single record it addresses — OpenAlex ID, DOI, ORCID, ROR, PMID, PMCID, or ISSN, bare or in URL form. No entity_type needed: the identifier determines its own
  • An identifier that matches nothing returns an empty result naming the scheme, not name-search advice
  • Optional entity type filter and field-level filters, applied to name queries

---

openalex_get_citation_graph

One-hop citation graph traversal from a seed work. Wraps the OpenAlex cites/cited_by/related_to filters behind an explicit direction argument so callers do not have to know the filter names.

  • cites: works that cite the seed (incoming citations)
  • cited_by: works the seed cites (its reference list)
  • related_to: OpenAlex algorithmic "related works" (~8-30 typical, may be empty for less-cited seeds)
  • Accepts OpenAlex IDs, DOIs, PMIDs, PMCIDs as seed_id; validates the seed via a singleton /works/{id} lookup before walking, so non-existent seeds surface as NotFound
  • Stacks with filters/sort/select to narrow the graph (e.g., publication_year=">2020", is_oa="true")

---

openalex_describe_fields

Discover valid field names before constructing a query — avoids invalid-field 400 errors. Backed by a catalog generated from OpenAlex's own field validation.

  • List valid fields for any entity type and context (filter, group_by, or select)
  • group_by returns the subset of the filter set OpenAlex can aggregate — raw date fields, .search operators, and from_/to_* range modifiers are excluded
  • Pass query (a partial or guessed name) to rank results by name similarity — surfaces the right field when you only know roughly what you want
  • Complements the ranked "did you mean" suggestions now appended to invalid-field errors on the search, trends, and citation-graph tools

Prompts

| Prompt | Description | |:-------|:------------| | openalex_literature_review | Guides a systematic literature search: formulate query, search, filter, analyze citation network, synthesize findings. | | openalex_research_landscape | Analyzes the research landscape for a topic: volume trends, top authors/institutions, open access rates, funding sources. |

Features

Built on @cyanheads/mcp-ts-core:

  • Declarative tool definitions — single file per tool, framework handles registration and validation
  • Unified error handling across all tools
  • Pluggable auth (none, jwt, oauth)
  • Swappable storage backends via the framework (not currently used by this server)
  • Structured logging with optional OpenTelemetry tracing
  • Runs locally (stdio/HTTP) or in Docker from the same codebase

OpenAlex-specific:

  • Typed API client with automatic ID normalization (DOI, ORCID, ROR, PMID, PMCID, ISSN, OpenAlex URLs)
  • Abstract reconstruction from inverted indices — plaintext instead of OpenAlex's position-keyed encoding
  • HTTP status codes mapped to specific MCP error classes (400 → InvalidParams, 422 → ValidationError, 429 → RateLimited, etc.) with upstream messages surfaced
  • Every API-calling tool reports what the call spent against the OpenAlex daily budget and what is left of it, so a paginated sweep can be priced before it runs instead of ending in a 429. An account holding prepaid balance sees that too, since it keeps serving once the day's allowance is gone
  • Timeout-aware request retries and cancellation support via AbortSignal

Getting Started

Public Hosted Instance

A public instance is available at https://openalex.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:

{
  "mcpServers": {
    "openalex-mcp-server": {
      "type": "streamable-http",
      "url": "https://openalex.caseyjhand.com/mcp"
    }
  }
}

Self-Hosted / Local

Add to your MCP client config (e.g., claude_desktop_config.json):

{
  "mcpServers": {
    "openalex-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/openalex-mcp-server"],
      "env": {
        "OPENALEX_API_KEY": "your-openalex-api-key"
      }
    }
  }
}

OPENALEX_API_KEY is optional — set it to a free OpenAlex account key for keyed rate limits and budget under OpenAlex's usage-based pricing, or omit it for anonymous access. Set OPENALEX_MAILTO to an email if you want to identify yourself to OpenAlex (the polite pool).

Prerequisites

Installation

  1. Clone the repository:
git clone https://github.com/cyanheads/openalex-mcp-server.git
  1. Navigate into the directory:
cd openalex-mcp-server
  1. Install dependencies:
bun install

Configuration

| Variable | Description | Default | |:---------|:------------|:--------| | OPENALEX_API_KEY | Optional. OpenAlex account API key, sent upstream as api_key= (free from openalex.org/settings/api). Without it, anonymous rate limits apply. | — | | OPENALEX_MAILTO | Optional. Email sent upstream as mailto= to identify yourself to OpenAlex (the polite pool). A courtesy identifier, separate from the API key. | — | | OPENALEX_BASE_URL | OpenAlex API base URL. | https://api.openalex.org | | MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio | | MCP_HTTP_PORT | Port for HTTP server. | 3010 | | MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none | | MCP_ALLOWED_ORIGINS | Comma-separated allow-list of browser Origin headers for HTTP transport. Unset = loopback-only; set to * to disable. | _loopback only_ | | MCP_LOG_LEVEL | Log level (RFC 5424). | debug | | LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs | | OTEL_ENABLED | Enable OpenTelemetry instrumentation (spans, metrics, completion logs). | false |

Running the Server

Local Development

  • Build and run the production version:
  bun run build
  bun run start:http   # or start:stdio
  • Run checks and tests:
  bun run devcheck     # Lints, formats, type-checks
  bun run test         # Runs test suite

Docker

docker build -t openalex-mcp-server .
docker run -e OPENALEX_API_KEY=your-key -p 3010:3010 openalex-mcp-server

Project Structure

| Directory | Purpose | |:----------|:--------| | src/mcp-server/tools/definitions/ | Tool definitions (.tool.ts). | | src/mcp-server/prompts/definitions/ | Prompt definitions (.prompt.ts). | | src/services/openalex/ | OpenAlex API client service and domain types. | | src/config/ | Environment variable parsing and validation with Zod. | | tests/ | Unit and integration tests, mirroring the src/ structure. |

Development Guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for logging, ctx.state for storage
  • Always resolve names to IDs via openalex_resolve_name before using them in filters

Contributing

Issues and pull requests are welcome. Run checks before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Search servers.