Skip to main content

MCP server wrapping the Crossref REST API for scholarly metadata.

Project description

crossref-mcp

CI License: MIT Docker

English | 中文

An MCP server wrapping the Crossref REST API, exposing scholarly-metadata lookups (works, members, journals, funders, types, licenses, prefixes) as tools an LLM client can call.

Not affiliated with or endorsed by Crossref. Data is served live from the public Crossref API. Set CROSSREF_MAILTO to join Crossref's polite pool.

Features

  • All major Crossref resource endpoints as 18 read-only tools.
  • Dual transport: stdio (local) and Streamable HTTP (container).
  • Polite pool (User-Agent + mailto), optional Crossref Plus token.
  • Token-bucket rate limiting (auto-tuned from X-Rate-Limit-* headers) with exponential backoff honoring Retry-After.
  • Cursor deep paging, field select, raw vs simplified output.
  • Optional X-API-Key HTTP auth (/health exempt), /health endpoint.
  • Optional Redis response cache + cross-replica rate limiting.
  • Optional Caddy TLS reverse proxy for public deployment.

Quick start (local, stdio)

uv sync
export CROSSREF_MAILTO="you@example.com"   # recommended (polite pool)
uv run crossref-mcp                         # starts a stdio MCP server

Inspect with the MCP Inspector: uv run mcp dev src/crossref_mcp/server.py.

Configuration

Env var Required Default Description
CROSSREF_MAILTO recommended Email for Crossref's polite pool.
CROSSREF_PLUS_TOKEN no Crossref Plus API token (sent as a header).
CROSSREF_BASE_URL no https://api.crossref.org API base URL.
CROSSREF_TIMEOUT no 30 Per-request timeout (seconds).
MCP_TRANSPORT no stdio stdio or http.
MCP_API_KEY no If set, HTTP requests need a matching X-API-Key header (/health exempt).
LOG_LEVEL no INFO Log level (logs go to stderr).
REDIS_URL no Enable Redis cache + shared rate limiting (optional).
CACHE_TTL no 86400 Cache TTL in seconds.
RATELIMIT_BACKEND no in-memory in-memory or redis.

Tools

Workssearch_works, get_work (by DOI), get_work_references (capped at 50), get_work_quality (registration agency). Members / Journals / Funderssearch_members · get_member · get_member_works; search_journals · get_journal (ISSN) · get_journal_works; search_funders · get_funder · get_funder_works. Types / Licenses / Prefixeslist_types · get_type; list_licenses; get_prefix. Plus ping.

Shared parameters. Search/list tools take query (and query_bibliographic / query_author / query_title on works), filter (Crossref key:value,… syntax), sort + order, rows (≤1000) + offset, and select. Deep paging: set cursor="*" then reuse the returned next_cursor. All tools return simplified fields by default; pass raw=true for the full Crossref JSON.

Connecting an MCP client

stdio (Claude Desktop / Cursor)claude_desktop_config.json:

{
  "mcpServers": {
    "crossref": {
      "command": "uvx",
      "args": ["crossref-mcp"],
      "env": { "CROSSREF_MAILTO": "you@example.com" }
    }
  }
}

Or run the container over stdio: "command": "docker", "args": ["run", "-i", "--rm", "-e", "CROSSREF_MAILTO", "heyinnaneo/crossref-mcp"].

Streamable HTTP — once the container is up, point an HTTP-capable client at http://localhost:8000/mcp. If MCP_API_KEY is set, send it as X-API-Key.

Docker / HTTP deployment

cp .env.example .env          # set CROSSREF_MAILTO
docker compose up -d          # pulls heyinnaneo/crossref-mcp, HTTP on :8000
curl http://localhost:8000/health

Serves Streamable HTTP at /mcp and /health (compose health check). Set MCP_API_KEY to require X-API-Key on /mcp. To build locally, uncomment build: . in docker-compose.yml.

Public deployment (TLS / reverse proxy) — optional

