# io.github.cyanheads/inaturalist-mcp-server (remote · inaturalist.caseyjhand.com)

Search iNaturalist sightings, identification threads, phenology, and look-alike species.

- Trust score: 66/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-21

## Components

- remote · `inaturalist.caseyjhand.com`: 66/100 (this document), [markdown](https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/inaturalist.md), [page](https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/inaturalist)
- npm · `@cyanheads/inaturalist-mcp-server`: 39/100, [markdown](https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/cyanheads-inaturalist-mcp-server.md), [page](https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/cyanheads-inaturalist-mcp-server)

## Channel facts

- Endpoint: `https://inaturalist.caseyjhand.com/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.1.2`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-21.

- **Endpoint Security**: 66/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 10 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC is configured correctly; the domain's records validate against the full chain to the root.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 61/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 4797 tokens (~479/item across 10 items; 10 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 3/100
  - Stability observed for 1 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 10 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 11 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the io.github.cyanheads/inaturalist-mcp-server server?

io.github.cyanheads/inaturalist-mcp-server is a hosted endpoint at https://inaturalist.caseyjhand.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http cyanheads-inaturalist-mcp-server 'https://inaturalist.caseyjhand.com/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "cyanheads-inaturalist-mcp-server": {
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "cyanheads-inaturalist-mcp-server": {
      "type": "http",
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.cyanheads-inaturalist-mcp-server]
url = "https://inaturalist.caseyjhand.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "cyanheads-inaturalist-mcp-server": {
      "type": "remote",
      "url": "https://inaturalist.caseyjhand.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add cyanheads-inaturalist-mcp-server --url 'https://inaturalist.caseyjhand.com/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  cyanheads-inaturalist-mcp-server:
    url: "https://inaturalist.caseyjhand.com/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "cyanheads-inaturalist-mcp-server": {
      "Transport": "http",
      "Url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add cyanheads-inaturalist-mcp-server -t streamable-http -u 'https://inaturalist.caseyjhand.com/mcp'
