OpenHerbarium MCP

Botanical Knowledge MCP Server — a Model Context Protocol server that gives AI agents structured, sourced botanical data from free/open sources.

OpenHerbarium MCP is designed for a downstream agent such as Hermes Agent Botaniste. It is deliberately a knowledge-access layer only: it fetches, normalizes and cites botanical evidence, then lets the client agent reason, write, format and publish.

What this MCP does

It exposes MCP tools for:

  • plant lookup by common or scientific name;
  • taxonomic information;
  • species information such as distribution, habitat and botanical descriptions;
  • horticultural care-source discovery;
  • image-source discovery with licence and author metadata;
  • targeted botanical source search through a local Firecrawl instance when configured.

Every returned data point is wrapped with provenance:

{
  "value": "Marantaceae",
  "source": "GBIF Backbone Taxonomy",
  "url": "https://www.gbif.org/species/8184122",
  "retrieved_at": "2026-08-02T12:00:00+00:00",
  "confidence": "high"
}

What this MCP does not do

OpenHerbarium MCP never:

  • creates final Markdown plant sheets;
  • writes to Outline;
  • manages Outline collections;
  • creates care calendars;
  • decides final horticultural recommendations;
  • replaces the reasoning/presentation layer of Hermes Agent.

MCP tools

search_plant(name: str)

Returns:

  • accepted scientific name;
  • canonical name;
  • common/vernacular names when available;
  • synonyms;
  • family, genus, species and rank;
  • external identifiers such as GBIF keys and GBIF species URL;
  • best-effort Kew/POWO results when accessible.

get_taxonomy(name: str)

Returns sourced taxonomy:

  • kingdom;
  • phylum/class/order when available;
  • family;
  • genus;
  • species;
  • scientific name;
  • botanical authorship;
  • taxonomic status;
  • synonyms.

Priority sources:

  • GBIF Backbone Taxonomy;
  • Plants of the World Online, Kew, best-effort.

get_species_information(name: str)

Returns raw evidence for:

  • botanical descriptions;
  • known distribution;
  • natural habitat where available;
  • additional source-search records when Firecrawl is configured.

get_care_sources(name: str)

Returns raw source candidates for:

  • light;
  • temperature;
  • humidity;
  • watering;
  • substrate;
  • fertilisation;
  • repotting.

It does not transform those sources into final care advice.

get_image_sources(name: str, limit: int = 10)

Uses Wikimedia Commons to return:

  • image URL;
  • licence;
  • author;
  • source page.

search_botanical_sources(query: str, limit: int = 5)

Uses the configured Firecrawl endpoint if FIRECRAWL_API_URL is configured. The examples default to the public Firecrawl API (https://api.firecrawl.dev), and you can replace it with a self-hosted endpoint if preferred. If Firecrawl is not configured, the tool returns source-constrained suggested queries rather than pretending to have scraped content.

Sources

Implemented/targeted sources:

No paid API is required.

Installation

Requirements

  • Python 3.11+
  • uv recommended, or any Python package installer capable of creating a virtual environment

Simplest install: run directly with uvx

You do not need to clone the repository manually. Hermes can let uvx install and run the MCP server directly from Gitea:

mcp_servers:
  openherbarium:
    command: "uvx"
    args:
      - "--from"
      - "git+https://git.home-deneuville.fr/Edern/openherbarium-mcp.git"
      - "openherbarium-mcp"
    timeout: 120
    connect_timeout: 60
    env:
      FIRECRAWL_API_URL: "https://api.firecrawl.dev"
      FIRECRAWL_API_KEY: ""
      BOTANICAL_ALLOWED_DOMAINS: "gbif.org,powo.science.kew.org,missouribotanicalgarden.org,tela-botanica.org,inpn.mnhn.fr,rhs.org.uk,edu,wikimedia.org,wikipedia.org"
      OPENHERBARIUM_TIMEOUT: "20"

Restart Hermes Agent after editing ~/.hermes/config.yaml.

An equivalent ready-to-copy snippet is available at examples/hermes-openherbarium-uvx.yaml.

JSON setup examples

Some MCP clients use a JSON config file instead of YAML. Ready-to-copy JSON examples are provided in examples/:

Client / use case Example file Notes
Hermes-style JSON examples/hermes-mcp.json Same structure as Hermes mcp_servers, but JSON. Useful if you keep MCP snippets in a separate mcp.json before converting/merging into config.yaml.
Generic MCP clients examples/generic-mcp.json Uses the common mcpServers JSON key.
Claude Desktop / Claude Code-style configs examples/claude-desktop-mcp.json Copy the openherbarium entry under your existing mcpServers.
Cursor examples/cursor-mcp.json Copy into Cursor's MCP configuration when it expects mcpServers.
Windsurf examples/windsurf-mcp.json Copy into Windsurf's MCP configuration when it expects mcpServers.
Local development checkout examples/local-dev-mcp.json Uses uv --directory /absolute/path/to/openherbarium-mcp run openherbarium-mcp.

Hermes JSON-style snippet:

{
  "mcp_servers": {
    "openherbarium": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://git.home-deneuville.fr/Edern/openherbarium-mcp.git",
        "openherbarium-mcp"
      ],
      "timeout": 120,
      "connect_timeout": 60,
      "env": {
        "FIRECRAWL_API_URL": "https://api.firecrawl.dev",
        "FIRECRAWL_API_KEY": "",
        "BOTANICAL_ALLOWED_DOMAINS": "gbif.org,powo.science.kew.org,missouribotanicalgarden.org,tela-botanica.org,inpn.mnhn.fr,rhs.org.uk,edu,wikimedia.org,wikipedia.org",
        "OPENHERBARIUM_TIMEOUT": "20"
      }
    }
  }
}

