Skip to main content

MCP server for the public PuRe (PubMan) REST API — search and retrieve Max Planck Society publications.

Project description

pure-mpg-mcp

PyPI CI License: MIT

An MCP server for the PuRe (PubMan) REST API — the Max Planck Society's publication repository at pure.mpg.de.

It lets any MCP client (Claude Desktop, Claude Code, etc.) search and retrieve Max Planck publications, organizational units, collections, and feeds.

Public & read-only. This server is anonymous: it only reaches RELEASED, publicly visible records. It does not log in, write, or access embargoed/private content. The PuRe write/curation/admin endpoints require authorization and are intentionally not exposed.

PuRe is the center. Every tool starts from a PuRe record. A few tools enrich that record with other free public scholarly APIs (CONE, OpenAlex, Crossref, Unpaywall, Semantic Scholar), but always keyed on identifiers PuRe itself provides (DOI, person ids). The external sources are enrichment only — never queried on their own, never the canonical record.

Tools

Search & retrieval

Tool What it does
search_publications Search with every field of the PuRe advanced search: text, title, keyword (Schlagwörter), classification, fulltext, author, orcid, organization, genre, review method, language, source/journal, identifier, local tag, collection, project info, event, and any of the 9 date criteria
search_raw Run a raw Elasticsearch query for advanced cases
get_publication Full metadata for one item id (e.g. item_1552993)
find_by_doi Look up a publication by DOI (bare or doi.org URL)
export_publication Export one item as BibTeX, citation, MARC, EndNote, …
export_search_results Bulk-export a whole search result set in one call (up to 5000 records)
get_file_metadata Metadata for an attached file (component), plus its content/thumbnail URLs
search_organizations Search institutes / departments (organizational units)
get_organization One organizational unit by id
list_top_organizations Top-level organizational units
list_first_level_organizations First-level organizational units
organization_children Direct child units of an organizational unit
organization_hierarchy Ancestor path (id + name) from a unit up to its root institute
search_collections Search contexts (collections)
get_collection One context (collection) by id
recent_publications Feed of recently released items
open_access_feed Feed of recent open-access items
organization_feed Feed of recent releases for one organizational unit
search_feed Any search, rendered as an RSS/Atom feed
service_info Version / status of the PuRe instance

Authority & analysis (for bibliometrics)

Tool What it does
resolve_author Resolve a name/person-id against the CONE authority → full name, affiliation, ORCID. Expands initials.
author_publications List an author's publications (by CONE id or family name)
list_languages Full ISO 639-3 language vocabulary from the CONE authority (id + display name)
publication_statistics Distributions over a result set: by year, genre, language, organization, open_access, or oa_status (gold/green/hybrid/…)
coauthorship_analysis Collaboration patterns: avg team size, solo-authored count, top co-authors & institutions (authors and editors)
analyze_authors Extract & enrich authors of a publication/query — full names (initials expanded via CONE), ORCID (inline or CONE), affiliation

External enrichment (PuRe DOI → public scholarly APIs)

Tool What it does
enrich_publication Attach external signals to a PuRe item: citations, topics, institutions (ROR), funders, license, OA full text. Pick sources from openalex, crossref, unpaywall, semanticscholar
get_citation_metrics Citation counts for one publication side-by-side across OpenAlex, Crossref, and Semantic Scholar (incl. influential citations)
find_full_text Locate free full text — PuRe's own public files first, then Unpaywall / OpenAlex open-access locations
find_research_data Find datasets linked to a PuRe publication DOI. Uses PuRe item_id or a direct DOI, fans out to ScholeXplorer, DataCite, B2FIND, Crossref, Zenodo, Figshare, and Dryad, then deduplicates dataset hits.
find_research_data_by_orcid Find datasets authored by an ORCID via DataCite, OpenAIRE Graph, OpenAlex, Zenodo, and Figshare.

Enrichment sources

All are free and require no authentication. They are queried only with an identifier taken from a PuRe record, and any source lacking that record is silently omitted.

Source Adds Notes
CONE Full author names, ORCID, affiliation MPG's own authority service
OpenAlex Citation count, topics, institutions/ROR, OA status, related works No key
Crossref References, funders, license, citing count No key
Unpaywall Definitive OA status + free full-text PDF Requires a contact email
Semantic Scholar Influential-citation count, TLDR summary No key; rate-limited

