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

# Tools, Approvals and Limits

```bash theme={null}
telnyx-acp add tool web_search
telnyx-acp add tool mcp --url https://mcp.deepwiki.com/mcp
telnyx-acp set approvals.<tool> ask
telnyx-acp set limits.steps 12
```

```text {2,5,13} theme={null}
support-agent/
├── agent.json                                         ◀
├── instructions.md
└── .telnyx/                        written by deploy
    ├── index.ts                                       ◀
    ├── telnyx.toml
    ├── telnyx-env.d.ts
    └── package.json

@telnyx/acp/                      the package
├── managed/
│   ├── index.ts
│   ├── agent.ts                                       ◀
│   ├── tools.ts                                       ◀
│   ├── mcp.ts                                         ◀
│   ├── model.ts
│   ├── memory.ts
│   ├── voice.ts
│   ├── direct-turn.ts
│   └── filler.ts
├── channels/
│   ├── index.ts
│   ├── phone.ts
│   ├── email.ts
│   ├── web.ts
│   └── wire.ts
├── synth/
│   ├── index.ts
│   ├── code-entry.ts
│   └── vendor.ts
└── spec/
    ├── schema.ts
    ├── model.ts
    ├── phone.ts
    ├── project.ts
    └── io.ts
```

`add tool` writes `tools`, `set approvals.<tool>` writes `approvals`, and `set limits.steps` writes `limits`. All three reach [`buildHarness()`](/docs/agent-sdk/inside/harness) in `managed/agent.ts`, which `harness()` calls with the spec's approvals and `callHarness()` with every `ask` turned to `deny`:

```ts theme={null}
// managed/agent.ts, buildHarness(card, approvals)
const { tools, activeTools, authorization } =
  applyApprovals({ ...specTools(this.spec, this.toolEnv()), ...(this.host.tools ?? {}) }, approvals, this.host.approvalTtlMs);
// …
limits: { steps: this.spec.limits?.steps ?? DEFAULT_STEPS },
```

`specTools`, in `managed/tools.ts`, builds a tool set in the `ai` package's shape from the `tools` entries of `agent.json`: for a `web_search` entry, `web_search`, plus `fetch_page` unless `contents` is false and `research` when `research` is true, over the function's `TELNYX` binding; for an `mcp` entry, one tool per listed server tool, named `<name>__<tool>`, its input schema the server's JSON Schema, each call made by the Streamable HTTP client in `managed/mcp.ts` with the secret read through `toolEnv().secret` at every request. A host's own tools are merged on top, a host tool of the same name winning. Every built tool catches its own failure and answers the model with `{ error }`, and writes one `toolCall` log line.

`applyApprovals`, in `managed/agent.ts`, takes that tool set and the approval policy and returns the tools the harness may call, the ones marked `ask` that pause for a decision, and the authorization that decides them. The policy is one word per tool.

| `approvals.<tool>` | Effect |
| - | - |
| `allow`, the default | The tool is offered as it is. |
| `ask` | The tool is marked as needing approval, and its action is `agent.tools.<tool>`, with any character of the name outside letters and digits escaped. On a call it is `deny`: a call cannot wait for an approval. |
| `deny` | The tool is left out of the set, and `activeTools` lists the rest. |

`applyApprovals` and the step limit fill four fields of the harness spec.

* `tools` is the spec's [`tools`](/docs/agent-sdk/harness-sdk/create-harness#spec-tools). An `ask` tool is passed with `needsApproval: true`, the one value the harness accepts.
* `activeTools` is the spec's [`activeTools`](/docs/agent-sdk/harness-sdk/create-harness#spec-activetools), passed only when a tool is denied.
* `authorization` is the spec's [`authorization`](/docs/agent-sdk/harness-sdk/create-harness#spec-authorization), passed only when a tool is marked `ask`. It maps every tool in the set to an action, as the harness requires, and carries the host's `approvalTtlMs`.
* `limits.steps` is the spec's [`limits`](/docs/agent-sdk/harness-sdk/create-harness#spec-limits). A run whose last allowed step still calls a tool fails with `HARNESS_STEP_LIMIT`.

`DEFAULT_STEPS` is 8, and a granted approval lives fifteen minutes by default, within the harness's bounds of five minutes and twenty-four hours. The managed classes attach neither the [scheduling tools](/docs/agent-sdk/harness-sdk/plug-ins/scheduling) nor the [workspace tools](/docs/agent-sdk/harness-sdk/plug-ins/workspace) of the harness package.

> [!WARNING]
>
> **Beta.** An `agent_gateway` entry is validated and deployed, but `specTools` builds nothing for it: the gateway client has not landed, so its tools are not called.
