Offline-first edge payments MCP — record sales into a local append-only ledger and sync them to Square via an outbox when connectivity returns. Runs on a Raspberry Pi at the venue.
Six tools with complete schemas and descriptions. Naming is clear and verb-based (sale_record, receipt_verify, square_sync, sync_status, daily_tally, reconcile). Descriptions are well-written (100-200 chars) and explain WHAT, WHEN, and state-change implications. All parameters have types and descriptions. However, output schemas are not formally documented, responses are free-text strings rather than structured objects. Error handling is basic (internal_error wrapper). No pagination support despite potential for large result sets. No tool annotations (readOnlyHint, destructiveHint). Parameter validation rules are implicit in descriptions rather than explicit constraints (enums, min/max).
Sum sales by currency and by method over an optional [since_ms, until_ms] window. Returns totals in cents plus sale counts.
Verify a sale by its receipt id — returns the transaction if found (proof the sale happened), else not-found.
Reconcile the ledger: flag transactions stuck unsynced longer than the threshold, and synced rows missing a square_id (a bug indicator).
Record a sale OFFLINE into the local append-only ledger. Touches no network — safe with no connectivity. Returns the receipt id; the sale is queued for Square sync.
Push all queued (unsynced) sales to Square and mark them synced. If SQUARE_ACCESS_TOKEN is unset, runs in offline mode: reports the queue depth and syncs nothing (never errors).
Outbox status: total transactions, synced, queued (unsynced), and the last sync time (epoch millis).
Output schemas not documented. All tools return free-text strings (e.g., 'Recorded sale: ...'). LLMs cannot parse structured fields or chain results to downstream tools. Responses should return JSON objects with typed fields (receipt_id, amount_cents, currency, synced_count, queued_count, etc.).
No tool annotations. Tools like sale_record (WRITE), square_sync (WRITE), and reconcile (READ_ONLY) lack readOnlyHint/destructiveHint metadata. Agents cannot infer which tools are safe to retry or have side effects.
Parameter constraints are implicit. amount_cents must be positive, threshold_ms has a default (1h) but no min/max bounds. Use JSON Schema constraints (minimum, maximum, enum) instead of relying on description text.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 70 | <=2025-11-25 | v2 |
Error handling is minimal. Internal errors return a generic wrapper with no recovery guidance. E.g., if a sale_record fails due to DB corruption, the LLM gets no hint about retry strategy or fallback actions.
No pagination or result limits. daily_tally and reconcile could return unbounded result sets. If a venue has thousands of transactions, responses could exhaust context windows. Add limit/offset parameters and cap results at 50-100 items.