MCP server for ezyVet — first MCP for cloud veterinary PIMS (IDEXX-owned). 17 tools for animals, contacts, appointments, consults, invoices. OAuth2 + token caching.
Server has 17 well-named tools with consistent verb_noun patterns (get_, find_, create_, update_, list_). All tools have descriptions (avg ~100 chars, within baseline 34-392). Input schemas are present and typed. However, descriptions are terse and lack actionable context for LLM selection. Parameter descriptions are minimal (e.g., 'The ezyVet animal ID' without format/constraint hints). Output schemas are not documented, responses are JSON strings without field-level guidance. Error handling exists but lacks recovery guidance. No tool annotations (readOnlyHint/destructiveHint). Pagination is implemented but not consistently described. Overall: functional but below production bar for agent reliability.
Create a new animal (patient). ``animal_json`` is a JSON object string matching ezyVet's animal schema (at minimum: name, species_id).
Book a new appointment. ``appointment_json`` is a JSON object string.
Create a new contact (owner). ``contact_json`` is a JSON object string.
Search animals by name / species / breed. Returns the standard ``{meta, items, messages}`` envelope from ezyVet.
List appointments. Use ``start_date`` + ``end_date`` for a date range, ``animal_id`` for a specific patient's visits.
List clinical consults (visits).
Output schemas not documented. Tools return JSON strings without field-level guidance. LLMs cannot plan downstream calls or extract specific fields reliably.
Descriptions lack actionable context. E.g., 'Fetch a single animal (patient) by ezyVet ID' does not explain when to use get_animal vs find_animals, or what fields are returned. Descriptions should be 50-200 chars and answer: what, when, what's returned.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Agents cannot distinguish safe reads from destructive writes without explicit hints. create_animal, update_animal, create_contact, create_appointment should be marked destructiveHint=true.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 67 | <=2025-11-25 | v2 |
Search contacts by name or email.
List invoices. Use ``start_date`` + ``end_date`` for a date range, ``contact_id`` for a specific owner's invoices.
Fetch a single animal (patient) by ezyVet ID.
Fetch a single consult (visit) by ID.
Fetch a contact (the pet owner) by ID.
Fetch a single invoice by ID.
List all appointment types.
List all breeds, optionally filtered by species.
List all invoice statuses.
List all species (dog, cat, rabbit, etc.).
Patch an animal record. ``updates_json`` is a JSON object with only the fields you want to change (e.g. ``'{"name": "Rex II", "weight": 32.4}'``).
JSON string parameters (animal_json, updates_json, contact_json, appointment_json) lack format constraints. Descriptions do not specify required fields, valid schema, or example structure. LLMs will hallucinate invalid JSON.
Error handling returns raw exceptions without recovery guidance. E.g., EzyvetAuthError, EzyvetNotFoundError are caught but descriptions do not tell LLM what to do next (retry, ask user, check config).