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
Last scanned (14 hours ago)
Scores higher than 92% of remote servers
Reachable. Last reached 7 Nov 2026.
Category E-commerce
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
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token. View diagnostics → Pass
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
- The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents. View diagnostics → Partial
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
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
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 →
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.
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 |
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 →
hub_cancel_purchase_order Cancel purchase order ~130
Cancel an order the merchant no longer wants. CONFIRM FIRST, naming the supplier and the PO number — there is no undo, and the order disappears from the list rather than showing as cancelled. REFUSED once any stock has been received against it: that stock is real and the record has to stay. Receive the rest instead, or leave it partially received. Cancelling does NOT tell the supplier anything. If the order was already sent, the merchant still has to contact them — say so.
| Name | Type | Req | Description |
|---|---|---|---|
| purchaseOrderId | string | yes | Purchase order id from get_purchase_orders — not a PO number |
No output schema declared.
No examples provided.
hub_confirm_booking Confirm a held booking ~87
Turn a hold into a real booking once the order behind it is paid, so it stops expiring. Needs the order the booking was sold on — confirming without one is refused, because a confirmed booking nobody can find on a receipt is worse than an expired hold.
| Name | Type | Req | Description |
|---|---|---|---|
| holdId | string | yes | From hold_booking |
| orderId | string | yes | The paid order carrying this booking |
No output schema declared.
No examples provided.
hub_create_booking_resource Create a booking resource ~147
Add one bookable thing to the company directory. Call get_booking_resources first — a resource is reused across every service, so a second "Marco" would split one barber into two calendars and let him be booked twice at once. The name is what staff will see in the calendar.
| Name | Type | Req | Description |
|---|---|---|---|
| kind | string | yes | What sort of thing it is — drives the labels the merchant sees |
| name | string | yes | As the merchant says it, e.g. "Marco", "Room 101", "Scooter 7" |
| tag | string | – | Identifier of this exact instance if it has one: room number, plate, QR, e.g. "SC-07" |
No output schema declared.
No examples provided.
hub_create_booking_rules Create a booking rule set ~420
Create a booking policy. Call get_booking_rules FIRST and reuse a matching set instead — these are shared company-wide, not per product. `weeklyHours` are LOCAL wall-clock times at the outlet; if neither the outlet nor the company has a timezone the engine refuses availability with a 400, so fix the outlet rather than guessing an offset. `bufferMinutes` consumes grid time for slot bookings (cleaning between appointments); for overnight stays use checkInTime/checkOutTime instead and leave the buffer at 0 — the cleaning window lives in the gap and does not consume a night.
| Name | Type | Req | Description |
|---|---|---|---|
| bookingType | string | yes | appointment = a person's time; rental = an asset; overnight = nights; group = a class |
| bufferMinutes | integer | – | Dead time after each booking, e.g. 15 for cleaning. Consumes the grid |
| checkInTime | string | – | Overnight only, "15:00" |
| checkOutTime | string | – | Overnight only, "11:00" |
| holdMinutes | integer | – | How long an unpaid hold survives before the window frees itself. Default 10 |
| maxAdvanceDays | integer | – | How far ahead bookings open. 0 = no limit |
| minNoticeMinutes | integer | – | Shortest notice accepted, e.g. 60 |
| name | string | yes | How the merchant refers to it, e.g. "Haircuts 9–18" |
| ratePeriod | string | yes | What ONE unit of price buys. `slot` for appointments and hourly rental. `week` and `month` are in the enum but NOT offered: the grid still cuts them one day at a time, so a weekly rate would be charg… |
| slotLengthMinutes | integer | yes | How long one booking lasts, e.g. 30 |
| weeklyHours | array | yes | Opening hours per weekday, local time. Days left out are closed. For overnight stays leave hours off only if the property has none — an empty list there means every day. |
No output schema declared.
No examples provided.
hub_create_category Create category ~201
Create a product category. Call get_categories FIRST — a second "Drinks" is easy to make and there is no merge. Pass parentId to make it a subcategory; leave it out for a top-level one. The cabinet's own form asks for a description, so ask the merchant for one rather than inventing it. This does NOT move any product into the category — do that with update_product and its categoryIds.
| Name | Type | Req | Description |
|---|---|---|---|
| description | string | – | Short description shown in the cabinet |
| image | string | – | Image URL, or a Lucide icon reference like "lucide:coffee" |
| name | string | yes | Category name as the merchant said it, e.g. "Beverages" |
| parentId | string | – | Parent category id from get_categories — a name is rejected. Omit for top level |
| sortOrder | number | – | Position among its siblings, lowest first. Omit to leave it unsorted |
No output schema declared.
No examples provided.
hub_create_customer Create customer ~185
Create a customer. Call get_customers with the email or name FIRST — a duplicate splits one person’s order history in two and there is no merge from here. Email is required, exactly as in the cabinet's own customer form. Ask the merchant for anything you do not know instead of inventing it — an invented phone number or address is worse than a missing one.
| Name | Type | Req | Description |
|---|---|---|---|
| billing | object | – | Billing address |
| string | yes | Required — the customer’s email address | |
| firstName | string | – | – |
| lastName | string | – | – |
| note | string | – | A first note about this customer, if the merchant gave one |
| phone | string | – | Phone as the merchant said it, e.g. "+1 555 123 4567" |
| shipping | object | – | Shipping address. Omit to reuse the billing address |
No output schema declared.
No examples provided.
hub_create_modifier Create modifier ~243
Create a new question the till can ask, with its choices. THIS ALONE DOES NOTHING AT THE TILL — follow it with link_modifier_to_category, or the modifier sits unused. Choose selectionType carefully, because it CANNOT be changed afterwards: "single" = pick exactly one (milk, cooking temperature); "multiple" = tick any number of different choices (toppings); "multiple" with allowQuantity true = tick choices AND say how many of each; "quantity" = every choice is a stepper (extra shots). The last two count UNITS, not distinct choices. allowQuantity is only accepted on "multiple" and is refused on the others. Names must be unique for the merchant, ignoring case.
| Name | Type | Req | Description |
|---|---|---|---|
| allowQuantity | boolean | – | Only with selectionType "multiple": let each ticked choice carry a count. CANNOT be changed later |
| choices | array | – | The choices. Can also be added later one at a time |
| name | string | yes | What the cashier sees, e.g. "Milk" or "Toppings" |
| selectionType | string | yes | How it is answered. CANNOT be changed later |
No output schema declared.
No examples provided.
hub_create_outlet Create outlet ~354
Open a new point of sale — the cabinet’s Add Outlet form. Name and the full street address (address, city, state, postCode) are all REQUIRED, exactly as on that form. Do NOT try to set a country: every outlet inherits the company’s country, and it can never be changed per outlet. Ask the merchant for any part of the address you do not know — an invented address ends up on receipts. This is BILLABLE: a new outlet counts against the company plan’s outlet allowance and the call is refused once that allowance is used up. Confirm with the merchant before calling. Afterwards the platform seeds a stock row of 0 for every product at the new outlet in the background, so its stock reads as empty until someone receives or transfers stock in. Linking a Stripe account to the outlet is NOT possible from here — the merchant does that in Settings → Outlets.
| Name | Type | Req | Description |
|---|---|---|---|
| address | string | yes | Street address, e.g. "123 King St W" |
| address2 | string | – | Unit, suite or floor |
| alias | string | – | Short code used by the WooCommerce / Metorik integration. Can never be changed once set — leave it out unless the merchant asked for it |
| city | string | yes | City |
| name | string | yes | Outlet name as the merchant calls it, e.g. "King Street" |
| phone | string | – | Phone number of this location |
| postCode | string | yes | ZIP / postal code |
| state | string | yes | State or province, e.g. "ON" |
| taxId | string | – | Business tax number printed on this outlet’s receipts (BN / GST / HST / VAT / EIN) |
No output schema declared.
No examples provided.
hub_create_product Create product ~442
Create a product in the merchant's catalogue. Call get_products first to make sure it does not already exist. Prices are HUMAN strings like "19.99" — this tool converts them into the company's currency itself, so never send cents. Tax: the company's standard tax table is applied by default; pass taxable:false for an untaxed product. Ask the merchant for anything you do not know instead of inventing it.
| Name | Type | Req | Description |
|---|---|---|---|
| barcode | string | – | EAN/UPC if the merchant gave one |
| categoryIds | array | – | Category ids — names are rejected |
| costPrice | string | – | What the merchant pays for it, human string |
| description | string | – | – |
| name | string | yes | Product name as the merchant said it |
| options | object | – | Variation axes and the values to build variants from, e.g. {"Size":["Small","Large"]}. Every combination becomes a variant. Call get_product_options FIRST and reuse existing axes. Every variant gets… |
| outletIds | array | – | Outlet ids. Omit for everywhere |
| price | string | yes | Selling price as a human string, e.g. "19.99" |
| productType | string | – | Only pass this for "booking" — a service sold as TIME (a haircut, a room for the night, an hour on a scooter). simple/variable are derived from `options`, so leave it out for goods. A booking product… |
| shortDescription | string | – | – |
| sku | string | – | – |
| taxTableId | string | – | A specific tax table, for non-standard tax |
| taxable | boolean | – | Default true: applies the standard tax table |
| trackInventory | boolean | – | Default false. True manages stock |
| variantPrices | array | – | Per-variant prices at creation, one entry per combination that differs from `price`, e.g. {"options":{"Size":"Large"},"price":"21.99"}. `options` must name one value for EVERY axis in `options`. |
No output schema declared.
No examples provided.
hub_create_product_option Create product option ~105
Create a new variation axis with its possible values. Use it only when get_product_options shows nothing suitable. The axis is shared across the whole catalogue, not one product — so confirm the name and values with the merchant first and reuse an existing axis when one fits.
| Name | Type | Req | Description |
|---|---|---|---|
| name | string | yes | Axis name as the merchant says it, e.g. "Size" |
| values | array | yes | Possible values in display order, e.g. ["Small","Medium","Large"] |
No output schema declared.
No examples provided.
hub_create_purchase_order Create purchase order ~355
Write a new order to a supplier. It is created as a DRAFT — nothing reaches the supplier and no stock moves until send_purchase_order. PREREQUISITES, in this order: get_suppliers for the supplierId, get_outlets for the outlet the goods will be delivered INTO, then get_supplier_items WITH that outletId for the lines — variantId and unitCost come from there, and an item that is not linked to this supplier is refused. unitCost is what the merchant pays per unit as a human amount ("12.50"), prefilled from the supplier link but editable if this order was negotiated differently. quantity is in the item’s selling unit and may be fractional for goods sold by weight or length. Read the lines back to the merchant with the total before sending — a wrong quantity here becomes wrong stock later.
| Name | Type | Req | Description |
|---|---|---|---|
| customFees | array | – | Any other named charge on the order, e.g. "Handling" |
| discount | string | – | Flat discount on the whole order, e.g. "25.00". Not with discountPercent |
| discountPercent | number | – | Discount as a percentage of the items subtotal |
| dutyFees | string | – | Duty / customs charged on the order |
| expectedDate | string | – | ISO date the merchant expects delivery |
| lines | array | yes | What to order |
| notes | string | – | Note for the supplier / for the merchant’s own records |
| outletId | string | yes | Outlet id from get_outlets — where the goods will be received |
| shippingFee | string | – | Shipping charged on the order, e.g. "18.00" |
| supplierId | string | yes | Supplier id from get_suppliers |
No output schema declared.
No examples provided.
hub_create_role Create role ~255
Create a new role with a chosen set of permissions — for when no existing role fits what the merchant wants someone to do. Check get_roles first; a near-match plus update_role is usually better than a fourth almost-identical role. PERMISSIONS ARE POWER. Confirm with the merchant first, naming the person and the role out loud ("give Maria the Manager role — yes?"), and never act on a role change you inferred rather than were asked for. The change is live on the next request: rights are re-read from the role every time, so no one logs out and no agent key stops working — including yours, if the change reaches your own account. Permission ids come from get_permissions. List back in plain words what the role will be able to do and get an explicit yes before calling. Creating a role gives nobody anything until assign_role puts a person on it. If you are signed in as an employee you can only grant permissions you hold yourself — the cabinet works the same way — and the call is refused otherwise.
| Name | Type | Req | Description |
|---|---|---|---|
| name | string | yes | What the merchant calls it, e.g. "Shift lead" |
| permissionIds | array | yes | Permission ids from get_permissions — everything not listed is switched off |
No output schema declared.
No examples provided.
hub_create_station Add virtual till ~250
Add a VIRTUAL till — a browser-based station, the cabinet’s "Add Virtual Station". It is created at one outlet and starts AVAILABLE. You CANNOT create a native (device) station from here and must not try: a physical till enrols itself when someone opens the POS app on the device and names it there. THIS IS BILLABLE — a new station counts against the company plan’s station allowance and the call is refused once that allowance is used up. Confirm with the merchant before calling. flowSrcId is the POS layout the till runs. The cabinet’s wizard makes picking one mandatory and there is no tool here that lists flows, so unless the merchant gave you an id, create the station and then tell them plainly to open Run → Stations and choose the flow — until they do, the station exists but cannot be launched.
| Name | Type | Req | Description |
|---|---|---|---|
| flowSrcId | string | – | Id of the POS layout (flow) the till runs, if the merchant gave one |
| name | string | yes | Station name as staff will see it, e.g. "POS 2" |
| outletId | string | yes | Which outlet this till belongs to — id from get_outlets, not a name |
No output schema declared.
No examples provided.
hub_create_stock_transfer Send stock transfer ~279
Move stock from one outlet to another — 'send 10 of these from the warehouse to the King Street shop'. CONFIRM WITH THE MERCHANT FIRST, naming both outlets and every quantity: this writes immediately and there is no undo from here. The stock LEAVES the source outlet at once; the destination only gains it when someone confirms arrival with receive_stock_transfer, so until then those units are in transit and count in neither shop. Tell the merchant that. Variant ids come from get_products, outlet ids from get_outlets. Check availability with get_stock first: sending more than the source holds is rejected, and so is sending a variant whose stock is not tracked at the source — there is no count there to move. To correct a count in place (damage, theft, a recount) use adjust_stock instead; to book in a supplier delivery use adjust_stock with STOCK_RECEIVED.
| Name | Type | Req | Description |
|---|---|---|---|
| fromOutletId | string | yes | Source outlet id from get_outlets — stock leaves here immediately |
| invoice | string | – | Invoice or reference number, if the merchant gave one |
| items | array | yes | What to move. One entry per variant |
| note | string | – | A note staff will read on the transfer |
| toOutletId | string | yes | Destination outlet id from get_outlets — must differ from the source |
No output schema declared.
No examples provided.
hub_create_supplier Create supplier ~238
Add a business the merchant buys from. Only the name is required, and it must be unique among this company’s suppliers. Set contactEmail if the merchant will ever email purchase orders to this supplier — send_purchase_order has nowhere to send without it. A brand-new supplier carries NO items, so it cannot be ordered from yet: link its items with link_supplier_items before creating a purchase order. Ask the merchant for details you do not have rather than inventing them — this ends up on the orders their supplier reads.
| Name | Type | Req | Description |
|---|---|---|---|
| address1 | string | – | Street address |
| address2 | string | – | Unit, suite or floor |
| city | string | – | – |
| contactEmail | string | – | Where purchase orders are emailed |
| contactName | string | – | Person the merchant deals with |
| country | string | – | – |
| name | string | yes | Supplier name as the merchant calls it |
| notes | string | – | Free-text notes, e.g. delivery days or account number |
| phone | string | – | – |
| postCode | string | – | ZIP / postal code |
| state | string | – | State or province |
No output schema declared.
No examples provided.
hub_create_tax_group Create tax group ~162
Create an empty tax group (a tax profile that products get assigned to, e.g. "Standard", "Food", "Zero-rated"). Call get_taxes FIRST — a second group with the same meaning splits the catalogue and is a common way to end up charging two different taxes for one thing. The group charges nothing until you add rates with create_tax_rate or add_tax_rate_to_group, and no product uses it until someone assigns it. isStandard marks the company default — set it only if the merchant explicitly says so. CONFIRM the name with the merchant before calling.
| Name | Type | Req | Description |
|---|---|---|---|
| isStandard | boolean | – | Make this the company default group. Default false |
| name | string | yes | What the merchant calls it, e.g. "Standard Tax" |
No output schema declared.
No examples provided.
hub_create_tax_rate Create tax rate ~315
Create a named tax rate ("State Sales Tax", "GST") with its percentage, and optionally put it straight into a tax group. Check get_taxes first: if a rate with this meaning already exists, add_tax_rate_to_group reuses it, which is almost always what the merchant wants — duplicating a rate means the next change has to be made twice and one of them gets forgotten. Give either percentage (the same at every outlet) or perOutlet (different per store) — never both, and never neither, since a rate with no percentage charges nothing. Without taxGroupId the rate exists but is charged nowhere. CONFIRM THE EXACT PERCENTAGE WITH THE MERCHANT before calling — do not infer it from suggest_tax_rate or from what is usual in that region. Sales already rung up are NOT recalculated — this only affects sales from now on.
| Name | Type | Req | Description |
|---|---|---|---|
| compounding | boolean | – | Only with taxGroupId: charge on the running total including the rates above it. Default false |
| name | string | yes | What appears on the receipt, e.g. "GST", "State Sales Tax" |
| perOutlet | array | – | Outlet-specific percentages, using outlet ids from get_taxes. REPLACES the stored list whole — an outlet you leave out stops charging this rate |
| percentage | number | – | One percentage for every outlet, e.g. 13 for 13% |
| taxGroupId | string | – | Tax group id from get_taxes to add it to right away |
No output schema declared.
No examples provided.
hub_create_user Create POS user ~343
Add a POS user — someone who signs in at the till with a PIN. Mirrors the cabinet’s "New POS user" form: first and last name, a 4-6 digit PIN, a role, optionally a phone. They get access to every outlet of the company, which update_user can narrow afterwards. BACK-OFFICE (Hub) users are NOT created here: those are invited by email from the cabinet, and that invitation flow is not available through this tool. If the merchant wants someone who can log in to the back office, say that and point them at Manage → Team → Users → Add User. The role decides what the new person may do, so PERMISSIONS ARE POWER. Confirm with the merchant first, naming the person and the role out loud ("give Maria the Manager role — yes?"), and never act on a role change you inferred rather than were asked for. The change is live on the next request: rights are re-read from the role every time, so no one logs out and no agent key stops working — including yours, if the change reaches your own account. A new user also counts against the company plan’s user allowance and the call is refused once it is used up.
| Name | Type | Req | Description |
|---|---|---|---|
| firstName | string | yes | Required |
| lastName | string | yes | Required |
| phone | string | – | Phone as the merchant said it, e.g. "+1 555 123 4567" |
| pincode | string | yes | Required — 4 to 6 digits, what they type at the till |
| roleId | string | yes | Role id from get_roles — required, and it decides their permissions |
No output schema declared.
No examples provided.
hub_delete_category Delete category ~123
Delete a category. Takes the category id ONLY — look it up with get_categories and never guess. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the category: there is no undo from here. Products in the category are NOT deleted — they are kept and simply lose this category, so a product that had no other category ends up uncategorised. A category that still has subcategories is refused: move or delete those first. So is a category synced from an integration.
| Name | Type | Req | Description |
|---|---|---|---|
| categoryId | string | yes | Category id from get_categories — not a name |
No output schema declared.
No examples provided.
hub_delete_customer Delete customer ~95
Remove a customer from the merchant's list. Takes the customer ID ONLY — look it up with get_customers and never guess. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the customer: there is no undo from here. Their past orders are kept. If several customers match, list them and ask which one instead of picking.
| Name | Type | Req | Description |
|---|---|---|---|
| customerId | string | yes | Customer id from get_customers — not a name |
No output schema declared.
No examples provided.
hub_delete_media_file Delete media file ~219
Permanently delete one file from the media library. Takes the file ID from get_media_library ONLY — never guess it. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the file: the image is destroyed and there is NO UNDO. Tell them this too, because the platform does not check it and nothing is cleaned up afterwards: if any product or category uses this image, it KEEPS the dead URL and its picture turns into a broken image — the file is not detached, it is only made unreachable. There is no reverse lookup here from a file to the products using it, so if they are unsure, say so and let them check on the Media screen in the cabinet rather than deleting on a guess. The file may also stay listed on that screen afterwards, because that screen is fed by a separate service. Removing a photo from ONE product without destroying the file is not this tool — that is a product edit.
| Name | Type | Req | Description |
|---|---|---|---|
| fileId | string | yes | File id from get_media_library — not a name or a URL |
No output schema declared.
No examples provided.
hub_delete_modifier Delete modifier ~84
Remove a modifier from the catalogue AND detach it from every category at once — the till stops asking it everywhere. Check get_modifier first and tell the merchant which categories lose it. To stop asking it in ONE place only, use unlink_modifier_from_category. Past orders keep the options that were already rung up.
| Name | Type | Req | Description |
|---|---|---|---|
| modifierId | string | yes | Modifier id from get_modifiers |
No output schema declared.
No examples provided.
hub_delete_modifier_choice Delete a choice ~65
Remove one choice from a modifier. Refused when it would leave a category asking for more choices than remain — the explanation names the category.
| Name | Type | Req | Description |
|---|---|---|---|
| choiceId | string | yes | Choice id from get_modifier |
| modifierId | string | yes | Modifier id from get_modifiers |
No output schema declared.
No examples provided.
hub_delete_outlet Delete outlet ~173
Close a point of sale permanently. Takes the outlet id from get_outlets. CONFIRM WITH THE MERCHANT FIRST, naming the outlet — there is NO undo from here. Tell them what goes with it: the stock recorded AT that outlet is removed and is NOT moved anywhere else (transfer it out first if they want to keep it), and so are the outlet’s tax rate values and its per-outlet product visibility. Past orders, sessions and reports still name the outlet and are not touched, and the stations that belonged to it are NOT deleted — they have to be dealt with separately. An outlet that WooCommerce uses as its default is refused: the merchant must change that default or uninstall the WooCommerce extension first.
| Name | Type | Req | Description |
|---|---|---|---|
| outletId | string | yes | Outlet id from get_outlets — not a name |
No output schema declared.
No examples provided.
hub_delete_product Delete product ~93
Remove a product from the merchant's catalogue. Takes the product ID ONLY — look it up with get_products and never guess. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the product: this also removes all of its variants and there is no undo. If several products match, list them and ask which one instead of picking.
| Name | Type | Req | Description |
|---|---|---|---|
| productId | string | yes | Product id from get_products — not a name |
No output schema declared.
No examples provided.
hub_delete_role Delete role ~119
Delete a role the merchant no longer uses. Takes the roleId from get_roles. CONFIRM FIRST, naming the role — there is no undo. A role that anyone still holds cannot be deleted: the server refuses and tells you how many people are on it. Move them with assign_role first, and check with the merchant which role they should land on — that move changes what those people can do. You cannot delete the role you are signed in under.
| Name | Type | Req | Description |
|---|---|---|---|
| roleId | string | yes | Role id from get_roles — not a role name |
No output schema declared.
No examples provided.
hub_delete_station Delete till ~190
Remove a till from Run → Stations. Takes the station id from get_stations. CONFIRM WITH THE MERCHANT FIRST, naming the station — there is NO undo from here, and it takes a working register out of service: the device that used it has to be set up again in the POS app, and it comes back as a NEW station with a new id. A station reporting IN_USE is REFUSED, exactly as the cabinet greys the button out — the shift has to be closed on the device first. If the merchant insists that till is idle, the flag is stale (it was closed while the device was offline); it clears once the device reconnects, so try again then instead of forcing anything. Past orders, sessions and End of Session reports keep naming this station and are not touched.
| Name | Type | Req | Description |
|---|---|---|---|
| stationId | string | yes | Station id from get_stations — not a name |
No output schema declared.
No examples provided.
hub_delete_supplier Delete supplier ~122
Remove a supplier the merchant no longer buys from. CONFIRM WITH THE MERCHANT FIRST, naming the supplier — there is no undo from here. Its item links go with it, so any auto-reorder rule pointing at this supplier stops producing suggestions. REFUSED while the supplier still has an open purchase order (anything not fully received): receive or cancel those first — get_purchase_orders filtered by this supplier shows them. Purchase orders already placed are kept and still name the supplier.
| Name | Type | Req | Description |
|---|---|---|---|
| supplierId | string | yes | Supplier id from get_suppliers — not a name |
No output schema declared.
No examples provided.
hub_delete_tax_group Delete tax group ~211
Delete a tax group. Takes the tax group id from get_taxes. THIS MOVES PRODUCTS: every product assigned to this group is re-pointed at replacementTaxGroupId, or — if you omit it — left with NO tax group at all, meaning those products are sold UNTAXED from that moment. Always ask the merchant which of the two they want and pass a replacement unless they say otherwise. The rates inside it are NOT deleted; they stay available to the other groups (use delete_tax_rate if the merchant really wants a rate gone). CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the group and how many products it affects. There is no undo. Sales already rung up are NOT recalculated — this only affects sales from now on.
| Name | Type | Req | Description |
|---|---|---|---|
| replacementTaxGroupId | string | – | Tax group its products move to. OMIT ONLY if the merchant wants those products left untaxed |
| taxGroupId | string | yes | Tax group id from get_taxes — not a name |
No output schema declared.
No examples provided.
hub_delete_tax_rate Delete tax rate ~188
Permanently delete a tax rate FROM THE WHOLE COMPANY. Takes the tax rate id from get_taxes. THIS CASCADES: the rate is stripped out of every tax group that lists it and all of its per-outlet percentages are deleted with it. Products in those groups immediately stop being charged this tax. This is almost never what a merchant means when they say "remove the tax from X" — that is remove_tax_rate_from_group. Use this one only when they say the rate should not exist at all any more. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the rate and listing every group it will disappear from. There is no undo and no way to recover the percentages. Sales already rung up are NOT recalculated — this only affects sales from now on.
| Name | Type | Req | Description |
|---|---|---|---|
| taxRateId | string | yes | Tax rate id from get_taxes — not a name |
No output schema declared.
No examples provided.
hub_export_records Export records ~253
Dump one resource in spreadsheet shape — every record flattened to the same columns the import tools accept, WITH its id. Answers 'export my catalogue / my customers', and it is the required first step before any import that changes existing records: the `updates` arrays all key on the ids this returns. For QUESTIONS about the data ("how many products", "find John") use get_products / get_customers / get_categories / get_outlets / get_options instead — they read better and filter server-side. LIMITATIONS: no filtering and no sorting; records come back in stored order, one window at a time. It also cannot produce a FILE — if the merchant wants a .csv/.xlsx download, send them to Settings → Import / Export → Export in the cabinet and do not page through thousands of rows to imitate it. Money is in minor units (cents), matching what the import tools read back.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Records to return, default 100, max 500 |
| offset | integer | – | Records to skip, default 0 |
| resource | string | yes | Which resource to dump. "options" means product attributes (Size, Colour) — the cabinet calls them Attributes |
No output schema declared.
No examples provided.
hub_export_stock_csv Export stock CSV ~258
The stock export file for ONE outlet, as CSV text: Variation ID, Product Name, Variation name, SKU, Stock Management, Cur Qty, New Qty. Use it when the merchant asks for the stock sheet itself — a stocktake worksheet, a hand-off to a supplier, 'give me my stock as CSV'. For stock QUESTIONS — how many of X are left, what is running out, history of a change — use get_stock, find_low_stock and get_stock_history: they filter on the server and explain when tracking is switched off. This dump includes untracked rows and cannot tell "zero" apart from "not counted here". It is READ-ONLY: to write counts back, edit the New Qty column and send the file to import_stock_csv. Large catalogues are truncated — the reply reports the true row count.
| Name | Type | Req | Description |
|---|---|---|---|
| categoryIds | array | – | Category ids from get_categories |
| maxRows | integer | – | Data rows to return, default 200, max 2000 |
| outletId | string | yes | Outlet id from get_outlets — not a store name |
| productTypes | array | – | Restrict to these product types |
| statuses | array | – | Restrict to these product statuses |
No output schema declared.
No examples provided.
hub_find_low_stock Low stock ~205
What is running out. Answers 'what is low', 'what do I need to reorder', 'what has run out at the warehouse'. Returns the stock-tracked (variant, outlet) lines at or below a threshold, lowest first. Threshold defaults to 5; pass threshold: 0 for "what has actually hit zero". Lines where stock is NOT tracked are excluded on purpose — they have no count, so they can never be low, and reporting them would invent a shortage that does not exist. This is per outlet: the same variant can be empty in one shop and full in another. For one specific product use get_stock instead.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | How many lines to return, default 25 |
| outletId | string | – | Outlet id from get_outlets. Omit to cover every outlet |
| threshold | integer | – | Report lines with this many units or fewer. Default 5; use 0 for out-of-stock only |
No output schema declared.
No examples provided.
hub_get_booking_availability Check booking availability ~180
The bookable windows for a product over a date range, per resource, with what is already taken. Quote times from THIS — never compute a grid yourself: the engine applies the hours, the buffer, notice and advance limits, and the outlet timezone, and a hold whose start is not exactly a slot start is refused. Ask for a few days at a time; a year-wide range is slow and pointless.
| Name | Type | Req | Description |
|---|---|---|---|
| from | string | yes | ISO instant, start of the range, e.g. "2026-09-12T00:00:00Z" |
| outletId | string | – | The shop the booking is for — decides the local wall clock. Omit for the company default |
| productId | string | yes | Product id from get_products |
| to | string | yes | ISO instant, end of the range |
No output schema declared.
No examples provided.
hub_get_booking_events Read booking history ~117
The trail of what happened to bookings — held, confirmed, cancelled, expired — newest first, with who did it. Use it to answer "what happened to this booking"; an actor of `system` is the server freeing an expired hold, not a person. Each row is immutable, so this is the record even when the booking itself is gone.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | How many rows, newest first. Default 100 |
| productId | string | – | Narrow to one product. Omit for the whole company |
No output schema declared.
No examples provided.
hub_get_booking_resources List booking resources ~87
List what can be booked — the staff, rooms, tables or assets in the company directory. A resource is whatever can only be in one place at a time, and it is shared across services: the same barber is one resource whether he cuts hair or trims a beard, which is why booking him for one closes the other. Read this before creating anything and reuse what is there.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
hub_get_booking_rules List booking rule sets ~79
List the reusable booking policies the merchant already has — opening hours, slot length, buffer, how far ahead people may book. A rule set is shared by every product pointing at it, exactly like a tax table, so ALWAYS read this before creating one and offer an existing set when it fits. Editing a set changes every product that uses it.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
hub_get_categories List categories ~169
The merchant's product categories, as the tree they see in the cabinet: every category with its subcategories nested inside it, sorted by sortOrder. Answers "what categories do I have", "is there a Drinks category", "where does Beer sit". Use it to get the category id any other tool needs. It returns categories ONLY — never products, and never a product count. There is no way to list the products of a category from this server today: get_products searches by name or SKU and cannot filter by category, so say that plainly instead of guessing. To put a product INTO a category, go to the product side: create_product / update_product take categoryIds. The whole tree comes back at once — there is no paging and no search argument, so filter by name yourself.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
hub_get_category_modifiers List modifier placements ~143
Where modifiers are actually asked: one row per category↔modifier link, with that category’s own rules (required, min, max, order). This is what makes a modifier reach the till, so use it to answer "what options does this category ask" or "where is this modifier used". Narrow to one category with categoryId. Remember products also inherit their ancestors’ links, so a subcategory asks more than its own rows show. The id on each row is the LINK id — that is what update_category_modifier and unlink_modifier_from_category take.
| Name | Type | Req | Description |
|---|---|---|---|
| categoryId | string | – | Category id from get_categories. Omit for every category |
No output schema declared.
No examples provided.
hub_get_customer Get customer details ~83
Everything known about ONE customer: addresses, notes, how many orders they placed, what they spent and what was refunded. Takes the customer ID from get_customers, never a name. Use it before answering a question about a specific person — the list leaves notes and refunds out.
| Name | Type | Req | Description |
|---|---|---|---|
| customerId | string | yes | Customer id from get_customers — not a name |
No output schema declared.
No examples provided.
hub_get_customer_orders Customer order history ~174
ONE customer's history as a single timeline, newest first: their orders AND the refunds taken against them, each row marked type "order" or "refund" — the same list the customer screen shows. Answers 'what has this person bought', 'did we refund them', 'when were they last in'. Takes the customer ID from get_customers, never a name. get_orders with customerIds returns the orders alone and a total count; use this tool when the refunds belong in the answer. No total count comes back here — keep paging until a page returns fewer rows than asked for.
| Name | Type | Req | Description |
|---|---|---|---|
| customerId | string | yes | Customer id from get_customers — not a name |
| page | integer | – | Page number, default 1 |
| pageSize | integer | – | Rows per page, default 20 |
No output schema declared.
No examples provided.
hub_get_customers List customers ~191
List the merchant's customers. Answers 'who are my customers', 'find John's email', 'has this person bought from us'. Search matches email, first name, last name and full name — NOT phone numbers, addresses or notes. LIMITATION — there is no sorting: results come back in stored order and cannot be ordered by spend, name or last visit. So 'my best customers' or 'who spent the most' CANNOT be answered from this tool, and you must NOT page through everyone trying. Say plainly that sorting is not supported yet, then offer what does work: search by a name or email, or ask the merchant to narrow it down.
| Name | Type | Req | Description |
|---|---|---|---|
| page | integer | – | Page number, default 1 |
| pageSize | integer | – | Results per page, default 20 |
| search | string | – | Filter by email, first name, last name or full name |
No output schema declared.
No examples provided.
hub_get_employee_orders Employee orders ~217
The orders ONE staff member rang up in a date range. Takes the employee id from get_employee_sales, never a name. Use it to back up a claim about a person — 'show me the sales behind Maria's number', 'which orders did he refund'.
| Name | Type | Req | Description |
|---|---|---|---|
| employeeId | string | yes | Employee id from get_employee_sales — not a name |
| endDate | string | yes | End of the window, ISO 8601. Inclusive of the day when a bare date is given |
| outlets | array | – | Outlet ids to restrict to. Omit for all outlets |
| page | integer | – | Page number, default 1 |
| pageSize | integer | – | Orders per page, default 20 |
| startDate | string | yes | Start of the window, ISO 8601, e.g. "2026-08-01" or "2026-08-01T00:00:00Z" |
| stations | array | – | Station ids to restrict to. Omit for all stations |
No output schema declared.
No examples provided.
hub_get_employee_sales Employee sales ~274
Sales per staff member for a date range — Reports → Employee Sales. Answers 'who is my best seller', 'how much did Maria sell', 'who took the most refunds', 'average ticket per employee'. One row per employee with orders, gross sales, refunds, tips and average transaction. Staff lists are short, so ranking is safe: pull the rows and sort them yourself rather than asking the merchant to narrow down. Pass employeeId to get a single person. For the actual orders one person rang up, use get_employee_orders.
| Name | Type | Req | Description |
|---|---|---|---|
| employeeId | string | – | Restrict to one employee, by id from a previous call |
| endDate | string | yes | End of the window, ISO 8601. Inclusive of the day when a bare date is given |
| outlets | array | – | Outlet ids to restrict to. Omit for all outlets |
| page | integer | – | Page number, default 1 |
| pageSize | integer | – | Rows per page, default 50 |
| startDate | string | yes | Start of the window, ISO 8601, e.g. "2026-08-01" or "2026-08-01T00:00:00Z" |
| stations | array | – | Station ids to restrict to. Omit for all stations |
No output schema declared.
No examples provided.
hub_get_extension_catalog Browse extension catalog ~231
The extension STORE: every built-in extension the platform offers, the same list for every merchant. Answers 'what can I add', 'do you have a WooCommerce integration', 'can I get X'. For 'what do I already have', use get_installed_extensions instead — this tool only flags each entry with `installed`. `availableOnYourPlan: false` means the subscription plan excludes it: the store hides it in the cabinet and install_extension will refuse — say so instead of trying. LIMITATIONS, do not paper over them: the platform stores only a name, a category, a price and an id per built-in extension — there is NO stored description, so do not invent what an extension does; say what the name and category say and offer to open its page in the cabinet. `price` is a bare stored string with no currency attached — quote it verbatim, never as a formatted amount. Custom extensions built by an organisation are NOT in this list (they need an organisation scope this agent key does not carry); they do show up in get_installed_extensions once installed.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
hub_get_extension_surfaces List extension screens ~222
What the installed extensions ADD to the apps — the answer to "where did this new menu item come from", "what is this extra block on the product page", "what did installing X actually change". Every entry belongs to an installed extension; nothing here is part of the base product. Read `platform` to know where it shows up: `hub` = this admin cabinet, `builder` = the POS flow builder, `render` = the station screen. Within `hub`, type `merchant-hub-page` is a navigation entry of its own and `merchant-hub-widget` is a block embedded in a detail page — `attachedTo` says which one (products / orders / customers / users). LIMITATION: this tells you which extension-provided screens EXIST, not what they contain — each one is an embedded page owned by its extension, and this agent cannot open or read it. It also cannot say which extension contributed a given entry. To go the other way — what is installed at all — use get_installed_extensions.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
hub_get_financial_summary Financial summary ~237
THE headline money report for a date range — the same numbers as Reports → Financial Summary. Answers 'how much did we make last week', 'what were sales this month', 'how much tax do I owe', 'what lands in my bank'. Returns gross sales, discounts, refunds, fees, tax, tips, net sales, and the settlement split (card / cash / custom) down to what the merchant actually receives. Start here for any "how did the business do" question, and only reach for get_sales_breakdown when the merchant wants the individual orders behind these totals.
| Name | Type | Req | Description |
|---|---|---|---|
| endDate | string | yes | End of the window, ISO 8601. Inclusive of the day when a bare date is given |
| outlets | array | – | Outlet ids to restrict to. Omit for all outlets |
| startDate | string | yes | Start of the window, ISO 8601, e.g. "2026-08-01" or "2026-08-01T00:00:00Z" |
| stations | array | – | Station ids to restrict to. Omit for all stations |
No output schema declared.
No examples provided.
hub_get_installed_extensions List installed extensions ~197
What THIS company actually has installed — built-in and organisation-built (custom) extensions alike. This is the answer to 'which extensions do I have', 'is WooCommerce turned on for me', 'what am I paying for'. Not to be confused with get_extension_catalog, which lists what exists on the platform whether or not this merchant has it. Each row carries `extensionId` (pass this to install_extension / uninstall_extension) and `companyExtensionId` (the install record itself — you never need to pass that one). `description` is filled in only for custom extensions; built-in ones store no prose, so do not guess what they do. LIMITATION: the install date is not stored — you cannot say when an extension was added or who added it. To answer what an installed extension CHANGED in the cabinet — a new menu entry, a block on a detail page — use get_extension_surfaces.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
hub_get_linkable_items List items a supplier could carry ~167
Catalogue items this supplier does NOT carry yet but could — the picker behind "add items to supplier". Feed what you choose to link_supplier_items. Only stock-managed items appear: something the merchant does not track stock for cannot be purchase-ordered at all, so if an expected item is missing here and missing from get_supplier_items too, the reason is almost always that stock tracking is off for it — say that instead of guessing. Omit supplierId to search the whole linkable catalogue, e.g. while deciding which supplier to create. Returns everything matching, unpaged, so pass a search.
| Name | Type | Req | Description |
|---|---|---|---|
| search | string | – | Match product name, item name, SKU or barcode |
| supplierId | string | – | Supplier id — omit to see the whole linkable catalogue |
No output schema declared.
No examples provided.
hub_get_media_library List media files ~264
List the image files stored on the merchant's account. Answers 'what images do I have', 'do I already have a photo of X', 'what did I upload recently', and it is where you get a file id before deleting one, or a URL to reuse on a product or category. Newest first; search is a case-insensitive match on the FILE NAME only. LIMITATIONS, state them rather than working around them: there is no other sorting, and no title, alt text, description, folder, file size or image dimensions here — the Media screen in the cabinet shows those, but they are stored by a different service that this tool cannot read, so it may list files this tool does not and vice versa. There is also NO WAY TO RENAME a file from here: if the merchant asks to rename one, or to change its alt text, title or folder, say that has to be done on the Media screen in the cabinet. Do not delete and re-upload to fake a rename.
| Name | Type | Req | Description |
|---|---|---|---|
| page | integer | – | Page number, default 1 |
| pageSize | integer | – | Results per page, default 20 |
| search | string | – | Filter by file name, e.g. "logo" or "shirt" |
No output schema declared.
No examples provided.
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
claude mcp add --transport http com-finalpos-final 'https://ai.finalpos.com/mcp'
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.