Skip to main content
Glama
theluckystrike

Duplicate supplier invoice check MCP server

Duplicate supplier invoice check MCP server

MCP server for duplicate supplier invoice and vendor bills review: supplied-batch exact and normalized references with free CSV evidence. Review duplicate supplier invoice candidates in supplied local history.

Works with Claude Desktop, Claude Code, Cursor and any Model Context Protocol client. Runs on your own machine: this one has no hosted endpoint, so install it from the bundle or from source.

Product page: https://mcp.zovo.one/s/duplicate-invoice-check — capabilities, free limits and supported installation paths.

Try the editable duplicate-invoice review in your browser before installing. Synthetic fields are checked locally in your browser without uploads. Candidates require review; they are not payment decisions.

Install

Claude Desktop, one click. Download duplicate-invoice-check.mcpb from the bundle catalog and double-click it.

From source. The mirror is self-contained: every @theluckystrike/* dependency is vendored, so a fresh clone builds with no extra setup.

git clone https://github.com/theluckystrike/mcp-duplicate-invoice-check.git
cd mcp-duplicate-invoice-check
npm install && npm run build

Then point your client at the built entry point:

{
  "mcpServers": {
    "duplicate-invoice-check": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-duplicate-invoice-check/dist/index.js"]
    }
  }
}

@theluckystrike/mcp-duplicate-invoice-check is not published on npm yet, so an npx -y @theluckystrike/mcp-duplicate-invoice-check command will fail. The three paths above are the working ones and each is exercised by CI.

duplicate-invoice-check demo

Read-only mirror of mcp-servers/servers/duplicate-invoice-check. See MIRROR.md.

Review a supplied batch of supplier invoices for repeated invoice numbers, conservative formatting variations, or identical amounts and invoice dates. This local MCP server returns complete grouped evidence and the exact reason each record needs review. Distinct legitimate invoices can share an amount and date. Candidates are not confirmed duplicates, fraud scores, recoverable money or payment decisions. It does not connect to an ERP, read PDFs, use OCR, or retrieve missing history.

Built by theluckystrike. MIT. Support: support@zovo.one.

Related MCP server: AP Invoice Exception Review MCPB

Install

Claude Desktop: download duplicate-invoice-check.mcpb v0.22.8 and open it. SHA-256: 181379eb6dcff3d90b55e080dd9c180f6c96802e991872865a6b0ce422b3aaea. Other clients can use the source instructions below.

Requires Node.js 18 or newer and an MCP client. No API key or account is needed for free use. The npm package is not published: build the source checkout, then use an absolute local path.

git clone https://github.com/theluckystrike/mcp-servers.git
cd mcp-servers
npm install
node scripts/bootstrap-timezone.mjs
npm run build --workspace @theluckystrike/mcp-license
npm run build --workspace @theluckystrike/mcp-duplicate-invoice-check

Claude Desktop: merge this entry into mcpServers in ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, or %APPDATA%\Claude\claude_desktop_config.json on Windows. Replace /absolute/path with the checkout location.

{"mcpServers":{"duplicate-invoice-check":{"command":"node","args":["/absolute/path/mcp-servers/servers/duplicate-invoice-check/dist/index.js"]}}}

Claude Code:

claude mcp add duplicate-invoice-check -- node /absolute/path/mcp-servers/servers/duplicate-invoice-check/dist/index.js

Cursor: put this local entry in .cursor/mcp.json in your project or ~/.cursor/mcp.json:

{"mcpServers":{"duplicate-invoice-check":{"type":"stdio","command":"node","args":["/absolute/path/mcp-servers/servers/duplicate-invoice-check/dist/index.js"]}}}

VS Code: use .vscode/mcp.json with the top-level key servers:

{"servers":{"duplicate-invoice-check":{"type":"stdio","command":"node","args":["/absolute/path/mcp-servers/servers/duplicate-invoice-check/dist/index.js"]}}}

Windsurf's legacy Cascade agent: merge the Claude Desktop mcpServers JSON into ~/.codeium/windsurf/mcp_config.json. This file applies to Cascade; its newer Devin Local agent uses a different configuration route. The standalone server exposes eight tools.

Cline: open its MCP Servers panel, Configure tab, then Configure MCP Servers. Add this entry to the settings JSON (for the Cline CLI, the file is ~/.cline/mcp.json):

{"mcpServers":{"duplicate-invoice-check":{"type":"stdio","command":"node","args":["/absolute/path/mcp-servers/servers/duplicate-invoice-check/dist/index.js"],"disabled":false,"autoApprove":[]}}}

These are the six local stdio client configurations used by this project. There is no hosted endpoint or browser chat connector. If the client cannot find node, replace it with the absolute path printed by which node. After saving, reconnect the server (fully quit and restart Claude Desktop), call license_status, then run the example below. A tools/list result alone does not verify candidate checking.

Tools

Tool

Input and result

duplicate_invoice_check

records, optional save (false); complete grouped candidates, unique counts, source evidence and a free preview id.

report_list

Optional offset (0), limit (20, max 100); saved UUIDs and count summaries.

report_get

Saved id; source records, groups and reasons.

report_page

Saved or preview id, section, optional offset, limit (max 100), group_id; complete evidence pages.

report_delete

Saved id; delete one report and reuse its storage slot.

report_export_csv

Saved or preview id, optional offset, limit (max 1000); one row per source record, candidate reasons and group ids.

license_status

No arguments; offline tier and checkout link.

license_activate

key; verify and store an offline Pro license.

A repeated reference and a legitimate equal total

Call duplicate_invoice_check with synthetic records:

{
  "records": [
    {"record_id":"A","entity_id":"UK-1","supplier_id":"S-9","document_type":"invoice","invoice_number":"INV-001","invoice_date":"2026-10-01","currency":"USD","total_minor":12500},
    {"record_id":"B","entity_id":"UK-1","supplier_id":"S-9","document_type":"invoice","invoice_number":"INV-001","invoice_date":"2026-10-02","currency":"USD","total_minor":13000},
    {"record_id":"C","entity_id":"UK-1","supplier_id":"S-9","document_type":"invoice","invoice_number":"inv /001","invoice_date":"2026-10-03","currency":"USD","total_minor":12500},
    {"record_id":"D","entity_id":"UK-1","supplier_id":"S-9","document_type":"invoice","invoice_number":"SERVICE-02","invoice_date":"2026-10-01","currency":"USD","total_minor":12500}
  ],
  "save": false
}

The result has four unique candidate records and three groups. exact_reference includes A/B despite their different dates and totals. normalized_reference includes A/B/C and exposes every conflicting field. same_amount_date includes A/D: two different legitimate services could have the same date and total, so this group is a review prompt. A appears in three groups but is counted once. No sum of possible losses is calculated. Changing C to INV-1 excludes it from the normalized INV001 group because leading zeros remain meaningful.

Exact input contract

Supply 1–1000 records, each with unique record_id, exact entity_id and supplier_id, document_type (invoice or credit_note), invoice_number, real YYYY-MM-DD invoice_date, uppercase three-letter currency, and positive safe-integer total_minor. IDs and invoice numbers are 1–160 characters without surrounding whitespace or control characters. Optional entity_label and supplier_label are display-only text, up to 200 characters without controls. Unknown fields are rejected.

Amounts are integer currency minor units, never floating point amounts: USD 12500 means $125.00. Currency codes are checked for uppercase three-letter syntax, not against an external currency registry. Credit notes use positive absolute amounts and compare only with credit notes. No amounts are added, converted or interpreted as a financial loss. Year 0000, impossible calendar dates, duplicate record ids, zero/negative/decimal/unsafe money and over-limit batches are input errors.

Each rule groups only records with exactly equal (entity_id, supplier_id, document_type, currency). Entity and supplier IDs are case-sensitive: similar names, different IDs and different entities never join. Multiple entities can appear in a batch, but each remains a separate scope. Display labels do not affect matching.

Three equality rules run independently:

  1. exact_reference: the original invoice number matches exactly, even when amounts/dates differ.

  2. normalized_reference: ASCII a-z becomes A-Z; only ASCII space, hyphen, slash and dot are removed. Leading zeros, accents, all Unicode characters, underscores, nonbreaking spaces, Unicode dashes and letter/digit lookalikes remain unchanged. Empty normalized keys do not collide.

  3. same_amount_date: positive amount and invoice date both match exactly. This frequently has legitimate explanations.

Groups contain complete membership, exact scope and match key, an explanation and differing source fields. They are independent overlapping reasons, not transitive confirmed-duplicate clusters. candidate_record_count counts the union once. no_candidates_in_supplied_batch means these limited rules found none in the records supplied; it does not mean safe to pay. Missing history and reference, date or amount changes can evade these rules. Saved reports never become implicit cross-call history: include all records you want compared every time.

Source records and report groups are sorted deterministically; reordering the same input records produces the same diagnostic evidence. The computation groups keys instead of producing every pair: at most 3000 memberships for 1000 records, including overlap. The server performs no telemetry or network requests.

Free evidence, paging and CSV

Every check returns a retrieval.report_id, including unsaved checks. Preview IDs are preview:<UUID>, local to the current server process. The last two previews remain available for 30 minutes. A third check, restart or expiry can evict a preview; resubmit the original free diagnostic. Saved UUIDs persist on disk.

report_page sections are records, groups, record_summaries, and group_members. Follow next_offset until null, with limit 1–100. Group pages return summary metadata and member_count; read all members using section: "group_members" and the exact group_id. Member pages contain complete original records. Records are stored once in the report; groups refer to their exact record ids. All pages and CSV exports are free, including after hitting the saved-report cap.

The encoded incoming stdio message must fit the SDK's 10 MiB receive buffer. Responses use an 8 MiB escaped text-envelope budget; a larger report returns an explicit paginated overview with the same free retrieval instructions. Current 1000-row/text limits fit that budget in transport tests, including worst-case quoting. CSV uses one row per record rather than repeating it for each group. It includes original source fields, candidate flag, reason codes and group ids. Formula-like leading text is escaped. Export returns text; it never writes to a caller-supplied filename. CSV pages can contain fewer rows than the requested limit when quoting would exceed the response budget. Follow the actual next_offset until null; returned always counts the rows in that page. Every CSV page repeats its header; retain one header when joining pages.

Free and Pro

Capability

Free

Pro

All checks, source records, grouped reasons

Included, up to 1000 records/call

Same

Preview pages and CSV

Included

Same

Concurrent saved reports

3

No report-count cap

Total saved storage

64 MiB

64 MiB

Input/output, text and preview safety bounds

Same documented bounds

Same

save: true at the free cap still returns the complete diagnostic and free preview with saved: false, save_error: "free_saved_report_cap", and an upgrade link. Delete a saved report to reuse a slot. Storage failures also preserve diagnostics. Pro removes only the saved-count cap; it does not increase input, transport, preview or total storage bounds.

Get Pro: $19 one time. All servers: $39 bundle. Set MCP_LICENSE_KEY or call license_activate. Keys verify offline.

All data stays local. Reports live under ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/duplicate-invoice-check/. XDG_DATA_HOME must be absolute and directory ancestry must contain no symlinks. Private JSON files use atomic writes and cross-process mutation locks; reads revalidate source records and recompute the evidence instead of trusting edited derived results. License activation writes the shared local license config. Manage local accounting-data access and backups yourself.

Development

npm run build --workspace @theluckystrike/mcp-duplicate-invoice-check
npm test --workspace @theluckystrike/mcp-duplicate-invoice-check

Build Docker from the repository root: docker build -f servers/duplicate-invoice-check/Dockerfile .. Tests cover actual stdio calls, schema rejection, scope/Unicode/zero negatives, an independent 2000-batch pairwise oracle, grouped 1000-record transport, pages and CSV, cross-process save caps, recomputation, symlink/path rejection and aggregate storage boundaries. A local signed-key stdio test uses the operator's existing signer if present; it skips when that private signer is absent.

Available Tools

8 tools
duplicate_invoice_checkReview duplicate invoice candidatesB

Group up to 1000 supplied records by exact/normalized reference or exact amount/date within exact entity, supplier, type and currency. All evidence is free. Candidates require review; no payment approval.

ParametersJSON Schema
NameRequiredDescriptionDefault
saveNo
recordsYes

TDQS

B3.4/5.0
Behavior3/5

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

Annotations declare readOnlyHint=false and idempotentHint=false, so the agent already knows this is not a pure read and is not safely repeatable. The description adds useful context the annotations do not (evidence is 'free', candidates require review, no payment approval), but it never explains the write implied by readOnlyHint=false — namely that save=true persists results — leaving the key behavioral question unanswered.

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?

Two sentences, front-loaded with the core action and no filler; 'All evidence is free' and the review caveat are terse and each carries information. The first sentence is dense but not padded, so only marginal tightening is possible.

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?

With no output schema and no parameter descriptions, the description should at least sketch the return shape and the effect of 'save'; it gestures at output ('candidates require review') but never describes what a candidate group contains or that save=true persists it. Adequate to call the tool, incomplete for predicting the result.

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?

Schema description coverage is 0%, so the description must carry the load; it partially does by naming the grouping keys (entity, supplier, type, currency, reference, amount, date), which map onto the nested record fields. However, the 'save' parameter is never mentioned, and the description does not add format or constraint detail beyond what the schema itself encodes.

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 a concrete action (group supplied records) and enumerates the matching rules (exact/normalized reference, exact amount/date within exact entity, supplier, type and currency), which lets an agent distinguish it from the report_*/license_* siblings. It never quite says 'detect duplicates' in prose, but the title plus the explicit match keys make the purpose unmistakable.

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?

