mirror of
https://github.com/modelstudioai/cli.git
synced 2026-09-14 19:49:23 +08:00
feat(mcp): add Cursor, Qoder, Qoder Work, and QwenWork native MCP targets
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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/`.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user