SysPOS MCP Server — API Docs

Everything AI agents need to use SysPOS MCP tools

← Back to Home

Authentication

Two ways in: the Claude custom connector uses OAuth 2.1 (you paste your key once on a login page); every other client sends the raw key as an Authorization: Bearer <key> header. Both resolve to the same tenant, scopes, and revocation.
Key formatsyspos_<64 hex chars>
Claude connectorOAuth 2.1 (DCR + PKCE) — paste your syspos_... key on the login page when connecting https://pos-mcp.syspos.ae/mcp
StandardAuthorization: Bearer syspos_... HTTP header (Claude Desktop config, Cursor, SDKs, curl, n8n)
Escape hatch?api_key=syspos_... on the URL — for clients that cannot set a Bearer header
Legacy fallback"api_key": "syspos_..." inside the JSON body / tool arguments
ScopingEach key is tied to a customer (tenant) and optionally limited to specific locations and tools

How to Call Tools

Option 1: Claude.ai custom connector (no code)

In Claude → Settings → Connectors → Add custom connector:

Name:                  SysPOS Product Tools
Remote MCP server URL: https://pos-mcp.syspos.ae/mcp
OAuth Client ID/Secret: (leave blank)

→ Add → Connect → paste your syspos_... key → Authorize
OAuth is automatic: Claude self-registers (DCR + PKCE) and walks you through a login page where you paste your syspos_... key. The key is exchanged for a short-lived access token that Claude refreshes on its own — it never appears in the chat.

Option 2: REST API (any HTTP client)

Simple HTTP POST — works with curl, fetch, n8n, Make, anything.

POST https://pos-mcp.syspos.ae/api/call
Authorization: Bearer syspos_your_key_here
Content-Type: application/json

{
  "tool": "list_products"
}

Option 3: MCP Protocol — SSE (Claude Desktop, Cursor, custom agents)

Use the remote MCP URL plus a Bearer header — the standard MCP-over-HTTP shape:

# MCP endpoint URL
https://pos-mcp.syspos.ae/sse

# Claude Desktop / Cursor / generic MCP client config
{
  "mcpServers": {
    "syspos": {
      "url": "https://pos-mcp.syspos.ae/sse",
      "headers": { "Authorization": "Bearer syspos_your_key_here" }
    }
  }
}

# Claude Code CLI
claude mcp add syspos --transport sse https://pos-mcp.syspos.ae/sse \
  --header "Authorization: Bearer syspos_your_key_here"
Tip: The Bearer header is sent once on the SSE connection and is automatically used for every tool call on that session — no need to pass an api_key argument.

Machine-Readable Docs for Agents

AI agents can fetch full tool schemas as JSON — no HTML parsing needed:

# Full docs with parameters, types, and example responses
curl https://pos-mcp.syspos.ae/api/docs

# Tool list with full parameter schemas
curl https://pos-mcp.syspos.ae/api/tools

Error Handling

StatusMeaningExample Response
200SuccessJSON result data
400Bad request / Auth error{ "error": "Invalid API key" }
404Tool not found{ "error": "Tool 'x' not found", "available": [...] }

Agent Integration Guide

System prompt template

Add this to your agent's instructions:

You have access to SysPOS product tools.

API endpoint:  https://pos-mcp.syspos.ae/api/call
Method:        POST
Content-Type:  application/json
Authorization: Bearer syspos_your_key_here

Rules:
- Use list_products to fetch the catalog. Pass page_limit if you need more than the default page size.
- Do not send customer_id. Tenant comes from the MCP API key.
- Create/update bodies match the dashboard product payload (name, prices, location_prices, modifiers, …).
Do send the API key as Authorization: Bearer syspos_... on every request.
Do use list_products to fetch the catalog; pass page_limit for more rows.
Note: /api/call is a regular HTTP POST endpoint; /sse is the MCP Server-Sent-Events stream — use one or the other, not both.

Tool Reference

Table of Contents

Products

list_products_web

