mcp-aws-manager 0.4.0 → 0.4.1

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
@@ -39,7 +39,7 @@ Use `mcp-aws-manager` when you need an operations workflow MCP, not just generic
39
39
 
40
40
  See detailed comparison and product boundaries in:
41
41
 
42
- - `MCP_DIFFERENTIATION.md`
42
+ - `docs/MCP_DIFFERENTIATION.md`
43
43
 
44
44
  ## Quick Comparison
45
45
 
@@ -51,7 +51,7 @@ See detailed comparison and product boundaries in:
51
51
  | Response contract | Normalized (`ok/summary/records/requiredActions/meta`) | Varies by implementation |
52
52
  | Best fit | Reproducible ops loops with operator guidance | Exploratory or wide API probing |
53
53
 
54
- For full rationale and boundaries, see `MCP_DIFFERENTIATION.md` and `MCP_DIFFERENTIATION_KO.md`.
54
+ For full rationale and boundaries, see `docs/MCP_DIFFERENTIATION.md` and `docs/MCP_DIFFERENTIATION_KO.md`.
55
55
 
56
56
  ## API Coverage Snapshot
57
57
 
@@ -142,6 +142,11 @@ mcp-aws-manager
142
142
  Bootstrap registers the default single MCP server for detected clients:
143
143
 
144
144
  - `mcp-aws-manager` (single-entry, `--surface all`)
145
+ - Runtime command is auto-resolved for host stability.
146
+ - Windows priority: absolute `mcp-aws-manager-mcp.cmd`
147
+ - macOS/Linux priority: absolute `mcp-aws-manager-mcp` binary
148
+ - Fallback: `node <installed-package>/bin/mcp-aws-manager-mcp.js`
149
+ - Last fallback (ephemeral npx context): pinned `npx -y -p mcp-aws-manager@<version> mcp-aws-manager-mcp`
145
150
 
146
151
  Optional explicit registration:
147
152
 
@@ -231,7 +236,22 @@ Use this only when automatic `bootstrap/setup` registration is unavailable.
231
236
  }
232
237
  ```
233
238
 
234
- 2) Global npm install:
239
+ 2) Global npm install (manual fallback):
240
+
241
+ Windows (recommended):
242
+
243
+ ```json
244
+ {
245
+ "mcpServers": {
246
+ "mcp-aws-manager": {
247
+ "command": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\mcp-aws-manager-mcp.cmd",
248
+ "args": ["--surface", "all"]
249
+ }
250
+ }
251
+ }
252
+ ```
253
+
254
+ macOS/Linux:
235
255
 
236
256
  ```json