Usage is implied rather than stated: 'Candidates require review; no payment approval' tells the agent the output is advisory and not an approval mechanism, which bounds how the result should be used. There is no explicit when-to-use/when-not or any named alternative, though the sibling set (reports, licensing) contains no plausible substitute for this tool.

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

license_activateActivate licenseA

Activate a Pro key (MCPL1.xxx.yyy) from checkout: verified offline against a built-in public key, saved to your config file. A wrong, malformed or expired key is refused, unsaved. license_status reads it back.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYesLicense key from the checkout confirmation page

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral burden. It discloses that verification happens offline against a built-in public key, that the key is persisted to the config file, and that invalid keys are refused and left unsaved. This is substantial transparency for an activation tool, though it could mention overwriting an existing key or the exact return 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 sentences with no filler. The first sentence front-loads the main action, source, verification method, and persistence. The second sentence efficiently covers error handling and points to the related read-back tool. Every clause adds value.

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 a single-parameter tool with no output schema and no annotations, the description covers activation behavior, verification mechanism, persistence, error outcomes, and how to read the result later. The only minor gap is an explicit statement of what the function returns upon success or failure, but the phrase 'refused, unsaved' implies a feedback mechanism. Overall, it is sufficiently complete for an agent to call 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?

The schema already documents the 'key' parameter at 100% coverage, so the baseline is 3. The description adds meaningful semantics by giving the concrete key format ('MCPL1.xxx.yyy'), confirming the key comes from the checkout page, and explaining that malformed or expired keys will be rejected. This goes beyond the schema's one-line description.

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 states a specific action ('Activate a Pro key'), the exact key format ('MCPL1.xxx.yyy'), the source ('from checkout'), and the core mechanism ('verified offline against a built-in public key'). It also differentiates itself from the sibling license_status by noting that license_status reads the activation back, so there is no ambiguity about which tool does what.

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

