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

# MCP

> Connect an AI client such as Claude Code to Curator with a personal MCP token and the tools it can call.

## Introduction

Curator exposes a Model Context Protocol (MCP) endpoint. An MCP client such as Claude Code or Claude Desktop
connects to it with a personal token and can then call a set of read and administrative tools. If the token
allows them, the client can also call content tools that build pages, navigation, themes, and files.

A token belongs to the backend user who generated it, and it can do nothing that user cannot do. Every tool
call checks the owner's backend permissions when it runs, and every call is recorded in the Usage Log with
the owner's login and the token's prefix.

## Generate a Token

1. Sign in to the backend and open the username dropdown at the top right.
2. Click **MCP Tokens**, then **Generate Token**.
3. Enter a **Name** that says where the token will be used, for example "Laptop Claude Code".
4. Choose when the token **Expires**. The default is 90 days. Choose **Never** only for unattended service
   accounts.
5. Under **Allowed tools**, every read tool is checked. Clear the tools this token must not call. A token with
   every read tool checked also gains read tools added in later releases. Content tools are labeled
   **(changes content)** and are never checked by default. Check each content tool that this token needs.
   A token never gains a content tool unless you check it.
6. Click **Generate**.

The next page shows the full token once. Copy it now: Curator stores only a hash, so the token cannot be
shown again. If you lose it, revoke it and generate a new one.

The same page has a **Connect a client** panel with the endpoint URL and a ready-to-run Claude Code setup
command. After you leave the page, the command shows `<token>` in place of the token.

## Connect a Client

The endpoint is `POST /curator/mcp` on your Curator site, and the token travels as a bearer credential:

```text theme={null}
Authorization: Bearer cmcp_...
```

For Claude Code, run the setup command from the token page in a terminal. It has this form:

```bash theme={null}
claude mcp add --transport http curator https://your-site.example.com/curator/mcp \
  --header "Authorization: Bearer cmcp_..."
```

Any client that speaks the MCP Streamable HTTP transport works the same way: point it at the endpoint URL
and send the token in the `Authorization` header. The endpoint accepts JSON-RPC 2.0 over POST and answers
with JSON. It does not open sessions or server-sent event streams.

## Manage Tokens

**MCP Tokens** lists your tokens with their prefix, allowed tools, expiry, and last use. Open a token to
edit its name or allowed tools; the owner, expiry, and token itself cannot change after generation. Tick one
or more tokens and click **Delete selected** to revoke them. A revoked token stops working at once.

You only see your own tokens. Tokens also stop working when their owner is banned, suspended, deleted, or
past their password expiry. When **Force Backend Users to Login Via Frontend Authentication Forms** is on, a
token also stops working if its owner's **Link to frontend user** switch is off, or if the frontend user with
the owner's username is missing or suspended.

## Tools

Each tool runs with the owner's permissions. A tool the owner cannot use is not offered to the client.

### Read and Administrative Tools

A new token allows every tool in this table. Only `clear_cache` changes the portal, and it clears caches
without changing any content.

