Skip to main content
Glama

πŸ›’ Shelf Auditor MCP

Point an LLM agent at a photo of a retail shelf β€” it counts the products, finds the out-of-stock gaps, and checks the layout against a planogram.

A Model Context Protocol server for retail-shelf computer vision.

Python MCP Detector License

count_products on a shelf photo β€” every facing boxed, with pixel + normalised coordinates and a confidence.


Why this exists

Retail audit work β€” counting facings, catching stockouts, verifying planogram compliance β€” is repetitive visual grunt work. An LLM agent with the right tools can do it from a single phone photo. This server gives an agent those tools over MCP, so it drops straight into Claude Desktop, Cline, or any MCP client.

It is built as a portfolio piece: a clean, documented, demoable MVP with a real fine-tuned model behind it, not a pile of half-features.

Related MCP server: Vision MCP Server

What it can do

Tool

What it returns

Status

count_products

Per-label counts, every item's bbox (pixels) + bbox_normalized (0–1) + confidence, and an annotated image

βœ…

detect_gaps

Empty shelf regions grouped by row, each with a width ratio vs. the row's mean product and a severity (minor / moderate / major)

βœ…

check_planogram

missing / misplaced / extra / wrong_order deviations against a slot spec, plus a compliant flag

βœ…

shelf_report

Meta-tool: runs count + gaps (+ planogram) and returns one combined JSON and a Markdown summary

βœ…

get_job_status Β· get_job_result

Poll long-running jobs

βœ…

read_price_tags

Prices OCR'd (python-doctr), parsed to {value, currency}, linked to the nearest product

πŸ§ͺ solid on readable labels; tiny / superscript-cent tags in wide shots need a dedicated tag detector

The vision backends are pluggable behind one interface. read_price_tags needs the optional ocr extra; without it the tool returns a clean not_implemented status (the agent handles it, and shelf_report still runs the rest) instead of crashing.

Resources: image://{id} Β· results://{job_id} Β· annotated://{job_id} Β· models://available Prompts: count-items Β· detect-gaps Β· read-shelf Β· planogram-check

See it work

In an agent (Claude Desktop)

Ask in plain language β€” "How many products are on this shelf and are there any gaps?" β€” and the agent picks shelf_report, runs it on the image, and comes back with the counts, the gap list, and an annotated picture. Walkthrough: examples/demo_walkthrough.md.

πŸŽ₯ Screen-recording of the agent flow β€” coming shortly.

Why a retail-specific detector

This is a class-ontology comparison, not a recall one. Stock YOLOv8s has no "product" class, so it forces every loaf into the nearest of its 80 COCO labels β€” donut, cake, sandwich. Confident and useless: you can't audit facings from a pile of "donuts". The SKU-110K fine-tune has one purpose-built class and reports each facing as product.

Stock YOLOv8s β€” COCO classes

YOLOv8s fine-tuned on SKU-110K

donut 0.78, cake, sandwich β€” wrong ontology

one product class per facing β€” right ontology, lower scores on this shot

That confidence drop is real and expected: a German bakery case behind glass β€” angled, warm-lit, reflective β€” is about as far from SKU-110K's evenly-lit US grocery aisles as a shelf photo gets, so scores fall and the default detector_conf of 0.2 filters some true loaves. On in-distribution shots like the wine shelf above, the same weights box 73/73 facings cleanly. Closing that domain gap is the "in-domain detector" item in the Roadmap; it does not affect the benchmark number (0.938 mAP@0.5 on SKU-110K val).

shelf_report output

{
  "count_products": { "total": 73, "counts": { "product": 73 } },
  "detect_gaps":    { "gap_count": 3, "rows_detected": 3,
                      "gaps": [{ "row": 0, "severity": "moderate", "width_ratio": 1.45 }, …] }
}
# Shelf audit report
**Products detected:** 73
**Shelf gaps:** 3 across 3 row(s)
- row 0: moderate (Γ—1.45 mean width)

Architecture

The MCP layer (protocol, schema validation, job management) is kept strictly separate from the vision backend. Every capability implements one interface β€” BaseVisionModel.run(image, params) -> Result β€” so swapping YOLOv8 for RT-DETR, or a local model for a cloud API, never touches MCP code.

