aws-security-mcp 0.6.2 → 0.6.3

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/dist/src/index.js CHANGED
@@ -4,7 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
4
4
  import { z } from "zod";
5
5
 
6
6
  // src/version.ts
7
- var VERSION = "0.6.2";
7
+ var VERSION = "0.6.3";
8
8
 
9
9
  // src/utils/aws-client.ts
10
10
  import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
@@ -3646,6 +3646,12 @@ var zhI18n = {
3646
3646
  trendTitle: "30\u65E5\u8D8B\u52BF",
3647
3647
  findingsBySeverity: "\u6309\u4E25\u91CD\u6027\u5206\u7C7B\u7684\u53D1\u73B0",
3648
3648
  showMoreCount: (n) => `\u663E\u793A\u5269\u4F59 ${n} \u9879\u2026`,
3649
+ // Filter toolbar
3650
+ filterSeverity: "\u4E25\u91CD\u6027\uFF1A",
3651
+ filterModule: "\u6A21\u5757\uFF1A",
3652
+ filterAll: "\u5168\u90E8",
3653
+ filterAllModules: "\u5168\u90E8\u6A21\u5757",
3654
+ filterCountTpl: "\u663E\u793A {shown} / {total} \u4E2A\u53D1\u73B0",
3649
3655
  // Extended — MLPS extras
3650
3656
  // Markdown report
3651
3657
  executiveSummary: "\u6267\u884C\u6458\u8981",
@@ -3916,6 +3922,12 @@ var enI18n = {
3916
3922
  trendTitle: "30-Day Trends",
3917
3923
  findingsBySeverity: "Findings by Severity",
3918
3924
  showMoreCount: (n) => `Show ${n} more\u2026`,
3925
+ // Filter toolbar
3926
+ filterSeverity: "Severity:",
3927
+ filterModule: "Module:",
3928
+ filterAll: "All",
3929
+ filterAllModules: "All Modules",
3930
+ filterCountTpl: "Showing {shown} / {total} findings",
3919
3931
  // Extended \u2014 MLPS extras
3920
3932
  // Markdown report
3921
3933
  executiveSummary: "Executive Summary",
@@ -7231,7 +7243,16 @@ function sharedCss() {
7231
7243
  .rec-body ol{padding-left:24px}
7232
7244
  .rec-body li{margin-bottom:8px;color:#cbd5e1;font-size:13px}
7233
7245
  .rec-body .badge{margin-right:6px;vertical-align:middle}
7246
+ .filter-toolbar{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin-bottom:20px;padding:12px 16px;background:#1e293b;border:1px solid #334155;border-radius:8px}
7247
+ .filter-group{display:flex;align-items:center;gap:8px}
7248
+ .filter-label{color:#94a3b8;font-size:13px}
7249
+ .filter-btn{padding:4px 12px;border-radius:4px;border:1px solid #475569;background:transparent;color:#cbd5e1;cursor:pointer;font-size:13px}
7250
+ .filter-btn:hover{background:#334155}
7251
+ .filter-btn.active{background:#3b82f6;border-color:#3b82f6;color:#fff}
7252
+ .filter-select{padding:4px 8px;border-radius:4px;border:1px solid #475569;background:#0f172a;color:#cbd5e1;font-size:13px}
7253
+ .filter-count{color:#64748b;font-size:13px;margin-left:auto}
7234
7254
  @media print{
7255
+ .filter-toolbar{display:none !important}
7235
7256
  body{background:#fff;color:#1e293b;-webkit-print-color-adjust:exact;print-color-adjust:exact}
7236
7257
  .container{max-width:100%;padding:20px}
7237
7258
  .card,.score-card,.stat-card,.chart-box,.finding-fold,.top5-card,.trend-chart,.category-fold,.module-fold,.finding-card,.rec-fold{background:#fff;border:1px solid #e2e8f0}
@@ -7490,13 +7511,14 @@ function generateHtmlReport(scanResults, history, lang) {
7490
7511
  </section>`;
7491
7512
  }
7492
7513
  let findingsHtml;
7514
+ let filterToolbarHtml = "";
7493
7515
  if (summary.totalFindings === 0) {
7494
7516
  findingsHtml = `<div class="no-findings">${esc(t.noIssuesFound)}</div>`;
7495
7517
  } else {
7496
7518
  const FOLD_THRESHOLD = 20;
7497
- const renderCard = (f) => {
7519
+ const renderCard = (f, moduleKey) => {
7498
7520
  const sev = f.severity.toLowerCase();
7499
- return `<div class="finding-card sev-${esc(sev)}">
7521
+ return `<div class="finding-card sev-${esc(sev)}" data-severity="${esc(f.severity)}" data-module="${esc(moduleKey)}">
7500
7522
  <span class="badge badge-${esc(sev)}">${esc(f.severity)}</span>
7501
7523
  <span class="finding-title-text">${esc(f.title)}</span>
7502
7524
  <span class="finding-resource">${esc(f.resourceArn || f.resourceId)}</span>
@@ -7507,12 +7529,12 @@ function generateHtmlReport(scanResults, history, lang) {
7507
7529
  </div></details>
7508
7530
  </div>`;
7509
7531
  };
7510
- const renderCards = (findings) => {
7532
+ const renderCards = (findings, moduleKey) => {
7511
7533
  if (findings.length <= FOLD_THRESHOLD) {
7512
- return findings.map(renderCard).join("\n");
7534
+ return findings.map((f) => renderCard(f, moduleKey)).join("\n");
7513
7535
  }
7514
- const first = findings.slice(0, FOLD_THRESHOLD).map(renderCard).join("\n");
7515
- const rest = findings.slice(FOLD_THRESHOLD).map(renderCard).join("\n");
7536
+ const first = findings.slice(0, FOLD_THRESHOLD).map((f) => renderCard(f, moduleKey)).join("\n");
7537
+ const rest = findings.slice(FOLD_THRESHOLD).map((f) => renderCard(f, moduleKey)).join("\n");
7516
7538
  return `${first}
7517
7539
  <details><summary>${t.showRemainingFindings(findings.length - FOLD_THRESHOLD)}</summary>
7518
7540
  ${rest}
@@ -7547,7 +7569,7 @@ ${rest}
7547
7569
  if (aHasCritHigh !== bHasCritHigh) return aHasCritHigh ? -1 : 1;
7548
7570
  return b[1].length - a[1].length;
7549
7571
  });
7550
- const renderSeverityGroups = (findings) => {
7572
+ const renderSeverityGroups = (findings, moduleKey) => {
7551
7573
  return SEVERITY_ORDER2.map((sev) => {
7552
7574
  const sevFindings = findings.filter((f) => f.severity === sev);
7553
7575
  if (sevFindings.length === 0) return "";
@@ -7556,7 +7578,7 @@ ${rest}
7556
7578
  const label = sev.charAt(0) + sev.slice(1).toLowerCase();
7557
7579
  return `<details class="severity-group-fold">
7558
7580
  <summary><h4>${emoji} ${label} (${sevFindings.length})</h4></summary>
7559
- ${renderCards(sevFindings)}
7581
+ ${renderCards(sevFindings, moduleKey)}
7560
7582
  </details>`;
7561
7583
  }).filter(Boolean).join("\n");
7562
7584
  };
@@ -7568,16 +7590,38 @@ ${rest}
7568
7590
  findingsHtml = moduleEntries.map(([modName, modFindings, subCatLabel]) => {
7569
7591
  const badges = renderModuleBadges(modFindings);
7570
7592
  const displayName = subCatLabel ?? (t.moduleNames[modName] ?? modName);
7571
- return `<details class="module-fold">
7593
+ return `<details class="module-fold" data-module="${esc(modName)}">
7572
7594
  <summary>
7573
7595
  <h3>&#128274; ${esc(displayName)} (${modFindings.length})</h3>
7574
7596
  <span class="module-badges">${badges}</span>
7575
7597
  </summary>
7576
7598
  <div class="module-body">
7577
- ${renderSeverityGroups(modFindings)}
7599
+ ${renderSeverityGroups(modFindings, modName)}
7578
7600
  </div>
7579
7601
  </details>`;
7580
7602
  }).join("\n");
7603
+ const moduleOptions = moduleEntries.map(([modKey, , subCatLabel]) => {
7604
+ const label = subCatLabel ?? (t.moduleNames[modKey] ?? modKey);
7605
+ return `<option value="${esc(modKey)}">${esc(label)}</option>`;
7606
+ }).join("\n ");
7607
+ filterToolbarHtml = `<div class="filter-toolbar" id="filterBar">
7608
+ <div class="filter-group">
7609
+ <span class="filter-label">${esc(t.filterSeverity)}</span>
7610
+ <button class="filter-btn active" data-severity="ALL">${esc(t.filterAll)}</button>
7611
+ <button class="filter-btn" data-severity="CRITICAL">Critical</button>
7612
+ <button class="filter-btn" data-severity="HIGH">High</button>
7613
+ <button class="filter-btn" data-severity="MEDIUM">Medium</button>
7614
+ <button class="filter-btn" data-severity="LOW">Low</button>
7615
+ </div>
7616
+ <div class="filter-group">
7617
+ <span class="filter-label">${esc(t.filterModule)}</span>
7618
+ <select class="filter-select" id="moduleFilter">
7619
+ <option value="ALL">${esc(t.filterAllModules)}</option>
7620
+ ${moduleOptions}
7621
+ </select>
7622
+ </div>
7623
+ <div class="filter-count" id="filterCount" data-tpl="${esc(t.filterCountTpl)}"></div>
7624
+ </div>`;
7581
7625
  }
7582
7626
  let trendHtml = "";
7583
7627
  if (history && history.length >= 2) {
@@ -7733,6 +7777,43 @@ ${remaining.map(renderRec).join("\n")}
7733
7777
  </div>
7734
7778
  </details>`;
7735
7779
  }
7780
+ const filterScript = summary.totalFindings > 0 ? `<script>
7781
+ (function(){
7782
+ var activeSev='ALL',activeMod='ALL';
7783
+ var countEl=document.getElementById('filterCount');
7784
+ var tpl=countEl?countEl.getAttribute('data-tpl'):'';
7785
+ function apply(){
7786
+ var cards=document.querySelectorAll('.finding-card[data-severity]');
7787
+ var shown=0,total=cards.length;
7788
+ cards.forEach(function(c){
7789
+ var sevOk=activeSev==='ALL'||c.getAttribute('data-severity')===activeSev;
7790
+ var modOk=activeMod==='ALL'||c.getAttribute('data-module')===activeMod;
7791
+ c.style.display=(sevOk&&modOk)?'':'none';
7792
+ if(sevOk&&modOk)shown++;
7793
+ });
7794
+ if(countEl)countEl.textContent=tpl.replace('{shown}',shown).replace('{total}',total);
7795
+ document.querySelectorAll('.module-fold').forEach(function(f){
7796
+ var mod=f.getAttribute('data-module');
7797
+ if(activeMod!=='ALL'&&mod!==activeMod){f.style.display='none';return;}
7798
+ f.style.display='';
7799
+ });
7800
+ document.querySelectorAll('.severity-group-fold').forEach(function(g){
7801
+ g.style.display=g.querySelectorAll('.finding-card:not([style*="display: none"])').length?'':'none';
7802
+ });
7803
+ }
7804
+ document.querySelectorAll('.filter-btn[data-severity]').forEach(function(b){
7805
+ b.addEventListener('click',function(){
7806
+ document.querySelectorAll('.filter-btn[data-severity]').forEach(function(x){x.classList.remove('active')});
7807
+ b.classList.add('active');
7808
+ activeSev=b.getAttribute('data-severity');
7809
+ apply();
7810
+ });
7811
+ });
7812
+ var sel=document.getElementById('moduleFilter');
7813
+ if(sel)sel.addEventListener('change',function(){activeMod=sel.value;apply();});
7814
+ apply();
7815
+ })();
7816
+ </script>` : "";
7736
7817
  return `<!DOCTYPE html>
7737
7818
  <html lang="${htmlLang}">
7738
7819
  <head>
@@ -7789,6 +7870,7 @@ ${buildServiceReminderHtml(modules, lang)}
7789
7870
 
7790
7871
  <section>
7791
7872
  <h2>${esc(t.allFindings)}</h2>
7873
+ ${filterToolbarHtml}
7792
7874
  ${findingsHtml}
7793
7875
  </section>
7794
7876
 
@@ -7800,6 +7882,7 @@ ${recsHtml}
7800
7882
  </footer>
7801
7883
 
7802
7884
  </div>
7885
+ ${filterScript}
7803
7886
  </body>
7804
7887
  </html>`;
7805
7888
  }