Copy as markdown[View .md](https://docs.funnelfizz.com/ai-agents/safety-tiers "View the raw markdown for this page")[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fdocs.funnelfizz.com%2Fai-agents%2Fsafety-tiers.md%20and%20help%20me%20with%20this%20FunnelFizz%20topic%3A%20Safety%20tiers "Open this page in Claude with context")[Open in ChatGPT](https://chat.openai.com/?q=Read%20https%3A%2F%2Fdocs.funnelfizz.com%2Fai-agents%2Fsafety-tiers.md%20and%20help%20me%20with%20this%20FunnelFizz%20topic%3A%20Safety%20tiers "Open this page in ChatGPT with context")

# Safety tiers

FunnelFizz MCP gates every write tool behind one of three tiers. The higher the tier, the more upfront confirmation is required. **Reads (T0) have no gate** — your agent can call `funnel.get_metrics` or `team.list_members` without ceremony.

## T0 — Reads[​](#t0--reads "Direct link to T0 — Reads")

Anything `list_*`, `get_*`, or `stage.drilldown` / `funnel.drilldown` is T0. They:

* Require only that your API key has the matching scope (`read` for most reads, `setup` for setup-status checks).
* Are filtered at `tools/list` time: if your key can't call a tool, the tool is hidden from your agent's tool catalog. No surprises.
* Have no expiry, no confirmation step.

## T1 — Mutations with target\_token[​](#t1--mutations-with-target_token "Direct link to T1 — Mutations with target_token")

Any tool that changes data outside a draft is T1. Examples: `funnel.split.create`, `email.draft.send_now`, `automation.activate`, `tracking.site.delete`, `email.template.delete`.

T1 has two flavors depending on what you're targeting:

### Funnel-scoped (the common case)[​](#funnel-scoped-the-common-case "Direct link to Funnel-scoped (the common case)")

Used for funnel structure changes, sends, automation activation — anything bound to a specific funnel.

```
1. Agent: funnel.resolve_by_name({ query: "onboarding" })

   → returns ranked matches with stage summaries and a `suggestion` field



2. Agent shows matches in chat. User picks. (Agents must NEVER auto-select,

   even on a single exact match.)



3. Agent: funnel.confirm_target({ funnelId: "...", action: "funnel.split.create" })

   → returns a 10-minute, single-use, action-bound target_token



4. Agent: funnel.split.create({ funnelId, ..., targetToken })

   → mutation runs; token is consumed
```

### Entity-scoped (deletes and disconnects)[​](#entity-scoped-deletes-and-disconnects "Direct link to Entity-scoped (deletes and disconnects)")

Used for high-impact non-funnel writes — deleting a tracking site, an email template, a sender, a domain, or disconnecting an integration.

```
1. Agent: tracking.site.list()

   → enumerate, show user, ask which to delete



2. Agent: confirm_target({

      targetType: "tracking_site",

      targetId: "site-id",

      action: "tracking.site.delete"

   })

   → returns a 10-minute target_token bound to (type, id, action)



3. Agent: tracking.site.delete({ id, targetToken })

   → site deleted; token consumed
```

### Low-stakes workspace writes[​](#low-stakes-workspace-writes "Direct link to Low-stakes workspace writes")

For routine workspace config (brand color, profile name, email template *create* and *update*, sender config), **no token is needed**. The `write` scope is enough; the user has already confirmed in chat by asking the agent.

## T2 — Admin code-paste[​](#t2--admin-code-paste "Direct link to T2 — Admin code-paste")

Workspace administration is the highest-trust tier. T2 actions:

* Invite, remove, or change role of a team member
* Cancel, resume, or change subscription plan
* Create or revoke API keys
* Transfer workspace ownership
* Delete the workspace

These actions require an **out-of-band confirmation code** emailed to the API-key-holder's address. Browser-controlling agents (like Claude with computer use) can fetch the code automatically. Text-only agents ask the user to read the email and paste the code.

```
1. Agent: admin.request_action({

      action: "team.invite_member",

      subject: "alice@example.com",

      summary: "Invite alice@example.com as MANAGER"

   })

   → returns { requestId, expiresAt: "10min" }

   → server emails a 6-digit code to the API-key-holder



2. Agent tells user: "Check your email for a 6-digit code."

   User reads the email and pastes the code.



3. Agent: admin.confirm_action({ requestId, code: "482910" })

   → returns { adminToken, expiresAt: "10min" }



4. Agent: team.invite_member({

      email: "alice@example.com",

      role: "MANAGER",

      adminToken

   })

   → invite sent; admin_token consumed
```

### Why code-paste[​](#why-code-paste "Direct link to Why code-paste")

Even if the agent is compromised by a prompt-injection attack, the attacker cannot perform a T2 action without access to the user's inbox. The two-channel handshake — agent in chat, code in email — is the only thing that resists agent compromise.

### Failure modes[​](#failure-modes "Direct link to Failure modes")

* 5 wrong code attempts → the request is consumed; agent must start a new one.
* 10 minutes elapse → code expires; restart.
* Code matches but `admin_token` expires before use → re-request.

## Failure visibility[​](#failure-visibility "Direct link to Failure visibility")

Insufficient-scope and missing-token errors are returned as structured `apiError` objects with codes:

* `forbidden_scope` — your key doesn't have the required scope (filtered out of `tools/list` if your role and plan allow none of the scopes for that tool)
* `missing_target_token` / `target_token_*` — token issue (missing, expired, consumed, wrong action, wrong funnel, wrong target)
* `missing_admin_token` / `admin_token_*` — code-paste handshake required

Your agent should surface these to the user with the specific reason so they understand whether to retry, upgrade their key, or restart the flow.

## Related[​](#related "Direct link to Related")

* [Browser handoffs](https://docs.funnelfizz.com/ai-agents/browser-handoffs.md) — Stripe Checkout, portal, OAuth.
* [Admin actions](https://docs.funnelfizz.com/ai-agents/admin-actions.md) — full code-paste walkthrough with screenshots.
* [Revert changes](https://docs.funnelfizz.com/ai-agents/revert-changes.md) — undoing mistakes.
