# How toolboxes work

> Source: https://elaichi.ai/docs/guides/toolboxes/overview/

Give an agent a curated set of tools instead of everything a product can do. Elaichi splits that curation into a reusable **template** (the tool list, no connections) and a connection-bound **toolbox** (what actually runs) — so a group of tools can be designed and shared long before anyone picks the accounts behind it.

Smaller, well-described toolboxes produce better results. An agent choosing between six clearly named tools makes better decisions than one sorting through two hundred.

**Where to find it:** **Toolboxes** in the sidebar → **Toolboxes**, **Templates**, or **Synthetic tools**

## Three kinds

| Kind | Where in the UI | What it is |
| --- | --- | --- |
| **Template** | **Templates** | A reusable definition — tools, frozen/default params, no connections. Teammates **stamp** their own toolbox from it. |
| **Toolbox** | **Toolboxes** | Connection-bound. What MCP clients connect to — stamped from a template, built from scratch, or one of the automatic system toolboxes below. |
| **Synthetic tools** | **Synthetic tools** | Multi-step composite tools you add into a template or a toolbox like normal entries. |

Elaichi also maintains automatic **system** toolboxes alongside the ones you build:

| System toolbox | Meaning |
| --- | --- |
| **Global toolbox** (“All tools”) | Everything you can currently reach |
| **Connection toolbox** (“{connection} tools”) | All tools for one **Active** connection |

System toolboxes are read-only: you can use them over the organization's MCP endpoint, but you can’t edit their entries.

### The important rule

**AI clients reach toolboxes over the MCP endpoint**, not templates
directly. A template is the recipe; a toolbox — stamped from one, or built by
hand — is what actually advertises tools over MCP. There is one endpoint, and
nothing is minted per toolbox: the organization it reaches and the access it
runs as both come from the OAuth grant, not from the address.

```mermaid title="Template → stamp → toolbox → MCP"
flowchart TD
  Template["Template<br/>tools, frozen/default params<br/>no connections"] -->|"stamp (use)"| Toolbox["Toolbox<br/>your copy, connections bound"]
  Conn["Active connection"] -->|"automatic"| Dynamic["Connection toolbox<br/>read-only"]
  Toolbox --> MCP["Org's MCP endpoint"]
  Dynamic --> MCP
  MCP --> Client["AI client"]
```

## Sharing levels (ACL)

Templates and toolboxes share the same ACL, but `use` means something
different on each:

| Level | On a template | On a toolbox |
| --- | --- | --- |
| **View** | See it and its tools | See its metadata and tool list |
| **Use** (default) | **Stamp** a toolbox from it | **Execute** its tools over its bound connections, reachable through the org's MCP endpoint |
| **Edit** | Change its tools and settings | Change its entries and settings |

Share with a **member**, a **team**, or **everyone at your organization**. View-only
recipients can’t stamp a template or run a toolbox.

Sharing a template never shares credentials — a template has none to share.
Sharing a **toolbox** is different: `use` **delegates** execution over the
connections its entries already have pinned. The grantee does not need their
own access to those connections at all; they run exactly this toolbox’s
tools, with its frozen params, over whichever connection an editor pinned in.
The live authority behind each entry is that editor (the entry’s
*delegator*) — if they later lose access to the connection they pinned, that
one entry stops working for everyone, independent of the toolbox share
itself. The share screen lists which connections a grantee will end up
running through before you confirm, especially private or someone-else-owned
ones.

## Per-tool customization

On a template (and on a toolbox’s own entries), open **Edit tool** to tune
what agents see and how calls run:

| Setting | Effect |
| --- | --- |
| **Name override** / **Description override** | What the model sees (empty = catalog) |
| **Enabled** | Disabled entries stay in the UI but aren’t offered over MCP |
| **Frozen parameters** | Fixed values stripped from the advertised schema and force-merged at execution — the model can’t see or override them |
| **Default values** | Applied when the client omits a parameter; the model can still override |
| **Input schema override** | Replace the advertised JSON Schema (with helpers to copy or reset the catalog schema) |

**Call-time precedence:** defaults < client arguments < frozen parameters.

