huaweicloud-devkit 1.0.2-next.13 → 1.0.2-next.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  Help AI coding agents use Huawei Cloud safely and accurately — a single integration that gives agents cloud knowledge, CLI tooling, and safety guardrails.
10
10
 
11
- Supports OpenCode, Codex, CodeArts Agent, WorkBuddy, DeepSeek Harness (DSH), and OfficeAce.
11
+ Supports OpenCode, CodeArts Agent, WorkBuddy, DeepSeek Harness (DSH), and OfficeAce.
12
12
 
13
13
  ## Prerequisites
14
14
 
@@ -33,23 +33,6 @@ npx --yes huaweicloud-devkit update --target opencode
33
33
  npx --yes huaweicloud-devkit uninstall --target opencode
34
34
  ```
35
35
 
36
- ### Codex
37
-
38
- ```bash
39
- npx --yes huaweicloud-devkit install --target codex
40
- ```
41
-
42
- > The Codex CLI must be installed first.
43
-
44
- ```bash
45
- npx --yes huaweicloud-devkit doctor --target codex
46
- npx --yes huaweicloud-devkit status --target codex
47
- npx --yes huaweicloud-devkit update --target codex
48
- npx --yes huaweicloud-devkit uninstall --target codex
49
- ```
50
-
51
- > **Codex Desktop** (Windows): use `--target codex-desktop` with the same commands.
52
-
53
36
  ### CodeArts Agent
54
37
 
55
38
  ```bash
@@ -65,7 +48,7 @@ npx --yes huaweicloud-devkit update --target codearts
65
48
  npx --yes huaweicloud-devkit uninstall --target codearts
66
49
  ```
67
50
 
68
- > **Sandbox mode**: CodeArts defaults to sandbox mode which blocks KooCLI. `install-hcloud` detects this and shows how to resolve it — install KooCLI outside the sandbox terminal, or disable sandbox mode in CodeArts settings (Settings → PermissionsBash mode).
51
+ > **Sandbox mode**: CodeArts defaults to sandbox mode which blocks KooCLI. `install-hcloud` detects this and shows how to resolve it — install KooCLI outside the sandbox terminal, or disable sandbox mode in CodeArts settings (Settings → ChatsAgents Terminal Command Running Mode → Auto Running).
69
52
 
70
53
  ### WorkBuddy
71
54
 
@@ -116,26 +99,22 @@ npx --yes huaweicloud-devkit uninstall --target officeace
116
99
 
117
100
  ### Other Agents
118
101
 
119
- For agents that support the Model Context Protocol (MCP), add the MCP server manually:
102
+ Any agent that supports MCP can use the standard config:
120
103
 
121
104
  ```json
122
105
  {
123
106
  "mcpServers": {
124
107
  "huaweicloud-devkit": {
125
- "command": "node",
126
- "args": ["<path>/plugins/huaweicloud-core/src/mcp-server.mjs"]
108
+ "command": "npx",
109
+ "args": ["-y", "-p", "huaweicloud-devkit@next", "huaweicloud-devkit-mcp"]
127
110
  }
128
111
  }
129
112
  }
130
113
  ```
131
114
 
132
- Then install the skills:
133
-
134
- ```bash
135
- npx --yes huaweicloud-devkit install
136
- ```
115
+ No installation required — `npx` handles everything.
137
116
 
138
- > For unified credentials across KooCLI and OBS, run `npx huaweicloud-devkit auth init`.
117
+ > Set `HW_ACCESS_KEY`/`HW_SECRET_KEY` in the MCP config `env` field for project-level credentials.
139
118
 
140
119
  ### Install KooCLI
141
120
 
@@ -171,6 +150,7 @@ npx --yes huaweicloud-devkit update --target all
171
150
  - **Safety-first execution** — all write operations require explicit user approval; credentials and secrets are automatically redacted from output
172
151
  - **Pre-execution risk checks** — public exposure, credential leaks, and destructive operations are caught before they run
173
152
  - **Regional awareness** — auto-discovers available regions and checks service availability before creating resources
153
+ - **Sandbox (DevStation)** — temporary cloud runtime for web app deployment with instant public URL preview
174
154
 
175
155
  ## Supported Services
176
156
 
package/README.zh-CN.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  帮助 AI 编码助手安全、准确地使用华为云——一站式集成云知识、CLI 工具和安全护栏。
10
10
 
11
- 支持 OpenCode、Codex、码道(CodeArts Agent)、WorkBuddy、DeepSeek Harness(DSH)、OfficeAce。
11
+ 支持 OpenCode、码道(CodeArts Agent)、WorkBuddy、DeepSeek Harness(DSH)、OfficeAce。
12
12
 
13
13
  ## 前置条件
14
14
 
@@ -33,23 +33,6 @@ npx --yes huaweicloud-devkit update --target opencode
33
33
  npx --yes huaweicloud-devkit uninstall --target opencode
34
34
  ```