Usage Guidelines4/5

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

The description gives clear context: use this when you have a Pro key from checkout that needs to be activated. It also points to license_status as the read-back tool, which implies when to use a related sibling. It does not explicitly spell out 'do not use for checking status' or list other alternatives, but the context is strong enough to avoid misuse.

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

license_statusLicense statusA

Report this server's licence state: product, tier free or pro, licence id, expiry, the key source and the upgrade URL. No arguments, no network. Explains a free-tier refusal; license_activate installs a key.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations are absent, so the description carries the full burden of behavioral disclosure. It discloses that the call is local ('no network') and argument-free, and it mentions a specific explanatory behavior. The word 'Report' implies read-only, though it does not explicitly state non-destructive or permission requirements; this is adequate for a status command.

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?

Two sentences with no filler. The first sentence lists the output fields; the second adds constraints and the sibling pointer. Every clause contributes meaningful information.

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 status tool with no output schema, the description lists the expected output fields, behavioral constraints, and the relevant alternative tool. Nothing an agent needs to call it correctly is missing.

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 schema has zero parameters and the description reinforces this with 'No arguments'. It adds value by listing the reported fields, helping an agent understand what the empty input will yield. The baseline for zero-parameter tools is high, and the description meets it.

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 states a specific verb ('Report'), a clear resource ('this server's licence state'), and enumerates the exact fields returned. It also names the sibling 'license_activate' as the tool that does something different, so an agent can distinguish them immediately.

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?

The description gives explicit usage constraints: no arguments, no network, and explains a free-tier refusal. It also directs the agent to license_activate when the task is to install a key, serving as an explicit pointer to the relevant alternative.

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

report_deleteDelete one saved candidate reportA
Destructive

Delete one local saved report and free a storage slot. Does not change accounting records.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, readOnlyHint=false, idempotentHint=false and openWorldHint=false, so safety is partly covered. The description still adds real context: that deletion frees a storage slot (a side effect beyond the record) and that accounting records are unaffected. It omits that the action is non-idempotent, i.e. a repeat call on the same id behaves differently.

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?

Two short sentences with zero filler, and the primary action plus its side effect are front-loaded before the scope caveat. Every sentence earns its place.

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?

For a single-parameter destructive tool with full annotation coverage and no output schema, the description covers the action, its side effect, and its blast radius. The main remaining gap is the irreversibility/non-idempotency of the delete, which an agent would want stated explicitly.

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?

There is a single 'id' parameter with 0% schema description coverage, so the description must carry the burden and says nothing about it. The schema's strict UUID regex pattern does document the expected format structurally, which limits the harm, but the description adds no meaning such as where the id comes from.

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?

States a specific verb and resource ('Delete one local saved report') and bounds the scope ('local', 'free a storage slot'). It implicitly separates itself from accounting-record tools, though it never names a sibling like report_get or report_list to sharpen the contrast.

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?

Usage is implied by the resource type ('saved report') and the scope note that it does not touch accounting records, which helps an agent decide this is a local cleanup action. However, there is no explicit when-to-use guidance, no prerequisites, and no mention of related siblings such as report_list or report_export_csv.

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

report_export_csvExport candidate records as CSVB
Read-onlyIdempotent

Export free CSV pages from a saved report or unsaved preview. One row per record with reasons and group ids. Formula-like cells are escaped; no financial-loss total is calculated.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
limitNo
offsetNo

TDQS

B3.4/5.0
Behavior4/5

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

Annotations already establish read-only, idempotent, non-destructive, closed-world behavior, so the bar is lower. The description still adds real value beyond them: formula-like cells are escaped (CSV-injection handling) and no financial-loss total is computed, both of which would otherwise surprise a caller.

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?

Three short sentences, front-loaded with the action, with no filler. The wording is dense to the point of being terse in places ('free CSV pages'), but nothing is wasted.

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?

With no output schema, the description does partially describe the return shape ('one row per record with reasons and group ids'), which is helpful. However, for a paginated export it omits the limit cap and how to advance through pages, so an agent cannot fully drive it from the definition alone.

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 carry the parameters, but it only obliquely touches the id (saved report vs. 'preview:' form) and says nothing about limit or offset. The 1000-row cap and pagination behavior are entirely undocumented outside the schema types.

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?

Specific verb (Export) plus resource (CSV pages of a saved report or unsaved preview), which separates it from report_get/report_page siblings that return report data in another form. The phrase 'free CSV pages' is slightly cryptic but the core action is unambiguous.

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 when to use it (when a CSV of a report or preview is wanted) and hints that the id may be a saved report or an unsaved preview, but it never names a competing tool such as report_page or states exclusions. Usage is inferred rather than stated.

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

report_getRead a saved candidate reportA
Read-onlyIdempotent

Read a saved report with source records, reason groups and overlap-safe candidate counts. Large reports return free paging instructions.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, closed-world, so safety is covered. The description still adds real behavior beyond them: what the response contains and that oversized reports return paging instructions rather than truncating silently.

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?

Two tight sentences with zero filler; the payload description is front-loaded and the paging caveat follows as a secondary clause. Every phrase earns its place.

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?

For a read-only tool with full annotations and no output schema, the description covers what is returned and how large results are handled. The only meaningful gap is guidance on sourcing the required id.

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?

Schema coverage is 0% for the single required 'id' parameter, so the description carries the burden. It implies the id identifies a saved report but never states that it is a required UUIDv4 or where to obtain it, so the compensation is only partial.

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?

States a specific verb (Read) and resource (a saved report) and enumerates the payload (source records, reason groups, overlap-safe candidate counts). This is clearly distinguishable from report_list and report_page, though it never names those siblings to sharpen the boundary.

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?

Usage is implied by 'Read a saved report' plus the hint that large reports return paging instructions, which gestures at report_page. There is no explicit when-to-use statement, no prerequisite that an id must come from report_list, and no stated exclusion.

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

report_listList saved candidate reportsA
Read-onlyIdempotent

List saved report ids, timestamps and unique candidate counts. Free on both tiers. Up to 100 reports per page.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds genuinely new information: cost across tiers and a page-size ceiling. It does not describe pagination traversal behavior or what ordering to expect, so it neither contradicts nor fully supplements the annotations.

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?

Three short sentences, front-loaded with the return fields, then cost, then pagination limit. No sentence is wasted and nothing is buried.

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?

For a simple paged list with no output schema, the description supplies the return fields, the cost model, and the page ceiling, which is most of what an agent needs. The gap is pagination mechanics (how offset interacts with the page limit), which is left implicit.

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?

Schema description coverage is 0%, so the two parameters (limit, offset) are only named in the schema. The description reinforces the limit ceiling ('up to 100 reports per page') but says nothing about offset semantics or how to advance pages. Partial compensation, not full.

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 a specific verb (List) and resource (saved reports) and enumerates exactly what is returned: ids, timestamps, and unique candidate counts. It is not tautological. It stops short of naming the sibling it is not (report_get, report_page, report_export_csv), so the agent must infer the boundary itself.

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?

'Free on both tiers' gives useful selection context, implying this cheap listing is the right entry point before a paid per-report call. However, it never explicitly says when to use this versus report_get, report_page, or report_export_csv, leaving the choice to inference.

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

report_pageRead full candidate evidence pagesC
Read-onlyIdempotent

Read free pages of records, group summaries, record reasons or one group’s members. Unsaved preview ids last 30 minutes for the last two checks in this process.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
limitNo
offsetNo
sectionYes
group_idNo

TDQS

C2.1/5.0
Behavior2/5

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

Annotations cover the safety profile (readOnly, idempotent, non-destructive), so the description need not repeat that. However, the description adds little beyond a cryptic note about preview ids expiring in 30 minutes. It doesn't explain pagination behavior, what 'free pages' means, or how the 'last two checks' relate to the preview id lifetime. This is insufficient behavioral context for a read tool with no output schema.

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 brief, but the second sentence about preview ids is confusing and lacks structure. It is not front-loaded with the tool's purpose; instead it leads with 'Read free pages' which is ambiguous.

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

Completeness1/5

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

Given no output schema and 0% parameter documentation, the description fails to provide enough information for an agent to correctly use the tool. It does not clarify what sections correspond to which enum values, how id and preview ids work, or what the return data looks like.

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%, and the description does not explain any of the five parameters. The critical 'section' enum values are listed vaguely as 'records, group summaries, record reasons or one group's members', but the mapping to the actual enum values (records, groups, record_summaries, group_members) is unclear, and group_id, limit, offset, and the id format (including preview: prefix) are entirely unaddressed.

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

Purpose3/5

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

The description names the resource ('records, group summaries, record reasons or one group's members') but uses a vague verb 'Read' and does not clearly distinguish this tool from siblings like report_get or report_list. It's unclear whether this is a paginated viewer, an export, or something else specific.

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 on when to use this tool versus alternatives such as report_list or report_get. The description does not state prerequisites or conditions for invocation, leaving the agent to guess based on the name.

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. 8 tool updatesv0.22.8
    • First observedduplicate_invoice_check
    • First observedlicense_activate
    • First observedlicense_status
    • First observedreport_delete
    • First observedreport_export_csv
    • First observedreport_get
    • First observedreport_list
    • First observedreport_page

TDQS

A3.5/5.0

Scored across 8 tools

Disambiguation4/5

The core duplicate_invoice_check tool is clearly distinct from the report and license management tools. The report tools mostly have separate purposes, but report_get and report_page overlap in reading report content/pages, which could cause some misselection despite clarifying descriptions.

Naming Consistency5/5

All tools use snake_case with a consistent domain-prefix plus action pattern: duplicate_invoice_check, report_list, report_get, report_page, report_delete, report_export_csv, license_status, and license_activate. The convention is predictable even though duplicate_invoice_check has a longer domain prefix.

Tool Count5/5

Eight tools are well-scoped for the server: one core duplicate-checking tool, five report lifecycle tools, and two license tools. There is no obvious bloat, and each tool appears to earn its place.

Completeness3/5

The server covers duplicate checking, report listing/reading/paging/deleting/exporting, and license status/activation. However, there is no explicit tool for creating or saving a report from a duplicate check preview, leaving a notable gap in the saved-report lifecycle that may force workarounds.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

  • Documents 1.4.2: five focused MCP tools. analyze_receipt extracts caller-supplied receipt text or checks supported fields (0.25 USDC). match_invoice allocates invoice quantities against a purchase order, including split lines and remaining quantities (0.50 USDC). reconcile_purchase_documents is the free choice for discrepancies across supplied receipt, invoice and PO fields; missing documents remain needs_review and split links are flagged rather than allocated. Neither comparison requires the other. Consolidated example and status tools are free. Paid calls require buyer-authorized x402 on Base. Human review required; no image OCR, stored-analysis retrieval, delivery certification, payment approval or accounting writes. Service-specific cache and payment-metadata terms are disclosed through status. Runtime utilities: https://agents.getardaro.com/mcp/utilities . Legacy /mcp remains compatible. Guide: https://agents.getardaro.com/document-review

  • Reconcile business documents, inspect exact differences and evidence, and export reports.

  • Evidence-backed UBL, PDF, and image invoice checks before approval or payment.

  • Review invoice records, flag duplicates, validate totals, and prepare spreadsheet-safe CSV.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI-powered invoice analysis and reasoning: given invoice fields, it detects missing data, inconsistencies, duplicates, and proposes actions (register, request data, mark duplicate, review) using deterministic rules.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Self-serve MCPB demo for accounts payable invoice exception review. It performs deterministic matching across invoice, purchase order, goods receipt, vendor master, invoice history, tax code master, and payment rules.
    -
  • F
    license
    A
    quality
    C
    maintenance
    Exposes a ledger system (invoice queue, duplicate control, VAT register, contractor history, decision journal) as MCP tools for AI agents, enabling accurate invoice processing with deterministic validation.
    7
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables accounts payable teams to extract invoice data from PDFs and images, detect duplicates, normalize vendor names, calculate payment terms, and validate invoice completeness. Supports local extraction for text PDFs and optional vision providers for scanned documents.
    -