Search INSPIRE-HEP papers, authors, experiments, HEPData records; get citation metrics and BibTeX.
One address for any MCP client. No sign-in needed on this server.
8 read
Grouped by tool name. At most: only reads or looks up information.
Odel charges nothing per call. The publisher may charge for its own service.
Search INSPIRE-HEP papers, authors, experiments, HEPData records; get citation metrics and BibTeX via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://cern-inspire.caseyjhand.com/mcp
High-energy-physics literature from INSPIRE-HEP, including its index of HEPData measurement records. Search papers, authors, and experiments, read a paper's full record, compute citation summaries, h-indices, and citations per year, export BibTeX or LaTeX entries, and find the HEPData record that holds a paper's numerical tables. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
| Tool | Description |
|---|---|
cern_inspire_search_literature | Search papers with INSPIRE query syntax or free text, filtered by document type, subject, and year |
cern_inspire_get_paper | Fetch one paper's full record by recid, arXiv ID, or DOI, with its HEPData availability |
cern_inspire_export_citations | Export INSPIRE's BibTeX or LaTeX \bibitem entries for the papers a query selects |
cern_inspire_search_authors | Find physicist profiles by name, BAI, ORCID, INSPIRE ID, or author recid |
cern_inspire_get_citation_summary | h-index, citation totals, citation buckets, and citations per year for one author or any literature query |
cern_inspire_search_experiments | Find experiments, collaborations, and facilities, with a query that selects their papers |
cern_inspire_search_hepdata | Find HEPData measurement records by process, observable, energy, or collaboration |
cern_inspire_list_reference | Decode query syntax, identifier forms, filter values, citation buckets, and HEPData DOIs |
| Resource | Description |
|---|---|
inspire://literature/{recid} | One literature record as the cern_inspire_get_paper dossier in JSON |
The same record is reachable through cern_inspire_get_paper for clients that don't surface resources.
cern_inspire_search_literature toolsort (relevance, mostrecent, mostcited), document_types and subjects (up to 4 values each, all must hold), and year_from / year_to; size 1–100 (default 10), paged by pagepage × size beyond that fails as beyond_result_window; a reversed year range fails as invalid_year_rangerecid, title, first author, date, citation counts, arXiv ID, DOI, publication, and a 300-character abstract snippet; the page also returns totalCount, nextPage, and appliedFilters, and a notice flags queries matching over 100,000 recordscern_inspire_get_paper toolpaper takes a recid, arXiv ID, DOI, inspirehep.net literature URL, or HEPData ins<recid> / hepdata.net record/ins<recid> URL; resolvedAs names the form that matched, and a miss fails as paper_not_found. A recid INSPIRE has merged into another record (older citations and HEPData ins links still carry such recids) returns the record INSPIRE redirects it to, with mergedFrom naming the recid asked for and a notice. A numbered hepdata.net record link, or a HEPData DOI no paper carries, names a HEPData record rather than a paper: its error gives the cern_inspire_search_hepdata query whose paperRecids reach the papermax_authors 0–500 (default 25) caps the author list; authorCount always gives the full numberhepdata.status is available, none, or lookup_failed, with recordDoi, latestVersion, tableCount, and hepdataUrl (the hepdata.net page of that record number) when available; a paper with more than one HEPData record lists the rest in hepdata.otherRecords, with a notice; citingQuery and referencesQuery feed cern_inspire_search_literaturecern_inspire_export_citations toolrecid:451647 or arxiv:1207.7214 for named papers); format is bibtex (default), latex-eu, or latex-us; sort as in search; size 1–50 (default 10) per page, paged by page up to the first 10,000 matches (beyond that, beyond_result_window)texkey; truncated is set when more matched papers follow the page, nextPage with it while the next page is within the 10,000-result window, and a page past the last returns no entries with a notice naming the last pagecern_inspire_search_authors toollimit 1–25 (default 5)matchedAs is orcid, inspire_id, bai, or recid (exact match), or name (free-text search returning ranked candidates to choose from)recid, bai, ORCID, positions (with an institutionRecid that affid:N takes for the institution's papers), advisors, arXiv categories, awards, and a literatureQuery selecting the person's paperscern_inspire_get_citation_summary toolauthor (BAI, ORCID, INSPIRE ID, or author recid) or query (any literature query, such as affid:902725 for an institution's papers); otherwise missing_target, and a name passed as author fails as author_not_identifierdocument_types and subjects narrow every figure; year_from / year_to narrow the summary, and exclude_self_citations drops self-citations from it0, 1–9, 10–49, 50–99, 100–249, 250–499, 500+, each for all citeable and for published paperscitationsByYear: citations received per year (the citing record's year, self-citations included, every matched record), ascending, with no row for a year without citations; left out, with a notice, under year_from, year_to, or exclude_self_citations, which INSPIRE's per-year series cannot apply, when INSPIRE does not return it, and for a query matching more than about 150,000 records, which INSPIRE cannot count in time, unless INSPIRE answers within about 2 s (a series it has cached); the call then returns in about 2 sauthor, which is resolved first); with year_from, year_to, or exclude_self_citations set, one (two). The per-year request holds one of the pacer's four in-flight slots for as long as INSPIRE takes (up to 15 s), so at most two per-year series run at once and other calls keep at least two slotscern_inspire_search_experiments toolCERN-LHC-CMS), or an experiment recid (digits only); limit 1–25 (default 5)ongoing (omitted when INSPIRE records neither state), INSPIRE's paper count, and a literatureQuery for cern_inspire_search_literature or cern_inspire_get_citation_summarycern_inspire_search_hepdata toolcollaborations.value:LHCb, literature.control_number:<recid>); sort is relevance or mostrecent; size 1–50 (default 10), within the same 10,000-result windowpaperRecids, collaborations, keywords (reactions, observables, centre-of-mass energies), recordDoi, latestVersion, tableCount, and hepdataUrl (each record's own hepdata.net page); table values are not returnedcern_inspire_list_reference tooltopic: search_syntax, identifiers, document_types, subjects, citation_buckets, or hepdataterm / meaning / example entries; no upstream callinspire://literature/{recid} resourcecern_inspire_get_paper dossier as application/json, listing the first 25 authorsmergedFromBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
INSPIRE-specific:
pacer_shed with a retryAfterarXiv: / doi: prefixes, version suffixes, arxiv.org, doi.org, or inspirehep.net URLs, and HEPData's ins<recid>, a recid INSPIRE has merged away is followed to the surviving record, and every documented spelling passes a client's validation against the advertised schema; author identifiers accept an orcid.org URLAgent-friendly output:
recid, author profiles and experiments carry a ready literatureQuery, and cern_inspire_get_paper returns citingQuery and referencesQuerytotalCount, truncated / shown / cap, nextPage, appliedFilters, and effectiveQuery, plus a notice with next-step text on empty, capped, or suspiciously broad resultshepdata.status, resolvedAs, matchedAs, and target.kind let callers branch on data; typed failure reasons (paper_not_found, author_not_found, beyond_result_window, inspire_rate_limited) each carry a recovery hintσ_γ, ^{23}Na(n,γ)) on every tool that returns titles or abstracts and on the resource, with LaTeX left as published; citation export entries stay verbatim, and other upstream strings reach structuredContent as INSPIRE sends them, less any invisible Unicode tag characters, which are dropped. The text output escapes them all, leaving identifiers such as DOIs and texkeys copyable as writtenrecordDoi) when you reuse the data.cern_inspire_get_paper and cern_inspire_search_hepdata return the record DOI and the hepdata.net page where the values are read.totalCount usually means a syntax slip (cern_inspire_list_reference topic search_syntax).A public instance is available at https://cern-inspire.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"cern-inspire-mcp-server": {
"type": "streamable-http",
"url": "https://cern-inspire.caseyjhand.com/mcp"
}
}
}
Every caller of the hosted instance shares one INSPIRE request budget of 12 request starts per 5 seconds. For sustained use, run your own instance.
Add the following to your MCP client configuration file. No API key is needed.
{
"mcpServers": {
"cern-inspire-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/cern-inspire-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"cern-inspire-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/cern-inspire-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"cern-inspire-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/cern-inspire-mcp-server:latest"]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/cern-inspire-mcp-server.git
cd cern-inspire-mcp-server
bun install
cp .env.example .env
# edit .env to change the transport, logging, or session settings
The server has no settings of its own: INSPIRE needs no key, and the request pacing is fixed in code. These framework variables cover most deployments.
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | HTTP server port. | 3010 |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto. .env.example and the Docker image set stateless. | auto |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (debug, info, notice, warning, error, etc.). The Docker image sets info. | debug |
LOGS_DIR | Directory for log files (Node.js only). | <app-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry. | false |
See .env.example for the full list of framework overrides.
Build and run the production version:
# One-time build
bun run rebuild
# Run the built server
bun run start:http
# or
bun run start:stdio
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more
bun run test # Runs the test suite
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point: registers tools and resource, sets server instructions, starts and disposes the INSPIRE service. |
src/mcp-server/tools | Tool definitions (*.tool.ts) and shared input schemas (inputs.ts). |
src/mcp-server/resources | The literature record resource. |
src/services/inspire | INSPIRE service: pacer, per-call budget, retries, identifier routing, normalization, controlled vocabularies. |
src/services/http | Bounded fetch: per-attempt timeout and response byte ceiling. |
src/utils | Escaping for upstream text in tool output and error messages (render.ts). |
tests/ | Vitest suites with INSPIRE response fixtures. |
docs/design.md | Tool surface, verified INSPIRE behavior, design decisions, and the deferred HEPData-direct tools. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicInspireService, with the call opened by beginCall(ctx); handlers never fetch directlysrc/mcp-server/tools/definitions/index.ts and src/mcp-server/resources/definitions/index.tsIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.