| Tool | What it does | Permission |
| - | - | - |
| `get_status` | Curator build, PHP version, environment, and the configured drivers. | Same as the **Status** page |
| `get_info` | The full `/portal/info` report with secrets removed. | Same as the **Status** page |
| `clear_cache` | Clears every Curator cache, like the toolbar's **Clear Cache** button. | Any backend user |
| `get_guide` | Returns a guide that teaches the AI client how to use these tools. | Any backend user |
| `list_pages` | Lists Curator pages. | **Manage pages** or **Manage navigation** |
| `list_files` | Lists files. | **Manage files**, **Manage navigation**, or **Manage pages** |
| `list_keywords` | Lists content keywords. | **Manage keywords** or **Manage pages** |
| `list_menus` | Lists the navigation menu flat, with parent ids, link types, and URLs. | **Manage navigation** or **Manage pages** |
| `list_dashboards` | Lists Tableau dashboards. | **Manage Tableau dashboards** |
| `list_powerbi_reports` | Lists Power BI reports. | Any Power BI permission |
| `list_powerbi_dashboards` | Lists Power BI dashboards. | Any Power BI permission |
| `list_thoughtspot_liveboards` | Lists ThoughtSpot liveboards. | **ThoughtSpot administrator** |
| `list_sigma_workbooks` | Lists Sigma workbooks. | Any Sigma permission |
| `get_page` | Returns a page with its settings, rows, and elements. | **Manage pages** |
| `get_page_element_types` | Describes the page builder elements and the settings each one accepts. | **Manage pages** |
| `preview_file` | Shows an image file as a small picture, so the client can check it. | **Manage files** |
| `list_themes` | Lists themes and shows which one is the Global Theme. | **Manage Curator settings** |
| `get_theme` | Returns a theme's settings and image URLs. | **Manage Curator settings** |
| `get_theme_schema` | Describes every theme setting, its type, and its allowed values. | **Manage Curator settings** |
| `list_mcp_snapshots` | Lists the snapshots saved before MCP changed a page or theme. | **Manage pages** or **Manage Curator settings** |
| `list_api_keys` | Lists REST API keys, with each key masked. | **Manage API keys** |
| `list_api_relays` | Lists the API relays that are available to MCP tools. | **Manage API relay** |
| `get_api_relay` | Returns an API relay's settings, without encrypted constants or credential headers. | **Manage API relay** |

"Same as the **Status** page" means any Portal permission: a user who holds any one Portal permission, such
as managing URL redirects, can call `get_status` and `get_info`, exactly as they can open the Status page.
`get_info` reports server, database, and hosting details, so review who holds a Portal permission before
issuing tokens broadly.

The content list tools, from `list_pages` to `list_sigma_workbooks`, only appear when their plugin is
installed. They take the same optional arguments and return the same shape:

**Arguments:**

**search**

Text to match against the title, case-insensitive. Optional.

**limit**

The maximum number of items to return. Optional, defaults to 100, maximum 500.

**offset**

The number of items to skip, for paging. Optional, defaults to 0.

**Returns:**

```JSON theme={null}
    {
        "total": 42,
        "offset": 0,
        "count": 2,
        "items": [
            {
                "id": 7,
                "title": "Sales Overview",
                "slug": "sales-overview",
                "url": "https://your-site.example.com/dashboard/sales-overview",
                "updated_at": "2026-09-01 14:02:11",
                "project_name": "Finance"
            }
        ]
    }
```

Some tools add a few columns of their own: pages include `content_type`, files include `file_type` and
`hidden`, Tableau dashboards include `project_name` and `featured`, and Power BI items include `group_name`.

### Content Tools

The tools in this table change portal content. A new token does not allow them. The token owner must check
each one under **Allowed tools**, where it is labeled **(changes content)**. The owner also needs the
permission in the table, because the token can do nothing that its owner cannot do.