Calls GET /api/products/webProducts on https://app.syspos.ae. Used by frontend-v2 getProducts. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
loc string optional Location id, csv, All, or 0. Default session location_id.
page number optional
limit number optional >= 10000 returns all
k string optional Name LIKE
addon enum: 0, 1 optional
category_id string optional Csv ids or All
cat string optional Csv category names. Used only if category_id absent/All
brand_id number optional
label_id number optional
channel_id number optional
is_archive string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "list_products_web"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

list_products

Calls GET /api/products on https://app.syspos.ae. Used by frontend-v2 getAddOnList, getSearchProduct. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
loc string optional
addon string optional 1 = add-ons
cat string optional Category name LIKE, or All
k string optional
brand_id number optional
page_limit number optional
current_page number optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "list_products"
}'

Example Response

{
  "data": [
    {
      "id": 11,
      "name": "Iced Latte",
      "actual_price": 18,
      "category_id": 3,
      "is_archive": 0
    }
  ],
  "pagination": {
    "current_page": 1,
    "page_limit": 10
  }
}

list_products_pos

Calls GET /api/v2/products on https://app.syspos.ae. Used by web-pos products, productsAddon. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
k string optional
addon string optional
cat string optional
page_limit number optional
current_page number optional
adm string optional Non-master: unlocks loc override
loc number optional Only used when adm is set (non-master)

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "list_products_pos"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_product

Calls GET /api/products/:id on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required
is_archive string optional
loc string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_product",
  "id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

search_products_for_assign

Calls GET /api/products/search-assign on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
k string required If shorter than 2 after trim, returns { data: [] }
loc string optional
limit number optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "search_products_for_assign",
  "k": "latte"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_products_from_ids

Calls POST /api/products/products-from-ids on https://app.syspos.ae. Used by invoice-services. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
ids array<number> required Must be an array. Empty array → empty products list.
customer_id number optional Required only when unauthenticated. Ignored when JWT present.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_products_from_ids",
  "ids": [
    11
  ]
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_update_prices_preview

Calls POST /api/products/bulk-update-prices/preview on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
product_ids array<number> required
adjustment_direction enum: add, subtract required
value number required NaN → 400
adjustment_type enum: fixed, percentage optional Anything other than fixed is percentage.
location_id string optional Location id, or "all" / null / omitted.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_update_prices_preview",
  "product_ids": [
    11
  ],
  "adjustment_direction": "example",
  "value": 1
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_update_channel_prices_preview

Calls POST /api/products/bulk-update-channel-prices/preview on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
product_ids array<number> required
adjustment_direction enum: add, subtract required
value number required
adjustment_type enum: fixed, percentage optional
channel_id string optional Channel id, or "all" / null / omitted.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_update_channel_prices_preview",
  "product_ids": [
    11
  ],
  "adjustment_direction": "example",
  "value": 1
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

match_products_by_name

Calls POST /api/products/match-by-name on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
productNames array<string> required
customer_id number required This handler reads body.customer_id (not only JWT). Gateway should inject and ignore client value.
location_id number required Non-master also filters products.location_id.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "match_products_by_name",
  "productNames": [
    11
  ],
  "customer_id": 11,
  "location_id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_product_pricing_summary

Calls GET /api/products/:id/pricing-summary on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_product_pricing_summary",
  "id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_products_recipe_costs

Also accepts the same fields on JSON body (req.query.x || req.body.x). Calls GET /api/products/recipe-costs on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
product_ids array<string> optional Csv or number[]. Missing → {}
loc string optional
breakdown enum: 1, true optional
per_location enum: 1, true optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_products_recipe_costs"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_product_materials

Calls GET /api/products/:id/materials on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_product_materials",
  "id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

verify_product_plu

Calls GET /api/products/unique-verification-plu on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
plu string optional
product_id number optional OK if the found product is this id (self).
location_id number optional Default req.user.location_id

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "verify_product_plu"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_product_units

Calls GET /api/products/units on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

No additional parameters — only the Authorization: Bearer header is required.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_product_units"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_product_tax_groups_enhanced

Calls GET /api/products/tax-groups-enhanced on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

