mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
fix(cli-runtime): replace overlapping user mcp servers
This commit is contained in:
committed by
Peter Steinberger
parent
d8ae63e7a2
commit
b86a04262d
@@ -263,6 +263,7 @@ describe("prepareCliBundleMcpConfig", () => {
|
||||
});
|
||||
|
||||
const configFlagIndex = prepared.backend.args?.indexOf("--mcp-config") ?? -1;
|
||||
expect(configFlagIndex).toBeGreaterThanOrEqual(0);
|
||||
const generatedConfigPath = prepared.backend.args?.[configFlagIndex + 1];
|
||||
const raw = JSON.parse(await fs.readFile(generatedConfigPath as string, "utf-8")) as {
|
||||
mcpServers?: Record<string, { url?: string }>;
|
||||
@@ -272,6 +273,90 @@ describe("prepareCliBundleMcpConfig", () => {
|
||||
await prepared.cleanup?.();
|
||||
});
|
||||
|
||||
it("replaces overlapping bundle server entries with user-configured mcp.servers", async () => {
|
||||
const workspaceDir = await tempHarness.createTempDir(
|
||||
"openclaw-cli-bundle-mcp-user-servers-replace-",
|
||||
);
|
||||
await writeClaudeBundleManifest({
|
||||
homeDir: bundleProbeHomeDir,
|
||||
pluginId: "omi",
|
||||
manifest: { name: "omi" },
|
||||
});
|
||||
const pluginDir = path.join(bundleProbeHomeDir, ".openclaw", "extensions", "omi");
|
||||
await fs.writeFile(
|
||||
path.join(pluginDir, ".mcp.json"),
|
||||
`${JSON.stringify(
|
||||
{
|
||||
mcpServers: {
|
||||
omi: {
|
||||
command: process.execPath,
|
||||
args: [bundleProbeServerPath],
|
||||
env: { BUNDLE_ONLY: "true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const env = captureEnv(["HOME"]);
|
||||
try {
|
||||
process.env.HOME = bundleProbeHomeDir;
|
||||
const prepared = await prepareCliBundleMcpConfig({
|
||||
enabled: true,
|
||||
mode: "claude-config-file",
|
||||
backend: {
|
||||
command: "node",
|
||||
args: ["./fake-claude.mjs"],
|
||||
},
|
||||
workspaceDir,
|
||||
config: {
|
||||
plugins: {
|
||||
entries: {
|
||||
omi: { enabled: true, path: pluginDir },
|
||||
},
|
||||
},
|
||||
mcp: {
|
||||
servers: {
|
||||
omi: {
|
||||
type: "sse",
|
||||
url: "https://api.omi.me/v1/mcp/sse",
|
||||
headers: { Authorization: "Bearer test-token" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const configFlagIndex = prepared.backend.args?.indexOf("--mcp-config") ?? -1;
|
||||
expect(configFlagIndex).toBeGreaterThanOrEqual(0);
|
||||
const generatedConfigPath = prepared.backend.args?.[configFlagIndex + 1];
|
||||
const raw = JSON.parse(await fs.readFile(generatedConfigPath as string, "utf-8")) as {
|
||||
mcpServers?: Record<
|
||||
string,
|
||||
{
|
||||
type?: string;
|
||||
url?: string;
|
||||
command?: string;
|
||||
args?: string[];
|
||||
env?: Record<string, string>;
|
||||
}
|
||||
>;
|
||||
};
|
||||
expect(raw.mcpServers?.omi?.type).toBe("sse");
|
||||
expect(raw.mcpServers?.omi?.url).toBe("https://api.omi.me/v1/mcp/sse");
|
||||
expect(raw.mcpServers?.omi?.command).toBeUndefined();
|
||||
expect(raw.mcpServers?.omi?.args).toBeUndefined();
|
||||
expect(raw.mcpServers?.omi?.env).toBeUndefined();
|
||||
|
||||
await prepared.cleanup?.();
|
||||
} finally {
|
||||
env.restore();
|
||||
}
|
||||
});
|
||||
|
||||
it("stabilizes the resume hash when only the OpenClaw loopback port changes", async () => {
|
||||
const first = await prepareBundleProbeCliConfig({
|
||||
additionalConfig: {
|
||||
|
||||
@@ -2,8 +2,8 @@ import crypto from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { applyMergePatch } from "../../config/merge-patch.js";
|
||||
import { normalizeConfiguredMcpServers } from "../../config/mcp-config.js";
|
||||
import { applyMergePatch } from "../../config/merge-patch.js";
|
||||
import type { CliBackendConfig } from "../../config/types.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import {
|
||||
@@ -418,7 +418,13 @@ export async function prepareCliBundleMcpConfig(params: {
|
||||
mergedConfig = applyMergePatch(mergedConfig, bundleConfig.config) as BundleMcpConfig;
|
||||
const configuredMcp = normalizeConfiguredMcpServers(params.config?.mcp?.servers);
|
||||
if (Object.keys(configuredMcp).length > 0) {
|
||||
mergedConfig = applyMergePatch(mergedConfig, { mcpServers: configuredMcp }) as BundleMcpConfig;
|
||||
mergedConfig = {
|
||||
...mergedConfig,
|
||||
mcpServers: {
|
||||
...(mergedConfig.mcpServers ?? {}),
|
||||
...configuredMcp,
|
||||
},
|
||||
} satisfies BundleMcpConfig;
|
||||
}
|
||||
if (params.additionalConfig) {
|
||||
mergedConfig = applyMergePatch(mergedConfig, params.additionalConfig) as BundleMcpConfig;
|
||||
|
||||
Reference in New Issue
Block a user