@aaa-sentinel/mcp-server 0.6.0 → 0.8.0
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 +3 -1
- package/dist/cli.js +129 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,9 +109,11 @@ status as plain JSON.
|
|
|
109
109
|
| `list_cost_anomalies` | `accountId?` | `reports:read` | Business |
|
|
110
110
|
| `get_security_overview` | — | `security:read` | Pro + security add-on |
|
|
111
111
|
| `get_security_score` | `accountId` | `security:read` | Pro + security add-on |
|
|
112
|
-
| `list_security_findings` | `accountId`, `source?` | `security:read` | Pro + security add-on |
|
|
112
|
+
| `list_security_findings` | `accountId`, `source?`, `category?` | `security:read` | Pro + security add-on |
|
|
113
113
|
| `get_security_critical_changes` | `accountId` | `security:read` | Pro + security add-on |
|
|
114
|
+
| `list_security_vulnerabilities` | `accountId` | `security:read` | Pro + security add-on |
|
|
114
115
|
| `get_security_conformance` | `accountId` or `clientId` | `security:read` | Pro + security add-on |
|
|
116
|
+
| `get_security_posture_history` | `accountId` or `clientId`, `days?` | `security:read` | Pro + security add-on |
|
|
115
117
|
| `get_account` | `accountId` | `accounts:read` | Pro |
|
|
116
118
|
| `get_account_monthly_costs` | `accountId` | `accounts:read` | Pro |
|
|
117
119
|
| `get_cost_history` | `accountId` | `reports:read` | Pro |
|
package/dist/cli.js
CHANGED
|
@@ -2800,6 +2800,28 @@ var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
|
|
|
2800
2800
|
return payload;
|
|
2801
2801
|
};
|
|
2802
2802
|
});
|
|
2803
|
+
var $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
|
|
2804
|
+
$ZodType.init(inst, def);
|
|
2805
|
+
const values = new Set(def.values);
|
|
2806
|
+
inst._zod.values = values;
|
|
2807
|
+
defineLazyInternal(inst, "pattern", (zod) => {
|
|
2808
|
+
const vals = zod.def.values;
|
|
2809
|
+
return new RegExp(vals.length ? `^(${vals.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$` : "^[^\\s\\S]$");
|
|
2810
|
+
});
|
|
2811
|
+
inst._zod.parse = (payload, _ctx) => {
|
|
2812
|
+
const input = payload.value;
|
|
2813
|
+
if (values.has(input)) {
|
|
2814
|
+
return payload;
|
|
2815
|
+
}
|
|
2816
|
+
payload.issues.push({
|
|
2817
|
+
code: "invalid_value",
|
|
2818
|
+
values: def.values,
|
|
2819
|
+
input,
|
|
2820
|
+
inst
|
|
2821
|
+
});
|
|
2822
|
+
return payload;
|
|
2823
|
+
};
|
|
2824
|
+
});
|
|
2803
2825
|
var $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) => {
|
|
2804
2826
|
$ZodType.init(inst, def);
|
|
2805
2827
|
inst._zod.optin = "optional";
|
|
@@ -4739,6 +4761,46 @@ var enumProcessor = (schema, _ctx, json, _params) => {
|
|
|
4739
4761
|
json.type = "string";
|
|
4740
4762
|
json.enum = values;
|
|
4741
4763
|
};
|
|
4764
|
+
var literalProcessor = (schema, ctx, json, params) => {
|
|
4765
|
+
const def = schema._zod.def;
|
|
4766
|
+
if (def.values.length === 0) {
|
|
4767
|
+
json.not = {};
|
|
4768
|
+
return;
|
|
4769
|
+
}
|
|
4770
|
+
const vals = [];
|
|
4771
|
+
for (const val of def.values) {
|
|
4772
|
+
if (val === void 0) {
|
|
4773
|
+
if (handleUnrepresentable(schema, ctx, json, params, "Literal `undefined` cannot be represented in JSON Schema"))
|
|
4774
|
+
return;
|
|
4775
|
+
} else if (typeof val === "bigint") {
|
|
4776
|
+
if (handleUnrepresentable(schema, ctx, json, params, "BigInt literals cannot be represented in JSON Schema"))
|
|
4777
|
+
return;
|
|
4778
|
+
vals.push(Number(val));
|
|
4779
|
+
} else {
|
|
4780
|
+
vals.push(val);
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4783
|
+
if (vals.length === 0) {
|
|
4784
|
+
} else if (vals.length === 1) {
|
|
4785
|
+
const val = vals[0];
|
|
4786
|
+
json.type = val === null ? "null" : typeof val;
|
|
4787
|
+
if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") {
|
|
4788
|
+
json.enum = [val];
|
|
4789
|
+
} else {
|
|
4790
|
+
json.const = val;
|
|
4791
|
+
}
|
|
4792
|
+
} else {
|
|
4793
|
+
if (vals.every((v) => typeof v === "number"))
|
|
4794
|
+
json.type = "number";
|
|
4795
|
+
if (vals.every((v) => typeof v === "string"))
|
|
4796
|
+
json.type = "string";
|
|
4797
|
+
if (vals.every((v) => typeof v === "boolean"))
|
|
4798
|
+
json.type = "boolean";
|
|
4799
|
+
if (vals.every((v) => v === null))
|
|
4800
|
+
json.type = "null";
|
|
4801
|
+
json.enum = vals;
|
|
4802
|
+
}
|
|
4803
|
+
};
|
|
4742
4804
|
var customProcessor = (schema, ctx, json, params) => {
|
|
4743
4805
|
handleUnrepresentable(schema, ctx, json, params, "Custom types cannot be represented in JSON Schema");
|
|
4744
4806
|
};
|
|
@@ -5668,6 +5730,27 @@ function _enum(values, params) {
|
|
|
5668
5730
|
...util_exports.normalizeParams(params)
|
|
5669
5731
|
});
|
|
5670
5732
|
}
|
|
5733
|
+
var ZodLiteral = /* @__PURE__ */ $constructor("ZodLiteral", (inst, def) => {
|
|
5734
|
+
$ZodLiteral.init(inst, def);
|
|
5735
|
+
ZodType.init(inst, def);
|
|
5736
|
+
inst._zod.processJSONSchema = (ctx, json, params) => literalProcessor(inst, ctx, json, params);
|
|
5737
|
+
inst.values = new Set(def.values);
|
|
5738
|
+
Object.defineProperty(inst, "value", {
|
|
5739
|
+
get() {
|
|
5740
|
+
if (def.values.length > 1) {
|
|
5741
|
+
throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");
|
|
5742
|
+
}
|
|
5743
|
+
return def.values[0];
|
|
5744
|
+
}
|
|
5745
|
+
});
|
|
5746
|
+
});
|
|
5747
|
+
function literal(value, params) {
|
|
5748
|
+
return new ZodLiteral({
|
|
5749
|
+
type: "literal",
|
|
5750
|
+
values: Array.isArray(value) ? value : [value],
|
|
5751
|
+
...util_exports.normalizeParams(params)
|
|
5752
|
+
});
|
|
5753
|
+
}
|
|
5671
5754
|
var ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
|
|
5672
5755
|
_ensureDefaultMemoizer();
|
|
5673
5756
|
$ZodTransform.init(inst, def);
|
|
@@ -5982,6 +6065,7 @@ function defineTool(def) {
|
|
|
5982
6065
|
}
|
|
5983
6066
|
var SAVINGS_TYPES = ["compute", "storage", "network", "database", "serverless", "governance"];
|
|
5984
6067
|
var SECURITY_SOURCES = ["own", "corroborated", "securityhub", "guardduty", "defender", "scc"];
|
|
6068
|
+
var SECURITY_CATEGORIES = ["security_network", "security_exposure", "security_encryption", "security_iam", "security_logging", "security_secrets"];
|
|
5985
6069
|
var AGENT_STATUSES = ["proposed", "pending_approval", "pending_second_approval", "approved", "executing", "completed", "failed", "cancelled", "expired"];
|
|
5986
6070
|
var BillingPeriod = string2().regex(/^\d{4}-(0[1-9]|1[0-2])$/, "Use YYYY-MM");
|
|
5987
6071
|
var ACCOUNT_ID = { type: "string", description: "Account identifier, as returned by list_accounts." };
|
|
@@ -6138,7 +6222,7 @@ var TOOLS = [
|
|
|
6138
6222
|
}),
|
|
6139
6223
|
defineTool({
|
|
6140
6224
|
name: "list_security_findings",
|
|
6141
|
-
description:
|
|
6225
|
+
description: 'List the security findings of the latest security scan of one account (up to 500, most severe first), with attack chains and a diff against the previous scan. Use category "security_iam" for the permissions view: effective administrators, unused identities, keys and service accounts, granted permissions that are not used, and assignments to deleted identities. Requires the security:read scope, the Pro plan and the security add-on on that account.',
|
|
6142
6226
|
inputSchema: {
|
|
6143
6227
|
type: "object",
|
|
6144
6228
|
properties: {
|
|
@@ -6147,16 +6231,25 @@ var TOOLS = [
|
|
|
6147
6231
|
type: "string",
|
|
6148
6232
|
enum: [...SECURITY_SOURCES],
|
|
6149
6233
|
description: "Filter by origin: own rules, corroborated, or a native tool (optional)."
|
|
6234
|
+
},
|
|
6235
|
+
category: {
|
|
6236
|
+
type: "string",
|
|
6237
|
+
enum: [...SECURITY_CATEGORIES],
|
|
6238
|
+
description: 'Filter by rule category (optional); "security_iam" is the permissions view.'
|
|
6150
6239
|
}
|
|
6151
6240
|
},
|
|
6152
6241
|
required: ["accountId"]
|
|
6153
6242
|
},
|
|
6154
|
-
argsSchema: object({
|
|
6155
|
-
|
|
6243
|
+
argsSchema: object({
|
|
6244
|
+
accountId: string2().min(1),
|
|
6245
|
+
source: _enum(SECURITY_SOURCES).optional(),
|
|
6246
|
+
category: _enum(SECURITY_CATEGORIES).optional()
|
|
6247
|
+
}),
|
|
6248
|
+
handler: async ({ accountId, source, category }, config2) => apiGet("/v1/security/findings", { accountId, source, category }, config2)
|
|
6156
6249
|
}),
|
|
6157
6250
|
defineTool({
|
|
6158
6251
|
name: "get_security_critical_changes",
|
|
6159
|
-
description: "List the critical configuration changes of the last 7 days in one
|
|
6252
|
+
description: "List the critical configuration changes of the last 7 days in one account (up to 100, newest first), read from CloudTrail in AWS, the activity log in Azure or the Admin Activity audit logs in GCP: public bucket, storage or snapshot, remote admin open to the internet, logging turned off, root use, admin granted. Each comes with who made it and, for rule-backed changes, whether a re-check confirmed the risk. Accounts without the security add-on return supported false and an empty list. Requires the security:read scope and the Pro plan or above.",
|
|
6160
6253
|
inputSchema: {
|
|
6161
6254
|
type: "object",
|
|
6162
6255
|
properties: { accountId: { type: "string", description: "Account identifier, as returned by list_accounts." } },
|
|
@@ -6165,6 +6258,17 @@ var TOOLS = [
|
|
|
6165
6258
|
argsSchema: object({ accountId: string2().min(1) }),
|
|
6166
6259
|
handler: async ({ accountId }, config2) => apiGet("/v1/security/critical-changes", { accountId }, config2)
|
|
6167
6260
|
}),
|
|
6261
|
+
defineTool({
|
|
6262
|
+
name: "list_security_vulnerabilities",
|
|
6263
|
+
description: "List the vulnerabilities (CVEs) that the cloud native scanner already found in one account (Amazon Inspector or ECR basic scanning, Microsoft Defender for Cloud, GCP Artifact Analysis and VM Manager), up to 200, highest priority first. Each one has the cloud severity and an effective severity that rises when the resource is exposed to the internet, has a known exploit or is unused according to a cost rule (low CPU is shown as context only). AAA Sentinel does not scan on its own: tools shows whether each scanner is active, absent or could not be read, truncated whether the cloud has more than the cap, and partial why the list may be incomplete (scanner missing in some regions or resource types listed in uncovered, failed reads, time budget, unreadable entries, expired rows). Amazon Inspector only sees image use on ECS and EKS: when the account has container Lambdas, App Runner services or images not in use there, uncovered.gaps says ecr_images_outside_ecs_eks and those images come last with imageInUse false. An account without the security add-on returns access teaser and an empty list, which does not mean it has no vulnerabilities. bySeverity counts the effective severity. Requires the security:read scope and the Pro plan or above.",
|
|
6264
|
+
inputSchema: {
|
|
6265
|
+
type: "object",
|
|
6266
|
+
properties: { accountId: { type: "string", description: "Account identifier, as returned by list_accounts." } },
|
|
6267
|
+
required: ["accountId"]
|
|
6268
|
+
},
|
|
6269
|
+
argsSchema: object({ accountId: string2().min(1) }),
|
|
6270
|
+
handler: async ({ accountId }, config2) => apiGet("/v1/security/vulnerabilities", { accountId }, config2)
|
|
6271
|
+
}),
|
|
6168
6272
|
defineTool({
|
|
6169
6273
|
name: "get_security_conformance",
|
|
6170
6274
|
description: "Get CIS benchmark coverage for one account, or for every account of a managed client (clientId, Business plan). Pass exactly one of accountId or clientId. Requires the security:read scope, plus reports:read when using clientId.",
|
|
@@ -6180,6 +6284,26 @@ var TOOLS = [
|
|
|
6180
6284
|
}),
|
|
6181
6285
|
handler: async ({ accountId, clientId: clientId2 }, config2) => apiGet("/v1/security/conformance", { accountId, clientId: clientId2 }, config2)
|
|
6182
6286
|
}),
|
|
6287
|
+
defineTool({
|
|
6288
|
+
name: "get_security_posture_history",
|
|
6289
|
+
description: "Get how the security posture changed over 30, 90 or 365 days (default 90) for one account, or for every account with the security add-on of a managed client (clientId, Business plan, up to 20 accounts; omitted counts the rest). Returns points, one per UTC day (the last scan of that day: score, scored/total rules, open findings by severity, events), and summary: from/to (Score of the first and last point), resolved (distinct findings gone in a scan that fully evaluated their rule), opened (new, from rules already fully evaluated before), surfaced (new but not comparable: rule not fully evaluated before, or an external tool), unverified (gone without confirmation), meanFixDays by severity, comparable and notComparableReasons. When comparable is false, do not describe the Score change as the account getting better or worse. Points keep the Score computed each day, without discounting risks accepted later (acceptedRisks). Pass exactly one of accountId or clientId. Requires the security:read scope, plus reports:read when using clientId.",
|
|
6290
|
+
inputSchema: {
|
|
6291
|
+
type: "object",
|
|
6292
|
+
properties: {
|
|
6293
|
+
accountId: { type: "string", description: "Account identifier (use this or clientId)." },
|
|
6294
|
+
clientId: { type: "string", description: "Managed client identifier (use this or accountId)." },
|
|
6295
|
+
days: { type: "number", enum: [30, 90, 365], description: "Period in days (optional, default 90)." }
|
|
6296
|
+
}
|
|
6297
|
+
},
|
|
6298
|
+
argsSchema: object({
|
|
6299
|
+
accountId: string2().min(1).optional(),
|
|
6300
|
+
clientId: string2().min(1).optional(),
|
|
6301
|
+
days: union([literal(30), literal(90), literal(365)]).optional()
|
|
6302
|
+
}).refine((a) => Boolean(a.accountId) !== Boolean(a.clientId), {
|
|
6303
|
+
message: "Pass exactly one of accountId or clientId"
|
|
6304
|
+
}),
|
|
6305
|
+
handler: async ({ accountId, clientId: clientId2, days }, config2) => apiGet("/v1/security/posture-history", { accountId, clientId: clientId2, days: days === void 0 ? void 0 : String(days) }, config2)
|
|
6306
|
+
}),
|
|
6183
6307
|
// ── Cuentas y costes ───────────────────────────────────────
|
|
6184
6308
|
defineTool({
|
|
6185
6309
|
name: "get_account",
|
|
@@ -6516,7 +6640,7 @@ function findTool(name) {
|
|
|
6516
6640
|
|
|
6517
6641
|
// src/protocol.ts
|
|
6518
6642
|
var SERVER_NAME = "aaa-sentinel-mcp";
|
|
6519
|
-
var SERVER_VERSION = "0.
|
|
6643
|
+
var SERVER_VERSION = "0.8.0";
|
|
6520
6644
|
var SUPPORTED_PROTOCOL_VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
|
|
6521
6645
|
var PARSE_ERROR = -32700;
|
|
6522
6646
|
var INVALID_REQUEST = -32600;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aaa-sentinel/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Read-only MCP server for AAA Sentinel: query cloud costs, savings, security posture, AI spend, uptime monitoring, the remediation agent and managed clients from an AI assistant",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|