How Codebuff Manages Tool Permissions Using toolNames: A Complete Technical Guide
Codebuff implements a strict two-layer permission system where agents declare allowed tools via the toolNames array in their definition, and the runtime executor blocks any unauthorized tool calls before execution begins.
Codebuff is an open-source AI coding assistant that requires precise control over agent capabilities to ensure safe code interactions. Understanding how tool permissions are defined and enforced is essential for building secure agents that access only the specific filesystem, search, or terminal operations you authorize.
The Two-Layer Permission Architecture
Codebuff's tool permissions operate through a combination of static declaration and dynamic enforcement. First, developers explicitly list which tools an agent may invoke in its configuration file. Then, at runtime, the executor validates every incoming tool request against this whitelist before invoking any handlers or MCP (Model Context Protocol) connections.
This architecture ensures that even if a language model attempts to call a restricted tool, the request is intercepted and blocked at the executor level before any code runs.
Step 1: Declaring the Tool Registry
All native tools available to Codebuff agents are centrally registered in common/src/tools/constants.ts (lines 21-55). This file exports the toolNames constant, which enumerates every built-in tool identifier that the runtime recognizes, such as read_files, write_file, str_replace, and code_search.
This registry serves as the master reference for the entire permission system. When configuring an agent, every string you place in the toolNames array must match an identifier defined in this constants file (or follow the MCP naming convention for external tools).
Step 2: Defining Agent-Level Permissions
Individual agent capabilities are configured through the AgentDefinition interface located in agents/types/agent-definition.ts (lines 21-30). The optional toolNames property accepts an array of strings that explicitly lists which tools the agent can access.
When this array is empty or omitted, the agent possesses no native tool permissions, effectively creating a sandboxed environment. This declarative approach allows developers to create specialized agents—such as linters that only read files or editors that cannot execute terminal commands—by selectively including only the necessary tool identifiers.
MCP-Scoped Tool Permissions
For external tools provided by MCP servers, Codebuff extends the toolNames format to include server scoping. Developers can grant access to specific MCP tools using the pattern serverName/toolName (for example, myMcp/web_search). The agent definition simultaneously references the server configuration in its mcpServers map while listing specific permitted tools in toolNames.
Step 3: Runtime Enforcement in the Tool Executor
The critical enforcement logic resides in packages/agent-runtime/src/tools/tool-executor.ts. When the system receives a tool call, the executeToolCall function (lines 167-174) performs an immediate permission check against agentTemplate.toolNames.
The validation logic follows this sequence:
- Extract the
toolNamefrom the incoming request - Verify the name exists in the agent's
toolNamesarray - If missing, check if the call originates from a permitted MCP server context
- Block execution if neither condition is satisfied
If the requested tool is not authorized, the executor immediately aborts the call before any handler is invoked, preventing unauthorized filesystem or terminal access.
Error Handling for Unauthorized Calls
When a tool call fails the permission verification, the executor streams a structured error response back to the client. As implemented in lines 176-180 of tool-executor.ts, the system emits:
onResponseChunk({
type: 'error',
message: `Tool \`${toolName}\` is not currently available. Make sure to only use tools provided at the start of the conversation AND that you most recently have permission to use.`,
});
This user-visible error message clearly communicates the restriction, allowing the client UI to display the violation without exposing internal system details.
Step 4: Prompt-Level Permission Injection
Codebuff reinforces tool permissions at the language model interaction layer. In packages/agent-runtime/src/templates/strings.ts (lines 173-194), the prompt builder injects a sentence explicitly listing the allowed tools when constructing the agent's system prompt.
This serves as a behavioral guardrail, reminding the LLM of its operational boundaries at the start of every conversation. By combining technical enforcement with prompt-based guidance, Codebuff minimizes the likelihood of permission violation attempts while maximizing transparency about agent capabilities.
Practical Configuration Examples
Restricting an Agent to File Operations
// .agents/safe-editor.ts
import { AgentDefinition } from '../agents/types/agent-definition';
const definition: AgentDefinition = {
id: 'safe-editor',
displayName: 'Restricted File Editor',
model: 'anthropic/claude-opus-4.6',
// Explicitly allow only file manipulation tools
toolNames: ['read_files', 'write_file', 'str_replace'],
};
export default definition;
This configuration restricts the agent to three specific native tools defined in common/src/tools/constants.ts. Any attempt to invoke run_terminal_command, code_search, or unlisted MCP tools triggers the permission error from tool-executor.ts lines 176-180.
Granting Selective MCP Access
// Agent with external search capabilities
const definition: AgentDefinition = {
id: 'web-researcher',
displayName: 'Web Research Assistant',
toolNames: ['brave/search', 'brave/fetch_content'],
mcpServers: {
brave: {
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-brave-search']
}
}
};
The executeCustomToolCall function validates these MCP-prefixed names (lines 78-86 in tool-executor.ts) by verifying both the server connection status and the specific tool permission before routing to the external handler.
Summary
- Static Declaration: Developers define permitted tools using the
toolNamesarray inAgentDefinitionfiles, as specified inagents/types/agent-definition.ts. - Native Tool Registry: All available native tools are enumerated in
common/src/tools/constants.ts(lines 21-55) as thetoolNamesconstant. - Runtime Enforcement: The
executeToolCallfunction inpackages/agent-runtime/src/tools/tool-executor.ts(lines 167-174) validates every request against the agent's whitelist before execution. - MCP Integration: External tools use the
serverName/toolNameformat withintoolNamesto grant selective access to MCP server capabilities, checked byexecuteCustomToolCall. - Immediate Feedback: Unauthorized attempts trigger user-visible error messages streamed from
tool-executor.tslines 176-180, preventing silent security failures. - Prompt Reinforcement: The template builder in
packages/agent-runtime/src/templates/strings.ts(lines 173-194) includes allowed tool lists in system prompts to guide model behavior.
Frequently Asked Questions
What happens if I omit the toolNames field in an agent definition?
If the toolNames array is omitted or left empty, the agent possesses no permissions to invoke native Codebuff tools. According to the interface in agents/types/agent-definition.ts, this optional field defaults to an unrestricted state for native tools only when explicitly populated; otherwise, the agent operates in a restricted sandbox unless granted specific MCP tool access.
Can agents request additional tool permissions during a conversation?
No. Tool permissions are immutable for the duration of a conversation. The executeToolCall function in tool-executor.ts checks the static agentTemplate.toolNames array for every single invocation. There is no runtime mechanism for permission escalation or dynamic tool enrollment; modifying an agent's capabilities requires updating its definition file and restarting the agent context.
How does Codebuff validate MCP tool permissions differently from native tools?
Native tools are validated by checking if the requested name exists in the toolNames array against the registry in common/src/tools/constants.ts. For MCP tools, the executeCustomToolCall function (lines 78-86 in tool-executor.ts) parses the serverName/toolName format, verifies the server connection is active, and confirms the specific tool is listed in the agent's permissions before routing the request to the external MCP handler.
Where is the complete list of available native tools documented?
The authoritative registry resides in common/src/tools/constants.ts at lines 21-55. This file exports the toolNames constant containing every built-in tool identifier (such as read_files, write_file, and str_replace) recognized by the Codebuff runtime, serving as the definitive reference for configuring agent tool permissions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →