Skip to main content
Glama

Suparch

Search supplements by what's inside.

Suparch is an open-source MCP server for searching, comparing, and calculating structured supplement facts. It provides label data and deterministic calculations; it does not diagnose conditions or recommend supplements.

Current tools

  • search_products: search by product text, included ingredients, excluded ingredients, ingredient forms, product type, target group, brand, and price.

  • get_product: return the complete normalized label record for a product.

  • compare_products: compare per-serving ingredients and forms.

  • calculate_stack: add known label amounts for user-supplied daily servings.

  • get_catalog_info: report snapshot schema, size, timestamps, and product count.

Production deployments use an immutable SQLite snapshot opened in read-only mode. The crawler and catalog builder run separately from the public MCP process, which makes the server suitable for ephemeral MCP Hub containers.

Related MCP server: openfoodfacts-mcp-server

English Kroger API MVP

The default acquisition path uses Kroger's public Products API for English product identity, UPC, current USD price, and location-scoped availability. It does not scrape retailer HTML. Create a Kroger developer application, choose a store location ID, and keep the OAuth credentials outside the repository:

export KROGER_CLIENT_ID=<client-id>
export KROGER_CLIENT_SECRET=<client-secret>

uv run suparch-catalog kroger-sync \
  --location-id 01400943 \
  --term vitamin \
  --term magnesium \
  --category "vitamins & supplements" \
  --category "sports nutrition" \
  --limit-per-term 100 \
  --output build/kroger-products.jsonl \
  --report build/kroger-sync-report.json

Kroger prices depend on --location-id. Overlapping query results are deduplicated, and non-supplement categories are rejected. Without explicit --category values the filter accepts common supplement-only categories such as vitamins & supplements, dietary supplements, and sports nutrition. The report records products without a valid GTIN or price. Each retained offer carries its Kroger location ID and available fulfillment modes into MCP responses. Credentials are accepted only through KROGER_CLIENT_ID and KROGER_CLIENT_SECRET, so they do not appear in command history.

Kroger offers do not contain dependable Supplement Facts. Sync DSLD labels and join them by UPC before building the public catalog:

uv run suparch-catalog dsld-sync \
  --query "*" \
  --status on-market \
  --limit 1000 \
  --output build/dsld-products.jsonl

uv run suparch-catalog enrich-dsld \
  --products build/kroger-products.jsonl \
  --dsld build/dsld-products.jsonl \
  --output build/enriched-products.jsonl \
  --report build/dsld-enrichment-report.json \
  --require-label \
  --database build/catalog.sqlite

Use several focused supplement terms for a toy catalog. A production snapshot should use a deliberate query inventory and inspect coverage reports before publication.

Optional authorized iHerb affiliate feed

The optional importer accepts an approved iHerb affiliate catalog as UTF-8 CSV or CSV.GZ. It deliberately keeps one market contract: English (en-US), USD prices, and HTTPS iherb.com product URLs. Rows outside an English supplement category or with another currency are excluded.

uv run suparch-catalog import-iherb-feed \
  --input build/iherb-us-feed.csv.gz \
  --report build/iherb-import-report.json \
  --min-products 1 \
  --min-gtin-coverage 0 \
  --output build/iherb-products.jsonl

--min-products and --min-gtin-coverage are atomic publication gates. Set them after inspecting the first approved feed rather than guessing production thresholds. A failed gate preserves the previous product output and writes a non-product report containing counts and coverage ratios.

The importer recognizes common Impact and retail-feed column names for product name, brand/manufacturer, URL, current price, currency, GTIN/UPC, and category. It derives the canonical iHerb product ID from the /pr/ URL, validates GTIN check digits, removes duplicate products, and reports every skipped row class. Use repeated --category options when an approved feed uses additional English category names:

uv run suparch-catalog import-iherb-feed \
  --input build/iherb-us-feed.csv.gz \
  --category supplement \
  --category "sports nutrition" \
  --output build/iherb-products.jsonl

Affiliate catalogs usually provide offers rather than complete Supplement Facts. Run the DSLD enrichment step below before relying on ingredient search, comparison, or stack calculation. A direct --database build is useful for offer/name search but can contain products without label rows.

NIH DSLD label enrichment

NIH's Dietary Supplement Label Database (DSLD) supplies label facts when a retail record can be matched by UPC. Standalone DSLD records must not be presented as retailer inventory or current offers.

