opencode-toolbox
v0.10.0
Published
Tool Search Tool Plugin for OpenCode - search and execute tools from MCP servers on-demand
Maintainers
Readme
opencode-toolbox (Tool Search Tool)
An OpenCode plugin that implements a tool search tool pattern, allowing users to keep only a tiny set of tools in LLM context while accessing a larger MCP catalog on-demand.
Motivation
OpenCode's MCP servers add tool schemas to LLM context at session start. With many MCPs, this can front-load tens of thousands of tokens, reducing "smart zone" capacity and degrading speed/accuracy.
opencode-toolbox solves this by:
- Exposing a few toolbox tools instead of 50+ MCP tools
- Search for tools using natural language (BM25) or regex patterns
- Execute discovered tools through the same interface
- Tool schemas are returned in search results for accurate LLM usage
Configuration
1. Add Plugin to OpenCode
Add opencode-toolbox to your ~/.config/opencode/opencode.jsonc:
{
"plugin": ["[email protected]"]
}⚡ Performance Tip: Always pin to a specific version for instant startup.
| Configuration | Startup Time | Why | |---------------|--------------|-----| | ✅
[email protected]| ~0ms | Cached version matches, skips npm check | | ❌opencode-toolbox| ~1000ms | Resolves "latest" via npm on every startup |OpenCode caches plugins by exact version. When you omit the version, it defaults to
"latest"which doesn't match the cached resolved version, triggering a freshbun addon every startup. Check npm for the latest version.
2. Configure Toolbox
Create ~/.config/opencode/toolbox.jsonc:
{
"$schema": "https://unpkg.com/opencode-toolbox@latest/toolbox.schema.json",
"mcp": {
"time": {
"type": "local",
"command": ["npx", "-y", "@anthropic/mcp-time"]
},
"github": {
"type": "local",
"command": ["npx", "-y", "@anthropic/mcp-github"],
"environment": {
"GITHUB_TOKEN": "{env:GITHUB_TOKEN}"
}
},
"weather": {
"type": "remote",
"url": "https://mcp.example.com/weather",
"headers": {
"Authorization": "Bearer {env:WEATHER_API_KEY}"
}
}
},
"settings": {
"defaultLimit": 5
}
}Note: The config file is auto-created with default settings if it doesn't exist.
Environment Variables
OPENCODE_TOOLBOX_CONFIG: Path to config file (default:~/.config/opencode/toolbox.jsonc)- Environment variable interpolation: Use
{env:VAR_NAME}in config values
Usage
The plugin exposes five tools:
toolbox_search_bm25
Search for tools using natural language:
toolbox_search_bm25({ text: "get current time in timezone" })toolbox_search_regex
Search for tools using regex patterns on tool names:
toolbox_search_regex({ pattern: "time_.*", limit: 5 })Search Results
Both search tools return tool schemas so the LLM knows exact parameters:
{
"count": 1,
"tools": [
{
"name": "time_get_current_time",
"description": "Get current time in a specific timezone",
"score": 0.87,
"schema": {
"type": "object",
"properties": {
"timezone": {
"type": "string",
"description": "IANA timezone name (e.g., 'America/New_York')"
}
},
"required": ["timezone"]
}
}
],
"usage": "Use toolbox_execute({ toolId: '<toolId>', arguments: '<json>' }) to run a discovered tool"
}toolbox_execute
Execute a discovered tool with JSON-encoded arguments. The toolId format is {serverName}_{toolName}:
toolbox_execute({ toolId: "time_get_current_time", arguments: '{"timezone": "Asia/Tokyo"}' })Example Flow
User: "What time is it in Tokyo?"
LLM: I need to find a time-related tool.
toolbox_search_bm25({ text: "current time timezone" })
Toolbox: Returns time_get_current_time with its schema
LLM: Now I know the parameters. Let me call it.
toolbox_execute({ toolId: "time_get_current_time", arguments: '{"timezone":"Asia/Tokyo"}' })
Toolbox: { "datetime": "2026-01-07T02:15:00+09:00", "timezone": "Asia/Tokyo" }
LLM: "The current time in Tokyo is 2:15 AM on January 7, 2026."toolbox_status
Get toolbox status including plugin health, MCP server connections, and tool counts:
toolbox_status({})Returns a comprehensive status object:
{
"plugin": {
"initialized": true,
"initState": "ready",
"initMode": "eager",
"initDurationMs": 1234,
"configPath": "/Users/username/.config/opencode/toolbox.jsonc",
"uptime": 123.45,
"searches": 23,
"executions": 15,
"successRate": "93%"
},
"servers": {
"total": 3,
"connected": 2,
"failed": 1,
"connecting": 0,
"connectionRatio": "2/3",
"details": [
{
"name": "time",
"status": "connected",
"type": "local",
"toolCount": 2,
"error": null,
"commandString": "uvx mcp-server-time",
"healthy": true
},
{
"name": "github",
"status": "connected",
"type": "local",
"toolCount": 12,
"error": null,
"commandString": "npx -y @anthropic/mcp-github",
"healthy": true
},
{
"name": "weather",
"status": "error",
"type": "remote",
"toolCount": 0,
"error": "Connection timeout after 5000ms",
"url": "https://mcp.example.com/weather",
"healthy": false
}
]
},
"tools": {
"total": 14,
"indexed": 14,
"serversWithTools": 2
},
"toolboxTools": [
"toolbox_search_bm25",
"toolbox_search_regex",
"toolbox_execute",
"toolbox_status",
"toolbox_perf",
"toolbox_test"
],
"health": {
"status": "degraded",
"message": "1 server(s) failed to connect"
}
}Health Status:
healthy: All servers connected successfullydegraded: Some servers failed to connect (checkservers.failed)unknown: No servers configured or initialization failed
/toolbox-status Slash Command
The plugin automatically creates and maintains the /toolbox-status slash command:
~/.config/opencode/command/toolbox-status.mdUse it in OpenCode by typing /toolbox-status to get a formatted status report.
Note: The command file auto-updates when the plugin version changes.
toolbox_perf
Get detailed performance metrics for the toolbox plugin:
toolbox_perf({})Returns performance data including initialization times, search latencies, and execution stats:
{
"init": {
"duration": 1234.56,
"serverCount": 6,
"toolCount": 42
},
"timers": {
"search.bm25": { "count": 15, "total": 45.2, "avg": 3.01, "min": 1.2, "max": 8.5 },
"search.regex": { "count": 5, "total": 12.1, "avg": 2.42, "min": 1.1, "max": 4.2 },
"tool.execute": { "count": 10, "total": 892.3, "avg": 89.23, "min": 12.5, "max": 245.8 }
},
"indexStats": {
"documentCount": 42,
"avgDocLength": 15.3
},
"config": {
"initMode": "eager",
"connectionTimeout": 5000,
"requestTimeout": 30000,
"retryAttempts": 2
}
}Search Modes
BM25 (Natural Language)
- Best for semantic queries: "search the web", "get current time"
- Uses TF-IDF based ranking
- Searches tool name, description, and parameter info
Regex (Pattern Matching)
- Best for precise matches:
^time_.*,github_ - Supports
(?i)prefix for case-insensitive matching - Limited to 200 characters for safety
Architecture
See docs/ARCHITECTURE.md for detailed diagrams and flow explanations.
Development
Setup
bun installTests
bun test # Run all tests
bun test --coverage # Run with coverageBuild
bun run buildObservability
The toolbox plugin provides built-in logging and status monitoring to help you understand what's happening.
Logging
All plugin operations are logged silently to a dedicated log file (no screen output):
~/.local/share/opencode/toolbox.logLog entries include:
- Plugin initialization status
- MCP server connection status (connected/error)
- Tool search operations (BM25/regex queries + result counts)
- Tool execution results (success/failure with duration)
- Errors with details
View logs:
# Watch logs in real-time
tail -f ~/.local/share/opencode/toolbox.log
# Check for errors only
grep "ERROR" ~/.local/share/opencode/toolbox.log
# Check for warnings
grep "WARN" ~/.local/share/opencode/toolbox.logLog format:
2026-01-08T12:34:56.789Z [INFO] Toolbox plugin loaded successfully {"configPath":"...","serverCount":6}
2026-01-08T12:34:57.100Z [INFO] time - connection time: 648.12ms, indexed 2 tools in 0.07ms
2026-01-08T12:34:57.200Z [INFO] github - connection time: 892.45ms, indexed 12 tools in 0.15ms
2026-01-08T12:34:58.500Z [INFO] Initialization complete in 1723.45ms: 2/3 servers, 14 tools indexed
2026-01-08T12:34:58.501Z [WARN] Server weather failed: Connection timeout after 5000ms
2026-01-08T12:35:00.456Z [INFO] BM25 search completed: "web search" -> 3 resultsStatus Tool
Use the toolbox_status command to check plugin health at any time:
toolbox_status({})This shows:
- Plugin Status: Initialization, config path, uptime, search/execution counts
- Server Status: Connection ratio (e.g., "2/3"), details per server
- Tools: Total available tools, servers with tools
- Health: Overall health status (healthy/degraded/unknown)
Connection Ratio: Shows success/total for servers. If success < total, it indicates failed connections.
Troubleshooting
Plugin not loading
- Run
toolbox_status({})to check initialization status - Check OpenCode logs at
~/.local/share/opencode/log/for plugin errors - Verify
opencode-toolboxis in thepluginarray inopencode.jsonc - Ensure
toolbox.jsoncexists and is valid JSON
Search finds no tools
- Verify underlying MCP servers are configured in
toolbox.jsonc - Check tool descriptions for relevant keywords
- Try broader search terms or regex patterns
MCP servers not connecting
- Run
toolbox_status({})to see which servers failed - Check logs for specific error messages from failed servers
- Verify server command works standalone:
npx -y @anthropic/mcp-time - For remote servers, verify URL is accessible
- Check environment variables are set correctly
Note: Connection retries use exponential backoff (100ms → 200ms → 400ms..., max 30s) before failing.
Execute fails
- Run
toolbox_status({})to check server health - Verify
toolIdformat:{serverName}_{toolName} - Check
argumentsis valid JSON - Ensure underlying MCP server is running and connected
- Check logs for detailed error messages
License
MIT
