Automated retinal image quality assessment for the Wisconsin Reading Center. MCP server with classical computer vision and deep learning checks.
A Model Context Protocol (MCP) server that accepts retinal fundus image URLs and evaluates them for diagnostic quality. It runs 7 classical computer vision checks plus an optional deep learning model (EyeQ/MCF-Net) and returns an ACCEPT, REVIEW, or REJECT verdict.
Connect this server to OpenCode, Claude Desktop, or any MCP-compatible assistant to quality-gate images before human grading.
Streamable HTTP transport. JSON-RPC 2.0 with headers
Content-Type: application/json and
Accept: application/json, text/event-stream
Runs ALL checks and returns a combined verdict with individual results. Use this for a single comprehensive assessment.
{
"image_url": {
"type": "string",
"format": "uri",
"required": true,
"description": "Publicly accessible URL of the image to check"
}
}
{
"verdict": "accept" | "review" | "reject",
"checks": [
{
"name": "string", // e.g. "sharpness", "resolution"
"passed": true | false,
"detail": "string" // human-readable explanation
}
],
"fundus_assessment": { // null if EyeQ unavailable
"grade": "good" | "usable" | "reject",
"confidence": 0.95,
"probabilities": {
"good": 0.95, "usable": 0.04, "reject": 0.01
}
},
"image_url": "string"
}
Laplacian variance analysis. Score >150 = sharp, <80 = blurry.
{
"image_url": {
"type": "string", "format": "uri",
"required": true,
"description": "Public image URL"
}
}
{
"score": 155.3, // Laplacian variance
"is_sharp": true, // pass/fail
"detail": "string"
}
Checks width/height against minimums (default 1024×1024).
{
"image_url": {
"type": "string", "format": "uri",
"required": true,
"description": "Public image URL"
}
}
{
"width": 2048,
"height": 2048,
"meets_minimum": true,
"megapixels": 4.19
}
Validates file type via magic bytes. Detects truncated or corrupted files.
{
"image_url": {
"type": "string", "format": "uri",
"required": true,
"description": "Public image URL"
}
}
{
"format": "JPEG",
"valid": true,
"corrupted": false,
"detail": "string"
}
Brightness uniformity, over/underexposure, and dark-corner detection.
{
"image_url": {
"type": "string", "format": "uri",
"required": true,
"description": "Public image URL"
}
}
{
"mean_brightness": 128.5,
"std_brightness": 42.3,
"uniform": true,
"vignetting_detected": false,
"detail": "string"
}
RGB validation and channel imbalance detection (tint, wash-out).
{
"image_url": {
"type": "string", "format": "uri",
"required": true,
"description": "Public image URL"
}
}
{
"mode": "RGB",
"channels": 3,
"balanced": true,
"channel_means": [130.2, 125.8, 122.1],
"detail": "string"
}
Extracts camera model, capture date, dimensions, and other metadata.
{
"image_url": {
"type": "string", "format": "uri",
"required": true,
"description": "Public image URL"
}
}
{
"has_exif": true,
"fields": {
"Make": "Canon",
"Model": "EOS R5",
"DateTime": "2026:03:15 14:30:00"
}
}
DenseNet121-based multi-color-space fusion model trained on fundus images. Processes in RGB, HSV, and LAB and returns Good / Usable / Reject with confidence scores.
{
"image_url": {
"type": "string", "format": "uri",
"required": true,
"description": "Public URL of a fundus/retinal image"
}
}
{
"grade": "good" | "usable" | "reject",
"confidence": 0.95,
"probabilities": {
"good": 0.95,
"usable": 0.04,
"reject": 0.01
}
}
All tools accept a single parameter: image_url (string) — a publicly accessible image URL.
{
"mcp": {
"data-quality": {
"type": "remote",
"url": "https://YOUR_DEPLOYMENT_URL/mcp",
"enabled": true
}
}
}
{
"mcpServers": {
"data-quality": {
"url": "https://YOUR_DEPLOYMENT_URL/mcp"
}
}
}
curl -X POST /mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
"protocolVersion":"2025-03-26","capabilities":{},
"clientInfo":{"name":"test","version":"0.1"}}}' \
-i
Copy the Mcp-Session-Id header from the response.
curl -X POST /mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
curl -X POST /mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
"name":"tool_check_image_quality",
"arguments":{"image_url":"https://picsum.photos/2048/2048.jpg"}}}'
All thresholds are configurable via environment variables:
| Variable | Default | Description |
|---|---|---|
| QUALITY_SHARPNESS_PASS | 150 | Sharpness score to pass |
| QUALITY_SHARPNESS_REVIEW | 80 | Sharpness score for review |
| QUALITY_MIN_WIDTH | 1024 | Minimum image width (px) |
| QUALITY_MIN_HEIGHT | 1024 | Minimum image height (px) |
| QUALITY_BRIGHTNESS_MIN_PASS | 60 | Min brightness to pass |
| QUALITY_BRIGHTNESS_MAX_PASS | 200 | Max brightness to pass |
| QUALITY_COLOR_BALANCE_PASS | 30 | Max channel diff to pass |
| QUALITY_ALLOWED_FORMATS | JPEG,PNG,TIFF,BMP | Accepted file formats |
| QUALITY_EYEQ_ENABLED | true | Enable EyeQ deep learning |
Python · Pydantic · FastMCP · OpenCV · Pillow · PyTorch + EyeQ/MCF-Net · Vercel