Tool surfaces
Passthrough, meta, code and auto, the four ways a profile presents its tools.
Every tool definition a client loads costs context in each request. A profile with a few tools can list them all; one with hundreds should not. Each profile's surface sets how its tools are presented:
| Surface | What the client sees | Best for |
|---|---|---|
passthrough | every allowed tool, as is | small profiles |
meta | search_tools, get_schema, call_tool | many tools, any model |
code | execute: the model writes JavaScript that calls tools | multi-step work across tools |
auto | passthrough for small profiles, meta above a threshold | the default |
Whatever the surface, every call is checked against the profile, so a tool outside it cannot be called by guessing its name.
passthrough
The profile's tools are listed as they are, named server__tool (or the name an override gives them). This is what a client would see if it connected to each server itself, with one entry instead of many. Only tools are passed through, not prompts or resources. The servers' own instructions are passed on in the session's instructions.
meta
The client sees three tools instead of the full list:
| Tool | Arguments | Returns |
|---|---|---|
search_tools | query, optional limit (default 10, at most 50) | ranked matches, one per line: server.tool - summary |
get_schema | names: up to 20 tool names | each tool's input as a TypeScript signature with its description |
call_tool | name, arguments | the tool's own result |
Tools are named server.tool here, as in github.create_issue. A server name as the query, or server.*, lists that server's tools. Search runs locally (BM25), weighting the tool name above the server, title and description, and it understands camelCase and snake_case names. The tool descriptions list the profile's servers and tell the model to search before concluding that a capability is unavailable.
The definitions of three tools cost the same context whether the profile has 20 tools or 500.
code
The client sees one tool, execute. The model writes an async JavaScript function that calls tools directly and returns a result; it runs in a sandbox with budgets. This turns a chain of tool calls into one round trip and keeps intermediate results out of the model's context. See Code mode.
auto
auto is the default. It uses passthrough while the profile has at most autoThreshold tools (40 by default) and meta above that. Adding servers to a profile switches it over automatically.
"work": { "servers": ["github", "linear"], "surface": "auto", "autoThreshold": 40 }Set the surface with switchboard profile set work --surface meta, or on the profile's page in the web UI, which also estimates how many tokens of context the tool list costs compared with passthrough.