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

# Tool capabilities

> How to control which Atoti AI tools are available under `atoti.ai.tools`

<Info>
  ### Atoti Intelligence Essentials

  This is part of the Atoti Intelligence Essentials offer.
</Info>

Every AI tool Atoti registers declares a capability that states the class of action it performs. Two properties decide whether a capability is active on a given deployment, without any change to the tool itself. One is a per-capability override. The other is a fallback for anything not listed. Two more properties together gate a small set of tools beyond their capability: a master switch, and a list naming which tools that switch applies to. The sections below cover each property and how they combine.

The policy applies to the tools Atoti registers itself. These include discovery, validation, MDX query, the Auto-Explain run, find, and remove tools, chat history, and connected-servers tools. Every built-in Atoti AI tool available today is annotated `read`, except `createCalculatedMember`, `deleteCalculatedMember`, and `updateCalculatedMember`, which declare `write`.

Two capability names carry meaning today, `read` and `write`.

## Configuration reference

| Property | What it controls | Default |
| - | - | - |
| `atoti.ai.tools.default-mode` | The fallback mode applied to a capability with no explicit entry in `atoti.ai.tools.capabilities` | `deny` |
| `atoti.ai.tools.capabilities` | A map from capability name to mode, `allow` or `deny` | `{read: allow}` |
| `atoti.ai.tools.extra-tools` | The list of tool names enabled under the experimental extra-tools mechanism, on top of their capability | `[]` (empty list) |
| `atoti.ai.tools.experimental` | The master switch for the whole extra-tools mechanism | `false` |

## How to configure the default mode

`atoti.ai.tools.default-mode`, available from Atoti Intelligence 6.1.25, sets the mode applied to a capability that has no explicit entry in `atoti.ai.tools.capabilities`. Accepted values are `allow` and `deny`, case-insensitive. The default is `deny`.

```yaml theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
atoti:
  ai:
    tools:
      default-mode: deny
```

The default `capabilities` map already lists `read` explicitly, so raising `default-mode` to `allow` does not change `read`. It changes the fallback for `write`, and for any future capability that ships without an explicit entry. It never changes `atoti.ai.tools.extra-tools` or `atoti.ai.tools.experimental`. Both properties are separate, with their own defaults, and are not part of the `capabilities` map.

## How to configure capabilities per tool

`atoti.ai.tools.capabilities`, available from Atoti Intelligence 6.1.25, maps a capability name to a mode, `allow` or `deny`. The default map is `{read: allow}`. `read` is explicitly allowed out of the box, and any unlisted capability, currently `write`, falls back to `default-mode`.

```yaml theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
atoti:
  ai:
    tools:
      capabilities:
        write: allow
```

The snippet above allows `write` tools without changing `default-mode` or the existing `read` entry. Declaring one entry in `capabilities` does not remove the others. The entry is added to the default map instead of replacing it.

An entry in `capabilities` always wins over `default-mode`, in both directions. Setting `write: deny` keeps `write` tools disabled even if `default-mode` is raised to `allow`. Setting `write: allow` enables `write` tools even while `default-mode` stays `deny`.

<Note>
  Capability names are plain strings. `read` and `write` are used by tools today. Each name is a key in the `atoti.ai.tools.capabilities` map. An environment variable reaches that map lower cased, with each underscore turned into a dot. A name with an uppercase letter or a hyphen could not be set from the environment, so capability names stay lower case and unpunctuated.
</Note>

## How to configure extra tools

<Warning>
  `atoti.ai.tools.extra-tools` is *experimental*. Its name is the signal: the property itself, the list of tool names it accepts, and the behavior of each tool it gates may change or be removed in any release, including a patch. None of it is covered by the usual compatibility guarantees.
</Warning>

Two properties together gate a small set of tools beyond their capability.

`atoti.ai.tools.experimental`, available from Atoti Intelligence 6.1.25, is a boolean switch for the whole extra-tools mechanism. Accepted values are `true` and `false`. The default is `false`.

`atoti.ai.tools.extra-tools`, available from Atoti Intelligence 6.1.25, lists the tools to enable by name. An entry is the tool's own name, exactly as the tool is named, for example `createCalculatedMember`. The default is an empty list. Entries are list values, not map keys, so they keep the tool's own camel case.

Both properties sit beside `atoti.ai.tools.capabilities` rather than inside it. `atoti.ai.tools.default-mode` never reaches either one: raising `default-mode` to `allow` does not turn any extra tool on.

### Which tools can be named in extra-tools?

