feat(mcp): reconnect failed MCP servers in managed OpenCode
OpenCode marks an MCP server failed when it does not come up at startup or when a live connection drops, and never retries. A new managed plugin reconnects those servers with a per-server backoff (1s doubling to a 30s cap), wakes early on mcp.tools.changed, and stops on dispose. Only the failed state is retried; disabled and auth states stay untouched. The OPENCODE_CONFIG_CONTENT merge that agent-tool and system-prompt each carried is now one shared helper so the three managed plugins compose. Claude-Session: https://claude.ai/code/session_01VqV56Hez25hTxXH4ipJfzH
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { parse as parseJsonc } from 'jsonc-parser';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { appendManagedPlugin } from '../opencode/managed-plugin-config.js';
|
||||
import {
|
||||
OPENCHAMBER_AGENT_TOOL_ACTION_DEFINITIONS,
|
||||
OPENCHAMBER_AGENT_TOOL_ACTIONS,
|
||||
@@ -252,23 +252,6 @@ ${entries.join('')} },
|
||||
`;
|
||||
};
|
||||
|
||||
const mergePluginConfig = (rawConfig, pluginUrl) => {
|
||||
const errors = [];
|
||||
const parsed = asNonEmptyString(rawConfig) ? parseJsonc(rawConfig, errors, { allowTrailingComma: true }) : {};
|
||||
if (errors.length > 0 || !parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
||||
throw new Error('OPENCODE_CONFIG_CONTENT must contain a valid JSON object before OpenChamber can inject its managed tool');
|
||||
}
|
||||
if (parsed.plugin !== undefined && !Array.isArray(parsed.plugin)) {
|
||||
throw new Error('OPENCODE_CONFIG_CONTENT plugin must be an array before OpenChamber can inject its managed tool');
|
||||
}
|
||||
const configured = Array.isArray(parsed.plugin) ? parsed.plugin : [];
|
||||
parsed.plugin = [
|
||||
...configured.filter((value) => value !== pluginUrl && (!Array.isArray(value) || value[0] !== pluginUrl)),
|
||||
pluginUrl,
|
||||
];
|
||||
return JSON.stringify(parsed);
|
||||
};
|
||||
|
||||
export const createAgentToolRuntime = (dependencies) => {
|
||||
const {
|
||||
crypto,
|
||||
@@ -296,7 +279,7 @@ export const createAgentToolRuntime = (dependencies) => {
|
||||
activeToken = crypto.randomBytes(32).toString('base64url');
|
||||
const pluginUrl = pathToFileURL(pluginPath).href;
|
||||
return {
|
||||
OPENCODE_CONFIG_CONTENT: mergePluginConfig(env.OPENCODE_CONFIG_CONTENT, pluginUrl),
|
||||
OPENCODE_CONFIG_CONTENT: appendManagedPlugin(env.OPENCODE_CONFIG_CONTENT, pluginUrl, 'managed tool'),
|
||||
OPENCHAMBER_AGENT_TOOL_URL: `http://127.0.0.1:${port}/api/openchamber/agent-tool`,
|
||||
OPENCHAMBER_AGENT_TOOL_TOKEN: activeToken,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user