Skip to main content

Tools

Tools are the mechanism by which the LLM interacts with your project and environment. Each tool gives the model a specific capability — running commands, editing files, searching code, fetching web content, and more.

Built-in Tools

opencode ships with the following built-in tools:

ToolDescriptionPermission Control
bashExecute shell commands in the project environmentper-command
editApply exact string replacements in filesper-edit
writeCreate new files (controlled by edit permission)same as edit
readRead file contents with optional line range supportalways allowed
grepRegex search across files using ripgrepalways allowed
globFile pattern matching by glob patternsalways allowed
lspCode intelligence (experimental, behind feature flag)always allowed
apply_patchApply patches to files (controlled by edit perm)same as edit
skillLoad and execute SKILL.md instruction filesalways allowed
todowriteManage structured task listsalways allowed
webfetchFetch and return web page contentper-request
websearchSearch the web for informationper-request
questionAsk the user for clarificationalways allowed

bash

Executes shell commands in the project's working directory. The model can run any command available in the shell environment.

{
"permission": {
"bash": "ask"
}
}

Common uses: npm install, git status, mkdir, python script.py, cargo build, go test ./....

The model receives the full stdout, stderr, and exit code of each command. Commands that exceed the timeout or output limit are terminated.

edit

Applies exact string replacements in existing files. The model provides the file path, the old string to replace, and the new string to insert.

{
"permission": {
"edit": "allow"
}
}

The edit tool validates that the old string exists and is unique in the file. If multiple matches are found, the model is asked to provide more surrounding context.

write

Creates new files with specified content. This tool is controlled by the edit permission level since it is a form of file modification.

{
"permission": {
"edit": "allow"
}
}

When edit is set to "deny", the write tool is also denied. When set to "ask", the user is prompted before each file creation.

read

Reads file contents and returns them to the model. Supports optional line ranges for reading specific sections of large files.

{
"permission": {
"read": "allow"
}
}

The read tool is always allowed by default since it poses no risk to the project. It supports reading line ranges — the model can request a specific range of lines from a file.

grep

Performs regular expression searches across files using ripgrep internally.

{
"permission": {
"grep": "allow"
}
}

The grep tool respects .gitignore by default. It supports the full regex syntax and returns file paths with line numbers for each match.

glob

Matches files using glob patterns (e.g., **/*.ts, src/**/*.test.js).

{
"permission": {
"glob": "allow"
}
}

Results are sorted by modification time, newest first. The tool is built on the same fast pattern-matching engine as ripgrep.

lsp (Experimental)

Provides code intelligence capabilities by communicating with Language Server Protocol servers.

Requires the feature flag:

export OPENCODE_EXPERIMENTAL_LSP_TOOL=true

Capabilities:

OperationDescription
definitionsGo-to-definition for symbols
referencesFind all references to a symbol
hoverGet hover documentation for a symbol
symbolsList symbols in a file or workspace
completionsGet code completion suggestions
diagnosticsGet file diagnostics (errors, warnings)

The LSP tool auto-detects which language server to use based on the file extension and project configuration (e.g., tsconfig.json, pyproject.toml, Cargo.toml).

{
"permission": {
"lsp": "allow"
}
}

apply_patch

Applies diff patches to files. Controlled by the edit permission.

{
"permission": {
"edit": "allow"
}
}

The model provides patches in unified diff format. The tool validates that the patch applies cleanly before modifying the file.

skill

Loads SKILL.md instruction files from the project or global skills directory.

{
"permission": {
"skill": "allow"
}
}

SKILL.md files provide structured instructions for specific workflows. The tool reads the file and injects its content into the model's context.

todowrite

Manages structured task lists during a session. The model can create, update, reorder, and mark tasks as complete.

{
"permission": {
"todowrite": "allow"
}
}

Tasks are displayed in the TUI and persist for the duration of the session.

webfetch

Fetches content from URLs and returns it to the model. Supports text, markdown, and HTML output formats.

