annotation-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@annotation-mcpscan barcode and ocr text from product.png"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
annotation-mcp
MCP (Model Context Protocol) server for image annotation. Draws bounding boxes, arrows, highlights, callouts, text, and circles on images. Also detects barcodes and text regions, and crops image regions for iterative inspection.
Supported Platforms
OS | Versions | Python | Notes |
macOS | 12+ (Monterey) | 3.12+ | Tested on Apple Silicon and Intel |
Linux | Ubuntu 22.04+, Debian 12+, Fedora 38+ | 3.12+ | glibc-based, x86_64 and aarch64 |
Windows | 10, 11, Server 2019+ | 3.12+ | x86_64 only |
Related MCP server: Lens
Tools
Tool | Purpose |
| Read image metadata (dimensions, format, EXIF orientation). |
| Draw multiple annotations on one image (bbox, arrow, highlight, callout, text, circle). |
| Single bounding box (convenience wrapper around |
| Semi-transparent rectangular highlight. |
| Numbered circle callouts. |
| Detect 1D/2D barcodes (EAN, UPC, QR, etc.) with exact pixel bboxes. |
| Detect text regions with Tesseract OCR. Returns text + bbox + confidence. |
| Crop a region to a new file. Used for iterative AI inspection. |
Installation
1. System dependencies
Tesseract OCR and zbar barcode library are required for detect_text_regions and detect_barcodes. The other 5 tools (annotate, draw_bounding_box, etc.) work without them.
macOS
brew install tesseract tesseract-lang zbarThis installs:
tesseract(OCR engine)tesseract-lang(163 language packs includingeng,rus,jpn,chi_sim,deu,fra, etc.)zbar(barcode scanning library, includinglibzbar.dylib)
Verify:
tesseract --version
tesseract --list-langs # should show 'eng' and 'rus'Linux (Debian/Ubuntu)
sudo apt-get update
sudo apt-get install -y \
tesseract-ocr \
tesseract-ocr-eng \
tesseract-ocr-rus \
libzbar0 \
zbar-toolsFor Fedora / RHEL:
sudo dnf install -y tesseract tesseract-langpack-eng tesseract-langpack-rus zbarFor Arch:
sudo pacman -S tesseract tesseract-data-eng zbarVerify:
tesseract --version
tesseract --list-langsWindows
The recommended install is via Chocolatey:
choco install --no-progress tesseract -y
choco install --no-progress python3 -y # if you don't have Python yetAfter install, ensure C:\Program Files\Tesseract-OCR is on your PATH (the choco package should do this automatically; you may need to restart your terminal).
pyzbar ships its own copy of libzbar-0.dll bundled in the wheel on Windows, so no separate zbar install is needed.
Verify in PowerShell:
tesseract --version
tesseract --list-langs2. Python package
The recommended Python install uses uv (fast, hermetic).
macOS / Linux
# Install via uv (creates an isolated tool install)
uv tool install annotation-mcp
# Or with pipx (similar to uv tool, classic alternative)
pipx install annotation-mcp
# Or with pip
pip install annotation-mcpThe annotation-mcp command will be installed and the server can be registered in your MCP client config (e.g. ~/.config/opencode/opencode.json):
{
"mcp": {
"annotation": {
"type": "local",
"command": ["annotation-mcp"],
"enabled": true
}
}
}Windows
# With uv (recommended)
uv tool install annotation-mcp
# With pip
pip install annotation-mcpThe annotation-mcp.exe will be installed. Same MCP client config works.
3. Install from source (development)
git clone https://github.com/aschokinatgmail/annotation-mcp.git
cd annotation-mcp
uv sync --all-extras --dev
uv tool install --force --reinstall .Detection tools — workflow
The detection tools are designed to solve the "where is X in this image?" problem. They return structured text + bbox data so the AI can match semantic labels to coordinates deterministically, rather than guessing from approximate vision.
Typical workflow
Call
detect_text_regionsto get all text regions in the image with their content, bounding boxes, and confidence scores.Match semantic label to region by inspecting the
textfield. E.g., for "find the brand title", look for the region whosetextmatches the brand name.Refine if needed — if a region is split across multiple detections (e.g., the brand title is "ФИТОС" + "ПОРИН"), use the
crop_for_inspectiontool to zoom in and re-detect, or extend the bbox using a y-band heuristic.Call
annotatewith the discovered bboxes.
Example: annotating a product package
# Step 1: Find all text regions
text_matches = detect_text_regions(image_path, lang="eng+rus", detail="word", min_confidence=30)
# Returns 400+ regions with text content + bbox_pixels
# Step 2: Find the brand title region
brand_region = next(r for r in text_matches if "ФИТО" in r["text"].upper())
# Returns: {text: "ФИТОС", bbox_pixels: [1019, 786, 1300, 881], confidence: 88, ...}
# Step 3: Find the barcode (deterministic decoding)
barcodes = detect_barcodes(image_path)
# Returns: [{type: "EAN13", data: "4607026420155", bbox_pixels: [2366, 3403, 2622, 3994], ...}]
# Step 4: Find the dosage table by keyword
table_regions = [r for r in text_matches if any(kw in r["text"].lower() for kw in ["мл", "м²", "капля", "растен"])]
# Take the union bbox
# Step 5: Annotate
annotate(image_path, output_path="result.png", normalized=True, annotations=[
{"type": "bbox", "bbox": brand_region["bbox_normalized"], "label": "Brand", "color": "#FF0000"},
{"type": "bbox", "bbox": barcodes[0]["bbox_normalized"], "label": "Barcode", "color": "#00AA00"},
{"type": "bbox", "bbox": table_bbox_normalized, "label": "Table", "color": "#0066FF"},
])When tesseract quality is poor: re-recognize with a vision model
Tesseract produces reliable output on clean documents but can return
high-confidence nonsense on real-world photos (small, low-contrast, curved,
embossed text). The detect_text_regions tool has two features for
handling this:
filter_garbage(defaultTrue): rejects OCR-noise regions (e.g.VLOAOL,yOLO,||||) based on a heuristic that combines text length, character-class diversity, vowel ratio, dictionary presence, and part-number pattern. Catches ~98% of typical Tesseract garbage on real photos.crop_regions(defaultFalse): when set toTrue, the tool also writes per-region image crops to disk and returns their paths in the result. A vision model can then re-recognize each crop with higher accuracy. The workflow:
# Step 1: get tesseract bboxes + cropped images for each region
result = handle_detect_text_regions(
photo_path,
lang="eng", detail="word", preprocess="clahe",
crop_regions=True,
crop_padding=0.15,
)
regions = result.structuredContent["regions"]
crops = result.structuredContent["region_crops"]
# Step 2: for each crop, send to vision model for re-recognition
for crop in crops:
vision_text = recognize_with_vision_model(crop["crop_path"])
# vision_text is the actual text in that regionWhen a region is split across multiple detections
OCR can split a single visual line into multiple text regions (especially with stylized fonts or low-resolution scans). To recover the full region:
Find a single word region whose text you recognize.
Compute the y-band:
y_band = (bbox_bottom - bbox_top) * 0.6around the y-center.Find all regions in the same y-band.
Take the union bbox (min/max of x1,y1,x2,y2).
Optionally add padding.
Preprocessing modes for detect_text_regions
Mode | Use case |
| Clean scans, screenshots, high-contrast documents. |
| Default. Photos with uneven lighting (most product photos). |
| High-contrast text on flat backgrounds (signs, screenshots). |
| Clean black-and-white text (book pages, printed labels). |
If opencv-python is not installed, only none is available; the others fall back to PIL autocontrast.
Graceful degradation
If system dependencies are missing, the detection tools return clear error messages instead of crashing:
detect_barcodeswithout pyzbar/zbar:"pyzbar not installed. Install with: pip install pyzbar; and the zbar shared library: brew install zbar (macOS) or apt install libzbar0 (Linux)"detect_text_regionswithout tesseract:"tesseract binary not found. Install with: brew install tesseract tesseract-lang"detect_text_regionswith missing language pack:"Tesseract language pack(s) not installed: ['rus']. Install with: brew install tesseract-lang"
The 5 original annotation tools (annotate, draw_bounding_box, highlight_region, draw_numbered_callouts, get_image_info) work without any system dependencies.
HEIC / iPhone photo support
iPhone photos are stored as .HEIC files. The image_io module
registers pillow_heif at import time so PIL can decode HEIC directly.
This works on all three platforms with no extra setup.
HEIC test fixtures are not committed to the repo (HEIC files can contain EXIF metadata with GPS coordinates and device info). The HEIC tests skip cleanly when no local HEIC file is found. To exercise them locally, place a HEIC file at any of:
tests/fixtures/exif_orientation.heictests/fixtures/sample.heic~/Pictures/sample.heic
Coordinate systems
All tools accept either pixel coordinates ([x1, y1, x2, y2] in absolute pixels) or normalized coordinates ([0.0, 0.0, 1.0, 1.0] fractions of image dimensions). Set the normalized flag accordingly.
Output bboxes are always provided in both pixel and normalized form for the caller's convenience.
Development
# Clone and install dev dependencies
git clone https://github.com/aschokinatgmail/annotation-mcp.git
cd annotation-mcp
uv sync --all-extras --dev
# Run tests (cross-platform)
uv run pytest
# Run tests with coverage
uv run pytest --cov=annotation_mcp
# Type check (strict mode)
uv run basedpyright
# Lint
uv run ruff checkCI runs on every push and PR across macOS, Linux, and Windows with Python 3.12:
.github/workflows/ci.yml
Architecture
image_io.py— Image loading with EXIF orientation handling (all 8 spec values), HEIC support.process.py/render.py— Annotation validation and PNG rendering.coords.py— Coordinate conversion (pixel ↔ normalized).handlers.py/handlers_detection.py— MCP tool handlers.server.py— FastMCP server registration (8 tools).detection/— Barcode (pyzbar), OCR (tesseract + garbage filter), and crop modules.
Privacy & security notes
EXIF data: Real photos often contain GPS coordinates, device info, and timestamps. The test fixtures in this repo have all such metadata stripped. The
crop_for_inspectionandannotatetools DO NOT strip EXIF from output images by default — if you save annotated images, the EXIF from the source is preserved. Strip it explicitly with PIL orexiftoolif needed.No telemetry: This server does not collect or transmit any data. All processing is local.
No file uploads: The server reads images from the local filesystem at the path you provide. It does not fetch images from URLs.
License
MIT.
Available Tools
8 toolsannotateC
Draw multiple annotations (bbox, arrow, highlight, callout, text, circle) on an image. Returns annotated image + manifest JSON.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| normalized | No | ||
| annotations | Yes | ||
| output_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. Description says it modifies the image but does not disclose side effects (e.g., whether original is overwritten, permissions needed, or if the operation is reversible). Returns results but lacks detail on behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with action and supported types. Efficient but could be better structured to include parameter hints. Not overly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Lacks essential details about the 'annotations' parameter structure, coordinate system, and output format. With 4 parameters and no output schema, the description is insufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description does not explain any of the four parameters (path, normalized, annotations, output_path). The 'annotations' array has no defined structure, which is a critical gap. The description adds no value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool draws multiple annotation types (bbox, arrow, etc.) on an image and returns an annotated image and manifest JSON. It specifies the verb and resource, and the list of annotation types distinguishes it from sibling tools that handle a single type.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like draw_bounding_box or highlight_region. No prerequisites or exclusions mentioned. The description assumes the agent knows the context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crop_for_inspectionA
Crop a region of an image and save it to a new file. Useful for iteratively zooming into a region so a vision model can give more precise coordinates. Bounding box can be in pixel or normalized [0, 1] coordinates; optional padding expands the crop on each side.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | Yes | ||
| path | Yes | ||
| padding | No | ||
| normalized | No | ||
| output_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are absent, so the description must carry the burden. It discloses bounding box coordinate systems and padding, which is helpful. However, it omits behavioral details such as what happens when output_path is null (e.g., default save behavior or return value) and whether the original file is preserved. This gap reduces transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly concise (three sentences) and front-loaded with purpose, then use case, then details. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 5 parameters, no output schema, and no annotations, the description covers the overall purpose and a key use case but lacks full parameter documentation (e.g., output_path behavior and normalized boolean). It is adequate for simple usage but not fully complete for an agent to confidently invoke without additional assumptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It explains bbox (pixel or normalized) and padding, adding meaning beyond the schema. However, it does not describe the normalized boolean parameter directly (only alludes to it), nor the behavior of output_path being null. Some parameters remain unexplained, leading to a moderate score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (crop), resource (image), and action (save to new file). It also provides a specific use case ('iteratively zooming into a region so a vision model can give more precise coordinates') that distinguishes it from sibling tools like annotate or draw_bounding_box.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear context for when to use the tool (iterative zooming for vision models) but does not explicitly exclude alternative tools or mention when not to use it. The context is clear enough for simple cropping tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_barcodesB
Detect 1D barcodes (EAN, UPC, Code 128/39, etc.) and 2D codes (QR, DataMatrix, PDF417) in an image. Returns deterministic pixel bounding boxes for each detected code. Requires pyzbar + zbar library.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| allowed_types | No | ||
| min_confidence | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It discloses that the tool returns 'deterministic pixel bounding boxes' and requires 'pyzbar + zbar library', adding useful behavioral context. However, it lacks details on permissions, side effects (e.g., file modification), or network usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, concise, and front-loaded with the primary action. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (multiple barcode types, three parameters) and no output schema, the description is insufficient. It does not explain parameter behavior or output structure beyond bounding boxes. A complete description would include parameter roles and output format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description does not explain any parameters (path, allowed_types, min_confidence). The schema provides names and types without further meaning, and the description adds no value for parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool detects 1D (EAN, UPC, Code 128/39) and 2D (QR, DataMatrix, PDF417) barcodes in an image. The verb 'Detect' and the resource are explicit, and it distinguishes from sibling 'detect_text_regions' which handles text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives or any prerequisites. It does not mention conditions, performance considerations, or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_text_regionsA
Detect text regions in an image using Tesseract OCR. Returns each region with its text content, pixel bounding box, and confidence score. Use this to find the coordinates of brand titles, dosage tables, ingredients lists, etc. Supports multiple languages (e.g. eng+rus) and various preprocessing modes for photos vs. clean scans. Set filter_garbage=false to keep OCR-noise regions, or crop_regions=true to also save per-region image crops that a vision model can re-recognize (useful when tesseract quality is low).
| Name | Required | Description | Default |
|---|---|---|---|
| psm | No | ||
| lang | No | eng | |
| path | Yes | ||
| detail | No | word | |
| preprocess | No | clahe | |
| crop_padding | No | ||
| crop_regions | No | ||
| filter_garbage | No | ||
| min_confidence | No | ||
| crop_output_dir | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries the full burden. It discloses that the tool uses OCR, returns region data (text, bounding box, confidence), and supports various preprocessing modes. It does not explicitly state that it is read-only or has no side effects, but the description implies non-destructive behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is six well-structured sentences. It fronts the purpose, then provides usage examples and key parameter explanations. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (10 parameters, no output schema), the description covers the main purpose and several critical parameters. However, it omits explanations for psm, detail, min_confidence, and crop_padding, and does not describe the return format beyond generalities. A more complete description would address these gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must compensate. It explains lang (via example), preprocess (various modes), filter_garbage, crop_regions, and crop_output_dir (implied). However, psm, detail, min_confidence, and crop_padding are not explained, leaving about half of the parameters undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Detect text regions in an image using Tesseract OCR', specifying the action (detect), resource (text regions in an image), and method (Tesseract OCR). It is distinct from sibling tools like detect_barcodes, which detects barcodes instead of general text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides specific use cases ('find the coordinates of brand titles, dosage tables, ingredients lists') and hints at when to use options like filter_garbage and crop_regions. However, it does not explicitly contrast with alternatives like detect_barcodes or explain when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_bounding_boxC
Draw a single bounding box on an image. Convenience wrapper around annotate.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | Yes | ||
| path | Yes | ||
| color | No | #FF0000 | |
| label | No | ||
| font_size | No | ||
| thickness | No | ||
| normalized | No | ||
| output_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears full burden for behavioral disclosure. It fails to mention side effects, permissions, or behavior (e.g., whether the original image is modified, how output_path works, or any constraints).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no redundancy; front-loaded with purpose. While it could benefit from more detail, it is not verbose. The efficiency earns a high score but misses opportunity to add context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with no output schema and no annotations, the description is severely lacking. It does not explain how to use parameters like 'normalized' or 'output_path', nor the tool's return value. It fails to provide sufficient context for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema coverage is 0%, and the description adds no meaning to parameters. For example, it does not explain what 'bbox' coordinates represent (e.g., absolute vs normalized), nor the impact of 'color' or 'thickness' defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it draws a bounding box on an image, identifying the verb and resource. It also mentions being a convenience wrapper around annotate, which hints at its relationship to a sibling, though it does not explicitly differentiate from other drawing tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like annotate or highlight_region. It only states it is a wrapper, without clarifying the trade-offs or preferred contexts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_numbered_calloutsC
Draw numbered callout circles on an image. Convenience wrapper around annotate.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| color | No | #FF0000 | |
| radius | No | ||
| callouts | Yes | ||
| font_size | No | ||
| normalized | No | ||
| output_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must fully disclose behavioral traits, but it only says 'Draw numbered callout circles'. It does not mention if the image is modified in-place, required permissions, side effects, or that it is a wrapper (which may imply limited functionality).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
While the description is short (one sentence), it is under-specified for a tool with 7 parameters. Important information is omitted, so brevity here sacrifices usefulness, making it less than concise in the sense of carrying necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of annotations and an output schema, and a tool with 7 parameters, the description fails to provide a complete understanding. It does not describe return behavior, the meaning of 'normalized', or how 'callouts' are structured, making it inadequate for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% schema description coverage, and the description adds no explanation of the parameters. 'callouts' is an array of objects with no constraints, but the description does not clarify its structure or expected format, leaving the agent with no guidance beyond parameter names and types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Draw numbered callout circles') and the resource ('on an image'), and explicitly distinguishes itself as a convenience wrapper around 'annotate', implying a specific use case for numbered callouts compared to sibling tools like draw_bounding_box.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description hints that this tool is a simplified version of 'annotate', suggesting when to use it (for numbered callouts) versus the more general 'annotate'. However, it does not provide explicit guidance on when not to use it or compare to other siblings like detect_text_regions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_image_infoB
Get image metadata (dimensions, format, orientation, size, alpha, density).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Lists metadata fields but does not disclose error behavior, permissions, or that it's a read-only operation. With no annotations, more detail would be helpful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with no wasted words; parenthetical list adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Lacks output structure and error handling details. For a metadata retrieval tool, more context on return format would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% parameter description coverage, and the description does not explain the 'path' parameter (e.g., format, supported sources).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves image metadata and lists examples. It distinguishes from sibling tools that perform modifications or detections.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use vs alternatives. Sibling tools are listed but without context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
highlight_regionB
Highlight a rectangular region on an image. Convenience wrapper around annotate.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | Yes | ||
| path | Yes | ||
| color | No | #FFFF00 | |
| opacity | No | ||
| normalized | No | ||
| output_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description should fully disclose behavior, but it only says it highlights and is a wrapper. It omits crucial details like whether it modifies the image, side effects, or authorization needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (two sentences) with no wasted words, though it could benefit from slightly more detail without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 6 parameters, no output schema, and no annotations, the description is far from complete. It fails to explain how to use parameters or what output to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description provides no explanation of the parameters (bbox, color, opacity, etc.), forcing the agent to rely solely on parameter names and types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool highlights a rectangular region on an image, with a specific verb and resource. It distinguishes itself from the sibling 'annotate' by calling itself a convenience wrapper.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage as a simpler alternative to 'annotate' for highlighting rectangles, but does not explicitly state when to avoid it or compare to other siblings like 'draw_bounding_box'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.2.0- First observed
annotate - First observed
crop_for_inspection - First observed
detect_barcodes - First observed
detect_text_regions - First observed
draw_bounding_box - First observed
draw_numbered_callouts - First observed
get_image_info - First observed
highlight_region
TDQS
Scored across 8 tools
Three tools (draw_bounding_box, draw_numbered_callouts, highlight_region) are explicitly convenience wrappers around annotate, creating overlapping functionality. An agent may be uncertain whether to use annotate directly or the wrapper.
All tool names follow a verb_noun snake_case pattern (e.g., detect_barcodes, get_image_info), with one minor exception (crop_for_inspection uses a preposition) but still consistent in style.
The 8-tool surface is well-scoped for an image annotation and detection server, providing core operations without unnecessary bloat.
Covers annotation, detection (barcodes, text), cropping, and metadata. Minor gaps: no tool to clear/undo annotations, but core workflows are supported.
Maintenance
Related MCP Connectors
MCP server for detecting and redacting PII (Personally Identifiable Information) in PDF documents.
MCP server for visual regression testing: triage a PR's UI diffs from your coding agent.
MCP server for medicaid-intelligence
MCP server for real-time product search by barcode (EAN, UPC, GTIN) or keyword on ean-search.org
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn MCP server providing tools for image processing operations126 PyPI331PythonMIT
- AlicenseNot gradedqualityDmaintenanceMCP server for visual feedback, video direction, and QA assertions on web pages, enabling AI agents to read, reply, and resolve annotations in real time.6MIT
- AlicenseAqualityFmaintenanceAn MCP server that adds image recognition to AI coding tools, enabling them to analyze images, extract text, and perform OCR via multimodal APIs and traditional OCR engines.325MIT
- FlicenseAqualityCmaintenanceMCP server for image analysis, providing OCR text extraction, image metadata, and EXIF/GPS data as structured JSON for downstream processing.3-