Put it behind the bundled Caddy proxy (Caddyfile + docker-compose.proxy.yml): TLS termination (auto Let's Encrypt), HTTP→HTTPS, SSE streaming, backend not published on the host.

cp .env.example .env   # add DOMAIN=, ACME_EMAIL=, MCP_API_KEY=
docker compose -f docker-compose.proxy.yml up -d
curl https://your-domain/health

Defense in depth: proxy edge (optional IP allowlist / Basic auth) + MCP_API_KEY app layer; both leave /health open. Needs a domain with DNS pointing at the host and ports 80/443 reachable. Caddy rate limiting needs the caddy-ratelimit plugin (custom build).

Redis cache + cross-replica rate limiting — optional

Set REDIS_URL for a response cache (cache-aside on the raw envelope; mailto/ secrets excluded from keys) and, with RATELIMIT_BACKEND=redis, a shared token bucket so replicas stay within Crossref's polite-pool rate.

docker compose -f docker-compose.redis.yml up -d
curl http://localhost:8000/health   # cache_enabled + ratelimit_backend + redis: up

Redis failures degrade gracefully (no cache, in-memory limiting); /health stays 200 with redis: down.

CI / publishing

.github/workflows/ci.yml: test (ruff + format + pytest with coverage on every push/PR), security (Trivy fs scan), build-push (multi-arch image to heyinnaneo/crossref-mcp on main / v* tags), and on tags publish-pypi (OIDC Trusted Publisher) + publish-registry (MCP registry).

Repository secrets (Settings → Secrets and variables → Actions): DOCKERHUB_USERNAME = heyinnaneo, DOCKERHUB_TOKEN = a Docker Hub Access Token (Read/Write). Tag a release (git tag v0.1.0 && git push origin v0.1.0); the tag must match pyproject.toml.

Install from the MCP registry

Published as io.github.jtl-neo/crossref-mcp (see server.json), with a PyPI package (uvx crossref-mcp) and an OCI image. Publishing is automated on version tags (publish-pypi + publish-registry); requires a public repo and a configured PyPI Trusted Publisher.

Security & trust

  • Read-only. Every tool is a lookup, annotated readOnlyHint.
  • Rate limiting. Single-process in-memory by default — don't run as a public proxy for heavy traffic; for replicas use RATELIMIT_BACKEND=redis.
  • Polite pool. Use your own CROSSREF_MAILTO.
  • Public HTTP. Set MCP_API_KEY and front with TLS.
  • No bundled secrets. .env is excluded from image and git.

License

MIT. Bibliographic data comes from the public Crossref REST API; not affiliated with Crossref.


中文

English | 中文

Crossref REST API 封裝成 MCP server,將學術文獻 metadata 查詢(works、members、journals、funders、types、 licenses、prefixes)包成 LLM client 可呼叫的工具。

非 Crossref 官方、未經其背書。資料即時取自公開的 Crossref API。請設定 CROSSREF_MAILTO 以加入 Crossref 的 polite pool

特色

  • 主要 Crossref 資源端點,共 18 個唯讀工具
  • 雙傳輸:stdio(本機)與 Streamable HTTP(容器)。
  • Polite pool(User-Agent + mailto)、可選 Crossref Plus token。
  • Token-bucket 速率控制(依 X-Rate-Limit-* header 自動調整),429 指數退避並 尊重 Retry-After
  • cursor 深分頁、欄位 selectraw 與精簡輸出切換。
  • 可選 X-API-Key HTTP 認證(/health 豁免)、/health 端點。
  • 可選 Redis 回應快取 + 跨副本速率控制。
  • 可選 Caddy TLS 反向代理,供公開部署。

快速開始(本機 stdio)

uv sync
export CROSSREF_MAILTO="you@example.com"   # 建議(polite pool)
uv run crossref-mcp                         # 啟動 stdio MCP server

用 MCP Inspector 檢視:uv run mcp dev src/crossref_mcp/server.py

設定

環境變數 必填 預設 說明
CROSSREF_MAILTO 建議 Crossref polite pool 用的 email。
CROSSREF_PLUS_TOKEN Crossref Plus API token(以 header 送出)。
CROSSREF_BASE_URL https://api.crossref.org API base URL。
CROSSREF_TIMEOUT 30 每請求逾時(秒)。
MCP_TRANSPORT stdio stdiohttp
MCP_API_KEY 設了則 HTTP 請求需帶相符的 X-API-Key header(/health 豁免)。
LOG_LEVEL INFO 日誌層級(日誌走 stderr)。
REDIS_URL 啟用 Redis 快取 + 共享速率控制(選用)。
CACHE_TTL 86400 快取 TTL(秒)。
RATELIMIT_BACKEND in-memory in-memoryredis

工具

Workssearch_worksget_work(依 DOI)、get_work_references(上限 50)、get_work_quality(註冊機構)。 Members / Journals / Funderssearch_membersget_memberget_member_workssearch_journalsget_journal(ISSN)/get_journal_workssearch_fundersget_funderget_funder_worksTypes / Licenses / Prefixeslist_typesget_typelist_licensesget_prefix。另有 ping

共用參數。 搜尋/列表工具接受 query(works 另有 query_bibliographicquery_authorquery_title)、filter(Crossref key:value,… 語法)、sort

  • orderrows(≤1000)+ offsetselect。深分頁:設 cursor="*",再把回傳 的 next_cursor 傳回續抓。所有工具預設回精簡欄位;傳 raw=true 取完整 Crossref JSON。

連接 MCP client

stdio(Claude Desktop / Cursor)claude_desktop_config.json

{
  "mcpServers": {
    "crossref": {
      "command": "uvx",
      "args": ["crossref-mcp"],
      "env": { "CROSSREF_MAILTO": "you@example.com" }
    }
  }
}

或以容器跑 stdio:"command": "docker""args": ["run", "-i", "--rm", "-e", "CROSSREF_MAILTO", "heyinnaneo/crossref-mcp"]

Streamable HTTP — 容器啟動後,將支援 HTTP 的 client 指向 http://localhost:8000/mcp。若設了 MCP_API_KEY,以 X-API-Key header 帶上。

Docker / HTTP 部署

cp .env.example .env          # 設定 CROSSREF_MAILTO
docker compose up -d          # 拉 heyinnaneo/crossref-mcp,HTTP 在 :8000
curl http://localhost:8000/health

/mcp 提供 Streamable HTTP,/health 供 compose 健康檢查。設 MCP_API_KEY 可要求 /mcpX-API-Key。要本地 build,取消 docker-compose.ymlbuild: . 註解。

公開部署(TLS / 反向代理)— 選用

放在內附的 Caddy proxy 後(Caddyfile + docker-compose.proxy.yml):TLS 終結 (自動 Let's Encrypt)、HTTP→HTTPS、SSE 串流、後端不對 host 公開。

cp .env.example .env   # 加上 DOMAIN=、ACME_EMAIL=、MCP_API_KEY=
docker compose -f docker-compose.proxy.yml up -d
curl https://your-domain/health

縱深防禦:proxy 邊界(可選 IP allowlist / Basic auth)+ MCP_API_KEY 應用層; 兩者皆留 /health 開放。需網域 DNS 指向主機、80/443 可達。Caddy 限流需 caddy-ratelimit plugin(自 build)。

Redis 快取 + 跨副本速率控制 — 選用

REDIS_URL 啟用回應快取(cache-aside 存原始 envelope;key 排除 mailto/ 密鑰),並以 RATELIMIT_BACKEND=redis 啟用共享 token bucket,讓多副本維持在 Crossref polite-pool 速率內。

docker compose -f docker-compose.redis.yml up -d
curl http://localhost:8000/health   # cache_enabled + ratelimit_backend + redis: up

Redis 故障會優雅降級(不快取、改 in-memory 限速);/health 仍回 200 並標 redis: down

CI / 發佈

.github/workflows/ci.ymltest(每次 push/PR 跑 ruff + format + pytest 含 覆蓋率)、security(Trivy fs 掃描)、build-pushmainv* tag 時 push multi-arch image 到 heyinnaneo/crossref-mcp),打 tag 時另跑 publish-pypi (OIDC Trusted Publisher)+ publish-registry(MCP registry)。

Repository secrets(Settings → Secrets and variables → Actions): DOCKERHUB_USERNAME = heyinnaneoDOCKERHUB_TOKEN = Docker Hub Access Token (Read/Write)。打 tag 發版(git tag v0.1.0 && git push origin v0.1.0);tag 須 與 pyproject.toml 版本一致。

從 MCP registry 安裝

io.github.jtl-neo/crossref-mcp 發佈(見 server.json),含 PyPI 套件(uvx crossref-mcp)與 OCI image。發佈於版本 tag 時自動進行 (publish-pypi + publish-registry);需公開 repo 與已設定的 PyPI Trusted Publisher。

安全與信任

  • 唯讀。 每個工具都是查詢,標註 readOnlyHint
  • 速率控制。 預設單 process in-memory — 勿當公開代理承載大流量;多副本請用 RATELIMIT_BACKEND=redis
  • Polite pool。 用你自己的 CROSSREF_MAILTO
  • 公開 HTTP。MCP_API_KEY 並前置 TLS。
  • 不內含密鑰。 .env 不進 image、不進 git。

授權

MIT。文獻資料來自公開的 Crossref REST API;與 Crossref 無隸屬關係。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crossref_mcp-0.1.0.tar.gz (106.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crossref_mcp-0.1.0-py3-none-any.whl (27.8 kB view details)

Uploaded Python 3

File details

Details for the file crossref_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: crossref_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 106.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crossref_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 af1f7b80df9a6a825388232614e618db71ea38d4749154f0f3d5c7bf4298ceb1
MD5 7a911b4362d0701a0ccecb26f6e625b1
BLAKE2b-256 afdd987766deb357ebee8e883e42341b5ed43fe8e95606e3fbefa196963c750d

See more details on using hashes here.

Provenance

The following attestation bundles were made for crossref_mcp-0.1.0.tar.gz:

Publisher: ci.yml on jtl-neo/crossref-api-MCP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file crossref_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: crossref_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crossref_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f04219ed3630319c41f74ec4b67ecbdb0ab137da3cefea4a392d16bfe040e44
MD5 5ecf28d0e1dab73165b5e3ba1b0c2fb0
BLAKE2b-256 eae48a1a603b5e85397d614c57a4481fc4dd68803d61b2fccfe31ff7f4bfe584

See more details on using hashes here.

Provenance

The following attestation bundles were made for crossref_mcp-0.1.0-py3-none-any.whl:

Publisher: ci.yml on jtl-neo/crossref-api-MCP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page