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 a local Firecrawl instance if FIRECRAWL_API_URL is configured. If not configured, the tool returns source-constrained suggested queries rather than pretending to have scraped content.
Sources
Implemented/targeted sources:
- GBIF
- Plants of the World Online, Kew best-effort connector
- Wikimedia Commons
- Royal Horticultural Society source candidates / Firecrawl search
- Tela Botanica source candidates / Firecrawl search
- public university horticultural resources via targeted Firecrawl search
No paid API is required.
Installation
Requirements
- Python 3.11+
uvrecommended, 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: "http://localhost:3002"
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": "http://localhost:3002",
"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 | Local Firecrawl base URL. Enables search_botanical_sources and richer source search in care/species tools. |
FIRECRAWL_API_KEY |
No | unset | Optional bearer token if your Firecrawl instance 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": "http://localhost:3002",
"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: "http://localhost:3002"
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_plantmcp_openherbarium_get_taxonomymcp_openherbarium_get_species_informationmcp_openherbarium_get_care_sourcesmcp_openherbarium_get_image_sourcesmcp_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=http://localhost:3002
FIRECRAWL_API_KEY=
If Firecrawl is not configured, source-search tools return explicit suggested queries and a not_configured status.
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