{
"permission": {
"webfetch": "ask"
}
}

Useful for looking up documentation, reading API specs, or fetching web content during development.

websearch

Performs web searches and returns summarized results.

Requires OpenCode provider or the OPENCODE_ENABLE_EXA environment variable:

export OPENCODE_ENABLE_EXA=true
{
"permission": {
"websearch": "ask"
}
}

Supports configurable result counts, live crawling modes, and domain filtering.

question

Asks the user for clarification, confirmation, or additional information during a task.

{
"permission": {
"question": "allow"
}
}

This tool is always allowed since it only prompts the user and does not modify anything.

Permission Control

Tool access is governed by the permission section in opencode.json.

Permission Levels

LevelDescription
allowTool runs automatically without user confirmation
askUser is prompted to approve each tool invocation
denyTool is blocked from use

Setting Permissions

{
"permission": {
"edit": "deny",
"bash": "ask",
"webfetch": "allow"
}
}

Wildcard Permissions

Use wildcards to control groups of tools, particularly useful for MCP servers:

{
"permission": {
"mymcp_*": "ask",
"database_*": "deny"
}
}

This pattern matches any tool whose name starts with the prefix.

Default Permissions

ToolDefault
bashallow
editallow
writeallow
readallow
grepallow
globallow
lspallow
apply_patchallow
skillallow
todowriteallow
webfetchallow
websearchallow
questionallow

Tool Control per Agent

Different agents can have different tool permissions and custom tools:

{
"agent": {
"reviewer": {
"permission": {
"bash": "deny",
"edit": "deny"
}
},
"builder": {
"permission": {
"bash": "allow",
"edit": "allow"
}
}
}
}

This allows code review agents to be read-only while development agents retain full access.

Custom Tools

Extend opencode with custom tools for project-specific capabilities.

Defining Custom Tools

{
"tool": {
"my-custom-tool": {
"npm": "@opencode/custom-tool",
"name": "My Custom Tool",
"description": "Does something specific to my project"
}
}
}

Custom tools can provide access to databases, internal APIs, deployment pipelines, or any other system the model needs to interact with.

MCP Servers

Model Context Protocol (MCP) servers expose external tools and resources to the LLM. Configure MCP servers under the mcpServers key:

{
"mcpServers": {
"database": {
"command": "node",
"args": ["path/to/mcp-server.js"],
"env": {
"DATABASE_URL": "{env:DATABASE_URL}"
}
},
"api-gateway": {
"command": "python",
"args": ["-m", "mcp_gateway"],
"env": {
"API_KEY": "{env:INTERNAL_API_KEY}"
}
}
}
}

MCP servers run as child processes. Each tool exposed by the server appears in the model's available tool list, prefixed with the server name.

Internal Implementation Details

grep and glob

Both tools use ripgrep under the hood for fast pattern matching. They respect .gitignore rules by default to avoid searching ignored files.

The .ignore File

To override .gitignore exclusions for search operations, place a .ignore file in the project root. This file follows the same format as .gitignore but only affects grep and glob operations.

Example .ignore:

# Only exclude node_modules from search
node_modules

Tool Timeouts

Each tool has a configurable timeout:

{
"tool": {
"bash": {
"timeout": 30000
},
"webfetch": {
"timeout": 10000
}
}
}

Tool timeouts are specified in milliseconds. If a tool exceeds its timeout, the operation is terminated and the model receives an error message.

Tool Output Limits

Tools that produce output (bash, read, webfetch) have output size limits to prevent context overflow. Large outputs are truncated, and the model can request additional data in chunks.

Security Best Practices

  • Set edit to "ask" or "deny" in sensitive repositories
  • Use "ask" for bash when running unknown code
  • Restrict webfetch and websearch in air-gapped environments
  • Use agent-level permissions to create read-only reviewers
  • Never expose secrets in tool configurations — use {env:VARIABLE_NAME} instead