Nodal-Agents
Concepts

Agents

What an agent is, how it's configured, and how a job runs.

An agent is a named, persistent AI persona you create in the dashboard. The catalog ships skills and connectors — never agents. Every agent comes from you.

Configuration

FieldWhat it does
Name / slug / avatarUI identity, and the handle orchestrators use to delegate
System promptthe Markdown injected at the top of every job
Modelany configured provider key — each agent picks its own
Skillsinject guidance and unlock gated built-in tools
ConnectorsOAuth / API-key integrations (Gmail, Notion, Airtable…)
MCP serversHTTP or stdio servers whose tools are namespaced per job
Workspacesfilesystem paths the agent can read and write
Channelsoptional connections for inbound + outbound messages (Telegram, Discord, Slack, WhatsApp)
Roleagent (worker), orchestrator, or system (reserved)

How a job runs

A job is one unit of work — a chat message, a cron tick, an API call, or an inbound Telegram message. The runner loads the agent's config, builds the tool whitelist and system prompt for that job, then enters the LLM loop.

The tool whitelist is computed per job — there are no defaults

The runner unions the always-on builtins with every tool unlocked by the agent's assigned skills (via requiredBuiltins), its connectors, and its MCP servers. An agent with no skills gets only the always-on set. A tool that isn't in the whitelist is never offered to the model.

Always-on built-in tools

Every agent gets these tools on every job, regardless of skills (ALWAYS_ON_TOOLS in packages/tools/src/builtin/index.ts). The count used to be written out here and went stale the first time a tool was added, so it is gone: the built-in tools reference is generated from the runtime and is the one that counts.

  • return_result — set the job's final answer.
  • ask_user — stop and ask you a question the agent cannot answer on its own.
  • skill_view — read the full content of an assigned skill on demand.
  • list_models — list the models available to this agent.
  • list_schedules — list the agent's cron automations.
  • save_memory, query_memory, mark_memory_helpful, mark_memory_outdated — the memory tools (write, recall, and rate persistent facts).
  • search_history — full-text recall across all of this workspace's past jobs and conversations, including ones run by other agents.
  • nodal_docs — search this documentation: what Nodal-Agents can do and where in the dashboard it is done. Offline, no model, no network.
  • web_search — search the web, using the agent's configured Tavily/Firecrawl provider if any, otherwise a free best-effort search.
  • dashboard_publish — publish the agent's substantive output to the dashboard (it becomes the job's result).
  • file_read, file_write, file_edit, file_list, file_search — read and edit files in the agent's workspaces.
  • register_project — declare a folder it worked in as a project.
  • declare_verification — declare the commands that prove what it just built, so Nodal runs and records them. Requires approval by default, exactly like run_command. See Proof.

The complete registry — always-on, skill-gated, grant-gated and channel tools — is generated from the runtime itself on the built-in tools reference.

Anti-loop guards

Every job is bounded. When a limit is hit the job fails loud with a clear code — never a silent fallback.

GuardLimit
Max turns per job50
Max tool calls per turn50
Max self-chain resumes15
Max delegation depth3
Max total tokens per job1,500,000
Max cost per job$2.00
Max consecutive delivery-only turns3
Max identical no-progress turns12

Autonomy

Tool calls with real-world side-effects (like run_command) can require approval before they run. You configure rules per-agent or per-tool:

  • Run without asking — run immediately.
  • Ask for approval — pause the job and wait for your approval in the dashboard.
  • Block — never allow this tool.

Built-in tools can be restricted too

The always-on built-ins are listed on the agent's Approvals tab under Built-in tools, with the same three settings as every other tool.

Before this, they were on and unlisted, and the only way to restrain one was the read-only preset — which blocks five write tools at once. There was no way to say "may read files, may not search the web". Now there is.

One tool cannot be blocked: return_result, which is how a job reports that it finished or got stuck. Blocking it would leave every job of that agent unable to end, with no way to tell you why. The dashboard says so on the row rather than simply refusing.

Blocking a tool leaves it visible to the agent and refuses the call, telling the model the restriction is deliberate. That wording is the point: an agent told "this is not available to you" reports the limit back to you, while an agent that simply sees a failure tends to try to work around it.

An agent does not recompose its own team

A per-agent setting, may_change_team, decides whether an agent may use the three meta-tools that change who is on its team: create_agent, attach_agent and detach_agent.

It is off by default, and the migration turned it off for every agent that already existed. With it off, those three are not in the list the runner computes for the job, so the model never sees them — this is not a refusal at call time.

Two gates, deliberately stacked: a ROOT grant says what the workspace allows, and this setting says whether this agent may rearrange its own team. The setting can only take away; it never adds a tool a disabled grant already refused.

The workspace brake

Settings → Safety → Auto-run brake pauses every auto-run at once, in every auth mode.

While it is engaged, any auto_approve rule on a code-execution tool is dropped for the job, and an explicit require_approval rule is injected so a blanket wildcard cannot sweep the tool back in. Nothing is deleted from the database: releasing the brake re-arms the rules exactly as they were. The brake also outranks the agent's autonomy level, so fully_autonomous cannot auto-approve past it.

On this page