> For the complete documentation index, see [llms.txt](https://help.fungies.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.fungies.io/for-saas-developers/fungies-mcp/mcp-capabilities.md).

# MCP Capabilities

### Read-only vs full access

You choose the power level by which key you give the MCP.

| Mode            | Headers sent                                    | Tools exposed                                               | Good for                          |
| --------------- | ----------------------------------------------- | ----------------------------------------------------------- | --------------------------------- |
| **Read-only**   | `x-fngs-public-key` only                        | 17 (list/get/inventory/verify)                              | Analytics, reporting, exploration |
| **Full access** | `x-fngs-public-key` **and** `x-fngs-secret-key` | 40 (adds create / update / archive / cancel / refund flows) | Day-to-day store management       |

You can install Fungies twice with different names — e.g. `fungies-read` and `fungies-write` — to keep destructive tools behind an explicit switch.

All destructive tools (`*_archive`, `*_cancel`, `offers_keys_remove`) additionally require `confirm: true` in the call, so your AI cannot accidentally wipe things out.

***

### Full capabilities (40 tools)

All tools return structured JSON suitable for follow-up reasoning. Read-only tools are marked **R**, write tools **W**, destructive tools **D**.

#### Products — 6 tools

| Tool                 | Type | What it does                                                                     |
| -------------------- | ---- | -------------------------------------------------------------------------------- |
| `products_list`      | R    | Browse / search / count products in your catalog                                 |
| `products_get`       | R    | Full details of one product (variants, plans, status)                            |
| `products_duplicate` | W    | Clone a product as a starting point for a new one                                |
| `products_create`    | W    | Create a new product (`OneTimePayment`, `Subscription`, `Membership`, `GameKey`) |
| `products_update`    | W    | Rename, rewrite copy, change slug                                                |
| `products_archive`   | D    | Soft-delete a product (also archives its offers)                                 |

#### Offers & price points — 5 tools

| Tool             | Type | What it does                                                     |
| ---------------- | ---- | ---------------------------------------------------------------- |
| `offers_list`    | R    | Browse offers, filter by product                                 |
| `offers_get`     | R    | Details of a single offer (price, currency, interval, inventory) |
| `offers_create`  | W    | Add a price point to a product (one-off or recurring)            |
| `offers_update`  | W    | Rename an offer (price/currency are immutable)                   |
| `offers_archive` | D    | Retire an offer; active subscriptions keep running               |

#### Game keys / license keys — 2 tools

| Tool                 | Type | What it does                                           |
| -------------------- | ---- | ------------------------------------------------------ |
| `offers_keys_add`    | W    | Upload new license/game keys into an offer's inventory |
| `offers_keys_remove` | D    | Pull an unsold key back; sold keys are preserved       |

#### Orders — 3 tools

| Tool            | Type | What it does                                                 |
| --------------- | ---- | ------------------------------------------------------------ |
| `orders_list`   | R    | Filter orders by status, date, recency                       |
| `orders_get`    | R    | Full details by UUID or short order number (e.g. `9XMrb9Hk`) |
| `orders_cancel` | D    | Mark an order CANCELLED (does not auto-refund)               |

#### Subscriptions — 7 tools

| Tool                   | Type | What it does                                          |
| ---------------------- | ---- | ----------------------------------------------------- |
| `subscriptions_list`   | R    | Filter by status: active, canceled, paused, past\_due |
| `subscriptions_get`    | R    | Full details: offer, period, cancel date              |
| `subscriptions_create` | W    | Programmatic create (migration / backfill)            |
| `subscriptions_update` | W    | Upgrade/downgrade, change billing                     |
| `subscriptions_cancel` | D    | Cancel end-of-period or immediately, optional refund  |
| `subscriptions_pause`  | W    | Pause billing; access stays active                    |
| `subscriptions_charge` | W    | Charge a one-off extra (usage-based billing)          |

#### Customers — 7 tools

| Tool              | Type | What it does                                                 |
| ----------------- | ---- | ------------------------------------------------------------ |
| `users_list`      | R    | Search by email or username                                  |
| `users_get`       | R    | Full customer profile                                        |
| `users_inventory` | R    | Everything a customer owns (products, subscriptions, access) |
| `users_create`    | W    | Create a customer record (migration, manual entry)           |
| `users_update`    | W    | Edit email, username, billing details                        |
| `users_archive`   | D    | Soft-delete, reversible                                      |
| `users_unarchive` | W    | Restore a previously archived customer                       |

#### Discounts — 5 tools

| Tool                | Type | What it does                                        |
| ------------------- | ---- | --------------------------------------------------- |
| `discounts_list`    | R    | Active or archived coupons and sales                |
| `discounts_get`     | R    | Full details of a discount                          |
| `discounts_create`  | W    | Coupon (code-redeemable) or sale (auto), % or fixed |
| `discounts_update`  | W    | Rename, adjust validity window                      |
| `discounts_archive` | D    | Retire a discount                                   |

#### Payments — 2 tools

| Tool            | Type | What it does                                         |
| --------------- | ---- | ---------------------------------------------------- |
| `payments_list` | R    | All transactions, filter by PAID / FAILED / REFUNDED |
| `payments_get`  | R    | Single payment (fee, tax, invoice URL)               |

#### Checkout elements — 2 tools

| Tool              | Type | What it does                                          |
| ----------------- | ---- | ----------------------------------------------------- |
| `elements_list`   | R    | All embeddable checkout widgets in the store          |
| `elements_create` | W    | Bind a set of offers into a reusable checkout element |

#### Webhooks — 1 tool

| Tool              | Type | What it does                                                                                                                                                                                                                  |
| ----------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webhooks_verify` | R    | Verify a Fungies webhook signature locally (HMAC-SHA256, timing-safe; no network call). Fungies does not expose a webhook delivery log over the API — use the Fungies dashboard → Developers → Webhooks for delivery history. |

***

### Example prompts

Paste any of these into your AI chat once the MCP is installed.

**Analytics**

> "How many paid orders did I have in the last 7 days? Break it down by product."

> "Show me my 10 biggest customers by lifetime spend."

> "Which subscription offers have the highest churn this quarter?"

**Catalog operations**

> "Duplicate 'Pro Plan' and call the copy 'Pro Plan — EUR'. Then create a €99 yearly offer for it."

> "Add these 500 Steam keys to the 'Indie Bundle' offer."

> "List every offer that's priced under $5."

**Customer support**

> "Find the customer with email `alice@example.com`, show me her inventory, and cancel any active subscriptions at period end."

> "What's the payment status of order 9XMrb9Hk?"

**Promotions**

> "Create a 25% off coupon code `WINTER25` that's valid from now until January 15th."

> "Archive all coupons whose validity window ended before this year."

**Webhooks**

> "Here's a webhook body and the `x-fngs-signature` header. Tell me if the signature is valid given my signing secret."

***

### Security & safety

Fungies MCP is built so your AI can be powerful without being dangerous.

* **No credential storage.** Keys live only in your AI tool's local config. Every request forwards them to `api.fungies.io` and the server forgets them.
* **Read-only install option.** If you only need analytics, use the public key alone — 23 write / destructive tools simply never appear.
* **Destructive confirm gate.** Archive / cancel / remove-key tools require the caller to pass `confirm: true`. Hosts that surface this to you (like Cursor's tool-call dialog) will ask before proceeding.
* **Tool annotations.** Every tool advertises `readOnlyHint` / `destructiveHint` / `idempotentHint` so your AI can reason about risk before calling.
* **Strict input validation.** Every tool input is a `.strict()` Zod object — unknown fields are rejected. All IDs must match `^[A-Za-z0-9_-]{1,64}$`, which blocks path traversal attacks against the upstream API.
* **Origin allowlist.** Browser `Origin` headers are checked against an allowlist (app schemes like `cursor://`, `vscode://` always pass; arbitrary websites are blocked with 403 — defeats DNS rebinding / CSRF).
* **Hard limits.** `/mcp` enforces a 256 KB body cap (413 `payload_too_large`) and a 300 req/min per-key rate limit (+ 120 req/min per IP on everything).
* **Nonce-based CSP on `/install`.** `default-src 'none'` with per-request nonces — no third-party scripts, no inline exec, no framing.
* **Log redaction + audit trail.** `pino` with strict redaction — your keys never show up in logs. Every write call records `{ tool, publicKey (masked), requestId }` with PII fields (email, billingDetails) replaced with `[REDACTED]`.
* **HTTPS-only upstream.** In production the server refuses to start if `FUNGIES_API_BASE` isn't `https://`.
* **Your data is yours.** The server never reads from or writes to a database; it is a pure passthrough to the Fungies API over TLS.
* **Revocation is one click.** Delete the key pair from the Fungies dashboard and the MCP becomes inert immediately.

If you spot a security issue, please report it privately via [help.fungies.io](https://help.fungies.io/).

***

### Troubleshooting

**"missing\_or\_invalid\_public\_key" (HTTP 401)** Your `x-fngs-public-key` header is missing or not in the `pub_...` shape. Recheck the value in your MCP config.

**"invalid\_secret\_key" (HTTP 401)** Your `x-fngs-secret-key` header is present but doesn't match the `sec_...` shape. Either fix it or remove the header to fall back to read-only mode.

**Tools list is empty in my AI tool**

1. Confirm your AI tool says the server is **connected** (not "starting" / "error").
2. Hit `https://mcp.fungies.io/healthz` in a browser — you should see `{"ok":true, ...}`.
3. Restart your AI tool after editing config — MCP clients only read it on startup.

**"Forbidden" errors on write tools** You installed with the public key only. Re-install with both keys (or add `x-fngs-secret-key` to the existing config) and restart.

**"Rate limited" messages** The upstream Fungies API is throttling. The server automatically retries GET/PATCH/DELETE on 429/5xx, but POST is not retried. Try again in a minute.

**Tool call hangs / times out** Default per-request timeout is 15 s. Long-running list queries? Narrow with `skip` / `take` or a `termOrId` filter.

Still stuck? Open an issue on [GitHub](https://github.com/dukenukemall/fungies-mcp/issues) or ping us in [Discord](https://discord.gg/yfH5ZyTZH4).

***

### Self-host

Want to run the MCP on your own infrastructure? It's a single container.

```
docker build -t fungies-mcp .
docker run -p 3000:3000 \
  -e PORT=3000 \
  -e NODE_ENV=production \
  -e LOG_LEVEL=info \
  -e FUNGIES_API_BASE=https://api.fungies.io \
  -e MCP_PUBLIC_URL=https://your-domain.example.com \
  fungies-mcp
```

| Env var                  | Default                                    | Notes                                                                                                                |
| ------------------------ | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `PORT`                   | `3000`                                     | HTTP listen port                                                                                                     |
| `NODE_ENV`               | `development`                              | Set to `production` in prod                                                                                          |
| `LOG_LEVEL`              | `info`                                     | `trace` / `debug` / `info` / `warn` / `error`                                                                        |
| `FUNGIES_API_BASE`       | `https://api.fungies.io`                   | Change for staging environments                                                                                      |
| `MCP_PUBLIC_URL`         | `https://mcp.fungies.io`                   | Baked into the `/install` page                                                                                       |
| `FUNGIES_TIMEOUT_MS`     | `15000`                                    | Upstream request timeout                                                                                             |
| `FUNGIES_MAX_RETRIES`    | `2`                                        | Retries for GET / PATCH / DELETE on 429 / 5xx                                                                        |
| `MCP_ALLOWED_ORIGINS`    | `mcp.fungies.io,app.fungies.io,fungies.io` | Comma list of https hosts allowed via `Origin` header (app schemes like `cursor://`, `vscode://` are always allowed) |
| `MCP_MAX_BODY_BYTES`     | `262144`                                   | Max JSON-RPC request size (256 KB)                                                                                   |
| `RATE_LIMIT_IP_PER_MIN`  | `120`                                      | Per-IP request cap across the whole server                                                                           |
| `RATE_LIMIT_KEY_PER_MIN` | `300`                                      | Per-public-key request cap on `/mcp`                                                                                 |

The container runs as a non-root user, ships a health endpoint at `/healthz`, and exposes a clickable onboarding UI at `/install`.
