inaturalist-mcp-server

v0.3.2 pre-1.0

Search wildlife sightings, read identification threads, rank taxa by area, chart phenology, and find look-alike taxa from iNaturalist via MCP. STDIO or Streamable HTTP.

inaturalist.caseyjhand.com/mcp
claude mcp add --transport http inaturalist-mcp-server https://inaturalist.caseyjhand.com/mcp
codex mcp add inaturalist-mcp-server --url https://inaturalist.caseyjhand.com/mcp
{
  "mcpServers": {
    "inaturalist-mcp-server": {
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http inaturalist-mcp-server https://inaturalist.caseyjhand.com/mcp
{
  "mcpServers": {
    "inaturalist-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://inaturalist.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "inaturalist-mcp-server": {
      "type": "http",
      "url": "https://inaturalist.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://inaturalist.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

10

inaturalist_list_reference

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_list_reference",
    "arguments": {
      "topic": "<topic>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "topic": {
      "type": "string",
      "enum": [
        "controlled_terms",
        "quality_grades",
        "licenses",
        "ranks",
        "iconic_taxa",
        "conservation_status_codes"
      ],
      "description": "Vocabulary to decode; controlled_terms is live/cached, the rest static."
    },
    "taxon_id": {
      "description": "Add annotation usage counts, most-used first; only with controlled_terms. Get the id from inaturalist_resolve_name.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "topic"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_resolve_name

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_resolve_name",
    "arguments": {
      "q": "<q>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "q": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "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."
    },
    "type": {
      "description": "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 search, and \"any\" searches all kinds. For place geometry and containment, use inaturalist_find_places.",
      "default": "taxon",
      "type": "string",
      "enum": [
        "taxon",
        "place",
        "project",
        "user",
        "any"
      ]
    },
    "rank": {
      "description": "Restrict taxon candidates to one rank. Honoured only on type \"taxon\" — the cross-kind search has no rank filter.",
      "type": "string",
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ]
    },
    "limit": {
      "default": 10,
      "description": "Maximum candidates to return, applied to every type. Ceiling: 30; oversized values are clamped.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "page": {
      "description": "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. page × applied limit must not exceed 10,000.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "q",
    "type",
    "limit"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_find_places

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_find_places",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "q": {
      "description": "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.",
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "nelat": {
      "description": "North-east corner latitude of the map area, at or north of swlat. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "nelng": {
      "description": "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.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "swlat": {
      "description": "South-west corner latitude of the map area. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "swlng": {
      "description": "South-west corner longitude of the map area. All four corners or none.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "per_page": {
      "default": 10,
      "description": "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 are accepted.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "per_page"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_search_observations

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_search_observations",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "place_id": {
      "description": "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.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "lat": {
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "lng": {
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "radius": {
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice.",
      "type": "number"
    },
    "nelat": {
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "nelng": {
      "description": "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.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "swlat": {
      "description": "South-west corner latitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "swlng": {
      "description": "South-west corner longitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "taxon_id": {
      "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "d1": {
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "d2": {
      "description": "Latest observation date, YYYY-MM-DD. Inclusive.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "quality_grade": {
      "default": [
        "research"
      ],
      "description": "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 identification confidence.",
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "research",
          "needs_id",
          "casual"
        ]
      }
    },
    "captive": {
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false.",
      "type": "boolean"
    },
    "term_id": {
      "description": "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 positional pairs.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      }
    },
    "term_value_id": {
      "description": "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 annotation with an attribute in term_id and a value in this set, not both annotations.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      }
    },
    "iconic_taxa": {
      "description": "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.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "Actinopterygii",
          "Amphibia",
          "Animalia",
          "Arachnida",
          "Aves",
          "Chromista",
          "Fungi",
          "Insecta",
          "Mammalia",
          "Mollusca",
          "Plantae",
          "Protozoa",
          "Reptilia",
          "unknown"
        ]
      }
    },
    "user_id": {
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "user_login": {
      "description": "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.",
      "type": "string",
      "minLength": 1
    },
    "project_id": {
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project.",
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647
    },
    "hrank": {
      "description": "Highest (coarsest) identification rank level to accept. Must be at or above lrank.",
      "type": "string",
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ]
    },
    "lrank": {
      "description": "Lowest (finest) identification rank level to accept. Equal bounds select a level, including ranks sharing that level such as species and hybrid.",
      "type": "string",
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ]
    },
    "csi": {
      "description": "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 conservation_status_codes.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "LC",
          "NT",
          "VU",
          "EN",
          "CR",
          "EW",
          "EX"
        ]
      }
    },
    "threatened": {
      "description": "Filter the observation’s indexed taxon as threatened at its location.",
      "type": "boolean"
    },
    "native": {
      "description": "Filter the observation’s indexed taxon as native at its location.",
      "type": "boolean"
    },
    "introduced": {
      "description": "Filter the observation’s indexed taxon as introduced at its location.",
      "type": "boolean"
    },
    "endemic": {
      "description": "Filter the observation’s indexed taxon as endemic at its location.",
      "type": "boolean"
    },
    "month": {
      "description": "Observed calendar months, 1–12, matched as alternatives.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 12
      }
    },
    "created_d1": {
      "description": "Earliest upload date, YYYY-MM-DD. Inclusive. Must be on or before created_d2.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "created_d2": {
      "description": "Latest upload date, YYYY-MM-DD. Inclusive.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "updated_since": {
      "description": "Records updated since this calendar date (YYYY-MM-DD) or ISO datetime with timezone, e.g. 2026-10-30T12:00:00Z.",
      "anyOf": [
        {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        },
        {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
        }
      ]
    },
    "acc_below": {
      "description": "Measured positional accuracy strictly below this positive threshold in metres, up to 2147483647; fractional metres are accepted. Records without measured accuracy are excluded.",
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "obscuration": {
      "description": "Observer or taxon geoprivacy values to include; none requires both to be open or unset. Multiple values match alternatives.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "obscured",
          "private",
          "none"
        ]
      }
    },
    "identifications": {
      "description": "Filter community identification agreement using one agreement category.",
      "type": "string",
      "enum": [
        "most_agree",
        "some_agree",
        "most_disagree"
      ]
    },
    "licensed": {
      "description": "Restrict to records whose own license_code is not null — any licence, NonCommercial and NoDerivatives variants included. For specific licences, use license.",
      "type": "boolean"
    },
    "photo_licensed": {
      "description": "Restrict to records with at least one licensed photo, under any licence. For specific licences, use photo_license.",
      "type": "boolean"
    },
    "license": {
      "description": "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 records have no code to pass.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "cc-by",
          "cc-by-nc",
          "cc-by-nd",
          "cc-by-sa",
          "cc-by-nc-nd",
          "cc-by-nc-sa",
          "cc0"
        ]
      }
    },
    "sounds": {
      "description": "True selects observations with sounds; false selects those without. Omit for either. Use include: [\"sounds\"] to expand sound metadata; no media is downloaded.",
      "type": "boolean"
    },
    "photo_license": {
      "description": "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.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "cc-by",
          "cc-by-nc",
          "cc-by-nd",
          "cc-by-sa",
          "cc-by-nc-nd",
          "cc-by-nc-sa",
          "cc0"
        ]
      }
    },
    "q": {
      "description": "Free text matched across observation properties.",
      "type": "string",
      "minLength": 1
    },
    "search_on": {
      "description": "Narrow what q matches against. Requires q.",
      "type": "string",
      "enum": [
        "names",
        "tags",
        "description",
        "place"
      ]
    },
    "order_by": {
      "description": "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.",
      "default": "observed_on",
      "type": "string",
      "enum": [
        "created_at",
        "geo_score",
        "id",
        "observed_on",
        "random",
        "species_guess",
        "updated_at",
        "votes"
      ]
    },
    "order": {
      "description": "Sort direction.",
      "default": "desc",
      "type": "string",
      "enum": [
        "asc",
        "desc"
      ]
    },
    "page": {
      "description": "Page number within the first 10,000 results, under any ordering. Defaults to 1. Mutually exclusive with cursor.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "cursor": {
      "description": "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 order_by \"id\", order \"desc\".",
      "type": "string",
      "pattern": "^[1-9]\\d*$"
    },
    "per_page": {
      "default": 10,
      "description": "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: 25; oversized values are clamped.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "include": {
      "description": "Embedded arrays to expand per record. Check photo_count and sound_count first — expanding costs context.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "photos",
          "annotations",
          "sounds"
        ]
      }
    }
  },
  "required": [
    "quality_grade",
    "captive",
    "order_by",
    "order",
    "per_page"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_get_observation

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_get_observation",
    "arguments": {
      "observation_id": "<observation_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "observation_id": {
      "minItems": 1,
      "maxItems": 100,
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      },
      "description": "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_search_observations."
    },
    "include": {
      "default": [
        "identifications"
      ],
      "description": "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 — like the observation_fields every record carries — share a 40-entry budget across the batch: each record keeps at most 40 ÷ records returned entries per array (never fewer than 4), and reports identifications_total, comments_total, and observation_fields_total beside what it kept — request one id alone for the 40-entry view.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "identifications",
          "comments",
          "photos",
          "annotations",
          "sounds"
        ]
      }
    }
  },
  "required": [
    "observation_id",
    "include"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_get_species_counts

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_get_species_counts",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "place_id": {
      "description": "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.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "lat": {
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "lng": {
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "radius": {
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice.",
      "type": "number"
    },
    "nelat": {
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "nelng": {
      "description": "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.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "swlat": {
      "description": "South-west corner latitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "swlng": {
      "description": "South-west corner longitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "taxon_id": {
      "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "d1": {
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "d2": {
      "description": "Latest observation date, YYYY-MM-DD. Inclusive.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "quality_grade": {
      "default": [
        "research"
      ],
      "description": "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 identification confidence.",
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "research",
          "needs_id",
          "casual"
        ]
      }
    },
    "captive": {
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false.",
      "type": "boolean"
    },
    "term_id": {
      "description": "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 positional pairs.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      }
    },
    "term_value_id": {
      "description": "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 annotation with an attribute in term_id and a value in this set, not both annotations.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      }
    },
    "iconic_taxa": {
      "description": "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.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "Actinopterygii",
          "Amphibia",
          "Animalia",
          "Arachnida",
          "Aves",
          "Chromista",
          "Fungi",
          "Insecta",
          "Mammalia",
          "Mollusca",
          "Plantae",
          "Protozoa",
          "Reptilia",
          "unknown"
        ]
      }
    },
    "user_id": {
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "user_login": {
      "description": "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.",
      "type": "string",
      "minLength": 1
    },
    "project_id": {
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project.",
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647
    },
    "hrank": {
      "description": "Highest (coarsest) identification rank level to accept. Must be at or above lrank.",
      "type": "string",
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ]
    },
    "lrank": {
      "description": "Lowest (finest) identification rank level to accept. Equal bounds select a level, including ranks sharing that level such as species and hybrid.",
      "type": "string",
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ]
    },
    "csi": {
      "description": "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 conservation_status_codes.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "LC",
          "NT",
          "VU",
          "EN",
          "CR",
          "EW",
          "EX"
        ]
      }
    },
    "threatened": {
      "description": "Filter the observation’s indexed taxon as threatened at its location.",
      "type": "boolean"
    },
    "native": {
      "description": "Filter the observation’s indexed taxon as native at its location.",
      "type": "boolean"
    },
    "introduced": {
      "description": "Filter the observation’s indexed taxon as introduced at its location.",
      "type": "boolean"
    },
    "endemic": {
      "description": "Filter the observation’s indexed taxon as endemic at its location.",
      "type": "boolean"
    },
    "month": {
      "description": "Observed calendar months, 1–12, matched as alternatives.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 12
      }
    },
    "rank": {
      "description": "Exact identification rank. Unlike hrank/lrank, species does not also select hybrid.",
      "type": "string",
      "enum": [
        "stateofmatter",
        "kingdom",
        "phylum",
        "subphylum",
        "superclass",
        "class",
        "subclass",
        "infraclass",
        "subterclass",
        "superorder",
        "order",
        "suborder",
        "infraorder",
        "parvorder",
        "zoosection",
        "zoosubsection",
        "superfamily",
        "epifamily",
        "family",
        "subfamily",
        "supertribe",
        "tribe",
        "subtribe",
        "genus",
        "genushybrid",
        "subgenus",
        "section",
        "subsection",
        "complex",
        "species",
        "hybrid",
        "subspecies",
        "variety",
        "form",
        "infrahybrid"
      ]
    },
    "page": {
      "default": 1,
      "description": "Page number. Defaults to 1.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "default": 25,
      "description": "Taxa per page. Raise page to continue the ranking. Ceiling: 50; oversized values are clamped.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "quality_grade",
    "captive",
    "page",
    "per_page"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_get_histogram

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_get_histogram",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "taxon_id": {
      "description": "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.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "place_id": {
      "description": "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.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "lat": {
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "lng": {
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "radius": {
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice.",
      "type": "number"
    },
    "nelat": {
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "nelng": {
      "description": "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.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "swlat": {
      "description": "South-west corner latitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "swlng": {
      "description": "South-west corner longitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "user_id": {
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "user_login": {
      "description": "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.",
      "type": "string",
      "minLength": 1
    },
    "project_id": {
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project.",
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647
    },
    "interval": {
      "description": "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 today UTC: year/month subtract 100 calendar years, week 10 years, day one year, hour seven days. The start is disclosed; no upper bound is added. At most 25000 buckets are returned, oldest first, with continuation guidance when cut.",
      "default": "month_of_year",
      "type": "string",
      "enum": [
        "year",
        "month",
        "week",
        "day",
        "hour",
        "month_of_year",
        "week_of_year"
      ]
    },
    "date_field": {
      "description": "Which date to bucket by: when the organism was observed, or when the record was uploaded.",
      "default": "observed",
      "type": "string",
      "enum": [
        "observed",
        "created"
      ]
    },
    "d1": {
      "description": "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 ranges can exceed the 25000-bucket cap; continuation names d1, or created_d1 for upload-date bucketing.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "d2": {
      "description": "Latest observation date, YYYY-MM-DD. Inclusive.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "created_d1": {
      "description": "Earliest upload date, YYYY-MM-DD. Inclusive. Must be on or before created_d2.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "created_d2": {
      "description": "Latest upload date, YYYY-MM-DD. Inclusive.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "quality_grade": {
      "default": [
        "research"
      ],
      "description": "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 identification confidence.",
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "research",
          "needs_id",
          "casual"
        ]
      }
    },
    "captive": {
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false.",
      "type": "boolean"
    },
    "term_id": {
      "description": "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 positional pairs.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      }
    },
    "term_value_id": {
      "description": "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 annotation with an attribute in term_id and a value in this set, not both annotations.",
      "type": "array",
      "items": {
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      }
    },
    "iconic_taxa": {
      "description": "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.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "Actinopterygii",
          "Amphibia",
          "Animalia",
          "Arachnida",
          "Aves",
          "Chromista",
          "Fungi",
          "Insecta",
          "Mammalia",
          "Mollusca",
          "Plantae",
          "Protozoa",
          "Reptilia",
          "unknown"
        ]
      }
    }
  },
  "required": [
    "interval",
    "date_field",
    "quality_grade",
    "captive"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_get_leaderboard

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_get_leaderboard",
    "arguments": {
      "kind": "<kind>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "observers",
        "identifiers"
      ],
      "description": "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; identifiers selects people who identified that observer’s observations, not identifications authored by that observer. project_id scopes observations to one project."
    },
    "place_id": {
      "description": "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.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "lat": {
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "lng": {
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "radius": {
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice.",
      "type": "number"
    },
    "nelat": {
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "nelng": {
      "description": "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.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "swlat": {
      "description": "South-west corner latitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "swlng": {
      "description": "South-west corner longitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "user_id": {
      "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "user_login": {
      "description": "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.",
      "type": "string",
      "minLength": 1
    },
    "project_id": {
      "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project.",
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647
    },
    "taxon_id": {
      "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "d1": {
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "d2": {
      "description": "Latest observation date, YYYY-MM-DD. Inclusive.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "quality_grade": {
      "default": [
        "research"
      ],
      "description": "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 identification confidence.",
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "research",
          "needs_id",
          "casual"
        ]
      }
    },
    "page": {
      "default": 1,
      "description": "Page number. Defaults to 1.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "default": 25,
      "description": "Entries per page. Two ceiling-sized pages cover the 500-entry window. Ceiling: 250; oversized values are clamped.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "kind",
    "quality_grade",
    "page",
    "per_page"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_get_similar_species

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_get_similar_species",
    "arguments": {
      "taxon_id": "<taxon_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "taxon_id": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991,
      "description": "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."
    },
    "place_id": {
      "description": "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.",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "lat": {
      "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "lng": {
      "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "radius": {
      "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. Ceiling: 20040; oversized values are clamped with notice.",
      "type": "number"
    },
    "nelat": {
      "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "nelng": {
      "description": "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.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "swlat": {
      "description": "South-west corner latitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "swlng": {
      "description": "South-west corner longitude of the bounding box. All four corners or none.",
      "type": "number",
      "minimum": -180,
      "maximum": 180
    },
    "d1": {
      "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "d2": {
      "description": "Latest observation date, YYYY-MM-DD. Inclusive.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "quality_grade": {
      "default": [
        "research"
      ],
      "description": "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 identification confidence.",
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "research",
          "needs_id",
          "casual"
        ]
      }
    },
    "captive": {
      "default": false,
      "description": "True returns captive and cultivated records only — zoo animals, garden plantings; false returns wild records only. Defaults to false.",
      "type": "boolean"
    },
    "limit": {
      "default": 20,
      "description": "Maximum related taxa to return. Served ceiling: 24; requests above it are reduced to 24. Positive safe integer requests are accepted.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "taxon_id",
    "quality_grade",
    "captive",
    "limit"
  ],
  "additionalProperties": false
}
view source ↗

inaturalist_get_taxon

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "inaturalist_get_taxon",
    "arguments": {
      "taxon_id": "<taxon_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "taxon_id": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991,
      "description": "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."
    },
    "sections": {
      "description": "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 whatever size, so sum the byte sizes from the outline before asking for several.",
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    }
  },
  "required": [
    "taxon_id"
  ],
  "additionalProperties": false
}
view source ↗

Resources

2

Taxon profile by numeric iNaturalist taxon id — taxonomic path, per-authority conservation listings, encyclopedia summary, photo gallery, immediate children, and observation counts. The whole projected document, whatever its size: a resource read has no way to name sections, so use inaturalist_get_taxon when the outline-and-sections path matters.

uri inaturalist://taxa/{taxon_id} mime application/json

One iNaturalist observation by numeric id, with its community identification thread expanded — who identified what, whether each identification agrees, and the consensus taxon — plus the observer’s description and filled observation fields. The thread keeps its first 40 identifications and the list its first 40 filled fields, both in upstream order; identifications_total beside identifications_shown, and observation_fields_total beside observation_fields_shown, say whether either was cut, and the record’s url opens the full record. An obscured coordinate is a locality with an accuracy radius, never a sighting position, and a null license_code means all rights reserved.

uri inaturalist://observations/{observation_id} mime application/json

Extensions

1

io.modelcontextprotocol/skills

{
  "directoryRead": true
}