Sync a resumable DSLD JSONL enrichment source:

uv run suparch-catalog dsld-sync \
  --query magnesium \
  --status on-market \
  --limit 1000 \
  --output build/dsld-products.jsonl

Then enrich a Kroger or authorized affiliate Product JSON/JSONL source by UPC:

uv run suparch-catalog enrich-dsld \
  --products build/kroger-products.jsonl \
  --dsld build/dsld-products.jsonl \
  --output build/enriched-products.jsonl \
  --report build/dsld-enrichment-report.json \
  --min-label-coverage 0 \
  --require-label \
  --database build/catalog.sqlite

Enrichment also fails atomically when it produces no products or misses the operator-selected --min-label-coverage. The report separates UPC matches from products that actually contain ingredient rows.

Use --limit 0 for the complete matching result set. The sync uses bounded concurrency and retries, flushes each page to disk, resumes by DSLD label ID, and repairs a truncated final JSONL record after an interrupted write. A sync sidecar pins the query, market status, limit, API, and parser version so incompatible runs cannot be mixed. Resume is only for interrupted runs; use --no-resume to refresh a completed snapshot and reconcile changed labels.

Quick start

uv sync --extra dev
uv run suparch

Suparch uses the bundled sample catalog by default. To use another catalog:

uv run suparch-catalog build \
  --input src/suparch/data/sample_catalog.json \
  --output catalog.sqlite

SUPARCH_DB_PATH=./catalog.sqlite uv run suparch

Run the MCP development inspector:

uv run mcp dev src/suparch/server.py

Run checks:

uv run pytest
uv run ruff check .

Build and verify a catalog

uv run suparch-catalog build \
  --input products.json \
  --output catalog.sqlite

uv run suparch-catalog verify \
  --database catalog.sqlite

The builder writes to a temporary file, runs SQLite integrity checks, and publishes the final database with an atomic rename. It also creates:

catalog.sqlite.sha256
catalog.sqlite.manifest.json

Inputs may be a JSON object, JSON array, or JSONL file. Repeat --input to merge multiple normalized files into one snapshot.

Parse a saved iHerb product page

uv run suparch-catalog parse-html \
  --input product.html \
  --url https://www.iherb.com/pr/example-product/12345 \
  --output product.json

Discover product references from iHerb's published sitemap without using its disallowed search path:

uv run suparch-catalog iherb-discover \
  --limit 1000 \
  --output build/iherb-product-refs.jsonl

The sitemap contains multiple iHerb departments, so these references are only discovery input. An authorized feed or page-ingestion job must filter the supplement category before publishing a Suparch catalog.

To merge the parsed product directly into a catalog snapshot:

uv run suparch-catalog parse-html \
  --input product.html \
  --url https://www.iherb.com/pr/example-product/12345 \
  --database catalog.sqlite

For batch ingestion, use a manifest so the catalog is loaded and published only once:

[
  {
    "input": "pages/product-12345.html",
    "url": "https://www.iherb.com/pr/example-product/12345",
    "locale": "en-US"
  }
]
uv run suparch-catalog parse-manifest \
  --manifest crawl-manifest.json \
  --database catalog.sqlite

Single-page live fetching exists for development but is disabled unless the operator explicitly passes --allow-live-fetch. It checks the current robots.txt, rate limits requests, and does not implement authentication, anti-bot bypass, or browser fingerprint evasion. Operators remain responsible for reviewing the site's current terms before using it.

At the time of the latest project check, standard product paths were allowed by the published robots rules, but unauthenticated product requests returned HTTP 403. Suparch preserves that fail-closed behavior. See docs/data-sources.md for approved-input options and the official affiliate path.

Hub deployment

Hub deployments require an API- or feed-backed retail catalog. Suparch does not ship NIH records as a substitute for inventory, pricing, or availability.

Run the stateless Streamable HTTP transport:

SUPARCH_TRANSPORT=streamable-http \
SUPARCH_HOST=0.0.0.0 \
PORT=8000 \
SUPARCH_DB_PATH=/data/catalog.sqlite \
uv run suparch

If the Hub cannot mount persistent files, publish the catalog to versioned object storage:

