squarespace-mcp
# squarespace-mcp
An [MCP](https://modelcontextprotocol.io) server that exposes the **Squarespace Commerce API** as tools an LLM agent can call — read products, inventory, orders, transactions, and customer profiles, and (with care) adjust inventory and fulfill orders.
- **Stack:** Python + [FastMCP](https://github.com/jlowin/fastmcp) 2.x/3.x
- **Transport:** stdio
- **API:** Squarespace Commerce APIs (`https://api.squarespace.com`), Bearer-key auth
## Setup
```bash
# with uv (recommended)
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
# or plain pip
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env # then fill in SQUARESPACE_API_KEY
```
Get an API key from **Squarespace → Settings → Developer API keys**. The key is
read from the environment (or a local `.env`) **lazily** — the server starts and
registers its tools even with no key set; a clear error is raised only when a
tool is actually invoked without one.
### Environment variables
| Variable | Required | Default | Purpose |
|---|---|---|---|
| `SQUARESPACE_API_KEY` | yes (at call time) | — | Bearer API key |
| `SQUARESPACE_API_VERSION` | no | `1.0` | Version for inventory / orders / transactions / profiles |
| `SQUARESPACE_PRODUCTS_API_VERSION` | no | `v2` | Products is versioned **independently** — v2 is current (legacy 1.0/1.1 not for new integrations) |
| `SQUARESPACE_USER_AGENT` | no | `squarespace-mcp/0.1 …` | Squarespace requires a descriptive User-Agent |
## Run
```bash
squarespace-mcp # runs the MCP server over stdio
```
The process reads/writes MCP frames on stdin/stdout and blocks waiting for a
client — that is expected. It is meant to be launched by an MCP client, not run
interactively.
## Register with Claude Code
```bash
claude mcp add squarespace \
--env SQUARESPACE_API_KEY=your_key_here \
-- /absolute/path/to/squarespace-mcp/.venv/bin/squarespace-mcp
```
(Or point the command at `uv run squarespace-mcp` / your installed console
script.) After registering, the tools below appear to the agent.
## Tools
### Read (safe)
| Tool | Purpose |
|---|---|
| `list_products(cursor?, modified_after?)` | List catalog products, 50/page |
| `get_product(product_id)` | Retrieve one product |
| `list_inventory(cursor?)` | List stock levels, 50/page |
| `get_inventory(variant_ids)` | Stock for specific variants (≤50 ids) |
| `list_orders(cursor?, modified_after?, fulfillment_status?)` | List orders (filter `PENDING`/`FULFILLED`/`CANCELED`) |
| `get_order(order_id)` | Retrieve one order |
| `list_transactions(cursor?, modified_after?, modified_before?)` | List financial transactions |
| `list_profiles(cursor?)` | List customer profiles |
| `get_profile(profile_id)` | Retrieve one profile |
**Pagination:** list tools return the raw Squarespace page including a
`pagination` object; pass its `nextPageCursor` back as `cursor` to page forward.
### Write (⚠️ mutates the live store)
| Tool | Purpose |
|---|---|
| `adjust_inventory(variant_id, quantity)` | Set a variant's stock to an exact quantity (sent with an idempotency key) |
| `fulfill_order(order_id, shipments, should_send_notification=true)` | Mark an order fulfilled with shipment details; optionally emails the customer |
Destructive operations (product delete, etc.) are intentionally **not**
implemented.
## Development
```bash
pytest -q # all HTTP is mocked with respx — no network calls
```
## Security
- Real credentials live in `.env` (gitignored). Only `.env.example` is committed.
- Never hardcode the API key; it is read from the environment at runtime.
- The client raises on any non-2xx response (status + body) — no silent fallbacks.
TDQS
Scored across 11 tools
Each tool has a clear, distinct purpose. The list/get pairs (e.g., list_products vs get_product) are differentiated by whether you're browsing with filters or fetching known IDs, and the two mutations (adjust_inventory, fulfill_order) are unambiguous.
All tool names follow a consistent verb_noun pattern in snake_case: list_* and get_* for reads, adjust_inventory and fulfill_order for writes. The naming is predictable and easy to navigate.
At 11 tools, the server is well-scoped for an e-commerce operations context. It covers the major resources (transactions, products, inventory, orders, profiles) without unnecessary duplication or bloat.
The read surface is strong with list/get for all core resources, and the mutations cover inventory adjustment and order fulfillment. However, there are notable gaps: no create/update/delete for products or orders, no order cancellation, and no profile management operations.