A template entry never references a connection at all — that’s what
stamping fills in (see [How the pieces fit](#how-the-pieces-fit) below).

## Several accounts, one tool

Connect two accounts of the same product — two Notion workspaces, two
Salesforce orgs — and Elaichi still advertises **one** tool, not two. Which
account a call uses is an argument, not part of the tool name.

- **One account backs the tool:** nothing to do. The tool keeps its plain
  name and its description starts with that account, like `[Work Notion]`.
- **Several accounts back the same tool:** the tool gains a required
  `connection` argument. Its choices are the account names, and it has no
  default — the agent must pick one.
- **A call that skips `connection`, or names an account that doesn’t back
  that tool, is refused.** The error lists the real choices and tells the
  agent to ask you when your request didn’t say. There is no default account
  and no "last one connected" fallback, anywhere.

### Accounts with the same name

When two accounts of one product share a name, **both** get a short piece of
their connection id added — `Notion (a1b2c3)` and `Notion (d4e5f6)` — so
neither keeps the bare name. Names that differ only in capitals or spacing
(`Work Notion` and `work notion`) count as the same name and are treated the
same way.

The added piece is as short as it can be while still telling those accounts
apart, so it grows only if it has to. Elaichi never numbers accounts `1` and
`2`: a number would move to a different account the moment you add or remove
an unrelated one.

Labels are worked out per tool. If two accounts back `get_page` but only one
backs `create_page`, `get_page` offers `Notion (a1b2c3)` and `Notion
(d4e5f6)` while `create_page` offers a plain `Notion`. Both are right at the
same time. Agents should copy the value from the tool they are calling.

### Example: two Notion workspaces

Connect two Notion workspaces, both named "Notion". Agents see one `get_page`
— not two lookalikes — with a required `connection` set to one of
`"Notion (a1b2c3)"` or `"Notion (d4e5f6)"`.

Ask an agent to look up a page without saying which workspace, and the call
comes back with:

> `connection` is required. This tool reaches 2 connected accounts — pass
> exactly one of: "Notion (a1b2c3)", "Notion (d4e5f6)". If the user's request
> does not say which account, ask them; do not pick one for them.

A well-behaved agent asks you which workspace and calls again. Delete one
workspace later and `get_page` keeps its name, drops the `connection`
argument, and an agent still naming the deleted workspace is refused — never
quietly pointed at the one that is left.

### When tools stay separate

Pinning an entry to a specific connection (see
[Connection binding](/guides/toolboxes/toolboxes#connection-binding)) does
not keep tools apart. Two entries for the same tool pinned to two different
accounts still merge into one tool with a `connection` argument. What keeps
tools separate is a difference in the call itself:

- Entries for the same tool that set different frozen parameters, defaults,
  overrides or schemas stay separate tools. Merging them would let one
  entry’s fixed values ride along on another account's call.
- A few products have their own `connection` parameter in their API. Tools
  for those stay one per account, so that parameter keeps working.

### Locked values

A tool with frozen parameters tells agents about the lock in its
description. The note `(frozen: folder_id=HR)` sits between the account
label and the tool’s own text; a value too long, too complex or unsafe to
print is shortened to `folder_id=…`, which still says the lock is there.
The locked parameter is not in the tool’s schema at all, and a value an
agent sends anyway is overridden, not an error.

When the same tool is added several times with different frozen values,
the pinned value goes into each copy’s name — names ending `_hr` and
`_legal`, say — but only when every value is short plain text that does
not look like an id. Long values, ids, lists and objects get a short
generated code instead. That test is about shape, not secrecy: a short
readable value such as an email address does go into the name, and names
are cached by client apps and written to logs, so do not freeze something
private and expect the name to hide it.

A well-behaved agent picks the variant whose note matches your words,
asks when none does, tells you when you ask for a value the tool is
locked away from instead of running it anyway, and presents results as
scoped — "contacts from the HR folder" — rather than as everything.

### Approvals stay with the account

An approval you give — including "always allow" — applies to the account it
was granted for. The same tool on another account asks again. If the account
is changed after you approve, the call is refused rather than run somewhere
else.

### What restrictions can’t do

[Restrictions](/guides/governance/set-restrictions) work on the product and
the tool, not on the account. You cannot allow a tool on one Notion workspace
and block it on another — a restriction applies to every account behind that
tool.

## Needs connection

An entry with no connection pinned — left unmapped at stamp time, or added
directly to a toolbox — renders as **Needs connection**, alongside the other
statuses a tool entry can carry (**Tool unavailable**, **Disabled**,
**Ready**). A needs-connection entry advertises nothing over MCP; it stays
visible in the console so you can finish setting it up.

Fix it by picking a connection for that entry (connecting the product first,
if you haven’t). The tool appears to MCP clients automatically once it
resolves — no server restart, no re-mint.

An entry whose connection **used to** work can also fall back into this
state: if the person who pinned it (its *delegator*) loses access to that
connection, the entry goes unmet for everyone who runs the toolbox, until
someone with `edit` re-pins it.

## How the pieces fit

1. Connect accounts → automatic **connection toolboxes** appear under
   **Toolboxes**.
2. Optionally build a **template**, tune its entries, and share it with
   **view** / **use** / **edit**.
3. Recipients with **use** **stamp** their own toolbox from it — naming it
   and filling each entry’s connection as they go.
4. Point an AI client at [your org's MCP endpoint](/guides/mcp-servers/how-it-works)
   — it reaches every toolbox you can use, your own or delegated to you, with
   nothing to mint per toolbox.
5. Optionally add [synthetic tools](/guides/toolboxes/synthetic-tools) into a
   template or a toolbox.

## Good to know

- Tools blocked by [restrictions](/guides/governance/set-restrictions) never
  appear to MCP clients, even if a template includes them.
- Renaming a tool changes it only inside that template or toolbox — the
  underlying product is untouched.
- A template’s entries are copied, not linked: editing a template later never
  changes toolboxes already stamped from it.
- Permissions: `template:create` / `toolbox:create` to build,
  `template:share` / `toolbox:share` to share, `template:manage` /
  `toolbox:manage` to edit or delete one you own or hold an `edit` share on.

## Related

- [Templates](/guides/toolboxes/templates)
- [Toolboxes](/guides/toolboxes/toolboxes)
- [Synthetic tools](/guides/toolboxes/synthetic-tools)