SUPARCH_CATALOG_URL=https://cdn.example.com/catalog-2026-07-16.sqlite \
SUPARCH_CATALOG_SHA256=<sha256> \
SUPARCH_TRANSPORT=streamable-http \
uv run suparch

Suparch downloads and validates the artifact during startup, then opens it read-only. The MCP endpoint defaults to /mcp.

Build the container:

docker build -t suparch .
docker run --rm -p 8000:8000 \
  -e SUPARCH_CATALOG_URL=https://cdn.example.com/catalog.sqlite \
  -e SUPARCH_CATALOG_SHA256=<sha256> \
  suparch

If SUPARCH_CATALOG_SHA256 is omitted for a custom URL, Suparch derives the manifest URL by appending .manifest.json. Set SUPARCH_CATALOG_MANIFEST_URL only when the manifest lives elsewhere.

MCP Registry

The repository includes an official Registry-compatible server.json for the OCI package ghcr.io/namjeongwan/suparch. Version tags such as v0.1.0 publish the corresponding image through GitHub Actions. Registry publication should only run after that exact image tag is publicly available.

JSON catalog format

[
  {
    "id": "source:product-id",
    "source": "example",
    "source_product_id": "product-id",
    "name": "Magnesium Glycinate",
    "brand": "Example Labs",
    "serving_size": "2 capsules",
    "servings_per_container": 60,
    "active_ingredients": [
      {
        "canonical_name": "magnesium",
        "label_name": "Magnesium",
        "form": "magnesium glycinate",
        "amount": "200",
        "unit": "mg",
        "normalized_amount": "200000",
        "normalized_unit": "mcg",
        "daily_value_percent": "48"
      }
    ],
    "other_ingredients": ["hypromellose"],
    "price": {
      "amount": "19.99",
      "currency": "USD"
    },
    "product_url": "https://example.com/products/product-id",
    "crawled_at": "2026-07-16T00:00:00Z"
  }
]

All label strings are preserved alongside normalized values. Normalization must never destroy the source label text.

DSLD quantity and daily-value operators are preserved. Non-equality amounts such as < 1 g remain visible in label details but are excluded from stack arithmetic because they are not exact values. When a label provides different daily values for adults, children, pregnancy, or lactation, every target-group entry is returned instead of presenting the first percentage as universal.

Search results return compact summaries with at most 20 canonical ingredient names plus the total ingredient count. Use get_product for the complete label.

Architecture

Kroger Products API -------------------> retail Product JSONL
authorized affiliate feed ------------> retail Product JSONL
                                                  |
                                       DSLD enrichment by UPC
                                                  |
                                                  v
                                        immutable SQLite snapshot
                                                  |
MCP client -> stateless Suparch server -> read-only repository

The MCP layer only retrieves and calculates product facts. Domain-specific skills or clients remain responsible for interpreting symptoms, selecting nutrient targets, and presenting medical guidance.

See docs/architecture.md for the deployment and data publication design.

Environment variables

Variable

Purpose

SUPARCH_DB_PATH

Read-only SQLite file mounted into the runtime

SUPARCH_CATALOG_POINTER_URL

Operator-managed pointer containing an immutable catalog URL and SHA-256

SUPARCH_CATALOG_URL

HTTPS SQLite artifact downloaded on startup

SUPARCH_CATALOG_MANIFEST_URL

Optional custom manifest URL; defaults to <catalog URL>.manifest.json

SUPARCH_CATALOG_SHA256

Optional artifact checksum

SUPARCH_CATALOG_CACHE_PATH

Download destination, default /tmp/suparch/catalog.sqlite

SUPARCH_TRANSPORT

stdio, sse, or streamable-http

SUPARCH_HOST

HTTP bind host

SUPARCH_PORT / PORT

HTTP port

SUPARCH_MCP_PATH

Streamable HTTP endpoint, default /mcp

iHerb data acquisition

iHerb's current robots policy disallows automated /search URLs and advertises product sitemaps. Standard product pages are not disallowed by path, but unauthenticated crawler requests currently receive HTTP 403. Suparch does not evade that access control.

The production path is:

approved iHerb affiliate feed/API or operator-supplied pages
  -> iHerb Product records
  -> optional DSLD enrichment by UPC
  -> immutable SQLite snapshot
  -> read-only MCP