35
35
 
36
- ### Codex
37
-
38
- ```bash
39
- npx --yes huaweicloud-devkit install --target codex
40
- ```
41
-
42
- > 需要先安装 Codex CLI。
43
-
44
- ```bash
45
- npx --yes huaweicloud-devkit doctor --target codex
46
- npx --yes huaweicloud-devkit status --target codex
47
- npx --yes huaweicloud-devkit update --target codex
48
- npx --yes huaweicloud-devkit uninstall --target codex
49
- ```
50
-
51
- > **Codex Desktop**(Windows):将 `--target codex` 换成 `--target codex-desktop`,命令相同。
52
-
53
36
  ### CodeArts Agent(码道)
54
37
 
55
38
  ```bash
@@ -65,7 +48,7 @@ npx --yes huaweicloud-devkit update --target codearts
65
48
  npx --yes huaweicloud-devkit uninstall --target codearts
66
49
  ```
67
50
 
68
- > **沙箱模式**:码道默认沙箱模式会阻止 KooCLI 运行。`install-hcloud` 自动检测并给出指引——请在码道外终端安装使用 KooCLI,或在码道设置中关闭沙箱模式(设置 → 权限Bash 模式)。
51
+ > **沙箱模式**:码道默认沙箱模式会阻止 KooCLI 运行。`install-hcloud` 自动检测并给出指引——请在码道外终端安装使用 KooCLI,或在码道设置中关闭沙箱模式(设置 → 对话流智能体 终端命令运行模式 → 自动运行)。
69
52
 
70
53
  ### WorkBuddy
71
54
 
@@ -116,26 +99,22 @@ npx --yes huaweicloud-devkit uninstall --target officeace
116
99
 
117
100
  ### 其他 Agent
118
101
 
119
- 支持 MCP 协议的 Agent,手动添加 MCP Server 配置:
102
+ 任何支持 MCP 协议的 Agent,直接使用标准 MCP 配置:
120
103
 
121
104
  ```json
122
105
  {
123
106
  "mcpServers": {
124
107
  "huaweicloud-devkit": {
125
- "command": "node",
126
- "args": ["<路径>/plugins/huaweicloud-core/src/mcp-server.mjs"]
108
+ "command": "npx",
109
+ "args": ["-y", "-p", "huaweicloud-devkit@next", "huaweicloud-devkit-mcp"]
127
110
  }
128
111
  }
129
112
  }
130
113
  ```
131
114
 
132
- 然后安装 skills:
133
-
134
- ```bash
135
- npx --yes huaweicloud-devkit install
136
- ```
115
+ 无需预安装 — `npx` 自动处理一切。
137
116
 
138
- > 执行 `npx huaweicloud-devkit auth init` 完成 KooCLI、OBS 的统一认证。
117
+ > 项目级 AK/SK 可通过 MCP 配置的 `env` 字段设置 `HW_ACCESS_KEY`/`HW_SECRET_KEY`。
139
118
 
140
119
  ### 安装 KooCLI
141
120
 
@@ -171,6 +150,7 @@ npx --yes huaweicloud-devkit update --target all
171
150
  - **安全优先执行** — 所有写操作需用户明确批准;凭证和密钥自动脱敏
172
151
  - **执行前风险检查** — 公网暴露、凭证泄露、破坏性操作在执行前即被拦截
173
152
  - **区域感知** — 自动发现可用区域,创建资源前检查服务可用性
153
+ - **沙箱(DevStation)** — 临时云端运行环境,部署 Web 应用并即刻获得公网预览地址
174
154
 
175
155
  ## 支持的服务
176
156
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huaweicloud-devkit",
3
- "version": "1.0.2-next.13",
3
+ "version": "1.0.2-next.17",
4
4
  "description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
5
5
  "type": "module",
