> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clickbase.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Writer tools

> The Writer server (https://clickbase.so/mcp/writer) exposes mutating tools.

The **Writer** server (`https://clickbase.so/mcp/writer`) exposes mutating tools. Every tool writes data and acts only within your current team; a `site` parameter accepts the site's domain or id. Deletes cannot be undone.

Some tools additionally enforce a **role or ownership** check on top of team tenancy (deleting a site, editing another author's annotation, and so on). Those checks are noted on the tool.

***

## Sites

### `create-site-tool`

*Writes.*

> Create a new site (property) in the current team for the given domain. Returns the created site.

Respects the team's **plan quota**: if the team cannot create another site (quota reached or a lapsed subscription), the call is rejected with a validation error.

**Parameters**

| Parameter  | Type   | Required | Description                                                                         |
| ---------- | ------ | -------- | ----------------------------------------------------------------------------------- |
| `domain`   | string | Yes      | The site domain, e.g. `example.com`. Must be unique within the team. Max 255 chars. |
| `timezone` | string | No       | IANA timezone for the site's reports (defaults to UTC).                             |

**Returns** — a `site` object: `id`, `domain`, `timezone`, `currency`, `tracking_mode`, `is_public`, `has_data`, `created_at`.

### `update-site-domain-tool`

*Writes.*

> Change a site's domain. Returns the updated site.

**Parameters**

| Parameter | Type   | Required | Description                                                                 |
| --------- | ------ | -------- | --------------------------------------------------------------------------- |
| `site`    | string | Yes      | The site domain or id.                                                      |
| `domain`  | string | Yes      | The new domain for the site. Must be unique within the team. Max 255 chars. |

**Returns** — the updated `site` object.

### `update-site-timezone-tool`

*Writes.*

> Change a site's reporting timezone. Returns the updated site.

**Parameters**

| Parameter  | Type   | Required | Description                                              |
| ---------- | ------ | -------- | -------------------------------------------------------- |
| `site`     | string | Yes      | The site domain or id.                                   |
| `timezone` | string | Yes      | The new IANA timezone identifier (e.g. `Europe/Lisbon`). |

**Returns** — the updated `site` object.

### `update-site-currency-tool`

*Writes.*

> Change a site's reporting currency. Rejected while the site has a revenue goal. Returns the updated site.

**Parameters**

| Parameter  | Type   | Required | Description                                                 |
| ---------- | ------ | -------- | ----------------------------------------------------------- |
| `site`     | string | Yes      | The site domain or id.                                      |
| `currency` | string | Yes      | The new ISO 4217 currency code (e.g. `USD`). Three letters. |

**Returns** — the updated `site` object.

### `update-site-tracking-mode-tool`

*Writes.*

> Set a site's tracking mode to "cookieless" or "cookie". Returns the updated site.

**Parameters**

| Parameter       | Type   | Required | Description                      |
| --------------- | ------ | -------- | -------------------------------- |
| `site`          | string | Yes      | The site domain or id.           |
| `tracking_mode` | string | Yes      | Either `cookieless` or `cookie`. |

**Returns** — the updated `site` object.

### `update-site-sharing-tool`

*Writes.*

> Toggle whether a site's dashboard is publicly shared. Returns the updated site.

**Parameters**

| Parameter   | Type   | Required | Description                                    |
| ----------- | ------ | -------- | ---------------------------------------------- |
| `site`      | string | Yes      | The site domain or id.                         |
| `is_public` | bool   | Yes      | Whether the site dashboard is publicly shared. |

**Returns** — the updated `site` object.

### `toggle-site-pin-tool`

*Writes.*

> Toggle whether a site is pinned to the top of the team's site list. Returns the updated site.

**Parameters**

| Parameter | Type   | Required | Description            |
| --------- | ------ | -------- | ---------------------- |
| `site`    | string | Yes      | The site domain or id. |

**Returns** — the updated `site` object.

### `record-payment-tool`

*Writes.*

> Record a verified payment for a site. Same Action as `POST /api/sites/{site}/payments`. Idempotent on `transaction_id` — a replay returns the existing payment. Amount is integer minor units (cents). Currency must match the site currency.

Requires **workspace Admin or Owner** (`SitePolicy::manage`).

**Parameters**

| Parameter        | Type   | Required | Description                                                       |
| ---------------- | ------ | -------- | ----------------------------------------------------------------- |
| `site`           | string | Yes      | The site domain or id.                                            |
| `amount`         | int    | Yes      | Payment amount in minor units (cents). Must be `> 0`.             |
| `currency`       | string | Yes      | ISO 4217 currency code; must match the site's reporting currency. |
| `transaction_id` | string | Yes      | Idempotency key unique per site. Max 255 chars.                   |
| `visitor_id`     | string | No       | Optional Clickbase visitor UUID for attribution.                  |
| `email`          | string | No       | Optional customer email. Max 255 chars.                           |
| `name`           | string | No       | Optional customer name. Max 255 chars.                            |
| `customer_id`    | string | No       | Optional provider customer id. Max 255 chars.                     |
| `renewal`        | bool   | No       | Whether this payment is a subscription renewal.                   |
| `refunded`       | bool   | No       | Whether this row represents a refund.                             |
| `is_free_trial`  | bool   | No       | Whether this is a free trial.                                     |
| `recurring`      | bool   | No       | Whether this payment is recurring.                                |
| `timestamp`      | string | No       | Optional ISO 8601 occurred-at timestamp.                          |

**Returns** — `message`, `transaction_id`, and `created` (whether a new row was written).

### `delete-payment-tool`

*Writes.*

> Delete an API-recorded payment (and its ClickHouse revenue row) by `transaction_id`. Same Action as `DELETE /api/sites/{site}/payments`. Only deletes payments with `provider=api` — never Stripe-ingested rows.

Requires **workspace Admin or Owner** (`SitePolicy::manage`).

**Parameters**

| Parameter        | Type   | Required | Description                                            |
| ---------------- | ------ | -------- | ------------------------------------------------------ |
| `site`           | string | Yes      | The site domain or id.                                 |
| `transaction_id` | string | Yes      | The payment `transaction_id` to delete. Max 255 chars. |

**Returns** — `message` and `deleted` (whether a row was removed).

### `delete-site-tool`

*Writes.*

> Permanently delete one of the current team's sites and queue removal of its analytics events. This cannot be undone.

Requires the **Owner or Admin** role. A regular team Member is tenancy-valid but is rejected with a permission error.

**Parameters**

| Parameter | Type   | Required | Description            |
| --------- | ------ | -------- | ---------------------- |
| `site`    | string | Yes      | The site domain or id. |

**Returns** — `deleted: true` and the deleted site's `domain`.

***

## Tracking features

### `enable-error-tracking-tool`

*Writes.*

> Turn on JavaScript error tracking for one of the current team's sites. Returns the updated site.

**Parameters**

| Parameter | Type   | Required | Description            |
| --------- | ------ | -------- | ---------------------- |
| `site`    | string | Yes      | The site domain or id. |

**Returns** — the updated `site` object.

### `enable-web-vitals-tracking-tool`

*Writes.*

> Turn on Core Web Vitals performance tracking for one of the current team's sites. Returns the updated site.

**Parameters**

| Parameter | Type   | Required | Description            |
| --------- | ------ | -------- | ---------------------- |
| `site`    | string | Yes      | The site domain or id. |

**Returns** — the updated `site` object.

### `enable-session-replay-tracking-tool`

*Writes.*

> Turn on session replay recording for one of the current team's sites. Returns the updated site.

**Parameters**

| Parameter | Type   | Required | Description            |
| --------- | ------ | -------- | ---------------------- |
| `site`    | string | Yes      | The site domain or id. |

**Returns** — the updated `site` object.

### `delete-session-replay-tool`

*Writes.*

> Permanently delete one session replay (its blobs and every ClickHouse row) from one of the current team's sites. This cannot be undone.

**Parameters**

| Parameter    | Type   | Required | Description                                                                    |
| ------------ | ------ | -------- | ------------------------------------------------------------------------------ |
| `site`       | string | Yes      | The site domain or id.                                                         |
| `session_id` | string | Yes      | The id of the session replay to delete. A replay not on this site is rejected. |

**Returns** — `deleted: true` and the `session_id`.

***

## Goals

### `create-goal-tool`

*Writes.*

> Create a goal on one of the current team's sites. Choose a match\_type (page, event, scroll, outbound, download, button, form, or copy) and an optional match\_value to scope it — e.g. a page path for a page/scroll goal, a custom event name for an event goal, or a link/file/label selector for an autocapture goal. A scroll goal also requires scroll\_threshold. Returns the created goal.

**Parameters**

| Parameter          | Type   | Required    | Description                                                                                                                                                                                                                                              |
| ------------------ | ------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `site`             | string | Yes         | The site domain or id.                                                                                                                                                                                                                                   |
| `match_type`       | string | Yes         | The goal kind: `page`, `event`, `scroll`, `outbound`, `download`, `button`, `form`, or `copy`.                                                                                                                                                           |
| `match_value`      | string | Conditional | Selector that scopes the goal — a page path (`page`/`scroll`), a custom event name (`event`), or a link/file/label selector (autocapture). Required for `page`/`scroll`/`event`; omit on an autocapture goal to match any event of that kind.            |
| `match_operator`   | string | No          | How `match_value` is compared: `is`, `is_not`, `contains`, `does_not_contain`, `starts_with`, `ends_with`, `matches_pattern` (`*`/`**` wildcards), or `matches_regex`. Omit to use the type default (`is` for event goals, `matches_pattern` otherwise). |
| `scroll_threshold` | int    | Conditional | Scroll depth 0–100 — required for a `scroll` goal, omitted otherwise.                                                                                                                                                                                    |
| `display_name`     | string | No          | Optional label; derived from the match type and value when omitted.                                                                                                                                                                                      |
| `currency`         | string | No          | Currency for a revenue event goal; must match the site's reporting currency.                                                                                                                                                                             |
| `custom_props`     | object | No          | Map of custom event property name → value (event goals only).                                                                                                                                                                                            |

**Returns** — a `goal` object: `id`, `display_name`, `type`, `match_value`, `match_operator`, `scroll_threshold`, `currency`, `custom_props`, `created_at`.

### `update-goal-tool`

*Writes.*

> Update a goal's full definition on one of the current team's sites — its match type, match value, match operator, scroll threshold, display name, currency and custom property filters. Metrics recompute live from the new definition. Returns the updated goal.

**Parameters**

| Parameter          | Type   | Required    | Description                                                                                                                      |
| ------------------ | ------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `site`             | string | Yes         | The site domain or id.                                                                                                           |
| `goal`             | string | Yes         | The id of the goal to update. A goal not on this site is rejected.                                                               |
| `match_type`       | string | Yes         | The goal kind: `page`, `event`, `scroll`, `outbound`, `download`, `button`, `form`, or `copy`.                                   |
| `match_value`      | string | No          | Selector to scope the goal — a page path, a custom event name, or an autocapture selector. Omit to match any event of that type. |
| `match_operator`   | string | No          | How `match_value` is compared (same options as `create-goal-tool`). Omit to use the type default.                                |
| `scroll_threshold` | int    | Conditional | Scroll depth 0–100 — required for a `scroll` goal, omitted otherwise.                                                            |
| `display_name`     | string | No          | Optional label; derived from the match type and value when omitted.                                                              |
| `currency`         | string | No          | Currency for a revenue event goal; must match the site's reporting currency.                                                     |
| `custom_props`     | object | No          | Map of custom event property name → value (event goals only).                                                                    |

**Returns** — the updated `goal` object (same fields as `create-goal-tool`).

### `batch-create-event-goals-tool`

*Writes.*

> Create one event goal per given name on one of the current team's sites in a single call, skipping any name that already exists as a goal or otherwise fails validation. Returns the number created and the site's full goal list.

**Parameters**

| Parameter     | Type      | Required | Description                                                   |
| ------------- | --------- | -------- | ------------------------------------------------------------- |
| `site`        | string    | Yes      | The site domain or id.                                        |
| `event_names` | string\[] | Yes      | List of custom event names to create as goals (at least one). |

**Returns** — `created` (the number of goals created) and a `goals` array of the site's full goal list.

### `delete-goal-tool`

*Writes.*

> Delete a goal from one of the current team's sites. Funnels are unaffected — their steps carry their own inline match definitions. This cannot be undone.

**Parameters**

| Parameter | Type   | Required | Description                                                        |
| --------- | ------ | -------- | ------------------------------------------------------------------ |
| `site`    | string | Yes      | The site domain or id.                                             |
| `goal_id` | string | Yes      | The id of the goal to delete. A goal not on this site is rejected. |

**Returns** — `deleted: true` and the `goal_id`.

***

## Funnels

### `create-funnel-tool`

*Writes.*

> Create a funnel on one of the current team's sites from an ordered list of 2-8 inline steps. Each step is a type + optional value; array position is the step order. Returns the created funnel.

**Parameters**

| Parameter      | Type      | Required | Description                                                                                                                                                                                                                                                                                               |
| -------------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `site`         | string    | Yes      | The site domain or id.                                                                                                                                                                                                                                                                                    |
| `name`         | string    | Yes      | The funnel name (unique within the site).                                                                                                                                                                                                                                                                 |
| `steps`        | object\[] | Yes      | Ordered 2–8 steps; array position is the step order. Each step: `match_type` (one of `page`, `event`, `scroll`, `outbound`, `download`, `button`, `form`, `copy`), `match_value` (required for page/event/scroll; optional for autocapture types), `scroll_threshold` (required 0–100 for a scroll step). |
| `strict_order` | bool      | No       | Whether steps must be completed in the given order (default false).                                                                                                                                                                                                                                       |

**Returns** — a `funnel` object: `id`, `name`, `strict_order`, `steps`, `created_at`.

### `update-funnel-tool`

*Writes.*

> Update a funnel on one of the current team's sites. Steps are replaced wholesale from an ordered list of inline step definitions (array position is the step order). Returns the updated funnel.

**Parameters**

| Parameter      | Type      | Required | Description                                                                                                      |
| -------------- | --------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
| `site`         | string    | Yes      | The site domain or id.                                                                                           |
| `funnel_id`    | string    | Yes      | The id of the funnel to update. A funnel not on this site is rejected.                                           |
| `name`         | string    | No       | The funnel name (unique within the site).                                                                        |
| `steps`        | object\[] | No       | Ordered 2–8 inline step definitions (same shape as `create-funnel-tool`); replaces the existing steps wholesale. |
| `strict_order` | bool      | No       | Whether steps must be completed in the given order (default false).                                              |

**Returns** — the updated `funnel` object.

### `delete-funnel-tool`

*Writes.*

> Delete a funnel from one of the current team's sites. Its steps are removed with it. This cannot be undone.

**Parameters**

| Parameter   | Type   | Required | Description                                                            |
| ----------- | ------ | -------- | ---------------------------------------------------------------------- |
| `site`      | string | Yes      | The site domain or id.                                                 |
| `funnel_id` | string | Yes      | The id of the funnel to delete. A funnel not on this site is rejected. |

**Returns** — `deleted: true` and the `funnel_id`.

***

## Annotations

### `create-annotation-tool`

*Writes.*

> Pin a new annotation to one of the current team's site charts. An annotation marks a date on the charts with a note (e.g. "launched pricing change", "ran a promo"). Provide the instant to anchor it to (annotated\_at) and the note text (body). Returns the created annotation.

The token must be associated with a user (the annotation's author); a user-less token is rejected.

**Parameters**

| Parameter      | Type   | Required | Description                                                                                              |
| -------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------- |
| `site`         | string | Yes      | The site domain or id.                                                                                   |
| `annotated_at` | string | Yes      | The instant the note is pinned to, as an ISO 8601 datetime (e.g. `2026-07-15T00:00:00Z`). Stored in UTC. |
| `body`         | string | Yes      | The note text shown on the chart marker. Max 10000 chars.                                                |

**Returns** — the created `annotation` object.

### `update-annotation-tool`

*Writes.*

> Edit the note text of an annotation on one of the current team's site charts. An annotation marks a date on the charts with a note; only the body can change — its anchor date is fixed. Returns the updated annotation.

Requires you be the annotation's **author, or a team Admin/Owner**; anyone else is rejected with a permission error.

**Parameters**

| Parameter    | Type   | Required | Description                                                       |
| ------------ | ------ | -------- | ----------------------------------------------------------------- |
| `site`       | string | Yes      | The site domain or id.                                            |
| `annotation` | string | Yes      | The id of the annotation to update. Not on this site is rejected. |
| `body`       | string | Yes      | The new note text. Max 10000 chars.                               |

**Returns** — the updated `annotation` object.

### `delete-annotation-tool`

*Writes.*

> Delete an annotation from one of the current team's site charts. An annotation marks a date on the charts with a note; removing it clears that chart marker. This cannot be undone.

Requires you be the annotation's **author, or a team Admin/Owner**; anyone else is rejected with a permission error.

**Parameters**

| Parameter       | Type   | Required | Description                                                       |
| --------------- | ------ | -------- | ----------------------------------------------------------------- |
| `site`          | string | Yes      | The site domain or id.                                            |
| `annotation_id` | string | Yes      | The id of the annotation to delete. Not on this site is rejected. |

**Returns** — `deleted: true` and the `annotation_id`.

***

## Stripe

### `connect-stripe-integration-tool`

*Writes.*

> Connect (or reconnect) one of the current team's sites to Stripe. The "key" argument must be a Stripe RESTRICTED SECRET KEY (starts with rk\_live\_, or rk\_test\_ outside production) — it is stored ENCRYPTED and is never returned by any tool. An invalid key, a wrong prefix (sk\_/pk\_), or a test key used in production is REJECTED with a validation error. On success this also starts importing the account's product list. Returns the connection status (never the key).

The key is a Stripe **restricted secret key** (`rk_live_…`, or `rk_test_…` outside production). It is **stored encrypted and never returned** by any tool. A wrong prefix (`sk_`/`pk_`), an invalid key, or a test key in production is rejected. On success the account's product list starts importing.

**Parameters**

| Parameter | Type   | Required | Description                                                                                                        |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------ |
| `site`    | string | Yes      | The site domain or id.                                                                                             |
| `key`     | string | Yes      | A Stripe restricted secret key (`rk_live_…`, or `rk_test_…` outside production). Stored encrypted; never returned. |

**Returns** — an `integration` connection-status object. The key is never included.

### `disconnect-stripe-integration-tool`

*Writes.*

> Disconnect one of the current team's sites' Stripe integration: wipes Stripe-derived payments, subscriptions, and MRR movements, best-effort deletes the remote webhook, then deletes the local integration row. API/manual payments are kept. This cannot be undone.

**Parameters**

| Parameter | Type   | Required | Description            |
| --------- | ------ | -------- | ---------------------- |
| `site`    | string | Yes      | The site domain or id. |

**Returns** — an `integration` object with `connected: false`.

### `update-stripe-product-selection-tool`

*Writes.*

> Set which Stripe products count as revenue for a site (the ingestion allowlist), then start importing the account's Stripe history. Pass the full list of product external ids to keep; an empty list is valid and simply stops future ingestion. The allowlist filters ingestion only — it never removes already-imported history. Returns the Stripe connection status including live backfill progress.

**Parameters**

| Parameter  | Type      | Required | Description                                                                                                               |
| ---------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `site`     | string    | Yes      | The site domain or id. Must have a Stripe integration connected.                                                          |
| `products` | string\[] | Yes      | The full list of Stripe product external ids to keep in the allowlist. An empty list is valid and stops future ingestion. |

**Returns** — an `integration` object including live backfill progress.

### `align-site-currency-tool`

*Writes.*

> Set a site's reporting currency to its connected Stripe account's settlement currency, so the site's revenue always reconciles with the merchant's Stripe statement. Pass the three-letter ISO 4217 code (e.g. "EUR"). Returns the Stripe connection status.

**Parameters**

| Parameter  | Type   | Required | Description                                         |
| ---------- | ------ | -------- | --------------------------------------------------- |
| `site`     | string | Yes      | The site domain or id.                              |
| `currency` | string | Yes      | A three-letter ISO 4217 currency code (e.g. `EUR`). |

**Returns** — an `integration` connection-status object.

### `retry-stripe-resource-sync-tool`

*Writes.*

> Retry a failed or stranded Stripe backfill resource for a site. This RESUMES the import from where it stopped (its persisted cursor) — it never restarts from the beginning, so it will not re-import everything. Valid resources: products, charges, refunds, disputes, invoices, subscriptions, customers. The resource must already have a sync row. Returns the Stripe connection status including live progress.

This **resumes** the import from its persisted cursor — it never restarts from page zero, so nothing is re-imported. The site must have a Stripe integration connected, and the resource must already have a sync row (otherwise the call is rejected).

**Parameters**

| Parameter  | Type   | Required | Description                                                                                                                    |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `site`     | string | Yes      | The site domain or id. Must have a Stripe integration connected.                                                               |
| `resource` | string | Yes      | The Stripe resource to resume — one of `products`, `charges`, `refunds`, `disputes`, `invoices`, `subscriptions`, `customers`. |

**Returns** — an `integration` object including live sync progress.
