Skip to main content
Glama
README.md
# sellerchamp-mcp

FastMCP HTTP server exposing SellerChamp inventory management as Model Context Protocol (MCP) tools. A single daemon process serves multiple Claude clients — Claude Desktop, Claude Code, and OpenClaw — simultaneously over a local HTTP endpoint.

---

## Architecture

The service uses a hybrid data model designed to balance freshness against rate limits.

```
MCP Clients (Claude Desktop / Claude Code / OpenClaw)
        |
        v
  HTTP POST 127.0.0.1:18790/mcp
        |
        v
  FastMCP Router (stateless HTTP, JSON responses)
        |
   +---------+----------+
   |                    |
   v                    v
SQLiteReader         SellerChampAPI
(cached reads)       (live API)
   |                    |
sellerchamp_         - Single-item lookups
inventory.db         - All writes
(updated by          - Bulk operations
 db-sync job)
```

**Bulk reads** — served from a local SQLite database maintained by a companion `db-sync` service (daily full sync at 3 AM, orders refresh every 2 hours). Tools that default to cached reads accept a `source` parameter: `"cached"`, `"live"`, or `""` (auto).

**Single-item lookups and all writes** — always routed to the live SellerChamp API.

**Rate limiter** — sliding window shared with the db-sync service. Interactive calls: 90 req/60s. Bulk calls: 60 req/60s. The server-side limit is 120 req/60s. 429 responses are handled by the pacer, not urllib3 retries, to avoid feedback loops. 5xx errors retry with exponential backoff (up to 3 times).

**Confirmation gates** — `sellerchamp_delete_product` requires `confirm=True`. Bulk update tools require `confirm=True` for batches larger than 50 items.

---

## Tool Inventory

24 tools across four categories.

### Read tools

| Tool | Source | Description |
|------|--------|-------------|
| `sellerchamp_get_marketplace_accounts` | cached | All connected marketplace accounts (Amazon, eBay, Shopify, etc.) with account IDs |
| `sellerchamp_get_orders` | cached | Paginated orders with filtering by status, marketplace, and date range |
| `sellerchamp_get_order` | live | Single order by ID with full details, shipping address, and tracking |
| `sellerchamp_get_products` | cached | Paginated product catalog with filtering by SKU, ASIN, UPC, marketplace, or tag |
| `sellerchamp_get_products_compact` | cached | Products with essential fields only (SKU, title, price, quantity, status) |
| `sellerchamp_get_product` | live | Single product by SKU or product ID with variants, images, and inventory locations |
| `sellerchamp_find_missing_listings` | cached | SKUs present on one marketplace but absent from another |
| `sellerchamp_find_crosslist_candidates` | cached | Products matching per-marketplace status filters across the full catalog |
| `sellerchamp_get_variants` | live | All variants (sizes, colors, etc.) for a product |
| `sellerchamp_get_inventory_locations` | live | Warehouse bin locations for a product |
| `sellerchamp_get_manifests` | live | Listing collections, optionally filtered by marketplace account |
| `sellerchamp_sync_status` | cache | Last db-sync timestamp and status |
| `sellerchamp_pending_shipments` | cache | Unshipped paid orders from the last 14 days with inventory age |
| `sellerchamp_bad_handling_times` | cache | Amazon FBM listings with handling time under 3 days or missing |
| `sellerchamp_handling_time_summary` | cache | Handling time distribution across all scanned Amazon listings |

### Write tools

| Tool | Description |
|------|-------------|
| `sellerchamp_update_order` | Update tracking number, carrier, or notes on an order |
| `sellerchamp_acknowledge_order` | Mark an order as received and in processing |
| `sellerchamp_update_product` | Update pricing, quantity, title, description, condition, or shipping fields by product ID |
| `sellerchamp_set_product_pricing` | Set min/max/retail/cost price by SKU (resolves product ID automatically) |
| `sellerchamp_set_product_quantity` | Set available quantity by SKU |
| `sellerchamp_update_variant` | Update pricing or inventory on a specific product variant |

### Bulk write tools

| Tool | Limit | Description |
|------|-------|-------------|
| `sellerchamp_bulk_update_products` | 1,000 items | Update multiple products in one call; requires `confirm=True` for batches over 50 |
| `sellerchamp_bulk_update_inventory` | 1,000 items | Update inventory quantities across locations; requires `confirm=True` for batches over 50 |

### Destructive tools

| Tool | Description |
|------|-------------|
| `sellerchamp_delete_product` | Delete a product permanently; requires `confirm=True` |

---

## Connecting a Client

The server binds to `127.0.0.1:18790` and runs as a macOS launchd daemon. Any MCP-compatible client on the same machine can connect with:

```json
{
  "mcpServers": {
    "sellerchamp": {
      "url": "http://127.0.0.1:18790/mcp"
    }
  }
}
```

Add this block to Claude Desktop's `claude_desktop_config.json` or to a Claude Code project's MCP configuration. OpenClaw and other HTTP MCP clients use the same URL.

---

## Setup

**Prerequisites:** Python 3.12+, a SellerChamp account with API access.

```bash
git clone https://github.com/WowWashington/sellerchamp-mcp.git
cd sellerchamp-mcp
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

Create a `.env` file (do not commit):

```env
SELLERCHAMP_API_TOKEN=your_token_here
SQLITE_DB_PATH=/path/to/sellerchamp_inventory.db
MCP_HOST=127.0.0.1
MCP_PORT=18790
```

Run directly:

```bash
python server.py
```

**Production (macOS launchd):** install a plist at `~/Library/LaunchAgents/com.sellerchamp-mcp.plist` pointing to `python server.py`. Logs land at `~/Library/Logs/sellerchamp-mcp/`.

**SQLite cache:** the `SQLITE_DB_PATH` database is maintained by a separate `sellerchamp-db-sync` companion service. Without it, the server falls back to the live API for all reads. The service logs a warning at startup if the cache file is not found.

---

## Security

- **Localhost-only binding** — the server listens on `127.0.0.1` only. No network exposure, no authentication required.
- **Confirmation gates** — destructive and bulk operations require an explicit `confirm=True` parameter. A first call without it returns a description of what would happen.
- **Read-only SQLite connections** — `PRAGMA query_only=ON` prevents accidental writes. WAL mode allows safe concurrent reads while the sync service writes.
- **Parameterized queries** — all SQLite queries use bound parameters; no string interpolation of user input.
- **No secrets in code** — API token is read from environment at startup.

---

## Stack

- [FastMCP](https://github.com/jlowin/fastmcp) — MCP server framework with Streamable HTTP transport
- [requests](https://docs.python-requests.org/) — SellerChamp API client
- SQLite (stdlib) — local inventory cache
- Python 3.12