Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.cyanheads/inaturalist-mcp-server

REMOTE · INATURALIST.CASEYJHAND.COM · 2 COMPONENTS · SCANNED SEP 21

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

66 Trust /100
Trust breakdown (7 categories)

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 Security66
  • The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
  • 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. See how to fix → View diagnostics → Unverified
  • 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
Schema Quality & AI Usability61
  • AI-judged instruction clarity (excellent).Pass
  • 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. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management3
  • Stability observed for 1 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
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 11 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
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.

remote · inaturalist.caseyjhand.com

# add to Claude Code
claude mcp add --transport http cyanheads-inaturalist-mcp-server 'https://inaturalist.caseyjhand.com/mcp'
// .cursor/mcp.json
{
  "mcpServers": {
    "cyanheads-inaturalist-mcp-server": {
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "cyanheads-inaturalist-mcp-server": {
      "type": "http",
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
# ~/.codex/config.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
    }
  }
}
# add to OpenClaw
openclaw mcp add cyanheads-inaturalist-mcp-server --url 'https://inaturalist.caseyjhand.com/mcp' --transport streamable-http
# ~/.hermes/config.yaml
mcp_servers:
  cyanheads-inaturalist-mcp-server:
    url: "https://inaturalist.caseyjhand.com/mcp"
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "cyanheads-inaturalist-mcp-server": {
      "Transport": "http",
      "Url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
# add to Vellum
assistant mcp add cyanheads-inaturalist-mcp-server -t streamable-http -u 'https://inaturalist.caseyjhand.com/mcp'
// mcp.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 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.

  • 21 Sept 26 +1
    • Stability: unverified → 0.03 functional
  • 20 Sept 26 65

    First indexed and scored.

Diagnostics

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 21 Sept 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 4 Sept 2026 3 Dec 2026 ECDSA 256 ECDSA-SHA256 a6985204ed51ae050e7738aa6be668e9
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
MCP tools · 10 exposed · ~4,520 tokens

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 →

Tool Tokens
inaturalist_find_places ~268

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.

NameTypeReqDescription
nelatnumberNorth-east corner latitude of the map area. All four corners or none.
nelngnumberNorth-east corner longitude of the map area. All four corners or none.
per_pageintegerMaximum places to return. Honoured on the bounding-box arm only — the name-prefix endpoint publishes no page size and returns a fixed page.
qstringPlace-name prefix to search. Matches the start of a name, not words inside it. Mutually exclusive with the bounding box.
swlatnumberSouth-west corner latitude of the map area. All four corners or none.
swlngnumberSouth-west corner longitude of the map area. All four corners or none.
NameTypeReqDescription
capnumberThe page size that bounded this response — per_page on the bounding-box arm, the fixed page upstream served on the name-prefix arm.
communityarrayMember-created places covering the area. Present on the bounding-box arm.
errorobjectPresent when the call failed. Absent on success.
noticestringGuidance when nothing matched, or when the page capped the result set.
placesarrayName-prefix matches. Present on the q arm.
shownnumberHow many places this response carries.
standardarrayCurated administrative places covering the area. Present on the bounding-box arm.
totalCountnumberTotal places upstream matched, before any page limit.
truncatedbooleanTrue when more places matched than were returned.

No examples provided.

inaturalist_get_histogram ~633

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.

NameTypeReqDescription
captivebooleanWhether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
d1stringEarliest 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.
d2stringLatest observation date, YYYY-MM-DD. Inclusive.
date_fieldstringWhich date to bucket by: when the organism was observed, or when the record was uploaded.
intervalstringBucketing. 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…
latnumberLatitude of the search centre, in decimal degrees. Requires lng and radius.
lngnumberLongitude of the search centre, in decimal degrees. Requires lat and radius.
nelatnumberNorth-east corner latitude of the bounding box. All four corners or none.
nelngnumberNorth-east corner longitude of the bounding box. All four corners or none.
place_idintegerNumeric 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_gradearrayIdentification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
radiusnumberSearch radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
swlatnumberSouth-west corner latitude of the bounding box. All four corners or none.
swlngnumberSouth-west corner longitude of the bounding box. All four corners or none.
taxon_idintegerRestrict to this taxon and its descendants. Omit to chart every taxon in the area. Resolve a name to an id with inaturalist_resolve_name.
NameTypeReqDescription
applied_filtersobjectThe server-applied defaults that determine what this answer means.
bucketsarrayEvery 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.
capnumberThe bucket cap that was applied.
errorobjectPresent when the call failed. Absent on success.
intervalstringThe bucketing that was applied.
noticestringGuidance when every bucket came back zero, or when the cap was reached.
shownnumberHow many buckets this response carries.
totalnumberSum of every bucket count upstream returned, including buckets past the cap that are not in the buckets array.
truncatedbooleanTrue when upstream returned more than 800 buckets.

No examples provided.

inaturalist_get_leaderboard ~570

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.

NameTypeReqDescription
d1stringEarliest observation date, YYYY-MM-DD. Inclusive.
d2stringLatest observation date, YYYY-MM-DD. Inclusive.
kindstringyesWhich leaderboard: "observers" ranks by observations recorded, "identifiers" by identifications made.
latnumberLatitude of the search centre, in decimal degrees. Requires lng and radius.
lngnumberLongitude of the search centre, in decimal degrees. Requires lat and radius.
nelatnumberNorth-east corner latitude of the bounding box. All four corners or none.
nelngnumberNorth-east corner longitude of the bounding box. All four corners or none.
pageintegerPage number. Defaults to 1.
per_pageintegerEntries 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_idintegerNumeric 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_gradearrayIdentification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
radiusnumberSearch radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
swlatnumberSouth-west corner latitude of the bounding box. All four corners or none.
swlngnumberSouth-west corner longitude of the bounding box. All four corners or none.
taxon_idintegerRestrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.
NameTypeReqDescription
applied_filtersobjectThe server-applied default that determines what this answer means.
capnumberThe per_page that was applied.
count_metricstringWhat the count on each entry measures.
entriesarrayThe ranked members, most active first.
errorobjectPresent when the call failed. Absent on success.
kindstringWhich leaderboard was ranked.
noticestringGuidance when nobody matched, or how to reach further down the ranking.
shownnumberHow many entries this page carries.
total_resultsnumberHow many people upstream reports as matching. Far larger than the 500 this leaderboard can actually address.
truncatedbooleanTrue when the page filled per_page and more entries follow.

No examples provided.

inaturalist_get_observation ~162

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.

NameTypeReqDescription
includearrayEmbedded 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_idarrayyesObservation ids to fetch, 1 to 10. Find current ids for an area with inaturalist_search_observations.
NameTypeReqDescription
errorobjectPresent when the call failed. Absent on success.
noticestringGuidance when part of the batch did not resolve.
observationsarrayThe observations that resolved, with the expansions that were requested.
unresolvedarrayRequested ids upstream returned nothing for. They may have been deleted, or never existed.

No examples provided.

inaturalist_get_similar_species ~495

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.

NameTypeReqDescription
captivebooleanWhether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
d1stringEarliest observation date, YYYY-MM-DD. Inclusive.
d2stringLatest observation date, YYYY-MM-DD. Inclusive.
latnumberLatitude of the search centre, in decimal degrees. Requires lng and radius.
limitintegerMaximum look-alikes to return. Applied in-process — the upstream endpoint publishes no page size and returns its whole confusion set.
lngnumberLongitude of the search centre, in decimal degrees. Requires lat and radius.
nelatnumberNorth-east corner latitude of the bounding box. All four corners or none.
nelngnumberNorth-east corner longitude of the bounding box. All four corners or none.
place_idintegerNumeric 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_gradearrayIdentification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
radiusnumberSearch radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
swlatnumberSouth-west corner latitude of the bounding box. All four corners or none.
swlngnumberSouth-west corner longitude of the bounding box. All four corners or none.
taxon_idintegeryesNumeric taxon id to find look-alikes for. Resolve a name to an id with inaturalist_resolve_name.
NameTypeReqDescription
capnumberThe limit that was applied.
errorobjectPresent when the call failed. Absent on success.
noticestringGuidance when no look-alikes are recorded, or when the limit cut the set.
shownnumberHow many look-alikes this response carries.
similar_speciesarrayLook-alikes ranked by misidentification_count, most-confused first.
taxon_idnumberThe taxon the look-alikes were found for.
totalCountnumberHow many look-alikes upstream returned, before the limit was applied.
truncatedbooleanTrue when the limit cut the confusion set.
truncationCeilingnumberMisidentification 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 ~665

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.

NameTypeReqDescription
captivebooleanWhether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
d1stringEarliest observation date, YYYY-MM-DD. Inclusive.
d2stringLatest observation date, YYYY-MM-DD. Inclusive.
iconic_taxaarrayBroad 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.
latnumberLatitude of the search centre, in decimal degrees. Requires lng and radius.
lngnumberLongitude of the search centre, in decimal degrees. Requires lat and radius.
nelatnumberNorth-east corner latitude of the bounding box. All four corners or none.
nelngnumberNorth-east corner longitude of the bounding box. All four corners or none.
pageintegerPage number. Defaults to 1.
per_pageintegerSpecies 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_idintegerNumeric 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_gradearrayIdentification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
radiusnumberSearch radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
swlatnumberSouth-west corner latitude of the bounding box. All four corners or none.
swlngnumberSouth-west corner longitude of the bounding box. All four corners or none.
taxon_idintegerRestrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.
term_idarrayAnnotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage.
term_value_idarrayAnnotation 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.
NameTypeReqDescription
applied_filtersobjectThe server-applied defaults that determine what this answer means.
capnumberThe per_page that was applied.
errorobjectPresent when the call failed. Absent on success.
noticestringGuidance when nothing matched, or how to reach the species beyond this page.
shownnumberHow many species this page carries.
speciesarrayThe species, ranked by observation_count, most-observed first.
total_resultsnumberHow many distinct species match. An estimate over a live index — it drifts between calls seconds apart.
truncatedbooleanTrue when the page filled per_page and more species follow.
truncationCeilingnumberObservation count of the last species shown. The ranking is descending, so no species left off this page exceeds it.

No examples provided.

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.

NameTypeReqDescription
sectionsarraySections 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_idintegeryesNumeric 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.
NameTypeReqDescription
childrenarrayImmediate children of this taxon.
common_namestring|nullPreferred common name, when one is recorded.
conservationobjectConservation listings for the taxon.
encyclopediaobjectThe encyclopedia text and link upstream carries for the taxon.
errorobjectPresent when the call failed. Absent on success.
extinctbooleanTrue when the taxon is recorded as extinct.
iconic_taxon_namestring|nullBroad organism group, e.g. "Insecta". Usable as an iconic_taxa filter value.
idnumberTaxon id.
is_activebooleanFalse for a taxon superseded by a taxonomic change; its id still resolves.
kindstring"full" when the profile itself is returned, "outline" when it overflowed and only the section list came back.
listed_taxa_countnumber|nullHow many place checklists include this taxon. The checklist entries themselves are not relayed.
namestring|nullScientific name.
noticestringHow to re-call for specific sections. Present on the outline.
observations_countnumber|nullHow many observations carry this taxon or a descendant of it.
photosarrayGallery photos, each with its own licence.
rankstring|nullTaxonomic rank, e.g. "species".
rank_levelnumber|nullNumeric rank level — 70 kingdom, 30 family, 10 species, 5 subspecies.
sectionsarrayAvailable sections and their byte sizes, largest first. Present on the outline.
sections_appliedarraySections 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.
taxonomyarrayAncestors from the root of the tree down to the taxon’s parent.
visionbooleanTrue when the taxon is covered by the upstream image classifier.

No examples provided.

inaturalist_list_reference ~214

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.

NameTypeReqDescription
taxon_idintegerAdd 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…
topicstringyesWhich vocabulary to decode. controlled_terms is fetched live and cached; the rest are spec-derived static tables.
NameTypeReqDescription
entriesarrayThe vocabulary, one entry per code or attribute.
errorobjectPresent when the call failed. Absent on success.
noticestringGuidance when the requested taxon has no recorded annotations yet.
observed_usagearrayObserved annotation usage for taxon_id, most-used first. Present only when taxon_id was given.
sourcestring"upstream" when the table was fetched from iNaturalist, "static" when spec-derived.
topicstringThe vocabulary that was decoded.

No examples provided.

inaturalist_resolve_name ~246

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.

NameTypeReqDescription
limitintegerMaximum candidates to return.
qstringyesThe 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.
rankstringRestrict taxon candidates to one rank. Honoured only on type "taxon" — the cross-kind search has no rank filter.
typestringWhich 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…
NameTypeReqDescription
candidatesarrayRanked candidates, best match first.
errorobjectPresent when the call failed. Absent on success.
foundbooleanTrue when at least one candidate matched.
guidancestringWhy nothing matched and what to try instead. Present only when found is false — this is the primary result of a miss.
totalCountnumberTotal candidates upstream matched, before the limit was applied.

No examples provided.

inaturalist_search_observations ~1,023

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.

NameTypeReqDescription
captivebooleanWhether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only.
csiarrayIUCN-normalised conservation status codes to include, e.g. ["EN","CR"]. Decode them with inaturalist_list_reference topic conservation_status_codes.
cursorstringnext_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.
d1stringEarliest observation date, YYYY-MM-DD. Inclusive.
d2stringLatest observation date, YYYY-MM-DD. Inclusive.
endemicbooleanRestrict to taxa endemic to the observation location.
hrankstringHighest taxonomic rank of the identification to accept.
iconic_taxaarrayBroad 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.
includearrayEmbedded arrays to expand per record. Check photo_count and sound_count first — expanding costs context.
introducedbooleanRestrict to taxa introduced to the observation location.
latnumberLatitude of the search centre, in decimal degrees. Requires lng and radius.
licensedbooleanRestrict to records whose own license_code is not null.
lngnumberLongitude of the search centre, in decimal degrees. Requires lat and radius.
lrankstringLowest taxonomic rank of the identification to accept.
nativebooleanRestrict to taxa native to the observation location.
nelatnumberNorth-east corner latitude of the bounding box. All four corners or none.
nelngnumberNorth-east corner longitude of the bounding box. All four corners or none.
orderstringSort direction.
order_bystringSort field. Forced to id when cursor is supplied, since a cursor only continues an id ordering.
pageintegerPage number within the first 10,000 results. Defaults to 1. Mutually exclusive with cursor.
per_pageintegerRecords 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_licensedbooleanRestrict to records with at least one licensed photo.
place_idintegerNumeric 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.
qstringFree text matched across observation properties.
quality_gradearrayIdentification confidence tiers to include. Defaults to research-grade only; adding "needs_id" roughly doubles the corpus and lowers identification confidence.
radiusnumberSearch radius around lat/lng, in KILOMETRES. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes.
search_onstringNarrow what q matches against. Requires q.
swlatnumberSouth-west corner latitude of the bounding box. All four corners or none.
swlngnumberSouth-west corner longitude of the bounding box. All four corners or none.
taxon_idintegerRestrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.
term_idarrayAnnotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage.
term_value_idarrayAnnotation 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.
threatenedbooleanRestrict to taxa considered threatened where observed.
NameTypeReqDescription
applied_filtersobjectThe server-applied defaults and overrides that determine what this answer means.
capnumberThe per_page that was applied.
errorobjectPresent when the call failed. Absent on success.
has_morebooleanTrue when this page filled per_page, so more records follow.
next_cursorstringPass back as cursor to continue past this page. Absent when has_more is false.
noticestringGuidance when nothing matched, or how to continue past a full page.
observationsarrayThe matching sightings, projected.
shownnumberHow many records this page carries.
total_resultsnumberHow many records upstream reports as matching. An estimate over a live index — it drifts between calls seconds apart.
truncatedbooleanTrue when the page filled per_page and more records follow.

No examples provided.

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.