No additional parameters — only the Authorization: Bearer header is required.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_product_tax_groups_enhanced"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_pos_product

Calls GET /api/v2/products/:id on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required
is_archive string optional
loc string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_pos_product",
  "id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

list_products_pos_list

Calls GET /api/v2/products/list on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
k string optional
addon string optional
cat string optional
page_limit number optional
records_per_page number optional Alias for page_limit
current_page number optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "list_products_pos_list"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

list_products_pos_web

Calls GET /api/v2/products/web on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
loc string optional
addon string optional
cat string optional
k string optional
page_limit number optional
current_page number optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "list_products_pos_web"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_product_modifier_ordering

Calls GET /api/v2/products/modifier-ordering on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
loc number optional Default req.user.location_id. 400 if neither present.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_product_modifier_ordering"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

get_top_saled_products

Calls GET /api/v2/products/top-saled on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
location_id number optional
page_limit number optional
current_page number optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "get_top_saled_products"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

Products (write)

create_product

Calls POST /api/products on https://app.syspos.ae. Used by frontend-v2 createProduct, createAddOn. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
name string required 400 if blank. Unique by name, or name+label when product_unique_formula includes label_id.
description string optional
localize_name string optional Sent by frontend create/update. Persist only if products.localize_name column exists (MySQL SET ?).
localize_description string optional
actual_price number optional
price number optional Ex-VAT / display price
combo_price number optional
product_cost number optional
vat number optional
discount_pct number optional Forced to 0 if missing, < 0, or > 100
stock number optional
preparation_time number optional Minutes. Frontend max 1440.
category_id array<string> optional Number, csv, or number[]. Arrays joined with comma.
label_id array<string> optional Arrays joined with comma. Frontend currently sends Number(label_id[0]).
tax_id number optional
tax_group_id string optional Stripped from product table insert. Not persisted by create/update handlers.
type string optional Category name(s). If omitted, built from category_id names.
categories array<string> optional Copied into type if type empty, then deleted before insert.
location_id array<string> optional Number, csv, or number[]. Master insert forces location_id=null on the products row; locations live in location_prices.
location_prices array<object> optional If omitted and location_id set (non-master), one row per location is built from actual_price. Update: empty array + master deletes all location rows and archives the product.
modifiers array<object> optional API expects an array. Frontend form is an object keyed by modifier_id with isChecked; client converts before POST/PUT.
replace_modifiers boolean optional true = replace all modifier links for the target locations.
modifiers_by_location string optional Update only. Keys are location ids, values are modifier arrays. If non-empty, used instead of modifiers with replace_modifiers true per location.
price_level array<object> optional Create path: saveChannelPrices(productId, price_level).
channel_price string optional Update path: saveChannelPrices uses req.body.channel_price (not price_level).
materials array<object> optional Update deletes all existing product_materials then rewrites. Omit/empty = clear.
recipes array<object> optional Update deletes all existing product_recipes then rewrites. Phantom recipes only.
addons array<string> optional JSON-stringified onto products.addons. Typically product ids.
bundle_items array<string> optional JSON-stringified onto products.bundle_items.
is_addon string optional
is_open_price string optional
is_weightage_item string optional
is_archive string optional
is_combo string optional
is_disabled string optional
is_stock_product string optional
is_auto_apply string optional
is_manual_cost string optional Stripped from product table insert. Frontend sends it.
sync_deliverect string optional
sync_otter string optional
unit_id string optional
plu string optional
sku_no string optional Trimmed. Master + empty → auto global SKU.
barcode_type string optional
barcode_value string optional
image string optional Upload path. Normalized. Overridden by web_image if both set.
web_image string optional Copied onto image, then stripped from table insert.
calories number optional
menu_sort_order number optional
base_price number optional
localized string optional
new_cost_date string optional
id number optional Frontend update mutation also puts id in the body; handler uses path param.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "create_product",
  "name": "Iced Latte"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

update_product

