@cyanheads/paleobiology-mcp-server
This server has a remotely hosted endpoint. Open its connector listing for connection details, authentication requirements, and setup instructions:
Public Hosted Server: https://paleobiology.caseyjhand.com/mcp
Overview
Fossil biodiversity over the Paleobiology Database (PBDB), spanning roughly 540 million years. Resolve taxon fossil ranges, search fossil occurrences and collections by taxon, geologic time, and location, and plot diversity through deep time.
Tools
Tool | Description |
| Search fossil occurrences by taxon, geologic time, geography, and depositional environment. Every row carries both modern and paleo coordinates; with DataCanvas on, broad results spill to a canvas for SQL. |
| Resolve a taxon by name or |
| Compute a diversity / origination / extinction curve for a clade across geologic time. |
| Look up the geologic time scale — named intervals ↔ absolute Ma boundaries. |
| Find fossil collections (localities) by area, geologic time, formation, and lithology. |
| Resolve the |
| Run a read-only SQL |
| List the tables and columns staged on a DataCanvas. Listed only when DataCanvas is on. |
| Drop a single staged table to free memory before its TTL expires. Opt-in; also needs DataCanvas. |
Resources
Resource | Description |
| One fossil occurrence with full detail — modern + paleo coordinates, classification, strata, locality. |
| One taxon record with its fossil range and classification. |
| One bibliographic reference — the formatted citation plus its structured fields. |
All resource data is also reachable via tools — the resources mirror a single-record read of paleobiology_search_occurrences / paleobiology_get_taxon / paleobiology_get_references for clients that surface resources. Tool-only clients lose nothing.
Related MCP server: mcp-macrostrat
Capability reference
paleobiology_search_occurrences tool
Requires at least one taxon, time, geographic, formation, environment, or
collection_nofilter. Usebase_nameorbase_idfor a clade,taxon_namefor an exact match; page withlimit(default 100, maximum 10,000, subject toPBDB_MAX_OCCURRENCES) andoffset. Every served row appears on both response surfacesReturns modern and paleo coordinates, named intervals and Ma ages, strata, and higher classification, with
totalCountfor PBDB's true match count. Errors:missing_filter,conflicting_taxon_filter,incomplete_bbox,inverted_ma_range, andpbdb_invalid_parameter(with PBDB's reason) for a value PBDB cannot useWith DataCanvas on, a first page with further matches fetches and stages up to 50,000 matching occurrences from offset zero. The requested page stays inline; the notice reports staged versus total coverage. Later pages and complete pages stage nothing. Use
canvas_id+table_namewithpaleobiology_dataframe_describe, then SQL. Reusing a canvas atomically replaces its occurrence table. At the canvas cap, reuse an existing canvas or narrow the matching setOptional staging shares a 55-second deadline with the page request. A transient staging-fetch failure returns the valid inline page with an unavailable notice; caller cancellation propagates
paleobiology_get_taxon tool
Resolve by
nameortaxon_noto the matched record's name, rank, classification, parent, occurrence count, and FAD/LAD range in Ma. Accepted identity (accepted_no,accepted_name,accepted_rank) and PBDB's taxonomic status are separate; useaccepted_noasbase_idfor an accepted-clade searchshow_childrenadds up to 200 immediate child taxa per call;children_truncatedandchildren_offsetsay whether and where to continueTyped errors:
taxon_not_found,missing_selector,conflicting_selectorwhen bothnameandtaxon_noare sent
paleobiology_get_diversity tool
Requires a clade (
base_nameorbase_id), optionally bounded by time,country,formation,environment, or a geographic bounding box. Choosecount(genera,species,families) andresolution(period,epoch,age); defaults are genera by periodReturns the full bin set inline, oldest-first, with sampled, implied, origination, extinction, range-through, and occurrence counts
Originations and extinctions are first/last appearances in the selected data, not established biological events. Notices identify possible truncation at the oldest and youngest bins.
recent: trueextends known extant ranges to the present; the default isfalseTyped errors:
missing_filter,conflicting_taxon_filter,incomplete_bbox,inverted_ma_range,pbdb_invalid_parameterfor a value PBDB cannot use (an unknown interval)
paleobiology_list_intervals tool
Filter by
name, amin_ma/max_maoverlap window, orlevel(eon,era,period,epoch,age); omit filters to browse the bundled ICS scale. Nonzero and single-bound windows require positive-duration overlap; an explicit equal-bound point includes both intervals meeting thereReturns interval rank, Ma boundaries,
parent_no, and an upstreamscalewhere available.source(bundled_ics/pbdb_upstream) andsnapshot_versionidentify the source; names outside the snapshot use PBDBTyped errors:
interval_not_foundfor an unmatched name; retryableinterval_lookup_unavailablewhen PBDB cannot resolve a name outside the snapshot;inverted_ma_rangewhenmax_mais belowmin_ma
paleobiology_search_collections tool
Requires at least one taxon, time, geographic,
country,formation,lithology, orenvironmentfilter. Page withlimit(default 100, maximum 10,000, subject toPBDB_MAX_OCCURRENCES) andoffset. Every served row appears on both response surfacesReturns locality coordinates, age, strata, lithology, environment, and
n_occs, with totals. Passcollection_notopaleobiology_search_occurrencesfor the fauna at that localityTyped errors:
missing_filter,conflicting_taxon_filter,incomplete_bbox,inverted_ma_range,pbdb_invalid_parameterfor a value PBDB cannot use (an unknown interval, or an unknown lithology sent as the only filter)
paleobiology_get_references tool
Pass a nonempty list of positive integer
reference_nosfrom occurrence or collection rows; the first 500 distinct IDs resolve in one PBDB request, and the rest come back inremaining_reference_nosfor the next callReturns references in request order:
citation,title, andpublicationconverted from PBDB HTML to plain text with one entity decode, plusyear,authors,editors,volume,issue, pages,publisher,language, anddoiwhere recordedIds PBDB has no reference for land in
not_foundwith a notice — a miss is a result, not an error
paleobiology_dataframe_query tool
Runs a read-only SQL
SELECTagainst occurrence sets staged bypaleobiology_search_occurrences, using thetable_nameit returned; writes and file-reading functions are rejectedThe
classificationcolumn is JSON — roll up by rank withjson_extract_string(classification, '$.family')(also$.phylum,$.class,$.order,$.genus)Returns every row supplied by the canvas query.
truncated: truemeansrow_countstopped at the framework's row cap; use a stableORDER BYwith SQLLIMIT/OFFSETto continueListed only when DataCanvas is on (
CANVAS_PROVIDER_TYPE=duckdb)
paleobiology_dataframe_describe tool
Lists the tables staged on a canvas, each with its row count and column names/types/nullability — call before
paleobiology_dataframe_queryto discover identifiersListed only when DataCanvas is on (
CANVAS_PROVIDER_TYPE=duckdb)
paleobiology_dataframe_drop tool
Drops one staged table by
canvas_id+table_nameto free memory before its TTL expires; dropping a nonexistent table returnsdropped: false, not an errorOpt-in — needs DataCanvas on and
PALEOBIOLOGY_DATAFRAME_DROP_ENABLED=trueTyped error:
canvas_not_foundwhen the canvas has expired or never existed
paleobiology://occurrence/{occurrence_no} resource
Path param
occurrence_nois a bare positive integer (regex-validated), frompaleobiology_search_occurrencesoutputReturns the same full occurrence detail as the tool — accepted/identified names, age, modern + paleo coordinates, formation/strata, locality — plus a CC BY 4.0
attributionfieldTyped error:
occurrence_not_found
paleobiology://taxon/{taxon_no} resource
Path param
taxon_nois a bare positive integer (regex-validated), frompaleobiology_get_taxonor an occurrence'saccepted_noMirrors
paleobiology_get_taxon's shape exactly — matched and accepted identities, status, classification, parent, FAD/LAD range — plus a CC BY 4.0attributionfieldTyped error:
taxon_not_found
paleobiology://reference/{reference_no} resource
Path param
reference_nois a bare positive integer (regex-validated), from an occurrence or collection rowReturns the same record as one
paleobiology_get_referencesentry plus a CC BY 4.0attributionfieldTyped error:
reference_not_found
Features
Built 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.
PBDB-specific:
Type-safe client for the Paleobiology Database (PBDB) REST API. Most endpoints use readable
vocab=pbdb; taxon endpoints use compact records to preserve matched rank separately from accepted rankBundled ICS geologic time-scale snapshot —
paleobiology_list_intervalsresolves the international scale's named intervals ↔ absolute Ma boundaries with no network call, falling back to a PBDB lookup for sub-stage and regional namesDataCanvas spill for broad occurrence queries (on by default;
CANVAS_PROVIDER_TYPE=noneturns it off): an inline preview plus a staged table queryable with read-only SQL (count by interval, group by formation/country, roll up by family from theclassificationJSON column)No auth, no API key — PBDB is fully open (
MCP_AUTH_MODEdefaults tonone)Diversity counts reflect sampling and collection effort, not true past diversity
Agent-friendly output:
Two coordinate systems on every occurrence — modern lng/lat and paleo lng/lat, distinctly labeled, so an agent never plots a deep-time fossil on a modern coastline
Both temporal representations on every age — the named interval and its Ma boundaries
Provenance on every row:
reference_noforpaleobiology_get_references, plus CC BY attribution on tools and resourcesSparse upstream fields (paleo-coords, formation,
late_interval) are omitted rather than zeroed
Occurrence, collection, and diversity searches accept country as comma-separated two-letter country codes or PBDB continent codes, with leading ! exclusion and ^ subtraction. Formation filters preserve PBDB's stored-name, list, and wildcard matching; do not automatically remove words such as “Formation” or “Member”.
The bundled paleobiology-guide covers identifier chaining, coverage checks, sampled turnover, and citation workflows. It ships with plugins, npm, Docker, and MCPB, and is served through MCP skill resources.
Getting started
Connect to the hosted instance:
claude mcp add --transport http paleobiology-mcp-server https://paleobiology.caseyjhand.com/mcpOr run it locally:
claude mcp add paleobiology-mcp-server -- npx -y @cyanheads/paleobiology-mcp-serverFor other clients, add this to the MCP config file:
{
"mcpServers": {
"paleobiology-mcp-server": {
"command": "npx",
"args": ["-y", "@cyanheads/paleobiology-mcp-server"]
}
}
}PBDB is keyless. For Docker or a source build, see Running the server.
SQL over large occurrence sets is on by default (the @duckdb/node-api peer dep ships in dependencies). With CANVAS_PROVIDER_TYPE=none, paleobiology_search_occurrences still returns its complete requested page, and the paleobiology_dataframe_* tools are left off tools/list (the HTTP landing page shows them as disabled, with the setting that enables them).
Configuration
All variables are optional — the server runs with no configuration against the public PBDB API.
Variable | Description | Default |
| Paleobiology Database API base. Override for a mirror/proxy or pinned API version. |
|
| Per-request timeout in milliseconds. Diversity queries over large clades can be slow. |
|
| Cap on rows per inline occurrence/collection page. Separate from the 50,000-row staging bound. |
|
| DataCanvas spill path and the |
|
| Enable |
|
| Transport: |
|
| Port for HTTP server. |
|
| HTTP session mode: |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Enable OpenTelemetry instrumentation (spans, metrics, completion logs). |
|
| Base OTLP URL for traces and metrics. Logs require their own endpoint. | unset |
| Enable OTLP log export to this exact URL. | unset |
| Log failed tool arguments and results, with key-name redaction; secrets in free-form values remain. |
|
| UTF-8 byte cap per logged payload. |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Requires Bun v1.4 or higher (or Node.js v24+). No API key is required.
git clone https://github.com/cyanheads/paleobiology-mcp-server.git
cd paleobiology-mcp-server
bun install
cp .env.example .env # optional overridesBuild and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/paleobiology-mcp-server:latestThe image defaults to HTTP transport, stateless session mode, and logs to /var/log/paleobiology-mcp-server. For stdio in an MCP client, use "command": "docker" and "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/paleobiology-mcp-server:latest"]. Build locally with docker build -t paleobiology-mcp-server .; OpenTelemetry peers are installed unless built with --build-arg OTEL_ENABLED=false.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions ( |
| Paleobiology Database HTTP client, normalization, and domain types. |
| In-memory index over the bundled ICS geologic time-scale snapshot. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools and resources via the barrels in
src/mcp-server/*/definitions/index.tsWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields (a missing paleo-coordinate is "unknown", not
0,0)
Data attribution
Data is from the Paleobiology Database, licensed CC BY 4.0 — credit it in downstream use.
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Paleobiology Database (PBDB) MCP — the global fossil record. Keyless.
GBIF MCP — wraps the Global Biodiversity Information Facility API v1 (free, no auth)
Macrostrat MCP — geologic map / column / unit data for North America and beyond.
Search DataCite datasets and software, fetch DOI metadata, trace relations, format citations.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables querying and exporting phenology data from the USA National Phenology Network, including raw data, phenometrics, and mapping capabilities.103MIT
- AlicenseNot gradedqualityCmaintenanceMacrostrat MCP — geologic map / column / unit data for North America and beyond.131 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables querying the Paleobiology Database for global fossil records via natural language or direct tools, without requiring an API key.328 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables keyless lookup of marine species and genus names, retrieval of full taxonomic lineages by AphiaID, and common vernacular names across languages via MCP tools.306 npmMIT