Vetwise
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Vetwise
A self-hosted MCP server that owns a household's pet records and answers "is this safe for my pet?" with species- and weight-aware toxicosis math and cited veterinary sources.
Vetwise is built for the ten minutes after a pet eats something wrong: a dog into a chocolate bar, a cat near a lily, a sitter who is not sure whether the evening dose was given. It is not a chatbot with a toxicology page pasted into its prompt. The server owns the household record, runs a deterministic safety engine, and returns one of five verdicts — including unverified when a fact is missing. A host (Claude, Alexa+, a local UI) talks to it over Streamable HTTP with a scoped bearer token.
Not veterinary advice. Vetwise names the veterinarian and poison-control numbers; it never advises treatment or inducing vomiting.

Run the demo
npm install
cp .env.example .env # optional; every value has a working demo default
npm start # http://127.0.0.1:3000Open http://127.0.0.1:3000. The demo clock is frozen at 21:40; the household has two pets and two doses still due. The page is a simulator: every answer it shows came from a real JSON-RPC tools/call against /mcp, and the traffic panel lists those calls.
Suggested first line: “What's due tonight?”
The full scripted walkthrough is in docs/DEMO.md.
Demo household
Household | The Chen–Patel house, Sacramento, CA |
Owner | Maya Chen — read, log, write, notify |
Sitter | Noah Patel — read, log, notify (no record changes) |
Dog | Mochi, Pembroke Welsh Corgi, 5 y, 13.6 kg |
Cat | Juniper, Domestic Shorthair, 9 y, 4.6 kg |
Primary vet | Cedar Creek Animal Hospital (Dr. Priya Raman) — |
Emergency | Sacramento Veterinary Emergency & Specialty — |
Poison control | ASPCA APCC |
Related MCP server: veterinary-fda
What is inside
9 MCP tools
Tool | Scope | What it does |
|
| People, pets, clinics in one call |
|
| One pet, every medicine including stopped ones, today's care |
|
| Taken / skipped / missed / due / upcoming for a day |
|
| Filter by pet; |
|
| The safety engine: verdict, dose math, cited evidence |
|
| Medication, symptom, weight or note; never guesses a slot |
|
| Phase one: mint a single-use confirmation token |
|
| Phase two: apply the token after an explicit yes |
|
| Queue a message to a person already on the record |
6 resources
vetwise://household, vetwise://pets/{petId}, vetwise://care/today, vetwise://medications, vetwise://toxins, vetwise://toxins/{toxinId}.
2 prompts
evening_check_in and something_my_pet_ate — the two shapes a real host would ship as suggested actions.
24 catalogued toxins
Foods, plants, human medicines, pesticides and household products. Every entry carries a published source URL and a verbatim quote. The full table with thresholds is in docs/TOXIN_CATALOGUE.md.
Verdicts
emergency · call_vet · monitor · no_known_toxicity · unverified
unverified is a first-class answer. Missing weight, amount, species, product or a substance outside the catalogue never becomes reassurance. Grapes/raisins, lilies, rodenticide and antifreeze escalate on any exposure, before any amount is requested.
How a request flows
browser / host
│ Bearer token
▼
Express ──► /mcp ──► MCP server (tools · resources · prompts)
│ │
│ ├─ scope check inside every tool
│ ├─ deterministic safety engine
│ └─ JSON-file store (atomic writes)
│
├─ /api/chat ──► scripted planner or Bedrock planner
│ └─ its own short-lived MCP client ──► /mcp
├─ /api/state ──► household snapshot + MCP traffic log
└─ / ──► static simulatorThe planner has no private access to the store. It is just another MCP client, authenticated with the same token the browser sent, so the traffic panel shows exactly what the model saw and called.
Deeper design notes: docs/ARCHITECTURE.md. Safety policy: docs/SAFETY.md.
Agent modes
scripted(default with no AWS credentials) — a deterministic planner that recognises exposure, symptom follow-up, medication logging, alerts and two-phase record changes. No network model call.bedrock— Amazon Bedrock Converse tool loop (VETWISE_AGENT=bedrock, AWS credentials required). If Bedrock fails, the turn falls back to the scripted planner and labels the answer.
Both paths call the same MCP tools over the same transport. The UI badge says which planner answered.
Configuration
Copy .env.example to .env. The values that matter:
Variable | Default | Purpose |
|
| HTTP listener |
|
| URL the simulator uses to reach its own |
|
| JSON store; delete to reseed the demo |
| unset (real time) |
|
| demo token when | Owner bearer token — required outside demo mode |
| demo token when | Sitter bearer token — required outside demo mode |
|
| Allow the published demo tokens; set |
|
|
|
|
| Required when |
| empty | Required behind a tunnel; prevents DNS rebinding |
| empty | If set, alerts are POSTed and delivery is recorded |
| unset (off) | Public demos: reseed the household, transcripts and traffic every N minutes; refused when |
Run with an env file if you prefer:
node --env-file=.env --import tsx src/index.tsDeploy a public demo
A hosted demo lets a buyer try every tool, writes included, from a link. Strangers will change the record, so a public demo turns on the reset: the household, chat transcripts and traffic panel are reseeded every VETWISE_DEMO_RESET_MINUTES, and the simulator shows a "Public demo · resets in N min" notice. Requests still running when a reset fires cannot write into the fresh household, and if a reset cannot be saved, /healthz answers 503 and the demo refuses requests until the next attempt succeeds.
Render (one click). render.yaml describes a free Docker web service with the demo clock at 21:40 and a 30-minute reset. In Render choose New → Blueprint, pick this repository, and deploy.
Any container host.
docker build -t vetwise .
docker run -p 3000:3000 -e DEMO_CLOCK=21:40 -e VETWISE_DEMO_RESET_MINUTES=30 vetwiseThe image binds 0.0.0.0, runs the scripted planner, keeps its data in /app/data (mount a volume to keep a real household), and has a /healthz health check. Render and similar hosts set PORT; the server's self-call follows it.
A public demo runs on the published demo tokens. For a real household, set NODE_ENV=production, OWNER_TOKEN and SITTER_TOKEN, and leave DEMO_CLOCK and VETWISE_DEMO_RESET_MINUTES unset; the server refuses to start otherwise.
Connect from an MCP client
The server speaks Streamable HTTP at /mcp with a bearer token. Replace the URL with your deployment and the token with the owner or sitter token.
Claude Code
claude mcp add --transport http vetwise https://your-host/mcp \
--header "Authorization: Bearer maya-owner-demo-token"Claude Desktop (through the mcp-remote bridge, in claude_desktop_config.json)
{
"mcpServers": {
"vetwise": {
"command": "npx",
"args": ["mcp-remote", "https://your-host/mcp", "--header", "Authorization:${VETWISE_AUTH}"],
"env": { "VETWISE_AUTH": "Bearer maya-owner-demo-token" }
}
}
}MCP Inspector: npx @modelcontextprotocol/inspector, transport Streamable HTTP, URL https://your-host/mcp, header Authorization: Bearer ….
Then ask the host "Mochi ate half a bar of dark chocolate" and watch the same tools the simulator uses.
Scripts
npm run typecheck # tsc --noEmit
npm test # safety-engine unit tests (17)
npm run smoke # boots the real server and drives it with a real MCP client
npm run regress # replays every finding in Vetwise-Code-Review.md
npm run check # all four
npm run dev # tsx watchThe smoke test starts its own server on port 8799 with a temporary data file, exercises all 9 tools, both identities, resources, prompts, single-use confirmations and the 401 gate, then removes its data. npm run regress boots a second server on 8811 and asserts the review fixes over real HTTP and MCP: hashed tokens, caller-bound sessions, /healthz minimalism, security headers, rate limiting, sanitised alert bodies, medication routes, id length, and the startup refusals.
Security posture
Bearer tokens are stored as SHA-256 digests and compared with
timingSafeEqual; the raw secret never leaves the request that carried it, and/api/whoamionly ever returns a four-character hint.Published demo tokens work only in demo mode.
NODE_ENV=production(orVETWISE_DEMO=0) refuses to start withoutOWNER_TOKENandSITTER_TOKEN, and rejects the demo strings outright.Chat sessions are keyed by
clientId:sessionId, expire after 30 minutes, and are capped at 200./api/chatis rate limited per token (20/min), request bodies over 2,000 characters are refused, and the client sees one generic error while the operator sees the full cause.The static app is served with a strict CSP (
default-src 'self'),nosniff,X-Frame-Options: DENYand no third-party origins./healthzreturns{ ok, time }only; version, agent mode and model are not public.Alert bodies are stripped of control characters and angle brackets before they reach the outbox or a webhook.
npm run regressproves each of those still holds.
Safety posture
The engine never invents a threshold. Every band traces to a cited source, and every answer carries the evidence it used.
Missing facts produce
unverifiedwith a concrete next step (get a weight, read the package, call poison control).Symptoms can only raise a verdict, never lower it.
Dose bands can raise a gate verdict but never lower one.
Record changes are two-phase and bound to the caller; replay is rejected.
Alerts go only to people on the household record.
No treatment advice, no induced vomiting, no therapeutic dosing. Ever.
no_known_toxicity exists as a verdict but is currently unreachable for the 24 catalogued toxins: every published band starts at 0 and resolves to monitor or higher. It is documented as reserved rather than used to manufacture false reassurance. See docs/SAFETY.md.
Licence
MIT — see LICENSE.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Read pet activity and weight history, and log events with your permission.
Source-verified pet food regulations, recalls, nutrient standards and species care data.
Household health records with source attribution. Read and add records with OAuth approval.
Track and share care records for babies and plants: feedings, diapers, sleep, and watering.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables Alexa+ users to coordinate household pet care by logging feeding, medication, activity, litter, and health observations for dogs and cats, with evidence-grounded triage, Q&A, and daily briefings backed by a verified veterinary library and citations.3MIT
- AlicenseNot gradedqualityCmaintenanceEnables searching FDA adverse-event reports for animal drugs, summarizing side effects by species, checking pet food and veterinary drug recalls, and finding nearby pet services from OpenStreetMap.12 npm1MIT
- AlicenseNot gradedqualityBmaintenanceTracks a household's possessions and cross-references them against CPSC, NHTSA, and FDA recall feeds, surfacing affected models, severities, and plain-language remedies by voice. It also manages maintenance reminders for items like smoke-detector batteries, filters, car-seat expiry, and vehicle service, rendered as interactive cards on an Echo Show.16 npmGPL 3.0
- AlicenseNot gradedqualityCmaintenanceEnables a family caregiver to ask spoken medication-safety questions and receive answers grounded in quoted FDA label text with citations, backed by one household's medication record, adherence tracking, and prescriber contacts. Read-only safety checks run against normalised drug names and current labels, while any record change requires a two-phase, single-use caregiver confirmation before it is applied.MIT