.codex-plugin — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited .codex-plugin (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<div align="center"> <h1>@cyanheads/gbif-biodiversity-mcp-server</h1> <p><b>Search GBIF species taxonomy, occurrence records, datasets, and publishers via MCP. STDIO or Streamable HTTP.</b> <div>12 Tools • 2 Resources</div> </p> </div>
<div align="center">
</div>
<div align="center">
Public Hosted Server: https://gbif-biodiversity.caseyjhand.com/mcp
</div>
12 tools for working with GBIF species taxonomy, occurrence records, datasets, and publishers:
| Tool | Description |
|---|---|
gbif_match_species | Match a species name against the GBIF backbone taxonomy — returns taxonKey, confidence score, and full classification |
gbif_get_species | Fetch a single backbone taxon by key — full classification, authorship, synonymy, vernacular name, descendant count |
gbif_search_species | Search or browse the GBIF backbone taxonomy by name fragment, rank, kingdom, family, or genus |
gbif_get_species_classification | Return the complete parent chain for a taxon — root-first ordered array from kingdom to immediate parent |
gbif_get_species_children | List direct children of a backbone taxon — genera within a family, species within a genus |
gbif_search_occurrences | Search 2.4B+ GBIF occurrence records with Darwin Core filters — country, bounding box, WKT geometry, year, month, basis of record |
gbif_count_occurrences | Count occurrences matching a filter without fetching records — fast single-number response |
gbif_get_occurrence | Fetch a single occurrence record by key — full Darwin Core record with GADM geography, media, and quality flags |
gbif_occurrence_facets | Aggregate occurrence counts by a dimension — country, year, basis of record, dataset, kingdom, and more |
gbif_search_datasets | Search GBIF datasets by keyword, type, country, or publishing organization |
gbif_get_dataset | Fetch full dataset metadata by UUID — title, description, citation, contacts, license, DOI, coverage |
gbif_search_publishers | Search GBIF-registered publishing organizations by name fragment or country |
gbif_match_speciesMatch a scientific or common name against the GBIF backbone taxonomy.
strict: true for exact-only matchingtaxonKey — the backbone key required by gbif_search_occurrences, gbif_count_occurrences, and gbif_occurrence_facetsmatchType NONE indicates no usable match — try removing strict mode or broadening the namegbif_get_speciesFetch a complete taxon record by GBIF backbone key.
taxonomicStatus: ACCEPTED, SYNONYM, DOUBTFUL — when SYNONYM, acceptedKey and accepted identify the current namenumDescendants and numOccurrences for scope at a glanceextinct field present only when explicitly flagged — not false on unlabeled taxapublishedIn carries the original description citation when availablegbif_search_speciesSearch or browse the GBIF backbone taxonomy.
isExtinct filter for extinct vs. extant taxadatasetKey (omit for the GBIF backbone)gbif_get_species_classificationReturn the full parent chain for a taxon as an ordered array.
gbif_get_species_childrenList direct children of a backbone taxon.
gbif_search_occurrencesSearch 2.4B+ GBIF occurrence records with full Darwin Core filtering.
taxonKey from gbif_match_species for reliable results — resolves synonyms automatically; scientificName filter does notcountry (ISO 3166-1 alpha-2), bounding box (decimalLatitude/decimalLongitude ranges as "min,max"), or WKT polygon (geometry)year as single year or range, month (1–12) for seasonal queriesbasisOfRecord enum: HUMAN_OBSERVATION, PRESERVED_SPECIMEN, MACHINE_OBSERVATION, and morehasCoordinate to require or exclude georeferenced recordsgbif_occurrence_facets for aggregate analysis beyond thisgbif_count_occurrencesCount occurrences matching a filter without fetching any records.
/occurrence/count endpoint — fast single-number responsetaxonKey, country, isGeoreferenced, datasetKey, yeargbif_get_occurrenceFetch a single occurrence record by GBIF occurrence key.
gbif_occurrence_facetsAggregate occurrence counts across a dimension.
COUNTRY, YEAR, BASIS_OF_RECORD, DATASET_KEY, KINGDOM_KEY, PHYLUM_KEY, CLASS_KEY, ORDER_KEY, FAMILY_KEY, GENUS_KEY, SPECIES_KEY, PUBLISHING_COUNTRY, MONTHtaxonKey, country, year, geometry, or basisOfRecord filtersgbif_search_datasetsSearch GBIF datasets by keyword, type, country, or publishing organization.
OCCURRENCE, CHECKLIST, METADATA, SAMPLING_EVENT), publishing country, hosting organization UUIDhostingOrg from gbif_search_publishers to scope to datasets from one organizationgbif_get_datasetFetch full dataset metadata by UUID.
numConstituents for aggregate datasets (e.g. iNaturalist, eBird)gbif_search_datasets or when an occurrence record's datasetKey needs provenance detailgbif_search_publishersSearch organizations registered with GBIF.
gbif_search_datasets with hostingOrg| Type | Name | Description |
|---|---|---|
| Resource | gbif://species/{taxonKey} | Taxon record from the GBIF backbone — classification, authorship, synonymy status, vernacular name |
| Resource | gbif://dataset/{datasetKey} | Dataset metadata — title, description, citation, license, contacts, coverage |
Built on @cyanheads/mcp-ts-core:
none, jwt, oauth)in-memory, filesystem, Supabase, Cloudflare KV/R2/D1GBIF-specific:
gbif_match_species as the entry point — resolves synonyms to backbone taxon keys used throughoutpaginationNote — redirects to facet aggregation before hitting the ~100,000 row limitAgent-friendly output:
gbif_match_species is the mandatory first step — all downstream tools document which key they expectwhen documentation per toolAdd the following to your MCP client configuration file.
{
"mcpServers": {
"gbif-biodiversity-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/gbif-biodiversity-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"gbif-biodiversity-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/gbif-biodiversity-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"gbif-biodiversity-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/gbif-biodiversity-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/mcpgit clone https://github.com/cyanheads/gbif-biodiversity-mcp-server.gitcd gbif-biodiversity-mcp-serverbun installAll configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE | Transport: stdio or http | stdio |
MCP_HTTP_PORT | HTTP server port | 3010 |
MCP_HTTP_ENDPOINT_PATH | HTTP endpoint path where the MCP server is mounted | /mcp |
MCP_PUBLIC_URL | Public origin override for TLS-terminating reverse-proxy deployments | none |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.) | info |
MCP_GC_PRESSURE_INTERVAL_MS | Opt-in Bun-only forced-GC pressure loop (ms). Try 60000 if RSS grows under sustained HTTP load. | 0 (disabled) |
LOGS_DIR | Directory for log files (Node.js only) | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory |
GBIF_BASE_URL | GBIF API base URL override | https://api.gbif.org/v1 |
GBIF_REQUEST_TIMEOUT_MS | HTTP request timeout in milliseconds | 10000 |
OTEL_ENABLED | Enable OpenTelemetry | false |
# One-time build
bun run rebuild
# Run the built server
bun run start:http
# or
bun run start:stdio bun run devcheck # Lints, formats, type-checks, and more
bun run test # Runs the test suite| Directory | Purpose |
|---|---|
src/mcp-server/tools | Tool definitions (*.tool.ts). Twelve tools across species taxonomy, occurrences, datasets, and publishers. |
src/mcp-server/resources | Resource definitions. Species and dataset stable-URI resources. |
src/services/gbif | GBIF REST API service layer — client, request handling, type definitions. |
src/config | Server-specific environment variable parsing and validation with Zod. |
tests/ | Unit and integration tests, mirroring the src/ structure. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for logging, ctx.state for storagecreateApp() arraysIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testThis project is licensed under the Apache 2.0 License. See the LICENSE file for details.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.