6
6
  "files": [
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "https://github.com/huaweicloud/HuaweiCloud-Devkit.git"
18
+ "url": "https://github.com/huaweicloud/huaweicloud-devkit.git"
19
19
  },
20
20
  "scripts": {
21
21
  "test": "node --test",
@@ -17,7 +17,7 @@
17
17
  "mcpServers": "./.mcp.json",
18
18
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
19
19
  "skills": "./skills/",
20
- "version": "1.0.2-next.13",
20
+ "version": "1.0.2-next.17",
21
21
  "author": {
22
22
  "name": "HuaweiCloud Mate",
23
23
  "url": "https://github.com/huaweicloud"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huaweicloud-core",
3
- "version": "1.0.2-next.13",
3
+ "version": "1.0.2-next.17",
4
4
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
5
5
  "author": {
6
6
  "name": "HuaweiCloud Mate",
@@ -17,7 +17,7 @@
17
17
  "mcpServers": "./.mcp.json",
18
18
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
19
19
  "skills": "./skills/",
20
- "version": "1.0.2-next.13",
20
+ "version": "1.0.2-next.17",
21
21
  "author": {
22
22
  "name": "HuaweiCloud Mate",
23
23
  "url": "https://github.com/huaweicloud"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huaweicloud-core",
3
- "version": "1.0.2-next.13",
3
+ "version": "1.0.2-next.17",
4
4
  "description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
5
5
  "author": {
6
6
  "name": "HuaweiCloud Mate",
@@ -18,15 +18,38 @@ from pathlib import Path
18
18
 
19
19
  DENY_PREFIX = "Huawei Cloud safety hook blocked this action: "
20
20
  RULES_PATH = Path(__file__).resolve().parents[1] / "safety" / "rules" / "cloud-risk-rules.json"
21
+ POLICY_PATH = Path(__file__).resolve().parents[1] / "safety" / "policy.json"
21
22
 
22
- CONFIG_FILE_RE = re.compile(r"(\.hcloud|\.huaweicloud|hcloud[/\\](config|credentials)|huaweicloud[/\\](config|credentials))", re.I)
23
- ENV_DUMP_RE = re.compile(r"(env|printenv|Get-ChildItem\s+Env:|gci\s+Env:|dir\s+Env:).*(HUAWEICLOUD|HWC_|HCLOUD|OS_)", re.I)
24
- SECRET_READ_RE = re.compile(r"(ShowSecretVersion|GetSecretValue|secret_string|secret_binary)", re.I)
25
- HCLOUD_RE = re.compile(r"(^|\s)hcloud(\.exe)?\s+", re.I)
26
- WRITE_OPERATION_RE = re.compile(
27
- r"\b(BatchCreate|BatchDelete|Create|Delete|Update|Modify|Resize|Reboot|Stop|Start|Restart|Authorize|Revoke|Add|Remove|Associate|Disassociate|Attach|Detach|Enable|Disable)\w*",
28
- re.I,
23
+ CONFIG_FILE_RE = None
24
+ SECRET_READ_RE = None
25
+ WRITE_OPERATION_RE = None
26
+
27
+
28
+ def load_policy():
29
+ global CONFIG_FILE_RE, SECRET_READ_RE, WRITE_OPERATION_RE
30
+ try:
31
+ with POLICY_PATH.open("r", encoding="utf-8") as file_obj:
32
+ policy = json.load(file_obj)
33
+ cred_patterns = policy.get("credentialFilePatterns", [])
34
+ if cred_patterns:
35
+ CONFIG_FILE_RE = re.compile("|".join(cred_patterns), re.I)
36
+ blocked_secrets = policy.get("blockedSecretOperations", [])
37
+ if blocked_secrets:
38
+ SECRET_READ_RE = re.compile("|".join(re.escape(op) for op in blocked_secrets), re.I)
39
+ write_prefixes = policy.get("writeOperationPrefixes", [])
40
+ if write_prefixes:
41
+ WRITE_OPERATION_RE = re.compile(r"\b(" + "|".join(write_prefixes) + r")\w*", re.I)
42
+ except Exception:
43
+ pass
44
+
45
+
46
+ load_policy()
47
+
48
+ ENV_DUMP_RE = re.compile(
49
+ r"(env|printenv|Get-ChildItem\s+Env:|gci\s+Env:|dir\s+Env:).*(HUAWEICLOUD|HWC_|HCLOUD|OS_)", re.I,
29
50
  )
51
+ HCLOUD_RE = re.compile(r"(^|\s)hcloud(\.exe)?\s+", re.I)
52
+ READ_OPERATION_RE = re.compile(r"\b(List|Show|Get|Describe|NovaList|NovaShow)\w*", re.I)
30
53
  READ_OPERATION_RE = re.compile(r"\b(List|Show|Get|Describe|NovaList|NovaShow)\w*", re.I)
31
54
 
32
55
 
@@ -117,11 +140,11 @@ def main():
117
140
  tool_name = data.get("tool_name", "")
118
141
  text = command_text(data.get("tool_input", {}))
119
142
 
120
- if CONFIG_FILE_RE.search(text):
143
+ if CONFIG_FILE_RE and CONFIG_FILE_RE.search(text):
121
144
  deny("reading Huawei Cloud credential/profile files can expose AK/SK or tokens. Use redacted toolkit tools.")
122
145
  if ENV_DUMP_RE.search(text):
123
146
  deny("dumping cloud credential environment variables is not allowed.")
124
- if SECRET_READ_RE.search(text):
147
+ if SECRET_READ_RE and SECRET_READ_RE.search(text):
125
148
  deny("direct secret value retrieval would put plaintext secrets into the agent context.")
126
149
  denied_rule = first_denied_command_rule(text)
127
150
  if denied_rule:
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "huaweicloud-devkit",
3
+ "displayName": "HuaweiCloud DevKit",
4
+ "version": "1.0.2-next.16",
5
+ "family": "bundle-plugin",
6
+ "bundleFormat": "codex",
7
+ "description": "Guide coding agents to use Huawei Cloud safely — KooCLI, APIs, SDKs, 28 MCP tools, skills, and safety guardrails.",
8
+ "author": {
9
+ "name": "HuaweiCloud Mate",
10
+ "url": "https://github.com/huaweicloud"
11
+ },
12
+ "homepage": "https://github.com/huaweicloud/huaweicloud-devkit",
13
+ "repository": "https://github.com/huaweicloud/huaweicloud-devkit",
14
+ "license": "Apache-2.0",
15
+ "keywords": ["huaweicloud", "huawei-cloud", "koocli", "hcloud", "agent", "mcp", "api", "sdk", "skills", "cloud"],
16
+ "category": "Cloud",
17
+ "capabilities": ["Read", "Interactive"],
18
+ "brandColor": "#C7000B"
19
+ }
@@ -121,8 +121,24 @@ hcloud <Service> <ListOp> --cli-output=json --cli-query "items[?status=='ACTIVE'
121
121
  hcloud <Service> <Op> --cli-debug=true
122
122
  ```
123
123
 
124
+ ## Credential Resolution Priority
125
+
126
+ Credentials are resolved in this order (highest priority first):
127
+
128
+ | Priority | Source | Mechanism | Persistence |
129
+ | -------- | ----------------------- | ---------------------------------------------------------- | ------------------------------- |
130
+ | 1 | Runtime credentials | `huaweicloud_auth_init` tool | Memory (cleared on MCP restart) |
131
+ | 2 | Environment variables | `HW_ACCESS_KEY` / `HW_SECRET_KEY` | MCP process lifetime |
132
+ | 3 | CodeArts project config | `.codeartsdoer/mcp/mcp_settings.json` (project, then user) | File |
133
+ | 4 | Global config file | `~/.config/huaweicloud/credentials.json` | Permanent |
134
+ | 5 | KooCLI profile | `~/.hcloud/config.json` (KooCLI only) | Permanent |
135
+
136
+ When switching accounts within the same Agent session, use `huaweicloud_auth_init` to set runtime credentials. This overrides all other sources for the current MCP process.
137
+
124
138
  ## Preferred Toolkit Tools
125
139
 
140
+ - `huaweicloud_auth_init`
141
+ - `huaweicloud_auth_status`
126
142
  - `huaweicloud_check_cli`
127
143
  - `huaweicloud_show_profile_redacted`
128
144
  - `huaweicloud_plan_cli_command`
@@ -100,6 +100,7 @@ When the intent is to **deploy, host, or preview a web app or static website** (
100
100
 
101
101
  - Use huaweicloud_search_docs to discover skills covering a topic
102
102
  - Use huaweicloud_retrieve_skill to load a full SKILL.md after routing
103
+ - Use huaweicloud_auth_init to switch credentials at runtime when different accounts co-exist in the same session
103
104
  - If no built-in skill matches, consult huaweicloud-capability-discovery for external marketplace options
104
105
  - Use huaweicloud_list_regions before creating regional resources
105
106
  - Use huaweicloud_get_regional_availability when unsure about service-region pairs
@@ -123,13 +123,16 @@ function officeaceRegistered() {
123
123
  let hasMcp = false;
124
124
  const dbPath = officeaceSqlitePath();
125
125
  if (existsSync(dbPath)) {
126
- try {
127
- const { DatabaseSync } = createRequire(import.meta.url)('node:sqlite');
128
- const db = new DatabaseSync(dbPath, { readonly: true });
129
- const row = db.prepare("SELECT enabled FROM mcp_connectors WHERE name = 'huaweicloud-devkit'").get();
130
- db.close();
131
- hasMcp = Boolean(row?.enabled);
132
- } catch {}
126
+ const nodeMajor = Number(process.versions.node.split('.')[0]);
127
+ if (nodeMajor >= 22) {
128
+ try {
129
+ const { DatabaseSync } = createRequire(import.meta.url)('node:sqlite');
130
+ const db = new DatabaseSync(dbPath, { readonly: true });
131
+ const row = db.prepare("SELECT enabled FROM mcp_connectors WHERE name = 'huaweicloud-devkit'").get();
132
+ db.close();
133
+ hasMcp = Boolean(row?.enabled);
134
+ } catch {}
135
+ }
133
136
  }
134
137
 
135
138
  const capFile = join(officeaceCapabilitiesDir(), 'capabilities.json');
@@ -84,6 +84,13 @@ export function resolveCredentials(options = {}) {
84
84
  let securityToken = process.env.HW_SECURITY_TOKEN;
85
85
  let region = process.env.HW_REGION || process.env.HUAWEICLOUD_REGION || '';
86
86
 
87
+ const codeartsCreds = isCodeArtsContext() ? readCodeArtsCredentials() : null;
88
+ if (codeartsCreds) {
89
+ if (!ak && codeartsCreds.ak) ak = codeartsCreds.ak;
90
+ if (!sk && codeartsCreds.sk) sk = codeartsCreds.sk;
91
+ if (!region && codeartsCreds.region) region = codeartsCreds.region;
92
+ }
93
+
87
94
  const stored = readGlobalCredentials();
88
95
  if (stored) {
89
96
  if (!ak && stored.ak) ak = stored.ak;
@@ -101,3 +108,61 @@ export function resolveCredentials(options = {}) {
101
108
 
102
109
  return { ak, sk, securityToken, region };
103
110
  }
111
+
112
+ function isCodeArtsContext() {
113
+ return existsSync(join(process.cwd(), '.codeartsdoer')) || existsSync(join(homedir(), '.codeartsdoer'));
114
+ }
115
+
116
+ function readCodeArtsCredentials() {
117
+ const searchPaths = [
118
+ join(process.cwd(), '.codeartsdoer', 'mcp', 'mcp_settings.json'),
119
+ join(homedir(), '.codeartsdoer', 'mcp', 'mcp_settings.json'),
120
+ ];
121
+
122
+ for (const path of searchPaths) {
123
+ try {
124
+ if (!existsSync(path)) continue;
125
+ const config = JSON.parse(readFileSync(path, 'utf8'));
126
+ const server = config?.mcpServers?.['huaweicloud-devkit'];
127
+ if (!server?.env) continue;
128
+
129
+ const ak = server.env.HW_ACCESS_KEY;
130
+ const sk = server.env.HW_SECRET_KEY;
131
+ if (ak && sk) {
132
+ return {
133
+ ak,
134
+ sk,
135
+ securityToken: server.env.HW_SECURITY_TOKEN || '',
136
+ region: server.env.HW_REGION || server.env.HUAWEICLOUD_REGION || '',
137
+ };
138
+ }
139
+ } catch {
140
+ // mcp_settings.json missing or invalid — skip
141
+ }
142
+ }
143
+
144
+ return null;
145
+ }
146
+
147
+ let runtimeCredentials = null;
148
+
149
+ export function setRuntimeCredentials(ak, sk, securityToken, region) {
150
+ runtimeCredentials = { ak, sk, securityToken: securityToken || '', region: region || '' };
151
+ }
152
+
153
+ export function clearRuntimeCredentials() {
154
+ runtimeCredentials = null;
155
+ }
156
+
157
+ export function resolveCredentialsWithRuntime(options = {}) {
158
+ if (runtimeCredentials) {
159
+ return {
160
+ ak: runtimeCredentials.ak,
161
+ sk: runtimeCredentials.sk,
162
+ securityToken: runtimeCredentials.securityToken,
163
+ region: runtimeCredentials.region,
164
+ };
165
+ }
166
+
167
+ return resolveCredentials(options);
168
+ }
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env node
2
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
3
2
  import { stdin, stdout } from 'node:process';
4
- import { rmSync, existsSync } from 'node:fs';
5
- import { resolve, dirname } from 'node:path';
3
+ import { rmSync, existsSync, readFileSync } from 'node:fs';
4
+ import { resolve, dirname, join } from 'node:path';
6
5
  import { fileURLToPath } from 'node:url';
7
6
  import { TOOL_DEFINITIONS, callTool } from './tools.mjs';
8
7
 
@@ -27,6 +26,14 @@ try {
27
26
  if (existsSync(marker)) rmSync(marker, { force: true });
28
27
  } catch {}
29
28
 
29
+ const __dirname = dirname(fileURLToPath(import.meta.url));
30
+ const pluginRoot = resolve(__dirname, '..');
31
+ const packageRoot = resolve(pluginRoot, '..', '..');
32
+ let pkgVersion = '0.0.0';
33
+ try {
34
+ pkgVersion = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8')).version;
35
+ } catch {}
36
+
30
37
  let buffer = Buffer.alloc(0);
31
38
  let useContentLengthFraming = true;
32
39
 
@@ -104,7 +111,7 @@ async function dispatch(method, params) {
104
111
  },
105
112
  serverInfo: {
106
113
  name: 'huaweicloud-devkit',
107
- version: '0.1.0',
114
+ version: pkgVersion,
108
115
  },
109
116
  };
110
117
  }
@@ -1,5 +1,5 @@
1
1
  import crypto from 'node:crypto';
2
- import { resolveCredentials } from '../auth/credentials.mjs';
2
+ import { resolveCredentialsWithRuntime } from '../auth/credentials.mjs';
3
3
  import { getProxyDispatcher } from '../proxy/proxy-agent.mjs';
4
4
 
5
5
  const BASE_URL = process.env.HWLINK_ENDPOINT || 'https://devstation.myhuaweicloud.com';
@@ -77,7 +77,7 @@ function signRequest(method, path, query, body, ak, sk, securitytoken) {
77
77
  }
78
78
 
79
79
  export function getCredentials() {
80
- const credentials = resolveCredentials();
80
+ const credentials = resolveCredentialsWithRuntime();
81
81
  return { ak: credentials.ak, sk: credentials.sk, securitytoken: credentials.securityToken };
82
82
  }
83
83
 
@@ -377,7 +377,7 @@ function printSandboxWarning(reason) {
377
377
  console.log(`\x1b[31m 请任选其一继续:\x1b[0m`);
378
378
  console.log(`\x1b[31m A. 在码道外的终端安装并使用 KooCLI (推荐):`);
379
379
  console.log(`\x1b[31m https://support.huaweicloud.com/qs-hcli/hcli_02_003.html`);
380
- console.log(`\x1b[31m B. 在码道设置中关闭沙箱模式后重试 (设置 → 权限Bash 模式)`);
380
+ console.log(`\x1b[31m B. 在码道设置中关闭沙箱模式后重试 (设置 → 对话流智能体 终端命令运行模式 → 自动运行)`);
381
381
  console.log(`\x1b[31m 关闭沙箱后重新运行: npx huaweicloud-devkit install-hcloud\x1b[0m`);
382
382
  }
383
383
 
@@ -16,7 +16,12 @@ import {
16
16
  } from './sandbox/session-manager.mjs';
17
17
  import { hdkitCheckUser, hdkitSignAgreement, hdkitConnect, hdkitCredentials } from './sandbox/hdkitservice-api.mjs';
18
18
  import { getAuthStatus, syncAuth } from './auth/service.mjs';
19
- import { readGlobalCredentials, writeObsConfig as writeObsConfigFile } from './auth/credentials.mjs';
19
+ import {
20
+ readGlobalCredentials,
21
+ writeObsConfig as writeObsConfigFile,
22
+ setRuntimeCredentials,
23
+ clearRuntimeCredentials,
24
+ } from './auth/credentials.mjs';
20
25
 
21
26
  const __dirname = dirname(fileURLToPath(import.meta.url));
22
27
  const SKILLS_ROOT_DEV = join(__dirname, '..', 'skills');
@@ -404,6 +409,20 @@ export const TOOL_DEFINITIONS = [
404
409
  },
405
410
  },
406
411
  },
412
+ {
413
+ name: 'huaweicloud_auth_init',
414
+ description:
415
+ 'Set or clear runtime Huawei Cloud credentials (AK/SK) for this MCP session. Runtime credentials take highest priority over environment variables and config files for all subsequent API calls. Use when switching accounts within the same Agent session — call with AK/SK to switch, or with clear=true to fall back to env/file credentials.',
416
+ inputSchema: {
417
+ type: 'object',
418
+ properties: {
419
+ ak: { type: 'string', description: 'Huawei Cloud Access Key (required unless clear=true)' },
420
+ sk: { type: 'string', description: 'Huawei Cloud Secret Key (required unless clear=true)' },
421
+ region: { type: 'string', description: 'Default region (optional)' },
422
+ clear: { type: 'boolean', description: 'Set to true to clear runtime credentials and revert to env/file' },
423
+ },
424
+ },
425
+ },
407
426
  {
408
427
  name: 'huaweicloud_sandbox_exec_with_session',
409
428
  description:
@@ -570,6 +589,16 @@ export async function callTool(name, args = {}) {
570
589
  return getAuthStatus(args.target || 'all');
571
590
  case 'huaweicloud_auth_sync':
572
591
  return syncAuth(args.target || 'all');
592
+ case 'huaweicloud_auth_init':
593
+ if (args.clear) {
594
+ clearRuntimeCredentials();
595
+ return { status: 'cleared', message: 'Runtime credentials cleared. Fallback to env/file.' };
596
+ }
597
+ if (!args.ak || !args.sk) {
598
+ throw new Error('ak and sk are required. Set clear=true to clear runtime credentials.');
599
+ }
600
+ setRuntimeCredentials(args.ak, args.sk, undefined, args.region);
601
+ return { status: 'ok', message: 'Runtime credentials set for this MCP session.' };
573
602
  case 'huaweicloud_sandbox_exec_with_session': {
574
603
  const sandboxWsId2 = args.workspace_id || DEFAULT_WORKSPACE_ID;
575
604
  const sandboxUser2 = args.username || 'root';
@@ -796,7 +825,7 @@ async function setupObsConfigFromHcloud(profile) {
796
825
  const SERVICE_EXAMPLES = {
797
826
  ECS: { list: 'ECS ListServersDetails', create: 'ECS CreateServers', show: 'IMS GlanceShowImage' },
798
827
  VPC: { list: 'VPC ListVpcs', create: 'VPC CreateVpc', show: 'VPC ShowVpc' },
799
- FunctionGraph: {
828
+ FUNCTIONGRAPH: {
800
829
  list: 'FunctionGraph ListFunctions',
801
830
  create: 'FunctionGraph CreateFunction',
802
831
  show: 'FunctionGraph ShowFunctionConfig',
@@ -805,7 +834,7 @@ const SERVICE_EXAMPLES = {
805
834
  OBS: { list: 'OBS ls', create: 'OBS mb obs://<bucket>', show: 'OBS stat obs://<bucket>/<key>' },
806
835
  RDS: { list: 'RDS ListInstances', create: 'RDS CreateInstance', show: 'RDS ShowInstance' },
807
836
  CES: { list: 'CES ListAlarms', create: 'CES CreateAlarm', show: 'CES ListMetrics' },
808
- GaussDB: { list: 'GaussDB ListInstances', create: 'GaussDB CreateInstance', show: 'GaussDB ShowInstance' },
837
+ GAUSSDB: { list: 'GaussDB ListInstances', create: 'GaussDB CreateInstance', show: 'GaussDB ShowInstance' },
809
838
  DDS: { list: 'DDS ListInstances', create: 'DDS CreateInstance', show: 'DDS ShowInstance' },
810
839
  DCS: { list: 'DCS ListInstances', create: 'DCS CreateInstance', show: 'DCS ShowInstance' },
811
840
  };