237
257
  {
@@ -489,7 +509,7 @@ Common `ACTION_REQUIRED` codes:
489
509
  - `rawNormalized` (always included for re-processing stability)
490
510
  - `schema` / `schemaVersion`
491
511
  - Contract schema: `schemas/mcp-tool-response.schema.json`
492
- - Compatibility policy: `RESPONSE_COMPATIBILITY_POLICY.md`
512
+ - Compatibility policy: `docs/RESPONSE_COMPATIBILITY_POLICY.md`
493
513
 
494
514
  <details>
495
515
  <summary>Detailed AWS Auth Setup (SSO vs Access Key)</summary>
@@ -942,15 +962,16 @@ Manual fallback mode:
942
962
  ## Related Docs
943
963
 
944
964
  Document status:
945
- - Canonical (keep synchronized with implementation): `README.md`, `RESPONSE_COMPATIBILITY_POLICY.md`
946
- - Reference (detail/positioning): `IMPLEMENTATION_INTEGRATIONS.md`, `MCP_DIFFERENTIATION.md`, `MCP_DIFFERENTIATION_KO.md`, `AGENT_WORKING_CONTEXT_KO.md`, `RECORDS_FIELD_REFERENCE_KO.md`
965
+ - Canonical (keep synchronized with implementation): `README.md`, `docs/RESPONSE_COMPATIBILITY_POLICY.md`
966
+ - Reference (detail/positioning): `docs/IMPLEMENTATION_INTEGRATIONS.md`, `docs/MCP_DIFFERENTIATION.md`, `docs/MCP_DIFFERENTIATION_KO.md`, `workflow/AGENT_WORKING_CONTEXT_KO.md`, `docs/RECORDS_FIELD_REFERENCE_KO.md`
947
967
 
948
968
  - `README_KO.md`: Korean overview and quick start
949
- - `IMPLEMENTATION_INTEGRATIONS.md`: API/CLI integration inventory
950
- - `MCP_DIFFERENTIATION.md`: differentiation from existing AWS MCP servers
951
- - `MCP_DIFFERENTIATION_KO.md`: Korean differentiation guide and selection criteria
952
- - `AGENT_WORKING_CONTEXT_KO.md`: agent-focused implementation invariants, gateway loop, and operation catalog quick reference
953
- - `RECORDS_FIELD_REFERENCE_KO.md`: full `records[]` field reference (292 fields)
954
- - `RESPONSE_COMPATIBILITY_POLICY.md`: response schema/version compatibility rules
969
+ - `docs/IMPLEMENTATION_INTEGRATIONS.md`: API/CLI integration inventory
970
+ - `docs/MCP_DIFFERENTIATION.md`: differentiation from existing AWS MCP servers
971
+ - `docs/MCP_DIFFERENTIATION_KO.md`: Korean differentiation guide and selection criteria
972
+ - `workflow/AGENT_WORKING_CONTEXT_KO.md`: agent-focused implementation invariants, gateway loop, and operation catalog quick reference
973
+ - `docs/RECORDS_FIELD_REFERENCE_KO.md`: full `records[]` field reference (292 fields)
974
+ - `docs/RESPONSE_COMPATIBILITY_POLICY.md`: response schema/version compatibility rules
955
975
  - `schemas/mcp-tool-response.schema.json`: canonical tool response JSON schema
956
976
 
977
+
package/README_KO.md CHANGED
@@ -39,7 +39,7 @@ mcp-aws-manager discover --profiles default --no-progress
39
39
 
40
40
  비교/경계는 아래 문서를 참고하세요.
41
41
 
42
- - `MCP_DIFFERENTIATION.md`
42
+ - `docs/MCP_DIFFERENTIATION.md`
43
43
 
44
44
  ## 빠른 비교 요약
45
45
 
@@ -51,7 +51,7 @@ mcp-aws-manager discover --profiles default --no-progress
51
51
  | 응답 계약 | 정규화(`ok/summary/records/requiredActions/meta`) | 구현마다 상이 |
52
52
  | 적합한 상황 | 반복 가능한 운영 루프 + 운영자 가이드 필요 | 탐색/실험 위주의 광범위 API 접근 |
53
53
 
54
- 상세 근거와 경계는 `MCP_DIFFERENTIATION.md`, `MCP_DIFFERENTIATION_KO.md`를 참고하세요.
54
+ 상세 근거와 경계는 `docs/MCP_DIFFERENTIATION.md`, `docs/MCP_DIFFERENTIATION_KO.md`를 참고하세요.
55
55
 
56
56
  ## API 커버리지 스냅샷
57
57
 
@@ -142,6 +142,11 @@ mcp-aws-manager
142
142
  bootstrap/setup 기본 동작은 단일 서버 1개를 등록합니다.
143
143
 
144
144
  - `mcp-aws-manager` (single-entry, `--surface all`)
145
+ - 런타임 커맨드는 호스트 안정성을 위해 자동으로 해석됩니다.
146
+ - Windows 우선순위: 절대경로 `mcp-aws-manager-mcp.cmd`
147
+ - macOS/Linux 우선순위: 절대경로 `mcp-aws-manager-mcp` 바이너리
148
+ - 폴백: `node <installed-package>/bin/mcp-aws-manager-mcp.js`
149
+ - 최종 폴백(npx 임시 실행 컨텍스트): 버전 고정 `npx -y -p mcp-aws-manager@<version> mcp-aws-manager-mcp`
145
150
 
146
151
  명시적 등록 예시:
147
152
 
@@ -232,7 +237,22 @@ mcp-aws-manager discover --profiles default --html-out ./inventory.html --open-h
232
237
  }