```

### Other

```json
{
  "mcpServers": {
    "cyanheads-inaturalist-mcp-server": {
      "type": "http",
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-21 (score 66, +1)

- [functional improvement] Stability: unverified → 0.03

### 2026-09-20 (score 65)

First indexed and scored.

## MCP tools (10)

### `inaturalist_list_reference` (~214 tokens)

Inaturalist List Reference

Decode the vocabularies the other iNaturalist tools take as input: annotation attributes and values, quality grades, license codes, taxonomic ranks, iconic taxa, and IUCN conservation-status codes. An unrecognized filter value is not rejected upstream — it silently returns nothing — so read the codes here before filtering. Note that the conservation codes are the normalised csi search filter; a taxon record’s own conservation_statuses[].status is authority-specific free text and reads differently. With topic controlled_terms and a taxon_id, the response also carries which annotations identifiers have actually recorded for that taxon, with counts.

Input parameters:

- `taxon_id` (integer): Add observed annotation usage for this taxon, ranked by how often each attribute/value pair has been recorded. Valid only with topic controlled_terms. Resolve a name to an id with inaturalist_resolve…
- `topic` (string, required): Which vocabulary to decode. controlled_terms is fetched live and cached; the rest are spec-derived static tables.

Output parameters:

- `entries` (array): The vocabulary, one entry per code or attribute.
- `error` (object): Present when the call failed. Absent on success.
- `notice` (string): Guidance when the requested taxon has no recorded annotations yet.
- `observed_usage` (array): Observed annotation usage for taxon_id, most-used first. Present only when taxon_id was given.
- `source` (string): "upstream" when the table was fetched from iNaturalist, "static" when spec-derived.
- `topic` (string): The vocabulary that was decoded.

### `inaturalist_resolve_name` (~246 tokens)

Inaturalist Resolve Name

Resolve a common or scientific name to a taxon id, or a place, project, or observer name to its id. Returns ranked candidates carrying the identifiers every other tool takes. A miss is a result rather than a failure: found comes back false with guidance naming why. Taxon lookup matches a name PREFIX, not words inside a name, so "monarch butterfly" misses where "monarch" hits.

Input parameters:

- `limit` (integer): Maximum candidates to return.
- `q` (string, required): The name to resolve. On type "taxon" this is a name prefix or an exact taxon id; on the other types it is matched across the record text.
- `rank` (string): Restrict taxon candidates to one rank. Honoured only on type "taxon" — the cross-kind search has no rank filter.
- `type` (string): Which kind of record to resolve. "taxon" uses the taxon autocomplete; the rest use the scored cross-kind search, and "any" searches every kind at once. For a place’s bounding box and containment chai…

Output parameters:

- `candidates` (array): Ranked candidates, best match first.
- `error` (object): Present when the call failed. Absent on success.
- `found` (boolean): True when at least one candidate matched.
- `guidance` (string): Why nothing matched and what to try instead. Present only when found is false — this is the primary result of a miss.
- `totalCount` (number): Total candidates upstream matched, before the limit was applied.

### `inaturalist_find_places` (~268 tokens)

Inaturalist Find Places

Resolve a place name to a place id, or list the places containing a map area. Pass q to match a place-name PREFIX, or all four of nelat, nelng, swlat and swlng to list every place covering that box — exactly one of the two, never both. Each result carries the bounding box, place type, and containment chain an area search needs. Place geometry is stripped: a single nearby response carries 247 KB of boundary polygons upstream, none of which reaches the caller.

Input parameters:

- `nelat` (number): North-east corner latitude of the map area. All four corners or none.
- `nelng` (number): North-east corner longitude of the map area. All four corners or none.
- `per_page` (integer): Maximum places to return. Honoured on the bounding-box arm only — the name-prefix endpoint publishes no page size and returns a fixed page.
- `q` (string): Place-name prefix to search. Matches the start of a name, not words inside it. Mutually exclusive with the bounding box.
- `swlat` (number): South-west corner latitude of the map area. All four corners or none.
- `swlng` (number): South-west corner longitude of the map area. All four corners or none.

Output parameters:

- `cap` (number): The page size that bounded this response — per_page on the bounding-box arm, the fixed page upstream served on the name-prefix arm.
- `community` (array): Member-created places covering the area. Present on the bounding-box arm.
- `error` (object): Present when the call failed. Absent on success.
- `notice` (string): Guidance when nothing matched, or when the page capped the result set.
- `places` (array): Name-prefix matches. Present on the q arm.
- `shown` (number): How many places this response carries.
- `standard` (array): Curated administrative places covering the area. Present on the bounding-box arm.
- `totalCount` (number): Total places upstream matched, before any page limit.
- `truncated` (boolean): True when more places matched than were returned.

### `inaturalist_search_observations` (~1023 tokens)

Inaturalist Search Observations

Search georeferenced wildlife sightings by area, date, taxon, quality grade, annotation, and conservation status. Returns a projected record per sighting with coordinates, licence, first photo, and identification counts. An area is given in exactly one form — place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box — and defaults to research-grade, wild-only records, which are echoed back on every call. Identifications and comments are deliberately not expandable here (one thread is 28 KB); fetch them for specific records with inaturalist_get_observation. Results past 10,000 need the cursor from the previous page rather than a higher page number.

Input parameters:

- `captive` (boolean): Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
- `csi` (array): IUCN-normalised conservation status codes to include, e.g. ["EN","CR"]. Decode them with inaturalist_list_reference topic conservation_status_codes.
- `cursor` (string): next_cursor from a previous page, to continue past the 10,000-result window — a positive integer observation id, sent upstream as id_below. Mutually exclusive with page, and forces an id ordering.
- `d1` (string): Earliest observation date, YYYY-MM-DD. Inclusive.
- `d2` (string): Latest observation date, YYYY-MM-DD. Inclusive.
- `endemic` (boolean): Restrict to taxa endemic to the observation location.
- `hrank` (string): Highest taxonomic rank of the identification to accept.
- `iconic_taxa` (array): Broad organism groups, by their scientific iconic-taxon name. A common-name value such as "Birds" matches nothing upstream, so only the listed values are accepted.
- `include` (array): Embedded arrays to expand per record. Check photo_count and sound_count first — expanding costs context.
- `introduced` (boolean): Restrict to taxa introduced to the observation location.
- `lat` (number): Latitude of the search centre, in decimal degrees. Requires lng and radius.
- `licensed` (boolean): Restrict to records whose own license_code is not null.
- `lng` (number): Longitude of the search centre, in decimal degrees. Requires lat and radius.
- `lrank` (string): Lowest taxonomic rank of the identification to accept.
- `native` (boolean): Restrict to taxa native to the observation location.
- `nelat` (number): North-east corner latitude of the bounding box. All four corners or none.
- `nelng` (number): North-east corner longitude of the bounding box. All four corners or none.
- `order` (string): Sort direction.
- `order_by` (string): Sort field. Forced to id when cursor is supplied, since a cursor only continues an id ordering.
- `page` (integer): Page number within the first 10,000 results. Defaults to 1. Mutually exclusive with cursor.
- `per_page` (integer): Records per page, maximum 25. A projected record costs roughly 1.9 KB across structuredContent and the rendered text together, so 25 is a full page near 49 KB and the default of 10 near 20 KB. Walk f…
- `photo_licensed` (boolean): Restrict to records with at least one licensed photo.
- `place_id` (integer): Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream.
- `q` (string): Free text matched across observation properties.
- `quality_grade` (array): Identification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
- `radius` (number): Search radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
- `search_on` (string): Narrow what q matches against. Requires q.
- `swlat` (number): South-west corner latitude of the bounding box. All four corners or none.
- `swlng` (number): South-west corner longitude of the bounding box. All four corners or none.
- `taxon_id` (integer): Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.
- `term_id` (array): Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage.
- `term_value_id` (array): Annotation value ids, from the same attribute listing — e.g. 6 for Larva. Requires term_id; sent alone it is ignored upstream and the unfiltered corpus comes back.
- `threatened` (boolean): Restrict to taxa considered threatened where observed.

Output parameters:

- `applied_filters` (object): The server-applied defaults and overrides that determine what this answer means.
- `cap` (number): The per_page that was applied.
- `error` (object): Present when the call failed. Absent on success.
- `has_more` (boolean): True when this page filled per_page, so more records follow.
- `next_cursor` (string): Pass back as cursor to continue past this page. Absent when has_more is false.
- `notice` (string): Guidance when nothing matched, or how to continue past a full page.
- `observations` (array): The matching sightings, projected.
- `shown` (number): How many records this page carries.
- `total_results` (number): How many records upstream reports as matching. An estimate over a live index — it drifts between calls seconds apart.
- `truncated` (boolean): True when the page filled per_page and more records follow.

### `inaturalist_get_observation` (~162 tokens)

Inaturalist Get Observation

Fetch up to 10 observations by id with their community identification thread — who identified what, whether each identification agrees, and the consensus taxon the community landed on. The whole batch costs one upstream request, so resolving ten ids here is far cheaper than ten separate lookups. A missing id is reported per id in unresolved rather than failing the batch; the call fails only when nothing resolved.

Input parameters:

- `include` (array): Embedded arrays to expand per record. identifications is the default and is what carries the thread; the others cost context, so check photo_count and sound_count first.
- `observation_id` (array, required): Observation ids to fetch, 1 to 10. Find current ids for an area with inaturalist_search_observations.

Output parameters:

- `error` (object): Present when the call failed. Absent on success.
- `notice` (string): Guidance when part of the batch did not resolve.
- `observations` (array): The observations that resolved, with the expansions that were requested.
- `unresolved` (array): Requested ids upstream returned nothing for. They may have been deleted, or never existed.

### `inaturalist_get_species_counts` (~665 tokens)

Inaturalist Get Species Counts

Rank the distinct species recorded in an area and period, most-observed first — the "what lives here" answer, without paging through individual sightings. An area is given in exactly one form: place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box. Narrow to a clade by passing taxon_id, e.g. the birds of a park. Defaults to research-grade, wild-only records and echoes those defaults back. For the most active people rather than the most recorded species, use inaturalist_get_leaderboard.

Input parameters:

- `captive` (boolean): Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
- `d1` (string): Earliest observation date, YYYY-MM-DD. Inclusive.
- `d2` (string): Latest observation date, YYYY-MM-DD. Inclusive.
- `iconic_taxa` (array): Broad organism groups, by their scientific iconic-taxon name. A common-name value such as "Birds" matches nothing upstream, so only the listed values are accepted.
- `lat` (number): Latitude of the search centre, in decimal degrees. Requires lng and radius.
- `lng` (number): Longitude of the search centre, in decimal degrees. Requires lat and radius.
- `nelat` (number): North-east corner latitude of the bounding box. All four corners or none.
- `nelng` (number): North-east corner longitude of the bounding box. All four corners or none.
- `page` (integer): Page number. Defaults to 1.
- `per_page` (integer): Species per page, maximum 50. A ranked species costs roughly 860 bytes across structuredContent and the rendered text together, so 50 is a full page near 43 KB. Upstream would serve 500 in one page —…
- `place_id` (integer): Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream.
- `quality_grade` (array): Identification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
- `radius` (number): Search radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
- `swlat` (number): South-west corner latitude of the bounding box. All four corners or none.
- `swlng` (number): South-west corner longitude of the bounding box. All four corners or none.
- `taxon_id` (integer): Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.
- `term_id` (array): Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage.
- `term_value_id` (array): Annotation value ids, from the same attribute listing — e.g. 6 for Larva. Requires term_id; sent alone it is ignored upstream and the unfiltered corpus comes back.

Output parameters:

- `applied_filters` (object): The server-applied defaults that determine what this answer means.
- `cap` (number): The per_page that was applied.
- `error` (object): Present when the call failed. Absent on success.
- `notice` (string): Guidance when nothing matched, or how to reach the species beyond this page.
- `shown` (number): How many species this page carries.
- `species` (array): The species, ranked by observation_count, most-observed first.
- `total_results` (number): How many distinct species match. An estimate over a live index — it drifts between calls seconds apart.
- `truncated` (boolean): True when the page filled per_page and more species follow.
- `truncationCeiling` (number): Observation count of the last species shown. The ranking is descending, so no species left off this page exceeds it.

### `inaturalist_get_histogram` (~633 tokens)

Inaturalist Get Histogram

Build a phenology histogram for a taxon in an area — which months, weeks, or years it is recorded in. The default month_of_year interval answers "when does this bloom or appear here" in twelve buckets; the absolute intervals (year, month, week, day, hour) bucket real dates and upstream applies a default start date to them. An area is given in exactly one form: place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box. Omit taxon_id to chart every taxon in the area. Defaults to research-grade, wild-only records and echoes those defaults back.

Input parameters:

- `captive` (boolean): Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
- `d1` (string): Earliest observation date, YYYY-MM-DD. Inclusive. With interval set to day or hour, a wide range can exceed the 800-bucket cap — narrow d1/d2 to reach buckets past it.
- `d2` (string): Latest observation date, YYYY-MM-DD. Inclusive.
- `date_field` (string): Which date to bucket by: when the organism was observed, or when the record was uploaded.
- `interval` (string): Bucketing. month_of_year and week_of_year fold every year together into a seasonal curve; the rest bucket absolute dates. day and hour over a wide date range can generate thousands of buckets — the r…
- `lat` (number): Latitude of the search centre, in decimal degrees. Requires lng and radius.
- `lng` (number): Longitude of the search centre, in decimal degrees. Requires lat and radius.
- `nelat` (number): North-east corner latitude of the bounding box. All four corners or none.
- `nelng` (number): North-east corner longitude of the bounding box. All four corners or none.
- `place_id` (integer): Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream.
- `quality_grade` (array): Identification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
- `radius` (number): Search radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
- `swlat` (number): South-west corner latitude of the bounding box. All four corners or none.
- `swlng` (number): South-west corner longitude of the bounding box. All four corners or none.
- `taxon_id` (integer): Restrict to this taxon and its descendants. Omit to chart every taxon in the area. Resolve a name to an id with inaturalist_resolve_name.

Output parameters:

- `applied_filters` (object): The server-applied defaults that determine what this answer means.
- `buckets` (array): Every bucket upstream returned, in order, including the zero ones — up to 800, the first in upstream key order. See the truncated/shown/cap enrichment when more exist.
- `cap` (number): The bucket cap that was applied.
- `error` (object): Present when the call failed. Absent on success.
- `interval` (string): The bucketing that was applied.
- `notice` (string): Guidance when every bucket came back zero, or when the cap was reached.
- `shown` (number): How many buckets this response carries.
- `total` (number): Sum of every bucket count upstream returned, including buckets past the cap that are not in the buckets array.
- `truncated` (boolean): True when upstream returned more than 800 buckets.

### `inaturalist_get_leaderboard` (~570 tokens)

Inaturalist Get Leaderboard

Rank the most active observers or identifiers for an area, period, and taxon — who knows this place or this group. kind selects which: observers are ranked by how many observations they recorded, identifiers by how many identifications they made. An area is given in exactly one form: place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box. Both endpoints rank only the top 500 entries, so page multiplied by per_page must stay at or below 500 — narrow the area, period, or taxon to bring someone further down into reach. For the most-recorded species rather than the most active people, use inaturalist_get_species_counts.

Input parameters:

- `d1` (string): Earliest observation date, YYYY-MM-DD. Inclusive.
- `d2` (string): Latest observation date, YYYY-MM-DD. Inclusive.
- `kind` (string, required): Which leaderboard: "observers" ranks by observations recorded, "identifiers" by identifications made.
- `lat` (number): Latitude of the search centre, in decimal degrees. Requires lng and radius.
- `lng` (number): Longitude of the search centre, in decimal degrees. Requires lat and radius.
- `nelat` (number): North-east corner latitude of the bounding box. All four corners or none.
- `nelng` (number): North-east corner longitude of the bounding box. All four corners or none.
- `page` (integer): Page number. Defaults to 1.
- `per_page` (integer): Entries per page, maximum 250. An entry costs roughly 140 bytes across structuredContent and the rendered text together, so 250 is a full page near 34 KB — and two such pages cover the whole 500-entr…
- `place_id` (integer): Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream.
- `quality_grade` (array): Identification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
- `radius` (number): Search radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
- `swlat` (number): South-west corner latitude of the bounding box. All four corners or none.
- `swlng` (number): South-west corner longitude of the bounding box. All four corners or none.
- `taxon_id` (integer): Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.

Output parameters:

- `applied_filters` (object): The server-applied default that determines what this answer means.
- `cap` (number): The per_page that was applied.
- `count_metric` (string): What the count on each entry measures.
- `entries` (array): The ranked members, most active first.
- `error` (object): Present when the call failed. Absent on success.
- `kind` (string): Which leaderboard was ranked.
- `notice` (string): Guidance when nobody matched, or how to reach further down the ranking.
- `shown` (number): How many entries this page carries.
- `total_results` (number): How many people upstream reports as matching. Far larger than the 500 this leaderboard can actually address.
- `truncated` (boolean): True when the page filled per_page and more entries follow.

### `inaturalist_get_similar_species` (~495 tokens)

Inaturalist Get Similar Species

List the taxa this one is most often misidentified as, ranked by how many times identifiers made the correction — the field-identification check before committing to a look-alike. Scope it to an area in exactly one form (place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box) to see the confusion set a specific region actually produces, or leave the area off for the global set. Resolve the organism name to a taxon id with inaturalist_resolve_name first.

Input parameters:

- `captive` (boolean): Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
- `d1` (string): Earliest observation date, YYYY-MM-DD. Inclusive.
- `d2` (string): Latest observation date, YYYY-MM-DD. Inclusive.
- `lat` (number): Latitude of the search centre, in decimal degrees. Requires lng and radius.
- `limit` (integer): Maximum look-alikes to return. Applied in-process — the upstream endpoint publishes no page size and returns its whole confusion set.
- `lng` (number): Longitude of the search centre, in decimal degrees. Requires lat and radius.
- `nelat` (number): North-east corner latitude of the bounding box. All four corners or none.
- `nelng` (number): North-east corner longitude of the bounding box. All four corners or none.
- `place_id` (integer): Numeric iNaturalist place id from inaturalist_find_places. Mutually exclusive with the lat/lng/radius triple and the bounding box. A non-numeric value answers HTTP 500 upstream.
- `quality_grade` (array): Identification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
- `radius` (number): Search radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
- `swlat` (number): South-west corner latitude of the bounding box. All four corners or none.
- `swlng` (number): South-west corner longitude of the bounding box. All four corners or none.
- `taxon_id` (integer, required): Numeric taxon id to find look-alikes for. Resolve a name to an id with inaturalist_resolve_name.

Output parameters:

- `cap` (number): The limit that was applied.
- `error` (object): Present when the call failed. Absent on success.
- `notice` (string): Guidance when no look-alikes are recorded, or when the limit cut the set.
- `shown` (number): How many look-alikes this response carries.
- `similar_species` (array): Look-alikes ranked by misidentification_count, most-confused first.
- `taxon_id` (number): The taxon the look-alikes were found for.
- `totalCount` (number): How many look-alikes upstream returned, before the limit was applied.
- `truncated` (boolean): True when the limit cut the confusion set.
- `truncationCeiling` (number): Misidentification count of the last look-alike shown. The ranking is descending, so no omitted look-alike exceeds it.

### `inaturalist_get_taxon` (~244 tokens)

Inaturalist Get Taxon

Fetch a taxon profile: the taxonomic path, per-authority conservation listings, the encyclopedia summary, the photo gallery, immediate children, and observation counts. Resolve a name to a taxon id with inaturalist_resolve_name first. The upstream record is 95 KB for a common species, so it is projected before anything else happens; a taxon that still overflows comes back as an outline of its sections with their byte sizes, and naming those sections in a re-call returns only those. The valid section names are summary, taxonomy, children, conservation, photos, and encyclopedia.

Input parameters:

- `sections` (array): Sections to return: summary, taxonomy, children, conservation, photos, encyclopedia. Omit for the whole profile, or an outline of it when it overflows. A selection returns whatever it names, at whate…
- `taxon_id` (integer, required): Numeric taxon id. A non-numeric value answers HTTP 422 with an empty message upstream, so the integer is enforced here. Resolve a name to an id with inaturalist_resolve_name.

Output parameters:

- `children` (array): Immediate children of this taxon.
- `common_name` (string|null): Preferred common name, when one is recorded.
- `conservation` (object): Conservation listings for the taxon.
- `encyclopedia` (object): The encyclopedia text and link upstream carries for the taxon.
- `error` (object): Present when the call failed. Absent on success.
- `extinct` (boolean): True when the taxon is recorded as extinct.
- `iconic_taxon_name` (string|null): Broad organism group, e.g. "Insecta". Usable as an iconic_taxa filter value.
- `id` (number): Taxon id.
- `is_active` (boolean): False for a taxon superseded by a taxonomic change; its id still resolves.
- `kind` (string): "full" when the profile itself is returned, "outline" when it overflowed and only the section list came back.
- `listed_taxa_count` (number|null): How many place checklists include this taxon. The checklist entries themselves are not relayed.
- `name` (string|null): Scientific name.
- `notice` (string): How to re-call for specific sections. Present on the outline.
- `observations_count` (number|null): How many observations carry this taxon or a descendant of it.
- `photos` (array): Gallery photos, each with its own licence.
- `rank` (string|null): Taxonomic rank, e.g. "species".
- `rank_level` (number|null): Numeric rank level — 70 kingdom, 30 family, 10 species, 5 subspecies.
- `sections` (array): Available sections and their byte sizes, largest first. Present on the outline.
- `sections_applied` (array): Sections this response carries. Empty when the whole profile came back, so an absent section means the taxon has none rather than that it was never asked for.
- `taxonomy` (array): Ancestors from the root of the tree down to the taxon’s parent.
- `vision` (boolean): True when the taxon is covered by the upstream image classifier.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/inaturalist#diagnostics

## Score history

- 2026-09-21: 66
- 2026-09-20: 65

## Common questions

### What is the io.github.cyanheads/inaturalist-mcp-server server?

io.github.cyanheads/inaturalist-mcp-server is listed in the public MCP registry as io.github.cyanheads/inaturalist-mcp-server. Search iNaturalist sightings, identification threads, phenology, and look-alike species. This page covers its hosted endpoint (https://inaturalist.caseyjhand.com/mcp).

### Is the io.github.cyanheads/inaturalist-mcp-server server safe to use?

io.github.cyanheads/inaturalist-mcp-server scores 66 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.github.cyanheads/inaturalist-mcp-server server expose?

io.github.cyanheads/inaturalist-mcp-server exposes 10 tools: inaturalist_list_reference, inaturalist_resolve_name, inaturalist_find_places, inaturalist_search_observations, inaturalist_get_observation, and 5 more. Their descriptions and schemas cost roughly 4,520 tokens of context every time the server is loaded.

### Does the io.github.cyanheads/inaturalist-mcp-server server require authentication?

No. We connected to io.github.cyanheads/inaturalist-mcp-server without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

### Is the io.github.cyanheads/inaturalist-mcp-server server still maintained?

io.github.cyanheads/inaturalist-mcp-server is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://inaturalist.caseyjhand.com/mcp
- Repository: https://github.com/cyanheads/inaturalist-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/inaturalist.xml
- Changelog JSON feed: https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/inaturalist.json
- HTML version of this page: https://verifymcp.io/servers/cyanheads-inaturalist-mcp-server/inaturalist
