Skip to content

Admin — Built-in Tools

Built-in tools are platform-owned capabilities that ship with ThinkWork itself. They are distinct from MCP servers and workspace skills: MCP servers are remote endpoints ThinkWork connects to at runtime, workspace skills are operator-editable files under workspace/skills/, and built-in tools are registered by the runtime from tenant and template policy.

App route: /capabilities/builtin-tools

Docs route: /applications/admin/builtin-tools/

File: apps/admin/src/routes/_authed/_tenant/capabilities/builtin-tools.tsx

The catalog is deliberately small. Four built-in tools ship in the current release:

ToolRuntime toolKindProviderTemplate control
Browser Automationbrowser_automationPolicy-gatedagentcore+nova_actAgent Template → Configuration → Browser Automation
Code Sandboxexecute_codePolicy-gatedagentcoreAgent Template → Configuration → Code Sandbox
Send Emailsend_emailPolicy-gatedthinkwork-emailAgent Template → Configuration → Send Email
Web Searchweb_searchCredentialedExa or SerpAPIAgent Template → Configuration → Web Search

Rows have two different treatments in the list:

  • Credentialed rows open a Configure dialog for provider + API key + test. Web Search is the current credentialed built-in.
  • Policy-gated rows open a read-only Info dialog. Their registration is controlled by tenant policy, template opt-in, and sometimes agent-level capability rows.

The catalog is defined in both the admin UI (as a hardcoded array) and backend capability/runtime code. Extending the catalog requires code in both places so the UI, REST API, runtime config resolver, and runtime tool registration agree on the slug and configuration shape.

Do not install built-in tools as workspace skills.

Workspace skills are editable SKILL.md files under workspace/skills/<slug>/. Built-in tools are platform-owned runtime registrations. The runtime can present them to the model with skill-like names such as web_search or send_email, but those implementations are injected from API policy and runtime configuration, not copied into the workspace tree.

This boundary matters for repair and backfill work:

  • Do not create workspace/skills/web-search/SKILL.md.
  • Do not create workspace/skills/agent-email-send/SKILL.md.
  • Keep built-in slugs filtered through packages/api/src/lib/builtin-tool-slugs.ts.
  • Use Agent Template configuration to opt agents into built-ins.

See docs/solutions/best-practices/injected-built-in-tools-are-not-workspace-skills-2026-04-28.md for the engineering pattern.

A DataTable showing every built-in tool and its current state:

ColumnNotes
Tool nameDisplay name, such as Web Search or Send Email
ProviderBadge showing a selected provider, such as Exa, or a fixed platform provider such as agentcore
StatusEnabled / Disabled / Not Configured for credentialed rows; policy/template state for policy-gated rows
API Key”Set” if a credential is stored, ”—” otherwise
Last testedRelative timestamp from the last Test result, for credentialed rows

Clicking a credentialed row opens the ConfigureDialog. Clicking a policy-gated row opens a read-only info dialog that points to the template or policy surface that actually controls the tool.

Web Search is the current credentialed built-in. The Configure dialog captures:

  • Provider — dropdown populated from the tool’s available providers list
  • API Key — password input; placeholder hides the stored key if one already exists
  • Enabled — toggle
  • Test — button that fires the test endpoint and surfaces the result inline
  • Delete — only visible once the tool has been configured

Saving goes through PUT /api/skills/builtin-tools/web-search with { provider, enabled, apiKey? }. The backend writes the API key to Secrets Manager and stores a secret reference on the tenant_builtin_tools row. The UI gets back a hasSecret boolean it uses to decide whether to show the placeholder or the “Set API key” state on subsequent visits.

EndpointPurpose
GET /api/skills/builtin-toolsList credentialed built-in tool configuration rows
PUT /api/skills/builtin-tools/:slugUpsert provider, key, or enabled state for a credentialed built-in
DELETE /api/skills/builtin-tools/:slugRemove a credentialed built-in configuration
POST /api/skills/builtin-tools/:slug/testTest the current or provided credentialed configuration

All requests carry tenant context in the request headers.

The Test button fires a provider-specific call — for Web Search, it runs a canonical query against Exa or SerpAPI and returns { ok: boolean; resultCount?: number; error?: string }. If the test succeeds, a toast shows the result count. If it fails, the error message surfaces inline so the operator can diagnose.