| Tool | What it does | Permission |
| - | - | - |
| `create_page` | Creates a page. The new page is hidden unless the client passes `hidden: false`. | **Manage pages**, and **Manage navigation** to add a menu item |
| `edit_page_content` | Adds, changes, moves, and removes rows and elements on a page. | **Manage pages** |
| `update_page_settings` | Changes a page's title, slug, description, and visibility. It can publish several pages at once. | **Manage pages** |
| `delete_page` | Deletes a page. | **Manage pages**, and **Manage navigation** when menu items link to the page |
| `create_menu_item` | Adds a navigation menu item. | **Manage navigation** |
| `update_menu_item` | Changes a menu item's title, description, enabled state, and new tab setting, or the URL of an external link. | **Manage navigation** |
| `move_menu_item` | Moves a menu item and its children to a new place in the menu. | **Manage navigation** |
| `delete_menu_item` | Deletes a menu item. | **Manage navigation** |
| `update_theme` | Changes theme settings, such as colors and fonts. | **Manage Curator settings** |
| `set_theme_image` | Sets or removes a theme image, such as the logo or the favicon. | **Manage Curator settings** and **Manage files** |
| `upload_file` | Creates a file from text, from base64 data, or from a public URL. | **Manage files** |
| `create_upload_url` | Returns a single-use URL that accepts a large file. | **Manage files** |
| `update_file` | Changes a file's title, slug, description, and visibility, and can replace its contents. | **Manage files** |
| `delete_file` | Deletes a file and its contents. | **Manage files** |
| `restore_mcp_snapshot` | Puts a page or theme back the way it was before an MCP change. | **Manage pages** or **Manage Curator settings** |
| `create_api_key` | Creates a REST API key for endpoints that the MCP tools do not cover. | **Manage API keys** |
| `delete_api_key` | Deletes a REST API key that MCP created. | **Manage API keys** |
| `create_api_relay` | Creates an API relay. | **Manage API relay** |
| `update_api_relay` | Changes an API relay's URL, headers, constants, variables, body, caching, logging, whether it requires a Curator session, and whether embedded HTML can call it. | **Manage API relay** |
| `delete_api_relay` | Deletes an API relay that MCP created. | **Manage API relay** |
| `call_api_relay` | Calls an API relay and returns the external API's response. | **Manage API relay** |

Most content tools accept `dry_run: true`. Curator then checks the change and returns the result, but it
does not save the change.

`create_api_key` returns the new key one time only. A REST API key has full REST API access and does not
expire, so check this tool on a token only when the client needs the REST API. `delete_api_key` deletes
only keys whose owner label starts with `MCP:`. Remove other keys in the backend.

