cloudvault-mcp 1.0.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/dist/adapters/aws.d.ts +42 -0
  4. package/dist/adapters/aws.d.ts.map +1 -0
  5. package/dist/adapters/aws.js +318 -0
  6. package/dist/adapters/aws.js.map +1 -0
  7. package/dist/adapters/types.d.ts +22 -0
  8. package/dist/adapters/types.d.ts.map +1 -0
  9. package/dist/adapters/types.js +2 -0
  10. package/dist/adapters/types.js.map +1 -0
  11. package/dist/index.d.ts +7 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +51 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/audit.d.ts +57 -0
  16. package/dist/lib/audit.d.ts.map +1 -0
  17. package/dist/lib/audit.js +136 -0
  18. package/dist/lib/audit.js.map +1 -0
  19. package/dist/lib/cost-estimates.d.ts +16 -0
  20. package/dist/lib/cost-estimates.d.ts.map +1 -0
  21. package/dist/lib/cost-estimates.js +101 -0
  22. package/dist/lib/cost-estimates.js.map +1 -0
  23. package/dist/lib/fetch-retry.d.ts +7 -0
  24. package/dist/lib/fetch-retry.d.ts.map +1 -0
  25. package/dist/lib/fetch-retry.js +35 -0
  26. package/dist/lib/fetch-retry.js.map +1 -0
  27. package/dist/lib/providers.d.ts +7 -0
  28. package/dist/lib/providers.d.ts.map +1 -0
  29. package/dist/lib/providers.js +37 -0
  30. package/dist/lib/providers.js.map +1 -0
  31. package/dist/premium/gate.d.ts +18 -0
  32. package/dist/premium/gate.d.ts.map +1 -0
  33. package/dist/premium/gate.js +27 -0
  34. package/dist/premium/gate.js.map +1 -0
  35. package/dist/tools/get_secrets.d.ts +16 -0
  36. package/dist/tools/get_secrets.d.ts.map +1 -0
  37. package/dist/tools/get_secrets.js +52 -0
  38. package/dist/tools/get_secrets.js.map +1 -0
  39. package/dist/tools/list_databases.d.ts +16 -0
  40. package/dist/tools/list_databases.d.ts.map +1 -0
  41. package/dist/tools/list_databases.js +42 -0
  42. package/dist/tools/list_databases.js.map +1 -0
  43. package/dist/tools/list_instances.d.ts +17 -0
  44. package/dist/tools/list_instances.d.ts.map +1 -0
  45. package/dist/tools/list_instances.js +43 -0
  46. package/dist/tools/list_instances.js.map +1 -0
  47. package/dist/tools/list_storage.d.ts +15 -0
  48. package/dist/tools/list_storage.d.ts.map +1 -0
  49. package/dist/tools/list_storage.js +40 -0
  50. package/dist/tools/list_storage.js.map +1 -0
  51. package/dist/types.d.ts +143 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +50 -0
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CloudVault MCP — Cloud infrastructure analysis server.
4
+ * Phase 1: AWS inventory — compute, databases, storage, secrets.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CloudVault MCP — Cloud infrastructure analysis server.
4
+ * Phase 1: AWS inventory — compute, databases, storage, secrets.
5
+ */
6
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
+ import { z } from 'zod';
9
+ import { list_instances } from './tools/list_instances.js';
10
+ import { list_databases } from './tools/list_databases.js';
11
+ import { list_storage } from './tools/list_storage.js';
12
+ import { get_secrets } from './tools/get_secrets.js';
13
+ const server = new McpServer({
14
+ name: 'cloudvault-mcp',
15
+ version: '1.0.0',
16
+ });
17
+ // list_instances
18
+ server.tool('list_instances', 'List compute instances with state, type, IP, region, and cost estimate.', {
19
+ provider: z.enum(['aws', 'gcp', 'azure']).describe('Cloud provider'),
20
+ region: z.string().optional().describe('Filter by region (e.g., us-east-1)'),
21
+ state: z.enum(['running', 'stopped', 'terminated', 'pending']).optional().describe('Filter by instance state'),
22
+ tags: z.record(z.string()).optional().describe('Filter by tag key/value pairs'),
23
+ }, async (input) => {
24
+ return list_instances(input);
25
+ });
26
+ // list_databases
27
+ server.tool('list_databases', 'List managed databases with engine, version, storage size, and backup status.', {
28
+ provider: z.enum(['aws', 'gcp', 'azure']).describe('Cloud provider'),
29
+ region: z.string().optional().describe('Filter by region'),
30
+ engine: z.string().optional().describe('Filter by database engine (e.g., postgres, mysql)'),
31
+ }, async (input) => {
32
+ return list_databases(input);
33
+ });
34
+ // list_storage
35
+ server.tool('list_storage', 'List storage buckets/containers with public access status and encryption info.', {
36
+ provider: z.enum(['aws', 'gcp', 'azure']).describe('Cloud provider'),
37
+ region: z.string().optional().describe('Filter by region'),
38
+ }, async (input) => {
39
+ return list_storage(input);
40
+ });
41
+ // get_secrets
42
+ server.tool('get_secrets', 'List secret names and metadata. SECURITY: Secret values are NEVER returned.', {
43
+ provider: z.enum(['aws', 'gcp', 'azure']).describe('Cloud provider'),
44
+ prefix: z.string().optional().describe('Filter secrets by name prefix (e.g., prod/)'),
45
+ }, async (input) => {
46
+ return get_secrets(input);
47
+ });
48
+ // Start server
49
+ const transport = new StdioServerTransport();
50
+ await server.connect(transport);
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Audit trail module — SQLite-backed logging of all CloudVault tool calls.
3
+ * Stores to ~/.cloudvault/audit.db by default.
4
+ * 90-day retention with automatic cleanup on init.
5
+ */
6
+ export interface AuditLogEntry {
7
+ tool_name: string;
8
+ input_summary: string;
9
+ result_summary: string;
10
+ success: boolean;
11
+ duration_ms?: number;
12
+ }
13
+ export interface AuditRow {
14
+ id: number;
15
+ created_at: string;
16
+ tool_name: string;
17
+ input_summary: string;
18
+ result_summary: string;
19
+ success: number;
20
+ duration_ms: number | null;
21
+ }
22
+ export interface AuditQueryOptions {
23
+ timeframe?: '1d' | '7d' | '30d';
24
+ tool_name?: string;
25
+ limit?: number;
26
+ }
27
+ /**
28
+ * Return the shared AuditLog singleton, creating it on first call (lazy init).
29
+ * Callers should use this instead of `new AuditLog()` to avoid opening a new
30
+ * SQLite connection per tool invocation.
31
+ */
32
+ export declare function getAuditLog(): AuditLog;
33
+ /**
34
+ * Reset the singleton — intended for test isolation only.
35
+ * Closes the existing connection (if any) and clears the cached instance.
36
+ */
37
+ export declare function resetAuditLogSingleton(): void;
38
+ export declare class AuditLog {
39
+ private readonly db;
40
+ constructor(dbPath?: string);
41
+ private defaultPath;
42
+ private init;
43
+ /**
44
+ * Sanitize input record — redact any values whose key looks like a secret.
45
+ * Values are truncated to 200 chars to keep audit.db small.
46
+ */
47
+ sanitize(input: Record<string, unknown>): string;
48
+ log(entry: AuditLogEntry): void;
49
+ query(opts?: AuditQueryOptions): AuditRow[];
50
+ /**
51
+ * Close the underlying SQLite connection.
52
+ * NOTE: Do not call this on the singleton returned by getAuditLog() — it will
53
+ * break subsequent log writes. This method is retained for test isolation only.
54
+ */
55
+ close(): void;
56
+ }
57
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/lib/audit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgBD;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAKtC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAS7C;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;gBAE3B,MAAM,CAAC,EAAE,MAAM;IAM3B,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,IAAI;IAsBZ;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAehD,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAe/B,KAAK,CAAC,IAAI,GAAE,iBAAsB,GAAG,QAAQ,EAAE;IA6B/C;;;;OAIG;IACH,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Audit trail module — SQLite-backed logging of all CloudVault tool calls.
3
+ * Stores to ~/.cloudvault/audit.db by default.
4
+ * 90-day retention with automatic cleanup on init.
5
+ */
6
+ import Database from 'better-sqlite3';
7
+ import { homedir } from 'os';
8
+ import { mkdirSync } from 'fs';
9
+ import { join } from 'path';
10
+ // Sensitive key patterns to redact from input summaries
11
+ const SENSITIVE_PATTERNS = [
12
+ /token/i,
13
+ /password/i,
14
+ /secret/i,
15
+ /api_key/i,
16
+ /auth/i,
17
+ /credential/i,
18
+ /private/i,
19
+ ];
20
+ // Module-level singleton — opened once, reused across all tool calls.
21
+ let _instance = null;
22
+ /**
23
+ * Return the shared AuditLog singleton, creating it on first call (lazy init).
24
+ * Callers should use this instead of `new AuditLog()` to avoid opening a new
25
+ * SQLite connection per tool invocation.
26
+ */
27
+ export function getAuditLog() {
28
+ if (!_instance) {
29
+ _instance = new AuditLog();
30
+ }
31
+ return _instance;
32
+ }
33
+ /**
34
+ * Reset the singleton — intended for test isolation only.
35
+ * Closes the existing connection (if any) and clears the cached instance.
36
+ */
37
+ export function resetAuditLogSingleton() {
38
+ if (_instance) {
39
+ try {
40
+ _instance.close();
41
+ }
42
+ catch {
43
+ // Ignore close errors during test teardown
44
+ }
45
+ _instance = null;
46
+ }
47
+ }
48
+ export class AuditLog {
49
+ db;
50
+ constructor(dbPath) {
51
+ const path = dbPath ?? this.defaultPath();
52
+ this.db = new Database(path);
53
+ this.init();
54
+ }
55
+ defaultPath() {
56
+ const dir = join(homedir(), '.cloudvault');
57
+ mkdirSync(dir, { recursive: true });
58
+ return join(dir, 'audit.db');
59
+ }
60
+ init() {
61
+ this.db.exec(`
62
+ CREATE TABLE IF NOT EXISTS audit_log (
63
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
64
+ created_at TEXT DEFAULT (datetime('now')),
65
+ tool_name TEXT NOT NULL,
66
+ input_summary TEXT NOT NULL DEFAULT '',
67
+ result_summary TEXT NOT NULL DEFAULT '',
68
+ success INTEGER DEFAULT 1,
69
+ duration_ms INTEGER
70
+ );
71
+
72
+ CREATE INDEX IF NOT EXISTS idx_audit_created_at ON audit_log(created_at);
73
+ CREATE INDEX IF NOT EXISTS idx_audit_tool ON audit_log(tool_name);
74
+ `);
75
+ // 90-day cleanup on init
76
+ this.db.exec("DELETE FROM audit_log WHERE created_at < datetime('now', '-90 days')");
77
+ }
78
+ /**
79
+ * Sanitize input record — redact any values whose key looks like a secret.
80
+ * Values are truncated to 200 chars to keep audit.db small.
81
+ */
82
+ sanitize(input) {
83
+ const sanitized = {};
84
+ for (const [key, value] of Object.entries(input)) {
85
+ const isSensitive = SENSITIVE_PATTERNS.some((p) => p.test(key));
86
+ if (isSensitive) {
87
+ sanitized[key] = '[REDACTED]';
88
+ }
89
+ else if (typeof value === 'string' && value.length > 200) {
90
+ sanitized[key] = value.substring(0, 200) + '…';
91
+ }
92
+ else {
93
+ sanitized[key] = value;
94
+ }
95
+ }
96
+ return JSON.stringify(sanitized);
97
+ }
98
+ log(entry) {
99
+ const stmt = this.db.prepare(`
100
+ INSERT INTO audit_log (tool_name, input_summary, result_summary, success, duration_ms)
101
+ VALUES (?, ?, ?, ?, ?)
102
+ `);
103
+ stmt.run(entry.tool_name, entry.input_summary, entry.result_summary?.substring(0, 500) ?? '', entry.success ? 1 : 0, entry.duration_ms ?? null);
104
+ }
105
+ query(opts = {}) {
106
+ const conditions = [];
107
+ const params = [];
108
+ if (opts.timeframe) {
109
+ const days = opts.timeframe === '1d' ? 1 : opts.timeframe === '7d' ? 7 : 30;
110
+ conditions.push(`created_at >= datetime('now', '-${days} days')`);
111
+ }
112
+ if (opts.tool_name) {
113
+ conditions.push('tool_name = ?');
114
+ params.push(opts.tool_name);
115
+ }
116
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
117
+ const limit = opts.limit ?? 50;
118
+ const sql = `
119
+ SELECT id, created_at, tool_name, input_summary, result_summary, success, duration_ms
120
+ FROM audit_log
121
+ ${where}
122
+ ORDER BY created_at DESC
123
+ LIMIT ?
124
+ `;
125
+ return this.db.prepare(sql).all(...params, limit);
126
+ }
127
+ /**
128
+ * Close the underlying SQLite connection.
129
+ * NOTE: Do not call this on the singleton returned by getAuditLog() — it will
130
+ * break subsequent log writes. This method is retained for test isolation only.
131
+ */
132
+ close() {
133
+ this.db.close();
134
+ }
135
+ }
136
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/lib/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Static monthly cost estimates for common AWS EC2 instance types.
3
+ * Values are approximate on-demand prices in USD cents (us-east-1).
4
+ * These are estimates only — actual costs vary by region, OS, and usage.
5
+ */
6
+ /**
7
+ * Get the estimated monthly cost in USD cents for a given EC2 instance type.
8
+ * Returns undefined if the instance type is not in the lookup table.
9
+ */
10
+ export declare function getInstanceCostEstimate(instanceType: string): number | undefined;
11
+ /**
12
+ * Get a human-readable cost estimate string (e.g., "~$8/mo").
13
+ * Returns "unknown" if the type is not in the table.
14
+ */
15
+ export declare function formatCostEstimate(instanceType: string): string;
16
+ //# sourceMappingURL=cost-estimates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-estimates.d.ts","sourceRoot":"","sources":["../../src/lib/cost-estimates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0FH;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEhF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAK/D"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Static monthly cost estimates for common AWS EC2 instance types.
3
+ * Values are approximate on-demand prices in USD cents (us-east-1).
4
+ * These are estimates only — actual costs vary by region, OS, and usage.
5
+ */
6
+ // Monthly cost in USD cents (approximate on-demand, us-east-1, Linux)
7
+ const COST_TABLE = {
8
+ // t3 family
9
+ 't3.nano': 475, // ~$4.75/mo
10
+ 't3.micro': 834, // ~$8.34/mo
11
+ 't3.small': 1670, // ~$16.70/mo
12
+ 't3.medium': 3341, // ~$33.41/mo
13
+ 't3.large': 6682, // ~$66.82/mo
14
+ 't3.xlarge': 13363, // ~$133.63/mo
15
+ 't3.2xlarge': 26726, // ~$267.26/mo
16
+ // t3a family
17
+ 't3a.nano': 428,
18
+ 't3a.micro': 752,
19
+ 't3a.small': 1505,
20
+ 't3a.medium': 3010,
21
+ 't3a.large': 6019,
22
+ 't3a.xlarge': 12038,
23
+ // t2 family
24
+ 't2.nano': 517,
25
+ 't2.micro': 1168,
26
+ 't2.small': 2336,
27
+ 't2.medium': 4672,
28
+ 't2.large': 9344,
29
+ 't2.xlarge': 18688,
30
+ 't2.2xlarge': 37376,
31
+ // m5 family
32
+ 'm5.large': 7008, // ~$70.08/mo
33
+ 'm5.xlarge': 14016,
34
+ 'm5.2xlarge': 28032,
35
+ 'm5.4xlarge': 56064,
36
+ 'm5.8xlarge': 112128,
37
+ 'm5.12xlarge': 168192,
38
+ 'm5.16xlarge': 224256,
39
+ 'm5.24xlarge': 336384,
40
+ // m6i family
41
+ 'm6i.large': 7344,
42
+ 'm6i.xlarge': 14688,
43
+ 'm6i.2xlarge': 29376,
44
+ 'm6i.4xlarge': 58752,
45
+ // c5 family
46
+ 'c5.large': 6197,
47
+ 'c5.xlarge': 12395,
48
+ 'c5.2xlarge': 24789,
49
+ 'c5.4xlarge': 49579,
50
+ 'c5.9xlarge': 111553,
51
+ 'c5.12xlarge': 148737,
52
+ 'c5.18xlarge': 223106,
53
+ 'c5.24xlarge': 297474,
54
+ // c6i family
55
+ 'c6i.large': 6140,
56
+ 'c6i.xlarge': 12279,
57
+ 'c6i.2xlarge': 24558,
58
+ 'c6i.4xlarge': 49117,
59
+ // r5 family
60
+ 'r5.large': 10079,
61
+ 'r5.xlarge': 20158,
62
+ 'r5.2xlarge': 40315,
63
+ 'r5.4xlarge': 80630,
64
+ 'r5.8xlarge': 161261,
65
+ 'r5.12xlarge': 241891,
66
+ 'r5.16xlarge': 322522,
67
+ 'r5.24xlarge': 483782,
68
+ // r6i family
69
+ 'r6i.large': 10548,
70
+ 'r6i.xlarge': 21096,
71
+ 'r6i.2xlarge': 42192,
72
+ 'r6i.4xlarge': 84384,
73
+ // p3 family (GPU)
74
+ 'p3.2xlarge': 306340,
75
+ 'p3.8xlarge': 1225360,
76
+ 'p3.16xlarge': 2450720,
77
+ // g4dn family (GPU)
78
+ 'g4dn.xlarge': 52631,
79
+ 'g4dn.2xlarge': 75209,
80
+ 'g4dn.4xlarge': 136314,
81
+ 'g4dn.8xlarge': 225657,
82
+ };
83
+ /**
84
+ * Get the estimated monthly cost in USD cents for a given EC2 instance type.
85
+ * Returns undefined if the instance type is not in the lookup table.
86
+ */
87
+ export function getInstanceCostEstimate(instanceType) {
88
+ return COST_TABLE[instanceType];
89
+ }
90
+ /**
91
+ * Get a human-readable cost estimate string (e.g., "~$8/mo").
92
+ * Returns "unknown" if the type is not in the table.
93
+ */
94
+ export function formatCostEstimate(instanceType) {
95
+ const cents = COST_TABLE[instanceType];
96
+ if (cents === undefined)
97
+ return 'unknown';
98
+ const dollars = Math.round(cents / 100);
99
+ return `~$${dollars}/mo`;
100
+ }
101
+ //# sourceMappingURL=cost-estimates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-estimates.js","sourceRoot":"","sources":["../../src/lib/cost-estimates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sEAAsE;AACtE,MAAM,UAAU,GAA2B;IACzC,YAAY;IACZ,SAAS,EAAK,GAAG,EAAK,YAAY;IAClC,UAAU,EAAI,GAAG,EAAK,YAAY;IAClC,UAAU,EAAI,IAAI,EAAI,aAAa;IACnC,WAAW,EAAG,IAAI,EAAI,aAAa;IACnC,UAAU,EAAI,IAAI,EAAI,aAAa;IACnC,WAAW,EAAG,KAAK,EAAG,cAAc;IACpC,YAAY,EAAE,KAAK,EAAG,cAAc;IAEpC,aAAa;IACb,UAAU,EAAI,GAAG;IACjB,WAAW,EAAG,GAAG;IACjB,WAAW,EAAG,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,WAAW,EAAG,IAAI;IAClB,YAAY,EAAE,KAAK;IAEnB,YAAY;IACZ,SAAS,EAAK,GAAG;IACjB,UAAU,EAAI,IAAI;IAClB,UAAU,EAAI,IAAI;IAClB,WAAW,EAAG,IAAI;IAClB,UAAU,EAAI,IAAI;IAClB,WAAW,EAAG,KAAK;IACnB,YAAY,EAAE,KAAK;IAEnB,YAAY;IACZ,UAAU,EAAK,IAAI,EAAI,aAAa;IACpC,WAAW,EAAI,KAAK;IACpB,YAAY,EAAG,KAAK;IACpB,YAAY,EAAG,KAAK;IACpB,YAAY,EAAG,MAAM;IACrB,aAAa,EAAE,MAAM;IACrB,aAAa,EAAE,MAAM;IACrB,aAAa,EAAE,MAAM;IAErB,aAAa;IACb,WAAW,EAAK,IAAI;IACpB,YAAY,EAAI,KAAK;IACrB,aAAa,EAAG,KAAK;IACrB,aAAa,EAAG,KAAK;IAErB,YAAY;IACZ,UAAU,EAAK,IAAI;IACnB,WAAW,EAAI,KAAK;IACpB,YAAY,EAAG,KAAK;IACpB,YAAY,EAAG,KAAK;IACpB,YAAY,EAAG,MAAM;IACrB,aAAa,EAAE,MAAM;IACrB,aAAa,EAAE,MAAM;IACrB,aAAa,EAAE,MAAM;IAErB,aAAa;IACb,WAAW,EAAK,IAAI;IACpB,YAAY,EAAI,KAAK;IACrB,aAAa,EAAG,KAAK;IACrB,aAAa,EAAG,KAAK;IAErB,YAAY;IACZ,UAAU,EAAK,KAAK;IACpB,WAAW,EAAI,KAAK;IACpB,YAAY,EAAG,KAAK;IACpB,YAAY,EAAG,KAAK;IACpB,YAAY,EAAG,MAAM;IACrB,aAAa,EAAE,MAAM;IACrB,aAAa,EAAE,MAAM;IACrB,aAAa,EAAE,MAAM;IAErB,aAAa;IACb,WAAW,EAAK,KAAK;IACrB,YAAY,EAAI,KAAK;IACrB,aAAa,EAAG,KAAK;IACrB,aAAa,EAAG,KAAK;IAErB,kBAAkB;IAClB,YAAY,EAAI,MAAM;IACtB,YAAY,EAAI,OAAO;IACvB,aAAa,EAAG,OAAO;IAEvB,oBAAoB;IACpB,aAAa,EAAG,KAAK;IACrB,cAAc,EAAE,KAAK;IACrB,cAAc,EAAE,MAAM;IACtB,cAAc,EAAE,MAAM;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,YAAoB;IAC1D,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACrD,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;IACxC,OAAO,KAAK,OAAO,KAAK,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * fetchWithRetry — retries on 429 (rate limit) and 5xx (server errors).
3
+ * Uses Retry-After header when present, otherwise exponential backoff.
4
+ * Max 3 retries by default.
5
+ */
6
+ export declare function fetchWithRetry(url: string | URL, init?: RequestInit, maxRetries?: number): Promise<Response>;
7
+ //# sourceMappingURL=fetch-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-retry.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,CAAC,EAAE,WAAW,EAClB,UAAU,SAAI,GACb,OAAO,CAAC,QAAQ,CAAC,CA+BnB"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * fetchWithRetry — retries on 429 (rate limit) and 5xx (server errors).
3
+ * Uses Retry-After header when present, otherwise exponential backoff.
4
+ * Max 3 retries by default.
5
+ */
6
+ export async function fetchWithRetry(url, init, maxRetries = 3) {
7
+ let lastError = null;
8
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
9
+ try {
10
+ const res = await fetch(url, init);
11
+ if (res.status === 429) {
12
+ if (attempt >= maxRetries)
13
+ return res;
14
+ const retryAfter = parseInt(res.headers.get('Retry-After') ?? '', 10);
15
+ const waitMs = (retryAfter > 0 ? retryAfter * 1000 : 2000) * Math.pow(2, attempt);
16
+ await new Promise(r => setTimeout(r, waitMs));
17
+ continue;
18
+ }
19
+ if (res.status >= 500 && attempt < maxRetries) {
20
+ await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
21
+ continue;
22
+ }
23
+ return res;
24
+ }
25
+ catch (err) {
26
+ lastError = err instanceof Error ? err : new Error(String(err));
27
+ if (attempt < maxRetries) {
28
+ await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
29
+ continue;
30
+ }
31
+ }
32
+ }
33
+ throw lastError ?? new Error('fetchWithRetry: max retries exceeded');
34
+ }
35
+ //# sourceMappingURL=fetch-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-retry.js","sourceRoot":"","sources":["../../src/lib/fetch-retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAiB,EACjB,IAAkB,EAClB,UAAU,GAAG,CAAC;IAEd,IAAI,SAAS,GAAiB,IAAI,CAAC;IAEnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAEnC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,IAAI,OAAO,IAAI,UAAU;oBAAE,OAAO,GAAG,CAAC;gBACtC,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gBACtE,MAAM,MAAM,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;gBAClF,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;gBAC9C,SAAS;YACX,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBAC9C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;gBACnE,SAAS;YACX,CAAC;YAED,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAChE,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBACzB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;gBACnE,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { CloudProvider } from '../adapters/types.js';
2
+ export type ProviderName = 'aws' | 'gcp' | 'azure';
3
+ export declare function getProvider(name: ProviderName): CloudProvider;
4
+ export declare function getProviders(names: ProviderName[]): CloudProvider[];
5
+ /** Clear the cache — useful for testing. */
6
+ export declare function clearProviderCache(): void;
7
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/lib/providers.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;AAEnD,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAkB7D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAEnE;AAED,4CAA4C;AAC5C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Cached provider factory.
3
+ * Adapters are created once and reused across calls to avoid
4
+ * repeated credential validation and multiple client instances.
5
+ *
6
+ * Phase 1: aws only
7
+ * Phase 2: + gcp
8
+ * Phase 3: + azure
9
+ */
10
+ import { AwsAdapter } from '../adapters/aws.js';
11
+ const cache = new Map();
12
+ export function getProvider(name) {
13
+ if (cache.has(name))
14
+ return cache.get(name);
15
+ let adapter;
16
+ switch (name) {
17
+ case 'aws':
18
+ adapter = new AwsAdapter();
19
+ break;
20
+ case 'gcp':
21
+ throw new Error('Unknown provider: gcp. Supported: aws');
22
+ case 'azure':
23
+ throw new Error('Unknown provider: azure. Supported: aws');
24
+ default:
25
+ throw new Error(`Unknown provider: ${name}. Supported: aws`);
26
+ }
27
+ cache.set(name, adapter);
28
+ return adapter;
29
+ }
30
+ export function getProviders(names) {
31
+ return names.map((n) => getProvider(n));
32
+ }
33
+ /** Clear the cache — useful for testing. */
34
+ export function clearProviderCache() {
35
+ cache.clear();
36
+ }
37
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/lib/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;AAI/C,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;IAE7C,IAAI,OAAsB,CAAC;IAC3B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,OAAO,GAAG,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,KAAK,OAAO;YACV,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC7D;YACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAc,kBAAkB,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAqB;IAChD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,kBAAkB;IAChC,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Premium license gate.
3
+ * Reads PRO_LICENSE dynamically from process.env at call time — not cached.
4
+ * This allows the license to be set after server start without restart.
5
+ */
6
+ /**
7
+ * Returns true if a valid Pro license is currently set in the environment.
8
+ * A valid key starts with "CPK-" and is at least 8 characters long.
9
+ */
10
+ export declare function isPro(): boolean;
11
+ /**
12
+ * Throws if no valid Pro license is configured.
13
+ * Call at the start of every Pro-gated tool handler.
14
+ *
15
+ * @param toolName - The name of the tool being called, used in the error message.
16
+ */
17
+ export declare function requirePro(toolName: string): void;
18
+ //# sourceMappingURL=gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/premium/gate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,wBAAgB,KAAK,IAAI,OAAO,CAG/B;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQjD"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Premium license gate.
3
+ * Reads PRO_LICENSE dynamically from process.env at call time — not cached.
4
+ * This allows the license to be set after server start without restart.
5
+ */
6
+ /**
7
+ * Returns true if a valid Pro license is currently set in the environment.
8
+ * A valid key starts with "CPK-" and is at least 8 characters long.
9
+ */
10
+ export function isPro() {
11
+ const key = process.env.PRO_LICENSE;
12
+ return Boolean(key && key.length >= 8 && key.startsWith("CPK-"));
13
+ }
14
+ /**
15
+ * Throws if no valid Pro license is configured.
16
+ * Call at the start of every Pro-gated tool handler.
17
+ *
18
+ * @param toolName - The name of the tool being called, used in the error message.
19
+ */
20
+ export function requirePro(toolName) {
21
+ if (!isPro()) {
22
+ throw new Error(`[${toolName}] requires a Pro license. ` +
23
+ `Get one at https://craftpipe.dev/products/cloudvault-mcp — ` +
24
+ `then set PRO_LICENSE=<your-key> in your environment.`);
25
+ }
26
+ }
27
+ //# sourceMappingURL=gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/premium/gate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,UAAU,KAAK;IACnB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACpC,OAAO,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,IAAI,QAAQ,4BAA4B;YACtC,6DAA6D;YAC7D,sDAAsD,CACzD,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * get_secrets tool — secret names and metadata only.
3
+ * SECURITY: Secret values are NEVER returned, only names and metadata.
4
+ */
5
+ import { type ProviderName } from '../lib/providers.js';
6
+ export interface GetSecretsInput {
7
+ provider: ProviderName;
8
+ prefix?: string;
9
+ }
10
+ export declare function get_secrets(input: GetSecretsInput): Promise<{
11
+ content: {
12
+ type: "text";
13
+ text: string;
14
+ }[];
15
+ }>;
16
+ //# sourceMappingURL=get_secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_secrets.d.ts","sourceRoot":"","sources":["../../src/tools/get_secrets.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGrE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,eAAe;;;;;GA+CvD"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * get_secrets tool — secret names and metadata only.
3
+ * SECURITY: Secret values are NEVER returned, only names and metadata.
4
+ */
5
+ import { getProvider } from '../lib/providers.js';
6
+ import { getAuditLog } from '../lib/audit.js';
7
+ export async function get_secrets(input) {
8
+ const start = Date.now();
9
+ const audit = getAuditLog();
10
+ try {
11
+ const provider = getProvider(input.provider);
12
+ const secrets = await provider.getSecrets({
13
+ prefix: input.prefix,
14
+ });
15
+ // SECURITY: Ensure no values are ever returned
16
+ const safeSecrets = secrets.map((s) => {
17
+ const safe = s;
18
+ const result = { ...safe };
19
+ // Belt-and-suspenders: remove any value fields that should not be there
20
+ delete result.value;
21
+ delete result.secret_value;
22
+ delete result.secret_string;
23
+ delete result.secret_binary;
24
+ return result;
25
+ });
26
+ audit.log({
27
+ tool_name: 'get_secrets',
28
+ input_summary: audit.sanitize({
29
+ provider: input.provider,
30
+ prefix: input.prefix,
31
+ }),
32
+ result_summary: JSON.stringify({ count: safeSecrets.length }),
33
+ success: true,
34
+ duration_ms: Date.now() - start,
35
+ });
36
+ return {
37
+ content: [{ type: 'text', text: JSON.stringify({ data: safeSecrets, count: safeSecrets.length }) }],
38
+ };
39
+ }
40
+ catch (err) {
41
+ const message = err instanceof Error ? err.message : String(err);
42
+ audit.log({
43
+ tool_name: 'get_secrets',
44
+ input_summary: audit.sanitize({ provider: input.provider }),
45
+ result_summary: message,
46
+ success: false,
47
+ duration_ms: Date.now() - start,
48
+ });
49
+ throw err;
50
+ }
51
+ }
52
+ //# sourceMappingURL=get_secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_secrets.js","sourceRoot":"","sources":["../../src/tools/get_secrets.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAO9C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAsB;IACtD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC;YACxC,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;QAEH,+CAA+C;QAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACpC,MAAM,IAAI,GAAG,CAAuC,CAAC;YACrD,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YAC3B,wEAAwE;YACxE,OAAO,MAAM,CAAC,KAAK,CAAC;YACpB,OAAO,MAAM,CAAC,YAAY,CAAC;YAC3B,OAAO,MAAM,CAAC,aAAa,CAAC;YAC5B,OAAO,MAAM,CAAC,aAAa,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,GAAG,CAAC;YACR,SAAS,EAAE,aAAa;YACxB,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC;gBAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB,CAAC;YACF,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;YAC7D,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAChC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;SAC7G,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,KAAK,CAAC,GAAG,CAAC;YACR,SAAS,EAAE,aAAa;YACxB,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC3D,cAAc,EAAE,OAAO;YACvB,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAChC,CAAC,CAAC;QACH,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}