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

An MCP server that lets an AI agent (Claude or Codex) **search FSA‑eligible
products on fsastore.com and add them to your shopping cart**, then place the
order only when you explicitly confirm the total.

- Runs with **one `uvx` command** — no clone, no manual install.
- **No password is ever stored.** You paste a short‑lived access token from your
  browser via a one‑click bookmarklet.
- Search → cart is verified against the live store API.

---

## 1. Add it to your agent

You need [`uv`](https://docs.astral.sh/uv/) installed (`brew install uv`). `uvx`
then builds and runs the server straight from the repo.

> This repo is **private**, so `uvx` clones it with your Git credentials. Run
> `gh auth login` (or have SSH set up) first. If you use SSH, swap the URL for
> `git+ssh://git@github.com/darrengruber/fsastore-mcp`.

### Claude Code (CLI)

```bash
claude mcp add fsastore -- \
  uvx --from git+https://github.com/darrengruber/fsastore-mcp fsastore-mcp
```

### Claude Desktop

Add to `claude_desktop_config.json` (Settings → Developer → Edit Config):

```json
{
  "mcpServers": {
    "fsastore": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/darrengruber/fsastore-mcp", "fsastore-mcp"]
    }
  }
}
```

### OpenAI Codex CLI

Add to `~/.codex/config.toml`:

```toml
[mcp_servers.fsastore]
command = "uvx"
args = ["--from", "git+https://github.com/darrengruber/fsastore-mcp", "fsastore-mcp"]
```

Restart the agent after editing config. To grab the latest code later, add
`--refresh` to the `uvx` args (e.g. `["--refresh", "--from", "git+...", "fsastore-mcp"]`).

---

## 2. Install the token bookmarklet (one minute, one time)

The store sits behind bot protection, so the server can't log in for you.
Instead you hand it a fresh token with one click. **Set this up once:**

1. **Copy** this entire line (it starts with `javascript:`):

   ```
   javascript:(function(){var m=document.cookie.match(/scapi_access_token=([^;]+)/);if(!m){alert('No token yet — open your Cart once, then click again.');return;}var t=decodeURIComponent(m[1]);navigator.clipboard.writeText(t).then(function(){alert('FSA token copied ('+t.length+' chars). Paste it to your agent.');},function(){window.prompt('Copy this token:',t);});})();
   ```

2. **Create a bookmark** and paste that line as its **URL**:
   - **Chrome / Edge:** ⭐ in the address bar → **Edit** → set **Name** to
     `FSA token` and replace the **URL** with the copied line → **Save**.
     (Or: menu → Bookmarks → **Bookmark Manager** → ⋮ → **Add new bookmark**.)
   - **Firefox:** Bookmarks menu → **Manage Bookmarks** → right‑click a folder →
     **Add Bookmark** → Name `FSA token`, **Location** = the copied line.
   - **Safari:** add any bookmark, then Edit Bookmarks and paste the line as its
     address.

That's it — you now have an **FSA token** button.

---

## 3. Use it

1. **Log in** at <https://www.fsastore.com> in your browser.
2. Click your **FSA token** bookmark. It copies a token to your clipboard.
   (If it says *"No token yet"*, open your **Cart** page once and click again.)
3. In Claude/Codex, tell the agent to **set the access token**, and paste it:

   > Use `set_access_token` with: `eyJ...` *(your copied token)*

4. Now just ask, e.g.:

   > Search fsastore for sunscreen and add two of the cheapest eligible one to my cart.

When the token expires (~30 min), any tool replies `login_required` — just click
the bookmark and `set_access_token` again.

> **Tip:** ask the agent to run `auth_status`. It reports whether your token is
> for your **account** or a **Guest** session. If it says Guest, log in first,
> then re‑run the bookmark — otherwise you'll be editing a guest cart.

---

## Tools the agent can call

| Tool | Purpose |
|------|---------|
| `set_access_token` | Cache a token copied by the bookmarklet |
| `auth_status` | Whether a valid token is cached, who it's for, time left |
| `search_products` | Search; FSA‑eligible only by default, each tier‑labeled |
| `add_to_cart` | Add a product (master products auto‑resolve to a buyable variant) |
| `view_cart` | Show cart contents and total |
| `get_checkout_summary` | Show the total to confirm |
| `confirm_order` | Place the order — only if the live total matches the one you pass |

The server never places an order except through `confirm_order` with a matching
total.

---

## Run it directly (optional)

```bash
# from a clone
uvx --from . fsastore-mcp
# or
uv run fsastore-mcp
```

## Run as an HTTP server / container (optional)

For local use the stdio transport above is all you need. To run it persistently
behind an MCP gateway, set `FSASTORE_MCP_TRANSPORT=http` (host/port via
`FSASTORE_MCP_HOST` / `FSASTORE_MCP_PORT`). A `Dockerfile` is included:

```bash
docker build -t fsastore-mcp .
docker run --rm -p 9130:9130 -v fsastore-state:/state fsastore-mcp
```

State (the cached token, active basket id) lives in the process, so serve HTTP
with a **single replica**. The token is written under `XDG_STATE_HOME`
(`/state` in the image) — mount a writable volume there.

## Develop

```bash
uv sync
uv run pytest        # tests
uv run ruff check .  # lint
uv run ty check src  # types
```

Design notes and decisions: [`CONTEXT.md`](CONTEXT.md) and [`docs/adr/`](docs/adr/).

## Status

Verified against the live store API: product search + FSA‑eligibility, cart reuse,
master→variant resolution, add‑to‑cart. **Checkout submission** (`confirm_order`)
is wired and gated but not yet exercised end‑to‑end — a saved shipping/payment
method may need to be applied to the cart first. The Confirm Gate prevents
accidental orders regardless.

TDQS

A3.9/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: auth, product search, cart manipulation, and order confirmation. No overlap in functionality.

Naming Consistency5/5

All tools follow a consistent verb_noun snake_case pattern (e.g., add_to_cart, search_products, view_cart), making it easy to predict tool names.

Tool Count5/5

With 7 tools, the set is concise yet covers the essential workflow of an FSA store checkout. No unnecessary tools or missing core actions for the apparent scope.

Completeness4/5

Covers the main flow (auth, search, cart add/view, checkout summary, confirm) but lacks cart modification tools like remove or update quantity, which agents might need.

Maintenance

ActivitySlowing
ResponsivenessSyncing