---
title: Admin — Built-in Tools
description: Platform-owned tools that ship with ThinkWork, including credentialed provider tools and policy/template-gated AgentCore tools.
---

import { Aside } from '@astrojs/starlight/components';

Built-in tools are platform-owned capabilities that ship with ThinkWork itself. They are distinct from [MCP servers](/applications/admin/mcp-servers/) and [workspace skills](/applications/admin/skills-catalog/): 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`

## What's in the catalog

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

| Tool | Runtime tool | Kind | Provider | Template control |
|---|---|---|---|---|
| Browser Automation | `browser_automation` | Policy-gated | `agentcore+nova_act` | Agent Template → Configuration → Browser Automation |
| Code Sandbox | `execute_code` | Policy-gated | `agentcore` | Agent Template → Configuration → Code Sandbox |
| Send Email | `send_email` | Policy-gated | `thinkwork-email` | Agent Template → Configuration → Send Email |
| Web Search | `web_search` | Credentialed | Exa or SerpAPI | Agent 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.

## Built-ins vs workspace skills

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.

## The list view

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

| Column | Notes |
|---|---|
| Tool name | Display name, such as Web Search or Send Email |
| Provider | Badge showing a selected provider, such as Exa, or a fixed platform provider such as `agentcore` |
| Status | Enabled / Disabled / Not Configured for credentialed rows; policy/template state for policy-gated rows |
| API Key | "Set" if a credential is stored, "—" otherwise |
| Last tested | Relative 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.

## Configuring Web Search

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.

### REST endpoints

| Endpoint | Purpose |
|---|---|
| `GET /api/skills/builtin-tools` | List credentialed built-in tool configuration rows |
| `PUT /api/skills/builtin-tools/:slug` | Upsert provider, key, or enabled state for a credentialed built-in |
| `DELETE /api/skills/builtin-tools/:slug` | Remove a credentialed built-in configuration |
| `POST /api/skills/builtin-tools/:slug/test` | Test the current or provided credentialed configuration |

All requests carry tenant context in the request headers.

## Testing

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.

## Policy-gated tools

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](/concepts/agents/code-sandbox/) for the sandbox-specific runtime flow.

## Assigning to agents

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.

<Aside type="note">
This is intentionally different from workspace skills. If an operator should edit the implementation or instructions, use a workspace skill. If ThinkWork owns the implementation, credentials, callbacks, or per-turn policy context, keep it as an injected built-in.
</Aside>

## Data model

- **`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.

## Workflows

### Configure Web Search for the first time

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`

### Switch providers

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.

### Disable temporarily

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.

### Enable Send Email for a template

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.

## Known limits

- **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.

## Related pages

- [Tenant MCP Servers](/applications/admin/mcp-servers/) — the other path for exposing external capabilities
- [Skills Catalog](/applications/admin/skills-catalog/) — the third path: reusable skill packs with embedded tools
- [Agent Templates](/applications/admin/agent-templates/) — where template-level built-in tool opt-ins live
