# MCP: site

Source: <https://telegafirst.com/docs/mcp-site>
Locale: ru
releaseGitSha: c9a428d902de0b479a981e43774f38b9ec077ed7
sourceContentDigest: 9c9579dcf4f893055aeb6785c8c8f8f0c1ee53d7b8ce69abb4c9837f255af156
Version: 1

# MCP: site

Это определения инструментов из текущего ToolRegistry, включая полные inputSchema/outputSchema, scope, required\_scopes (ALL), risk и версию платформы. Наличие определения не означает, что инструмент уже установлен вашим хостом или разрешён вашим credential. Обновляйте tools/list после изменения бизнеса, readiness и прав. Progressive disclosure через load\_domain/describe\_tool и существующий meta-dispatch описаны в [MCP-руководстве](https://telegafirst.com/docs/mcp-guide). [Scopes и права](https://telegafirst.com/docs/scopes-and-permissions) применяются при вызове; risk не заменяет согласие и отдельные требования денежной операции. JSON ниже — схема, а не успешный результат вызова.

## secret\_delete

Delete a stored secret by name. REQUIRES THE OWNER'S CONFIRMATION — same two-call handshake as `secret_put`: once without `action_id` to ask, then again with the returned `action_id` once they confirm. Anything still configured to use that name stops working at once, and the value cannot be recovered — the name simply becomes free again.

```json
{
  "description": "Delete a stored secret by name. REQUIRES THE OWNER'S CONFIRMATION — same two-call handshake as `secret_put`: once without `action_id` to ask, then again with the returned `action_id` once they confirm. Anything still configured to use that name stops working at once, and the value cannot be recovered — the name simply becomes free again.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "action_id": {
        "description": "Value for action id.",
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        "type": "string"
      },
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "name": {
        "description": "Value for name.",
        "maxLength": 128,
        "minLength": 1,
        "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
        "type": "string"
      }
    },
    "required": [
      "name"
    ],
    "type": "object"
  },
  "name": "secret_delete",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "destructive",
  "scope": "site:write",
  "title": "Secret Delete"
}
```

## secret\_list

List the NAMES of the secrets stored for the business's hosted site, with when each was stored and last rotated. Values are never returned — there is no parameter that changes that. Use it to check whether a name exists before wiring a form handler or relay to it. 0-cost read.

```json
{
  "description": "List the NAMES of the secrets stored for the business's hosted site, with when each was stored and last rotated. Values are never returned — there is no parameter that changes that. Use it to check whether a name exists before wiring a form handler or relay to it. 0-cost read.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {},
    "type": "object"
  },
  "name": "secret_list",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:read"
  ],
  "risk": "read",
  "scope": "site:read",
  "title": "Secret List"
}
```

## secret\_put

Store a NEW secret for the business's hosted site (an API token its pages or form handlers call out with). REQUIRES THE OWNER'S CONFIRMATION: call it once without `action_id` and you get back `pending_approval` with an `action_id` — the owner is asked in Telegram to confirm storing a secret under this name. Once they confirm, call again with the SAME `action_id` and the same value, and it is stored. Nothing is kept between the two calls. The value is encrypted at rest and is NEVER returned by any tool — not by this one, not by `secret_list`. A name that already holds a live secret is a conflict: use `secret_rotate` to change a value, or `secret_delete` first to re-use the name.

```json
{
  "description": "Store a NEW secret for the business's hosted site (an API token its pages or form handlers call out with). REQUIRES THE OWNER'S CONFIRMATION: call it once without `action_id` and you get back `pending_approval` with an `action_id` — the owner is asked in Telegram to confirm storing a secret under this name. Once they confirm, call again with the SAME `action_id` and the same value, and it is stored. Nothing is kept between the two calls. The value is encrypted at rest and is NEVER returned by any tool — not by this one, not by `secret_list`. A name that already holds a live secret is a conflict: use `secret_rotate` to change a value, or `secret_delete` first to re-use the name.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "action_id": {
        "description": "Value for action id.",
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        "type": "string"
      },
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "name": {
        "description": "Value for name.",
        "maxLength": 128,
        "minLength": 1,
        "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
        "type": "string"
      },
      "value": {
        "description": "Value for value.",
        "maxLength": 8192,
        "minLength": 1,
        "type": "string"
      }
    },
    "required": [
      "name",
      "value"
    ],
    "type": "object"
  },
  "name": "secret_put",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Secret Put"
}
```

## secret\_rotate

Replace the value stored under an existing secret name. REQUIRES THE OWNER'S CONFIRMATION — same two-call handshake as `secret_put`: once without `action_id` to ask, then again with the returned `action_id` and the value once they confirm. The name does not change (it cannot — it is bound into the encryption of the value). Everything already wired to this name picks up the new value on its next use, so rotate only when the old credential is being retired.

```json
{
  "description": "Replace the value stored under an existing secret name. REQUIRES THE OWNER'S CONFIRMATION — same two-call handshake as `secret_put`: once without `action_id` to ask, then again with the returned `action_id` and the value once they confirm. The name does not change (it cannot — it is bound into the encryption of the value). Everything already wired to this name picks up the new value on its next use, so rotate only when the old credential is being retired.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "action_id": {
        "description": "Value for action id.",
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        "type": "string"
      },
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "name": {
        "description": "Value for name.",
        "maxLength": 128,
        "minLength": 1,
        "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
        "type": "string"
      },
      "value": {
        "description": "Value for value.",
        "maxLength": 8192,
        "minLength": 1,
        "type": "string"
      }
    },
    "required": [
      "name",
      "value"
    ],
    "type": "object"
  },
  "name": "secret_rotate",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Secret Rotate"
}
```

## site\_checkout\_key

Get the PUBLIC key the business's checkout page uses to start an order from its own website. Paste the returned key into the page — it is designed to sit in page source where every visitor can read it, and it can do exactly one thing: start a checkout for a form the business configured. It can read nothing. Calling this again REPLACES the key: the previous one keeps working for 24 hours so an already-published page does not break before you redeploy it. The key is shown ONCE — it cannot be retrieved later, only replaced. Which website addresses may use it is set per form (`allowed_origins`), not here.

```json
{
  "description": "Get the PUBLIC key the business's checkout page uses to start an order from its own website. Paste the returned key into the page — it is designed to sit in page source where every visitor can read it, and it can do exactly one thing: start a checkout for a form the business configured. It can read nothing. Calling this again REPLACES the key: the previous one keeps working for 24 hours so an already-published page does not break before you redeploy it. The key is shown ONCE — it cannot be retrieved later, only replaced. Which website addresses may use it is set per form (`allowed_origins`), not here.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      }
    },
    "type": "object"
  },
  "name": "site_checkout_key",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Site Checkout Key"
}
```

## site\_execute\_delete

Delete the deployed site identified by a matching prepared scenario. Call this tool only after final human confirmation of the prepared scenario.

```json
{
  "description": "Delete the deployed site identified by a matching prepared scenario. Call this tool only after final human confirmation of the prepared scenario.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "payload_hash": {
        "description": "Value for payload hash.",
        "pattern": "^[a-f0-9]{64}$",
        "type": "string"
      },
      "preparation_id": {
        "description": "Value for preparation id.",
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        "type": "string"
      }
    },
    "required": [
      "preparation_id",
      "payload_hash"
    ],
    "type": "object"
  },
  "name": "site_execute_delete",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "destructive",
  "scope": "site:write",
  "title": "Site Execute Delete"
}
```

## site\_fetch\_file

Read one UTF-8 file from a deployed site bundle. Use `site_get_manifest` first to discover its exact path and checksum. This returns page/source text for editing; platform access-policy configuration is intentionally not readable through this tool. After editing, publish the complete bundle through `site_request_upload` and `site_publish`: Delta Sync uploads only the changed file.

```json
{
  "description": "Read one UTF-8 file from a deployed site bundle. Use `site_get_manifest` first to discover its exact path and checksum. This returns page/source text for editing; platform access-policy configuration is intentionally not readable through this tool. After editing, publish the complete bundle through `site_request_upload` and `site_publish`: Delta Sync uploads only the changed file.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "host": {
        "description": "Value for host.",
        "maxLength": 253,
        "minLength": 4,
        "pattern": "^(?=.{4,253}$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+\\.?$",
        "type": "string"
      },
      "path": {
        "description": "Value for path.",
        "maxLength": 512,
        "minLength": 1,
        "type": "string"
      }
    },
    "required": [
      "host",
      "path"
    ],
    "type": "object"
  },
  "name": "site_fetch_file",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:read"
  ],
  "risk": "read",
  "scope": "site:read",
  "title": "Site Fetch File"
}
```

## site\_form\_declare

Declare a form the business's web pages submit to, and get the address they post to. DO THIS BEFORE BUILDING THE PAGES: the call returns `clientSlug` and `code`, the pages POST to `https://fn.telegafirst.ru/f/{clientSlug}/{code}` (`fn.telegafirst.com` when `zone` is `com`). That URL cannot exist before this call. It also returns `seqNum`: pass it back to UPDATE this declaration — `clientSlug` + `code` stay the same, so re-running setup never breaks live pages. Omit `seqNum` to create a NEW form with a NEW address. It configures the ENVELOPE (delivery, allowed submitter origins, captcha), NOT the form's fields: draw any inputs in your HTML, stored exactly as submitted. `destinations` lists delivery targets, one of: `{"kind":"telegram","topicId":<topic id>}`, `{"kind":"webhook","url":"https://…"}`, or `{"kind":"external_api","url":"https://…","method":"POST","headerName":"X-Api-Key","secretName":"<name from secret_put>"}` — never a literal credential, only the NAME of a stored secret. `allowedOrigins` must list the site's own addresses (`https://acme.ru`), or no submission is accepted. To stop accepting submissions, re-declare with `enabled: false` — never delete (collected answers would lose the config that explains them). AFTER A SUBMISSION the `variants` ladder runs: each names a prepared funnel step by `stepSeqNum` plus a condition — `when` for `funnelMode: "deterministic"` (first match by `sort` order wins) or `hint` (plain language) for `funnelMode: "ai_agent"`; exactly one per entry. `defaultStepSeqNum` is used when nothing matches. `callOperatorOnSubmit: true` (or an entry's `callsOperator: true`) calls a live operator. ⚠️ The ladder is DECLARED, not patched: omitting `variants` on a re-declaration REMOVES it — always send the complete list. `submissionSchema` is OPTIONAL, e.g. `[{"name":"phone","type":"tel","required":true}]`; omit it and any fields are accepted. Pass it only to validate: a non-matching submission is refused, naming the wrong field; names must match your HTML inputs.