flowchart LR
    A[MCP client<br/>Claude Desktop Β· Cline] -->|tool call| B[FastMCP server]
    B --> C[schemas.py<br/>strict Pydantic]
    C --> D[tools/*]
    D --> E[imaging.py<br/>load Β· resize Β· annotate]
    D --> F[jobs.py Β· storage.py]
    D --> G[backends/BaseVisionModel]
    G --> H[YoloDetector<br/>SKU-110K fine-tune]
    G --> I[OcrBackend<br/>stub]
src/vision_mcp/
  server.py     FastMCP instance β€” registers tools, resources, prompts
  schemas.py    per-tool input/output models
  config.py     pydantic settings (env prefix VISION_MCP_)
  imaging.py    path / URL / base64 β†’ RGB array; resize; annotate
  jobs.py       async job manager      storage.py   image + result cache
  backends/     base.py + detector.py (YOLO) + ocr.py (stub) + matching.py
  tools/        one module per tool
scripts/hpc/    fine-tune the detector on a SLURM cluster

Quickstart

uv sync
uv run python scripts/download_models.py     # COCO fallback weights β†’ models/
uv run python -m vision_mcp.server           # stdio MCP server

Runs out of the box on the COCO fallback. For the SKU-110K accuracy in the numbers above, fetch the fine-tune β€” see scripts/hpc/README.md.

Wire it into a client with examples/claude_desktop_config.json (fix the path), then walk through examples/demo_walkthrough.md.

Try it on any image β€” annotated PNGs + JSON land in out/:

uv run python scripts/try_image.py path/to/shelf.jpg
uv run python scripts/try_image.py shelf.jpg --slots planogram.json

Poke the protocol with the MCP Inspector:

uv run mcp dev src/vision_mcp/server.py

The detector

Default weights are a YOLOv8s fine-tuned on SKU-110K, trained on the University of Twente GPU cluster (scripts/hpc/, one L40, 42 min).

Value

SKU-110K val mAP@0.5

0.938

SKU-110K val mAP@0.5:0.95

0.595

Precision / Recall

0.916 / 0.886

Training

30 epochs Β· imgsz 960 Β· 1Γ— NVIDIA L40 Β· 42 min

The detector runs class-agnostic, so its single object class is reported as "product". If models/yolov8s_sku110k.pt is missing, it falls back to auto-downloaded COCO yolov8n.pt and says so in the response notes. To fetch the fine-tune, follow scripts/hpc/README.md then:

export VISION_MCP_DETECTOR_WEIGHTS=yolov8s_sku110k.pt

Development

uv run pytest                          # core suite is synthetic β€” no weights needed
uv run ruff check . && uv run mypy src

uv run python tests/fixtures/download_fixtures.py   # + real-photo integration tests

Docker

docker build -t shelf-auditor .                            # CPU
docker build -f Dockerfile.cuda -t shelf-auditor:cuda .    # CUDA β€” run with --gpus all

Roadmap

  • Price-tag OCR β€” read_price_tags runs python-doctr and parses {value, currency} (works well on clear labels β€” $11, $0.25/100, 1.19). Generic OCR misses small / distant tags and European superscript-cent formats (5⁴⁰); a production version needs a price-tag region detector feeding per-crop OCR.

  • In-domain detector. SKU-110K is dead-on, evenly-lit US grocery; on angled or dim store photos the fine-tune localises well but scores lower (hence detector_conf 0.2). train_sku110k.sbatch retrains on any labelled set (IMGSZ=1280 for the tiniest facings).

  • Deliberately out of scope: video / tracking, per-client model training, batch folders, cloud vision backends, multi-tenant auth.

Credits & licensing

  • Code: MIT β€” see LICENSE.

  • SKU-110K (Goldman et al., CVPR 2019) is released for academic / non-commercial use β€” the shipped fine-tuned weights inherit that restriction. Retrain on licensed or self-collected data before commercial deployment.

  • Demo photos are CC-BY from Wikimedia Commons: Alsatian wines in a supermarket by francois (CC BY 2.0); Krustenbrot for sale at supermarket by Maksym Kozlenko (CC BY-SA 4.0). Full list in tests/fixtures/SOURCES.md.

Config reference

Environment variables, prefix VISION_MCP_ (see src/vision_mcp/config.py):

Var

Default

DEVICE

auto

auto / cpu / cuda

DETECTOR_WEIGHTS

yolov8s_sku110k.pt

file in models/, or an ultralytics name

DETECTOR_CONF

0.2

detection confidence floor

DETECTOR_IMGSZ

960

YOLO inference resolution

MAX_EDGE_PX

1920

longest image edge before inference

MAX_INLINE_IMAGE_BYTES

4 MiB

above this, annotated images return as a reference


Built by TrαΊ§n Quang ThΓ nh β€” AI Engineer specialising in Computer Vision &amp; LLM agents. Available for freelance work.

Upwork Β· LinkedIn Β· GitHub

Available Tools

7 tools
check_planogramB

Compare the shelf against a planogram spec (list of slots with expected normalized regions + optional order). Lists missing / misplaced / extra / wrong-order deviations.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
imageYes
notesNo
annotatedNo
compliantYes
deviationsYes
deviation_countYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It accurately describes the read-only comparison and output, but does not mention any side effects, failure modes, or dependence on confidence thresholds, leaving some transparency gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that packs the essential function and output. No fluff or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema, the return details are not necessary. However, the description lacks context about input requirements (e.g., how image is provided) and any prerequisites, making it only partially complete for a new agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%. The description only vaguely references 'list of slots' but does not explain parameters like image, conf, iou_threshold, or annotate. It adds minimal value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('Compare the shelf against a planogram spec') and its output (lists deviations: missing, misplaced, extra, wrong-order). It is specific and easily distinguishes it from a generic checker.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like detect_gaps or shelf_report. It only describes the function without context on suitable scenarios or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

count_productsB

Count products on a shelf photo. Returns per-label counts, per-item boxes (absolute + normalized) with confidence, and an annotated image.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
imageYes
itemsYes
notesNo
totalYes
countsYes
annotatedNo

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does disclose the main outputs: per-label counts, per-item boxes with confidence, and an annotated image. However, it does not explain behavioral details such as how the annotate flag switches between inline and by-reference results, how the conf override affects detection, or any error/edge-case behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two tight sentences (~20 words) that front-load the primary purpose first and then list the returns. There is no fluff, redundancy, or extraneous detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Since an output schema exists, the description need not re-explain return values, and the purpose is clearly stated. However, it lacks usage direction relative to sibling tools and does not clarify parameter behavior, leaving the overall context slightly incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Given the reported 0% schema description coverage, the description must compensate for the three parameters (image, conf, annotate) but does not explain any of them. It merely alludes to the annotated image output, leaving the meaning and effect of the conf override and annotate flag unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with the specific verb+resource pair 'Count products on a shelf photo', which precisely states the tool's core function. This clearly distinguishes it from siblings like read_price_tags and detect_gaps without any ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implicitly conveyed through the verb 'Count products on a shelf photo' β€” the agent must infer when to prefer this over sibling tools such as read_price_tags or detect_gaps. No explicit guidance is given on when to choose this tool or when to select an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detect_gapsB

Find empty (out-of-stock) regions on the shelf, grouped by row, each with a width ratio versus the row's mean product width and a severity.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
gapsYes
imageYes
notesNo
annotatedNo
gap_countYes
rows_detectedYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It does not mention whether the tool is read-only, has side effects, or returns an annotated image. The return format (inline or by reference) is only implied via the 'annotate' parameter in the schema, not in the description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that conveys the essential functionality without unnecessary words. It is concise, easy to parse, and directly to the point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides the output details but omits the input requirements (like needing an image) and any mention of optional annotations. Given the moderate complexity of a vision-based tool, this missing context could leave an agent uncertain about how to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description does not mention any parameters (e.g., image input, confidence threshold, annotation flag). Given that the schema description coverage is 0% according to the context, the description fails to compensate by providing parameter context, even though the schema itself includes descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: detecting empty (out-of-stock) regions on a shelf, grouped by row, and providing width ratio and severity. This leaves no ambiguity about the core purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not mention when to use this tool compared to its siblings (e.g., count_products, check_planogram). It lacks explicit guidance on selection criteria or scenarios where this tool is preferred over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_job_resultC

Result of a finished async job.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYes

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, and the description does not disclose whether this operation is read-only, whether it can block or wait, whether it errors on incomplete jobs, or any other behavioral details. The full burden falls on the description, which does not carry it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very short and front-loaded, containing no unnecessary words. It is concise, though it sacrifices informative content for brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description gives only a minimal high-level context. It does not explain how to obtain a job_id, what the returned result looks like, or how this tool relates to get_job_status beyond the word 'finished'.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter job_id is only defined by its name and schema type. The description adds no meaning about where the job_id comes from, its expected format, or how it relates to other async job tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly indicates this tool provides the result of an async job, distinguishing it from get_job_status which would report status. However, it lacks an explicit verb like 'returns' or 'retrieves', making it a noun phrase rather than a full action statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'finished async job' implies usage should occur after job completion, but it does not explicitly direct the agent to check status first via get_job_status or mention any alternatives. The guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_job_statusC

Status of an async job created by a heavy tool call.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries the full burden of disclosing side effects and behavior. It implies a read-only status check, but it does not mention potential outcomes such as pending, completed, or failed states, nor does it address polling semantics or error conditions. The description is too minimal to fully inform an agent of behavioral expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single short sentence that conveys the essential purpose without unnecessary words. It is appropriately concise and well-structured for the tool's simple nature.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple status-checking tool, the description gives minimal but sufficient context about its async-job relationship. However, there is no output schema or explanation of the return format, and the relationship to get_job_result is not explicitly clarified. An agent might need additional details to use the tool confidently in a polling workflow.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides no description for job_id, and the tool description only vaguely references 'an async job'. Since schema coverage is 0%, the description should compensate by explaining what job_id refers to and how to obtain it. The identifier's purpose is inferable from context, but no format, source, or validation details are provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states that the tool returns the status of an async job, which is clear enough given the tool name. It does not explicitly use a verb like 'retrieve' or 'get', but the intent is unambiguous. It also distinguishes itself from the sibling get_job_result by focusing on status rather than result.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides limited context by mentioning 'async job created by a heavy tool call', implying it is used for polling. However, it does not explicitly state when to use this tool versus alternatives like get_job_result, nor does it explain the expected workflow. No concrete usage conditions are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_price_tagsB

Read price labels and link each to the nearest product. NOTE: the OCR backend is currently a stub and returns status 'not_implemented'.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
tagsNo
imageNo
notesNo
statusYes

TDQS

B3.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explicitly discloses a critical limitation: the OCR backend is a stub and returns 'not_implemented'. This is a clear behavioral warning that directly informs the agent of an expected failure mode. Since no annotations are provided, this note carries the full transparency burden, and it does so effectively. It does not mention other potential behaviors (e.g., annotated image output), but the core limitation is disclosed, so a 4 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is highly concise, consisting of just two sentences. The first presents the core purpose, and the second delivers a vital behavioral note. There is no redundant information, and the structure is clean and direct. It earns full marks for efficiency and clear organization.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description includes the essential purpose and the most critical behavioral caveat (the stub). However, it lacks usage guidance and fails to explain how the parameters relate to the tool's function, even though the schema provides some detail. Given the presence of sibling tools, the description is not fully self-contained for an agent to decide when to invoke it. It is adequate but has clear gaps, so a 3 is appropriate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool description provides zero coverage of the parameters (image, conf, annotate). While the schema itself includes descriptions for each field, the description does not compensate for the low coverage (0% per the context signals). Since the description adds no meaning about how the parameters affect the tool's behavior, this dimension is weak. The schema descriptions partially mitigate the gap, but the description fails to integrate them, resulting in a score of 2.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's primary action: reading price labels and linking them to the nearest product. It gives a concrete verb ('read', 'link') and a specific object ('price labels', 'nearest product'), which distinguishes it from sibling tools like count_products or detect_gaps. However, the term 'nearest' is somewhat ambiguous without specifying the reference frame (e.g., image position), so it is not a perfect 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance on when to use this tool versus its siblings. The description does not mention use cases, prerequisites, or alternatives. The note about the OCR stub is a behavioral warning, not usage direction. An agent would have to infer when to call read_price_tags from the name alone, which is insufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

shelf_reportB

Run count, gap detection, and (optionally) a planogram check on one image and return a combined JSON and/or markdown report.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
imageYes
reportYes
markdownNo
annotatedNo

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, and the description does not disclose potential side effects, permissions, rate limits, or whether the tool is read-only. The description only mentions what it does, not behavioral constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that clearly states the main function and output. It is well-structured and free of unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core functionality but omits mention of optional features like format selection, annotation, and price-tag reading. While the schema fills some gaps, the description alone is not fully complete for an agent to understand all capabilities.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides detailed descriptions for most parameters (e.g., image, slots, conf, annotate, include_price_tags). The tool description adds little beyond stating the high-level purpose, so it contributes minimal value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool runs count, gap detection, and optionally a planogram check, returning a combined report. It distinguishes itself from sibling tools by combining these functionalities, though it does not explicitly mention the format or price-tag options.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this combined tool versus the individual sibling tools (e.g., count_products, detect_gaps, check_planogram). Agents must infer the appropriate context.

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.

  1. 7 tool updatesv0.1.0
    • First observedcheck_planogram
    • First observedcount_products
    • First observeddetect_gaps
    • First observedget_job_result
    • First observedget_job_status
    • First observedread_price_tags
    • First observedshelf_report

TDQS

A3.6/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: counting products, detecting gaps, reading price tags, checking planograms, and managing async jobs. The shelf_report tool is a composite but still distinct from the individual analysis tools.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., count_products, detect_gaps, get_job_status). The naming is predictable and uniform.

Tool Count5/5

With 7 tools, the set is well-scoped for a shelf analysis domain. It covers the main analysis functions plus job management without being excessive or sparse.

Completeness5/5

The toolset covers all core shelf analysis tasks: product counting, gap detection, price tag reading, planogram compliance, and combined reporting. Async job support is also included, providing a comprehensive surface.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    Not graded
    maintenance
    Enables AI agents to analyze images through vision AI providers (Gemini, OpenAI, Claude), performing tasks like image description, object detection with bounding boxes, region-specific analysis, and precise color extraction without consuming context window with raw pixels.
    4
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to analyze images using any OpenAI-compatible vision API, providing tools for image analysis, OCR, error diagnosis, diagram understanding, and chart analysis.
    MIT