io.github.cyanheads/inaturalist-mcp-server
REMOTE · INATURALIST.CASEYJHAND.COM · 2 COMPONENTS
Search iNaturalist sightings, identification threads, phenology, and look-alike species.
Available components
Last scanned (10 hours ago)
Scores higher than 96% of remote servers
Reachable. Last reached 5 Nov 2026.
Category Health and Science
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. How we score → Why this is hard to score →
Endpoint Security83
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- No authorisation is required to call this server. Every tool declares its destructiveHint and none is destructive, so open access doesn't expose one. See how to fix → View diagnostics → Partial
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC is configured correctly; the domain's records validate against the full chain to the root. View diagnostics → Pass
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
Schema Quality & AI Usability70
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 6921 tokens (~629/item across 11 items; 10 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
- No destabilizing schema changes in the last 30 days.Pass
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 10 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 12 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a current MCP spec version (2026-07-28).Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 1 Nov 26 0
- Tool “inaturalist_get_species_counts” rewrote its description, which is the text the model reads security
- Tool “inaturalist_get_similar_species” rewrote its description, which is the text the model reads security
- Tool “inaturalist_resolve_name” rewrote its description, which is the text the model reads security
- Tool “inaturalist_get_histogram” rewrote its description, which is the text the model reads security
- Tool “inaturalist_find_places” rewrote its description, which is the text the model reads security
- Schema quality: 551 → 629 ▼ functional
- Server version: 0.3.0 → 0.3.2 functional
- “inaturalist_resolve_name” added an optional parameter “page” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “threatened” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “rank” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “native” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “month” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “lrank” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “introduced” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “hrank” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “endemic” cosmetic
- “inaturalist_get_species_counts” added an optional parameter “csi” cosmetic
- “inaturalist_get_leaderboard” added an optional parameter “user_login” cosmetic
- “inaturalist_search_observations” added an optional parameter “updated_since” cosmetic
- “inaturalist_search_observations” added an optional parameter “month” cosmetic
- “inaturalist_search_observations” added an optional parameter “obscuration” cosmetic
- “inaturalist_get_leaderboard” added an optional parameter “user_id” cosmetic
- “inaturalist_get_leaderboard” added an optional parameter “project_id” cosmetic
- “inaturalist_get_histogram” added an optional parameter “user_login” cosmetic
- “inaturalist_get_histogram” added an optional parameter “user_id” cosmetic
- “inaturalist_get_histogram” added an optional parameter “project_id” cosmetic
- “inaturalist_search_observations” added an optional parameter “acc_below” cosmetic
- “inaturalist_search_observations” added an optional parameter “created_d1” cosmetic
- “inaturalist_search_observations” added an optional parameter “created_d2” cosmetic
- “inaturalist_search_observations” added an optional parameter “identifications” cosmetic
- “inaturalist_resolve_name” reworded the description of “type” cosmetic
- “inaturalist_search_observations” reworded the description of “csi” cosmetic
- “inaturalist_search_observations” reworded the description of “endemic” cosmetic
- “inaturalist_get_species_counts” reworded the description of “term_value_id” cosmetic
- “inaturalist_get_species_counts” reworded the description of “term_id” cosmetic
- “inaturalist_get_species_counts” reworded the description of “radius” cosmetic
- “inaturalist_get_species_counts” reworded the description of “per_page” cosmetic
- “inaturalist_get_similar_species” reworded the description of “radius” cosmetic
- “inaturalist_get_similar_species” reworded the description of “limit” cosmetic
- “inaturalist_resolve_name” reworded the description of “q” cosmetic
- “inaturalist_get_leaderboard” reworded the description of “radius” cosmetic
- “inaturalist_get_leaderboard” reworded the description of “kind” cosmetic
- “inaturalist_get_histogram” reworded the description of “term_value_id” cosmetic
- “inaturalist_get_histogram” reworded the description of “term_id” cosmetic
- “inaturalist_get_histogram” reworded the description of “radius” cosmetic
- “inaturalist_get_histogram” reworded the description of “interval” cosmetic
- “inaturalist_get_histogram” reworded the description of “d1” cosmetic
- “inaturalist_find_places” reworded the description of “q” cosmetic
- “inaturalist_find_places” reworded the description of “per_page” cosmetic
- “inaturalist_search_observations” reworded the description of “hrank” cosmetic
- “inaturalist_search_observations” reworded the description of “introduced” cosmetic
- “inaturalist_search_observations” reworded the description of “lrank” cosmetic
- “inaturalist_search_observations” reworded the description of “native” cosmetic
- “inaturalist_search_observations” reworded the description of “radius” cosmetic
- “inaturalist_search_observations” reworded the description of “term_id” cosmetic
- “inaturalist_search_observations” reworded the description of “term_value_id” cosmetic
- “inaturalist_search_observations” reworded the description of “threatened” cosmetic
- 26 Oct 26 +2
- The server rewrote its instructions, which are the text every model session reads security
- Tool “inaturalist_get_observation” rewrote its description, which is the text the model reads security
- Tool “inaturalist_list_reference” rewrote its description, which is the text the model reads security
- First check of Schema quality: 100 functional
- New resource “inaturalist-guide” functional
- Server version: 0.2.2 → 0.3.0 functional
- “inaturalist_get_histogram” added an optional parameter “created_d1” cosmetic
- “inaturalist_get_histogram” added an optional parameter “created_d2” cosmetic
- “inaturalist_search_observations” added an optional parameter “sounds” cosmetic
- “inaturalist_get_histogram” reworded the description of “quality_grade” cosmetic
- “inaturalist_get_leaderboard” reworded the description of “per_page” cosmetic
- “inaturalist_get_leaderboard” reworded the description of “quality_grade” cosmetic
- “inaturalist_get_observation” reworded the description of “observation_id” cosmetic
- “inaturalist_get_similar_species” reworded the description of “captive” cosmetic
- “inaturalist_get_similar_species” reworded the description of “limit” cosmetic
- “inaturalist_get_species_counts” reworded the description of “captive” cosmetic
- “inaturalist_get_species_counts” reworded the description of “per_page” cosmetic
- “inaturalist_get_species_counts” reworded the description of “quality_grade” cosmetic
- “inaturalist_list_reference” reworded the description of “taxon_id” cosmetic
- “inaturalist_list_reference” reworded the description of “topic” cosmetic
- “inaturalist_resolve_name” reworded the description of “limit” cosmetic
- “inaturalist_search_observations” reworded the description of “captive” cosmetic
- “inaturalist_search_observations” reworded the description of “per_page” cosmetic
- “inaturalist_search_observations” reworded the description of “quality_grade” cosmetic
- “inaturalist_get_similar_species” reworded the description of “quality_grade” cosmetic
- “inaturalist_find_places” reworded the description of “per_page” cosmetic
- “inaturalist_get_histogram” reworded the description of “captive” cosmetic
- 20 Oct 26 +1
- Stability: 0.97 → pass security
- 18 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.
- 16 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.
- 13 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 73 to 77. That category is still filling its 30-day observation window: 22 days of observed history at the previous scan, 23 at this one. The score rises as the window fills, whether or not the server changes.
- 11 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 67 to 70. That category is still filling its 30-day observation window: 20 days of observed history at the previous scan, 21 at this one. The score rises as the window fills, whether or not the server changes.
- 9 Oct 26 +2
- Server version: 0.2.1 → 0.2.2 functional
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 5 Nov 2026 · Probed https://inaturalist.caseyjhand.com/mcp
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=caseyjhand.com | CN=WE1,O=Google Trust Services,C=US | 2 Nov 2026 | 31 Jan 2027 | ECDSA 256 | ECDSA-SHA256 | 995a30681ab772540e934241ca1d576c |
| SANs: caseyjhand.com, *.caseyjhand.com | ||||||
| CN=WE1,O=Google Trust Services,C=US (CA) | CN=GTS Root R4,O=Google Trust Services LLC,C=US | 13 Dec 2023 | 20 Feb 2029 | ECDSA 256 | ECDSA-SHA384 | 7ff31977972c224a76155d13b6d685e3 |
| CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) | CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE | 15 Nov 2023 | 28 Jan 2028 | ECDSA 384 | SHA256-RSA | 7fe530bf331343bedd821610493d8a1b |
Background: What to check on a remote MCP endpoint →
DNSSEC secure
Validation of inaturalist.caseyjhand.com. — Secure
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | trust_anchor | 20326, 38696 | 8, 8 | Verified |
| com. | present | 19718 | 13 | Verified |
| caseyjhand.com. | present | 2371 | 13 | Verified |
| inaturalist.caseyjhand.com. | Verified address RRset verified with the apex keys |
Authentication No authorisation required
The endpoint answered without asking for a token. Anyone who knows the URL can reach it.
| Result | No authorisation required |
|---|---|
| HTTP status | 200 |
| Header | Value |
|---|---|
| strict-transport-security | max-age=63072000; includeSubDomains; preload |
| x-content-type-options | nosniff |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://inaturalist.caseyjhand.com/mcp | Verified | 200 | |
| http (plaintext) | http://inaturalist.caseyjhand.com/mcp | HTTPS enforced | 301 | https://inaturalist.caseyjhand.com/mcp |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
inaturalist_find_places Inaturalist Find Places ~308
Resolve a place name to a place id, or list places covering a map area. Pass q to match a display-name prefix or all analyzed query terms within it, or all four of nelat, nelng, swlat and swlng for a map area — exactly one of the two, never both. Each result carries its bounding box, place type, and containment chain. Upstream serves at most 20 places per list and may omit more.
| Name | Type | Req | Description |
|---|---|---|---|
| nelat | number | – | North-east corner latitude of the map area, at or north of swlat. All four corners or none. |
| nelng | number | – | North-east corner longitude of the map area. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian. |
| per_page | integer | – | Maximum places per list, applied to name queries and to standard and community lists separately on map queries. Served ceiling: 20; requests above it are reduced to 20. Positive safe integer requests… |
| q | string | – | Place text to search. Matches the beginning of the display name or all analyzed query terms within it. Try whole words or the beginning of the official name. 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. |
| Name | Type | Req | Description |
|---|---|---|---|
| cap | number | – | The applied per_page on name queries, or twice the applied per_page on map queries where it bounds each list separately. |
| 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 | – | Place-name 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 | – | Places upstream reports. On name queries, every match before the applied size; on map queries, only returned standard plus community places, not an exhaustive match count. |
| truncated | boolean | – | True when more places may exist than were returned — on the bounding-box arm, when the standard or community list reached per_page. |
No examples provided.
inaturalist_get_histogram Inaturalist Get Histogram ~1,072
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; absolute intervals (year, month, week, day, hour) bucket real dates and disclose their window start. 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. Narrow to one life stage or reproductive state with an annotation pair (term_id and term_value_id, e.g. Life Stage = Larva, or Flowers and Fruits = Flowers), or to broad groups with iconic_taxa. Defaults to research-grade, wild-only records and echoes those defaults back.
| Name | Type | Req | Description |
|---|---|---|---|
| captive | boolean | – | True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false. |
| created_d1 | string | – | Earliest upload date, YYYY-MM-DD. Inclusive. Must be on or before created_d2. |
| created_d2 | string | – | Latest upload date, YYYY-MM-DD. Inclusive. |
| d1 | string | – | Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. For absolute observed-date intervals, a missing d1 is derived from d2 or today UTC and disclosed as window_start. Wide range… |
| 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. |
| 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. |
| interval | string | – | Bucketing. month_of_year and week_of_year fold every year together into a seasonal curve. Absolute intervals default the selected date family's missing lower bound from its upper bound, otherwise tod… |
| 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, at or north of swlat. All four corners or none. |
| nelng | number | – | North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian. |
| 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. |
| project_id | integer | – | Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project. |
| quality_grade | array | – | Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identificat… |
| radius | number | – | Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice. |
| 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. |
| term_id | array | – | Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage. Multiple ids match any one annotation, not all annotations; arrays are membership sets, not p… |
| 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. Multiple ids match any one annotati… |
| user_id | integer | – | Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login. |
| user_login | string | – | Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id. |
| Name | Type | Req | Description |
|---|---|---|---|
| applied_filters | object | – | Effective cohort defaults, bucketed date family, and absolute window start. |
| buckets | array | – | Every bucket upstream returned, in order, including the zero ones — up to 25000, 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 | – | Generated window start, filter guidance, and continuation when buckets are cut. |
| shown | number | – | How many buckets this response carries. |
| total | number | – | Observations in the upstream histogram window: sum of every returned bucket count, including buckets past the cap; not an all-time taxon count. |
| truncated | boolean | – | True when upstream returned more than 25000 buckets. |
No examples provided.
inaturalist_get_leaderboard Inaturalist Get Leaderboard ~741
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.
| Name | Type | Req | Description |
|---|---|---|---|
| d1 | string | – | Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. |
| d2 | string | – | Latest observation date, YYYY-MM-DD. Inclusive. |
| kind | string | yes | Which leaderboard: "observers" ranks by observations recorded, "identifiers" by identifications made. user_id or user_login scopes observation ownership: observers selects that observer’s own row; id… |
| 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, at or north of swlat. All four corners or none. |
| nelng | number | – | North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian. |
| page | integer | – | Page number. Defaults to 1. |
| per_page | integer | – | Entries per page. Two ceiling-sized pages cover the 500-entry window. Ceiling: 250; oversized values are clamped. |
| 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. |
| project_id | integer | – | Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project. |
| quality_grade | array | – | Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identificat… |
| radius | number | – | Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice. |
| 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. |
| user_id | integer | – | Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login. |
| user_login | string | – | Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id. |
| Name | Type | Req | Description |
|---|---|---|---|
| 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, when the page is past the last one holding entries, 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. |
No examples provided.
inaturalist_get_observation Inaturalist Get Observation ~307
Fetch up to 10 distinct 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 attempted batch costs one upstream request. Records come back in requested order; remaining distinct ids are deferred for another call with the same include. Missing attempted ids appear in unresolved; the call fails only when nothing resolved and no deferred work remains. Long threads and observation-field lists share a response budget across resolved records — up to 40 entries per array for one record, 4 for a full batch — and every record reports the size of each array beside what it kept.
| Name | Type | Req | Description |
|---|---|---|---|
| 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. identifications and comments… |
| observation_id | array | yes | Observation ids to fetch, 1 to 100 submitted ids. The first 10 distinct ids are attempted; any remaining distinct ids are deferred to another call. Find current ids for an area with inaturalist_searc… |
| Name | Type | Req | Description |
|---|---|---|---|
| deferred | array | – | Distinct ids beyond the attempted batch, in requested order. Empty when no work remains. |
| error | object | – | Present when the call failed. Absent on success. |
| notice | string | – | Guidance when part of the batch did not resolve, or when a thread or observation-field list was cut to fit the response. |
| observations | array | – | The observations that resolved, in the requested order with unresolved ids left out, carrying the expansions that were requested. |
| unresolved | array | – | Requested ids upstream returned nothing for. They may have been deleted, or never existed. |
No examples provided.
inaturalist_get_similar_species Inaturalist Get Similar Species ~576
List related taxa ranked by observations carrying current identifications of both taxa. This is co-identification evidence, not a directional correction count or an exhaustive list of visually similar organisms. Scope it to an area in exactly one form (place_id, the lat/lng/radius triple in kilometres, or a four-corner bounding box), or leave the area off for global results. The taxon must be a genus or finer (genus, species, or below). Resolve the organism name to a taxon id with inaturalist_resolve_name first.
| Name | Type | Req | Description |
|---|---|---|---|
| captive | boolean | – | True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false. |
| d1 | string | – | Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. |
| 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 related taxa to return. Served ceiling: 24; requests above it are reduced to 24. Positive safe integer requests are accepted. |
| lng | number | – | Longitude of the search centre, in decimal degrees. Requires lat and radius. |
| nelat | number | – | North-east corner latitude of the bounding box, at or north of swlat. All four corners or none. |
| nelng | number | – | North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian. |
| 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, normalized to unique values in first-appearance order. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identificat… |
| radius | number | – | Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice. |
| 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 | yes | Numeric taxon id to find look-alikes for, at genus or finer — a genus, species, or subspecies; a family or anything coarser is refused. Resolve a name to an id with inaturalist_resolve_name. |
| Name | Type | Req | Description |
|---|---|---|---|
| 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 local limit cut the list or upstream reached its ceiling, so more related taxa may exist. |
| truncationCeiling | number | – | Misidentification count of the last look-alike shown. The ranking is descending, so no omitted look-alike exceeds it. |
No examples provided.
inaturalist_get_species_counts Inaturalist Get Species Counts ~1,078
Rank leaf taxa recorded in an area and period, most-observed first. Includes hybrids and coarser identifications; subspecies roll up to their species. 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, or to one observer or one project by user_id, user_login, or project_id. Defaults to research-grade, wild-only records and echoes those defaults back. For the most active people rather than the most recorded taxa, use inaturalist_get_leaderboard.
| Name | Type | Req | Description |
|---|---|---|---|
| captive | boolean | – | True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false. |
| csi | array | – | IUCN-normalised conservation status codes. Matches global statuses plus statuses listed at exactly place_id, excluding ancestor-place listings; decode with inaturalist_list_reference topic conservati… |
| d1 | string | – | Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. |
| d2 | string | – | Latest observation date, YYYY-MM-DD. Inclusive. |
| endemic | boolean | – | Filter the observation’s indexed taxon as endemic at its location. |
| hrank | string | – | Highest (coarsest) identification rank level to accept. Must be at or above lrank. |
| 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. |
| introduced | boolean | – | Filter the observation’s indexed taxon as introduced at its location. |
| 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. |
| lrank | string | – | Lowest (finest) identification rank level to accept. Equal bounds select a level, including ranks sharing that level such as species and hybrid. |
| month | array | – | Observed calendar months, 1–12, matched as alternatives. |
| native | boolean | – | Filter the observation’s indexed taxon as native at its location. |
| nelat | number | – | North-east corner latitude of the bounding box, at or north of swlat. All four corners or none. |
| nelng | number | – | North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian. |
| page | integer | – | Page number. Defaults to 1. |
| per_page | integer | – | Taxa per page. Raise page to continue the ranking. Ceiling: 50; oversized values are clamped. |
| 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. |
| project_id | integer | – | Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project. |
| quality_grade | array | – | Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identificat… |
| radius | number | – | Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice. |
| rank | string | – | Exact identification rank. Unlike hrank/lrank, species does not also select hybrid. |
| 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. Multiple ids match any one annotation, not all annotations; arrays are membership sets, not p… |
| 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. Multiple ids match any one annotati… |
| threatened | boolean | – | Filter the observation’s indexed taxon as threatened at its location. |
| user_id | integer | – | Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login. |
| user_login | string | – | Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id. |
| Name | Type | Req | Description |
|---|---|---|---|
| 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, when the page is past the last one holding taxa, or how to reach the taxa beyond this page. |
| shown | number | – | How many taxa this page carries. |
| species | array | – | The taxa, ranked by observation_count, most-observed first, each at its absolute position. |
| total_results | number | – | How many taxa match. An estimate over a live index — it drifts between calls seconds apart. |
| truncated | boolean | – | True when the page filled per_page and more taxa follow. |
| truncationCeiling | number | – | Observation count of the last taxon shown. The ranking is descending, so no taxon left off this page exceeds it. |
No examples provided.
inaturalist_get_taxon Inaturalist Get Taxon ~244
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.
| Name | Type | Req | Description |
|---|---|---|---|
| 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 | yes | 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. |
| Name | Type | Req | Description |
|---|---|---|---|
| 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 | – | Number of place checklists containing this taxon. |
| 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. |
No examples provided.
inaturalist_list_reference Inaturalist List Reference ~131
Look up annotation attributes/values, quality grades, licences, ranks, iconic taxa, and conservation codes before filtering; unknown values can silently return nothing. Conservation codes are the normalised csi filter, distinct from authority-specific taxon status text. With topic controlled_terms and taxon_id, also return observed annotation usage and counts.
| Name | Type | Req | Description |
|---|---|---|---|
| taxon_id | integer | – | Add annotation usage counts, most-used first; only with controlled_terms. Get the id from inaturalist_resolve_name. |
| topic | string | yes | Vocabulary to decode; controlled_terms is live/cached, the rest static. |
| Name | Type | Req | Description |
|---|---|---|---|
| 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 | – | Annotation usage, most-used first; present with taxon_id. |
| source | string | – | "upstream" for fetched data, "static" for spec-derived tables. |
| topic | string | – | The vocabulary that was decoded. |
No examples provided.
inaturalist_resolve_name Inaturalist Resolve Name ~317
Resolve organism, place, project, or observer names to identifiers. Taxon lookup matches word starts within a name, not only its beginning; other types use cross-kind search with limited spelling tolerance. Without page, candidates retain relevance order. Explicit taxon pages browse name matches in ascending taxon-ID order; this can differ from autocomplete matching across languages. A miss returns found false with recovery guidance.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Maximum candidates to return, applied to every type. Ceiling: 30; oversized values are clamped. |
| page | integer | – | Optional page for browsing beyond relevance-ranked suggestions. Taxon name pages use ascending taxon-ID order from page 1; numeric taxon IDs have only one page. Keep limit unchanged while paging. pag… |
| q | string | yes | The name to resolve. Taxon queries match word starts within a name or an exact numeric taxon id; other types match record text with limited spelling tolerance. |
| 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 autocomplete unless an explicit page browses name matches in taxon-ID order; numeric taxon IDs always use autocomplete. Other types use scored cross-kind… |
| Name | Type | Req | Description |
|---|---|---|---|
| candidates | array | – | Candidates in relevance order, or ascending taxon-ID order on explicit taxon name pages. |
| cap | number | – | Applied candidate limit. |
| error | object | – | Present when the call failed. Absent on success. |
| found | boolean | – | True when candidates matched, including an empty explicit page past an existing match set. |
| guidance | string | – | Why nothing matched and what to try instead. Present only when found is false — this is the primary result of a miss. |
| notice | string | – | Composed clamp, continuation, or empty-page guidance. |
| shown | number | – | Number of candidates returned on this slice. |
| totalCount | number | – | Total candidates upstream matched, before the limit was applied. |
| truncated | boolean | – | True when further matching candidates remain beyond this slice. |
No examples provided.
inaturalist_search_observations Inaturalist Search Observations ~1,691
Search georeferenced wildlife sightings by area, date, taxon, quality grade, annotation, conservation status, observer, project, and licence. 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. page walks the first 10,000 results under any ordering; past 10,000, order by id descending (order_by "id", order "desc") and pass each page’s next_cursor as cursor.
| Name | Type | Req | Description |
|---|---|---|---|
| acc_below | number | – | Measured positional accuracy strictly below this positive threshold in metres, up to 2147483647; fractional metres are accepted. Records without measured accuracy are excluded. |
| captive | boolean | – | True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false. |
| created_d1 | string | – | Earliest upload date, YYYY-MM-DD. Inclusive. Must be on or before created_d2. |
| created_d2 | string | – | Latest upload date, YYYY-MM-DD. Inclusive. |
| csi | array | – | IUCN-normalised conservation status codes. Matches global statuses plus statuses listed at exactly place_id, excluding ancestor-place listings; decode with inaturalist_list_reference topic conservati… |
| cursor | string | – | next_cursor from a previous id-descending 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 orde… |
| d1 | string | – | Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. |
| d2 | string | – | Latest observation date, YYYY-MM-DD. Inclusive. |
| endemic | boolean | – | Filter the observation’s indexed taxon as endemic at its location. |
| hrank | string | – | Highest (coarsest) identification rank level to accept. Must be at or above lrank. |
| 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. |
| identifications | string | – | Filter community identification agreement using one agreement category. |
| include | array | – | Embedded arrays to expand per record. Check photo_count and sound_count first — expanding costs context. |
| introduced | boolean | – | Filter the observation’s indexed taxon as introduced at its location. |
| lat | number | – | Latitude of the search centre, in decimal degrees. Requires lng and radius. |
| license | array | – | Restrict to records whose own license_code is one of these, e.g. ["cc-by","cc0"] for reuse with attribution only. Decode the codes with inaturalist_list_reference topic licenses; all-rights-reserved… |
| licensed | boolean | – | Restrict to records whose own license_code is not null — any licence, NonCommercial and NoDerivatives variants included. For specific licences, use license. |
| lng | number | – | Longitude of the search centre, in decimal degrees. Requires lat and radius. |
| lrank | string | – | Lowest (finest) identification rank level to accept. Equal bounds select a level, including ranks sharing that level such as species and hybrid. |
| month | array | – | Observed calendar months, 1–12, matched as alternatives. |
| native | boolean | – | Filter the observation’s indexed taxon as native at its location. |
| nelat | number | – | North-east corner latitude of the bounding box, at or north of swlat. All four corners or none. |
| nelng | number | – | North-east corner longitude of the bounding box. All four corners or none. West of swlng is accepted: it describes a box crossing the antimeridian. |
| obscuration | array | – | Observer or taxon geoprivacy values to include; none requires both to be open or unset. Multiple values match alternatives. |
| order | string | – | Sort direction. |
| order_by | string | – | Sort field. Set "id" with order "desc" to walk past 10,000 results: that is the one ordering next_cursor continues, so it is the only one that issues a next_cursor. A cursor forces it. |
| page | integer | – | Page number within the first 10,000 results, under any ordering. Defaults to 1. Mutually exclusive with cursor. |
| per_page | integer | – | Records fetched per page. Complete records may be deferred to keep the response within its byte budget; retrieve deferred ids through inaturalist_get_observation with the same include values. Ceiling… |
| photo_license | array | – | Restrict to records carrying at least one photo under one of these licence codes. Matched independently of the record’s own license_code, so check each photo’s license_code before reusing it. |
| photo_licensed | boolean | – | Restrict to records with at least one licensed photo, under any licence. For specific licences, use photo_license. |
| 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. |
| project_id | integer | – | Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project. |
| q | string | – | Free text matched across observation properties. |
| quality_grade | array | – | Identification confidence tiers to include, normalized to unique values in first-appearance order. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identificat… |
| radius | number | – | Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice. |
| search_on | string | – | Narrow what q matches against. Requires q. |
| sounds | boolean | – | True selects observations with sounds; false selects those without. Omit for either. Use include: ["sounds"] to expand sound metadata; no media is downloaded. |
| 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. Multiple ids match any one annotation, not all annotations; arrays are membership sets, not p… |
| 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. Multiple ids match any one annotati… |
| threatened | boolean | – | Filter the observation’s indexed taxon as threatened at its location. |
| updated_since | – | – | Records updated since this calendar date (YYYY-MM-DD) or ISO datetime with timezone, e.g. 2026-10-30T12:00:00Z. |
| user_id | integer | – | Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login. |
| user_login | string | – | Restrict to one observer, by login — the login on an inaturalist_resolve_name user candidate, a leaderboard entry, or an observation’s observer. Mutually exclusive with user_id. |
| Name | Type | Req | Description |
|---|---|---|---|
| applied_filters | object | – | The server-applied defaults and overrides that determine what this answer means. |
| cap | number | – | The per_page that was applied. |
| deferred | array | – | Ordered ids of the fetched-page suffix omitted from observations to meet the response budget. Empty when the whole page fits; independent of has_more. |
| error | object | – | Present when the call failed. Absent on success. |
| has_more | boolean | – | True when the fetched page filled the applied per_page and more records follow, independent of deferred ids. On the page path an exactly full final page is false; under a cursor, where the offset is… |
| next_cursor | string | – | Pass back as cursor to continue past this page. Present only when has_more is true and the page was ordered by id descending; under any other ordering, raise page instead. |
| notice | string | – | Composed guidance for applied limits, ignored filters, empty pages, deferred ids and pagination. |
| 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 records were deferred or more pages follow. |
No examples provided.
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.
remote · inaturalist.caseyjhand.com
claude mcp add --transport http cyanheads-inaturalist-mcp-server 'https://inaturalist.caseyjhand.com/mcp'
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 88 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 6,465 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 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.