Citation counts differ across sources because each indexes a different corpus — that's expected, and why get_citation_metrics shows them side by side rather than picking one.

Research-data discovery returns both a merged datasets list (doi, title, publisher, year, relation, sources) and the original bySource evidence. Google Dataset Search has no public API, so the research-data tools include a prefilled googleDatasetSearchUrl instead of scraping the UI. See docs/research-data-discovery.md for the API capability matrix and verified query patterns.

Note on analytics. PuRe's search endpoint strips Elasticsearch aggregations, so publication_statistics and coauthorship_analysis fetch a capped sample of records (scrolled, default 300–500) and aggregate client-side. When numberOfRecords exceeds the cap, treat the figures as sample-based, and raise max_records if you need more (at the cost of more requests).

Use with MCP clients

There are two ways to use this server:

  1. Local stdio: the MCP client starts pure-mpg-mcp on your machine. This is the easiest path for Claude Code and Claude Desktop.
  2. Remote Streamable HTTP: the server runs behind HTTPS and clients connect to https://.../mcp. This is required for ChatGPT custom apps/connectors and is also useful for Claude web or team-wide installs.

The server is published on PyPI, so most users do not need to clone this repo. Clients can run it on demand with uvx.

Install uv first (it provides uvx):

curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

PyPI package

PyPI is the canonical distribution path for this MCP server. It hosts the installable package named pure-mpg-mcp; MCP clients then start that package locally.

For local MCP setup, there is no separate <server> URL or hosted endpoint to fill in. The MCP client config should point to the PyPI command:

uvx pure-mpg-mcp

or pin a specific release:

uvx --from pure-mpg-mcp==0.1.3 pure-mpg-mcp

Package page: https://pypi.org/project/pure-mpg-mcp/

This is the right setup for Claude Code and Claude Desktop because they can start local stdio MCP servers. ChatGPT cannot start a local PyPI package; for ChatGPT, deploy the same package as an HTTPS Streamable HTTP server and use the public /mcp URL.

Quick smoke test

Before wiring an MCP client, confirm the package can start:

uvx pure-mpg-mcp

That command starts the stdio MCP server and waits for an MCP client. Stop it with Ctrl+C. If it downloads and starts without an import error, the package is installed correctly.

Claude Code

Add the local stdio server:

claude mcp add pure-mpg -- uvx pure-mpg-mcp

To enable the Unpaywall full-text source, pass a real contact email:

claude mcp add pure-mpg -e PURE_CONTACT_EMAIL=you@example.org -- uvx pure-mpg-mcp

Then start a new Claude Code session and ask something that should require a tool call, for example:

Search PuRe for recent open-access articles about Neanderthals and export the top result as BibTeX.

Claude should discover tools such as search_publications, find_by_doi, export_publication, and publication_statistics.

Claude Desktop

Edit claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Use this config:

{
  "mcpServers": {
    "pure-mpg": {
      "command": "uvx",
      "args": ["pure-mpg-mcp"],
      "env": {
        "PURE_CONTACT_EMAIL": "you@example.org"
      }
    }
  }
}

mcpServers is Claude Desktop's required config object. pure-mpg is just the local name you give this MCP server inside Claude. The actual server comes from PyPI via uvx pure-mpg-mcp; no URL is needed for this local setup.

The env block is optional. It only enables Unpaywall-backed full-text lookup; the PuRe, CONE, OpenAlex, Crossref, and Semantic Scholar features work without it.

After editing the file, fully quit and reopen Claude Desktop. Closing only the window is not enough. In a new chat, ask Claude to search or retrieve a PuRe publication and it should offer to use the pure-mpg MCP server.

Claude by remote URL

If you cannot run local commands, host this server once and add it to Claude as a custom connector by URL. The endpoint is /mcp over Streamable HTTP:

https://<your-host>/mcp

No OAuth is required because this server is public, read-only, and anonymous. In Claude, add a custom connector and choose Streamable HTTP as the transport.

ChatGPT

ChatGPT connects to MCP servers as custom apps/connectors over HTTPS. It cannot start this package locally with stdio, so deploy the HTTP endpoint first. The OpenAI Apps SDK documentation describes the ChatGPT flow as: make the MCP server reachable over HTTPS, go to Settings -> Connectors -> Create, and enter the public /mcp URL. See OpenAI's official docs:

