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_reorder_categories Reorder categories ~106
Set the display order of several categories in one call — "put Drinks first", "sort my categories alphabetically". Lowest sortOrder shows first, and ordering only applies among categories that share the same parent. Send every category whose position should change, with the ids from get_categories; ones you leave out keep their current order, which can leave two categories tied. It changes NOTHING but the order — for a rename or a move use update_category.
| Name | Type | Req | Description |
|---|---|---|---|
| categories | array | yes | – |
No output schema declared.
No examples provided.
hub_reorder_category_modifiers Reorder a category’s modifiers ~91
Set the order the till asks a category’s modifiers in. Pass EVERY link id for that category exactly once, in the order wanted — a partial list is refused. Read them from get_category_modifiers with that categoryId.
| Name | Type | Req | Description |
|---|---|---|---|
| categoryId | string | yes | Category id from get_categories |
| orderedIds | array | yes | Every link id for this category, each once, in ask order |
No output schema declared.
No examples provided.
hub_reorder_modifier_choices Reorder choices ~83
Set the order the choices appear in at the till. Pass EVERY current choice id exactly once, in the order wanted — a partial list is refused. Read them from get_modifier first.
| Name | Type | Req | Description |
|---|---|---|---|
| modifierId | string | yes | Modifier id from get_modifiers |
| orderedChoiceIds | array | yes | Every current choice id, each exactly once, in display order |
No output schema declared.
No examples provided.
hub_send_purchase_order Send purchase order to supplier ~215
Place the order: moves a `draft` or `suggested` order to `sent` and, when asked, EMAILS IT TO THE SUPPLIER. ASK THE MERCHANT WHETHER TO EMAIL, EVERY TIME, and only then pass sendEmail: true — that message leaves the platform and cannot be recalled. Default is false, which records the order as placed without mailing anything: the right choice when they ordered by phone, in person, or through the supplier’s own portal. Emailing needs a contactEmail on the supplier; without one, send with sendEmail: false and tell them why. The email carries the order in its body — this tool cannot attach the PO PDF the cabinet produces. After sending, the order can no longer be edited; only receiving or cancelling remain.
| Name | Type | Req | Description |
|---|---|---|---|
| purchaseOrderId | string | yes | Purchase order id from get_purchase_orders — not a PO number |
| sendEmail | boolean | – | Email the supplier. Defaults to false — set true ONLY after the merchant said to send it |
No output schema declared.
No examples provided.
hub_set_product_booking_setup Make a product bookable ~141
Point a booking product at its rule set AND the resources that serve it — both in one call, because a product with only one of them takes no bookings at all. `resourceIds` REPLACES the current list rather than adding to it, so pass every resource that should serve the product. The product must already exist and be of the booking type (create_product with productType "booking").
| Name | Type | Req | Description |
|---|---|---|---|
| bookingRulesId | string | yes | Rule set id from get_booking_rules |
| productId | string | yes | Product id from get_products |
| resourceIds | array | yes | Every resource that can serve this product, ids from get_booking_resources |
No output schema declared.
No examples provided.
hub_set_reorder_rule Turn on auto-reorder for an item ~221
Tell the platform to watch one item and suggest reordering it when stock runs low: below lowStockPoint, suggest ordering reorderQuantity from this supplier. Calling it again on the same item replaces the rule rather than adding a second one. The supplier MUST already carry this item (get_supplier_items) — otherwise the rule would draft orders to a supplier that cannot fulfil them, and it is refused. The thresholds apply company-wide unless you pass outletOverrides, which set a different point or quantity per outlet — a busy store may need a higher one than a quiet one. This only produces SUGGESTIONS. Nothing is ever ordered or emailed automatically.
| Name | Type | Req | Description |
|---|---|---|---|
| lowStockPoint | integer | yes | Suggest reordering once stock falls below this |
| outletOverrides | array | – | Per-outlet thresholds for outlets that differ from the default |
| reorderQuantity | integer | yes | How many to suggest ordering |
| supplierId | string | yes | Supplier to reorder from — must already carry this item |
| variantId | string | yes | Item id from get_supplier_items |
No output schema declared.
No examples provided.
hub_suggest_tax_rate Suggest tax rate ~155
Look up the statutory headline rate for a country (and US state / Canadian province). Answers 'what should I charge in Ontario', 'what is the VAT in Germany'. This is a reference lookup — it changes NOTHING and creates nothing; use create_tax_rate to actually charge it. Report the `confidence` and any `note` back to the merchant verbatim: local / city taxes are not included and the merchant, not you, decides the real rate.
| Name | Type | Req | Description |
|---|---|---|---|
| country | string | yes | Two-letter ISO country code, e.g. "US", "CA", "DE" |
| state | string | – | US state or Canadian province code, e.g. "NY", "ON". Needed for US and CA |
No output schema declared.
No examples provided.
hub_sync_order_to_ecommerce Sync order to store ~149
Push one order to the company's connected online store (WooCommerce): creates it there the first time, updates it afterwards, and syncs its notes. Use ONLY when the merchant says an order is missing from or stale in their online store — 'this sale never showed up in WooCommerce'. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the order: it writes into their live store and nothing here can undo it. It changes NOTHING in Final POS — it is not a way to change status, cancel an order or refund anything. Companies with no supported platform connected get a no-op.
| Name | Type | Req | Description |
|---|---|---|---|
| orderId | string | yes | Order id from get_orders — not a receipt number |
No output schema declared.
No examples provided.
hub_sync_refund_to_ecommerce Sync refund to store ~138
Push a refund that ALREADY exists in Final POS to the connected WooCommerce store, so the online order shows as refunded there. Takes the REFUND id from get_refunds — the order id will not work. CONFIRM WITH THE MERCHANT BEFORE CALLING: it creates a refund on their live store, there is no undo from here, and calling it twice creates a second refund there. It does NOT move money back to the customer and it does NOT create a refund in Final POS — that happens on the POS terminal.
| Name | Type | Req | Description |
|---|---|---|---|
| refundId | string | yes | Refund id from get_refunds — not an order id |
No output schema declared.
No examples provided.
hub_uninstall_extension Uninstall extension ~203
Uninstall an extension from the company. Takes the `extensionId` from get_installed_extensions, never a name. CONFIRM WITH THE MERCHANT BEFORE CALLING, naming the extension: the install record is deleted for good — there is NO undo from here, and re-installing does not bring the extension’s own settings back. It also removes what the extension added to the cabinet (its menu entries and detail-page blocks disappear for every user) and runs the extension’s own teardown: WooCommerce stops syncing the store, Vendara and Zapier are disabled, TIMEmSYSTEM’s settings are deleted, Custom Payment queues a final invoice for the transactions already processed. Orders, products and customers that came in through the extension are NOT deleted. If the merchant only wants to stop using it for a while, tell them there is no pause — uninstall is the only option.
| Name | Type | Req | Description |
|---|---|---|---|
| extensionId | string | yes | extensionId from get_installed_extensions — not a name |
No output schema declared.
No examples provided.
hub_unlink_modifier_from_category Stop asking a modifier on a category ~104
Stop asking a modifier in one category. The modifier itself survives and keeps working everywhere else — use delete_modifier to remove it entirely. Takes the LINK id from get_category_modifiers, not the modifier id. If the category inherits the same modifier from a parent, the till keeps asking it; unlink it from the parent instead.
| Name | Type | Req | Description |
|---|---|---|---|
| categoryModifierId | string | yes | Link id from get_category_modifiers — the link, NOT the modifier and NOT the category |
No output schema declared.
No examples provided.
hub_update_category Update category ~226
Rename a category, change its description or image, move it under a different parent, or set its sortOrder. Takes the category id from get_categories, never a name. Only the fields you pass are changed. parentId can only MOVE the category under another one; making an existing subcategory top-level again is not supported here, and neither is it in the cabinet. A category synced from an integration (WooCommerce and the like) is read-only and will be refused — it has to be changed in that platform. This never touches which products are in the category; that lives on the product (update_product, categoryIds).
| Name | Type | Req | Description |
|---|---|---|---|
| categoryId | string | yes | Category id from get_categories — not a name |
| description | string | – | – |
| image | string | – | Image URL or "lucide:<icon>" reference |
| name | string | – | – |
| parentId | string | – | New parent id from get_categories. Cannot be the category itself or one of its own subcategories |
| sortOrder | number | – | Position among its siblings, lowest first |
No output schema declared.
No examples provided.
hub_update_category_modifier Change a modifier’s rules on a category ~204
Change how a modifier is asked in ONE category — required, min, max, order — leaving every other category alone. Omit a field to leave it as it is; pass null to min or max to CLEAR that limit. The two are different, so be deliberate. The platform tidies the combination and reports what it actually stored: turning required on sets a minimum of 1, any minimum of 1 or more turns required on, and a "Pick one" modifier keeps no min or max at all. Read the result rather than assuming your input was kept. required: false together with a minimum of 1 or more is a contradiction and is refused.
| Name | Type | Req | Description |
|---|---|---|---|
| categoryModifierId | string | yes | Link id from get_category_modifiers — the link, NOT the modifier and NOT the category |
| max | – | – | null clears the cap |
| min | – | – | null clears the minimum |
| required | boolean | – | – |
| sortOrder | integer | – | – |
No output schema declared.
No examples provided.
hub_update_customer Update customer ~151
Change contact details on an existing customer. Takes the customer ID from get_customers, never a name. Only the fields you pass are changed, but an address you pass REPLACES the stored one whole — read it back with get_customer first and resend the parts that should stay. Notes are not editable here: use add_customer_note.
| Name | Type | Req | Description |
|---|---|---|---|
| billing | object | – | Replaces the stored billing address |
| customerId | string | yes | Customer id from get_customers — not a name |
| string | – | – | |
| firstName | string | – | – |
| lastName | string | – | – |
| phone | string | – | – |
| shipping | object | – | Replaces the stored shipping address |
No output schema declared.
No examples provided.
hub_update_modifier Edit modifier ~186
Rename a modifier and/or REPLACE its whole choice list. Passing choices is a full replacement: whatever you send becomes the list and anything you leave out is DELETED. Read get_modifier first and send the complete set back, keeping each choice’s id so prices and till history stay attached. To change one choice, use update_modifier_choice instead — it is safer and cannot drop the others. selectionType and allowQuantity cannot be changed; a modifier that needs a different kind of answer has to be created fresh. Renaming alone never breaks a rule; replacing choices can, and is refused with an explanation if it would.
| Name | Type | Req | Description |
|---|---|---|---|
| choices | array | – | The COMPLETE new choice list. Omitting this leaves the choices untouched |
| modifierId | string | yes | Modifier id from get_modifiers |
| name | string | – | New name. Must stay unique for the merchant, ignoring case |
No output schema declared.
No examples provided.
hub_update_modifier_choice Edit a choice ~196
Change one choice — its name, price, whether it is pre-selected, or where it is sold. Everything you leave out stays as it is. unavailableOutletIds is the exception list and REPLACES the stored one: pass [] to make the choice available everywhere again. Marking a choice unsold somewhere can be refused if a category requires more choices than would remain available at every outlet.
| Name | Type | Req | Description |
|---|---|---|---|
| choiceId | string | yes | Choice id from get_modifier |
| defaultQuantity | integer | – | – |
| isDefault | boolean | – | – |
| modifierId | string | yes | Modifier id from get_modifiers |
| name | string | – | – |
| price | string | – | New extra charge, e.g. "0.90". Pass "0" to make it free |
| sortOrder | integer | – | – |
| unavailableOutletIds | array | – | REPLACES the exception list. [] = sold at every outlet |
No output schema declared.
No examples provided.
hub_update_outlet Update outlet ~236
Change the details of one outlet. Takes the outlet id from get_outlets, never a name. Only the fields you pass are changed; the rest are left alone. Renaming is safe and takes effect everywhere, including past orders and reports — they store the outlet id and look the name up. Country cannot be changed here: it belongs to the company. An alias that is already set cannot be changed either and the attempt is refused. Stripe account linking is not editable from here.
| Name | Type | Req | Description |
|---|---|---|---|
| address | string | – | Street address |
| address2 | string | – | Unit, suite or floor |
| alias | string | – | Only settable while it is still empty |
| city | string | – | – |
| name | string | – | New outlet name |
| outletId | string | yes | Outlet id from get_outlets — not a name |
| phone | string | – | – |
| postCode | string | – | ZIP / postal code |
| state | string | – | State or province |
| taxId | string | – | Business tax number printed on this outlet’s receipts (BN / GST / HST / VAT / EIN) |
No output schema declared.
No examples provided.
hub_update_product Update product ~240
Change fields on an existing product. Takes the product ID — get it from get_products, never guess. Only the fields you pass are changed. Prices are HUMAN strings like "24.99". Variant fields (price, sku, barcode): for a product with several variants use `variants` with the ids from get_products; plain `price`/`sku`/`barcode` work only when there is exactly one variant.
| Name | Type | Req | Description |
|---|---|---|---|
| barcode | string | – | New barcode, only for a single-variant product |
| categoryIds | array | – | – |
| description | string | – | – |
| name | string | – | – |
| outletIds | array | – | – |
| price | string | – | New price, only for a single-variant product |
| productId | string | yes | Product id from get_products — not a name |
| shortDescription | string | – | – |
| sku | string | – | New SKU, only for a single-variant product |
| status | string | – | e.g. "active" or "draft" |
| variants | array | – | Per-variant changes; ids and labels come from the variants list in get_products |
No output schema declared.
No examples provided.
hub_update_purchase_order Edit purchase order ~314
Rewrite an order that has not been sent yet. ONLY works while it is `suggested` or `draft` — a sent or received order is refused, because the supplier already has it. This REPLACES the whole order: the lines and charges you pass become the order, and anything you leave out is dropped. Read it with get_purchase_order first and send the full set back. This is also how a suggestion is ACCEPTED: editing a `suggested` order turns it into a `draft` and gives it its PO number. To accept one unchanged, pass its existing lines back verbatim.
| 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 | – | – |
| lines | array | yes | The complete new set of lines |
| notes | string | – | – |
| outletId | string | yes | Outlet id the goods will be received into |
| purchaseOrderId | string | yes | Purchase order id from get_purchase_orders — not a PO number |
| shippingFee | string | – | Shipping charged on the order, e.g. "18.00" |
| supplierId | string | yes | Supplier id — normally the order’s current supplier |
No output schema declared.
No examples provided.
hub_update_role Update role ~282
Change what a role allows, or rename it. This is the tool for "let cashiers give discounts" or "stop them seeing the reports" — it changes things for EVERY person on that role at once, so name them from get_roles when you confirm. 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. Grant and revoke by permission id: grant ids from get_permissions, revoke ids from the role’s granted list in get_roles. Permissions you do not mention are left exactly as they are. You cannot edit the role you are signed in under — the cabinet locks it too, because it decides your own powers. Ask someone on another role. To move one person instead of changing the role, use assign_role.
| Name | Type | Req | Description |
|---|---|---|---|
| grantPermissionIds | array | – | Permission ids to switch ON |
| name | string | – | New name for the role |
| revokePermissionIds | array | – | Permission ids to switch OFF |
| roleId | string | yes | Role id from get_roles |
No output schema declared.
No examples provided.
hub_update_supplier Update supplier ~197
Change one supplier’s details. Only the fields you pass change; the rest are left alone, and a blank string is ignored rather than blanking the stored value. Renaming is safe — past purchase orders store the id and look the name up. A name already used by another supplier of this company is refused. This does NOT change item costs: those live on the supplier–item link, so use link_supplier_items to re-price.
| Name | Type | Req | Description |
|---|---|---|---|
| address1 | string | – | – |
| address2 | string | – | – |
| city | string | – | – |
| contactEmail | string | – | – |
| contactName | string | – | – |
| country | string | – | – |
| name | string | – | – |
| notes | string | – | – |
| phone | string | – | – |
| postCode | string | – | – |
| state | string | – | – |
| supplierId | string | yes | Supplier id from get_suppliers — not a name |
No output schema declared.
No examples provided.
hub_update_tax_group Update tax group ~223
Rename a tax group, make it the standard one, or change the ORDER its rates are charged in. Takes the tax group id from get_taxes, never a name. Order matters for money: a compounding rate is charged on the running total including everything above it, so reordering changes what customers pay. rateIdsInOrder must list exactly the rate ids already in the group, once each — it reorders, it never adds or removes. Use add_tax_rate_to_group / remove_tax_rate_from_group for that. CONFIRM WITH THE MERCHANT before reordering or changing the standard group. Sales already rung up are NOT recalculated — this only affects sales from now on.
| Name | Type | Req | Description |
|---|---|---|---|
| isStandard | boolean | – | Make this the company default group |
| name | string | – | New name for the group |
| rateIdsInOrder | array | – | Every rate id currently in the group, in the new charging order. A permutation, nothing else |
| taxGroupId | string | yes | Tax group id from get_taxes — not a name |
No output schema declared.
No examples provided.
hub_update_tax_rate Update tax rate ~271
Change a tax rate’s name or its percentage. Takes the tax rate id from get_taxes, never a name. THE RATE IS SHARED: this changes EVERY tax group that lists it, not just the one the merchant was talking about. Call get_taxes first, tell them exactly which groups are affected, and get an explicit yes. If they only meant one group, the answer is a separate rate via create_tax_rate, not this tool. percentage sets the same value at every outlet. perOutlet REPLACES the stored per-outlet list whole — an outlet you leave out STOPS charging this rate, so read the current values back with get_taxes and resend every outlet that should keep charging. Sales already rung up are NOT recalculated — this only affects sales from now on. Reports and receipts for past sales keep the old rate.
| Name | Type | Req | Description |
|---|---|---|---|
| name | string | – | New name for the rate |
| 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 | – | New percentage at every outlet, e.g. 13 for 13% |
| taxRateId | string | yes | Tax rate id from get_taxes — not a name |
No output schema declared.
No examples provided.
hub_update_user Update team member ~223
Change a team member's own details: name, phone, till PIN, and which outlets they work at. Takes the userId from get_team, never a name. Only the fields you pass change, but outletIds REPLACES their whole outlet list — read it back from get_team first and resend the ones that should stay, or you will quietly cut someone off from a location. Email cannot be changed here at all (the sign-in identity is not rotated, so the old address would keep working) — the merchant has to remove and re-invite the person. This tool does NOT change permissions: for that use assign_role.
| Name | Type | Req | Description |
|---|---|---|---|
| firstName | string | – | – |
| lastName | string | – | – |
| outletIds | array | – | Replaces the outlets they may work at, ids from get_outlets. Omit to leave untouched |
| phone | string | – | – |
| pincode | string | – | New till PIN, 4 to 6 digits |
| userId | string | yes | User id from get_team — not a name |
No output schema declared.
No examples provided.
hub_upload_media Upload images ~167
Store image files from public URLs in the media library so the merchant can use them later. Returns the stored URL of each file. JPEG/PNG/WebP/GIF, up to 20MB each. This ONLY stores the files — it attaches them to nothing. If the merchant wants a photo ON A PRODUCT, use add_product_images instead: it uploads AND attaches in one step, and doing it here first would upload the same picture twice. Use this one when they just want the file kept — a logo, a banner, a picture for later. A file uploaded here may not appear on the cabinet's Media screen, which is fed by a separate service; the file is stored and its URL works regardless.
| Name | Type | Req | Description |
|---|---|---|---|
| imageUrls | array | yes | Public URLs of the images to store |
No output schema declared.
No examples provided.
list_packs List packs ~33
Every tool pack with its product, description, tool count and whether it is allowed for this connection and listed right now.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
switch_company Switch company ~43
Choose the company Hub tools act on, by id or name (get_connection lists them). Remembered on this connection.
| Name | Type | Req | Description |
|---|---|---|---|
| company | string | yes | Company id or name. |
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.