Skip to content

Commit b0ac8ce

Browse files
fix(mcp): write QwenWork config to ~/.qwenworkcn/mcp.json
QwenWork reads the home-directory mcp.json, not Electron userData, so native connect was a no-op. Also emit type streamable-http to match the official connector schema. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 02d4e97 commit b0ac8ce

2 files changed

Lines changed: 21 additions & 32 deletions

File tree

packages/commands/src/commands/mcp/agent-config.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,15 @@ function unsupportedSseError(agent: NativeMcpAgent): BailianError {
180180
);
181181
}
182182

183-
function qwenworkUserDataDirs(home: string): string[] {
184-
if (process.platform === "darwin") {
185-
const support = join(home, "Library", "Application Support");
186-
return [join(support, "QwenWorkCN"), join(support, "QwenWork"), join(support, "QwenWork CN")];
187-
}
188-
if (process.platform === "win32") {
189-
const appData = join(home, "AppData", "Roaming");
190-
return [join(appData, "QwenWorkCN"), join(appData, "QwenWork")];
191-
}
192-
return [join(home, ".config", "QwenWorkCN"), join(home, ".config", "QwenWork")];
183+
const QWENWORK_DIRS = [".qwenworkcn", ".qwenwork"] as const;
184+
185+
function qwenworkConfigDirs(home: string): string[] {
186+
return QWENWORK_DIRS.map((dir) => join(home, dir));
193187
}
194188

195-
/** QwenWork / 千问办公 stores MCP config in Electron userData (`mcp.json`). */
189+
/** QwenWork / 千问办公 stores MCP config in `~/.qwenworkcn/mcp.json` (or `~/.qwenwork/mcp.json`). */
196190
export function qwenworkMcpPath(home: string): string {
197-
const dirs = qwenworkUserDataDirs(home);
191+
const dirs = qwenworkConfigDirs(home);
198192
for (const dir of dirs) {
199193
const file = join(dir, "mcp.json");
200194
if (existsSync(file)) return file;
@@ -393,8 +387,13 @@ const adapters: Record<NativeMcpAgent, AgentAdapter> = {
393387
}),
394388
qwenwork: jsonMcpAdapter({
395389
path: qwenworkMcpPath,
396-
installed: (home) => qwenworkUserDataDirs(home).some((dir) => existsSync(dir)),
397-
typed: true,
390+
installed: (home) =>
391+
qwenworkConfigDirs(home).some((dir) => existsSync(dir) || existsSync(join(dir, "mcp.json"))),
392+
buildEntry: (spec) => ({
393+
type: spec.transport === "sse" ? "sse" : "streamable-http",
394+
url: spec.endpoint,
395+
headers: spec.headers,
396+
}),
398397
}),
399398
"qwen-code": {
400399
path: (home) => join(home, ".qwen", "settings.json"),

packages/commands/tests/mcp-agent-config.test.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,8 @@ describe("MCP Agent registration", () => {
133133
},
134134
{
135135
agent: "qwenwork" as const,
136-
path:
137-
process.platform === "darwin"
138-
? ["Library", "Application Support", "QwenWorkCN", "mcp.json"]
139-
: process.platform === "win32"
140-
? ["AppData", "Roaming", "QwenWorkCN", "mcp.json"]
141-
: [".config", "QwenWorkCN", "mcp.json"],
142-
streamable: { type: "http", url: spec().endpoint, headers: spec().headers },
136+
path: [".qwenworkcn", "mcp.json"],
137+
streamable: { type: "streamable-http", url: spec().endpoint, headers: spec().headers },
143138
sse: { type: "sse", url: spec("sse").endpoint, headers: spec("sse").headers },
144139
},
145140
])(
@@ -282,7 +277,7 @@ describe("MCP Agent registration", () => {
282277
});
283278
});
284279

285-
test("qwenwork writes Electron userData mcp.json and never uses Qoder Work", () => {
280+
test("qwenwork writes ~/.qwenworkcn/mcp.json and never uses Qoder Work", () => {
286281
mkdirSync(join(home, ".qoderwork"), { recursive: true });
287282
const [result] = connectMcpAgents({
288283
agents: ["qwenwork"],
@@ -292,23 +287,18 @@ describe("MCP Agent registration", () => {
292287
configDir,
293288
});
294289
expect(result.status).toBe("added");
295-
expect(result.path).toBe(qwenworkMcpPath(home));
290+
expect(result.path).toBe(join(home, ".qwenworkcn", "mcp.json"));
296291
expect(result.path).not.toContain(".qoderwork");
297292
expect(existsSync(join(home, ".qoderwork", "mcp.json"))).toBe(false);
298293
expect(readJson(result.path)).toMatchObject({
299294
mcpServers: {
300-
ImageGenerate: { type: "http", url: spec().endpoint, headers: spec().headers },
295+
ImageGenerate: { type: "streamable-http", url: spec().endpoint, headers: spec().headers },
301296
},
302297
});
303298
});
304299

305-
test("qwenwork prefers an existing QwenWork mcp.json over creating QwenWorkCN", () => {
306-
const intlPath =
307-
process.platform === "darwin"
308-
? join(home, "Library", "Application Support", "QwenWork", "mcp.json")
309-
: process.platform === "win32"
310-
? join(home, "AppData", "Roaming", "QwenWork", "mcp.json")
311-
: join(home, ".config", "QwenWork", "mcp.json");
300+
test("qwenwork prefers an existing ~/.qwenwork/mcp.json over creating .qwenworkcn", () => {
301+
const intlPath = join(home, ".qwenwork", "mcp.json");
312302
mkdirSync(join(intlPath, ".."), { recursive: true });
313303
writeFileSync(intlPath, JSON.stringify({ keep: true }));
314304

@@ -323,7 +313,7 @@ describe("MCP Agent registration", () => {
323313
expect(readJson(intlPath)).toMatchObject({
324314
keep: true,
325315
mcpServers: {
326-
ImageGenerate: { type: "http", url: spec().endpoint, headers: spec().headers },
316+
ImageGenerate: { type: "streamable-http", url: spec().endpoint, headers: spec().headers },
327317
},
328318
});
329319
});

0 commit comments

Comments
 (0)