MCP server exposing a COVID-19 lateral flow test reader to AI assistants. Wraps a FastAPI service running on Google Cloud Run that serves a two-stage computer-vision pipeline: YOLOv8-OBB locates the test cassette in a photo, MobileNetV3-Small classifies the result, and a classical OpenCV line counter corroborates the verdict.
Two tools with clear, detailed descriptions (194 - 250 chars each) and explicit input schemas. Tool names follow verb_noun pattern (read_*, check_*). However, input schemas lack formal type constraints (no enums, no min/max bounds), and output schemas are documented only in prose, not as structured JSON Schema. Error handling returns helpful guidance but lacks categorization (retryable vs. fatal). No parameter descriptions beyond the tool docstring.
Check whether the lateral flow reader service is up and its models loaded. Useful before reading a batch of images, or to distinguish a service problem from a problem with a particular photo. Returns the service status, whether the models finished loading, how long loading took, and how long the current instance has been running. A short uptime means the instance just cold-started.
Read a COVID-19 lateral flow (antigen) test from a photograph. Returns the verdict — positive, negative or invalid — with the model's confidence and how the decision was reached. Pass a photo of the test sitting in a scene (on a table, held in a hand). The detector was trained to find a cassette within a wider frame, so a tight crop of just the cassette will come back as not detected. Args: image_path: Path to a local image file (.jpg, .jpeg, .png, .bmp, .webp). Returns: A dict with: detected — whether a test cassette was found at all result — "positive", "negative" or "invalid" confidence — classifier confidence, 0.0 to 1.0 decision_source — how the CNN and the line counter combined detection_confidence — detector confidence for the cassette processing_ms — server-side inference time When no cassette is found, returns detected=False with a `note` explaining what kind of photo the detector expects. That is a result, not an error. This is a research demonstration, not a medical device. Do not present its output as a diagnosis.
Input schemas lack formal constraints. 'image_path' is a bare string with no format, pattern, or length bounds. No enums, min/max for numeric fields, or regex patterns. LLMs cannot validate inputs before calling.
Output schemas documented only in prose (docstring). No structured JSON Schema returned to the client. LLMs cannot parse expected fields programmatically or plan downstream tool calls with confidence.
Error responses lack categorization. Timeouts, network errors, and validation errors all return a dict with 'error' key, but do not signal whether the error is retryable, user-fixable, or fatal. LLMs cannot decide whether to retry or escalate.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | <=2025-11-25 | v2 |
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Both tools are read-only and idempotent, but this is not declared in the schema. Clients cannot infer safety properties.
read_lateral_flow_test returns verbose, unstructured error dicts (e.g., 'No file at /path', 'Unsupported file type'). Should validate inputs early and return a single, consistent error schema with error_code, message, and recovery_hint.