Species MCP Server Specification - jra3/mulm GitHub Wiki
Species Database MCP Server Specification
Overview
The Species Database MCP Server provides comprehensive tools and resources for managing the species database used by the Breeder Awards Program (BAP). It handles the canonical species groups (species_name_group) and their name variants stored in two separate tables: species_common_name for common names and species_scientific_name for scientific names.
Database Schema
The database uses a split schema design that independently manages common names and scientific names.
species_name_group
Represents a unique biological species with its canonical taxonomic name and metadata.
| Column | Type | Description |
|---|---|---|
| group_id | INTEGER | Primary key |
| program_class | TEXT | BAP program class (e.g., "Cichlids - New World", "Livebearers") |
| canonical_genus | TEXT | Official genus name |
| canonical_species_name | TEXT | Official species epithet |
| species_type | TEXT | High-level category (Fish/Plant/Invert/Coral) |
| base_points | INTEGER | Points awarded for breeding this species |
| external_references | TEXT | JSON array of reference URLs (FishBase, etc.) |
| image_links | TEXT | JSON array of image URLs |
| is_cares_species | INTEGER | 1 if CARES conservation species, 0 otherwise |
| iucn_redlist_category | TEXT | IUCN conservation status (e.g., 'VU', 'EN', 'CR') |
| iucn_population_trend | TEXT | Population trend from IUCN |
| iucn_taxon_id | INTEGER | IUCN Red List taxon ID |
| iucn_last_synced_at | DATETIME | Last IUCN data sync timestamp |
species_common_name
Common name variants for species (many-to-one with species_name_group).
| Column | Type | Description |
|---|---|---|
| common_name_id | INTEGER | Primary key |
| group_id | INTEGER | Foreign key to species_name_group (ON DELETE CASCADE) |
| common_name | TEXT | Common name variant (e.g., "Guppy", "Fancy Guppy") |
Unique Constraint: (group_id, common_name) - Each species can have each common name only once
species_scientific_name
Scientific name variants for species (many-to-one with species_name_group).
| Column | Type | Description |
|---|---|---|
| scientific_name_id | INTEGER | Primary key |
| group_id | INTEGER | Foreign key to species_name_group (ON DELETE CASCADE) |
| scientific_name | TEXT | Scientific name variant (synonyms, reclassifications) |
Unique Constraint: (group_id, scientific_name) - Each species can have each scientific name only once
Split Schema Benefits:
- Common names and scientific names are managed independently
- A species can have multiple common names with one scientific name, or vice versa
- No forced pairing of common + scientific (was a limitation of old schema)
- More flexible for real-world taxonomy (many scientific synonyms, one common name is common)
MCP Resources
Resources are read-only endpoints for accessing species data.
species://groups/list
Description: List all species groups with basic information Returns: Array of species groups with group_id, canonical names, program_class, species_type, base_points
species://groups/{group_id}
Description: Get detailed information about a specific species group Parameters:
group_id(number): The species group ID
Returns: Complete group data including all metadata fields
species://groups/by-type/{type}
Description: List species groups filtered by species type Parameters:
type(string): One of: Fish, Plant, Invert, Coral
Returns: Array of species groups matching the type
species://groups/by-class/{class}
Description: List species groups filtered by program class Parameters:
class(string): Program class name (e.g., "Cichlids", "Livebearers")
Returns: Array of species groups matching the class
species://groups/cares
Description: List all CARES conservation priority species Returns: Array of species groups where is_cares_species = 1
species://common-names/{common_name_id}
Description: Get information about a specific common name variant Parameters:
common_name_id(number): The common name variant ID
Returns: Common name record with common_name and associated group info
species://scientific-names/{scientific_name_id}
Description: Get information about a specific scientific name variant Parameters:
scientific_name_id(number): The scientific name variant ID
Returns: Scientific name record with scientific_name and associated group info
species://common-names/by-group/{group_id}
Description: List all common name variants for a species group Parameters:
group_id(number): The species group ID
Returns: Array of all common name variants for the species
species://scientific-names/by-group/{group_id}
Description: List all scientific name variants for a species group Parameters:
group_id(number): The species group ID
Returns: Array of all scientific name variants for the species
species://statistics
Description: Get statistics about the species database Returns:
- Total species count
- Count by species_type
- Count by program_class
- CARES species count
- Species with/without base_points
- Species with most breeders
- Recently added species
MCP Tools
Tools are operations that create, update, or delete species data.
Core CRUD Operations
create_species_group
Description: Creates a new species group with canonical taxonomic name.
Input Schema:
{
"program_class": "string (required)",
"canonical_genus": "string (required)",
"canonical_species_name": "string (required)",
"species_type": "string (required, enum: Fish|Plant|Invert|Coral)",
"base_points": "number (optional)",
"is_cares_species": "boolean (optional, default: false)"
}
Returns:
{
"success": true,
"group_id": 123,
"message": "Species group created successfully"
}
Validations:
- program_class must be valid for the species_type
- canonical_genus and canonical_species_name cannot be empty
- Prevents duplicate canonical names (genus + species combo must be unique)
Use Cases:
- Adding newly discovered species
- Importing species from external databases
- Manual data entry by administrators
update_species_group
Description: Updates metadata for an existing species group (does NOT change canonical name).
Input Schema:
{
"group_id": "number (required)",
"base_points": "number (optional)",
"is_cares_species": "boolean (optional)",
"external_references": "string[] (optional, array of URLs)",
"image_links": "string[] (optional, array of URLs)"
}
Returns:
{
"success": true,
"group_id": 123,
"updated_fields": ["base_points", "is_cares_species"],
"message": "Species group updated successfully"
}
Validations:
- group_id must exist
- base_points must be positive integer
- URLs must be valid format
Use Cases:
- Adding point values to species
- Marking species as CARES conservation priority
- Adding reference links to FishBase, SeriouslyFish
- Adding species photos
delete_species_group
Description: Deletes a species group and all its name variants. DESTRUCTIVE OPERATION.
Input Schema:
{
"group_id": "number (required)",
"force": "boolean (optional, default: false)"
}
Returns:
{
"success": true,
"group_id": 123,
"deleted_synonyms_count": 5,
"warning": "This species had 3 approved submissions",
"message": "Species group deleted successfully"
}
Safety Checks:
- If species has approved submissions, requires
force: true - Returns warning about number of affected submissions
- Cascades delete to all name variants
Use Cases:
- Removing duplicate species (use merge instead if possible)
- Removing invalid/test data
- Cleaning up database errors
add_common_name
Description: Adds a common name variant to an existing species group.
Input Schema:
{
"group_id": "number (required)",
"common_name": "string (required)"
}
Returns:
{
"success": true,
"common_name_id": 456,
"group_id": 123,
"message": "Common name added successfully"
}
Validations:
- group_id must exist
- common_name cannot be empty
- Prevents duplicate (group_id, common_name) combinations
Use Cases:
- Adding alternative common names (e.g., "Oscar" vs "Velvet Cichlid")
- Adding regional name variations
- Adding popular hobbyist names
add_scientific_name
Description: Adds a scientific name variant to an existing species group.
Input Schema:
{
"group_id": "number (required)",
"scientific_name": "string (required)"
}
Returns:
{
"success": true,
"scientific_name_id": 789,
"group_id": 123,
"message": "Scientific name added successfully"
}
Validations:
- group_id must exist
- scientific_name cannot be empty
- Prevents duplicate (group_id, scientific_name) combinations
- Scientific name should follow genus-species format
Use Cases:
- Adding historical scientific names (species reclassified)
- Adding taxonomic synonyms
- Adding variant spellings or misspellings
update_common_name
Description: Updates an existing common name variant.
Input Schema:
{
"common_name_id": "number (required)",
"common_name": "string (required)"
}
Returns:
{
"success": true,
"common_name_id": 456,
"message": "Common name updated successfully"
}
Validations:
- common_name_id must exist
- common_name cannot be empty
- Updated name must not create duplicates for the same group
Use Cases:
- Fixing typos in common names
- Standardizing capitalization
- Correcting regional name variations
update_scientific_name
Description: Updates an existing scientific name variant.
Input Schema:
{
"scientific_name_id": "number (required)",
"scientific_name": "string (required)"
}
Returns:
{
"success": true,
"scientific_name_id": 789,
"message": "Scientific name updated successfully"
}
Validations:
- scientific_name_id must exist
- scientific_name cannot be empty
- Updated name must not create duplicates for the same group
- Scientific name should follow genus-species format
Use Cases:
- Fixing typos in scientific names
- Correcting taxonomic spelling
- Standardizing name format
delete_common_name
Description: Removes a common name variant from a species group.
Input Schema:
{
"common_name_id": "number (required)",
"force": "boolean (optional, default: false)"
}
Returns:
{
"success": true,
"common_name_id": 456,
"message": "Common name deleted successfully"
}
Safety Checks:
- Warns if this is the last common name for the species (requires force: true)
- Checks if common name is used in any submissions
Use Cases:
- Removing incorrect or outdated common names
- Cleaning up duplicate entries
- Removing non-standard regional names
delete_scientific_name
Description: Removes a scientific name variant from a species group.
Input Schema:
{
"scientific_name_id": "number (required)",
"force": "boolean (optional, default: false)"
}
Returns:
{
"success": true,
"scientific_name_id": 789,
"message": "Scientific name deleted successfully"
}
Safety Checks:
- Warns if this is the last scientific name for the species (requires force: true)
- Checks if scientific name is used in any submissions
Use Cases:
- Removing incorrect or outdated scientific names
- Cleaning up duplicate synonym entries
- Removing deprecated taxonomic names
Advanced Operations
merge_species_groups
Description: Merges two species groups by moving all common names, scientific names, and submissions from defunct group to canonical group. DESTRUCTIVE OPERATION.
Input Schema:
{
"canonical_group_id": "number (required)",
"defunct_group_id": "number (required)",
"preview": "boolean (optional, default: false)"
}
Returns:
{
"success": true,
"canonical_group_id": 123,
"defunct_group_id": 124,
"common_names_moved": 3,
"scientific_names_moved": 2,
"submissions_updated": 12,
"preview_data": {
"canonical_name": "Astronotus ocellatus",
"defunct_name": "Astronotus orbiculatus",
"common_names_to_move": ["Oscar", "Velvet Cichlid", "Marble Cichlid"],
"scientific_names_to_move": ["Astronotus orbiculatus"],
"affected_members": 8
},
"message": "Species groups merged successfully"
}
Validations:
- Both group_ids must exist
- Cannot merge a group with itself
- If preview=true, returns what would happen without making changes
Use Cases:
- Combining duplicate species entries
- Fixing taxonomic errors where species were split incorrectly
- Consolidating historical name variants
search_species
Description: Search species with filters and sorting
Input Schema:
{
"query": "string (optional, searches names and synonyms)",
"species_type": "string (optional)",
"program_class": "string (optional)",
"has_base_points": "boolean (optional)",
"is_cares_species": "boolean (optional)",
"sort_by": "string (optional, enum: name|points|class, default: name)",
"limit": "number (optional, default: 100)",
"offset": "number (optional, default: 0)"
}
Returns:
{
"success": true,
"total_count": 1172,
"returned_count": 100,
"results": [
{
"group_id": 123,
"canonical_genus": "Astronotus",
"canonical_species_name": "ocellatus",
"program_class": "Cichlids",
"species_type": "Fish",
"base_points": 10,
"is_cares_species": false,
"common_name_count": 3,
"scientific_name_count": 2
}
]
}
Use Cases:
- Admin species browser/search
- Finding species to edit
- Generating reports
- API endpoints for frontend
get_species_detail
Description: Get comprehensive details for a single species including all name variants
Input Schema:
{
"group_id": "number (required)"
}
Returns:
{
"success": true,
"species": {
"group_id": 123,
"program_class": "Cichlids",
"canonical_genus": "Astronotus",
"canonical_species_name": "ocellatus",
"species_type": "Fish",
"base_points": 10,
"is_cares_species": false,
"external_references": [
"https://fishbase.org/summary/Astronotus-ocellatus.html"
],
"image_links": [
"https://example.com/oscar.jpg"
],
"common_names": [
{"common_name_id": 1, "common_name": "Oscar"},
{"common_name_id": 2, "common_name": "Velvet Cichlid"},
{"common_name_id": 3, "common_name": "Marble Cichlid"}
],
"scientific_names": [
{"scientific_name_id": 1, "scientific_name": "Astronotus ocellatus"},
{"scientific_name_id": 2, "scientific_name": "Astronotus orbiculatus"}
]
}
}
Use Cases:
- Species detail pages
- Admin editing interface
- Generating species reports
Metadata Management
set_base_points
Description: Update point values for species (individual or bulk)
Input Schema:
{
"group_id": "number (optional, for single species)",
"group_ids": "number[] (optional, for multiple species)",
"species_type": "string (optional)",
"program_class": "string (optional)",
"base_points": "number (required)",
"preview": "boolean (optional, default: false)"
}
Returns:
{
"success": true,
"updated_count": 25,
"updated_species": [
{"group_id": 123, "canonical_name": "Astronotus ocellatus", "old_points": 10, "new_points": 15}
],
"message": "Base points updated for 25 species"
}
Use Cases:
- Updating point system across species
- Setting points for new species
- Rebalancing difficulty tiers
toggle_cares_status
Description: Mark species as CARES conservation priority or remove CARES status
Input Schema:
{
"group_id": "number (required)",
"is_cares_species": "boolean (required)"
}
Returns:
{
"success": true,
"group_id": 123,
"canonical_name": "Astronotus ocellatus",
"is_cares_species": true,
"message": "CARES status updated"
}
Use Cases:
- Marking endangered species
- Updating CARES program list
- Highlighting conservation priorities
Taxonomic Operations
update_canonical_name
Description: Update the canonical genus and/or species name (for taxonomic revisions)
Input Schema:
{
"group_id": "number (required)",
"new_canonical_genus": "string (optional)",
"new_canonical_species_name": "string (optional)",
"preserve_old_as_synonym": "boolean (optional, default: true)"
}
Returns:
{
"success": true,
"group_id": 123,
"old_canonical_name": "Astronotus ocellatus",
"new_canonical_name": "Astronotus orbiculatus",
"synonym_created": true,
"message": "Canonical name updated, old name preserved as synonym"
}
Validations:
- At least one new field must be provided
- New canonical name must not already exist
- If preserve_old_as_synonym=true, creates synonym automatically
Use Cases:
- Taxonomic updates when species are reclassified
- Fixing incorrect canonical names
- Scientific nomenclature changes
Implementation Notes
Error Handling
All tools return consistent error format:
{
"success": false,
"error": "Error message here",
"error_code": "VALIDATION_ERROR|NOT_FOUND|DUPLICATE|DATABASE_ERROR",
"details": {}
}
Transaction Safety
- All write operations use
withTransaction() - Bulk operations batch changes
- Provide rollback on any error
Validation
- Validate all inputs before database operations
- Return descriptive error messages
- Check foreign key constraints
- Prevent data corruption
Performance
- Use prepared statements for bulk operations
- Leverage existing database indexes
- Return paginated results for large queries
- Provide progress updates for long-running operations
Security
- Sanitize all inputs
- Validate URLs before storing
- Prevent SQL injection
- Rate limit bulk operations
Compatibility
- Maintains compatibility with existing code in
src/db/species.ts - Doesn't break existing submission references
- Preserves data integrity across updates