Generic mcp.json snippet used by many MCP clients:

{
  "mcpServers": {
    "openherbarium": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://git.home-deneuville.fr/Edern/openherbarium-mcp.git",
        "openherbarium-mcp"
      ]
    }
  }
}

The MCP is configured through environment variables passed by the MCP client. This lets you change endpoints and timeouts directly in config.yaml, mcp.json or your client's MCP settings screen, without modifying the repository.

Available parameters:

Environment variable Required Default Purpose
FIRECRAWL_API_URL No unset Firecrawl base URL. The examples use the public API https://api.firecrawl.dev; replace it with your self-hosted endpoint if preferred. Enables search_botanical_sources and richer source search in care/species tools.
FIRECRAWL_API_KEY No unset Bearer token for the public Firecrawl API, or for any self-hosted instance that requires authentication.
BOTANICAL_ALLOWED_DOMAINS No built-in allow-list Comma-separated source domains used to constrain targeted botanical searches.
OPENHERBARIUM_TIMEOUT No 20 HTTP timeout in seconds for public APIs and Firecrawl calls.

Generic JSON example with all configurable parameters:

{
  "mcpServers": {
    "openherbarium": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://git.home-deneuville.fr/Edern/openherbarium-mcp.git",
        "openherbarium-mcp"
      ],
      "env": {
        "FIRECRAWL_API_URL": "https://api.firecrawl.dev",
        "FIRECRAWL_API_KEY": "",
        "BOTANICAL_ALLOWED_DOMAINS": "gbif.org,powo.science.kew.org,missouribotanicalgarden.org,tela-botanica.org,inpn.mnhn.fr,rhs.org.uk,edu,wikimedia.org,wikipedia.org",
        "OPENHERBARIUM_TIMEOUT": "20"
      }
    }
  }
}

Client-specific file locations change between applications and versions. When in doubt, use the app's MCP settings screen and paste the openherbarium server entry under its existing mcpServers object.

Development install with uv

git clone https://git.home-deneuville.fr/Edern/openherbarium-mcp.git
cd openherbarium-mcp
uv sync --extra dev

Run tests:

uv run pytest

Run the MCP server over stdio from the checked-out project:

uv run openherbarium-mcp

Hermes Agent configuration for local development

If you want to work on the source code locally instead of using the uvx setup, add the checked-out server to ~/.hermes/config.yaml:

mcp_servers:
  openherbarium:
    command: "uv"
    args:
      - "--directory"
      - "/absolute/path/to/openherbarium-mcp"
      - "run"
      - "openherbarium-mcp"
    timeout: 120
    connect_timeout: 60
    env:
      FIRECRAWL_API_URL: "https://api.firecrawl.dev"
      FIRECRAWL_API_KEY: ""
      BOTANICAL_ALLOWED_DOMAINS: "gbif.org,powo.science.kew.org,missouribotanicalgarden.org,tela-botanica.org,inpn.mnhn.fr,rhs.org.uk,edu,wikimedia.org,wikipedia.org"
      OPENHERBARIUM_TIMEOUT: "20"

Restart Hermes Agent. Tools will be exposed with names similar to:

  • mcp_openherbarium_search_plant
  • mcp_openherbarium_get_taxonomy
  • mcp_openherbarium_get_species_information
  • mcp_openherbarium_get_care_sources
  • mcp_openherbarium_get_image_sources
  • mcp_openherbarium_search_botanical_sources

.env fallback for manual/local runs

For direct local execution outside an MCP client, you can also copy .env.example to .env and set the same parameters there:

FIRECRAWL_API_URL=https://api.firecrawl.dev
FIRECRAWL_API_KEY=

If Firecrawl is not configured, source-search tools return explicit suggested queries and a not_configured status. With the public API URL, set FIRECRAWL_API_KEY to your Firecrawl key.

Development

uv sync --extra dev
uv run pytest

Project layout:

openherbarium-mcp/
├── src/
│   └── openherbarium_mcp/
│       ├── server.py
│       ├── gbif.py
│       ├── kew.py
│       ├── rhs.py
│       ├── tela_botanica.py
│       ├── wikimedia.py
│       └── firecrawl.py
├── tests/
├── README.md
├── pyproject.toml
├── LICENSE
└── .env.example

Reliability model

The server distinguishes between:

  • high confidence: exact/high-confidence API matches, mostly GBIF taxonomic matches;
  • medium confidence: sourced API records that still require interpretation;
  • low confidence: source candidates or search results that must be manually/agent verified.

OpenHerbarium MCP prefers returning status: unavailable, status: not_configured or empty records over inventing missing data.

License

MIT

S
Description
Botanical Knowledge MCP server providing structured, sourced plant data from open sources.
Readme MIT
123 KiB
Languages
Python 100%