mcp-aws-manager 0.3.7 → 0.3.9
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 +5 -3
- package/README_KO.md +3 -3
- package/bin/mcp-aws-manager-mcp.js +3 -2
- package/bin/mcp-aws-manager.js +84 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ If AWS auth is not available, use manual fallback:
|
|
|
91
91
|
mcp-aws-manager discover --manual-server-list ./servers.csv --pem-paths C:\keys\prod.pem --no-progress
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
GUI report is generated by default (
|
|
94
|
+
GUI report is generated by default (auto path: workspace/home `aws-inventory.html`):
|
|
95
95
|
|
|
96
96
|
```bash
|
|
97
97
|
mcp-aws-manager discover --profiles default --no-progress
|
|
@@ -103,6 +103,8 @@ Custom path / open behavior:
|
|
|
103
103
|
mcp-aws-manager discover --profiles default --html-out ./inventory.html --open-html --no-progress
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
By default, HTML open is enabled. Use `--no-open-html` to disable.
|
|
107
|
+
|
|
106
108
|
## User Confirmation Required
|
|
107
109
|
|
|
108
110
|
These are normally the only manual steps (agent-guided):
|
|
@@ -234,8 +236,8 @@ aws sts get-caller-identity --profile default
|
|
|
234
236
|
- `--ssh-user <name>`
|
|
235
237
|
- `--ssh-port <port>`
|
|
236
238
|
- `--ssh-connect-timeout <seconds>`
|
|
237
|
-
- `--html-out <path>` (default:
|
|
238
|
-
- `--open-html` (
|
|
239
|
+
- `--html-out <path>` (default: auto path, workspace/home `aws-inventory.html`)
|
|
240
|
+
- `--open-html` (open; default is on)
|
|
239
241
|
- `--no-open-html` (disable auto-open)
|
|
240
242
|
- `--auto-sso-login` / `--no-auto-sso-login`
|
|
241
243
|
- `--format <json|csv>`
|
package/README_KO.md
CHANGED
|
@@ -19,7 +19,7 @@ mcp-aws-manager discover --profiles default --no-progress
|
|
|
19
19
|
- SSM 상태 확인: managed/online
|
|
20
20
|
- 런타임 스냅샷(선택), SSM 완화(선택)
|
|
21
21
|
- AWS 인증이 안 될 때 수동 모드: JSON/CSV 서버 목록 + PEM SSH
|
|
22
|
-
- GUI 리포트 기본 생성:
|
|
22
|
+
- GUI 리포트 기본 생성: 워크스페이스/홈 자동 경로 `aws-inventory.html` (검색/필터/CSV 다운로드 버튼 포함)
|
|
23
23
|
- 사람이 개입해야 할 상황을 `ACTION_REQUIRED`로 표준화
|
|
24
24
|
|
|
25
25
|
## 바이너리
|
|
@@ -73,9 +73,9 @@ mcp-aws-manager discover --manual-server-list ./servers.csv --pem-paths C:\keys\
|
|
|
73
73
|
mcp-aws-manager discover --profiles default --no-progress
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
- 기본 경로:
|
|
76
|
+
- 기본 경로: 워크스페이스/홈 자동 선택(`aws-inventory.html`)
|
|
77
77
|
- `--html-out <path>`: 리포트 경로 변경
|
|
78
|
-
- `--open-html`: 생성 후 브라우저 오픈
|
|
78
|
+
- `--open-html`: 생성 후 브라우저 오픈(기본값: 켜짐)
|
|
79
79
|
- `--no-open-html`: 자동 오픈 비활성화
|
|
80
80
|
- GUI에서 현재 뷰 기준 CSV 다운로드 가능
|
|
81
81
|
|
|
@@ -137,7 +137,8 @@ function buildCliArgs(input) {
|
|
|
137
137
|
if (input.sshPort != null) args.push("--ssh-port", String(input.sshPort));
|
|
138
138
|
if (input.sshConnectTimeoutSec != null) args.push("--ssh-connect-timeout", String(input.sshConnectTimeoutSec));
|
|
139
139
|
if (input.htmlOutPath) args.push("--html-out", input.htmlOutPath);
|
|
140
|
-
if (input.openHtml) args.push("--open-html");
|
|
140
|
+
if (input.openHtml === true) args.push("--open-html");
|
|
141
|
+
if (input.openHtml === false) args.push("--no-open-html");
|
|
141
142
|
|
|
142
143
|
if (input.autoSsoLogin === false) args.push("--no-auto-sso-login");
|
|
143
144
|
if (input.autoSsoLogin === true) args.push("--auto-sso-login");
|
|
@@ -829,7 +830,7 @@ function toolSchema() {
|
|
|
829
830
|
sshPort: z.number().int().positive().optional().describe("Default SSH port for manual mode (default: 22)."),
|
|
830
831
|
sshConnectTimeoutSec: z.number().positive().optional().describe("SSH connect timeout seconds (default: 8)."),
|
|
831
832
|
htmlOutPath: z.string().min(1).optional().describe("Optional HTML GUI report output path."),
|
|
832
|
-
openHtml: z.boolean().optional().describe("
|
|
833
|
+
openHtml: z.boolean().optional().describe("Control HTML auto-open (default: true)."),
|
|
833
834
|
autoSsoLogin: z.boolean().optional().describe("Enable/disable automatic aws sso login retry."),
|
|
834
835
|
noProgress: z.boolean().optional().describe("Suppress CLI progress logs."),
|
|
835
836
|
timeoutSec: z.number().positive().max(3600).optional().describe("Wrapper timeout for CLI process."),
|
package/bin/mcp-aws-manager.js
CHANGED
|
@@ -207,6 +207,64 @@ function expandHome(input) {
|
|
|
207
207
|
return value;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
function isWritableDirectory(dirPath) {
|
|
211
|
+
try {
|
|
212
|
+
const resolved = path.resolve(String(dirPath || ""));
|
|
213
|
+
fs.mkdirSync(resolved, { recursive: true });
|
|
214
|
+
fs.accessSync(resolved, fs.constants.W_OK);
|
|
215
|
+
return true;
|
|
216
|
+
} catch (_error) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function isLikelyProtectedInstallDir(dirPath) {
|
|
222
|
+
const resolved = path.resolve(String(dirPath || ""));
|
|
223
|
+
if (!resolved) return false;
|
|
224
|
+
const normalized = resolved.replace(/\//g, "\\").toLowerCase();
|
|
225
|
+
if (process.platform === "win32") {
|
|
226
|
+
if (normalized.includes("\\program files\\")) return true;
|
|
227
|
+
if (/^[a-z]:\\windows(\\|$)/.test(normalized)) return true;
|
|
228
|
+
} else {
|
|
229
|
+
if (normalized === "\\usr" || normalized.startsWith("\\usr\\")) return true;
|
|
230
|
+
if (normalized === "\\opt" || normalized.startsWith("\\opt\\")) return true;
|
|
231
|
+
if (normalized === "\\system" || normalized.startsWith("\\system\\")) return true;
|
|
232
|
+
}
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function resolveDefaultHtmlOutPath() {
|
|
237
|
+
const explicit = envText("MCP_AWS_WORKSPACE_DIR");
|
|
238
|
+
if (explicit) {
|
|
239
|
+
const dir = path.resolve(expandHome(explicit));
|
|
240
|
+
if (isWritableDirectory(dir)) {
|
|
241
|
+
return path.join(dir, DEFAULT_HTML_REPORT_NAME);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const candidates = [
|
|
246
|
+
envText("PWD"),
|
|
247
|
+
envText("INIT_CWD"),
|
|
248
|
+
envText("WORKSPACE_DIR"),
|
|
249
|
+
envText("PROJECT_ROOT")
|
|
250
|
+
];
|
|
251
|
+
for (const raw of candidates) {
|
|
252
|
+
if (!raw) continue;
|
|
253
|
+
const dir = path.resolve(expandHome(raw));
|
|
254
|
+
if (isLikelyProtectedInstallDir(dir)) continue;
|
|
255
|
+
if (isWritableDirectory(dir)) {
|
|
256
|
+
return path.join(dir, DEFAULT_HTML_REPORT_NAME);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const home = os.homedir();
|
|
261
|
+
if (isWritableDirectory(home)) {
|
|
262
|
+
return path.join(home, DEFAULT_HTML_REPORT_NAME);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return path.resolve(process.cwd(), DEFAULT_HTML_REPORT_NAME);
|
|
266
|
+
}
|
|
267
|
+
|
|
210
268
|
function usageText() {
|
|
211
269
|
const clientList = Array.from(SUPPORTED_CLIENTS).join(",");
|
|
212
270
|
return [
|
|
@@ -267,9 +325,9 @@ function usageText() {
|
|
|
267
325
|
" --ssh-user <name> (default: ec2-user)",
|
|
268
326
|
" --ssh-port <port> (default: 22)",
|
|
269
327
|
" --ssh-connect-timeout <seconds> (default: 8)",
|
|
270
|
-
" --html-out <path> (default:
|
|
271
|
-
" --open-html (
|
|
272
|
-
" --no-open-html (disable auto-open
|
|
328
|
+
" --html-out <path> (default: auto -> workspace/home aws-inventory.html)",
|
|
329
|
+
" --open-html (open HTML report after write; default: on)",
|
|
330
|
+
" --no-open-html (disable HTML auto-open)",
|
|
273
331
|
" --auto-sso-login / --no-auto-sso-login",
|
|
274
332
|
" --format <json|csv> (default: json)",
|
|
275
333
|
" --out <path>",
|
|
@@ -287,7 +345,7 @@ function usageText() {
|
|
|
287
345
|
" MCP_AWS_SNAPSHOT_MAX_KB, MCP_AWS_AUTO_SSO_LOGIN",
|
|
288
346
|
" MCP_AWS_MANUAL_SERVER_LIST, MCP_AWS_PEM_PATHS, MCP_AWS_SSH_USER, MCP_AWS_SSH_PORT",
|
|
289
347
|
" MCP_AWS_SSH_CONNECT_TIMEOUT",
|
|
290
|
-
" MCP_AWS_HTML_OUT, MCP_AWS_OPEN_HTML, MCP_AWS_HEADLESS",
|
|
348
|
+
" MCP_AWS_HTML_OUT, MCP_AWS_OPEN_HTML, MCP_AWS_HEADLESS, MCP_AWS_WORKSPACE_DIR",
|
|
291
349
|
" MCP_AWS_FORMAT, MCP_AWS_OUT, MCP_AWS_NO_PROGRESS",
|
|
292
350
|
""
|
|
293
351
|
].join("\n");
|
|
@@ -566,8 +624,8 @@ function parseDiscoverArgs(argv) {
|
|
|
566
624
|
sshConnectTimeoutSec: Math.round(toPosNum(options.sshConnectTimeoutSec || envText("MCP_AWS_SSH_CONNECT_TIMEOUT") || "8", "--ssh-connect-timeout", 8)),
|
|
567
625
|
htmlOutPath: options.htmlOutPath
|
|
568
626
|
? path.resolve(expandHome(options.htmlOutPath))
|
|
569
|
-
: (envText("MCP_AWS_HTML_OUT") ? path.resolve(expandHome(envText("MCP_AWS_HTML_OUT"))) :
|
|
570
|
-
openHtml: options.openHtml != null ? options.openHtml : (envOpenHtml != null ? envBool("MCP_AWS_OPEN_HTML") :
|
|
627
|
+
: (envText("MCP_AWS_HTML_OUT") ? path.resolve(expandHome(envText("MCP_AWS_HTML_OUT"))) : resolveDefaultHtmlOutPath()),
|
|
628
|
+
openHtml: options.openHtml != null ? options.openHtml : (envOpenHtml != null ? envBool("MCP_AWS_OPEN_HTML") : true),
|
|
571
629
|
autoSsoLogin: options.autoSsoLogin != null ? options.autoSsoLogin : (envText("MCP_AWS_AUTO_SSO_LOGIN") != null ? envBool("MCP_AWS_AUTO_SSO_LOGIN") : true),
|
|
572
630
|
format,
|
|
573
631
|
outPath: options.outPath ? path.resolve(expandHome(options.outPath)) : (envText("MCP_AWS_OUT") ? path.resolve(expandHome(envText("MCP_AWS_OUT"))) : null),
|
|
@@ -2939,9 +2997,25 @@ function renderHtmlReport(records) {
|
|
|
2939
2997
|
function writeHtmlReport(config, records) {
|
|
2940
2998
|
if (!config.htmlOutPath) return null;
|
|
2941
2999
|
const html = renderHtmlReport(records);
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
3000
|
+
try {
|
|
3001
|
+
fs.writeFileSync(config.htmlOutPath, html, "utf8");
|
|
3002
|
+
eprint(`Wrote HTML report to ${config.htmlOutPath}`);
|
|
3003
|
+
return config.htmlOutPath;
|
|
3004
|
+
} catch (error) {
|
|
3005
|
+
const code = String(error && error.code ? error.code : "");
|
|
3006
|
+
if (!["EACCES", "EPERM", "EROFS"].includes(code)) {
|
|
3007
|
+
throw error;
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
const fallbackPath = path.join(os.homedir(), path.basename(config.htmlOutPath) || DEFAULT_HTML_REPORT_NAME);
|
|
3011
|
+
if (path.resolve(fallbackPath) === path.resolve(config.htmlOutPath)) {
|
|
3012
|
+
throw error;
|
|
3013
|
+
}
|
|
3014
|
+
fs.mkdirSync(path.dirname(fallbackPath), { recursive: true });
|
|
3015
|
+
fs.writeFileSync(fallbackPath, html, "utf8");
|
|
3016
|
+
eprint(`WARNING: failed to write HTML report to ${config.htmlOutPath} (${code}); wrote fallback to ${fallbackPath}`);
|
|
3017
|
+
return fallbackPath;
|
|
3018
|
+
}
|
|
2945
3019
|
}
|
|
2946
3020
|
|
|
2947
3021
|
function tryOpenFile(targetPath) {
|
|
@@ -3060,7 +3134,7 @@ async function runWorkflow(config) {
|
|
|
3060
3134
|
if (htmlPath && shouldAutoOpenHtml(config)) {
|
|
3061
3135
|
const opened = tryOpenFile(htmlPath);
|
|
3062
3136
|
if (!opened.ok) {
|
|
3063
|
-
|
|
3137
|
+
eprint(`NOTE: Failed to auto-open HTML report: ${opened.detail}`);
|
|
3064
3138
|
} else {
|
|
3065
3139
|
eprint(`Opened HTML report via ${opened.detail}`);
|
|
3066
3140
|
}
|
package/package.json
CHANGED