Moltline Vision Maths
Image header probing, bbox conversion, resize plans and colour maths. 4 of 6 free.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"vision": {
"url": "https://mcp.moltlinestudio.com/vision"
}
}
}Remote endpoints
https://mcp.moltlinestudio.com/visionstreamable-httpWhat it can do
Tool inventory
Tools (6)
🟢image_probe(data_base64)
Read an image's format and pixel size from its header alone. FREE. Dimensions live in the first few dozen bytes of PNG, JPEG, GIF, BMP and WebP, so a base64 prefix is enough - you do not need to send the whole file, and nothing is decoded. Typical input {"data_base64": "iVBORw0KG..."} returns {"format": "png", "width": 1920, "height": 1080, "aspect_ratio": 1.7778, "aspect_label": "16:9", "megapixels": 2.07, "orientation": "landscape", "bytes_inspected": 512}. Use to find out what you are dealing with before planning a resize. Not for pixel content - nothing here reads pixels - and not for EXIF. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "data_base64 must not be empty"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Input Schema
{
"type": "object",
"properties": {
"data_base64": {
"type": "string",
"description": "The image file, base64-encoded. The first few hundred\nbytes are enough for every supported format; send a prefix rather\nthan a large file. Data-URL prefixes like \"data:image/png;base64,\"\nare accepted and stripped."
}
},
"required": [
"data_base64"
],
"additionalProperties": false
}Output Schema
{
"type": "object",
"additionalProperties": true
}🟢bbox_convert(boxes, from_format, to_format, image_width, image_height, ...)
Convert bounding boxes between COCO, Pascal VOC and YOLO. FREE. The three formats disagree on everything: COCO is [x, y, width, height], VOC is [x1, y1, x2, y2], YOLO is [cx, cy, w, h] normalised to the image. Getting this wrong produces boxes that look plausible and quietly ruin every metric. Typical input {"boxes": [[10, 20, 100, 50]], "from_format": "coco", "to_format": "yolo", "image_width": 640, "image_height": 480} returns {"boxes": [[0.0938, 0.0938, 0.1562, 0.1042]], "converted": 1, "rejected": []}. Use whenever a dataset and a model disagree about format. Not for scoring predictions (detection_metrics) and not for removing overlaps (nms). Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "boxes must contain at least one box"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Input Schema
{
"type": "object",
"properties": {
"boxes": {
"items": {
"items": {
"type": "number"
},
"type": "array"
},
"type": "array",
"description": "Boxes to convert, each a list of exactly four numbers in\nfrom_format, e.g. [[10, 20, 100, 50]]."
},
"from_format": {
"enum": [
"coco",
"voc",
"yolo"
],
"type": "string",
"description": "\"coco\" for [x, y, w, h], \"voc\" for [x1, y1, x2, y2], or\n\"yolo\" for normalised [cx, cy, w, h]."
},
"to_format": {
"enum": [
"coco",
"voc",
"yolo"
],
"type": "string",
"description": "The format to convert to; same three choices."
},
"image_width": {
"default": 0,
"minimum": 0,
"type": "integer",
"description": "Pixel width, required whenever yolo is on either side."
},
"image_height": {
"default": 0,
"minimum": 0,
"type": "integer",
"description": "Pixel height, required whenever yolo is on either side."
},
"clip": {
"default": false,
"type": "boolean",
"description": "When true, clamp boxes to the image bounds instead of returning\nthem as they are. Off by default, because a box outside the image\nis usually a bug worth seeing."
}
},
"required": [
"boxes",
"from_format",
"to_format"
],
"additionalProperties": false
}Output Schema
{
"type": "object",
"additionalProperties": true
}🟢resize_plan(width, height, target, target_size, mode)
Work out the exact scale, padding and crop for a model input size. FREE. Returns the numbers you need to transform boxes alongside the image, which is the step that usually gets skipped. Typical input {"width": 1920, "height": 1080, "target": "yolo_640"} returns {"scale": 0.3333, "resized": [640, 360], "pad": {"left": 0, "top": 140, "right": 0, "bottom": 140}, "box_transform": "x_new = x * 0.3333 + 0; y_new = y * 0.3333 + 140"}. Use before feeding an image to a fixed-input model. Not for finding out the image's size in the first place - that is image_probe. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "unknown target <value>; use one of <value> or set"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Input Schema
{
"type": "object",
"properties": {
"width": {
"exclusiveMinimum": 0,
"type": "integer",
"description": "Source image width in pixels."
},
"height": {
"exclusiveMinimum": 0,
"type": "integer",
"description": "Source image height in pixels."
},
"target": {
"default": "yolo_640",
"type": "string",
"description": "A named preset: \"clip_224\", \"vit_384\", \"yolo_640\", \"sam_1024\",\n\"sd_512\", \"sd_768\" or \"detr_800\". Ignored when target_size is set."
},
"target_size": {
"default": 0,
"minimum": 0,
"type": "integer",
"description": "A square side length in pixels, overriding target. Use\nthis for a size the presets do not cover."
},
"mode": {
"default": "letterbox",
"enum": [
"letterbox",
"cover",
"stretch"
],
"type": "string",
"description": "\"letterbox\" scales to fit and pads the remainder, preserving\naspect; \"cover\" scales to fill and crops the overflow; \"stretch\"\ndistorts to fit exactly. Default \"letterbox\"."
}
},
"required": [
"width",
"height"
],
"additionalProperties": false
}Output Schema
{
"type": "object",
"additionalProperties": true
}🟢colour_check(foreground, background, large_text)
Check a colour pair against the WCAG contrast thresholds. FREE. Uses the WCAG 2 relative-luminance formula, so the number matches what an accessibility audit will report. Typical input {"foreground": "#767676", "background": "#ffffff"} returns {"contrast_ratio": 4.54, "AA": true, "AAA": false, "required": {"AA": 4.5, "AAA": 7.0}, "verdict": "Passes AA for normal text, fails AAA."}. Use when generating or auditing an interface. Not for converting colours between spaces and not for palettes. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "foreground must be a hex colour like #767676"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Input Schema
{
"type": "object",
"properties": {
"foreground": {
"type": "string",
"description": "Text colour as hex, e.g. \"#767676\" or \"767676\" or \"#777\"."
},
"background": {
"type": "string",
"description": "Background colour in the same notation."
},
"large_text": {
"default": false,
"type": "boolean",
"description": "True for text at least 18pt, or 14pt bold, which WCAG\nallows to pass at a lower ratio. Default false."
}
},
"required": [
"foreground",
"background"
],
"additionalProperties": false
}Output Schema
{
"type": "object",
"additionalProperties": true
}🟢nms(boxes, scores, iou_threshold, box_format, image_width, ...)
Remove duplicate detections of the same object. PREMIUM (license). Greedy non-maximum suppression: keep the highest-scoring box, drop everything overlapping it above the threshold, repeat. Ties break on the earlier index, so the result is deterministic rather than dependent on sort stability. Typical input {"boxes": [[0,0,10,10],[1,1,11,11],[50,50,60,60]], "scores": [0.9, 0.8, 0.7]} returns {"keep": [0, 2], "suppressed": [{"index": 1, "by": 0, "iou": 0.6807}], "kept": 2}. Use after a detector that emits overlapping boxes. Not for scoring against ground truth (detection_metrics) and not for format changes (bbox_convert). Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "boxes and scores must be the same length"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Input Schema
{
"type": "object",
"properties": {
"boxes": {
"items": {
"items": {
"type": "number"
},
"type": "array"
},
"type": "array",
"description": "Candidate boxes in box_format, e.g. [[0, 0, 10, 10]]."
},
"scores": {
"items": {
"type": "number"
},
"type": "array",
"description": "One confidence per box, same order and same length as boxes."
},
"iou_threshold": {
"default": 0.5,
"exclusiveMinimum": 0,
"maximum": 1,
"type": "number",
"description": "Overlap above which the lower-scoring box is dropped.\nDefault 0.5."
},
"box_format": {
"default": "voc",
"enum": [
"coco",
"voc",
"yolo"
],
"type": "string",
"description": "\"voc\", \"coco\" or \"yolo\". Default \"voc\"."
},
"image_width": {
"default": 0,
"minimum": 0,
"type": "integer",
"description": "Pixel width; required for yolo boxes."
},
"image_height": {
"default": 0,
"minimum": 0,
"type": "integer",
"description": "Pixel height; required for yolo boxes."
}
},
"required": [
"boxes",
"scores"
],
"additionalProperties": false
}Output Schema
{
"type": "object",
"additionalProperties": true
}🟢detection_metrics(predictions, ground_truth, iou_threshold, box_format, image_width, ...)
Score detections against ground truth and show the working. PREMIUM (license). Greedy matching at the IoU threshold, highest-confidence prediction first, each ground-truth box matched at most once - the standard protocol. Reports per-class precision, recall and F1, and average precision by the all-points interpolation used by Pascal VOC 2010 onward. Typical input {"predictions": [{"box": [0,0,10,10], "label": "cat", "score": 0.9}], "ground_truth": [{"box": [1,1,11,11], "label": "cat"}]} returns {"overall": {"tp": 1, "fp": 0, "fn": 0, "precision": 1.0, "recall": 1.0, "f1": 1.0}, "per_class": {...}, "mAP": 1.0}. Use to compare two models on the same held-out set. Not for cleaning up a single model's overlapping output first - run nms before this. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "ground_truth must contain at least one box"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Input Schema
{
"type": "object",
"properties": {
"predictions": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "Predicted boxes, each {\"box\": [...], \"label\": ...,\n\"score\": ...}. Score defaults to 1.0 when omitted."
},
"ground_truth": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "True boxes, each {\"box\": [...], \"label\": ...}."
},
"iou_threshold": {
"default": 0.5,
"exclusiveMinimum": 0,
"maximum": 1,
"type": "number",
"description": "Overlap at which a prediction counts as a match.\nDefault 0.5, the usual reporting threshold."
},
"box_format": {
"default": "voc",
"enum": [
"coco",
"voc",
"yolo"
],
"type": "string",
"description": "\"voc\", \"coco\" or \"yolo\". Default \"voc\"."
},
"image_width": {
"default": 0,
"minimum": 0,
"type": "integer",
"description": "Pixel width; required for yolo boxes."
},
"image_height": {
"default": 0,
"minimum": 0,
"type": "integer",
"description": "Pixel height; required for yolo boxes."
}
},
"required": [
"predictions",
"ground_truth"
],
"additionalProperties": false
}Output Schema
{
"type": "object",
"additionalProperties": true
}Community
Evidence