npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cyanheads/openalex-mcp-server

v0.7.4

Published

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

Readme

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

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


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 partial name to an OpenAlex ID via autocomplete. | | 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)
  • 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, sorting, up to 100 results per 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

Name-to-ID resolution via autocomplete. Always use this before filtering by entity — names are ambiguous, IDs are not.

  • Returns up to 10 matches with disambiguation hints
  • Accepts partial names and DOIs for direct lookup
  • Optional entity type filter and field-level filters
  • ~200ms response time

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 resolves to the same valid-field set as filter
  • 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/422 → InvalidParams, 429 → RateLimited, etc.) with upstream messages surfaced
  • 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.