docs: add setup guide and test coverage
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
# 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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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](https://www.gbif.org/)
|
||||
- [Plants of the World Online, Kew](https://powo.science.kew.org/) best-effort connector
|
||||
- [Wikimedia Commons](https://commons.wikimedia.org/)
|
||||
- [Royal Horticultural Society](https://www.rhs.org.uk/) source candidates / Firecrawl search
|
||||
- [Tela Botanica](https://www.tela-botanica.org/) source candidates / Firecrawl search
|
||||
- public university horticultural resources via targeted Firecrawl search
|
||||
|
||||
No paid API is required.
|
||||
|
||||
## Installation
|
||||
|
||||
### Requirements
|
||||
|
||||
- Python 3.11+
|
||||
- `uv` recommended, or any Python package installer capable of creating a virtual environment
|
||||
|
||||
### Local install with `uv`
|
||||
|
||||
```bash
|
||||
git clone <YOUR_GITEA_URL>/openherbarium-mcp.git
|
||||
cd openherbarium-mcp
|
||||
uv sync --extra dev
|
||||
```
|
||||
|
||||
Run tests:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
Run the MCP server over stdio:
|
||||
|
||||
```bash
|
||||
uv run openherbarium-mcp
|
||||
```
|
||||
|
||||
## Hermes Agent configuration
|
||||
|
||||
Add the server to `~/.hermes/config.yaml`:
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
openherbarium:
|
||||
command: "uv"
|
||||
args:
|
||||
- "--directory"
|
||||
- "/absolute/path/to/openherbarium-mcp"
|
||||
- "run"
|
||||
- "openherbarium-mcp"
|
||||
timeout: 120
|
||||
connect_timeout: 60
|
||||
```
|
||||
|
||||
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`
|
||||
|
||||
## Firecrawl configuration
|
||||
|
||||
Copy `.env.example` to `.env` and set:
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
uv sync --extra dev
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
Project layout:
|
||||
|
||||
```text
|
||||
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
|
||||
Reference in New Issue
Block a user