```json
{
  "description": "Declare a form the business's web pages submit to, and get the address they post to. DO THIS BEFORE BUILDING THE PAGES: the call returns `clientSlug` and `code`, the pages POST to `https://fn.telegafirst.ru/f/{clientSlug}/{code}` (`fn.telegafirst.com` when `zone` is `com`). That URL cannot exist before this call. It also returns `seqNum`: pass it back to UPDATE this declaration — `clientSlug` + `code` stay the same, so re-running setup never breaks live pages. Omit `seqNum` to create a NEW form with a NEW address. It configures the ENVELOPE (delivery, allowed submitter origins, captcha), NOT the form's fields: draw any inputs in your HTML, stored exactly as submitted. `destinations` lists delivery targets, one of: `{\"kind\":\"telegram\",\"topicId\":<topic id>}`, `{\"kind\":\"webhook\",\"url\":\"https://…\"}`, or `{\"kind\":\"external_api\",\"url\":\"https://…\",\"method\":\"POST\",\"headerName\":\"X-Api-Key\",\"secretName\":\"<name from secret_put>\"}` — never a literal credential, only the NAME of a stored secret. `allowedOrigins` must list the site's own addresses (`https://acme.ru`), or no submission is accepted. To stop accepting submissions, re-declare with `enabled: false` — never delete (collected answers would lose the config that explains them). AFTER A SUBMISSION the `variants` ladder runs: each names a prepared funnel step by `stepSeqNum` plus a condition — `when` for `funnelMode: \"deterministic\"` (first match by `sort` order wins) or `hint` (plain language) for `funnelMode: \"ai_agent\"`; exactly one per entry. `defaultStepSeqNum` is used when nothing matches. `callOperatorOnSubmit: true` (or an entry's `callsOperator: true`) calls a live operator. ⚠️ The ladder is DECLARED, not patched: omitting `variants` on a re-declaration REMOVES it — always send the complete list. `submissionSchema` is OPTIONAL, e.g. `[{\"name\":\"phone\",\"type\":\"tel\",\"required\":true}]`; omit it and any fields are accepted. Pass it only to validate: a non-matching submission is refused, naming the wrong field; names must match your HTML inputs.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "allowedOrigins": {
        "description": "Value for allowed Origins.",
        "items": {
          "description": "Value for allowed Origins item.",
          "maxLength": 255,
          "minLength": 1,
          "type": "string"
        },
        "maxItems": 20,
        "type": "array"
      },
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "callOperatorOnSubmit": {
        "description": "Value for call Operator On Submit.",
        "type": "boolean"
      },
      "captchaRequired": {
        "description": "Value for captcha Required.",
        "type": "boolean"
      },
      "catalogSeqNum": {
        "anyOf": [
          {
            "description": "Value for catalog Seq Num option.",
            "exclusiveMinimum": 0,
            "maximum": 2147483647,
            "type": "integer"
          },
          {
            "description": "Value for catalog Seq Num option.",
            "type": "null"
          }
        ],
        "description": "Value for catalog Seq Num."
      },
      "defaultStepSeqNum": {
        "anyOf": [
          {
            "description": "Value for default Step Seq Num option.",
            "exclusiveMinimum": 0,
            "maximum": 2147483647,
            "type": "integer"
          },
          {
            "description": "Value for default Step Seq Num option.",
            "type": "null"
          }
        ],
        "description": "Value for default Step Seq Num."
      },
      "destinations": {
        "description": "Value for destinations.",
        "items": {
          "description": "Value for destinations item."
        },
        "maxItems": 20,
        "type": "array"
      },
      "enabled": {
        "description": "Value for enabled.",
        "type": "boolean"
      },
      "funnelAgentPrompt": {
        "anyOf": [
          {
            "description": "Value for funnel Agent Prompt option.",
            "maxLength": 4000,
            "minLength": 1,
            "type": "string"
          },
          {
            "description": "Value for funnel Agent Prompt option.",
            "type": "null"
          }
        ],
        "description": "Value for funnel Agent Prompt."
      },
      "funnelMode": {
        "description": "Value for funnel Mode.",
        "enum": [
          "none",
          "deterministic",
          "ai_agent"
        ],
        "type": "string"
      },
      "funnelOutcome": {
        "description": "Value for funnel Outcome.",
        "enum": [
          "content",
          "checkout"
        ],
        "type": "string"
      },
      "seqNum": {
        "anyOf": [
          {
            "description": "Value for seq Num option.",
            "exclusiveMinimum": 0,
            "maximum": 2147483647,
            "type": "integer"
          },
          {
            "description": "Value for seq Num option.",
            "type": "null"
          }
        ],
        "description": "Value for seq Num."
      },
      "submissionSchema": {
        "anyOf": [
          {
            "description": "Value for submission Schema option.",
            "items": {
              "description": "Value for submission Schema option item."
            },
            "maxItems": 100,
            "type": "array"
          },
          {
            "description": "Value for submission Schema option.",
            "type": "null"
          }
        ],
        "description": "Value for submission Schema."
      },
      "title": {
        "description": "Value for title.",
        "maxLength": 200,
        "minLength": 1,
        "type": "string"
      },
      "variants": {
        "description": "Value for variants.",
        "items": {
          "additionalProperties": false,
          "description": "Value for variants item.",
          "properties": {
            "callsOperator": {
              "description": "Value for calls Operator.",
              "type": "boolean"
            },
            "hint": {
              "anyOf": [
                {
                  "description": "Value for hint option.",
                  "maxLength": 500,
                  "minLength": 1,
                  "type": "string"
                },
                {
                  "description": "Value for hint option.",
                  "type": "null"
                }
              ],
              "description": "Value for hint."
            },
            "sort": {
              "description": "Value for sort.",
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            },
            "stepSeqNum": {
              "description": "Value for step Seq Num.",
              "exclusiveMinimum": 0,
              "maximum": 2147483647,
              "type": "integer"
            },
            "when": {
              "description": "Value for when."
            }
          },
          "required": [
            "stepSeqNum"
          ],
          "type": "object"
        },
        "maxItems": 50,
        "type": "array"
      },
      "zone": {
        "description": "Value for zone.",
        "enum": [
          "ru",
          "com"
        ],
        "type": "string"
      }
    },
    "required": [
      "zone",
      "title"
    ],
    "type": "object"
  },
  "name": "site_form_declare",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Site Form Declare"
}
```

## site\_get\_analytics

Read the daily analytics rollup for this business's own hosted site. It returns total page views, tab sessions (the historical `views_unique` / `unique` names do NOT mean unique visitors), bot-link clicks, pages, referrer hostnames, UTM labels and click actions. It reads durable daily rollups, not the live event buffer, and costs no tokens. Omit `days` for the latest 7 days; requests above 30 days are bounded to 30. Optionally pass `page_path` to report one published page. There is intentionally no `host` argument: this call is scoped to the authenticated tenant's own site.

```json
{
  "description": "Read the daily analytics rollup for this business's own hosted site. It returns total page views, tab sessions (the historical `views_unique` / `unique` names do NOT mean unique visitors), bot-link clicks, pages, referrer hostnames, UTM labels and click actions. It reads durable daily rollups, not the live event buffer, and costs no tokens. Omit `days` for the latest 7 days; requests above 30 days are bounded to 30. Optionally pass `page_path` to report one published page. There is intentionally no `host` argument: this call is scoped to the authenticated tenant's own site.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "days": {
        "description": "Value for days.",
        "exclusiveMinimum": 0,
        "maximum": 9007199254740991,
        "type": "integer"
      },
      "page_path": {
        "description": "Value for page path.",
        "maxLength": 255,
        "minLength": 1,
        "type": "string"
      }
    },
    "type": "object"
  },
  "name": "site_get_analytics",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:read"
  ],
  "risk": "read",
  "scope": "site:read",
  "title": "Site Get Analytics"
}
```

## site\_get\_manifest

Read the deployed site bundle manifest for one connected domain. It returns every path with its MD5 checksum and byte size, plus `manifestDigest`. To edit one page, read this first, then use `site_fetch_file` for that page; when you publish, still declare and stage the COMPLETE bundle. The existing checksum Delta Sync writes only files whose bytes changed, so unchanged pages are not re-uploaded. 0-cost read.

```json
{
  "description": "Read the deployed site bundle manifest for one connected domain. It returns every path with its MD5 checksum and byte size, plus `manifestDigest`. To edit one page, read this first, then use `site_fetch_file` for that page; when you publish, still declare and stage the COMPLETE bundle. The existing checksum Delta Sync writes only files whose bytes changed, so unchanged pages are not re-uploaded. 0-cost read.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "host": {
        "description": "Value for host.",
        "maxLength": 253,
        "minLength": 4,
        "pattern": "^(?=.{4,253}$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+\\.?$",
        "type": "string"
      }
    },
    "required": [
      "host"
    ],
    "type": "object"
  },
  "name": "site_get_manifest",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:read"
  ],
  "risk": "read",
  "scope": "site:read",
  "title": "Site Get Manifest"
}
```

## site\_page\_preview

Open a private preview of a tenant page. Returns a short-lived opaque URL on an isolated origin, using stored content without publishing it.

```json
{
  "description": "Open a private preview of a tenant page. Returns a short-lived opaque URL on an isolated origin, using stored content without publishing it.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "seq_num": {
        "description": "Value for seq num.",
        "exclusiveMinimum": 0,
        "maximum": 9007199254740991,
        "type": "integer"
      }
    },
    "required": [
      "seq_num"
    ],
    "type": "object"
  },
  "name": "site_page_preview",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "read",
  "scope": "site:write",
  "title": "Site Page Preview"
}
```

## site\_pages\_set\_visibility

Show or hide existing site pages by their tenant page numbers. Root and system pages are protected. Returns one result per selected page. Hidden desire survives redeployment and tariff restore; showing does not override tariff or moderation.

```json
{
  "description": "Show or hide existing site pages by their tenant page numbers. Root and system pages are protected. Returns one result per selected page. Hidden desire survives redeployment and tariff restore; showing does not override tariff or moderation.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "published": {
        "description": "Value for published.",
        "type": "boolean"
      },
      "seq_nums": {
        "description": "Value for seq nums.",
        "items": {
          "description": "Value for seq nums item.",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991,
          "type": "integer"
        },
        "maxItems": 100,
        "minItems": 1,
        "type": "array"
      }
    },
    "required": [
      "seq_nums",
      "published"
    ],
    "type": "object"
  },
  "name": "site_pages_set_visibility",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Site Pages Set Visibility"
}
```

## site\_prepare\_delete

Prepare deletion of the deployed site at one connected domain. The preparation freezes the current manifest checksum for human review and does not delete anything. Show the returned scenario to a human, then call `site_execute_delete` only if they give final confirmation.

```json
{
  "description": "Prepare deletion of the deployed site at one connected domain. The preparation freezes the current manifest checksum for human review and does not delete anything. Show the returned scenario to a human, then call `site_execute_delete` only if they give final confirmation.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "host": {
        "description": "Value for host.",
        "maxLength": 253,
        "minLength": 4,
        "pattern": "^(?=.{4,253}$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+\\.?$",
        "type": "string"
      }
    },
    "required": [
      "host"
    ],
    "type": "object"
  },
  "name": "site_prepare_delete",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Site Prepare Delete"
}
```

## site\_publish

Step 2 of publishing the site: take the files uploaded under `uploadId` and make them live on the connected domain. Only files that actually differ from what is deployed are written; files the new bundle no longer contains are removed; `index.html` is written LAST so visitors never see a half-swapped site. If the bundle contains `tgf-gate.json`, the access rules in it are applied to the site's gated pages. Returns which paths were written, which were removed and which were already identical. The uploaded files are consumed — to publish again, request fresh upload URLs. It also returns `attributionSnippet`: a one-line `<script>` tag. Paste it into every page of the site that links to the business's bot. Without it, a visitor who taps such a link on this site arrives anonymous and the business cannot tell which page or campaign brought them — the links keep working either way, so nothing looks broken. If the pages you just published do not carry it yet, add it and publish again.

```json
{
  "description": "Step 2 of publishing the site: take the files uploaded under `uploadId` and make them live on the connected domain. Only files that actually differ from what is deployed are written; files the new bundle no longer contains are removed; `index.html` is written LAST so visitors never see a half-swapped site. If the bundle contains `tgf-gate.json`, the access rules in it are applied to the site's gated pages. Returns which paths were written, which were removed and which were already identical. The uploaded files are consumed — to publish again, request fresh upload URLs. It also returns `attributionSnippet`: a one-line `<script>` tag. Paste it into every page of the site that links to the business's bot. Without it, a visitor who taps such a link on this site arrives anonymous and the business cannot tell which page or campaign brought them — the links keep working either way, so nothing looks broken. If the pages you just published do not carry it yet, add it and publish again.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "host": {
        "description": "Value for host.",
        "maxLength": 253,
        "minLength": 4,
        "pattern": "^(?=.{4,253}$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+\\.?$",
        "type": "string"
      },
      "uploadId": {
        "description": "Value for upload Id.",
        "format": "uuid",
        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        "type": "string"
      }
    },
    "required": [
      "host",
      "uploadId"
    ],
    "type": "object"
  },
  "name": "site_publish",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Site Publish"
}
```

## site\_request\_upload

Step 1 of publishing the business's static site to its connected custom domain: declare EVERY file of the bundle (path, byte size, content type) and get back one upload URL per file plus an `uploadId`. Upload each file with an HTTP PUT to its URL — the byte length must match what you declared, or the upload is rejected. Declare the WHOLE site, not just what changed: the platform works out which files actually differ from what is deployed and only writes those. Then call `site_publish` with the same `host` and the `uploadId`. The domain must already be connected to this account (`domain_add_request` → `domain_verify`), and the bundle must fit the plan's size limit — both are checked here, before any URL is issued. Before you build the pages: every page that carries a link to the business's bot should also carry the platform's small attribution script, or the business cannot tell which page or campaign produced a customer. `site_publish` returns the exact `<script>` line to paste — put it in the page template now and you will not need a second deploy to add it.

```json
{
  "description": "Step 1 of publishing the business's static site to its connected custom domain: declare EVERY file of the bundle (path, byte size, content type) and get back one upload URL per file plus an `uploadId`. Upload each file with an HTTP PUT to its URL — the byte length must match what you declared, or the upload is rejected. Declare the WHOLE site, not just what changed: the platform works out which files actually differ from what is deployed and only writes those. Then call `site_publish` with the same `host` and the `uploadId`. The domain must already be connected to this account (`domain_add_request` → `domain_verify`), and the bundle must fit the plan's size limit — both are checked here, before any URL is issued. Before you build the pages: every page that carries a link to the business's bot should also carry the platform's small attribution script, or the business cannot tell which page or campaign produced a customer. `site_publish` returns the exact `<script>` line to paste — put it in the page template now and you will not need a second deploy to add it.",
  "domain": "site",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "bot": {
        "description": "Optional slug of the bot you expect to act on (get_active_bot). If the active bot differs, the call is refused with ACTIVE_BOT_CHANGED and nothing runs.",
        "maxLength": 128,
        "minLength": 1,
        "type": "string"
      },
      "files": {
        "description": "Value for files.",
        "items": {
          "additionalProperties": false,
          "description": "Value for files item.",
          "properties": {
            "contentType": {
              "description": "Value for content Type.",
              "maxLength": 255,
              "minLength": 1,
              "type": "string"
            },
            "path": {
              "description": "Value for path.",
              "maxLength": 512,
              "minLength": 1,
              "type": "string"
            },
            "references": {
              "description": "Value for references.",
              "items": {
                "description": "Value for references item.",
                "maxLength": 512,
                "minLength": 1,
                "type": "string"
              },
              "type": "array"
            },
            "sizeBytes": {
              "description": "Value for size Bytes.",
              "maximum": 9007199254740991,
              "minimum": 0,
              "type": "integer"
            }
          },
          "required": [
            "path",
            "sizeBytes",
            "contentType"
          ],
          "type": "object"
        },
        "minItems": 1,
        "type": "array"
      },
      "host": {
        "description": "Value for host.",
        "maxLength": 253,
        "minLength": 4,
        "pattern": "^(?=.{4,253}$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+\\.?$",
        "type": "string"
      }
    },
    "required": [
      "host",
      "files"
    ],
    "type": "object"
  },
  "name": "site_request_upload",
  "outputSchema": null,
  "platform_version": "1.0.19",
  "required_scopes": [
    "site:write"
  ],
  "risk": "write",
  "scope": "site:write",
  "title": "Site Request Upload"
}
```
