# OpenCode Features and Practical Usage
🧰 When the built-in tools aren't enough and you need to hit an internal API or DB, you can give the LLM its own purpose-built tool.
🏷️ Title: Custom Tools
🔗 URL:
📘 Overview
Custom tools are your own functions that the LLM can invoke autonomously during a conversation. They extend the built-in tools (read/write/bash) so the agent can perform domain-specific operations like internal API access or database queries. Definitions are written in TypeScript/JavaScript, but the implementation can shell out to any language.
⚙️ How It Works
・Two locations: `.opencode/tools/` for project-scoped tools, or `~/.config/opencode/tools/` for global ones.
・The filename becomes the tool name. `database.ts` creates a `database` tool.
・You can define multiple tools per file via named exports, which become `
_`.
・Define tools with the `tool()` helper from `@opencode-ai/plugin`. The core fields are `description` (what the LLM sees), `args` (a Zod schema), and `execute` (the async implementation).
・Arguments are type-safe via Zod. Use `tool.schema` or import `zod` directly.
・The second argument to `execute` is a context object exposing session info: `agent`, `sessionID`, `messageID`, `directory`, and `worktree` (the git root).
🛠️ Practical Usage
Minimal example at `.opencode/tools/database.ts`: a default-exported `tool()` with a `description`, an `args` Zod schema (e.g. a `query` string), and an async `execute` that runs the query and returns the result.
The body can call any language. For instance, build a script path from `context.worktree` and run it with `Bun.$`python3 ...``.
💡 Use Cases
Define a tool that hits your internal inventory API or an authenticated internal endpoint, and the agent can fetch or update internal data just like it uses built-in tools. The more carefully you write the `description`, the better the LLM picks the right moment to call it.
⚠️ Caveats
・A custom tool with the same name as a built-in one overrides it. Unless you mean to replace it, use unique names. If you only want to disable a built-in tool, `deny` it via permissions instead of overriding.
・Since `execute` may run external commands or internal APIs, be careful with execution rights and secret handling.
#OpenCode# #AIAgents#