Calls PUT /api/products/:id on https://app.syspos.ae. Used by frontend-v2 updateProduct, updateAddOn. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required
name string required 400 if blank. Unique by name, or name+label when product_unique_formula includes label_id.
description string optional
localize_name string optional Sent by frontend create/update. Persist only if products.localize_name column exists (MySQL SET ?).
localize_description string optional
actual_price number optional
price number optional Ex-VAT / display price
combo_price number optional
product_cost number optional
vat number optional
discount_pct number optional Forced to 0 if missing, < 0, or > 100
stock number optional
preparation_time number optional Minutes. Frontend max 1440.
category_id array<string> optional Number, csv, or number[]. Arrays joined with comma.
label_id array<string> optional Arrays joined with comma. Frontend currently sends Number(label_id[0]).
tax_id number optional
tax_group_id string optional Stripped from product table insert. Not persisted by create/update handlers.
type string optional Category name(s). If omitted, built from category_id names.
categories array<string> optional Copied into type if type empty, then deleted before insert.
location_id array<string> optional Number, csv, or number[]. Master insert forces location_id=null on the products row; locations live in location_prices.
location_prices array<object> optional If omitted and location_id set (non-master), one row per location is built from actual_price. Update: empty array + master deletes all location rows and archives the product.
modifiers array<object> optional API expects an array. Frontend form is an object keyed by modifier_id with isChecked; client converts before POST/PUT.
replace_modifiers boolean optional true = replace all modifier links for the target locations.
modifiers_by_location string optional If non-empty, used instead of modifiers.
price_level array<object> optional Create path: saveChannelPrices(productId, price_level).
channel_price string optional Preferred over price_level on update.
materials array<object> optional Update deletes all existing product_materials then rewrites. Omit/empty = clear.
recipes array<object> optional Update deletes all existing product_recipes then rewrites. Phantom recipes only.
addons array<string> optional JSON-stringified onto products.addons. Typically product ids.
bundle_items array<string> optional JSON-stringified onto products.bundle_items.
is_addon string optional
is_open_price string optional
is_weightage_item string optional
is_archive string optional
is_combo string optional
is_disabled string optional
is_stock_product string optional
is_auto_apply string optional
is_manual_cost string optional Stripped from product table insert. Frontend sends it.
sync_deliverect string optional
sync_otter string optional
unit_id string optional
plu string optional
sku_no string optional Trimmed. Master + empty → auto global SKU.
barcode_type string optional
barcode_value string optional
image string optional Upload path. Normalized. Overridden by web_image if both set.
web_image string optional Copied onto image, then stripped from table insert.
calories number optional
menu_sort_order number optional
base_price number optional
localized string optional
new_cost_date string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "update_product",
  "id": 11,
  "name": "Iced Latte"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

archive_product

Calls PUT /api/products/archive_product/:id on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required
is_archive string optional "0" un-archives. Anything else archives.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "archive_product",
  "id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_archive_products

Calls POST /api/products/bulk-archive on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
product_ids array<number> required
location_id array<string> required Single id, csv, or number[]. All/empty → 400.
is_archive string optional 0 or "0" = enable (unarchive). Else disable (1).

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_archive_products",
  "product_ids": [
    11
  ],
  "location_id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

assign_product_locations

Calls POST /api/products/assign-locations on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
product_ids array<number> required
location_ids array<number> required
mode enum: add, replace optional Anything other than replace is treated as add.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "assign_product_locations",
  "product_ids": [
    11
  ],
  "location_ids": [
    11
  ]
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_update_prices

Calls POST /api/products/bulk-update-prices on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
product_ids array<number> required
adjustment_direction enum: add, subtract required
value number required
adjustment_type enum: fixed, percentage optional
location_id string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_update_prices",
  "product_ids": [
    11
  ],
  "adjustment_direction": "example",
  "value": 1
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_update_channel_prices

Calls POST /api/products/bulk-update-channel-prices on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
product_ids array<number> required
adjustment_direction enum: add, subtract required
value number required
adjustment_type enum: fixed, percentage optional
channel_id string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_update_channel_prices",
  "product_ids": [
    11
  ],
  "adjustment_direction": "example",
  "value": 1
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_update_sort_order

