Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Final POS – Custom POS Builder

REMOTE · AI.FINALPOS.COM

Build custom POS apps with any AI agent: checkout flows, kiosks, payment terminals. Plus store ops.

Available components

+3 this week 86 Trust /100

Last scanned (14 hours ago)

Scores higher than 92% of remote servers

Reachable. Last reached 7 Nov 2026.

Category E-commerce

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security94
Transport & Reachability100
Schema Quality & AI Usability65
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 36159 tokens (~204/item across 177 items; 177 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management67
  • Stability observed for 20 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage92
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 77% of tool parameters carry a description.Partial
Tool Safety98
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 24 of 26 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "hub_get_refunds" implies "refund" and declares readOnlyHint instead, contradicting what its own name says it does. See how to fix → Partial
  • An AI judge read all 178 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
What we tested

Checks we ran (13)

  • TLS certificate
  • Authorization
  • HTTPS
  • HSTS header
  • DNSSEC
  • Transport
  • Schema quality
  • Stability
  • Tool coverage
  • Injection markers
  • Destructive annotations
  • Judged manipulation
  • MCP protocol

Does not apply to this hosted endpoint (2)

  • Supply Chain SecurityScored on package channels only. This is a hosted endpoint, so there is nothing to install or inspect.
  • Provenance & TransparencyScored on package channels only. This is a hosted endpoint, so there is nothing to install or inspect.

The score does not measure everything. What the score does not measure →

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 7 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 63 to 67. That category is still filling its 30-day observation window: 19 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.

  • 6 Nov 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 4 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.

  • 2 Nov 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.

  • 31 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.

  • 29 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

  • 27 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

  • 25 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 7 Nov 2026 · Probed https://ai.finalpos.com/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=ai.finalpos.com CN=WR3,O=Google Trust Services,C=US 29 Oct 2026 27 Jan 2027 RSA 2048 SHA256-RSA 7400e20ba493be190946bf1402d60490
SANs: ai.finalpos.com
CN=WR3,O=Google Trust Services,C=US (CA) CN=GTS Root R1,O=Google Trust Services LLC,C=US 13 Dec 2023 20 Feb 2029 RSA 2048 SHA256-RSA 7ff005a91568d63abc22861684aa4b5a
CN=GTS Root R1,O=Google Trust Services LLC,C=US (CA) CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE 19 Jun 2020 28 Jan 2028 RSA 4096 SHA256-RSA 77bd0d6cdb36f91aea210fc4f058d30d

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of ai.finalpos.com. — Not signed

Zone DS Keys Algorithms Outcome
. Trust anchor 20326, 38696 8, 8 Verified
com. DS published 19718 13 Verified
finalpos.com. No DS Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication Enforced and verified

The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.

Result Enforced and verified
Enforced On tool calls
HTTP status 200

WWW-Authenticate challenge Bearer error="invalid_token", error_description="Sign in with Final through OAuth, or create a connection key at https://ai.finalpos.com/connections.", resource_metadata="https://ai.finalpos.com/.well-known/oauth-protected-resource/mcp"

Bearer error="invalid_token", error_description="Sign in with Final through OAuth, or create a connection key at https://ai.finalpos.com/connections.", resource_metadata="https://ai.finalpos.com/.well-known/oauth-protected-resource/mcp"
Header Value
strict-transport-security max-age=63072000; includeSubDomains; preload
content-security-policy frame-ancestors 'self' https://app.finalpos.com
x-content-type-options nosniff
referrer-policy strict-origin-when-cross-origin

Protected resource metadata

Document https://ai.finalpos.com/.well-known/oauth-protected-resource/mcp
Retrieved Yes
Resource https://ai.finalpos.com/mcp
Authorisation server https://ai.finalpos.com

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://ai.finalpos.com/mcp Verified 200
http (plaintext) http://ai.finalpos.com/mcp HTTPS enforced 302 https://ai.finalpos.com/mcp
MCP tools · 177 exposed · ~35,433 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
hub_get_modifier ~105

One modifier in full: its choices with prices and defaults, and every category it is linked to with that category’s own rules. Read this before editing — update_modifier REPLACES the whole choice list, so you need the current one to send back. Each choice carries price (formatted, for reading out) and priceAmount (plain, what the write tools accept back). Pass priceAmount, never price.

NameTypeReqDescription
modifierIdstringyesModifier id from get_modifiers

No output schema declared.

No examples provided.

hub_get_modifiers ~149

Every modifier the merchant has — the questions the till can ask about an item, with their choices and prices. Start here for anything about options, add-ons, extras, toppings, sizes, milk, cooking temperature or "how do I let them choose X". Each row says how it is answered: "Pick one" (radio), "Pick many" (checkboxes), "Pick many · qty" or "stepper per choice" (the last two count UNITS, so one choice taken three times counts as 3). usedIn is how many categories it is linked to — a modifier with usedIn 0 is invisible at the till no matter how well it is set up.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_order ~212

Everything inside ONE order: line items with quantity, unit price and per-line tax, custom sales, gift-card and other non-revenue lines, the totals block, every payment taken (method, processor, card type and last 4, tip, change), every refund already made against it, plus the customer, outlet, station, employee and order notes. Answers 'what was in order 1042', 'how did they pay', 'was this one refunded', 'why is this total different'. Takes the order ID from get_orders — a receipt number will NOT work, search for it with get_orders first. READ-ONLY, and there is no sibling tool that writes: an order's status cannot be changed, an order cannot be cancelled or completed, and a refund cannot be created from this API — refunds are taken on the POS terminal against the original payment. Say that plainly instead of hunting for another tool.

NameTypeReqDescription
orderIdstringyesOrder id from get_orders — not a receipt number

No output schema declared.

No examples provided.

hub_get_order_count ~116

How many orders the company has, in total or at given outlets — 'how many orders do we have', 'how busy is the King Street shop'. Cheap: it counts, it loads no order data. It counts EVERY order ever recorded and takes no date, status or source filter. For anything time-boxed or filtered, call get_orders and read its `matching` count, or use get_financial_summary for a period.

NameTypeReqDescription
outletsarray–Outlet ids to restrict to. Omit to count every outlet

No output schema declared.

No examples provided.

hub_get_orders ~509

Find orders — the same rows as Manage → Orders. Answers 'show me order 1042', 'what did we sell on Saturday', 'are there parked orders', 'orders rung up by Maria', 'orders over $500 at the King Street shop'. Filter by receipt number, status, source, employee, customer, product, date window, order total, outlet or station. Results are ALWAYS newest first — there is no other sorting, so a "biggest order" question needs the amount filter, not paging. Search matches the receipt number and the order id ONLY, never customer names or product names: for those, pass customerIds from get_customers or productIds from get_products. One row per order with its total; for what is INSIDE an order — line items, payments, refunds, notes — call get_order with the id from here. For how much the business took over a period use get_financial_summary or get_sales_breakdown instead of adding these rows up.

NameTypeReqDescription
customerIdsarray–Customer ids from get_customers, not names
employeeIdsarray–Employee ids — from get_employee_sales, not names
endDatestring–Only orders created at or before this ISO 8601 moment
maxTotalnumber–Maximum order total in MINOR units (cents)
minTotalnumber–Minimum order total in MINOR units (cents), e.g. 50000 for $500
outletsarray–Outlet ids. Combined with stations by OR
pageinteger–Page number, default 1
pageSizeinteger–Orders per page, default 20
productIdsarray–Product ids from get_products — matches orders containing them
searchstring–Receipt number or order id. Does NOT match customer or product names
sourcearray–e.g. ["in-store"], ["woo-commerce"]
startDatestring–Only orders created at or after this ISO 8601 moment
stationsarray–Station ids. Combined with outlets by OR
statusarray–Final POS statuses: "completed", "refunded", "partial-refund", "parked". WooCommerce orders keep their own ("processing", "on-hold", "pending", "cancelled", "failed") — pass "other" to match every st…

No output schema declared.

No examples provided.

hub_get_outlets ~207

Every point of sale (store, location, branch) the merchant has — the same list as Settings → Outlets. Answers 'how many stores do I have', 'what is the address of the King Street shop', 'what is that location’s phone number'. ALSO THE WAY TO TURN A STORE NAME INTO AN ID: the reports, inventory and station tools filter by outlet ID and never by name, so when the merchant says 'sales for King Street' or 'stock at the warehouse', call this FIRST and pass the id you find here. Returns every outlet in one call — the list is short, there is no paging and no server-side search, so match the name yourself. Deleted outlets are not returned. Outlets carry NO opening hours, timezone or currency: store hours are not stored anywhere on this platform and currency is a company-wide setting, so say that plainly instead of guessing. Per-outlet tax percentages are not here either — those belong to the tax tools.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_payment_methods_breakdown ~195

How customers paid over a date range, netted of refunds — 'how much came in on card vs cash', 'what did processing fees cost me', 'how much hits my bank account'. Card and each custom processor also report their processing fees and the resulting deposit; cash has no fees. The same aggregation the Financial Summary settlement section uses, so the two always agree.

NameTypeReqDescription
endDatestringyesEnd of the window, ISO 8601. Inclusive of the day when a bare date is given
outletsarray–Outlet ids to restrict to. Omit for all outlets
startDatestringyesStart of the window, ISO 8601, e.g. "2026-08-01" or "2026-08-01T00:00:00Z"
stationsarray–Station ids to restrict to. Omit for all stations

No output schema declared.

No examples provided.

hub_get_permissions ~133

The catalogue of permissions a role can be given — every switch on the Roles screen, with the id create_role and update_role need. Call this to turn a request like 'let her see the reports' into the right permission id; match on the label and the permission path, and ask the merchant if two of them could both be meant. Permissions are granted exactly as named — there is no parent-grants-the-children cascade here — so pass every line the merchant actually needs. The list is the same for every merchant; it is not their current setup. For what a role currently grants, use get_roles.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_product_booking_setup ~70

Which resources serve this bookable product. Use it to check a product is actually ready to take bookings before quoting availability — an empty resource list means every hold will be refused, however correct the rule set looks.

NameTypeReqDescription
productIdstringyesProduct id from get_products — not a name

No output schema declared.

No examples provided.

hub_get_product_options ~70

List the variation axes the merchant already has — e.g. 'Size' with Small/Medium/Large. Call this BEFORE creating a product with variants and offer the existing axes instead of inventing new ones. Only call create_product_option when the merchant needs an axis that is not in this list.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_products ~225

List products in the merchant's catalogue. Answers 'what products do I have', 'find the Coca-Cola product', 'how much is X'. Pass categoryIds to answer 'what is in the Drinks category' — take the ids from get_categories, which does not return products itself. LIMITATION — there is no sorting: results come back in catalogue order and cannot be ordered by price, name or date. So 'the most expensive products' CANNOT be answered from this tool, and you must NOT page through the whole catalogue trying. Say plainly that sorting is not supported yet, then offer what does work: search by a name or SKU, filter by category, or ask the merchant to narrow it down.

NameTypeReqDescription
categoryIdsarray–Only products in these categories. Ids come from get_categories; a product matching any of them is returned
pageinteger–Page number, default 1
pageSizeinteger–Results per page, default 20
searchstring–Filter by product name or SKU (partial match)

No output schema declared.

No examples provided.

hub_get_purchase_order ~223

One purchase order in full: supplier, outlet, status, and every line — what was ORDERED and what has actually ARRIVED, per item, across each delivery. Answers 'what is on this order', 'what is still outstanding', 'did the price change from what we agreed'. Money appears twice on every writable field: the formatted one (CA$12.50) is for reading out to the merchant, the *Amount twin (12.50) is what update_purchase_order accepts back. The `ordered` block is the agreed order; each entry in `receipts` is one delivery booked against it, with its invoice number. Compare an item’s ordered quantity against the sum of its received quantities to see what is still owed — receiving more than ordered is allowed, so an overage is real, not an error. ALWAYS CALL THIS AFTER receive_purchase_order instead of retrying the receive: it is the way to confirm what was booked.

NameTypeReqDescription
purchaseOrderIdstringyesPurchase order id from get_purchase_orders — not a PO number

No output schema declared.

No examples provided.

hub_get_purchase_orders ~403

Stock the merchant has ordered from suppliers — the same list as Purchasing → Purchase Orders, and THE tool for any purchasing question over a period: 'what did I spend on stock last month', 'what is still on order', 'what have I ordered from this supplier', 'what is arriving this week'. Filter by status, supplier, outlet and a created-date range. READ totalCost CAREFULLY: it is what the order was placed FOR, not what was paid, and it sits on suggested and draft rows too — summing the whole list answers 'what have I proposed', not 'what did I spend'. For spend, filter status to ['sent','partially_received','fully_received']; for what a delivery actually cost, read the receipts block of get_purchase_order. Statuses, in order: suggested (auto-proposed by a reorder rule, not ordered), draft (being written), sent (with the supplier), partially_received (some arrived), fully_received (all in). "Open" means anything not fully_received. Cancelled orders are gone from this list entirely. The date range filters on when the order was CREATED, not when it was sent or received. Costs here are what the merchant pays suppliers — for sales and revenue use the report tools instead.

NameTypeReqDescription
endDatestring–ISO date — orders created up to and including this day
outletIdsarray–Outlet ids from get_outlets
pageinteger–1-based page, default 1
pageSizeinteger–Rows per page, default 20
searchstring–Match the PO number
sortBystring–Default createdAt
sortOrderstring–Default desc
startDatestring–ISO date — orders created on or after this day
statusarray–Keep only these statuses
supplierIdsarray–Supplier ids from get_suppliers

No output schema declared.

No examples provided.

hub_get_receive_progress ~156

How far a delivery has got in being applied to stock. A large delivery is applied item by item in the background, so its order keeps its old status until the work finishes — this is the only place that shows the real progress. Call it with the receiptId that receive_purchase_order returned, or the one get_purchase_order reports as still being received. Read `failures` seriously: those items did NOT get their stock and say why (the item was deleted, the outlet no longer exists, the supplier link was removed). Everything else on the delivery still landed, so the fix is per item, not a re-receive of the whole thing.

NameTypeReqDescription
receiptIdstringyesReceipt id from receive_purchase_order

No output schema declared.

No examples provided.

hub_get_refunds ~199

Refunds recorded against orders, newest first: what was refunded, why, by whom, on which order and for which customer. Answers 'what did we refund lately', 'show the refunds on order 1042', 'who processed that refund'. Filter by order id, or search by the REFUND's own receipt number. LIMITATIONS: no date filter and no total count — for refunds in a date range use get_sales_breakdown (one row per refund) or get_financial_summary (refund totals). Refunds CANNOT be created here: they are taken on the POS terminal against the original payment. This tool only reads.

NameTypeReqDescription
orderIdstring–Only refunds against this order — id from get_orders
pageinteger–Page number, default 1
pageSizeinteger–Refunds per page, default 20
searchstring–Search by the refund's receipt number

No output schema declared.

No examples provided.

hub_get_reorder_suggestions ~168

What the platform thinks should be reordered: rescans stock against the merchant's auto-reorder rules and returns the suggested orders it left behind, grouped by supplier and outlet. Answers 'what am I running low on', 'what should I order this week'. A suggestion is NOT an order — nothing has been sent and no supplier knows about it. Turn one into a real order with update_purchase_order (which accepts it as a draft) and then send_purchase_order. Only items with an auto-reorder rule can appear here, so an empty result usually means no rules are set rather than nothing being low — say that, and offer set_reorder_rule. The rescan is skipped and the stored suggestions returned when one ran moments ago; `rescanned: false` says so.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_roles ~109

The roles this merchant has defined and exactly what each one is allowed to do — Settings → Roles. Answers 'what can a cashier do', 'which roles exist', 'who is on the Manager role'. A role is the ONLY place permissions live: people do not carry their own. Read this before changing anything, and take permission ids from the granted list when revoking. Owners and organisation-level accounts hold no role and are never restricted by one — a role change cannot take anything away from them.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_sales_breakdown ~290

Order-by-order breakdown for a date range — the same rows as Reports → Sales Breakdown. One row per order AND per refund. Answers 'show me the orders from Saturday', 'which order had that big discount', 'how many refunds last month', 'sales per day'. The `totals` and `dailyTrend` in the reply cover the WHOLE date range, not just the returned page — quote them directly instead of adding up rows. For headline figures alone use get_financial_summary; this tool is for when the merchant wants to see the actual orders.

NameTypeReqDescription
endDatestringyesEnd of the window, ISO 8601. Inclusive of the day when a bare date is given
outletsarray–Outlet ids to restrict to. Omit for all outlets
pageinteger–Page number, default 1
pageSizeinteger–Rows per page, default 50
startDatestringyesStart of the window, ISO 8601, e.g. "2026-08-01" or "2026-08-01T00:00:00Z"
stationsarray–Station ids to restrict to. Omit for all stations
timezonestring–IANA timezone for the daily grouping, e.g. "America/Toronto". Defaults to the server timezone

No output schema declared.

No examples provided.

hub_get_session_report ~114

The full End of Session report for ONE shift: sales, taxes, settlement, refunds, staff sales, tips and the cash drawer. Answers 'does the drawer balance', 'was the till short last night', 'what did that shift take'. Takes the session id from get_sessions, never a station or a person. The cash drawer section is what tells you over / short — report it plainly, and do not compute it yourself from the other sections.

NameTypeReqDescription
sessionIdstringyesSession id from get_sessions

No output schema declared.

No examples provided.

hub_get_sessions ~206

Register sessions (shifts) opened and closed in a date range — the list behind Reports → End of Session. Answers 'what shifts ran yesterday', 'who closed the register last night', 'is a session still open'. Returns who opened and closed each one, the opening float and the declared closing amounts. A session with no closeTime is still open. For the full money report of one shift, pass its id to get_session_report.

NameTypeReqDescription
endDatestringyesEnd of the window, ISO 8601. Inclusive of the day when a bare date is given
outletsarray–Outlet ids to restrict to. Omit for all outlets
startDatestringyesStart of the window, ISO 8601, e.g. "2026-08-01" or "2026-08-01T00:00:00Z"
stationsarray–Station ids to restrict to. Omit for all stations

No output schema declared.

No examples provided.

hub_get_station ~314

Everything about ONE station, including what its device last reported about itself — app version, OS, network, printer, battery and whatever else that device sends. THIS IS THE TOOL FOR 'the till will not connect', 'it will not print', 'the card reader is not working', 'this register is acting up'. Takes the station id from get_stations, never a name. How to read it when troubleshooting: `kind` tells you whether it is a physical device or a browser till (a browser till has no device to blame — check the share link and the flow instead); an empty `deviceId` on a native station means no device ever enrolled under it; `enrolledBy` and `createdAt` say who set it up and when; an empty `deviceEnvironment` means the device has never reported anything, which is itself the finding. The values carry NO timestamp — they are the last ones received, and there is no way to tell how old they are. `recordUpdatedAt` is the last time the station RECORD changed (mostly a shift opening or closing, or a rename) — it is NOT a heartbeat: the platform stores no online/offline ping for a till, so never report a station as "online" or "last seen". Card readers shown here are read-only: pairing and unpairing a reader happens on the Terminals screen of the cabinet, not through any tool.

NameTypeReqDescription
stationIdstringyesStation id from get_stations — not a name

No output schema declared.

No examples provided.

hub_get_stations ~420

Every POS station (till, register, checkout lane, cash desk) the merchant has — the same list as Run → Stations. Answers 'how many tills do I have', 'which register is busy right now', 'which store is this till at', 'which of them are browser tills'. Each station belongs to exactly ONE outlet and the outlet name is resolved here, so you do not need get_outlets to answer where a till stands — call get_outlets only to turn a store NAME the merchant said into the outletId filter of this tool. WHAT status MEANS, EXACTLY: the server does not compute it. The POS app on the till writes it — IN_USE when a cashier opens a register shift on that station, AVAILABLE when the shift is closed. It is best-effort: the update is lost while the device is offline and only flushed when it reconnects, and older app versions never sent it at all, so a station can sit at AVAILABLE with a shift open on it or at IN_USE hours after one was closed. Read it as "what this till last told us", never as proof. NEVER answer a shift or money question from it: for shifts that are actually open, who opened them and what they took, use get_sessions (a session with no closeTime is open) and get_session_report. If those disagree with this flag, they are right and the flag is stale. The whole list comes back in one call — it is short and plan-capped, there is no paging; search matches the station NAME only. Deleted stations are not returned.

NameTypeReqDescription
kindstring–native = a physical device running the POS app; virtual = a browser till
outletIdstring–Only stations at this outlet — id from get_outlets, not a store name
searchstring–Filter by station name, e.g. "POS 2"
statusstring–IN_USE = the till last reported an open register shift; AVAILABLE = it did not

No output schema declared.

No examples provided.

hub_get_stock ~244

How many of ONE product are on hand, broken down by variant and by outlet. Answers 'how many of these do I have', 'how many are left at the King Street shop', 'where is this product in stock'. Takes the product id from get_products — get_products itself returns prices, never quantities. Pass outletId (from get_outlets) to narrow it to a single shop. CRITICAL — "tracked: false" means the merchant switched stock counting OFF for that variant at that outlet, so there is NO count at all. It is NOT "0 in stock". Never say "you have 0" or "it is out of stock" about an untracked line; say stock is not being tracked there. Only lines with tracked: true carry a real quantity. Outlets where the product is hidden do not appear at all. For 'what is running out' across the whole catalogue use find_low_stock instead — do not page through products with this tool.

NameTypeReqDescription
outletIdstring–Outlet id from get_outlets. Omit for every outlet
productIdstringyesProduct id from get_products — not a name

No output schema declared.

No examples provided.

hub_get_stock_history ~242

Every recorded stock movement for ONE product, newest first — the audit trail behind a count. Answers 'why is the number wrong', 'who changed this', 'when did we last receive these'. Each entry says what happened (SALE, STOCK_RECEIVED, DAMAGE, THEFT, LOSS, RESTOCK_RETURN, INVENTORY_RECOUNT, TRANSFER, BULK_RECOUNT), the signed quantity, the resulting on-hand, the outlet and the employee. Use this when the merchant disputes a number: state what the log shows rather than guessing at a cause. Only changes that were actually applied appear — an adjustment on an untracked line writes no history at all, which is itself the explanation when the log looks empty.

NameTypeReqDescription
actionsarray–Limit to these action names, e.g. ["DAMAGE","THEFT"]
endDatestring–ISO date. Pass together with startDate or neither
outletIdsarray–Limit to these outlets (ids from get_outlets)
productIdstringyesProduct id from get_products
startDatestring–ISO date. Pass together with endDate or neither

No output schema declared.

No examples provided.

hub_get_stock_transfer ~164

ONE transfer in full: both outlets, the employee, the invoice, the notes and the line items with quantities. Takes the transactionId AND the type exactly as get_stock_transfers returned them — the type decides which leg is read, and a wrong one fails. For send-transfer and receive-transfer this also returns the sibling leg, so you can name where the stock came from and where it is going, plus stockTransferId, which is what receive_stock_transfer needs. Line quantities are the amounts MOVED, recorded when the transfer was created — they are not current stock. Use get_stock for that.

NameTypeReqDescription
transactionIdstringyestransactionId from get_stock_transfers
typestringyesThe same type get_stock_transfers reported for that row

No output schema declared.

No examples provided.

hub_get_stock_transfers ~235

The Stock Transfers list. Answers 'what transfers are open', 'what is still in transit', 'did the warehouse send those yet'. Each row is ONE LEG: a move between outlets produces a send-transfer (already completed — the stock has left the source) and a receive-transfer (in-transit until the destination confirms). receive-stock is stock booked in from a supplier; bulk-edit is a recount. To find work that is still open, filter status "in-transit". Search matches the transfer number and the invoice only — not product names. Rows carry no line items: open one with get_stock_transfer to see what was actually moved.

NameTypeReqDescription
outletIdsarray–Only legs at these outlets (ids from get_outlets)
pageinteger–Page number, default 1
pageSizeinteger–Rows per page, default 20
searchstring–Matches the transfer number or the invoice number
statusstring–"in-transit" = waiting to be received
typestring–Only this leg type. Omit for all

No output schema declared.

No examples provided.

hub_get_supplier ~85

One supplier in full: contact details, address, notes, how many catalogue items it is linked to and how many of its purchase orders are still open. Does NOT list the items themselves or the orders — those are get_supplier_items and get_purchase_orders (filter it by this supplier id).

NameTypeReqDescription
supplierIdstringyesSupplier id from get_suppliers — not a name

No output schema declared.

No examples provided.

hub_get_supplier_items ~273

The catalogue items one supplier carries, with the cost the merchant pays and the supplier’s own part number. Answers 'what do I buy from this supplier', 'what does this supplier charge me for X'. CALL THIS BEFORE create_purchase_order: an order may only contain items the supplier is linked to, and the variantId + unitCost you need for each line come from here. PASS outletId when you are about to build an order: that narrows the list to items whose stock is actually tracked at that outlet — the only ones a receive can add stock to — and adds onHand, the quantity there right now, so you can see what genuinely needs reordering. Search and paging work the same either way. An item the merchant expects but does not see here is simply not linked yet — get_linkable_items then link_supplier_items.

NameTypeReqDescription
outletIdstring–Outlet id from get_outlets — narrows to stock-managed items there and adds onHand
pageinteger–1-based page, default 1
pageSizeinteger–Rows per page, default 20
searchstring–Match product name, item name, SKU, barcode or part number
supplierIdstringyesSupplier id from get_suppliers — not a name

No output schema declared.

No examples provided.

hub_get_suppliers ~175

The businesses this merchant BUYS stock from — the same list as Purchasing → Suppliers. Answers 'who do I order from', 'what is my supplier’s email', 'which suppliers have open orders'. ALSO THE WAY TO TURN A SUPPLIER NAME INTO AN ID: every purchase-order and item-linking tool takes a supplier id and never a name. Each row carries openPoCount — purchase orders not yet fully received — and itemCount, how many catalogue items that supplier is linked to. This is the buying side. For what the merchant SELLS and at what price, use get_products.

NameTypeReqDescription
pageinteger–1-based page, default 1
pageSizeinteger–Rows per page, default 20
searchstring–Match supplier name, contact name or email

No output schema declared.

No examples provided.

hub_get_suppliers_for_product ~106

The other direction: given a product from get_products, which suppliers carry its items and at what cost. Answers 'who can I reorder this from', 'who is cheapest for this', 'am I buying this from more than one place'. Nothing comes back when the product is linked to no supplier — that is a real answer, not an error: it cannot be purchase-ordered until it is linked.

NameTypeReqDescription
productIdstringyesProduct id from get_products

No output schema declared.

No examples provided.

hub_get_taxes ~139

The whole Settings → Taxes screen: every tax group, the rates inside it in charging order, and each rate’s percentage at each outlet. Answers 'what sales tax do I charge', 'what tax applies in the King Street store', 'which tax group is the standard one', 'do I charge GST and PST separately'. ALWAYS call this before any other tax tool — every other tool takes ids from here (tax group ids, tax rate ids, outlet ids) and none of them accept names. It also reports which rates are shared across groups and which belong to no group, both of which change what an edit will do. Read-only.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_team ~125

Everyone who works for this merchant — Manage → Team → Users. Answers 'who works here', 'what role does Maria have', 'who can see reports', 'what is Tom's phone number'. This is about who works here and what they are allowed to do — for how much anyone SOLD, use get_employee_sales instead. Returns the whole team at once: there is no search and no paging, so filter the rows yourself instead of asking the merchant to narrow down. Removed people are not listed at all. Every other tool in this domain takes its userId from here.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

hub_get_transactions ~304

Individual payments and refunds — Reports → Transactions. This is the PAYMENT level, not the order level: one order can hold several transactions. Answers 'find the payment for receipt 1042', 'show every Amex refund last week', 'which transactions failed'. Filter by payment method, processor, card provider or status, or search by order number. For sales figures use get_financial_summary — this tool is for locating a specific payment.

NameTypeReqDescription
cardProvidersarray–e.g. ["Visa", "Mastercard", "Amex"]
endDatestringyesEnd of the window, ISO 8601. Inclusive of the day when a bare date is given
outletsarray–Outlet ids to restrict to. Omit for all outlets
pageinteger–Page number, default 1
pageSizeinteger–Rows per page, default 50
paymentMethodsarray–e.g. ["card", "cash"]
processorsarray–Processor ids
searchstring–Search by order / receipt number
startDatestringyesStart of the window, ISO 8601, e.g. "2026-08-01" or "2026-08-01T00:00:00Z"
stationsarray–Station ids to restrict to. Omit for all stations
statusstring–Transaction status to filter by

No output schema declared.

No examples provided.

hub_hold_booking ~217

Claim a window on one resource. The hold is what makes the window unavailable to everybody else, and it expires by itself if nobody pays — so holding is safe, and a hold nobody confirms costs nothing. `startAt` must be exactly a slot start from get_booking_availability, and `endAt` exactly where the last slot ends; anything else is refused rather than rounded. A refusal with 409 means somebody took it first: re-read availability and offer what is left, do not retry the same window.

NameTypeReqDescription
customerIdstring–Who it is for, id from get_customers. Omit for a walk-in nobody identified
endAtstringyesISO instant, exactly where the booked window ends
outletIdstring–The shop the sale happens at
productIdstringyesProduct id
resourceIdstringyesWhich resource — the barber, room or asset being booked
startAtstringyesISO instant, exactly a slot start from availability

No output schema declared.

No examples provided.

hub_import_categories ~396

Load a category tree in one call — a whole department structure, a migration. For one or two categories use create_category. Parents and children may sit in the SAME batch: `parentRef` takes a parent NAME (matched inside this batch first, then against existing categories) or an existing id, which is what makes a flat spreadsheet importable. Loops and unresolvable parents fail those rows and their descendants, not the batch. This tool does NOT match rows against what already exists — the cabinet does that in the browser, not on the server. Every row in `creates` becomes a NEW record even if an identical one is already there. To change existing records, read them with export_records and pass their ids in `updates`. Two rows named the same thing in one batch, or a name that already exists, will produce two categories with that name. On `updates` this is the only import with true merge-patch semantics: omit a field to leave it, pass null to CLEAR it, and pass `parentId: null` to move a category back to the top level (which create_category and update_category cannot do). Products are untouched — importing categories neither assigns nor removes products; that is the products side. Rows are independent and per-row failures come back in the reply. Max 500 rows per call. BEFORE CALLING: show the merchant a preview of the first few rows, state the EXACT number of rows and which resource they hit, and get an explicit yes. There is NO undo and no dry-run — nothing here validates without writing. If you are unsure a row is right, ask; a wrong bulk import is far more expensive to repair than a question. Afterwards, tell the merchant what landed: an import done here does NOT appear in the cabinet's Recent Imports list, which only records uploads made through the wizard.

NameTypeReqDescription
createsarray––
updatesarray––

No output schema declared.

No examples provided.

hub_import_customers ~325

Load a customer list in one call — a mailing list, a migration from another system. For one person use create_customer. This is the ONE import that recognises records it already has: pass `rows` and the server looks each one up BY EMAIL, updating that customer instead of duplicating them. A row with no email is always created new and can never be matched again, so push for emails before importing. Fields you pass overwrite the stored ones; fields you omit are left alone — but an address you pass replaces the stored address whole, and `tags` replaces the whole tag list. ALL-OR-NOTHING: unlike the other imports this one runs in a single transaction, so one bad row rolls the entire batch back and nothing is written. There is no per-row failure list. Max 500 rows per call. BEFORE CALLING: show the merchant a preview of the first few rows, state the EXACT number of rows and which resource they hit, and get an explicit yes. There is NO undo and no dry-run — nothing here validates without writing. If you are unsure a row is right, ask; a wrong bulk import is far more expensive to repair than a question. Afterwards, tell the merchant what landed: an import done here does NOT appear in the cabinet's Recent Imports list, which only records uploads made through the wizard.

NameTypeReqDescription
rowsarray–Spreadsheet rows — matched by email, then created or updated by the server
updatesarray–Use only when you already hold the id and do not want email matching

No output schema declared.

No examples provided.

hub_import_options ~303

Load product attributes and their values in one call — "Size: S,M,L", "Colour: Red,Blue,Green" — the axes variants are built from. For one axis use create_option. Attribute names are unique per company: a `creates` row whose name already exists is REJECTED (that row only), so read get_options first and send existing ones through `updates`. On `updates`, values are APPEND-ONLY: the list you pass is merged into what is there and existing values are never renamed or removed, because variants reference them by name and would be orphaned. Renaming the attribute itself does cascade to its variants. To remove a value, use the cabinet. This creates no products and no variants — it only defines the axes. Rows are independent and per-row failures come back in the reply. Max 500 rows per call. BEFORE CALLING: show the merchant a preview of the first few rows, state the EXACT number of rows and which resource they hit, and get an explicit yes. There is NO undo and no dry-run — nothing here validates without writing. If you are unsure a row is right, ask; a wrong bulk import is far more expensive to repair than a question. Afterwards, tell the merchant what landed: an import done here does NOT appear in the cabinet's Recent Imports list, which only records uploads made through the wizard.

NameTypeReqDescription
createsarray––
updatesarray––

No output schema declared.

No examples provided.

hub_import_outlets ~398

Load a list of store locations in one call — opening a chain, migrating from another system. For one shop use create_outlet. Name, street address, city, state and postal code are ALL required on new rows, exactly as in the cabinet form; ask the merchant rather than inventing an address. Country is not settable: every outlet takes the company country, and the import fails outright if the company has none. This tool does NOT match rows against what already exists — the cabinet does that in the browser, not on the server. Every row in `creates` becomes a NEW record even if an identical one is already there. To change existing records, read them with export_records and pass their ids in `updates`. Bulk-created outlets differ from ones added in the cabinet in two ways worth telling the merchant: no Stripe location is wired up (payments must be linked per outlet afterwards) and stock rows are seeded in the background, so a fresh outlet can look empty for a while. This path also does NOT check the plan allowance, so it can push the company past the number of outlets it pays for — say so before importing more than a couple. Updates only set what you pass; alias and country cannot be changed here. Rows are independent and per-row failures come back in the reply. Max 500 rows per call. BEFORE CALLING: show the merchant a preview of the first few rows, state the EXACT number of rows and which resource they hit, and get an explicit yes. There is NO undo and no dry-run — nothing here validates without writing. If you are unsure a row is right, ask; a wrong bulk import is far more expensive to repair than a question. Afterwards, tell the merchant what landed: an import done here does NOT appear in the cabinet's Recent Imports list, which only records uploads made through the wizard.

NameTypeReqDescription
createsarray––
updatesarray––

No output schema declared.

No examples provided.

hub_import_products ~425

Load a spreadsheet of products in one call — "here are my 200 items", a catalogue from another POS, a price list. For one or two products use create_product instead: it can build variants from options, this cannot (every created row is a SIMPLE product with a single variant). This tool does NOT match rows against what already exists — the cabinet does that in the browser, not on the server. Every row in `creates` becomes a NEW record even if an identical one is already there. To change existing records, read them with export_records and pass their ids in `updates`. An update row is found by productId OR by sku (the SKU of its variant — what a spreadsheet has); a SKU that matches no product or several fails that row. price, costPrice, barcode and sku in an update go to the product's single variant; a product with several variants fails that row — use update_product for it. An update cannot clear categories; omit the field to leave them as they are. Prices are written as the merchant says them ("19.99"), in the company currency. Category entries may be names or ids: an unknown NAME is created as a new top-level category, so check the spelling against get_categories first or the import will litter the catalogue. Rows are independent — the reply lists per-row failures alongside what landed, so a bad row does not stop the rest. Max 500 rows per call. BEFORE CALLING: show the merchant a preview of the first few rows, state the EXACT number of rows and which resource they hit, and get an explicit yes. There is NO undo and no dry-run — nothing here validates without writing. If you are unsure a row is right, ask; a wrong bulk import is far more expensive to repair than a question. Afterwards, tell the merchant what landed: an import done here does NOT appear in the cabinet's Recent Imports list, which only records uploads made through the wizard.

NameTypeReqDescription
createsarray–New products, one per spreadsheet row
updatesarray––

No output schema declared.

No examples provided.

hub_import_stock_csv ~231

Write stock counts for ONE outlet from the CSV that export_stock_csv returns — the cabinet's stock upload. Edit only the New Qty column; each row SETS that variant's quantity at the outlet (it is not a +/- adjustment). Keep the header and the Variation ID column as exported. Rows whose Variation ID is not in this company are skipped. For one or two variants use adjust_stock instead. BEFORE CALLING: show the merchant a preview of the first few rows, state the EXACT number of rows and which resource they hit, and get an explicit yes. There is NO undo and no dry-run — nothing here validates without writing. If you are unsure a row is right, ask; a wrong bulk import is far more expensive to repair than a question. Afterwards, tell the merchant what landed: an import done here does NOT appear in the cabinet's Recent Imports list, which only records uploads made through the wizard.

NameTypeReqDescription
csvstringyesThe CSV text, header row included
outletIdstringyesOutlet id from get_outlets — the one the CSV was exported for

No output schema declared.

No examples provided.

hub_install_extension ~235

Install an extension for the whole company. Takes the `extensionId` from get_extension_catalog, never a name. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the extension: this is not a personal setting — it changes the cabinet for EVERY user of the company, and several extensions do real work on install (WooCommerce connects the store and starts syncing, TIMEmSYSTEM writes default settings, Custom Payment schedules Stripe billing). MONEY: an extension with a non-zero `price` starts costing the merchant from the moment it is installed — quote the stored price string and let them decide. Installing is not enough to finish a setup: most extensions then need their own settings page in the cabinet (a WooCommerce store URL, a payment gateway key), which this agent cannot fill in — say that plainly after installing. Refused when the plan excludes the extension, when the caller lacks the Extensions permission, or when it is already installed (installing twice is not a no-op — it would run the side effects again).

NameTypeReqDescription
extensionIdstringyesextensionId from get_extension_catalog — not a name, not a guid

No output schema declared.

No examples provided.

hub_link_modifier_to_category ~262

Start asking a modifier on every product in a category — THIS is what puts it on the till. The rules are per category, so the same modifier can be required here and optional elsewhere. required means the cashier cannot finish the line until they answer. min/max count distinct choices, or UNITS when the modifier uses quantities. Refused when the category already inherits this modifier from a parent category (link it to the parent or the child, not both), when it is already linked, and when the rules could not be satisfied — for example asking for at least 3 when only 2 choices are sold at every outlet. Linking a modifier to a PARENT category detaches it from any subcategories that already had it, since they now inherit it.

NameTypeReqDescription
categoryIdstringyesCategory id from get_categories
maxinteger–Most that may be chosen. Omit for no cap
mininteger–Fewest that must be chosen. Setting this makes it required
modifierIdstringyesModifier id from get_modifiers
requiredboolean–The cashier must answer before ringing up. Default false
sortOrderinteger–Position among this category’s modifiers. Omit to append

No output schema declared.

No examples provided.

hub_link_supplier_items ~322

Change what a supplier carries and what it charges, in one call: `add` new items, `update` the cost or part number of items already linked, `remove` items it no longer sells. variantId comes from get_linkable_items for `add` and from get_supplier_items for `update` / `remove`. unitCost is what the merchant PAYS per unit, as a human amount like "12.50" in the company currency — never the selling price, and never cents. It is only the DEFAULT that prefills new order lines: changing it does not re-price purchase orders already placed. Adding an item that is already linked is refused, so read the current list first rather than re-adding blindly. REMOVING is the destructive half — confirm it with the merchant, and tell them it also EDITS ORDERS THAT ARE ALREADY WRITTEN: the item’s line is dropped from every suggested and draft order from this supplier, which changes their totals. Orders already sent keep their lines, the item stays in the catalogue, but it can no longer be added to a new order from this supplier, and any auto-reorder rule pointing at this supplier for it stops producing suggestions.

NameTypeReqDescription
addarray–Items to start buying from this supplier
removearray–Item ids from get_supplier_items to stop buying from this supplier
supplierIdstringyesSupplier id from get_suppliers — not a name
updatearray–Already-linked items to re-price or re-code

No output schema declared.

No examples provided.

hub_receive_purchase_order ~494

Book a delivery in against an order that was sent: ADDS THE RECEIVED QUANTITIES TO REAL STOCK at the order’s outlet and updates the item cost book. This is not a note — it changes inventory. CONFIRM THE QUANTITIES WITH THE MERCHANT FIRST, item by item, and record what genuinely ARRIVED, not what was ordered — they differ, which is the whole point of receiving. Only `sent` and `partially_received` orders can be received; each item must be one that was ordered; receiving more than ordered is allowed. A short delivery leaves the order `partially_received` — receive again when the rest turns up. A CALL THAT RETURNS IS NOT PROOF EVERY ITEM LANDED — check `partialFailure`, and `stockApplied.complete` on a large delivery. IF IT FAILS, DO NOT RETRY BLINDLY: "still being received" means a previous delivery is being applied right now (get_receive_progress), and a wrong-status error means it was already fully received. Call get_purchase_order to see what actually landed before deciding anything. unitCost is what this delivery actually cost per unit — pass the invoice price if it differs from the order. When it does differ, the supplier’s stored cost is NOT updated unless you list that item in updateSupplierCostVariantIds, so ask the merchant whether the new price is the going rate or a one-off.

NameTypeReqDescription
customFeesarray–Any other named charge on the order, e.g. "Handling"
discountstring–Flat discount on the whole order, e.g. "25.00". Not with discountPercent
discountPercentnumber–Discount as a percentage of the items subtotal
dutyFeesstring–Duty / customs charged on the order
invoiceDatestring–ISO date on the invoice
invoiceNumberstring–Supplier invoice number for this delivery
linesarrayyesWhat actually arrived
purchaseOrderIdstringyesPurchase order id from get_purchase_orders — not a PO number
receivedAtstring–ISO date the goods arrived — defaults to now
shippingFeestring–Shipping charged on the order, e.g. "18.00"
updateSupplierCostVariantIdsarray–Items whose new unitCost should become the supplier’s stored cost from now on

No output schema declared.

No examples provided.

hub_receive_stock_transfer ~129

Confirm that a transfer arrived: the destination outlet gains the units and the transfer closes. CONFIRM WITH THE MERCHANT FIRST — this adds stock and cannot be undone from here. Only do it when they say the goods are physically there; confirming a transfer that never arrived hides a loss instead of recording one. Takes stockTransferId (from get_stock_transfer), NOT the transactionId. Only applies to a receive-transfer leg still in-transit; a transfer already completed has nothing left to receive.

NameTypeReqDescription
stockTransferIdstringyesstockTransferId from get_stock_transfer — not the transactionId

No output schema declared.

No examples provided.

hub_record_received_goods ~364

Stock that arrived with no purchase order behind it — the merchant bought it on the spot, or it was ordered outside the platform. Creates the order already fully received and ADDS THE QUANTITIES TO REAL STOCK at the outlet, in one step. Use this ONLY when no order exists. If the goods match an order that was sent, use receive_purchase_order instead — otherwise the same delivery is counted twice, once here and once when someone receives the real order. Check get_purchase_orders for an open order from this supplier before calling. The items must already be linked to the supplier (get_supplier_items) and stock-managed at the outlet. There is no undo: correcting a mistake means a stock adjustment afterwards.

NameTypeReqDescription
customFeesarray–Any other named charge on the order, e.g. "Handling"
discountstring–Flat discount on the whole order, e.g. "25.00". Not with discountPercent
discountPercentnumber–Discount as a percentage of the items subtotal
dutyFeesstring–Duty / customs charged on the order
invoiceDatestring–ISO date on the invoice
invoiceNumberstring––
linesarrayyesWhat arrived
notesstring––
outletIdstringyesOutlet id from get_outlets — where the goods physically arrived
receivedAtstring–ISO date the goods arrived — defaults to now
shippingFeestring–Shipping charged on the order, e.g. "18.00"
supplierIdstringyesSupplier id from get_suppliers
updateSupplierCostVariantIdsarray–Items whose unitCost should become the supplier’s stored cost from now on

No output schema declared.

No examples provided.

hub_remove_reorder_rule ~80

Stop watching one item: it will no longer be suggested for reordering however low it runs. Its thresholds are forgotten, so turning it back on means setting them again. Suggestions already produced for this item are not withdrawn — cancel those orders separately if the merchant wants them gone.

NameTypeReqDescription
variantIdstringyesItem id from get_supplier_items

No output schema declared.

No examples provided.

hub_remove_tax_rate_from_group ~140

Stop ONE tax group charging a rate. The rate itself, its percentages and its use by other groups are untouched — this only drops the link. This is what the merchant means by "remove the city tax from Food". Use delete_tax_rate ONLY when they want the rate gone from the whole company. CONFIRM WITH THE MERCHANT: every product in this group immediately stops being charged this tax. Sales already rung up are NOT recalculated — this only affects sales from now on.

NameTypeReqDescription
taxGroupIdstringyesTax group id from get_taxes
taxRateIdstringyesTax rate id from get_taxes

No output schema declared.

No examples provided.

hub_remove_user ~144

Remove someone from the merchant's team — the tool for 'she left', 'take the leaver off'. Takes the userId from get_team ONLY, never a name. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the person: there is no undo from here. If two people share a name, list them and ask which. They stop being able to sign in immediately; their past orders and sales figures are kept, so reports about them still work. You cannot remove the account this agent key belongs to — the server refuses, so that an administrator cannot lock themselves out.

NameTypeReqDescription
userIdstringyesUser id from get_team — not a name

No output schema declared.

No examples provided.

hub_rename_station ~146

Rename one station. Takes the station id from get_stations. Renaming is safe and takes effect everywhere — past orders, sessions and reports store the id and look the name up. The name is the ONLY thing the cabinet lets anyone change on an existing station, and the only thing this tool changes. A station cannot be moved to another outlet, and its device, card reader and POS layout are not editable from here — moving a till to another store means creating a new station there and deleting this one, which loses its id.

NameTypeReqDescription
namestringyesThe new station name
stationIdstringyesStation id from get_stations — not a name

No output schema declared.

No examples provided.

Install

How do I install the Final POS – Custom POS Builder MCP server?

Final POS – Custom POS Builder is a hosted endpoint at https://ai.finalpos.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · ai.finalpos.com

# add to Claude Code
claude mcp add --transport http com-finalpos-final 'https://ai.finalpos.com/mcp'
Common questions

What is the Final POS – Custom POS Builder MCP server?

Final POS – Custom POS Builder is an MCP server listed in the public MCP registry as com.finalpos/final. Build custom POS apps with any AI agent: checkout flows, kiosks, payment terminals. Plus store ops. This page covers its hosted endpoint (https://ai.finalpos.com/mcp).

Is the Final POS – Custom POS Builder MCP server safe to use?

Final POS – Custom POS Builder scores 86 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Final POS – Custom POS Builder MCP server expose?

Final POS – Custom POS Builder exposes 177 tools: get_connection, list_packs, find_tools, call_tool, call_write_tool, and 172 more. Their descriptions and schemas cost roughly 35,433 tokens of context every time the server is loaded.

Does the Final POS – Custom POS Builder MCP server require authentication?

Yes. Final POS – Custom POS Builder asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

Is the Final POS – Custom POS Builder MCP server still maintained?

Final POS – Custom POS Builder is still listed as active in the MCP registry. We last reached this channel on 7 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What did VerifyMCP test on the Final POS – Custom POS Builder MCP server?

VerifyMCP ran 13 checks on Final POS – Custom POS Builder, covering TLS certificate, Authorization, HTTPS, HSTS header and 9 more. Supply Chain Security and Provenance & Transparency do not apply to a hosted endpoint, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.