Steps:

  1. Deploy this server with MCP_TRANSPORT=http.
  2. Make sure the final URL is HTTPS and ends in /mcp.
  3. In ChatGPT, enable developer mode if your plan/workspace requires it.
  4. Go to Settings -> Connectors -> Create.
  5. Enter a name such as PuRe MPG Publications.
  6. Enter a description such as "Search and analyze public Max Planck Society publications from PuRe/PubMan."
  7. Set the connector URL to https://<your-host>/mcp.
  8. Create the connector. ChatGPT should show the tools advertised by the MCP server.
  9. Start a new chat, open the tool/app picker, choose your connector, and ask a PuRe-related question.

Good first prompt:

Use PuRe MPG Publications to find recent Max Planck open-access articles about quantum materials and summarize the top five results with DOIs.

If ChatGPT cannot create the connector, check that your ChatGPT plan/workspace allows custom MCP apps/connectors and that workspace admins have enabled the feature.

Host the HTTP endpoint

The same Python server speaks Streamable HTTP at /mcp when MCP_TRANSPORT=http is set. A Dockerfile is included.

Option A: Render (render.yaml)

Go to render.com, choose New -> Blueprint, and select this repo. Render builds the container and your MCP URL is:

https://<service>.onrender.com/mcp

Render sets RENDER_EXTERNAL_HOSTNAME, which the server trusts as an allowed host. Free Render services may sleep after idle periods, so the first request can be slow.

Option B: Docker Compose with Caddy (compose.yaml and Caddyfile)

Use this when you have a VPS or home server and a domain pointing at it:

git clone https://github.com/Toymen/pure-mpg-mcp.git
cd pure-mpg-mcp
cp .env.example .env
# edit .env and set MCP_DOMAIN=your.domain.example
docker compose up -d --build

Your connector URL is:

https://<MCP_DOMAIN>/mcp

Open-source PaaS options such as Coolify, Dokku, or CapRover can also build the same Dockerfile.

Option C: Any container host

Set these environment variables:

MCP_TRANSPORT=http
HOST=0.0.0.0
PORT=8000
MCP_ALLOWED_HOSTS=your.domain.example
PURE_CONTACT_EMAIL=you@example.org

Expose port 8000 behind HTTPS and route requests to /mcp.

Host allow-list. The MCP SDK includes DNS-rebinding protection. On hosts other than Render, set MCP_ALLOWED_HOSTS to the public hostname clients will use, without https:// and without /mcp. For multiple hostnames, use a comma-separated list.

From source

Use this for local development or if you want to test unreleased changes:

git clone https://github.com/Toymen/pure-mpg-mcp.git
cd pure-mpg-mcp
uv pip install -e ".[dev]"
pure-mpg-mcp

For HTTP mode from source:

MCP_TRANSPORT=http PORT=8000 uv run pure-mpg-mcp

Then connect a remote-capable MCP client to:

http://localhost:8000/mcp

For ChatGPT, use a real HTTPS URL, not localhost.

Troubleshooting

Symptom What to check
Client cannot find uvx Install uv, then restart the MCP client so it sees the updated PATH.
Claude Desktop does not show tools Fully quit and reopen Claude Desktop, then check the JSON config syntax.
ChatGPT cannot create the connector Confirm the /mcp URL is public HTTPS and your workspace allows custom MCP apps/connectors.
HTTP endpoint returns host/origin errors Set MCP_ALLOWED_HOSTS to the public hostname, for example mcp.example.org.
Unpaywall is skipped Set PURE_CONTACT_EMAIL to a real non-example email address.
First remote request is slow Free hosting tiers may cold-start after idle periods.

Configuration

Env var Default Purpose
PURE_BASE_URL https://pure.mpg.de/rest Override the API base (e.g. a QA instance)
PURE_CONE_URL https://pure.mpg.de/cone Override the CONE authority base
PURE_CONTACT_EMAIL (unset) A real contact email. Used for the OpenAlex/Crossref "polite pool", and required by Unpaywallfind_full_text and enrich_publication skip the Unpaywall source (and say so) until this is set. @example.com addresses are treated as unset.
MCP_TRANSPORT stdio Set to http to serve Streamable HTTP at /mcp (for remote hosting) instead of stdio.
PORT / HOST 8000 / 0.0.0.0 Bind address in HTTP mode (most hosts inject PORT).
MCP_ALLOWED_HOSTS (unset) Comma-separated hostnames to trust in HTTP mode (DNS-rebinding protection). Render's hostname is trusted automatically.