Calls POST /api/products/bulk-update-sort-order on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
products array<object> required

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_update_sort_order",
  "products": [
    11
  ]
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_update_tax

Calls POST /api/products/bulk-update-tax on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
productIds array<number> required camelCase. Not product_ids.
taxId number required camelCase. Not tax_id.

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_update_tax",
  "productIds": [
    11
  ],
  "taxId": 1
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

create_product_materials

Path :id is not read. product_id must be in the body. location_id and customer_id overwritten from JWT. Calls POST /api/products/:id/materials on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number optional Unused by handler
name string optional
qty number optional
product_id number required Inserted as product_materials.product_id
material_id number required
price number optional
unit string optional
wastage number optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "create_product_materials",
  "product_id": 11,
  "material_id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

edit_product_materials

Not in the 528 client list. Path :id is the product_materials row id. SQL updates qty, price, wastage only. Calls PUT /api/products/materials/:id on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required product_materials.id
qty number optional
price number optional
wastage number optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "edit_product_materials",
  "id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

upload_product_image

Calls POST /api/products/:productId/upload-image on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
productId number required
attachment string required Single file. Multer upload.single("attachment").

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "upload_product_image",
  "productId": 11,
  "attachment": "example"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

bulk_upload_product_image

Despite the name, exactly one product id per request. Calls POST /api/products/bulk-image-upload on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
productIds array<number> required JSON array or JSON string. Aliases: productsIds, product_ids, ids. Length must be 1.
attachment string required File field; JSON calls are not supported

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "bulk_upload_product_image",
  "productIds": [
    11
  ],
  "attachment": "example"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

remove_product_image

Path :id is unused. SQL uses body.id. Calls PUT /api/products/remove_image/:id on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number optional Unused in SQL

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "remove_product_image"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

update_product_availability

Calls POST /api/v2/products/availability on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
itemId string optional Product or already-prefixed PRO-{id}. Required unless product_id / item_id / modifier_item_id is sent.
item_id string optional Alias for itemId
product_id number optional Used as PRO-{id} when itemId/item_id omitted
modifier_item_id number optional Used as MOD-{id} when itemId/item_id omitted
availability enum: AVAILABLE, UNAVAILABLE, HIDDEN required Also accepted as status
status enum: AVAILABLE, UNAVAILABLE, HIDDEN optional Alias for availability
itemType string optional Empty → PRODUCT. Alias item_type.
item_type string optional
locationId number optional Default JWT location_id. Alias location_id.
location_id number optional
brandId number optional Alias brand_id
brand_id number optional
menuId string optional Grubtech menu id. Alias menu_id. Derived from location if omitted.
menu_id string optional
storeId string optional Alias store_id. Derived from location if omitted.
store_id string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "update_product_availability",
  "availability": "example"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

quick_update_product

Not in the 528 client list. Path :id unused. SQL uses body.id. No validation. Calls PUT /api/products/:id/quick on https://app.syspos.ae. Safety: write. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number optional Unused in SQL
name string optional
description string optional
menu_sort_order number optional
is_stock_product string optional
calories number optional
localize_name string optional
localize_description string optional

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "quick_update_product"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

Products (destructive)

delete_product

Soft delete: SET is_deleted = 1 Calls DELETE /api/products/:id on https://app.syspos.ae. Safety: destructive. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
id number required

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "delete_product",
  "id": 11
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}

delete_all_products

Master only. Removes products_locations for loc; archives products with no remaining locations. Calls DELETE /api/products/all on https://app.syspos.ae. Safety: destructive. customer_id is taken from the MCP session — do not send it.

Parameters

ParameterTypeDescription
loc number optional Default session location_id

Example Request

curl -X POST https://pos-mcp.syspos.ae/api/call \
  -H "Authorization: Bearer syspos_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "tool": "delete_all_products"
}'

Example Response

{
  "message": "JSON body returned by the matching app.syspos.ae product API"
}
SysPOS MCP Server