Tool Search Tool Plugin for OpenCode - search and execute tools from MCP servers on-demand
npm install opencode-toolbox





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.
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
Add opencode-toolbox to your ~/.config/opencode/opencode.jsonc:
``jsonc`
{
"plugin": ["opencode-toolbox@x.y.z"]
}
> ⚡ Performance Tip: Always pin to a specific version for instant startup.
>
> | Configuration | Startup Time | Why |
> |---------------|--------------|-----|
> | ✅ opencode-toolbox@x.y.z | ~0ms | Cached version matches, skips npm check |opencode-toolbox
> | ❌ | ~1000ms | Resolves "latest" via npm on every startup |"latest"
>
> OpenCode caches plugins by exact version. When you omit the version, it defaults to which doesn't match the cached resolved version, triggering a fresh bun add on every startup. Check npm for the latest version.
Create ~/.config/opencode/toolbox.jsonc:
`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.
- OPENCODE_TOOLBOX_CONFIG: Path to config file (default: ~/.config/opencode/toolbox.jsonc){env:VAR_NAME}
- Environment variable interpolation: Use in config values
The plugin exposes five tools:
Search for tools using natural language:
``
toolbox_search_bm25({ text: "get current time in timezone" })
Search for tools using regex patterns on tool names:
``
toolbox_search_regex({ pattern: "time_.*", limit: 5 })
Both search tools return tool schemas so the LLM knows exact parameters:
`json`
{
"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: '
}
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"}' })
`
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."
`
Get toolbox status including plugin health, MCP server connections, and tool counts:
``
toolbox_status({})
Returns a comprehensive status object:
`json`
{
"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 (check servers.failed)unknown
- : No servers configured or initialization failed
The plugin automatically creates and maintains the /toolbox-status slash command:
``
~/.config/opencode/command/toolbox-status.md
Use it in OpenCode by typing /toolbox-status to get a formatted status report.
> Note: The command file auto-updates when the plugin version changes.
Get detailed performance metrics for the toolbox plugin:
``
toolbox_perf({})
Returns performance data including initialization times, search latencies, and execution stats:
`json`
{
"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
}
}
, github_
- Supports (?i) prefix for case-insensitive matching
- Limited to 200 characters for safetyArchitecture
See docs/ARCHITECTURE.md for detailed diagrams and flow explanations.
Development
$3
`bash
bun install
`$3
`bash
bun test # Run all tests
bun test --coverage # Run with coverage
`$3
`bash
bun run build
`Observability
The toolbox plugin provides built-in logging and status monitoring to help you understand what's happening.
$3
All plugin operations are logged silently to a dedicated log file (no screen output):
`
~/.local/share/opencode/toolbox.log
`Log 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:
`bash
Watch logs in real-time
tail -f ~/.local/share/opencode/toolbox.logCheck for errors only
grep "ERROR" ~/.local/share/opencode/toolbox.logCheck for warnings
grep "WARN" ~/.local/share/opencode/toolbox.log
`Log 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 results
`$3
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
$3
1. Run
toolbox_status({}) to check initialization status
2. Check OpenCode logs at ~/.local/share/opencode/log/ for plugin errors
3. Verify opencode-toolbox is in the plugin array in opencode.jsonc
4. Ensure toolbox.jsonc exists and is valid JSON$3
1. Verify underlying MCP servers are configured in
toolbox.jsonc
2. Check tool descriptions for relevant keywords
3. Try broader search terms or regex patterns$3
1. Run
toolbox_status({}) to see which servers failed
2. Check logs for specific error messages from failed servers
3. Verify server command works standalone: npx -y @anthropic/mcp-time
4. For remote servers, verify URL is accessible
5. Check environment variables are set correctly> Note: Connection retries use exponential backoff (100ms → 200ms → 400ms..., max 30s) before failing.
$3
1. Run
toolbox_status({}) to check server health
2. Verify toolId format: {serverName}_{toolName}
3. Check arguments` is valid JSONMIT