Example

"Find recent open-access articles from the Max Planck Institute for Evolutionary Anthropology about Neanderthals, and give me the BibTeX for the top hit."

The agent calls search_publications(text="Neanderthal", genre="ARTICLE"), then export_publication(item_id, format="BibTex").

Development

uv pip install -e ".[dev]"
ruff check .
pytest -m "not network"   # offline unit tests (what CI runs)
pytest -m "network and not limit"  # live API smoke tests
PURE_RUN_LIMIT_TESTS=1 pytest -m "network and limit"  # explicit boundary probes

Tests are split with network and limit markers: offline tests cover all the pure aggregation/parsing logic and run in CI; network and not limit checks hit live public APIs at low volume; network and limit probes rate limits and large result-window boundaries and requires PURE_RUN_LIMIT_TESTS=1. GitHub Actions runs lint + offline tests on Python 3.10 and 3.12 (.github/workflows/ci.yml). Live smoke tests run in a separate scheduled/manual workflow; limit probes are manual-only.

Releases & publishing

Versioning and changelogs are automated with release-please from Conventional Commits — see CONTRIBUTING.md. The flow:

  1. Land Conventional Commits on main (feat:, fix:, …).
  2. release-please opens a release PR that bumps the version across pyproject.toml, src/pure_mpg_mcp/__init__.py, and server.json, and updates CHANGELOG.md (.github/workflows/release-please.yml).
  3. Merge the release PR → the tag and GitHub Release are created. Publish the tagged release through the Publish workflow (.github/workflows/publish.yml), which is configured for PyPI Trusted Publishing (OIDC, no stored token).

MCP servers aren't "hosted" on GitHub — GitHub holds the source, PyPI ships the package (uvx pure-mpg-mcp), and clients launch it locally over stdio. For discovery, the optional MCP Registry uses server.json as its manifest; the <!-- mcp-name: io.github.toymen/pure-mpg-mcp --> line in this README verifies ownership. Publish it with the mcp-publisher CLI once a PyPI release exists.

The PyPI trusted publisher is configured for publish.yml with environment pypi. The workflow can run on a published GitHub Release or manually with a tag ref such as pure-mpg-mcp-v0.1.2.

API reference

License

MIT. This project is an independent client and is not affiliated with or endorsed by the Max Planck Society / Max Planck Digital Library.

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

pure_mpg_mcp-0.1.5.tar.gz (76.1 kB view details)

Uploaded Source

Built Distribution

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

pure_mpg_mcp-0.1.5-py3-none-any.whl (55.3 kB view details)

Uploaded Python 3

File details

Details for the file pure_mpg_mcp-0.1.5.tar.gz.

File metadata

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

File hashes

Hashes for pure_mpg_mcp-0.1.5.tar.gz
Algorithm Hash digest
SHA256 3a16d2b28c939a54a45ae337b604d22ee5c713028da1e7abd874c1fd2206c90c
MD5 eb7c8e2090b1e0af376a998a9a383a49
BLAKE2b-256 fc1f4c93eb4da35dfa4ba7abf5b97de0874c99f18a088430c5db20e0208ad8be

See more details on using hashes here.

Provenance

The following attestation bundles were made for pure_mpg_mcp-0.1.5.tar.gz:

Publisher: release-please.yml on Toymen/pure-mpg-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 pure_mpg_mcp-0.1.5-py3-none-any.whl.

File metadata

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

File hashes

Hashes for pure_mpg_mcp-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 44330c924d7f33a0f648262c151292e77c118a77607b4d09468d2fb2cf64867a
MD5 43f55fd35b7f99b66304e8c60f6016e4
BLAKE2b-256 d7edf553e0f62e0bcb4a14c053a4db70c465bb8c7444c8da7b87543077107cfe

See more details on using hashes here.

Provenance

The following attestation bundles were made for pure_mpg_mcp-0.1.5-py3-none-any.whl:

Publisher: release-please.yml on Toymen/pure-mpg-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