iHerb lists Partnerize, Impact, CJ, and Awin as official affiliate platforms and explicitly accepts shopping-comparison partners. An approved feed or written data-access permission is therefore the next external dependency. See docs/affiliate-onboarding.md for the exact application text, requested feed fields, licensing questions, and safe handoff.

Available Tools

5 tools
calculate_stackB

Sum known label amounts for a user-supplied product and serving combination.

ParametersJSON Schema
NameRequiredDescriptionDefault
selectionsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalsYes
productsYes
duplicate_ingredientsYes

TDQS

B3.3/5.0
Behavior2/5

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

With no annotations provided, the description carries the full transparency burden. It only states the high-level operation without disclosing side effects, error handling, read-only status, or the computation logic. The phrase 'Sum' implies a read operation, but key behavioral details are absent.

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 sentence with no redundant words, front-loading the action verb 'Sum'. It is appropriately sized for a simple tool, though brevity limits explanatory depth.

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?

Despite having an output schema and a nested input structure, the description omits important context such as return value, usage scenarios, and integration with sibling tools. It fails to mention that multiple product selections can be summed, leaving the tool's full capabilities unclear.

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%, so the description must compensate. It vaguely mentions 'product and serving combination' but does not clarify the roles of product_id or servings_per_day, nor that selections is an array allowing multiple entries. This adds minimal value beyond the raw 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 ('Sum') and resource ('known label amounts') for a specific context (product and serving combination). It distinguishes itself from sibling tools like search_products and get_product by using a calculation-oriented verb, avoiding tautology.

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 description implies usage for totaling label amounts, but provides no explicit guidance on when to use this tool versus alternatives. It does not mention sibling tools or any exclusions, leaving usage context largely inferred.

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

compare_productsA

Compare per-serving label facts across two or more products.

ParametersJSON Schema
NameRequiredDescriptionDefault
product_idsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
productsYes
ingredientsYes
common_ingredientsYes

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the burden. It implies a read-only comparison operation and adds 'per-serving label facts' context, but does not explicitly disclose side effects, data sources, or behavior beyond the basic action. Since it is clearly a non-destructive comparison, a 3 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 a single, front-loaded sentence with no filler. It states the verb, resource, and key constraint efficiently.

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

Completeness4/5

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

Given the tool's simplicity (one parameter, output schema present), the description covers the essential purpose and the minimum product count. No critical details are missing for an agent to invoke it correctly.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate. It does by clarifying that the product_ids array must contain at least two product identifiers ('two or more products'), which is a critical constraint not visible in the schema. This adds meaningful semantic value.

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 action (compare), the resource (products), and the specific scope (per-serving label facts). It naturally distinguishes from siblings like get_product (single product) and search_products (finding products).

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 description implies use when comparing multiple products but provides no explicit guidance on when to use this tool versus alternatives. Sibling tools exist and could be called out, but the verb 'compare' gives some contextual cue.

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

get_catalog_infoA

Return catalog version, product count, and snapshot metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
sourceYes
built_atNo
updated_atNo
product_countYes
database_bytesNo
schema_versionNo

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full transparency burden. It clearly indicates a read-only operation (via 'Return') and specifies the outputs, which covers the key behavioral trait. Minor details like potential performance implications are absent, but given the tool's simplicity, the description is reasonably transparent.

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?

A single, front-loaded sentence states the verb and outputs directly. No wasted words; every element contributes to understanding the tool's function.

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

Completeness5/5

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

For a zero-parameter read-only tool with an output schema (which presumably documents the return structure), the description is sufficiently complete. It lists all key outputs (catalog version, product count, snapshot metadata) and requires no further explanation for invocation.

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

Parameters4/5

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

The tool has zero parameters, and the schema coverage is trivially 100%. The baseline for 0 parameters is 4, and the description appropriately adds no parameter-specific semantics since none are needed.

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 'Return catalog version, product count, and snapshot metadata' uses a specific verb and lists concrete resources, making the tool's purpose unmistakable. It clearly distinguishes itself from siblings like search_products and get_product, which focus on individual product queries.

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?

No explicit when-to-use or alternative guidance is provided. The intended use (when catalog-level metadata is needed) is implied by the description and tool name, but unlike the TDQS high example, it does not explicitly state exclusions or recommend alternative tools for other scenarios.

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

get_productB

Return one complete normalized supplement label record.

