{/* Metadata lives in ./layout.tsx */}

# MCP server

The MCP server lets AI tools work with your Pluto numbers. Ask Claude how last week performed, have an agent run your morning kill-list review, or let it log an influencer payment as ad spend. Reads return the same numbers your dashboard shows, to the cent. Writes are limited to costs and campaign labels, and every one is recorded. {{ className: 'lead' }}

<Warning>
  The Pluto MCP server is not live yet. The endpoint and client setups below
  describe the planned surface and may change before launch.
</Warning>

Pluto follows the [remote MCP specification](https://modelcontextprotocol.io/specification), so the server is centrally hosted. Clients with native remote support connect directly; others use the [`mcp-remote`](https://github.com/geelen/mcp-remote) proxy.

---

## Before you start

Create an API key at **app.plutoprofit.com/developers**. The key is shown once. A `pk_plp_` key reads your shop's data. The three write tools need an `sk_plp_` key with the matching scope; a read key never sees them in the tool list. (Keys minted before 2026-07-15 may use the legacy `pk_` prefix; both still work.) Every client below authenticates the same way:

<CodeGroup title="MCP server">

```txt {{ title: 'URL' }}
https://mcp.plutoprofit.com/mcp
```

```txt {{ title: 'Auth header' }}
Authorization: Bearer pk_plp_your_key
```

</CodeGroup>

---

## Claude

**Claude Desktop and claude.ai**

Open **Settings -> Connectors** and add a custom connector pointing at `https://mcp.plutoprofit.com/mcp`. Static API-key headers on custom connectors are currently a **beta in limited rollout** at Anthropic - if your workspace has the "Request headers" field, add `Authorization: Bearer pk_plp_your_key` there. Otherwise use the `mcp-remote` bridge below (works today), or wait for OAuth sign-in (coming - no key handling at all).

**Claude Code**

```sh
claude mcp add --transport http pluto https://mcp.plutoprofit.com/mcp --header "Authorization: Bearer pk_plp_your_key"
```

---

## Cursor

Open Cursor Settings (`Ctrl+Shift+J` / `Cmd+Shift+J`) -> **MCP** -> **Add new global MCP server**, and add this entry to your `mcp.json`:

```json
{
  "mcpServers": {
    "pluto": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.plutoprofit.com/mcp",
        "--header",
        "Authorization: Bearer pk_plp_your_key"
      ]
    }
  }
}
```

<Note>
  `mcp-remote` proxies the remote server through stdio for clients without
  native remote support. No install needed. `npx -y` fetches it on first use.
</Note>

---

## Other clients

Most MCP-capable tools accept a stdio entry that proxies via `mcp-remote`. Use:

<Properties>
  <Property name="Command">`npx`</Property>
  <Property name="Arguments">
    `-y mcp-remote https://mcp.plutoprofit.com/mcp --header "Authorization: Bearer
    pk_plp_your_key"`
  </Property>
</Properties>

If your client supports remote MCP natively, point it at `https://mcp.plutoprofit.com/mcp` directly and set the `Authorization` header.

---

## Tools

Eighteen tools in three groups. Reads return the same numbers your dashboard shows, computed by the same code, so the two can never disagree. Money is always an exact decimal string with its currency.

Read tools:

| Tool | Returns |
|---|---|
| `get_profit_summary` | Net profit, revenue, and every cost bucket for a range. Day, week, or month series on request. |
| `get_cost_breakdown` | Costs decomposed: COGS, gateway fees, shipping, custom costs, ad spend, disputes. |
| `get_channel_performance` | Spend and attributed revenue per ad channel, with each platform's attribution window named, plus Pluto's deterministic attributed revenue and orders beside the platform number. |
| `get_attribution_report` | The Attribution page's reconciliation: attributed plus unattributed equals total revenue to the cent, platform and Pluto columns side by side, journey coverage. |
| `get_product_pnl` | Per-product contribution, worst margin first. The kill-list view. |
| `get_refund_chargeback_report` | Refunds by day, dispute outcomes, top refunded products. |
| `get_cash_position` | Settled payouts, upcoming committed costs, ad-spend run rate. |
| `list_anomalies` | Rule hits: spend without sales, ROAS below break-even for 3 days or more, spend spikes. |
| `accountant_export` | The period as a P&L statement plus tax totals. |
| `get_assistant_findings` | Open data-quality and cost-accuracy issues that make profit wrong, each with the exact inputs that fired it. |
| `get_sync_status` | Which sources are connected and when they last synced. |
| `list_metric_definitions` | What each metric means and how it is calculated. |

Simulate tools compute what-ifs with exact decimal math. The model composes the question; it never does the arithmetic. `breakeven_roas` derives your break-even from actual contribution margin. `price_for_margin` solves the unit price for a target margin after fees and VAT. `simulate_cost_change` re-runs a period with one cost shifted.

Write tools need an `sk_plp_` key with the matching scope. `log_custom_cost` records an expense (costs:write). `set_product_cost` sets a dated per-unit cost for a variant (products:write). `classify_campaign` labels a campaign prospecting, retargeting, or retention (campaigns:write). Each write goes through the same validation as the dashboard, is safe to retry, and lands in an audit log with the key that made it.

No tool can create, change, or delete orders or revenue. That is structural, not policy: the write tools have no path to order data at all.

---

## Provenance

Every read answer carries a provenance block: when it was computed, how fresh each source was, and which cost components are measured versus estimated. An agent can always tell a real number from an estimate, and a current number from a stale one. When a component cannot be derived, the answer says so with a reason rather than guessing.

---

## Revoking access

Delete the key at **app.plutoprofit.com/developers**. Revocation is immediate. The next call from any client using that key returns `401`.

---

## FAQ

<Properties>
 <Property name="Numbers don't match the dashboard">
 Check the date range and timezone. The MCP server and the dashboard read the same data, so the same range returns the same numbers. Recent days also keep settling as ad platforms finalize their reporting. See [Data freshness](/docs/data-freshness).
 </Property>
 <Property name="Write tools don't appear in the tool list">
 The connected key is a read key. Write tools only exist for `sk_plp_` keys carrying the matching scope. Mint one at app.plutoprofit.com/developers and pick the scopes when creating it.
 </Property>
 <Property name="The client reports 'unauthorized'">
 The key was deleted or mistyped. Create a new one at app.plutoprofit.com/developers and update the client config.
 </Property>
 <Property name="'mcp-remote' fails with a network error">
 `npx -y` needs network access on first run. Behind a proxy, install it globally with `npm install -g mcp-remote` and replace the npx command in your config.
 </Property>
</Properties>