Testing does not require saving first — the dialog lets the operator test with a new key before committing it to the vault.

Browser Automation, Code Sandbox, and Send Email are policy-gated rows. Unlike Web Search, there is no provider API key to configure on this page. Clicking one of these rows opens a read-only Info dialog, not the Configure dialog.

The dialog shows:

  • Provider - a fixed provider badge, such as agentcore, agentcore+nova_act, or thinkwork-email.
  • Status - for Code Sandbox, tenant provisioning state. Browser Automation and Send Email show template opt-in state.
  • Agent template opt-in - pointer to Agent Template → Configuration, where the actual template-level switch lives.
  • Tenant or agent policy - extra gates such as sandbox_enabled, the agent email channel, or agent-level Browser Automation overrides.

Registration rules:

  • execute_code registers only when the template is opted in and the tenant has sandbox_enabled set. Either gate closed means the tool is absent from the turn’s tool list.
  • browser_automation registers when the template is opted in or an individual agent capability override enables it, unless blocked by template/tool policy.
  • send_email registers when the template’s Send Email config is enabled and the agent email channel can provide the sending address and delivery policy.
  • web_search registers when the tenant has a configured/enabled provider row and the template’s Web Search config is enabled.

See the Code Sandbox concept page for the sandbox-specific runtime flow.

Built-in tools do not get assigned like skills or MCP servers. They are injected into an agent turn by the runtime config resolver:

  • Tenant-level provider or policy enables the tool family.
  • Agent Template configuration opts the template into the specific built-in.
  • Agent-level capability overrides can further narrow or widen where supported, such as Browser Automation.
  • Template blocked_tools and tenant disabled built-ins narrow the final toolset.
  • tenant_builtin_tools - one row per (tenant_id, tool_slug) for credentialed provider tools such as Web Search.
  • agent_templates.web_search - template opt-in metadata for the tenant-configured web_search built-in.
  • agent_templates.send_email - template opt-in metadata for the injected send_email built-in.
  • agent_templates.browser - template opt-in metadata for Browser Automation.
  • agent_templates.sandbox - template opt-in metadata for Code Sandbox, including network mode.
  • Secrets Manager - API keys are stored under references like thinkwork/{stage}/builtin-tools/{tenant_id}/{tool_slug}.

The admin UI never receives a plaintext API key after the initial save. Subsequent loads see hasSecret: true and render a placeholder in the password input.

  1. Open /capabilities/builtin-tools
  2. Click the Web Search row → Configure dialog opens
  3. Pick a provider (Exa is recommended for cost and result quality)
  4. Paste the API key
  5. Click Test — verify the result count comes back non-zero
  6. Set Enabled = true
  7. Save
  8. Open the relevant Agent Template → Configuration tab and enable Web Search
  9. New agent turns using that template can receive web_search
  1. Open the Configure dialog for Web Search
  2. Change the provider dropdown
  3. Paste the new provider’s API key
  4. Test
  5. Save

Switching providers does not flush in-flight agent invocations, but the next invocation will use the new provider.

  1. Open Configure
  2. Toggle Enabled to false
  3. Save

All agents stop receiving web_search, even when their template has Web Search enabled. Re-enabling the tenant row restores it for opted-in templates.

  1. Open the relevant Agent Template
  2. Go to the Configuration tab
  3. Toggle Send Email
  4. Save
  5. Confirm the agent email channel is configured for agents using that template

The runtime injects send_email as a direct platform tool. It does not install agent-email-send as a workspace skill.

  • CLI only manages Web Search today. The admin UI shows policy-gated tools, but thinkwork tools currently configures only credentialed Web Search.
  • No per-agent API key or per-agent provider override. Web Search provider configuration is tenant-level.
  • Hardcoded catalog in multiple places. Adding a new built-in tool requires code changes in the admin UI, API/runtime config resolver, and Strands/Pi runtime registration.
  • No key format validation. The Test button catches bad keys; there is no pre-submit format check.
  • Send Email smoke requires care. A true end-to-end send test emits a real email. Prefer runtime-config checks and explicit user-approved send tests.