| Tool name | Capability | What it does |
| - | - | - |
| `createCalculatedMember` | `write` | Creates a persisted calculated member on a cube from an MDX expression. The member is saved and available to every future query and widget until removed. |
| `deleteCalculatedMember` | `write` | Permanently removes a persisted calculated member from a cube. The member stops being available to every future query and every widget. Its parameters are the cube name and the member's fully qualified MDX unique name. It fails if the member or the cube does not exist, or if the calling user cannot see that member. It also fails if another calculated member or KPI still depends on it. The error names the dependents, which must be removed first. The assistant reports them and does not delete them unless the user explicitly asks. |
| `retrieveOneCalculatedMember` | `read` | Returns the full definition of one calculated member on a cube: its MDX expression, caption, folder, and format string. Covers both the members saved on the Content Server and the members declared in the application's cube configuration. Its parameters are the cube name and the member's exact unique MDX name. It fails if the member or the cube does not exist, or if the calling user is not allowed to see that member. |
| `updateCalculatedMember` | `write` | Updates a persisted calculated member of a cube in place, keeping its unique name and the users it is shared with. Its parameters are the cube name, the member's fully qualified MDX unique name, and the optional new MDX expression, caption, folder, and format string. Only the fields passed are changed, the others keep their current value. A field cannot be cleared this way, and the unique name cannot be changed: delete the member and create a new one for that. It fails if there is no persisted calculated member under that name on that cube, including when the member is only declared in the application's cube configuration, or if the calling user cannot see it. Unlike `deleteCalculatedMember`, it is not blocked when another calculated member or KPI depends on the member. |

This is the complete list of extra tools today. Naming any other tool in `extra-tools` has no effect.

## How to enable the extra tools

`createCalculatedMember` declares the `write` capability. Enabling it takes three settings together: allowing `write`, turning on `experimental`, and naming the tool in `extra-tools`. `deleteCalculatedMember` and `updateCalculatedMember`, both available from Atoti Intelligence 6.1.25, also declare `write` and are enabled the same way. `retrieveOneCalculatedMember`, available from Atoti Intelligence 6.1.25, goes through the same three gates with `read` in place of `write`; `read` is allowed by default, so it needs only `experimental: true` and its name in `extra-tools`.

```yaml theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
atoti:
  ai:
    tools:
      capabilities:
        write: allow
      experimental: true
      extra-tools:
        - createCalculatedMember
        - deleteCalculatedMember
        - retrieveOneCalculatedMember
        - updateCalculatedMember
```

The equivalent environment variables for the experimental switch and the tool list are `ATOTI_AI_TOOLS_EXPERIMENTAL` and `ATOTI_AI_TOOLS_EXTRA_TOOLS`. Several tool names are comma-separated:

```bash theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
ATOTI_AI_TOOLS_EXPERIMENTAL=true
ATOTI_AI_TOOLS_EXTRA_TOOLS=createCalculatedMember,deleteCalculatedMember,retrieveOneCalculatedMember,updateCalculatedMember
```

Naming no extra tool is a deliberate choice, and never an error: the default empty list simply offers nothing extra. Naming a tool whose other gates stay shut is a configuration mistake. Atoti refuses to start rather than silently withholding a tool that was explicitly asked for.

The following table shows every combination for a `write` extra tool, using `createCalculatedMember` as the example. The same four outcomes apply identically to `deleteCalculatedMember` and `updateCalculatedMember`.

| `extra-tools` | `experimental` | `capabilities.write` | Outcome |
| - | - | - | - |
| empty (default) | any | `allow` | Starts normally, tool not offered |
| `[createCalculatedMember]` | `false` (default) | any | Startup fails, error names `atoti.ai.tools.experimental` |
| `[createCalculatedMember]` | `true` | `deny` (default) | Startup fails, error names `atoti.ai.tools.capabilities.write` |
| `[createCalculatedMember]` | `true` | `allow` | Tool available |

Setting `capabilities.write: allow` on its own no longer fails startup, and does not by itself enable `createCalculatedMember`, `deleteCalculatedMember`, or `updateCalculatedMember`. It only takes effect once the tool is also named in `extra-tools` and `experimental` is `true`.

## What is the default behavior out of the box?

With no configuration, `read` tools are allowed and `write` tools are denied. Every built-in Atoti AI tool available today is annotated `read`, except `createCalculatedMember`, `deleteCalculatedMember`, and `updateCalculatedMember`, which declare `write`. With `extra-tools` empty and `experimental` `false` by default, none of `createCalculatedMember`, `deleteCalculatedMember`, `retrieveOneCalculatedMember`, or `updateCalculatedMember` is offered, regardless of the `read` or `write` setting. This changes nothing about the tools available before this feature. It matters once a `write` tool ships, or once `createCalculatedMember`, `deleteCalculatedMember`, `retrieveOneCalculatedMember`, or `updateCalculatedMember` needs to be enabled.

## How to allow write tools

To allow `write` tools without changing any other capability, set only the `capabilities` entry:

```yaml theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
atoti:
  ai:
    tools:
      capabilities:
        write: allow
```

## How to change the fallback for unlisted capabilities

To flip the fallback applied to every unlisted capability, set `default-mode` to `allow`:

```yaml theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
atoti:
  ai:
    tools:
      default-mode: allow
```

This also allows `write`, since it has no explicit entry in the default `capabilities` map. To keep `write` denied while raising the fallback for future capabilities, add an explicit `write: deny` entry alongside it.

Raising `default-mode` does not by itself enable a `write` extra tool such as `createCalculatedMember`, `deleteCalculatedMember`, or `updateCalculatedMember`. Each tool also requires `experimental: true` and its own name in `extra-tools`; see [How to enable the extra tools](#how-to-enable-the-extra-tools).

## Related reading

* [Retries and timeouts](./retries-and-timeouts) bounds how long and how often a prompt calls tools.
