Skip to main content
Glama
mx-fiscal-mcp-server

mx-fiscal-mcp-server

by OrtaMarco

CFDI Status at the SAT, several invoices

cfdi_batch_status
Read-onlyIdempotent

Ask the SAT about up to 25 invoices in one call — same service and same answer per invoice as cfdi_status, with the SAT's request for restraint built in: at most 2 requests in flight, duplicates asked once, answers remembered in…

Instructions

Ask the SAT about up to 25 invoices in one call — same service and same answer per invoice as cfdi_status, with the SAT's request for restraint built in: at most 2 requests in flight, duplicates asked once, answers remembered in memory for 10 minutes (an outage is never remembered), and once 2 consecutive requests have failed no new one is started (one already in flight still finishes). Use it to reconcile a handful of invoices; it is not a bulk-verification pipeline, and the SAT states its service is sized for up to 2 million queries per hour and asks callers not to raise their volume.

Each item is either { xml } (preferred — the four values are derived from it) or { rfc_emisor, rfc_receptor, total, uuid }. An item that cannot be queried (bad XML, unstamped, malformed field) is reported on its own line with the reason and costs no request; it does not fail the batch.

Per item, outcome is: queried (asked the SAT now), cached (answered from memory, up to 10 minutes old), duplicate (same invoice as an earlier item), rejected (never sent; see error) or skipped (not attempted after repeated outages). A queried item whose result.available is false means the SAT did not answer — a statement about the SAT, never about the invoice. The same applies to skipped.

Args:

  • items (array of 1-25): each with xml OR rfc_emisor + rfc_receptor + total + uuid.

  • response_format ('markdown' | 'json'): output format (default 'markdown').

Returns: { total, queried, cached, duplicates, rejected, skipped, unavailable, stopped_after_outage, items[{index, outcome, source, error, uuid, result}] }, where result has the shape cfdi_status returns (without source).

Example: "Are these three invoices still live?" -> cfdi_batch_status(items=[{xml:"…"},{xml:"…"},{xml:"…"}]).

Input Schema

NameRequiredDescriptionDefault
itemsYesThe invoices to check, 1-25.
response_formatNoOutput format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload.markdown

Output Schema

NameRequiredDescriptionDefault
itemsYes
totalYes
cachedYes
queriedYes
skippedYes
rejectedYes
duplicatesYes
unavailableYes
stopped_after_outageYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv1.1.1

TDQS

A4.8/5.0
Behavior5/5

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

Far exceeds the annotations (which only cover readOnly/idempotent/openWorld): discloses max 2 requests in flight, 10-minute in-memory caching, that outages are never cached, duplicate dedup, a circuit breaker after 2 consecutive failures, and that a malformed item costs no request and does not fail the batch. These are exactly the runtime traits an agent cannot infer elsewhere.

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?

Front-loaded with the constraint set, then item shape, then outcome vocabulary — a sensible order. It loses a little to duplication: the explicit 'Args:' and 'Returns:' blocks restate what the input and output schemas already declare, and the bolded SAT-roles paragraph is dense on first read.

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?

Covers the non-obvious parts an agent cannot get from structured fields: the meaning of every `outcome` value and the critical disambiguation that `available: false` (and `skipped`) describes the SAT, never the invoice. With an output schema present, not restating field shapes in depth is acceptable.

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 coverage is 100%, so the baseline is 3; the description still adds value by marking `{ xml }` as preferred and stating the alternative four-field shape inline. It also explains that unusable items are rejected per-item with a reason rather than failing the call, which changes how an agent should construct `items`.

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?

Specific verb and resource ('ask the SAT about up to 25 invoices in one call') plus an explicit relation to the single-invoice sibling: 'same service and same answer per invoice as `cfdi_status`'. An agent can distinguish this from `cfdi_status` without inspecting either schema.

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

Usage Guidelines5/5

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

Gives both the intended use ('reconcile a handful of invoices') and an explicit exclusion ('it is not a bulk-verification pipeline'), plus the reason (SAT sizing of ~2M queries/hour). The example question ('Are these three invoices still live?') anchors the trigger condition.

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