opencode-toolbox 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +157 -8
- package/dist/index.js +238 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ Create `~/.config/opencode/toolbox.jsonc`:
|
|
|
30
30
|
|
|
31
31
|
```jsonc
|
|
32
32
|
{
|
|
33
|
-
"
|
|
33
|
+
"mcp": {
|
|
34
34
|
"time": {
|
|
35
35
|
"type": "local",
|
|
36
36
|
"command": ["npx", "-y", "@anthropic/mcp-time"]
|
|
@@ -63,7 +63,7 @@ Create `~/.config/opencode/toolbox.jsonc`:
|
|
|
63
63
|
|
|
64
64
|
## Usage
|
|
65
65
|
|
|
66
|
-
The plugin exposes
|
|
66
|
+
The plugin exposes four tools:
|
|
67
67
|
|
|
68
68
|
### toolbox_search_bm25
|
|
69
69
|
|
|
@@ -135,6 +135,89 @@ Toolbox: { "datetime": "2026-01-07T02:15:00+09:00", "timezone": "Asia/Tokyo" }
|
|
|
135
135
|
LLM: "The current time in Tokyo is 2:15 AM on January 7, 2026."
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
+
### toolbox_status
|
|
139
|
+
|
|
140
|
+
Get toolbox status including plugin health, MCP server connections, and tool counts:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
toolbox_status({})
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Returns a comprehensive status object:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"plugin": {
|
|
151
|
+
"initialized": true,
|
|
152
|
+
"configPath": "/Users/username/.config/opencode/toolbox.jsonc",
|
|
153
|
+
"uptime": 123.45,
|
|
154
|
+
"searches": 23,
|
|
155
|
+
"executions": 15,
|
|
156
|
+
"successRate": "93%"
|
|
157
|
+
},
|
|
158
|
+
"servers": {
|
|
159
|
+
"total": 3,
|
|
160
|
+
"connected": 2,
|
|
161
|
+
"failed": 1,
|
|
162
|
+
"connecting": 0,
|
|
163
|
+
"connectionRatio": "2/3",
|
|
164
|
+
"details": [
|
|
165
|
+
{
|
|
166
|
+
"name": "time",
|
|
167
|
+
"status": "connected",
|
|
168
|
+
"type": "local",
|
|
169
|
+
"toolCount": 5,
|
|
170
|
+
"error": null,
|
|
171
|
+
"healthy": true
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"name": "github",
|
|
175
|
+
"status": "connected",
|
|
176
|
+
"type": "local",
|
|
177
|
+
"toolCount": 12,
|
|
178
|
+
"error": null,
|
|
179
|
+
"healthy": true
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "weather",
|
|
183
|
+
"status": "error",
|
|
184
|
+
"type": "remote",
|
|
185
|
+
"toolCount": 0,
|
|
186
|
+
"error": "Failed to connect: timeout",
|
|
187
|
+
"healthy": false
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"tools": {
|
|
192
|
+
"total": 17,
|
|
193
|
+
"available": 17,
|
|
194
|
+
"serversWithTools": 2
|
|
195
|
+
},
|
|
196
|
+
"health": {
|
|
197
|
+
"status": "degraded",
|
|
198
|
+
"message": "1 server(s) failed to connect"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Health Status:**
|
|
204
|
+
- `healthy`: All servers connected successfully
|
|
205
|
+
- `degraded`: Some servers failed to connect (check `servers.failed`)
|
|
206
|
+
- `unknown`: No servers configured or initialization failed
|
|
207
|
+
|
|
208
|
+
### /toolbox-status Slash Command
|
|
209
|
+
|
|
210
|
+
The plugin automatically creates and maintains a `/toolbox-status` slash command:
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
~/.config/opencode/command/toolbox-status.md
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
- **Auto-created** on first plugin launch
|
|
217
|
+
- **Auto-updated** when plugin version changes (tracked via `toolbox_version` in frontmatter)
|
|
218
|
+
|
|
219
|
+
Use it in OpenCode by typing `/toolbox-status` to get a formatted status report.
|
|
220
|
+
|
|
138
221
|
## Search Modes
|
|
139
222
|
|
|
140
223
|
### BM25 (Natural Language)
|
|
@@ -172,13 +255,69 @@ bun test --coverage # Run with coverage
|
|
|
172
255
|
bun run build
|
|
173
256
|
```
|
|
174
257
|
|
|
258
|
+
## Observability
|
|
259
|
+
|
|
260
|
+
The toolbox plugin provides built-in logging and status monitoring to help you understand what's happening.
|
|
261
|
+
|
|
262
|
+
### Logging
|
|
263
|
+
|
|
264
|
+
All plugin operations are logged **silently** to a dedicated log file (no screen output):
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
~/.local/share/opencode/toolbox.log
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Log entries include:
|
|
271
|
+
- Plugin initialization status
|
|
272
|
+
- MCP server connection status (connected/error)
|
|
273
|
+
- Tool search operations (BM25/regex queries + result counts)
|
|
274
|
+
- Tool execution results (success/failure with duration)
|
|
275
|
+
- Errors with details
|
|
276
|
+
|
|
277
|
+
**View logs:**
|
|
278
|
+
```bash
|
|
279
|
+
# Watch logs in real-time
|
|
280
|
+
tail -f ~/.local/share/opencode/toolbox.log
|
|
281
|
+
|
|
282
|
+
# Check for errors only
|
|
283
|
+
grep "ERROR" ~/.local/share/opencode/toolbox.log
|
|
284
|
+
|
|
285
|
+
# Check for warnings
|
|
286
|
+
grep "WARN" ~/.local/share/opencode/toolbox.log
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Log format:**
|
|
290
|
+
```
|
|
291
|
+
2026-01-08T12:34:56.789Z [INFO] Toolbox plugin loaded successfully {"configPath":"...","serverCount":6}
|
|
292
|
+
2026-01-08T12:34:57.123Z [INFO] Initialization complete: 5/6 servers connected, 42 tools indexed
|
|
293
|
+
2026-01-08T12:34:57.124Z [WARN] 1 server(s) failed to connect: weather
|
|
294
|
+
2026-01-08T12:35:00.456Z [INFO] BM25 search completed: "web search" -> 3 results
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Status Tool
|
|
298
|
+
|
|
299
|
+
Use the `toolbox_status` command to check plugin health at any time:
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
toolbox_status({})
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
This shows:
|
|
306
|
+
- **Plugin Status**: Initialization, config path, uptime, search/execution counts
|
|
307
|
+
- **Server Status**: Connection ratio (e.g., "2/3"), details per server
|
|
308
|
+
- **Tools**: Total available tools, servers with tools
|
|
309
|
+
- **Health**: Overall health status (healthy/degraded/unknown)
|
|
310
|
+
|
|
311
|
+
**Connection Ratio**: Shows `success/total` for servers. If `success < total`, it indicates failed connections.
|
|
312
|
+
|
|
175
313
|
## Troubleshooting
|
|
176
314
|
|
|
177
315
|
### Plugin not loading
|
|
178
316
|
|
|
179
|
-
1.
|
|
180
|
-
2.
|
|
181
|
-
3.
|
|
317
|
+
1. Run `toolbox_status({})` to check initialization status
|
|
318
|
+
2. Check OpenCode logs at `~/.local/share/opencode/log/` for plugin errors
|
|
319
|
+
3. Verify `opencode-toolbox` is in the `plugin` array in `opencode.jsonc`
|
|
320
|
+
4. Ensure `toolbox.jsonc` exists and is valid JSON
|
|
182
321
|
|
|
183
322
|
### Search finds no tools
|
|
184
323
|
|
|
@@ -186,11 +325,21 @@ bun run build
|
|
|
186
325
|
2. Check tool descriptions for relevant keywords
|
|
187
326
|
3. Try broader search terms or regex patterns
|
|
188
327
|
|
|
328
|
+
### MCP servers not connecting
|
|
329
|
+
|
|
330
|
+
1. Run `toolbox_status({})` to see which servers failed
|
|
331
|
+
2. Check logs for specific error messages from failed servers
|
|
332
|
+
3. Verify server command works standalone: `npx -y @anthropic/mcp-time`
|
|
333
|
+
4. For remote servers, verify URL is accessible
|
|
334
|
+
5. Check environment variables are set correctly
|
|
335
|
+
|
|
189
336
|
### Execute fails
|
|
190
337
|
|
|
191
|
-
1.
|
|
192
|
-
2.
|
|
193
|
-
3.
|
|
338
|
+
1. Run `toolbox_status({})` to check server health
|
|
339
|
+
2. Verify tool name format: `serverName_toolName`
|
|
340
|
+
3. Check `arguments` is valid JSON
|
|
341
|
+
4. Ensure underlying MCP server is running and connected
|
|
342
|
+
5. Check logs for detailed error messages
|
|
194
343
|
|
|
195
344
|
## License
|
|
196
345
|
|
package/dist/index.js
CHANGED
|
@@ -19266,6 +19266,9 @@ function tool(input) {
|
|
|
19266
19266
|
return input;
|
|
19267
19267
|
}
|
|
19268
19268
|
tool.schema = exports_external;
|
|
19269
|
+
// src/plugin.ts
|
|
19270
|
+
import { appendFile, mkdir, writeFile, readFile } from "fs/promises";
|
|
19271
|
+
|
|
19269
19272
|
// node_modules/zod/v4/classic/external.js
|
|
19270
19273
|
var exports_external2 = {};
|
|
19271
19274
|
__export(exports_external2, {
|
|
@@ -32817,7 +32820,7 @@ var SettingsConfigSchema = exports_external2.object({
|
|
|
32817
32820
|
defaultLimit: exports_external2.number().min(1).max(20).default(5)
|
|
32818
32821
|
});
|
|
32819
32822
|
var ConfigSchema = exports_external2.object({
|
|
32820
|
-
|
|
32823
|
+
mcp: exports_external2.record(exports_external2.string(), ServerConfigSchema),
|
|
32821
32824
|
settings: SettingsConfigSchema.optional()
|
|
32822
32825
|
});
|
|
32823
32826
|
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
@@ -37908,8 +37911,69 @@ function generateSignature(tool3) {
|
|
|
37908
37911
|
}).join(", ");
|
|
37909
37912
|
return `${tool3.id.name}(${argList})`;
|
|
37910
37913
|
}
|
|
37914
|
+
// package.json
|
|
37915
|
+
var package_default = {
|
|
37916
|
+
name: "opencode-toolbox",
|
|
37917
|
+
version: "0.5.0",
|
|
37918
|
+
description: "Tool Search Tool Plugin for OpenCode - search and execute tools from MCP servers on-demand",
|
|
37919
|
+
main: "dist/index.js",
|
|
37920
|
+
module: "dist/index.js",
|
|
37921
|
+
type: "module",
|
|
37922
|
+
exports: {
|
|
37923
|
+
".": {
|
|
37924
|
+
import: "./dist/index.js",
|
|
37925
|
+
types: "./dist/index.d.ts"
|
|
37926
|
+
}
|
|
37927
|
+
},
|
|
37928
|
+
scripts: {
|
|
37929
|
+
build: "bun build src/index.ts --outdir dist --target bun",
|
|
37930
|
+
dev: "bun --hot src/index.ts",
|
|
37931
|
+
test: "bun test",
|
|
37932
|
+
"test:coverage": "bun test --coverage",
|
|
37933
|
+
typecheck: "tsc --noEmit"
|
|
37934
|
+
},
|
|
37935
|
+
files: [
|
|
37936
|
+
"dist",
|
|
37937
|
+
"README.md"
|
|
37938
|
+
],
|
|
37939
|
+
keywords: [
|
|
37940
|
+
"opencode",
|
|
37941
|
+
"plugin",
|
|
37942
|
+
"tool-search",
|
|
37943
|
+
"mcp"
|
|
37944
|
+
],
|
|
37945
|
+
license: "MIT",
|
|
37946
|
+
devDependencies: {
|
|
37947
|
+
"@types/bun": "latest",
|
|
37948
|
+
typescript: "^5.9.3"
|
|
37949
|
+
},
|
|
37950
|
+
peerDependencies: {
|
|
37951
|
+
typescript: "^5"
|
|
37952
|
+
},
|
|
37953
|
+
dependencies: {
|
|
37954
|
+
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
37955
|
+
"@opencode-ai/plugin": "latest",
|
|
37956
|
+
"jsonc-parser": "^3.3.1",
|
|
37957
|
+
zod: "^4.3.5"
|
|
37958
|
+
}
|
|
37959
|
+
};
|
|
37960
|
+
|
|
37911
37961
|
// src/plugin.ts
|
|
37962
|
+
var PLUGIN_VERSION = package_default.version;
|
|
37912
37963
|
var DEFAULT_CONFIG_PATH = `${process.env.HOME}/.config/opencode/toolbox.jsonc`;
|
|
37964
|
+
var LOG_FILE_PATH = `${process.env.HOME}/.local/share/opencode/toolbox.log`;
|
|
37965
|
+
var LOG_DIR = `${process.env.HOME}/.local/share/opencode`;
|
|
37966
|
+
var COMMAND_DIR = `${process.env.HOME}/.config/opencode/command`;
|
|
37967
|
+
var COMMAND_FILE_PATH = `${COMMAND_DIR}/toolbox-status.md`;
|
|
37968
|
+
function getCommandContent() {
|
|
37969
|
+
return `---
|
|
37970
|
+
description: Check toolbox plugin status and server health
|
|
37971
|
+
toolbox_version: ${PLUGIN_VERSION}
|
|
37972
|
+
---
|
|
37973
|
+
Run toolbox_status({}) and show me the results in a readable format.
|
|
37974
|
+
Highlight any failed servers or issues.
|
|
37975
|
+
`;
|
|
37976
|
+
}
|
|
37913
37977
|
function parseToolName(fullName) {
|
|
37914
37978
|
const underscoreIndex = fullName.indexOf("_");
|
|
37915
37979
|
if (underscoreIndex === -1) {
|
|
@@ -37948,14 +38012,38 @@ Returns tools with schemas. Use toolbox_execute() to run them.`;
|
|
|
37948
38012
|
var EXECUTE_DESC = `Execute a tool discovered via toolbox_search_bm25 or toolbox_search_regex.
|
|
37949
38013
|
|
|
37950
38014
|
Pass arguments as JSON string matching the tool's schema.`;
|
|
38015
|
+
var STATUS_DESC = `Get toolbox status including plugin initialization, MCP server connections, and tool counts.
|
|
38016
|
+
|
|
38017
|
+
Shows success/total metrics to highlight failures. Use to check if toolbox is working correctly.`;
|
|
38018
|
+
function log(level, message, extra) {
|
|
38019
|
+
const timestamp = new Date().toISOString();
|
|
38020
|
+
const extraStr = extra ? ` ${JSON.stringify(extra)}` : "";
|
|
38021
|
+
const line = `${timestamp} [${level.toUpperCase()}] ${message}${extraStr}
|
|
38022
|
+
`;
|
|
38023
|
+
mkdir(LOG_DIR, { recursive: true }).then(() => appendFile(LOG_FILE_PATH, line)).catch(() => {});
|
|
38024
|
+
}
|
|
38025
|
+
function ensureCommandFile() {
|
|
38026
|
+
const content = getCommandContent();
|
|
38027
|
+
readFile(COMMAND_FILE_PATH, "utf-8").then((existing) => {
|
|
38028
|
+
const versionMatch = existing.match(/toolbox_version:\s*([^\n]+)/);
|
|
38029
|
+
const existingVersion = versionMatch?.[1]?.trim() ?? null;
|
|
38030
|
+
if (existingVersion !== PLUGIN_VERSION) {
|
|
38031
|
+
return writeFile(COMMAND_FILE_PATH, content).then(() => {
|
|
38032
|
+
log("info", `Updated /toolbox-status command (${existingVersion} -> ${PLUGIN_VERSION})`);
|
|
38033
|
+
});
|
|
38034
|
+
}
|
|
38035
|
+
}).catch(() => {
|
|
38036
|
+
mkdir(COMMAND_DIR, { recursive: true }).then(() => writeFile(COMMAND_FILE_PATH, content)).then(() => log("info", `Created /toolbox-status command (v${PLUGIN_VERSION})`)).catch(() => {});
|
|
38037
|
+
});
|
|
38038
|
+
}
|
|
37951
38039
|
var SYSTEM_PROMPT_BASE = `# Extended Toolbox
|
|
37952
38040
|
|
|
37953
38041
|
You have access to an extended toolbox with additional capabilities (web search, time utilities, code search, etc.).
|
|
37954
38042
|
|
|
37955
|
-
##
|
|
37956
|
-
|
|
37957
|
-
|
|
37958
|
-
|
|
38043
|
+
## Rule
|
|
38044
|
+
ALWAYS search before saying "I cannot do that" or "I don't have access to."
|
|
38045
|
+
DO NOT try to execute a tool without having the tool's exact tool schema. If you don't have the tool's schema
|
|
38046
|
+
then run toolbox_search_* to get them.
|
|
37959
38047
|
|
|
37960
38048
|
## Workflow
|
|
37961
38049
|
1. Search: toolbox_search_bm25({ text: "what you need" }) or toolbox_search_regex({ pattern: "prefix_.*" })
|
|
@@ -37965,43 +38053,78 @@ function generateSystemPrompt(mcpManager) {
|
|
|
37965
38053
|
if (servers.length === 0) {
|
|
37966
38054
|
return SYSTEM_PROMPT_BASE;
|
|
37967
38055
|
}
|
|
37968
|
-
const
|
|
38056
|
+
const toolboxSchema = {};
|
|
37969
38057
|
for (const server of servers) {
|
|
37970
38058
|
if (server.status === "connected" && server.tools.length > 0) {
|
|
37971
|
-
|
|
37972
|
-
serverLines.push(`- ${server.name}: ${toolNames}`);
|
|
38059
|
+
toolboxSchema[server.name] = server.tools.map((t) => t.idString);
|
|
37973
38060
|
}
|
|
37974
38061
|
}
|
|
37975
|
-
if (
|
|
38062
|
+
if (Object.keys(toolboxSchema).length === 0) {
|
|
37976
38063
|
return SYSTEM_PROMPT_BASE;
|
|
37977
38064
|
}
|
|
37978
38065
|
return `${SYSTEM_PROMPT_BASE}
|
|
37979
38066
|
|
|
37980
|
-
##
|
|
37981
|
-
|
|
37982
|
-
|
|
38067
|
+
## Toolbox Schema
|
|
38068
|
+
Tool names use \`<server>_<tool>\` format. Pass exact names to toolbox_execute().
|
|
38069
|
+
\`\`\`json
|
|
38070
|
+
${JSON.stringify(toolboxSchema, null, 2)}
|
|
38071
|
+
\`\`\``;
|
|
37983
38072
|
}
|
|
37984
38073
|
var ToolboxPlugin = async (ctx) => {
|
|
38074
|
+
const { client } = ctx;
|
|
37985
38075
|
const configPath = process.env.OPENCODE_TOOLBOX_CONFIG || DEFAULT_CONFIG_PATH;
|
|
37986
38076
|
const configResult = await loadConfig(configPath);
|
|
37987
38077
|
if (!configResult.success) {
|
|
37988
|
-
|
|
38078
|
+
const errorMsg = `Failed to load config from ${configPath}: ${configResult.error.issues.map((i) => i.message).join(", ")}`;
|
|
38079
|
+
log("error", errorMsg);
|
|
37989
38080
|
return {};
|
|
37990
38081
|
}
|
|
37991
38082
|
const config3 = configResult.data;
|
|
37992
38083
|
const mcpManager = new MCPManager;
|
|
37993
38084
|
const bm25Index = new BM25Index;
|
|
37994
38085
|
let initialized = false;
|
|
38086
|
+
let searchCount = 0;
|
|
38087
|
+
let executionCount = 0;
|
|
38088
|
+
let executionSuccessCount = 0;
|
|
38089
|
+
ensureCommandFile();
|
|
38090
|
+
const serverNames = Object.keys(config3.mcp);
|
|
38091
|
+
log("info", `Toolbox plugin loaded successfully`, {
|
|
38092
|
+
configPath,
|
|
38093
|
+
serverCount: serverNames.length,
|
|
38094
|
+
servers: serverNames
|
|
38095
|
+
});
|
|
37995
38096
|
async function ensureInitialized() {
|
|
37996
38097
|
if (initialized)
|
|
37997
38098
|
return;
|
|
37998
38099
|
try {
|
|
37999
|
-
|
|
38100
|
+
log("info", "Initializing MCP servers...");
|
|
38101
|
+
await mcpManager.initialize(config3.mcp);
|
|
38000
38102
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38001
38103
|
bm25Index.indexTools(allTools);
|
|
38002
38104
|
initialized = true;
|
|
38105
|
+
const servers = mcpManager.getAllServers();
|
|
38106
|
+
const connectedServers = servers.filter((s) => s.status === "connected");
|
|
38107
|
+
const failedServers = servers.filter((s) => s.status === "error");
|
|
38108
|
+
const initMsg = `Initialization complete: ${connectedServers.length}/${servers.length} servers connected, ${allTools.length} tools indexed`;
|
|
38109
|
+
log("info", initMsg, {
|
|
38110
|
+
totalServers: servers.length,
|
|
38111
|
+
connectedServers: connectedServers.length,
|
|
38112
|
+
failedServers: failedServers.length,
|
|
38113
|
+
totalTools: allTools.length,
|
|
38114
|
+
servers: servers.map((s) => ({
|
|
38115
|
+
name: s.name,
|
|
38116
|
+
status: s.status,
|
|
38117
|
+
toolCount: s.tools.length,
|
|
38118
|
+
error: s.error || null
|
|
38119
|
+
}))
|
|
38120
|
+
});
|
|
38121
|
+
if (failedServers.length > 0) {
|
|
38122
|
+
const warnMsg = `${failedServers.length} server(s) failed to connect: ${failedServers.map((s) => s.name).join(", ")}`;
|
|
38123
|
+
log("warn", warnMsg);
|
|
38124
|
+
}
|
|
38003
38125
|
} catch (error92) {
|
|
38004
|
-
|
|
38126
|
+
const errorMsg = `Failed to initialize MCP servers: ${error92 instanceof Error ? error92.message : String(error92)}`;
|
|
38127
|
+
log("error", errorMsg);
|
|
38005
38128
|
throw error92;
|
|
38006
38129
|
}
|
|
38007
38130
|
}
|
|
@@ -38022,9 +38145,16 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38022
38145
|
error: `Failed to initialize: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38023
38146
|
});
|
|
38024
38147
|
}
|
|
38148
|
+
searchCount++;
|
|
38025
38149
|
const searchLimit = args.limit || config3.settings?.defaultLimit || 5;
|
|
38026
38150
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38027
38151
|
const results = bm25Index.search(args.text, searchLimit);
|
|
38152
|
+
log("info", `BM25 search completed: "${args.text}" -> ${results.length} results`, {
|
|
38153
|
+
searchType: "bm25",
|
|
38154
|
+
query: args.text,
|
|
38155
|
+
resultsCount: results.length,
|
|
38156
|
+
limit: searchLimit
|
|
38157
|
+
});
|
|
38028
38158
|
return formatSearchResults(results, allTools);
|
|
38029
38159
|
}
|
|
38030
38160
|
}),
|
|
@@ -38043,15 +38173,23 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38043
38173
|
error: `Failed to initialize: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38044
38174
|
});
|
|
38045
38175
|
}
|
|
38176
|
+
searchCount++;
|
|
38046
38177
|
const searchLimit = args.limit || config3.settings?.defaultLimit || 5;
|
|
38047
38178
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38048
38179
|
const result = searchWithRegex(allTools, args.pattern, searchLimit);
|
|
38049
38180
|
if ("error" in result) {
|
|
38181
|
+
log("warn", `Regex search failed: "${args.pattern}" -> ${result.error}`);
|
|
38050
38182
|
return JSON.stringify({
|
|
38051
38183
|
success: false,
|
|
38052
38184
|
error: result.error
|
|
38053
38185
|
});
|
|
38054
38186
|
}
|
|
38187
|
+
log("info", `Regex search completed: "${args.pattern}" -> ${result.length} results`, {
|
|
38188
|
+
searchType: "regex",
|
|
38189
|
+
pattern: args.pattern,
|
|
38190
|
+
resultsCount: result.length,
|
|
38191
|
+
limit: searchLimit
|
|
38192
|
+
});
|
|
38055
38193
|
return formatSearchResults(result, allTools);
|
|
38056
38194
|
}
|
|
38057
38195
|
}),
|
|
@@ -38072,6 +38210,9 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38072
38210
|
}
|
|
38073
38211
|
const parsed = parseToolName(args.name);
|
|
38074
38212
|
if (!parsed) {
|
|
38213
|
+
log("warn", `Invalid tool name format: ${args.name}`, {
|
|
38214
|
+
toolName: args.name
|
|
38215
|
+
});
|
|
38075
38216
|
return JSON.stringify({
|
|
38076
38217
|
success: false,
|
|
38077
38218
|
error: `Invalid tool name format: ${args.name}. Expected format: serverName_toolName (e.g., 'time_get_current_time')`
|
|
@@ -38082,25 +38223,106 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38082
38223
|
try {
|
|
38083
38224
|
toolArgs = JSON.parse(args.arguments);
|
|
38084
38225
|
} catch (error92) {
|
|
38226
|
+
log("warn", `Failed to parse arguments as JSON for ${args.name}`, {
|
|
38227
|
+
toolName: args.name,
|
|
38228
|
+
arguments: args.arguments
|
|
38229
|
+
});
|
|
38085
38230
|
return JSON.stringify({
|
|
38086
38231
|
success: false,
|
|
38087
38232
|
error: `Failed to parse arguments as JSON: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38088
38233
|
});
|
|
38089
38234
|
}
|
|
38090
38235
|
}
|
|
38236
|
+
executionCount++;
|
|
38091
38237
|
try {
|
|
38238
|
+
const startTime = Date.now();
|
|
38092
38239
|
const result = await mcpManager.callTool(parsed.serverName, parsed.toolName, toolArgs);
|
|
38240
|
+
const duration5 = Date.now() - startTime;
|
|
38241
|
+
executionSuccessCount++;
|
|
38242
|
+
log("info", `Tool executed successfully: ${args.name}`, {
|
|
38243
|
+
server: parsed.serverName,
|
|
38244
|
+
tool: parsed.toolName,
|
|
38245
|
+
durationMs: duration5
|
|
38246
|
+
});
|
|
38093
38247
|
return JSON.stringify({
|
|
38094
38248
|
success: true,
|
|
38095
38249
|
result
|
|
38096
38250
|
});
|
|
38097
38251
|
} catch (error92) {
|
|
38252
|
+
const errorMsg = `Tool execution failed: ${error92 instanceof Error ? error92.message : String(error92)}`;
|
|
38253
|
+
log("error", errorMsg, {
|
|
38254
|
+
server: parsed.serverName,
|
|
38255
|
+
tool: parsed.toolName,
|
|
38256
|
+
error: errorMsg
|
|
38257
|
+
});
|
|
38098
38258
|
return JSON.stringify({
|
|
38099
38259
|
success: false,
|
|
38100
|
-
error:
|
|
38260
|
+
error: errorMsg
|
|
38101
38261
|
});
|
|
38102
38262
|
}
|
|
38103
38263
|
}
|
|
38264
|
+
}),
|
|
38265
|
+
toolbox_status: tool({
|
|
38266
|
+
description: STATUS_DESC,
|
|
38267
|
+
args: {},
|
|
38268
|
+
async execute() {
|
|
38269
|
+
if (!initialized) {
|
|
38270
|
+
try {
|
|
38271
|
+
await ensureInitialized();
|
|
38272
|
+
} catch (error92) {
|
|
38273
|
+
return JSON.stringify({
|
|
38274
|
+
status: "error",
|
|
38275
|
+
message: "Failed to initialize toolbox",
|
|
38276
|
+
error: error92 instanceof Error ? error92.message : String(error92)
|
|
38277
|
+
});
|
|
38278
|
+
}
|
|
38279
|
+
}
|
|
38280
|
+
const servers = mcpManager.getAllServers();
|
|
38281
|
+
const connectedServers = servers.filter((s) => s.status === "connected");
|
|
38282
|
+
const failedServers = servers.filter((s) => s.status === "error");
|
|
38283
|
+
const connectingServers = servers.filter((s) => s.status === "connecting");
|
|
38284
|
+
const totalTools = mcpManager.getAllCatalogTools().length;
|
|
38285
|
+
const status = {
|
|
38286
|
+
plugin: {
|
|
38287
|
+
initialized: true,
|
|
38288
|
+
configPath,
|
|
38289
|
+
uptime: process.uptime(),
|
|
38290
|
+
searches: searchCount,
|
|
38291
|
+
executions: executionCount,
|
|
38292
|
+
successRate: executionCount > 0 ? `${Math.round(executionSuccessCount / executionCount * 100)}%` : "N/A"
|
|
38293
|
+
},
|
|
38294
|
+
servers: {
|
|
38295
|
+
total: servers.length,
|
|
38296
|
+
connected: connectedServers.length,
|
|
38297
|
+
failed: failedServers.length,
|
|
38298
|
+
connecting: connectingServers.length,
|
|
38299
|
+
connectionRatio: `${connectedServers.length}/${servers.length}`,
|
|
38300
|
+
details: servers.map((server) => ({
|
|
38301
|
+
name: server.name,
|
|
38302
|
+
status: server.status,
|
|
38303
|
+
type: server.config.type,
|
|
38304
|
+
toolCount: server.tools.length,
|
|
38305
|
+
error: server.error || null,
|
|
38306
|
+
healthy: server.status === "connected"
|
|
38307
|
+
}))
|
|
38308
|
+
},
|
|
38309
|
+
tools: {
|
|
38310
|
+
total: totalTools,
|
|
38311
|
+
available: totalTools,
|
|
38312
|
+
serversWithTools: servers.filter((s) => s.tools.length > 0).length
|
|
38313
|
+
},
|
|
38314
|
+
health: {
|
|
38315
|
+
status: failedServers.length === 0 && servers.length > 0 ? "healthy" : failedServers.length > 0 ? "degraded" : "unknown",
|
|
38316
|
+
message: servers.length === 0 ? "No servers configured" : failedServers.length === 0 ? "All servers connected" : `${failedServers.length} server(s) failed to connect`
|
|
38317
|
+
}
|
|
38318
|
+
};
|
|
38319
|
+
log("info", `Status requested: ${connectedServers.length}/${servers.length} servers connected`, {
|
|
38320
|
+
connectedServers: connectedServers.length,
|
|
38321
|
+
totalServers: servers.length,
|
|
38322
|
+
totalTools
|
|
38323
|
+
});
|
|
38324
|
+
return JSON.stringify(status, null, 2);
|
|
38325
|
+
}
|
|
38104
38326
|
})
|
|
38105
38327
|
},
|
|
38106
38328
|
"experimental.chat.system.transform": async (_input, output) => {
|
package/package.json
CHANGED