233
238
  ```
234
239
 
235
- 2) 전역 npm 설치:
240
+ 2) 전역 npm 설치(수동 대체 경로):
241
+
242
+ Windows(권장):
243
+
244
+ ```json
245
+ {
246
+ "mcpServers": {
247
+ "mcp-aws-manager": {
248
+ "command": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\mcp-aws-manager-mcp.cmd",
249
+ "args": ["--surface", "all"]
250
+ }
251
+ }
252
+ }
253
+ ```
254
+
255
+ macOS/Linux:
236
256
 
237
257
  ```json
238
258
  {
@@ -490,7 +510,7 @@ Discover 연산 참고:
490
510
  - `rawNormalized` (재처리 안정성을 위해 항상 포함)
491
511
  - `schema` / `schemaVersion`
492
512
  - 계약 스키마: `schemas/mcp-tool-response.schema.json`
493
- - 호환성 정책: `RESPONSE_COMPATIBILITY_POLICY.md`
513
+ - 호환성 정책: `docs/RESPONSE_COMPATIBILITY_POLICY.md`
494
514
 
495
515
  <details>
496
516
  <summary>상세 AWS 인증 설정 (SSO vs Access Key)</summary>
@@ -936,16 +956,17 @@ E2E 러너 검증 항목:
936
956
  ## 관련 문서
937
957
 
938
958
  문서 상태:
939
- - Canonical(구현과 동기화 필수): `README.md`, `RESPONSE_COMPATIBILITY_POLICY.md`
940
- - Reference(상세/비교 참고): `IMPLEMENTATION_INTEGRATIONS.md`, `MCP_DIFFERENTIATION.md`, `MCP_DIFFERENTIATION_KO.md`, `AGENT_WORKING_CONTEXT_KO.md`, `RECORDS_FIELD_REFERENCE_KO.md`
959
+ - Canonical(구현과 동기화 필수): `README.md`, `docs/RESPONSE_COMPATIBILITY_POLICY.md`
960
+ - Reference(상세/비교 참고): `docs/IMPLEMENTATION_INTEGRATIONS.md`, `docs/MCP_DIFFERENTIATION.md`, `docs/MCP_DIFFERENTIATION_KO.md`, `workflow/AGENT_WORKING_CONTEXT_KO.md`, `docs/RECORDS_FIELD_REFERENCE_KO.md`
941
961
 
942
962
  - `README_KO.md`: 한국어 개요/빠른 시작
943
- - `IMPLEMENTATION_INTEGRATIONS.md`: API/CLI 연동 인벤토리
944
- - `MCP_DIFFERENTIATION.md`: AWS MCP 대안 대비 차별점
945
- - `MCP_DIFFERENTIATION_KO.md`: 한국어 차별화/선택 가이드
946
- - `AGENT_WORKING_CONTEXT_KO.md`: 에이전트 협업 시 불변 원칙/작업 루프/operationId 빠른 참조
947
- - `RECORDS_FIELD_REFERENCE_KO.md`: `records[]` 전수 필드(292개) 레퍼런스
948
- - `RESPONSE_COMPATIBILITY_POLICY.md`: 응답 스키마/버전 호환 정책
963
+ - `docs/IMPLEMENTATION_INTEGRATIONS.md`: API/CLI 연동 인벤토리
964
+ - `docs/MCP_DIFFERENTIATION.md`: AWS MCP 대안 대비 차별점
965
+ - `docs/MCP_DIFFERENTIATION_KO.md`: 한국어 차별화/선택 가이드
966
+ - `workflow/AGENT_WORKING_CONTEXT_KO.md`: 에이전트 협업 시 불변 원칙/작업 루프/operationId 빠른 참조
967
+ - `docs/RECORDS_FIELD_REFERENCE_KO.md`: `records[]` 전수 필드(292개) 레퍼런스
968
+ - `docs/RESPONSE_COMPATIBILITY_POLICY.md`: 응답 스키마/버전 호환 정책
949
969
  - `schemas/mcp-tool-response.schema.json`: 표준 도구 응답 JSON 스키마
950
970
 
951
971
 
972
+
@@ -52,6 +52,8 @@ const APP_ANALYSIS_MEM_HIGH_PCT = 90;
52
52
  const ACM_EXPIRING_SOON_DAYS = 30;
53
53
  const DEFAULT_SERVER_NAME = "mcp-aws-manager";
54
54
  const DEFAULT_MCP_COMMAND = "mcp-aws-manager-mcp";
55
+ const DEFAULT_MCP_COMMAND_ENTRY = path.resolve(__dirname, "mcp-aws-manager-mcp.js");
56
+ const PACKAGE_JSON_PATH = path.resolve(__dirname, "..", "package.json");
55
57
  const DEFAULT_HTML_REPORT_NAME = "aws-inventory.html";
56
58
  const DEFAULT_TOPOLOGY_REPORT_NAME = "aws-topology.json";
57
59
  const DEFAULT_RELATIONSHIPS_REPORT_NAME = "aws-relationships.json";
@@ -154,6 +156,7 @@ const REQUIRED_ACTION_DEFAULTS = Object.freeze({
154
156
  const POLICY_PACK_NAMES = Object.keys(POLICY_PACKS);
155
157
  const ASSUMED_PROFILE_PREFIX = "assume-role://";
156
158
  const assumeRoleProviderCache = new Map();
159
+ let packageVersionCache = null;
157
160
 
158
161
  function eprint(msg) {
159
162
  process.stderr.write(String(msg) + "\n");
@@ -187,6 +190,200 @@ function parseCsv(raw) {
187
190
  return list.length ? list : null;
188
191
  }
189
192
 
193
+ function pathCompareKey(value) {
194
+ const resolved = path.resolve(String(value || ""));
195
+ return process.platform === "win32" ? resolved.toLowerCase() : resolved;
196
+ }
197
+
198
+ function uniquePaths(values) {
199
+ const out = [];
200
+ const seen = new Set();
201
+ for (const raw of Array.isArray(values) ? values : []) {
202
+ const text = String(raw || "").trim();
203
+ if (!text) continue;
204
+ const key = pathCompareKey(text);
205
+ if (seen.has(key)) continue;
206
+ seen.add(key);
207
+ out.push(path.resolve(text));
208
+ }
209
+ return out;
210
+ }
211
+
212
+ function readPathEnvDirs() {
213
+ const raw = process.env.PATH || process.env.Path || process.env.path || "";
214
+ if (!raw) return [];
215
+ return String(raw)
216
+ .split(path.delimiter)
217
+ .map((item) => String(item || "").trim())
218
+ .filter(Boolean);
219
+ }
220
+
221
+ function fileExists(filePath) {
222
+ try {
223
+ return fs.statSync(filePath).isFile();
224
+ } catch (_error) {
225
+ return false;
226
+ }
227
+ }
228
+
229
+ function readCurrentPackageVersion() {
230
+ if (packageVersionCache) return packageVersionCache;
231
+ try {
232
+ const parsed = JSON.parse(fs.readFileSync(PACKAGE_JSON_PATH, "utf8"));
233
+ const value = String(parsed && parsed.version ? parsed.version : "").trim();
234
+ packageVersionCache = value || "latest";
235
+ } catch (_error) {
236
+ packageVersionCache = "latest";
237
+ }
238
+ return packageVersionCache;
239
+ }
240
+
241
+ function isLikelyNpxCachePath(filePath) {
242
+ const normalized = String(filePath || "")
243
+ .replace(/\\/g, "/")
244
+ .toLowerCase();
245
+ return normalized.includes("/_npx/");
246
+ }
247
+
248
+ function lookupCommandInPath(commandName) {
249
+ const bin = String(commandName || "").trim();
250
+ if (!bin) return null;
251
+ const lookupTool = process.platform === "win32" ? "where.exe" : "which";
252
+ try {
253
+ const run = spawnSync(lookupTool, [bin], {
254
+ stdio: "pipe",
255
+ encoding: "utf8",
256
+ shell: false,
257
+ timeout: 2500,
258
+ windowsHide: true
259
+ });
260
+ if (!run || run.status !== 0) return null;
261
+ const lines = String(run.stdout || "")
262
+ .split(/\r?\n/)
263
+ .map((line) => String(line || "").trim())
264
+ .filter(Boolean);
265
+ for (const line of lines) {
266
+ const resolved = path.resolve(line);
267
+ if (fileExists(resolved)) return resolved;
268
+ }
269
+ } catch (_error) {
270
+ return null;
271
+ }
272
+ return null;
273
+ }
274
+
275
+ function resolveNpxCommandBinary() {
276
+ if (process.platform === "win32") {
277
+ const nodeDir = path.dirname(path.resolve(String(process.execPath || "")));
278
+ const bundled = path.join(nodeDir, "npx.cmd");
279
+ if (fileExists(bundled)) return bundled;
280
+ return lookupCommandInPath("npx.cmd") || lookupCommandInPath("npx") || "npx";
281
+ }
282
+ return lookupCommandInPath("npx") || "npx";
283
+ }
284
+
285
+ function resolveWindowsMcpCommand() {
286
+ if (process.platform !== "win32") return null;
287
+
288
+ const fromPathCmd = lookupCommandInPath(`${DEFAULT_MCP_COMMAND}.cmd`);
289
+ if (fromPathCmd) {
290
+ return { mcpCommand: fromPathCmd, mcpArgs: [], resolution: "windows-cmd-path" };
291
+ }
292
+
293
+ const packageRoot = path.resolve(__dirname, "..");
294
+ const nodeModulesDir = path.dirname(packageRoot);
295
+ const npmRootCandidate = path.dirname(nodeModulesDir);
296
+ const npmPrefix = envText("npm_config_prefix");
297
+ const appData = envText("APPDATA");
298
+ const candidateDirs = uniquePaths([
299
+ path.join(nodeModulesDir, ".bin"),
300
+ npmRootCandidate,
301
+ npmPrefix ? path.resolve(expandHome(npmPrefix)) : null,
302
+ appData ? path.join(path.resolve(appData), "npm") : null,
303
+ ...readPathEnvDirs()
304
+ ]);
305
+
306
+ for (const dirPath of candidateDirs) {
307
+ const candidate = path.join(dirPath, `${DEFAULT_MCP_COMMAND}.cmd`);
308
+ if (!fileExists(candidate)) continue;
309
+ return { mcpCommand: candidate, mcpArgs: [], resolution: "windows-cmd-absolute" };
310
+ }
311
+
312
+ const fromPathGeneric = lookupCommandInPath(DEFAULT_MCP_COMMAND);
313
+ if (fromPathGeneric && fromPathGeneric.toLowerCase().endsWith(".cmd")) {
314
+ return { mcpCommand: fromPathGeneric, mcpArgs: [], resolution: "windows-cmd-generic" };
315
+ }
316
+ return null;
317
+ }
318
+
319
+ function resolvePosixMcpCommand() {
320
+ if (process.platform === "win32") return null;
321
+
322
+ const fromPath = lookupCommandInPath(DEFAULT_MCP_COMMAND);
323
+ if (fromPath) {
324
+ return { mcpCommand: fromPath, mcpArgs: [], resolution: "posix-path-absolute" };
325
+ }
326
+
327
+ const packageRoot = path.resolve(__dirname, "..");
328
+ const localBin = path.join(path.dirname(packageRoot), ".bin", DEFAULT_MCP_COMMAND);
329
+ if (fileExists(localBin)) {
330
+ return { mcpCommand: localBin, mcpArgs: [], resolution: "posix-local-bin" };
331
+ }
332
+ return null;
333
+ }
334
+
335
+ function resolveNodeScriptMcpTarget() {
336
+ if (!fileExists(DEFAULT_MCP_COMMAND_ENTRY)) return null;
337
+ const nodeBin = path.resolve(String(process.execPath || ""));
338
+ if (!fileExists(nodeBin)) return null;
339
+ const ephemeral = isLikelyNpxCachePath(DEFAULT_MCP_COMMAND_ENTRY);
340
+ return {
341
+ mcpCommand: nodeBin,
342
+ mcpArgs: [DEFAULT_MCP_COMMAND_ENTRY],
343
+ resolution: ephemeral ? "node-script-ephemeral" : "node-script-absolute",
344
+ ephemeral
345
+ };
346
+ }
347
+
348
+ function resolveNpxMcpTarget() {
349
+ const npxCommand = resolveNpxCommandBinary();
350
+ if (!npxCommand) return null;
351
+ const version = readCurrentPackageVersion();
352
+ return {
353
+ mcpCommand: npxCommand,
354
+ mcpArgs: ["-y", "-p", `mcp-aws-manager@${version}`, DEFAULT_MCP_COMMAND],
355
+ resolution: "npx-pinned"
356
+ };
357
+ }
358
+
359
+ function resolveDefaultRegistrationTarget() {
360
+ const serverName = DEFAULT_SERVER_NAME;
361
+ const windowsCmdTarget = resolveWindowsMcpCommand();
362
+ const posixTarget = resolvePosixMcpCommand();
363
+ const nodeScriptTarget = resolveNodeScriptMcpTarget();
364
+ const npxTarget = resolveNpxMcpTarget();
365
+
366
+ if (process.platform === "win32") {
367
+ if (windowsCmdTarget) return { serverName, ...windowsCmdTarget };
368
+ if (nodeScriptTarget && !nodeScriptTarget.ephemeral) return { serverName, ...nodeScriptTarget };
369
+ if (npxTarget) return { serverName, ...npxTarget };
370
+ if (nodeScriptTarget) return { serverName, ...nodeScriptTarget };
371
+ return { serverName, mcpCommand: DEFAULT_MCP_COMMAND, mcpArgs: [], resolution: "path-default" };
372
+ }
373
+
374
+ if (posixTarget) return { serverName, ...posixTarget };
375
+ if (nodeScriptTarget && !nodeScriptTarget.ephemeral) return { serverName, ...nodeScriptTarget };
376
+ if (npxTarget) return { serverName, ...npxTarget };
377
+ if (nodeScriptTarget) return { serverName, ...nodeScriptTarget };
378
+ return { serverName, mcpCommand: DEFAULT_MCP_COMMAND, mcpArgs: [], resolution: "path-default" };
379
+ }
380
+
381
+ function registrationTargetHelpArgs(target) {
382
+ const args = Array.isArray(target && target.mcpArgs) ? target.mcpArgs.slice() : [];
383
+ args.push("--help");
384
+ return args;
385
+ }
386
+
190
387
  function parseShardSpec(raw, label) {
191
388
  if (raw == null || String(raw).trim() === "") return null;
192
389
  const text = String(raw).trim();
@@ -545,7 +742,7 @@ function usageText() {
545
742
  " discover Run multi-service inventory workflow (EC2/Lambda/ALB/ASG/RDS/ElastiCache/Route53 + VPC/ECS/S3/IAM/KMS/CloudWatch + extended platform/security/analytics services)",
546
743
  "",
547
744
  "Setup/Bootstrap/Doctor options:",
548
- " (fixed target: mcp-aws-manager => mcp-aws-manager-mcp)",
745
+ " (target: mcp-aws-manager => auto-resolved runtime command for mcp-aws-manager-mcp)",
549
746
  ` --clients <${clientList}> (default: codex,claude)`,
550
747
  " --force (setup/bootstrap only; always remove then add)",
551
748
  " -h, --help",
@@ -873,9 +1070,10 @@ function parseRegistrationArgs(argv, opts = {}) {
873
1070
  return { help: true };
874
1071
  }
875
1072
 
1073
+ const defaultTarget = resolveDefaultRegistrationTarget();
876
1074
  return {
877
1075
  help: false,
878
- targets: [{ serverName: DEFAULT_SERVER_NAME, mcpCommand: DEFAULT_MCP_COMMAND, mcpArgs: [] }],
1076
+ targets: [defaultTarget],
879
1077
  clients: options.clients ? parseClients(options.clients) : ["codex", "claude"],
880
1078
  force: options.force
881
1079
  };
@@ -2264,16 +2462,17 @@ function targetCommandLabel(target) {
2264
2462
 
2265
2463
  function runSetupInternal(config, options = {}) {
2266
2464
  const ensureOnly = options.ensureOnly === true;
2465
+ const defaultTarget = resolveDefaultRegistrationTarget();
2267
2466
  const targets = Array.isArray(config.targets) && config.targets.length
2268
2467
  ? config.targets
2269
- : [{ serverName: DEFAULT_SERVER_NAME, mcpCommand: DEFAULT_MCP_COMMAND, mcpArgs: [] }];
2468
+ : [defaultTarget];
2270
2469
  const clients = config.clients.filter((cli) =>
2271
2470
  clientHelpAttempts(cli).some((args) => commandExists(cli, args))
2272
2471
  );
2273
2472
  const results = [];
2274
2473
  const commandChecks = targets.map((target) => ({
2275
2474
  ...target,
2276
- ok: commandExists(target.mcpCommand, ["--help"])
2475
+ ok: commandExists(target.mcpCommand, registrationTargetHelpArgs(target))
2277
2476
  }));
2278
2477
 
2279
2478
  process.stdout.write(ensureOnly ? "Bootstrap start.\n" : "Setup start.\n");
@@ -2343,16 +2542,17 @@ function runSetupInternal(config, options = {}) {
2343
2542
  }
2344
2543
 
2345
2544
  function runDoctor(config) {
2545
+ const defaultTarget = resolveDefaultRegistrationTarget();
2346
2546
  const targets = Array.isArray(config.targets) && config.targets.length
2347
2547
  ? config.targets
2348
- : [{ serverName: DEFAULT_SERVER_NAME, mcpCommand: DEFAULT_MCP_COMMAND, mcpArgs: [] }];
2548
+ : [defaultTarget];
2349
2549
  process.stdout.write("Doctor start.\n");
2350
2550
  process.stdout.write(`Targets: ${targets.map((t) => `${t.serverName}=>${targetCommandLabel(t)}`).join(", ")}\n`);
2351
2551
  let hasIssue = false;
2352
2552
  let foundClient = false;
2353
2553
 
2354
2554
  for (const target of targets) {
2355
- const mcpCommandRun = runCLICommand(target.mcpCommand, ["--help"], { stdio: "pipe" });
2555
+ const mcpCommandRun = runCLICommand(target.mcpCommand, registrationTargetHelpArgs(target), { stdio: "pipe" });
2356
2556
  if (mcpCommandRun && mcpCommandRun.status === 0) {
2357
2557
  process.stdout.write(`mcp-command: ok (${target.serverName}=>${targetCommandLabel(target)})\n`);
2358
2558
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-aws-manager",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "AWS operations CLI and MCP server (SSM-only) for EC2/Lambda inventory, remediation, and runtime snapshots",
5
5
  "license": "MIT",
6
6
  "publishConfig": {