andriistakhov

SalesBox MCP Server

Community andriistakhov
Updated

MCP server wrapping the SalesBox public API (/openapi/*)

SalesBox MCP Server

An MCP server that wraps the SalesBox public API (https://prod.salesbox.me). It exposes the /openapi/* endpoints as MCP tools so Claude / any MCP client can manage cashbacks, categories, chats, SEO, custom fields, discounts, and filters.

It ships with two transports:

  • Streamable HTTP (default) — for running on a VPS and connecting remotely.
  • stdio — for local MCP clients (Claude Desktop, etc.).

Rate limits (100 req/min per company; upload 200/hour) are handled automatically: on HTTP 429 the server reads Retry-After and retries.

1. Prerequisites

  • A SalesBox OpenAPI token — get it from the support bot.
  • Node.js 20+ or Docker.

2. Configure

cp .env.example .env
# edit .env — set SALESBOX_API_TOKEN and (recommended) MCP_AUTH_TOKEN

Key settings (see .env.example for all):

Var Purpose
SALESBOX_API_TOKEN Default SalesBox token. Clients can override per-request via the X-Salesbox-Token header.
MCP_TRANSPORT http (VPS) or stdio (local).
PORT / HOST HTTP listen address.
MCP_AUTH_TOKEN Shared secret guarding /mcp. Clients send Authorization: Bearer <token>. Set this if the port is public.

3. Run locally

npm install
npm run build
npm start            # HTTP on :3000
# or
npm run start:stdio  # stdio

Health check: curl http://localhost:3000/health

4. Deploy to a Hetzner VPS

Two options — Docker (recommended) or systemd.

A note on the SDK security default

The Streamable HTTP transport validates the Origin header on requests it processes; keeping the container bound to 127.0.0.1 and terminating TLS at a reverse proxy (below) is the safe setup. Always also set MCP_AUTH_TOKEN.

Quickest path — one-shot script (Docker + Caddy + firewall)

On a fresh Ubuntu Hetzner box, with a DNS A record mcp.yourdomain.com → server IP:

# 1. Authenticate to GitHub once (private repo), then clone
gh auth login            # or set up an SSH deploy key
git clone https://github.com/andriistakhov/salesbox-mcp.git /opt/salesbox-mcp
cd /opt/salesbox-mcp

# 2. Run the installer with your domain
sudo bash deploy/setup.sh mcp.yourdomain.com

The script installs Docker + Caddy, generates .env (multi-tenant: empty SALESBOX_API_TOKEN, a random MCP_AUTH_TOKEN it prints for you), builds and starts the container, configures Caddy for automatic HTTPS, and opens the firewall (22/80/443). Endpoint: https://mcp.yourdomain.com/mcp.

To redeploy after pushing new code: sudo bash deploy/update.sh.

The manual steps below do the same thing by hand.

Option A — Docker + Caddy (auto HTTPS)

On a fresh Hetzner Cloud Ubuntu box:

# 1. Install Docker
curl -fsSL https://get.docker.com | sh

# 2. Get the code
git clone <your-repo-url> /opt/salesbox-mcp
cd /opt/salesbox-mcp
cp .env.example .env && nano .env   # set tokens

# 3. Build & run (binds to 127.0.0.1:3000 by compose default)
docker compose up -d --build
docker compose logs -f

Put TLS in front with Caddy (gets a Let's Encrypt cert automatically):

apt install -y caddy
# Point an A record: mcp.yourdomain.com -> <VPS IP>, then:
cp deploy/Caddyfile /etc/caddy/Caddyfile
nano /etc/caddy/Caddyfile      # replace mcp.example.com with your domain
systemctl restart caddy

Your endpoint is now https://mcp.yourdomain.com/mcp.

Firewall (Hetzner Cloud firewall or ufw): allow only 22, 80, 443. Do not expose port 3000 publicly — Caddy proxies to it over localhost.

ufw allow 22,80,443/tcp && ufw enable

Option B — systemd (no Docker)

# Install Node 22
curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && apt install -y nodejs

# Code + build
git clone <your-repo-url> /opt/salesbox-mcp
cd /opt/salesbox-mcp
npm ci && npm run build
cp .env.example .env && nano .env

# Dedicated user + service
useradd --system --no-create-home salesbox || true
chown -R salesbox:salesbox /opt/salesbox-mcp
cp deploy/salesbox-mcp.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now salesbox-mcp
systemctl status salesbox-mcp

Then front it with Caddy/Nginx for TLS the same way as Option A.

5. Connect a client

Claude Code / any HTTP MCP client

{
  "mcpServers": {
    "salesbox": {
      "type": "http",
      "url": "https://mcp.yourdomain.com/mcp",
      "headers": {
        "Authorization": "Bearer <MCP_AUTH_TOKEN>",
        "X-Salesbox-Token": "<optional-per-client-salesbox-token>"
      }
    }
  }
}

X-Salesbox-Token is only needed if you did not bake SALESBOX_API_TOKEN into .env, or you want a different token per client.

Claude Desktop (stdio, local)

{
  "mcpServers": {
    "salesbox": {
      "command": "node",
      "args": ["/opt/salesbox-mcp/dist/index.js"],
      "env": {
        "MCP_TRANSPORT": "stdio",
        "SALESBOX_API_TOKEN": "<your-token>"
      }
    }
  }
}

Quick manual test

curl -X POST https://mcp.yourdomain.com/mcp \
  -H "Authorization: Bearer <MCP_AUTH_TOKEN>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

6. Tools

Grouped by resource. Every tool accepts an optional token argument to override the server token for that call.

  • Cashbacksalesbox_cashback_list, _get, _create, _update, _delete
  • Categoriessalesbox_categories_list, salesbox_category_get, _create_many, _update_many, _delete, _set_ordering
  • Category custom fieldssalesbox_category_custom_fields_get, _set, salesbox_category_custom_field_clear
  • Category SEOsalesbox_category_seo_get, _set, _clear_field, salesbox_categories_seo_list, _seo_update_many, _seo_delete_many
  • Chatssalesbox_chats_by_user, salesbox_chat_send_message
  • Companysalesbox_company_custom_fields_get, _set, salesbox_company_custom_field_clear, salesbox_company_seo_get, _set, _clear_field
  • Custom field definitionssalesbox_custom_field_definitions_list, _definition_create, _definition_update, _definition_delete
  • Discountssalesbox_discounts_list, salesbox_discount_get, _create, _update, _delete, salesbox_discounts_delete_many
  • Filterssalesbox_filters_list, _create_many, _update_many, _delete_many
  • Escape hatchsalesbox_raw_request — call any /openapi/* endpoint not covered above (the provided OpenAPI was large; use this for offers, orders, users, uploads, etc.).

The salesbox_raw_request tool covers any endpoint that doesn't have a dedicated wrapper yet. If you want first-class tools for more resources (offers, orders, users, S3 upload…), the pattern in src/tools.ts is easy to extend.

Project layout

src/
  index.ts     entrypoint (http + stdio transports)
  server.ts    builds the MCP server
  tools.ts     all tool definitions
  client.ts    SalesBox HTTP client (auth, 429 retry)
  config.ts    env-based config
  context.ts   per-request token (X-Salesbox-Token)
Dockerfile, docker-compose.yml
deploy/salesbox-mcp.service, deploy/Caddyfile

MCP Server · Populars

MCP Server · New

    agent-room-alkl

    Agent Room

    Multi-agent collaboration rooms for Claude Code, Cursor, Codex & Gemini — distributed dev, code review, PR handoff, FE↔BE integration. MCP-native, self-hostable.

    Community agent-room-alkl
    Last-emo-boy

    Rikune

    MCP Server

    Community Last-emo-boy
    koul777

    PR MCP Builder

    PR MCP Builder - 공공기관 규정 MCP 빌더

    Community koul777
    TrueClicks

    Google Ads MCP (Node.js) - by TrueClicks

    The easiest to use Google Ads MCP. Connect Google Ads with Claude's AI in seconds and let it analyze your campaigns. You'll be surprised how well the AI knows PPC! This is the only Google Ads MCP where you won't need to create developer tokens or OAuth credentials.

    Community TrueClicks
    whuanle

    EasyTouch

    一个跨平台的系统自动化操作工具,支持鼠标、键盘、屏幕、窗口、系统资源等多种操作。支持 CLI 和 MCP 两种使用方式。

    Community whuanle