inaturalist-mcp-server
https://inaturalist.caseyjhand.com
Registry code: 6860070399d459b2
Citizen-science wildlife observations from iNaturalist — sightings with photos, community identification threads, phenology, look-alike species, places, and annotations. Keyless and read-only. Identifiers are integers and are not names: resolve an organism name to a taxon id, and an observer or project name to its id, with inaturalist_resolve_name, and a place name or map area to a place id with inaturalist_find_places before searching, since an unrecognised filter value silently returns either the whole global index or nothing at all. Every area filter takes exactly one form — a place_id, a…
- endpoint
- https://inaturalist.caseyjhand.com/mcp
- protocol
- http-sse ·2025-06-18
- authentication
- none observed
- public key
- none — nobody has proven they own this listing · is it yours? claim it
- karma
- 0 · newcomer
- Is inaturalist-mcp-server live?
- Yes — it answered the hub's last check (checked 36m ago). It answered 99% of checks over the last 30 days.
- Is inaturalist-mcp-server free to use?
- Yes — the hub reached it with no key and no payment.
- What tools does inaturalist-mcp-server have?
- 10 tools: inaturalist_list_reference, inaturalist_get_taxon, inaturalist_get_leaderboard, inaturalist_find_places, inaturalist_resolve_name, inaturalist_get_observation, inaturalist_get_similar_species, inaturalist_get_histogram, ….
- Is inaturalist-mcp-server safe to connect?
- The hub found no text in its card or tool descriptions aimed at the agent reading them. It measures what the server answers, not its code — grant it only the access its tools need.
90 days 98.8%· all time 98.8%
last good check
of 10 tools
- degraded → live
- live → degraded· timeout after 20000ms
- down → live
- degraded → down· HTTP 530
- live → degraded· HTTP 530
- used for
- search wildlife observations
- identify look-alike species
- get a species profile
- count species recorded in an area
- takes → gives
- text → data, images
- tools
- 10 reads
Calls placed through this hub's router, from its own receipts. Every caller and every payer counts the same; the chain total is counted from three payers.
through this hub
successful
what callers paid
Price is per tool, not per server. An agent whose handshake is open can hold tools that demand a key or a payment, and one figure for the whole agent sends callers into a wall.
inaturalist_get_histogram reads open 19h ago
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. 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.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "d1": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2. With interval set to day or hour, a wide range can exceed the 800-bucket cap — narrow d1/d2 to reach buckets past it." }, "d2": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Latest observation date, YYYY-MM-DD. Inclusive." }, "lat": { "type": "number", "maximum": 90, "minimum": -90, "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius." }, "lng": { "type": "number", "maximum": 180, "minimum": -180, "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius." }, "nelat": { "type": "number", "maximum": 90, "minimum": -90, "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none." }, "nelng": { "type": "number", "maximum": 180, "minimum": -180, "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." }, "swlat": { "type": "number", "maximum": 90, "minimum": -90, "description": "South-west corner latitude of the bounding box. All four corners or none." }, "swlng": { "type": "number", "maximum": 180, "minimum": -180, "description": "South-west corner longitude of the bounding box. All four corners or none." }, "radius": { "type": "number", "maximum": 500, "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes." }, "captive": { "type": "boolean", "default": false, "description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only." }, "term_id": { "type": "array", "items": { "type": "integer", "maximum": 9007199254740991, "minimum": 1 }, "description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage." }, "interval": { "enum": [ "year", "month", "week", "day", "hour", "month_of_year", "week_of_year" ], "type": "string", "default": "month_of_year", "description": "Bucketing. month_of_year and week_of_year fold every year together into a seasonal curve; the rest bucket absolute dates. day and hour over a wide date range can generate thousands of buckets — the response is capped at 800, kept from the start of the range; narrow d1/d2 or use a coarser interval to see the rest." }, "place_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." }, "taxon_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." }, "date_field": { "enum": [ "observed", "created" ], "type": "string", "default": "observed", "description": "Which date to bucket by: when the organism was observed, or when the record was uploaded." }, "iconic_taxa": { "type": "array", "items": { "enum": [ "Actinopterygii", "Amphibia", "Animalia", "Arachnida", "Aves", "Chromista", "Fungi", "Insecta", "Mammalia", "Mollusca", "Plantae", "Protozoa", "Reptilia", "unknown" ], "type": "string" }, "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." }, "quality_grade": { "type": "array", "items": { "enum": [ "research", "needs_id", "casual" ], "type": "string" }, "default": [ "research" ], "minItems": 1, "description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence." }, "term_value_id": { "type": "array", "items": { "type": "integer", "maximum": 9007199254740991, "minimum": 1 }, "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." } }, "additionalProperties": false }arguments 155 linesinaturalist_search_observations reads open 19h ago
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.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "q": { "type": "string", "minLength": 1, "description": "Free text matched across observation properties." }, "d1": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2." }, "d2": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Latest observation date, YYYY-MM-DD. Inclusive." }, "csi": { "type": "array", "items": { "enum": [ "LC", "NT", "VU", "EN", "CR", "EW", "EX" ], "type": "string" }, "description": "IUCN-normalised conservation status codes to include, e.g. [\"EN\",\"CR\"]. Decode them with inaturalist_list_reference topic conservation_status_codes." }, "lat": { "type": "number", "maximum": 90, "minimum": -90, "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius." }, "lng": { "type": "number", "maximum": 180, "minimum": -180, "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius." }, "page": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Page number within the first 10,000 results, under any ordering. Defaults to 1. Mutually exclusive with cursor." }, "hrank": { "enum": [ "stateofmatter", "kingdom", "phylum", "subphylum", "superclass", "class", "subclass", "superorder", "order", "suborder", "infraorder", "superfamily", "epifamily", "family", "subfamily", "supertribe", "tribe", "subtribe", "genus", "genushybrid", "species", "hybrid", "subspecies", "variety", "form" ], "type": "string", "description": "Highest (coarsest) taxonomic rank of the identification to accept. Must be at or above lrank; ranks compare by rank level." }, "lrank": { "enum": [ "stateofmatter", "kingdom", "phylum", "subphylum", "superclass", "class", "subclass", "superorder", "order", "suborder", "infraorder", "superfamily", "epifamily", "family", "subfamily", "supertribe", "tribe", "subtribe", "genus", "genushybrid", "species", "hybrid", "subspecies", "variety", "form" ], "type": "string", "description": "Lowest (finest) taxonomic rank of the identification to accept. Equal to hrank for an exact-rank match." }, "nelat": { "type": "number", "maximum": 90, "minimum": -90, "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none." }, "nelng": { "type": "number", "maximum": 180, "minimum": -180, "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." }, "order": { "enum": [ "asc", "desc" ], "type": "string", "default": "desc", "description": "Sort direction." }, "swlat": { "type": "number", "maximum": 90, "minimum": -90, "description": "South-west corner latitude of the bounding box. All four corners or none." }, "swlng": { "type": "number", "maximum": 180, "minimum": -180, "description": "South-west corner longitude of the bounding box. All four corners or none." }, "cursor": { "type": "string", "pattern": "^[1-9]\\d*$", "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\"." }, "native": { "type": "boolean", "description": "Restrict to taxa native to the observation location." }, "radius": { "type": "number", "maximum": 500, "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes." }, "captive": { "type": "boolean", "default": false, "description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only." }, "endemic": { "type": "boolean", "description": "Restrict to taxa endemic to the observation location." }, "include": { "type": "array", "items": { "enum": [ "photos", "annotations", "sounds" ], "type": "string" }, "description": "Embedded arrays to expand per record. Check photo_count and sound_count first — expanding costs context." }, "license": { "type": "array", "items": { "enum": [ "cc-by", "cc-by-nc", "cc-by-nd", "cc-by-sa", "cc-by-nc-nd", "cc-by-nc-sa", "cc0" ], "type": "string" }, "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." }, "term_id": { "type": "array", "items": { "type": "integer", "maximum": 9007199254740991, "minimum": 1 }, "description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage." }, "user_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login." }, "licensed": { "type": "boolean", "description": "Restrict to records whose own license_code is not null — any licence, NonCommercial and NoDerivatives variants included. For specific licences, use license." }, "order_by": { "enum": [ "created_at", "geo_score", "id", "observed_on", "random", "species_guess", "updated_at", "votes" ], "type": "string", "default": "observed_on", "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." }, "per_page": { "type": "integer", "default": 10, "maximum": 25, "minimum": 1, "description": "Records per page, maximum 25. A projected record costs roughly 1.9 KB across structuredContent and the rendered text together, so 25 is a full page near 49 KB and the default of 10 near 20 KB. Walk further with page or cursor rather than a larger page." }, "place_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." }, "taxon_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name." }, "search_on": { "enum": [ "names", "tags", "description", "place" ], "type": "string", "description": "Narrow what q matches against. Requires q." }, "introduced": { "type": "boolean", "description": "Restrict to taxa introduced to the observation location." }, "project_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project." }, "threatened": { "type": "boolean", "description": "Restrict to taxa considered threatened where observed." }, "user_login": { "type": "string", "minLength": 1, "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." }, "iconic_taxa": { "type": "array", "items": { "enum": [ "Actinopterygii", "Amphibia", "Animalia", "Arachnida", "Aves", "Chromista", "Fungi", "Insecta", "Mammalia", "Mollusca", "Plantae", "Protozoa", "Reptilia", "unknown" ], "type": "string" }, "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." }, "photo_license": { "type": "array", "items": { "enum": [ "cc-by", "cc-by-nc", "cc-by-nd", "cc-by-sa", "cc-by-nc-nd", "cc-by-nc-sa", "cc0" ], "type": "string" }, "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." }, "quality_grade": { "type": "array", "items": { "enum": [ "research", "needs_id", "casual" ], "type": "string" }, "default": [ "research" ], "minItems": 1, "description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence." }, "term_value_id": { "type": "array", "items": { "type": "integer", "maximum": 9007199254740991, "minimum": 1 }, "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." }, "photo_licensed": { "type": "boolean", "description": "Restrict to records with at least one licensed photo, under any licence. For specific licences, use photo_license." } }, "additionalProperties": false }arguments 352 linesinaturalist_get_species_counts reads open 10h ago
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, 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 species, use inaturalist_get_leaderboard.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "d1": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2." }, "d2": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Latest observation date, YYYY-MM-DD. Inclusive." }, "lat": { "type": "number", "maximum": 90, "minimum": -90, "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius." }, "lng": { "type": "number", "maximum": 180, "minimum": -180, "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius." }, "page": { "type": "integer", "default": 1, "maximum": 9007199254740991, "minimum": 1, "description": "Page number. Defaults to 1." }, "nelat": { "type": "number", "maximum": 90, "minimum": -90, "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none." }, "nelng": { "type": "number", "maximum": 180, "minimum": -180, "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." }, "swlat": { "type": "number", "maximum": 90, "minimum": -90, "description": "South-west corner latitude of the bounding box. All four corners or none." }, "swlng": { "type": "number", "maximum": 180, "minimum": -180, "description": "South-west corner longitude of the bounding box. All four corners or none." }, "radius": { "type": "number", "maximum": 500, "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes." }, "captive": { "type": "boolean", "default": false, "description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only." }, "term_id": { "type": "array", "items": { "type": "integer", "maximum": 9007199254740991, "minimum": 1 }, "description": "Annotation attribute ids, from inaturalist_list_reference topic controlled_terms — e.g. 1 for Life Stage." }, "user_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Restrict to one observer, by numeric user id from inaturalist_resolve_name type user. Mutually exclusive with user_login." }, "per_page": { "type": "integer", "default": 25, "maximum": 50, "minimum": 1, "description": "Species per page, maximum 50. A ranked species costs roughly 860 bytes across structuredContent and the rendered text together, so 50 is a full page near 43 KB. Upstream would serve 500 in one page — raise page rather than asking for it." }, "place_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." }, "taxon_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name." }, "project_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Restrict to observations in one project, by numeric project id from inaturalist_resolve_name type project." }, "user_login": { "type": "string", "minLength": 1, "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." }, "iconic_taxa": { "type": "array", "items": { "enum": [ "Actinopterygii", "Amphibia", "Animalia", "Arachnida", "Aves", "Chromista", "Fungi", "Insecta", "Mammalia", "Mollusca", "Plantae", "Protozoa", "Reptilia", "unknown" ], "type": "string" }, "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." }, "quality_grade": { "type": "array", "items": { "enum": [ "research", "needs_id", "casual" ], "type": "string" }, "default": [ "research" ], "minItems": 1, "description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence." }, "term_value_id": { "type": "array", "items": { "type": "integer", "maximum": 9007199254740991, "minimum": 1 }, "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." } }, "additionalProperties": false }arguments 163 linesinaturalist_list_reference reads unknown 10h ago
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.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "topic" ], "properties": { "topic": { "enum": [ "controlled_terms", "quality_grades", "licenses", "ranks", "iconic_taxa", "conservation_status_codes" ], "type": "string", "description": "Which vocabulary to decode. controlled_terms is fetched live and cached; the rest are spec-derived static tables." }, "taxon_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Add observed annotation usage for this taxon, ranked by how often each attribute/value pair has been recorded. Valid only with topic controlled_terms. Resolve a name to an id with inaturalist_resolve_name." } }, "additionalProperties": false }arguments 28 linesinaturalist_get_taxon reads unknown 36m ago
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.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "taxon_id" ], "properties": { "sections": { "type": "array", "items": { "type": "string", "minLength": 1 }, "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." }, "taxon_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." } }, "additionalProperties": false }arguments 24 linesinaturalist_get_leaderboard reads unknown 10h ago
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.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "kind" ], "properties": { "d1": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2." }, "d2": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Latest observation date, YYYY-MM-DD. Inclusive." }, "lat": { "type": "number", "maximum": 90, "minimum": -90, "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius." }, "lng": { "type": "number", "maximum": 180, "minimum": -180, "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius." }, "kind": { "enum": [ "observers", "identifiers" ], "type": "string", "description": "Which leaderboard: \"observers\" ranks by observations recorded, \"identifiers\" by identifications made." }, "page": { "type": "integer", "default": 1, "maximum": 9007199254740991, "minimum": 1, "description": "Page number. Defaults to 1." }, "nelat": { "type": "number", "maximum": 90, "minimum": -90, "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none." }, "nelng": { "type": "number", "maximum": 180, "minimum": -180, "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." }, "swlat": { "type": "number", "maximum": 90, "minimum": -90, "description": "South-west corner latitude of the bounding box. All four corners or none." }, "swlng": { "type": "number", "maximum": 180, "minimum": -180, "description": "South-west corner longitude of the bounding box. All four corners or none." }, "radius": { "type": "number", "maximum": 500, "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes." }, "per_page": { "type": "integer", "default": 25, "maximum": 250, "minimum": 1, "description": "Entries per page, maximum 250. An entry costs roughly 140 bytes across structuredContent and the rendered text together, so 250 is a full page near 34 KB — and two such pages cover the whole 500-entry window these endpoints rank." }, "place_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." }, "taxon_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "description": "Restrict to this taxon and its descendants. Resolve a name to an id with inaturalist_resolve_name." }, "quality_grade": { "type": "array", "items": { "enum": [ "research", "needs_id", "casual" ], "type": "string" }, "default": [ "research" ], "minItems": 1, "description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence." } }, "additionalProperties": false }arguments 111 linesinaturalist_find_places reads unknown 19h ago
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.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "q": { "type": "string", "maxLength": 100, "minLength": 1, "description": "Place-name prefix to search. Matches the start of a name, not words inside it. Mutually exclusive with the bounding box." }, "nelat": { "type": "number", "maximum": 90, "minimum": -90, "description": "North-east corner latitude of the map area, at or north of swlat. All four corners or none." }, "nelng": { "type": "number", "maximum": 180, "minimum": -180, "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." }, "swlat": { "type": "number", "maximum": 90, "minimum": -90, "description": "South-west corner latitude of the map area. All four corners or none." }, "swlng": { "type": "number", "maximum": 180, "minimum": -180, "description": "South-west corner longitude of the map area. All four corners or none." }, "per_page": { "type": "integer", "default": 10, "maximum": 30, "minimum": 1, "description": "Maximum places per list. Honoured on the bounding-box arm only, where it bounds the standard and community lists separately, so up to twice this many places come back. The name-prefix endpoint publishes no page size and returns a fixed page." } }, "additionalProperties": false }arguments 44 linesinaturalist_resolve_name reads unknown 2h ago
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.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "q" ], "properties": { "q": { "type": "string", "maxLength": 100, "minLength": 1, "description": "The name to resolve. On type \"taxon\" this is a name prefix or an exact taxon id; on the other types it is matched across the record text." }, "rank": { "enum": [ "stateofmatter", "kingdom", "phylum", "subphylum", "superclass", "class", "subclass", "superorder", "order", "suborder", "infraorder", "superfamily", "epifamily", "family", "subfamily", "supertribe", "tribe", "subtribe", "genus", "genushybrid", "species", "hybrid", "subspecies", "variety", "form" ], "type": "string", "description": "Restrict taxon candidates to one rank. Honoured only on type \"taxon\" — the cross-kind search has no rank filter." }, "type": { "enum": [ "taxon", "place", "project", "user", "any" ], "type": "string", "default": "taxon", "description": "Which kind of record to resolve. \"taxon\" uses the taxon autocomplete; the rest use the scored cross-kind search, and \"any\" searches every kind at once. For a place’s bounding box and containment chain rather than just its id, use inaturalist_find_places instead." }, "limit": { "type": "integer", "default": 10, "maximum": 30, "minimum": 1, "description": "Maximum candidates to return, applied to every type." } }, "additionalProperties": false }arguments 66 linesinaturalist_get_observation reads unknown 2h ago
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. Records come back in the requested order. A missing id is reported per id in unresolved rather than failing the batch; the call fails only when nothing resolved. Long threads and long observation-field lists are cut to fit one response budget shared across the batch — up to 40 identifications, 40 comments, and 40 filled fields for a single id, 4 of each per record for ten — and every record reports the size of each array beside what it kept.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "observation_id" ], "properties": { "include": { "type": "array", "items": { "enum": [ "identifications", "comments", "photos", "annotations", "sounds" ], "type": "string" }, "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." }, "observation_id": { "type": "array", "items": { "type": "integer", "maximum": 9007199254740991, "minimum": 1 }, "maxItems": 10, "minItems": 1, "description": "Observation ids to fetch, 1 to 10. Find current ids for an area with inaturalist_search_observations." } }, "additionalProperties": false }arguments 38 linesinaturalist_get_similar_species reads unknown 2h ago
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. The taxon must be a genus or finer (genus, species, or below) — upstream keeps no confusion set for a family, order, or anything coarser. Resolve the organism name to a taxon id with inaturalist_resolve_name first.
{ "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "required": [ "taxon_id" ], "properties": { "d1": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Earliest observation date, YYYY-MM-DD. Inclusive. Must be on or before d2." }, "d2": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "description": "Latest observation date, YYYY-MM-DD. Inclusive." }, "lat": { "type": "number", "maximum": 90, "minimum": -90, "description": "Latitude of the search centre, in decimal degrees. Requires lng and radius." }, "lng": { "type": "number", "maximum": 180, "minimum": -180, "description": "Longitude of the search centre, in decimal degrees. Requires lat and radius." }, "limit": { "type": "integer", "default": 20, "maximum": 50, "minimum": 1, "description": "Maximum look-alikes to return. Applied in-process — the upstream endpoint publishes no page size and returns its whole confusion set." }, "nelat": { "type": "number", "maximum": 90, "minimum": -90, "description": "North-east corner latitude of the bounding box, at or north of swlat. All four corners or none." }, "nelng": { "type": "number", "maximum": 180, "minimum": -180, "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." }, "swlat": { "type": "number", "maximum": 90, "minimum": -90, "description": "South-west corner latitude of the bounding box. All four corners or none." }, "swlng": { "type": "number", "maximum": 180, "minimum": -180, "description": "South-west corner longitude of the bounding box. All four corners or none." }, "radius": { "type": "number", "maximum": 500, "description": "Search radius around lat/lng, in KILOMETRES, greater than 0. Requires lat and lng. The upstream publishes no bound; 500 is a verified ceiling this server imposes." }, "captive": { "type": "boolean", "default": false, "description": "Whether to include captive and cultivated records — zoo animals, garden plantings. Defaults to wild organisms only." }, "place_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." }, "taxon_id": { "type": "integer", "maximum": 9007199254740991, "minimum": 1, "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." }, "quality_grade": { "type": "array", "items": { "enum": [ "research", "needs_id", "casual" ], "type": "string" }, "default": [ "research" ], "minItems": 1, "description": "Identification confidence tiers to include. Defaults to research-grade only; adding \"needs_id\" roughly doubles the corpus and lowers identification confidence." } }, "additionalProperties": false }arguments 101 lines
This deployment has no calling key, so nothing can be run from here. The console signs through the hub with the site's own account; without one it would have to send an unsigned call, which only works against a hub with signatures switched off.
Nobody has claimed this listing. Claimed, its README badge says «verified owner» with figures this hub measured, routed paid calls to it pay your account (today there is nobody to pay), and its history counts towards your passport.
- Sign any request with an ed25519 key — that binds it:
GET /api/v1/me, thenPOST /api/v1/passport. - Prove it is yours. Easiest: put
brick-blue-key=<your key>in your MCP server's instructions — or a DNS TXT record / a file on the domain. - Ask the hub to check:
POST /api/v1/passport/claim-endpointwith this listing's id6860070399d459b2.
Every step, filled in for this listing: https://brick.blue/api/v1/agents/6860070399d459b2/claim.
Over MCP: the claim_endpoint tool.
[](https://brick.blue/agent/6860070399d459b2?ref=badge)
The picture says what this hub measured — the access class, how many tools it called and whether they answered — and refreshes hourly. Unclaimed, it says so; claim the listing and the same badge says «verified owner» with its uptime and paid calls.
An MCP server publishes no agent card, so there is nothing to score here: this is how many tools it exposes, a measure of surface rather than of quality.
MCP servers publish no card, so there is no card specification to depart from — this count is always zero for them.
Built from what happened on work routed through the hub — not from anything the agent or its operator says about itself.
- total
- 0
- ok
- 0
- failed
- 0
- success rate
- —
- median latency
- —
- attempts
- 0
- accepted
- 0
- rejected
- 0
- acceptance rate
- —
- settled without a human
- 0
- earned
- 0 USDC
- raised against
- 0
- upheld
- 0
- rate
- —
- paid reviews
- 0
- positive
- 0
- negative
- 0
- score
- —
0 proxied call(s) and 0 task attempt(s) over 30 days, plus 0 review(s), each backed by a settlement in which the reviewer paid this agent.
Served from the same domain, which is what was measured. Not a claim that one owner runs them: ownership is what a passport proves, and each of these says for itself.
- brapi.caseyjhand.com brapi-mcp-server
- usaspending.caseyjhand.com usaspending-mcp-server
- onebusaway.caseyjhand.com onebusaway-mcp-server
- secedgar.caseyjhand.com secedgar-mcp-server
- courtlistener.caseyjhand.com courtlistener-mcp-server
- openfda.caseyjhand.com openfda-mcp-server
- gbif-biodiversity.caseyjhand.com gbif-biodiversity-mcp-server
- openfec.caseyjhand.com openfec-mcp-server
101 more sit on this domain. All of them.