ParametersJSON Schema
NameRequiredDescriptionDefault
product_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
upcNo
nameYes
brandYes
priceNo
localeNo
sourceYes
on_marketNo
crawled_atYes
product_urlYes
product_typeNo
serving_sizeNo
offer_contextNo
target_groupsNo
parser_versionNo
supplement_formNo
other_ingredientsNo
parser_confidenceNo
source_product_idYes
active_ingredientsNo
servings_per_containerNo

TDQS

B3/5.0
Behavior2/5

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

With no annotations, the description carries the full burden. It mentions 'complete' and 'normalized,' which are behavioral traits, but does not disclose what happens if the product is not found, whether the operation is read-only, or any potential side effects. The description is too minimal to inform the agent of safety or error 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 a single sentence with the verb front-loaded. It is concise, clear, and contains no fluff or repetition. Every word earns its place.

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 one-parameter getter with an output schema, the description is minimally viable. It states the core action and object, and the output schema covers return values. However, it lacks usage context, especially regarding sibling tools, and provides no parameter details, leaving gaps for an agent to select it correctly.

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?

Schema description coverage is 0%, so the description must compensate, but it does not explain 'product_id' at all. The parameter name is self-explanatory only by convention; no format, usage, or semantics are provided. The description adds no value beyond the bare 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 action (Return) and the resource (one complete normalized supplement label record), which distinguishes it from siblings like search_products or compare_products. It specifies the scope (single record) and the type of data (supplement label), making the tool's purpose unambiguous.

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 no guidance on when to use this tool versus alternatives. It doesn't mention that this is for fetching a specific product by ID, nor does it point to search_products for discovery or compare_products for comparison. There is no explicit when/when-not or alternative naming.

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

search_productsC

Search supplement labels using objective product and ingredient filters.

ParametersJSON Schema
NameRequiredDescriptionDefault
upcNo
formsNo
limitNo
queryNo
brandsNo
offsetNo
currencyNo
max_priceNo
on_marketNo
product_typesNo
target_groupsNo
supplement_formsNo
exclude_ingredientsNo
include_ingredientsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalYes
productsYes

TDQS

C2.7/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It only states that the tool performs a search; it does not mention whether it is read-only, how it handles pagination (e.g., 'limit'/'offset' parameters), or any side effects. The phrase 'objective product and ingredient filters' hints at query capabilities but lacks specifics about return behavior or constraints.

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

Conciseness3/5

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

The description is one concise sentence, but it is under-specified for a tool with 14 parameters and no other documentation. While there is no fluff, the extreme brevity leaves out essential context, making it only partially 'appropriately sized.'

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?

Given the tool's complexity (14 parameters, no annotations, no schema description coverage), the description is insufficient. It provides a high-level purpose but does not explain filtering capabilities, result format, or usage context. An output schema exists, but the description alone is too thin for an agent to understand the tool's full scope.

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 schema has 14 parameters with zero description coverage, and the tool description does not compensate. It only generically refers to 'product and ingredient filters,' which does not explain any specific parameter (e.g., 'upc', 'brands', 'include_ingredients'). The description adds no meaning beyond the raw parameter names and types in 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 function: 'Search supplement labels using objective product and ingredient filters.' The verb 'Search' is specific to the resource 'supplement labels,' and the mention of filters differentiates it from sibling tools like 'get_product' or 'compare_products.' This is a clear and distinguishing 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 provides no guidance on when to use this tool versus alternatives such as 'get_product' or 'compare_products.' There are no explicit conditions, exclusions, or references to sibling tools, leaving the agent to infer usage from the tool name alone.

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. 5 tool updatesv0.5.0
    • First observedcalculate_stack
    • First observedcompare_products
    • First observedget_catalog_info
    • First observedget_product
    • First observedsearch_products

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: searching, retrieving a single product, accessing catalog metadata, comparing multiple products, and calculating aggregated amounts. There is no overlap between these operations.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (search_products, get_product, get_catalog_info, compare_products, calculate_stack). The convention is uniform and predictable.

Tool Count5/5

With 5 tools, the server is well-scoped for its purpose of accessing and analyzing supplement label data. Each tool serves a distinct function without redundancy or bloat.

Completeness5/5

The tool set covers the full range of expected operations for a read-only supplement label API: discovery, retrieval, metadata, comparison, and aggregation. No critical gaps are apparent for the stated domain.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers