opencode-toolbox 0.4.0 → 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 +156 -7
- package/dist/index.js +226 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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, {
|
|
@@ -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,12 +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
38043
|
## Rule
|
|
37956
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.
|
|
37957
38047
|
|
|
37958
38048
|
## Workflow
|
|
37959
38049
|
1. Search: toolbox_search_bm25({ text: "what you need" }) or toolbox_search_regex({ pattern: "prefix_.*" })
|
|
@@ -37981,26 +38071,60 @@ ${JSON.stringify(toolboxSchema, null, 2)}
|
|
|
37981
38071
|
\`\`\``;
|
|
37982
38072
|
}
|
|
37983
38073
|
var ToolboxPlugin = async (ctx) => {
|
|
38074
|
+
const { client } = ctx;
|
|
37984
38075
|
const configPath = process.env.OPENCODE_TOOLBOX_CONFIG || DEFAULT_CONFIG_PATH;
|
|
37985
38076
|
const configResult = await loadConfig(configPath);
|
|
37986
38077
|
if (!configResult.success) {
|
|
37987
|
-
|
|
38078
|
+
const errorMsg = `Failed to load config from ${configPath}: ${configResult.error.issues.map((i) => i.message).join(", ")}`;
|
|
38079
|
+
log("error", errorMsg);
|
|
37988
38080
|
return {};
|
|
37989
38081
|
}
|
|
37990
38082
|
const config3 = configResult.data;
|
|
37991
38083
|
const mcpManager = new MCPManager;
|
|
37992
38084
|
const bm25Index = new BM25Index;
|
|
37993
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
|
+
});
|
|
37994
38096
|
async function ensureInitialized() {
|
|
37995
38097
|
if (initialized)
|
|
37996
38098
|
return;
|
|
37997
38099
|
try {
|
|
38100
|
+
log("info", "Initializing MCP servers...");
|
|
37998
38101
|
await mcpManager.initialize(config3.mcp);
|
|
37999
38102
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38000
38103
|
bm25Index.indexTools(allTools);
|
|
38001
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
|
+
}
|
|
38002
38125
|
} catch (error92) {
|
|
38003
|
-
|
|
38126
|
+
const errorMsg = `Failed to initialize MCP servers: ${error92 instanceof Error ? error92.message : String(error92)}`;
|
|
38127
|
+
log("error", errorMsg);
|
|
38004
38128
|
throw error92;
|
|
38005
38129
|
}
|
|
38006
38130
|
}
|
|
@@ -38021,9 +38145,16 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38021
38145
|
error: `Failed to initialize: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38022
38146
|
});
|
|
38023
38147
|
}
|
|
38148
|
+
searchCount++;
|
|
38024
38149
|
const searchLimit = args.limit || config3.settings?.defaultLimit || 5;
|
|
38025
38150
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38026
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
|
+
});
|
|
38027
38158
|
return formatSearchResults(results, allTools);
|
|
38028
38159
|
}
|
|
38029
38160
|
}),
|
|
@@ -38042,15 +38173,23 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38042
38173
|
error: `Failed to initialize: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38043
38174
|
});
|
|
38044
38175
|
}
|
|
38176
|
+
searchCount++;
|
|
38045
38177
|
const searchLimit = args.limit || config3.settings?.defaultLimit || 5;
|
|
38046
38178
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38047
38179
|
const result = searchWithRegex(allTools, args.pattern, searchLimit);
|
|
38048
38180
|
if ("error" in result) {
|
|
38181
|
+
log("warn", `Regex search failed: "${args.pattern}" -> ${result.error}`);
|
|
38049
38182
|
return JSON.stringify({
|
|
38050
38183
|
success: false,
|
|
38051
38184
|
error: result.error
|
|
38052
38185
|
});
|
|
38053
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
|
+
});
|
|
38054
38193
|
return formatSearchResults(result, allTools);
|
|
38055
38194
|
}
|
|
38056
38195
|
}),
|
|
@@ -38071,6 +38210,9 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38071
38210
|
}
|
|
38072
38211
|
const parsed = parseToolName(args.name);
|
|
38073
38212
|
if (!parsed) {
|
|
38213
|
+
log("warn", `Invalid tool name format: ${args.name}`, {
|
|
38214
|
+
toolName: args.name
|
|
38215
|
+
});
|
|
38074
38216
|
return JSON.stringify({
|
|
38075
38217
|
success: false,
|
|
38076
38218
|
error: `Invalid tool name format: ${args.name}. Expected format: serverName_toolName (e.g., 'time_get_current_time')`
|
|
@@ -38081,25 +38223,106 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38081
38223
|
try {
|
|
38082
38224
|
toolArgs = JSON.parse(args.arguments);
|
|
38083
38225
|
} catch (error92) {
|
|
38226
|
+
log("warn", `Failed to parse arguments as JSON for ${args.name}`, {
|
|
38227
|
+
toolName: args.name,
|
|
38228
|
+
arguments: args.arguments
|
|
38229
|
+
});
|
|
38084
38230
|
return JSON.stringify({
|
|
38085
38231
|
success: false,
|
|
38086
38232
|
error: `Failed to parse arguments as JSON: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38087
38233
|
});
|
|
38088
38234
|
}
|
|
38089
38235
|
}
|
|
38236
|
+
executionCount++;
|
|
38090
38237
|
try {
|
|
38238
|
+
const startTime = Date.now();
|
|
38091
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
|
+
});
|
|
38092
38247
|
return JSON.stringify({
|
|
38093
38248
|
success: true,
|
|
38094
38249
|
result
|
|
38095
38250
|
});
|
|
38096
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
|
+
});
|
|
38097
38258
|
return JSON.stringify({
|
|
38098
38259
|
success: false,
|
|
38099
|
-
error:
|
|
38260
|
+
error: errorMsg
|
|
38100
38261
|
});
|
|
38101
38262
|
}
|
|
38102
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
|
+
}
|
|
38103
38326
|
})
|
|
38104
38327
|
},
|
|
38105
38328
|
"experimental.chat.system.transform": async (_input, output) => {
|
package/package.json
CHANGED