The API relay tools let an AI assistant connect a page to an external API without seeing the API's
credentials. They only work with relays that have **Available to MCP Tools?** turned on, which is the default.
A relay's URL must be a public `http` or `https` address. Constants are encrypted unless the client asks
otherwise, and the tools never return an encrypted value or a header value that looks like a credential. Relays
that use a dynamic URL, dynamic headers, dynamic body content, or a webhook can only be changed in the backend.
`delete_api_relay` deletes only relays that MCP created and that no Data Manager group uses. `call_api_relay`
really calls the external API, and a relay that sends a POST can change data there, so check this tool on a
token only when the client needs it. See [API Relay](https://docs.curator.interworks.com/creating_integrations/api_relay.md).

### Safety Rules

* **Managed and distributed portals refuse changes.** On a portal that Central Dispatch manages, and on a
  high availability node, every content tool returns an error, but the read tools still work. On a managed
  portal, make the change on the managing Curator. On a high availability node, make the change in the
  Curator backend.
* **New pages start hidden.** A new page is hidden unless the client passes `hidden: false`. Publish a page
  with `update_page_settings` and `hidden: false` after you review it.
* **Group restrictions are not set.** No tool sets or edits the group restrictions on pages, menu items, or
  files. A page that a tool creates has no group restrictions. Check its restrictions in the backend before
  you publish it. A page that a tool recreates after a delete is hidden, and it is restricted to no groups, so
  no frontend user can open it until an administrator assigns its groups in the backend.
* **Page text cannot contain code.** Curator refuses rich text that contains scripts, event handler
  attributes, `javascript:` URLs, embedded frames, forms, style tags, or Twig tags. The same rule applies to
  hero headings, hero descriptions, and the descriptions of pages, files, and menu items, because Curator
  shows them as HTML. Links can use `http`, `https`, `mailto`, `tel`, `sms`, `webcal`, `msteams`, `slack`,
  and `zoommtg` addresses, relative addresses, and image data. To embed another site,
  use an iframe element.
* **Theme styles cannot read server files.** Changing custom CSS needs the **Manage custom code**
  permission. In custom CSS, `update_theme` accepts only one kind of
  `@import`: a remote stylesheet such as a web font, written as `@import url('https://...');`. It refuses
  other imports and the LESS functions that read files, such as `data-uri()`. When the styles do not
  compile, the error gives the line and column only.
* **Some content is protected.** No tool can change the theme's head insert. The tools can add and edit
  only the common page elements. Other elements, such as accordions, tabbed pages, feeds, and lists, can be
  moved or removed, but not edited.
* **Uploads are checked.** Curator refuses file types that a web server can run as code. HTML, SVG, XML,
  and JavaScript files uploaded through MCP are saved as downloads only. Curator also checks the contents,
  so an HTML file with a name such as `report.txt` is saved as a download only too. `set_theme_image` accepts
  only raster images, such as PNG, JPEG, GIF, WebP, and ICO files, and refuses files that are downloads only, so
  an SVG logo or favicon can only be set in the backend. When a page embeds one of these
  HTML files, Curator renders it in a sandboxed frame.
* **Deletes are checked.** `delete_page` refuses the homepage and any page that another page embeds. It
  also refuses a page that a tabbed pages element, a tile selection, or a theme footer uses, unless the client
  passes `force`. It refuses a page that menu items link to, unless the client passes `remove_menu_links`,
  which deletes those menu items too. It always refuses when a linked menu item has children. `delete_file` refuses a
  file that pages or menu items use, unless the client passes `force`. `delete_menu_item` refuses an item
  that has children, unless the client passes `include_children`. No tool deletes or moves a top-level menu.

### Undo Changes

Before a tool changes a page's settings or content, or a theme's settings, Curator saves a snapshot of it.
`list_mcp_snapshots` lists the snapshots, newest first. `restore_mcp_snapshot` puts one back. When it
restores a page or theme that still exists, it saves a snapshot first, so you can undo the restore too.

A restore is refused when the page or theme changed after the MCP change that the snapshot undoes, for
example when someone edited it in the backend. Run the restore with `dry_run: true` to see the changes, and
pass `force: true` to restore anyway. A restore never makes a hidden page visible, and it never changes the
theme's head insert.

If a page was deleted, the restore creates it again with a new id. The restored page gets back its
settings and content, but not its menu items, keywords, group restrictions, or custom code. The restored
page is hidden and restricted to no groups. Assign its groups in the backend before you publish it.
Restoring the same snapshot again updates that page and does not create a second copy.

Curator keeps the newest 25 snapshots of each page and each theme, for up to 90 days.

Menu and file changes have no snapshot. Instead, the menu and file tools return the values that were there
before the change. A deleted file cannot be restored.

Theme images and page thumbnails also have no snapshot. When `set_theme_image` or `update_page_settings`
replaces an image, Curator keeps the old image as a hidden file and returns its id.

### Upload Large Files

`upload_file` accepts inline contents up to 10 MB, or a public URL that Curator downloads, up to 50 MB.
Curator refuses a URL that points to a private or internal address. Curator downloads the URL directly and
never through a proxy. If the server reaches the internet only through a proxy, use `create_upload_url`.

For a file on the client's own computer, `create_upload_url` returns a URL under
`/curator/mcp/upload/`. The client sends the file to that URL with an HTTP PUT, for example
`curl --upload-file ./photo.jpg '<upload_url>'`. The URL works one time only, expires after 15 minutes,
and accepts files up to 50 MB. Without a `file_id`, the upload creates a new file. With a `file_id`, the upload
replaces the contents of that file. Curator checks the token, its owner, and the owner's permissions again
when the file arrives.

## Limits and Logging

* Requests are rate limited per client address using the same limits as the REST API, set under
  **Settings** > **Security** > **Authentication Settings**.
* Every tool call writes a Usage Log row of type `interworks.portal.mcp.call` with the tool, its arguments,
  the owner, the token prefix, and the outcome.
* Rejected sign-ins are written to the Curator log with the reason and the token prefix. The full token is
  never logged.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.