# Context and voice actions

> Context and voice: 10 Xholic actions (3 read, 7 change), each with its MCP tool, REST endpoint and CLI command.

Source: https://docs.xholic.ai/actions/context/

10 actions. Every field marked *Required* must be sent; `account`, `dryRun`, `idempotencyKey`, `confirmCredits` and `quoteId` are the [control fields](/api/responses/#control-fields) every surface adds.

## Writing kit

`context.writing_kit` · read

Material for writing posts in the user's voice: real posts that worked (their own winners, their circle this week, bookmarks, library outliers) to build each new post from, fresh facts and takes, and what they posted lately so you don't repeat it. Write the posts yourself from this kit, one subject per post, then run check_draft. Never copy a source post's claims or numbers as the user's own.

- **MCP tool:** `get_writing_kit`. Loaded by default in MCP clients.
- **REST:** `GET /v1/context/writing-kit`
- **CLI:** `xholic context writing-kit`
- **Scope:** `read`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `read`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `topic` | string ≤ 200 chars | No | Optional subject to pull material for. |
| `limit` | integer 1–20 | No |  |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |

## Update account context

`context.update` · write

Change the account's audience, goals, product context, topics or rules that every Xholic writer reads. Call it only when the user asked for this in the conversation; never on your own initiative.

- **MCP tool:** `update_account_context`. Catalog: reach it with `find_actions` and `run_write_action`, or turn on the full toolset.
- **REST:** `POST /v1/context/update`
- **CLI:** `xholic context update`
- **Scope:** `write`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `write`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `targetAudience` | string ≤ 2000 chars or null | No |  |
| `contentGoals` | string ≤ 2000 chars or null | No |  |
| `productContext` | string ≤ 6000 chars or null | No |  |
| `selectedTopics` | array of string ≤ 120 chars (max 30) | No |  |
| `accountRules` | string ≤ 500 chars or null | No | The account's writing rules, applied to every draft: short lines such as "No hashtags." At most 500 characters, so keep only the rules that matter most. Replaces the saved rules, so include any existing rules to keep. Null clears them. |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |
| `dryRun` | boolean | No | Return exactly what would happen without doing it. |
| `idempotencyKey` | string ≤ 200 chars | No | A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice. |

## Products and context

`context.products` · read

The account's saved products with their facts (what it is, audience, features, proof), analysis limits and removal notices. Writers and Signals read these facts.

- **MCP tool:** `context_products`. Catalog: reach it with `find_actions` and `run_read_action`, or turn on the full toolset.
- **REST:** `GET /v1/context/products`
- **CLI:** `xholic context products`
- **Scope:** `read`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `read`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |

## Product from the bio link

`context.bio_product_suggestion` · read

The link in the account's X bio when it isn't a saved product yet, so it can be added with context.add_product.

- **MCP tool:** `context_bio_product_suggestion`. Catalog: reach it with `find_actions` and `run_read_action`, or turn on the full toolset.
- **REST:** `GET /v1/context/bio-product-suggestion`
- **CLI:** `xholic context bio-product-suggestion`
- **Scope:** `read`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `read`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |

## Add a product

`context.add_product` · write

Add a product by its website URL. Xholic reads the site and saves its facts; this counts against the plan's daily product analyses. Call it only when the user asked for this in the conversation; never on your own initiative.

- **MCP tool:** `context_add_product`. Catalog: reach it with `find_actions` and `run_write_action`, or turn on the full toolset.
- **REST:** `POST /v1/context/add-product`
- **CLI:** `xholic context add-product`
- **Scope:** `write`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `write`
- **Undo:** from the activity log, which runs `context.delete_product`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string ≤ 2048 chars | Yes | The product's website. |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |
| `dryRun` | boolean | No | Return exactly what would happen without doing it. |
| `idempotencyKey` | string ≤ 200 chars | No | A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice. |

**Example: Add a product**

```bash
curl https://api.xholic.ai/v1/context/add-product \
  -H "Authorization: Bearer $XHOLIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}'
```

## Refresh a product

`context.refresh_product` · write

Read the product's website again and update its facts. Counts against the plan's daily product analyses. Call it only when the user asked for this in the conversation; never on your own initiative.

- **MCP tool:** `context_refresh_product`. Catalog: reach it with `find_actions` and `run_write_action`, or turn on the full toolset.
- **REST:** `POST /v1/context/refresh-product`
- **CLI:** `xholic context refresh-product`
- **Scope:** `write`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `write`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productId` | string ≤ 120 chars | Yes | Product id from context.products. |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |
| `dryRun` | boolean | No | Return exactly what would happen without doing it. |
| `idempotencyKey` | string ≤ 200 chars | No | A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice. |

## Product auto-refresh

`context.set_product_auto_refresh` · write

Choose whether a product keeps refreshing automatically after its facts were edited by hand. Call it only when the user asked for this in the conversation; never on your own initiative.

- **MCP tool:** `context_set_product_auto_refresh`. Catalog: reach it with `find_actions` and `run_write_action`, or turn on the full toolset.
- **REST:** `POST /v1/context/set-product-auto-refresh`
- **CLI:** `xholic context set-product-auto-refresh`
- **Scope:** `write`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `write`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productId` | string ≤ 120 chars | Yes | Product id from context.products. |
| `whenEdited` | boolean | Yes |  |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |
| `dryRun` | boolean | No | Return exactly what would happen without doing it. |
| `idempotencyKey` | string ≤ 200 chars | No | A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice. |

## Edit product facts

`context.update_product` · write

Replace a product's facts. Read them with context.products, change what the user asked, and send the whole structuredFacts object back: lists left out are cleared. Call it only when the user asked for this in the conversation; never on your own initiative.

- **MCP tool:** `context_update_product`. Catalog: reach it with `find_actions` and `run_write_action`, or turn on the full toolset.
- **REST:** `POST /v1/context/update-product`
- **CLI:** `xholic context update-product`
- **Scope:** `write`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `write`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productId` | string ≤ 120 chars | Yes | Product id from context.products. |
| `structuredFacts` | object | Yes | The product's full facts object (name, tagline, summary, audience, features, benefits, proofPoints...) as context.products returns it. |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |
| `dryRun` | boolean | No | Return exactly what would happen without doing it. |
| `idempotencyKey` | string ≤ 200 chars | No | A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice. |

## Remove a product

`context.delete_product` · write

Remove a product from the account's context. Writers and Signals stop using it. Call it only when the user asked for this in the conversation; never on your own initiative.

- **MCP tool:** `context_delete_product`. Catalog: reach it with `find_actions` and `run_write_action`, or turn on the full toolset.
- **REST:** `POST /v1/context/delete-product`
- **CLI:** `xholic context delete-product`
- **Scope:** `write`. Destructive: it can't be taken back
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `write`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productId` | string ≤ 120 chars | Yes | Product id from context.products. |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |
| `dryRun` | boolean | No | Return exactly what would happen without doing it. |
| `idempotencyKey` | string ≤ 200 chars | No | A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice. |

## Dismiss a removal notice

`context.dismiss_product_notice` · write

Hide the notice that a product was removed automatically.

- **MCP tool:** `context_dismiss_product_notice`. Catalog: reach it with `find_actions` and `run_write_action`, or turn on the full toolset.
- **REST:** `POST /v1/context/dismiss-product-notice`
- **CLI:** `xholic context dismiss-product-notice`
- **Scope:** `write`
- **Plan:** Every plan, including the trial
- **Cost:** Free.
- **Rate limit bucket:** `write`

**Input**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productId` | string ≤ 120 chars | Yes | Product id from context.products. |
| `account` | string ≤ 64 chars | No | X account to act on, as @handle. Leave it out to use the connection's default account. |
| `dryRun` | boolean | No | Return exactly what would happen without doing it. |
| `idempotencyKey` | string ≤ 200 chars | No | A unique key for this write. Repeating a call with the same key returns the first result instead of acting twice. |
