Everything AI agents need to use SysPOS MCP tools
| Key format | syspos_<64 hex chars> |
| Claude connector | OAuth 2.1 (DCR + PKCE) — paste your syspos_... key on the login page when connecting https://pos-mcp.syspos.ae/mcp |
| Standard | Authorization: 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 |
| Scoping | Each key is tied to a customer (tenant) and optionally limited to specific locations and tools |
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
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"
}
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"
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
| Status | Meaning | Example Response |
|---|---|---|
| 200 | Success | JSON result data |
| 400 | Bad request / Auth error | { "error": "Invalid API key" } |
| 404 | Tool not found | { "error": "Tool 'x' not found", "available": [...] } |
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, …).
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"data": [
{
"id": 11,
"name": "Iced Latte",
"actual_price": 18,
"category_id": 3,
"is_archive": 0
}
],
"pagination": {
"current_page": 1,
"page_limit": 10
}
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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) |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
Calls GET /api/products/:id on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | required | |
| is_archive | string | optional | |
| loc | string | optional |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| k | string | required | If shorter than 2 after trim, returns { data: [] } |
| loc | string | optional | |
| limit | number | optional |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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. |
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
]
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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. |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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. |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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. |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | required |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| product_ids | array<string> | optional | Csv or number[]. Missing → {} |
| loc | string | optional | |
| breakdown | enum: 1, true | optional | |
| per_location | enum: 1, true | optional |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | required |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
Calls GET /api/products/units on https://app.syspos.ae. Safety: read. customer_id is taken from the MCP session — do not send it.
No additional parameters — only the Authorization: Bearer header is required.
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
No additional parameters — only the Authorization: Bearer header is required.
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | required | |
| is_archive | string | optional | |
| loc | string | optional |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| loc | string | optional | |
| addon | string | optional | |
| cat | string | optional | |
| k | string | optional | |
| page_limit | number | optional | |
| current_page | number | optional |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| loc | number | optional | Default req.user.location_id. 400 if neither present. |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| location_id | number | optional | |
| page_limit | number | optional | |
| current_page | number | optional |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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. |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | required | |
| is_archive | string | optional | "0" un-archives. Anything else archives. |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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). |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| product_ids | array<number> | required | |
| location_ids | array<number> | required | |
| mode | enum: add, replace | optional | Anything other than replace is treated as add. |
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
]
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| product_ids | array<number> | required | |
| adjustment_direction | enum: add, subtract | required | |
| value | number | required | |
| adjustment_type | enum: fixed, percentage | optional | |
| location_id | string | optional |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| product_ids | array<number> | required | |
| adjustment_direction | enum: add, subtract | required | |
| value | number | required | |
| adjustment_type | enum: fixed, percentage | optional | |
| channel_id | string | optional |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| products | array<object> | required |
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
]
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| productIds | array<number> | required | camelCase. Not product_ids. |
| taxId | number | required | camelCase. Not tax_id. |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | required | product_materials.id |
| qty | number | optional | |
| price | number | optional | |
| wastage | number | optional |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| productId | number | required | |
| attachment | string | required | Single file. Multer upload.single("attachment"). |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | optional | Unused in SQL |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| 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 |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| id | number | required |
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
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}
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.
| Parameter | Type | Description | |
|---|---|---|---|
| loc | number | optional | Default session location_id |
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"
}'
{
"message": "JSON body returned by the matching app.syspos.ae product API"
}