Cosmo Docs
API Reference

Built-in Tools

Provider-specific server-side tools like web search, and how to integrate them.

Built-in tools are capabilities provided natively by the AI provider and executed server-side. Unlike MCP tools or Cosmo's internal tools (tasks, workspaces, artifacts), built-in tools don't go through the engine's tool executor — the provider handles everything.

Architecture

The built-in tools system is designed to be provider-agnostic. Each provider declares what built-in tools it supports, and the engine automatically enables the ones configured in LLMConfig.

Type Definitions

interface BuiltInToolConfig {
  /** Tool identifier — e.g., 'web_search'. */
  type: string
  /** Max number of uses per request (provider-specific). */
  maxUses?: number
}

interface LLMConfig {
  provider: 'anthropic' | 'openai'
  model: string
  apiKey?: string
  /** Enable provider-specific built-in tools. */
  builtInTools?: BuiltInToolConfig[]
}

Provider Interface

Providers declare their capabilities via supportedBuiltInTools:

interface LLMProvider {
  readonly name: string
  readonly supportedBuiltInTools?: string[]
  chat(messages, tools, opts): AsyncIterable<ChatChunk>
}

How It Works

  1. Configuration — The engine is created with builtInTools in the LLM config
  2. Provider mapping — Each provider maps generic BuiltInToolConfig to its native format (e.g., Anthropic's WebSearchTool20250305)
  3. Streaming — Server-handled tool calls come back as tool_call chunks with serverHandled: true
  4. Engine loop — The agentic loop skips execution for server-handled calls; they resolve within a single provider turn
  5. UI — Server-handled tools look identical to regular tools in the event stream (spinner → checkmark)

Available Built-in Tools

PropertyValue
Typeweb_search
Supported byAnthropic
Enabled by defaultYes (in desktop)

Allows the AI to search the web for current information. The provider executes the search server-side and returns results inline.

Configuration:

const engine = createEngine({
  mode: 'local',
  llm: {
    provider: 'anthropic',
    model: 'claude-haiku-4-5-20251001',
    apiKey: '...',
    builtInTools: [
      { type: 'web_search', maxUses: 5 },
    ],
  },
})

Stream behavior:

The Anthropic provider handles two special content block types:

  • server_tool_use — Emitted when the model decides to search. The provider yields a tool_call chunk with serverHandled: true.
  • web_search_tool_result — Emitted when search results arrive. The provider yields a tool_result chunk.

These events happen within a single provider turn. The engine does not re-enter the agentic loop for them.

ToolCall.serverHandled Flag

interface ToolCall {
  id: string
  name: string
  args: Record<string, unknown>
  serverId?: string
  /** True when the provider executed this tool server-side. */
  serverHandled?: boolean
}

The engine uses this flag to decide whether to execute a tool call:

// In the agentic loop
if (chunk.toolCall.serverHandled) {
  serverHandledCalls.push(chunk.toolCall)  // Track for history, don't execute
} else {
  pendingToolCalls.push(chunk.toolCall)    // Execute via tool registry
}

Adding a New Built-in Tool

To add support for a new provider-specific tool:

  1. Add the type to BuiltInToolConfig mapping in the relevant provider (e.g., toAnthropicBuiltInTool() in anthropic.ts)
  2. Handle stream events for the new tool type in the provider's streaming loop
  3. Update supportedBuiltInTools on the provider class
  4. Yield tool_call with serverHandled: true so the engine skips execution
  5. Yield tool_result when the server-side execution completes

No changes needed in the engine, router, or other providers — the abstraction handles it.

Provider Compatibility

If a built-in tool is configured but the active provider doesn't support it, the tool is silently ignored. This means you can configure builtInTools: [{ type: 'web_search' }] and it will work with Anthropic but have no effect with OpenAI — no errors, no behavior change.