add tool writes tools, set approvals.<tool> writes approvals, and set limits.steps writes limits. All three reach buildHarness() in managed/agent.ts, which harness() calls with the spec’s approvals and callHarness() with every ask turned to deny:
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.
applyApprovals and the step limit fill four fields of the harness spec.
toolsis the spec’stools. Anasktool is passed withneedsApproval: true, the one value the harness accepts.activeToolsis the spec’sactiveTools, passed only when a tool is denied.authorizationis the spec’sauthorization, passed only when a tool is markedask. It maps every tool in the set to an action, as the harness requires, and carries the host’sapprovalTtlMs.limits.stepsis the spec’slimits. A run whose last allowed step still calls a tool fails withHARNESS_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 nor the workspace tools of the harness package.