feat(mcp): add Cursor, Qoder, Qoder Work, and QwenWork native MCP targets

This commit is contained in:
rendianmeng
2026-09-14 11:42:29 +08:00
parent abfb69b6d6
commit c957e2ed28
13 changed files with 290 additions and 53 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ _Built for AI Agents. Every command works as a structured tool call._
- **Model generation** — Full-modality generation across text, image, video, and speech, with editing and reference-based generation
- **Asset understanding** — Parse and ask questions about images, documents, audio, and long videos
- **App orchestration** — Call Managed Agents, agents, and workflows published on Aliyun Model Studio, wired to knowledge bases, memory, web search, and MCP tools
- **Native MCP setup** — Register Bailian MCP servers in Codex, Claude Code, Qwen Code, or Gemini CLI with channel attribution preserved
- **Native MCP setup** — Register Bailian MCP servers in Codex, Claude Code, Cursor, Qoder, Qoder Work, QwenWork (千问办公), Qwen Code, or Gemini CLI with channel attribution preserved
- **Training & deployment** — Validate and upload datasets, fine-tune models, deploy dedicated models as endpoints
- **Account operations** — Login, UI-based configuration, model marketplace, usage and quota, rate-limit increases, team seat management
- **Plan onboarding** — Connect subscription plans such as Token Plan to the CLI and common coding agents in one step
+1 -1
View File
@@ -25,7 +25,7 @@ _专为 AI Agent 打造,每个命令均可作为结构化工具调用。_
- **模型生成** — 文本、图像、视频、语音全模态生成,支持编辑与参考生成
- **素材理解** — 图像、文档、音频、长视频的解析与问答
- **应用编排** — 调用百炼已发布的 Managed Agent、智能体和工作流,接入知识库、记忆库、联网搜索与 MCP 工具
- **原生 MCP 接入** — 将百炼 MCP 服务注册到 Codex、Claude Code、Qwen Code 或 Gemini CLI,并保留渠道归因
- **原生 MCP 接入** — 将百炼 MCP 服务注册到 Codex、Claude Code、Cursor、Qoder、Qoder Work、千问办公(QwenWork)、Qwen Code 或 Gemini CLI,并保留渠道归因
- **模型训推** — 数据集校验上传、模型精调、专属模型部署上线
- **账号运维** — 授权登录、界面化配置、模型市场、用量与额度、限流提额、团队席位管理
- **套餐接入** — 支持 Token Plan 等订阅计划一键接到 CLI 和常见 Coding Agent
+1 -1
View File
@@ -26,7 +26,7 @@ _Built for AI Agents. Every command works as a structured tool call._
- **Model generation** — Full-modality generation across text, image, video, and speech, with editing and reference-based generation
- **Asset understanding** — Parse and ask questions about images, documents, audio, and long videos
- **App orchestration** — Call Managed Agents, agents, and workflows published on Aliyun Model Studio, wired to knowledge bases, memory, web search, and MCP tools
- **Native MCP setup** — Register Bailian MCP servers in Codex, Claude Code, Qwen Code, or Gemini CLI with channel attribution preserved
- **Native MCP setup** — Register Bailian MCP servers in Codex, Claude Code, Cursor, Qoder, Qoder Work, QwenWork (千问办公), Qwen Code, or Gemini CLI with channel attribution preserved
- **Training & deployment** — Validate and upload datasets, fine-tune models, deploy dedicated models as endpoints
- **Account operations** — Login, UI-based configuration, model marketplace, usage and quota, rate-limit increases, team seat management
- **Plan onboarding** — Connect subscription plans such as Token Plan to the CLI and common coding agents in one step
+1 -1
View File
@@ -25,7 +25,7 @@ _专为 AI Agent 打造,每个命令均可作为结构化工具调用。_
- **模型生成** — 文本、图像、视频、语音全模态生成,支持编辑与参考生成
- **素材理解** — 图像、文档、音频、长视频的解析与问答
- **应用编排** — 调用百炼已发布的 Managed Agent、智能体和工作流,接入知识库、记忆库、联网搜索与 MCP 工具
- **原生 MCP 接入** — 将百炼 MCP 服务注册到 Codex、Claude Code、Qwen Code 或 Gemini CLI,并保留渠道归因
- **原生 MCP 接入** — 将百炼 MCP 服务注册到 Codex、Claude Code、Cursor、Qoder、Qoder Work、千问办公(QwenWork)、Qwen Code 或 Gemini CLI,并保留渠道归因
- **模型训推** — 数据集校验上传、模型精调、专属模型部署上线
- **账号运维** — 授权登录、界面化配置、模型市场、用量与额度、限流提额、团队席位管理
- **套餐接入** — 支持 Token Plan 等订阅计划一键接到 CLI 和常见 Coding Agent
@@ -19,6 +19,7 @@ import {
import { inflateRawSync } from "node:zlib";
import yaml from "yaml";
import { parse as parseToml } from "smol-toml";
import { qwenworkMcpPath } from "../mcp/agent-config.ts";
/**
* Where an item comes from. Everything discovered on disk today is `local`;
@@ -453,20 +454,26 @@ export function listMcpServers(home: string = homedir()): McpServerInfo[] {
const opencode = readJsonSafe(join(home, ".config", "opencode", "opencode.json"));
if (opencode) collectMcpMap(opencode.mcp, "opencode", "global", out, true);
// Cursor, Windsurf, Gemini, QoderWork, OpenClaw, Claude Desktop: all JSON with
// a top-level `mcpServers` map (Claude/Cursor convention).
// Cursor, Windsurf, Gemini, Qoder, Qoder Work, QwenWork (千问办公), OpenClaw,
// Claude Desktop: JSON with a top-level `mcpServers` map.
const cursor = readJsonSafe(join(home, ".cursor", "mcp.json"));
if (cursor) collectMcpMap(cursor.mcpServers, "cursor", "global", out, true);
const qoder = readJsonSafe(join(home, ".qoder", "mcp.json"));
if (qoder) collectMcpMap(qoder.mcpServers, "qoder", "global", out, true);
const qoderwork = readJsonSafe(join(home, ".qoderwork", "mcp.json"));
if (qoderwork) collectMcpMap(qoderwork.mcpServers, "qoderwork", "global", out, true);
const qwenwork = readJsonSafe(qwenworkMcpPath(home));
if (qwenwork) collectMcpMap(qwenwork.mcpServers, "qwenwork", "global", out, true);
const windsurf = readJsonSafe(join(home, ".codeium", "windsurf", "mcp_config.json"));
if (windsurf) collectMcpMap(windsurf.mcpServers, "windsurf", "global", out, true);
const gemini = readJsonSafe(join(home, ".gemini", "settings.json"));
if (gemini) collectMcpMap(gemini.mcpServers, "gemini", "global", out, true);
const qoder = readJsonSafe(join(home, ".qoderwork", "mcp.json"));
if (qoder) collectMcpMap(qoder.mcpServers, "qoderwork", "global", out, true);
const openclaw = readJsonSafe(join(home, ".openclaw", "openclaw.json"));
if (openclaw) collectMcpMap(openclaw.mcpServers, "openclaw", "global", out, true);
@@ -553,12 +560,24 @@ function mcpWriteTarget(source: string, scope: string, home: string): McpWriteTa
mapKey: "mcpServers",
projectScoped: false,
};
if (source === "qoder")
return {
file: join(home, ".qoder", "mcp.json"),
mapKey: "mcpServers",
projectScoped: false,
};
if (source === "qoderwork")
return {
file: join(home, ".qoderwork", "mcp.json"),
mapKey: "mcpServers",
projectScoped: false,
};
if (source === "qwenwork")
return {
file: qwenworkMcpPath(home),
mapKey: "mcpServers",
projectScoped: false,
};
if (source === "openclaw")
return {
file: join(home, ".openclaw", "openclaw.json"),
@@ -10,7 +10,16 @@ import {
writeTextAtomic,
} from "../config/agent/writers/utils.ts";
export const MCP_AGENT_IDS = ["codex", "claude-code", "qwen-code", "gemini"] as const;
export const MCP_AGENT_IDS = [
"codex",
"claude-code",
"cursor",
"qoder",
"qoderwork",
"qwenwork",
"qwen-code",
"gemini",
] as const;
export type NativeMcpAgent = (typeof MCP_AGENT_IDS)[number];
export type McpTransport = "streamable-http" | "sse";
@@ -121,6 +130,54 @@ function serverMap(config: Record<string, unknown>, key: string): Record<string,
return current;
}
function qwenworkUserDataDirs(home: string): string[] {
if (process.platform === "darwin") {
const support = join(home, "Library", "Application Support");
return [join(support, "QwenWorkCN"), join(support, "QwenWork"), join(support, "QwenWork CN")];
}
if (process.platform === "win32") {
const appData = join(home, "AppData", "Roaming");
return [join(appData, "QwenWorkCN"), join(appData, "QwenWork")];
}
return [join(home, ".config", "QwenWorkCN"), join(home, ".config", "QwenWork")];
}
/** QwenWork / 千问办公 stores MCP config in Electron userData (`mcp.json`). */
export function qwenworkMcpPath(home: string): string {
const dirs = qwenworkUserDataDirs(home);
for (const dir of dirs) {
const file = join(dir, "mcp.json");
if (existsSync(file)) return file;
}
for (const dir of dirs) {
if (existsSync(dir)) return join(dir, "mcp.json");
}
return join(dirs[0], "mcp.json");
}
function jsonMcpAdapter(options: {
path: (home: string) => string;
installed: (home: string) => boolean;
typed?: boolean;
}): AgentAdapter {
return {
path: options.path,
installed: options.installed,
supports: () => true,
parse: parseJson,
serialize: (config) => `${JSON.stringify(config, null, 2)}\n`,
getServers: (config) => serverMap(config, "mcpServers"),
buildEntry: (spec) =>
options.typed
? {
type: spec.transport === "sse" ? "sse" : "http",
url: spec.endpoint,
headers: spec.headers,
}
: { url: spec.endpoint, headers: spec.headers },
};
}
const adapters: Record<NativeMcpAgent, AgentAdapter> = {
codex: {
path: (home) => join(process.env.CODEX_HOME || join(home, ".codex"), "config.toml"),
@@ -147,6 +204,26 @@ const adapters: Record<NativeMcpAgent, AgentAdapter> = {
headers: spec.headers,
}),
},
cursor: jsonMcpAdapter({
path: (home) => join(home, ".cursor", "mcp.json"),
installed: (home) =>
existsSync(join(home, ".cursor")) || existsSync(join(home, ".cursor", "mcp.json")),
}),
qoder: jsonMcpAdapter({
path: (home) => join(home, ".qoder", "mcp.json"),
installed: (home) =>
existsSync(join(home, ".qoder")) || existsSync(join(home, ".qoder", "mcp.json")),
}),
qoderwork: jsonMcpAdapter({
path: (home) => join(home, ".qoderwork", "mcp.json"),
installed: (home) =>
existsSync(join(home, ".qoderwork")) || existsSync(join(home, ".qoderwork", "mcp.json")),
}),
qwenwork: jsonMcpAdapter({
path: qwenworkMcpPath,
installed: (home) => qwenworkUserDataDirs(home).some((dir) => existsSync(dir)),
typed: true,
}),
"qwen-code": {
path: (home) => join(home, ".qwen", "settings.json"),
installed: (home) => existsSync(join(home, ".qwen")),
@@ -74,9 +74,15 @@ export default defineCommand({
"The resolved API key is written to the selected Agent's private local configuration. Existing unmanaged entries are never overwritten.",
"zh-CN": "解析出的 API Key 会写入所选 Agent 的本地私有配置;CLI 不会覆盖非其管理的同名条目。",
},
{
"en-US":
"qoder, qoderwork, and qwenwork are independent products. qwenwork is QwenWork (千问办公); qoderwork is Qoder Work.",
"zh-CN":
"qoder、qoderwork、qwenwork 是彼此独立的产品。qwenwork 是千问办公(QwenWork);qoderwork 是 Qoder Work。",
},
],
exampleArgs: [
"--server TextGenerateImage --transport streamable-http --agent codex",
"--server TextGenerateImage --transport streamable-http --agent cursor",
"--server VideoGenerate --transport sse --agent claude-code",
"--server TextGenerateImage --transport streamable-http --agent all",
],
@@ -54,7 +54,7 @@ export default defineCommand({
},
],
exampleArgs: [
"--server TextGenerateImage --agent codex",
"--server TextGenerateImage --agent cursor",
"--server TextGenerateImage --agent all",
],
async run(ctx) {
@@ -43,6 +43,10 @@ describe("e2e: mcp", () => {
const connect = await runCommandHelp(MCP_ROUTES, ["mcp", "connect", "--help"]);
expect(connect.exitCode, connect.stderr).toBe(0);
expect(connect.stderr).toMatch(/--server|--transport|streamable-http|--agent/i);
expect(connect.stderr).toMatch(/cursor/);
expect(connect.stderr).toMatch(/qoder/);
expect(connect.stderr).toMatch(/qoderwork/);
expect(connect.stderr).toMatch(/qwenwork/);
const disconnect = await runCommandHelp(MCP_ROUTES, ["mcp", "disconnect", "--help"]);
expect(disconnect.exitCode, disconnect.stderr).toBe(0);
+28 -1
View File
@@ -1,6 +1,6 @@
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, symlinkSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { join, relative } from "node:path";
import { expect, test } from "vite-plus/test";
import {
listSkills,
@@ -8,6 +8,7 @@ import {
listAgents,
getSkillDetail,
} from "../src/commands/config/inventory.ts";
import { qwenworkMcpPath } from "../src/commands/mcp/agent-config.ts";
/** Build an isolated fake $HOME and clean it up afterwards. */
function withHome(fn: (home: string) => void): void {
@@ -145,6 +146,32 @@ test("listMcpServers 无配置时返回空数组", () => {
});
});
test("listMcpServers 区分 Qoder、Qoder Work 与千问办公 QwenWork", () => {
withHome((home) => {
write(
home,
".qoder/mcp.json",
JSON.stringify({ mcpServers: { qoder: { url: "https://qoder" } } }),
);
write(
home,
".qoderwork/mcp.json",
JSON.stringify({ mcpServers: { qoderwork: { url: "https://qoderwork" } } }),
);
write(
home,
relative(home, qwenworkMcpPath(home)),
JSON.stringify({ mcpServers: { qwenwork: { type: "http", url: "https://qwenwork" } } }),
);
const servers = listMcpServers(home);
const byName = Object.fromEntries(servers.map((s) => [s.name, s]));
expect(byName.qoder).toMatchObject({ source: "qoder" });
expect(byName.qoderwork).toMatchObject({ source: "qoderwork" });
expect(byName.qwenwork).toMatchObject({ source: "qwenwork" });
});
});
test("listAgents 报告安装与已连接 bailian-cli 的状态", () => {
withHome((home) => {
// Claude Code: installed + configured (base url present).
@@ -6,6 +6,7 @@ import { afterEach, beforeEach, describe, expect, test } from "vite-plus/test";
import {
connectMcpAgents,
disconnectMcpAgents,
qwenworkMcpPath,
resolveMcpAgentTargets,
type McpConnectionSpec,
} from "../src/commands/mcp/agent-config.ts";
@@ -107,6 +108,35 @@ describe("MCP Agent registration", () => {
streamable: { httpUrl: spec().endpoint, headers: spec().headers },
sse: { url: spec("sse").endpoint, headers: spec("sse").headers },
},
{
agent: "cursor" as const,
path: [".cursor", "mcp.json"],
streamable: { url: spec().endpoint, headers: spec().headers },
sse: { url: spec("sse").endpoint, headers: spec("sse").headers },
},
{
agent: "qoder" as const,
path: [".qoder", "mcp.json"],
streamable: { url: spec().endpoint, headers: spec().headers },
sse: { url: spec("sse").endpoint, headers: spec("sse").headers },
},
{
agent: "qoderwork" as const,
path: [".qoderwork", "mcp.json"],
streamable: { url: spec().endpoint, headers: spec().headers },
sse: { url: spec("sse").endpoint, headers: spec("sse").headers },
},
{
agent: "qwenwork" as const,
path:
process.platform === "darwin"
? ["Library", "Application Support", "QwenWorkCN", "mcp.json"]
: process.platform === "win32"
? ["AppData", "Roaming", "QwenWorkCN", "mcp.json"]
: [".config", "QwenWorkCN", "mcp.json"],
streamable: { type: "http", url: spec().endpoint, headers: spec().headers },
sse: { type: "sse", url: spec("sse").endpoint, headers: spec("sse").headers },
},
])(
"$agent maps both remote transports to its native JSON format",
({ agent, path, streamable, sse }) => {
@@ -214,10 +244,83 @@ describe("MCP Agent registration", () => {
test("all targets only installed supported agents", () => {
mkdirSync(join(home, ".codex"), { recursive: true });
mkdirSync(join(home, ".gemini"), { recursive: true });
mkdirSync(join(home, ".cursor"), { recursive: true });
mkdirSync(join(home, ".qoderwork"), { recursive: true });
expect(resolveMcpAgentTargets("all", home)).toEqual(["codex", "gemini"]);
expect(resolveMcpAgentTargets("all", home)).toEqual(["codex", "cursor", "qoderwork", "gemini"]);
expect(resolveMcpAgentTargets("qwen-code", home)).toEqual(["qwen-code"]);
expect(existsSync(join(home, ".qwen"))).toBe(false);
mkdirSync(join(qwenworkMcpPath(home), ".."), { recursive: true });
expect(resolveMcpAgentTargets("all", home)).toEqual([
"codex",
"cursor",
"qoderwork",
"qwenwork",
"gemini",
]);
});
test("qoderwork writes ~/.qoderwork/mcp.json", () => {
mkdirSync(join(home, ".qoderwork"), { recursive: true });
const [result] = connectMcpAgents({
agents: ["qoderwork"],
spec: spec(),
cliVersion: "1.18.2",
home,
configDir,
});
expect(result.status).toBe("added");
expect(result.path).toBe(join(home, ".qoderwork", "mcp.json"));
expect(readJson(result.path)).toMatchObject({
mcpServers: { ImageGenerate: { url: spec().endpoint, headers: spec().headers } },
});
});
test("qwenwork writes Electron userData mcp.json and never uses Qoder Work", () => {
mkdirSync(join(home, ".qoderwork"), { recursive: true });
const [result] = connectMcpAgents({
agents: ["qwenwork"],
spec: spec(),
cliVersion: "1.18.2",
home,
configDir,
});
expect(result.status).toBe("added");
expect(result.path).toBe(qwenworkMcpPath(home));
expect(result.path).not.toContain(".qoderwork");
expect(existsSync(join(home, ".qoderwork", "mcp.json"))).toBe(false);
expect(readJson(result.path)).toMatchObject({
mcpServers: {
ImageGenerate: { type: "http", url: spec().endpoint, headers: spec().headers },
},
});
});
test("qwenwork prefers an existing QwenWork mcp.json over creating QwenWorkCN", () => {
const intlPath =
process.platform === "darwin"
? join(home, "Library", "Application Support", "QwenWork", "mcp.json")
: process.platform === "win32"
? join(home, "AppData", "Roaming", "QwenWork", "mcp.json")
: join(home, ".config", "QwenWork", "mcp.json");
mkdirSync(join(intlPath, ".."), { recursive: true });
writeFileSync(intlPath, JSON.stringify({ keep: true }));
const [result] = connectMcpAgents({
agents: ["qwenwork"],
spec: spec(),
cliVersion: "1.18.2",
home,
configDir,
});
expect(result.path).toBe(intlPath);
expect(readJson(intlPath)).toMatchObject({
keep: true,
mcpServers: {
ImageGenerate: { type: "http", url: spec().endpoint, headers: spec().headers },
},
});
});
test("disconnecting an unmanaged absent server does not create a manifest", () => {
+26 -26
View File
@@ -58,32 +58,32 @@ Do not guess flags — use the reference files or `--help`.
Use this table only after the decision table in [`bailian-protocol`](../bailian-protocol/SKILL.md#provider-selection-and-consent) has routed the request to `bl` (class 4, or class 2 after the user picks Bailian). Hub-owned intents only — for media / fine-tune / agents.yaml / Sandbox, soft hand-off to the domain skill.
| User intent | Command | Notes |
| ------------------------------------------------ | --------------------------------------------- | -------------------------------------------------------------------------- |
| Explicit Bailian model chat / text execution | `bl text chat` | Default `qwen3.8-max` |
| Bailian agent / workflow | `bl app call` | Needs `--app-id` |
| Find app by name | `bl app list` then `bl app call` | Console auth |
| Bailian app memory CRUD (not host-agent memory) | `bl memory *` | [`reference/memory.md`](reference/memory.md) |
| Bailian knowledge base RAG | `bl knowledge search` / `chat` | API key + agent/workspace IDs |
| Upload a file as a step of a Bailian workflow | `bl file upload` | When you need `oss://` URL explicitly; not for generic hosting |
| Bailian model selection / recommendation | `bl advisor recommend` | Intent → candidate recall → LLM ranking |
| Bailian model catalog / pricing / params | `bl model list` | Console auth; `--model <family>` for detail, `--enrich` for input params |
| Install / list / update / remove registry skills | `bl skill add` / `list` / `update` / `remove` | Bailian skill registry; see [`reference/skill.md`](reference/skill.md) |
| Bailian MCP marketplace discovery / call | `bl mcp list` / `tools` / `call` | — |
| Register or remove a Bailian MCP in an Agent | `bl mcp connect` / `disconnect` | Codex, Claude Code, Qwen Code, and Gemini CLI |
| Bailian pipeline workflow (a step in a bl flow) | `bl pipeline run` / `validate` | JSON/YAML workflow definitions |
| Bailian rate limits / quota | `bl quota list` / `check` / `request` | Console auth; class 2 — ask which product first if unnamed |
| Bailian free tier / usage stats | `bl usage free` / `stats` / `freetier` | Console auth; class 2 — ask which product first if unnamed |
| Bailian Token Plan quota usage | `bl usage token-plan` | Console auth; class 2 — ask which product first if unnamed |
| Bailian Coding Plan quota usage | `bl usage coding-plan` | Console auth; class 2 — ask which product first if unnamed |
| Console API (advanced) | `bl console call` | Console auth |
| Bailian workspace listing | `bl workspace list` | Console auth |
| Switch CLI Help / Quick Start language | `bl config set --key language --value zh-CN` | Use `en-US` to switch back; follows the active config profile |
| Image / video / speech / omni / vision | → skill `bailian-gen` | Fallback: `bl image\|video\|speech\|omni\|vision --help` |
| Dataset / fine-tune / deploy | → skill `bailian-finetune` | Fallback: `bl dataset\|finetune\|deploy --help` |
| agents.yaml IaC / managed-agent sessions | → skill `bailian-managed-agent` | Fallback: `bl managed-agent --help`; `apply`/`destroy` also require `plan` |
| Bailian Sandbox instance / template lifecycle | → skill `bailian-sandbox` | Fallback: `bl sandbox --help` |
| Web search (model-aware routing) | → skill `bailian-web-search` | Token Plan vs MCP path + fallback; fallback: `bl search web --help` |
| User intent | Command | Notes |
| ------------------------------------------------ | --------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Explicit Bailian model chat / text execution | `bl text chat` | Default `qwen3.8-max` |
| Bailian agent / workflow | `bl app call` | Needs `--app-id` |
| Find app by name | `bl app list` then `bl app call` | Console auth |
| Bailian app memory CRUD (not host-agent memory) | `bl memory *` | [`reference/memory.md`](reference/memory.md) |
| Bailian knowledge base RAG | `bl knowledge search` / `chat` | API key + agent/workspace IDs |
| Upload a file as a step of a Bailian workflow | `bl file upload` | When you need `oss://` URL explicitly; not for generic hosting |
| Bailian model selection / recommendation | `bl advisor recommend` | Intent → candidate recall → LLM ranking |
| Bailian model catalog / pricing / params | `bl model list` | Console auth; `--model <family>` for detail, `--enrich` for input params |
| Install / list / update / remove registry skills | `bl skill add` / `list` / `update` / `remove` | Bailian skill registry; see [`reference/skill.md`](reference/skill.md) |
| Bailian MCP marketplace discovery / call | `bl mcp list` / `tools` / `call` | — |
| Register or remove a Bailian MCP in an Agent | `bl mcp connect` / `disconnect` | Codex, Claude Code, Cursor, Qoder, Qoder Work, QwenWork (千问办公), Qwen Code, Gemini CLI |
| Bailian pipeline workflow (a step in a bl flow) | `bl pipeline run` / `validate` | JSON/YAML workflow definitions |
| Bailian rate limits / quota | `bl quota list` / `check` / `request` | Console auth; class 2 — ask which product first if unnamed |
| Bailian free tier / usage stats | `bl usage free` / `stats` / `freetier` | Console auth; class 2 — ask which product first if unnamed |
| Bailian Token Plan quota usage | `bl usage token-plan` | Console auth; class 2 — ask which product first if unnamed |
| Bailian Coding Plan quota usage | `bl usage coding-plan` | Console auth; class 2 — ask which product first if unnamed |
| Console API (advanced) | `bl console call` | Console auth |
| Bailian workspace listing | `bl workspace list` | Console auth |
| Switch CLI Help / Quick Start language | `bl config set --key language --value zh-CN` | Use `en-US` to switch back; follows the active config profile |
| Image / video / speech / omni / vision | → skill `bailian-gen` | Fallback: `bl image\|video\|speech\|omni\|vision --help` |
| Dataset / fine-tune / deploy | → skill `bailian-finetune` | Fallback: `bl dataset\|finetune\|deploy --help` |
| agents.yaml IaC / managed-agent sessions | → skill `bailian-managed-agent` | Fallback: `bl managed-agent --help`; `apply`/`destroy` also require `plan` |
| Bailian Sandbox instance / template lifecycle | → skill `bailian-sandbox` | Fallback: `bl sandbox --help` |
| Web search (model-aware routing) | → skill `bailian-web-search` | Token Plan vs MCP path + fallback; fallback: `bl search web --help` |
Flags, usage, and examples: see hub [`reference/`](reference/index.md) or `bl <command> --help` — do not guess flags. Domain command details live in the owning skill's `reference/`.
+14 -13
View File
@@ -63,23 +63,24 @@ bl mcp call --target market-cmapi00073529.SmartFundSelection --arg riskLevel=R3
#### Flags
| Flag | Type | Required | Description |
| ------------------------------------------------------ | ------ | -------- | ----------------------------------------------------------- |
| `--server <code>` | string | yes | Bailian MCP Server Code, such as TextGenerateImage |
| `--transport <streamable-http\|sse>` | string | yes | MCP transport exposed by the server: streamable-http or sse |
| `--agent <codex\|claude-code\|qwen-code\|gemini\|all>` | string | yes | Target Agent: codex, claude-code, qwen-code, gemini, all |
| `--api-key <key>` | string | no | API key |
| `--base-url <url>` | string | no | API base URL |
| Flag | Type | Required | Description |
| ------------------------------------------------------------------------------------------ | ------ | -------- | -------------------------------------------------------------------------------------------- |
| `--server <code>` | string | yes | Bailian MCP Server Code, such as TextGenerateImage |
| `--transport <streamable-http\|sse>` | string | yes | MCP transport exposed by the server: streamable-http or sse |
| `--agent <codex\|claude-code\|cursor\|qoder\|qoderwork\|qwenwork\|qwen-code\|gemini\|all>` | string | yes | Target Agent: codex, claude-code, cursor, qoder, qoderwork, qwenwork, qwen-code, gemini, all |
| `--api-key <key>` | string | no | API key |
| `--base-url <url>` | string | no | API base URL |
#### Notes
- This release registers the official China-site MCP endpoint; the model API --base-url does not change the MCP endpoint.
- The resolved API key is written to the selected Agent's private local configuration. Existing unmanaged entries are never overwritten.
- qoder, qoderwork, and qwenwork are independent products. qwenwork is QwenWork (千问办公); qoderwork is Qoder Work.
#### Examples
```bash
bl mcp connect --server TextGenerateImage --transport streamable-http --agent codex
bl mcp connect --server TextGenerateImage --transport streamable-http --agent cursor
```
```bash
@@ -101,10 +102,10 @@ bl mcp connect --server TextGenerateImage --transport streamable-http --agent al
#### Flags
| Flag | Type | Required | Description |
| ------------------------------------------------------ | ------ | -------- | -------------------------------------------------------- |
| `--server <code>` | string | yes | Bailian MCP Server Code used during connect |
| `--agent <codex\|claude-code\|qwen-code\|gemini\|all>` | string | yes | Target Agent: codex, claude-code, qwen-code, gemini, all |
| Flag | Type | Required | Description |
| ------------------------------------------------------------------------------------------ | ------ | -------- | -------------------------------------------------------------------------------------------- |
| `--server <code>` | string | yes | Bailian MCP Server Code used during connect |
| `--agent <codex\|claude-code\|cursor\|qoder\|qoderwork\|qwenwork\|qwen-code\|gemini\|all>` | string | yes | Target Agent: codex, claude-code, cursor, qoder, qoderwork, qwenwork, qwen-code, gemini, all |
#### Notes
@@ -113,7 +114,7 @@ bl mcp connect --server TextGenerateImage --transport streamable-http --agent al
#### Examples
```bash
bl mcp disconnect --server TextGenerateImage --agent codex
bl mcp disconnect --server TextGenerateImage --agent cursor
```
```bash