cloud-cost-mcp 1.1.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 (48) hide show
  1. package/LICENSE +190 -0
  2. package/NOTICE +15 -0
  3. package/README.md +232 -0
  4. package/dist/data/bundled/aws-pricing.json +379 -0
  5. package/dist/data/bundled/azure-pricing.json +367 -0
  6. package/dist/data/bundled/gcp-pricing.json +383 -0
  7. package/dist/data/bundled/oci-pricing.json +290 -0
  8. package/dist/data/cache.d.ts +53 -0
  9. package/dist/data/cache.d.ts.map +1 -0
  10. package/dist/data/cache.js +95 -0
  11. package/dist/data/cache.js.map +1 -0
  12. package/dist/data/fetchers/aws.d.ts +65 -0
  13. package/dist/data/fetchers/aws.d.ts.map +1 -0
  14. package/dist/data/fetchers/aws.js +298 -0
  15. package/dist/data/fetchers/aws.js.map +1 -0
  16. package/dist/data/fetchers/azure.d.ts +83 -0
  17. package/dist/data/fetchers/azure.d.ts.map +1 -0
  18. package/dist/data/fetchers/azure.js +369 -0
  19. package/dist/data/fetchers/azure.js.map +1 -0
  20. package/dist/data/fetchers/gcp.d.ts +44 -0
  21. package/dist/data/fetchers/gcp.d.ts.map +1 -0
  22. package/dist/data/fetchers/gcp.js +182 -0
  23. package/dist/data/fetchers/gcp.js.map +1 -0
  24. package/dist/data/fetchers/oci.d.ts +65 -0
  25. package/dist/data/fetchers/oci.d.ts.map +1 -0
  26. package/dist/data/fetchers/oci.js +130 -0
  27. package/dist/data/fetchers/oci.js.map +1 -0
  28. package/dist/data/loader.d.ts +56 -0
  29. package/dist/data/loader.d.ts.map +1 -0
  30. package/dist/data/loader.js +149 -0
  31. package/dist/data/loader.js.map +1 -0
  32. package/dist/index.d.ts +21 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +715 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/tools/calculator.d.ts +36 -0
  37. package/dist/tools/calculator.d.ts.map +1 -0
  38. package/dist/tools/calculator.js +271 -0
  39. package/dist/tools/calculator.js.map +1 -0
  40. package/dist/tools/compare.d.ts +64 -0
  41. package/dist/tools/compare.d.ts.map +1 -0
  42. package/dist/tools/compare.js +243 -0
  43. package/dist/tools/compare.js.map +1 -0
  44. package/dist/types.d.ts +171 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +6 -0
  47. package/dist/types.js.map +1 -0
  48. package/package.json +57 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Cloud Cost MCP - In-memory cache for pricing data
3
+ */
4
+ export declare class PricingCache {
5
+ private cache;
6
+ private defaultTTL;
7
+ constructor(defaultTTLMinutes?: number);
8
+ /**
9
+ * Get an item from the cache
10
+ */
11
+ get<T>(key: string): T | null;
12
+ /**
13
+ * Set an item in the cache
14
+ */
15
+ set<T>(key: string, data: T, ttlMinutes?: number): void;
16
+ /**
17
+ * Check if a key exists and is not expired
18
+ */
19
+ has(key: string): boolean;
20
+ /**
21
+ * Delete an item from the cache
22
+ */
23
+ delete(key: string): boolean;
24
+ /**
25
+ * Clear all items from the cache
26
+ */
27
+ clear(): void;
28
+ /**
29
+ * Get cache statistics
30
+ */
31
+ getStats(): {
32
+ size: number;
33
+ keys: string[];
34
+ };
35
+ /**
36
+ * Clean expired entries
37
+ */
38
+ private cleanExpired;
39
+ }
40
+ export declare const pricingCache: PricingCache;
41
+ export declare const CACHE_KEYS: {
42
+ readonly AWS_PRICING: "aws_pricing_data";
43
+ readonly AZURE_PRICING: "azure_pricing_data";
44
+ readonly GCP_PRICING: "gcp_pricing_data";
45
+ readonly OCI_PRICING: "oci_pricing_data";
46
+ readonly ALL_COMPUTE: "all_compute_instances";
47
+ readonly ALL_STORAGE: "all_storage_options";
48
+ readonly ALL_EGRESS: "all_egress_pricing";
49
+ readonly ALL_KUBERNETES: "all_kubernetes_options";
50
+ readonly AZURE_REALTIME: "azure_realtime";
51
+ readonly OCI_REALTIME: "oci_realtime";
52
+ };
53
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/data/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,UAAU,CAAS;gBAEf,iBAAiB,GAAE,MAAW;IAI1C;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAgB7B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAWvD;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;IAQ5C;;OAEG;IACH,OAAO,CAAC,YAAY;CAQrB;AAGD,eAAO,MAAM,YAAY,cAAuB,CAAC;AAGjD,eAAO,MAAM,UAAU;;;;;;;;;;;CAgBb,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Cloud Cost MCP - In-memory cache for pricing data
3
+ */
4
+ export class PricingCache {
5
+ cache = new Map();
6
+ defaultTTL; // milliseconds
7
+ constructor(defaultTTLMinutes = 60) {
8
+ this.defaultTTL = defaultTTLMinutes * 60 * 1000;
9
+ }
10
+ /**
11
+ * Get an item from the cache
12
+ */
13
+ get(key) {
14
+ const entry = this.cache.get(key);
15
+ if (!entry) {
16
+ return null;
17
+ }
18
+ // Check if expired
19
+ if (Date.now() > entry.expiresAt) {
20
+ this.cache.delete(key);
21
+ return null;
22
+ }
23
+ return entry.data;
24
+ }
25
+ /**
26
+ * Set an item in the cache
27
+ */
28
+ set(key, data, ttlMinutes) {
29
+ const ttl = ttlMinutes ? ttlMinutes * 60 * 1000 : this.defaultTTL;
30
+ const now = Date.now();
31
+ this.cache.set(key, {
32
+ data,
33
+ timestamp: now,
34
+ expiresAt: now + ttl,
35
+ });
36
+ }
37
+ /**
38
+ * Check if a key exists and is not expired
39
+ */
40
+ has(key) {
41
+ return this.get(key) !== null;
42
+ }
43
+ /**
44
+ * Delete an item from the cache
45
+ */
46
+ delete(key) {
47
+ return this.cache.delete(key);
48
+ }
49
+ /**
50
+ * Clear all items from the cache
51
+ */
52
+ clear() {
53
+ this.cache.clear();
54
+ }
55
+ /**
56
+ * Get cache statistics
57
+ */
58
+ getStats() {
59
+ this.cleanExpired();
60
+ return {
61
+ size: this.cache.size,
62
+ keys: Array.from(this.cache.keys()),
63
+ };
64
+ }
65
+ /**
66
+ * Clean expired entries
67
+ */
68
+ cleanExpired() {
69
+ const now = Date.now();
70
+ for (const [key, entry] of this.cache.entries()) {
71
+ if (now > entry.expiresAt) {
72
+ this.cache.delete(key);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ // Singleton instance for the pricing data cache
78
+ export const pricingCache = new PricingCache(60); // 1 hour default TTL
79
+ // Cache keys for all providers
80
+ export const CACHE_KEYS = {
81
+ // Provider-specific data
82
+ AWS_PRICING: 'aws_pricing_data',
83
+ AZURE_PRICING: 'azure_pricing_data',
84
+ GCP_PRICING: 'gcp_pricing_data',
85
+ OCI_PRICING: 'oci_pricing_data',
86
+ // Combined/computed data
87
+ ALL_COMPUTE: 'all_compute_instances',
88
+ ALL_STORAGE: 'all_storage_options',
89
+ ALL_EGRESS: 'all_egress_pricing',
90
+ ALL_KUBERNETES: 'all_kubernetes_options',
91
+ // Real-time API caches
92
+ AZURE_REALTIME: 'azure_realtime',
93
+ OCI_REALTIME: 'oci_realtime',
94
+ };
95
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/data/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Cloud Cost MCP - AWS Real-Time Pricing Fetcher
3
+ * Uses instances.vantage.sh API (no auth required)
4
+ * Data source: https://instances.vantage.sh/instances.json
5
+ *
6
+ * Coverage: 1,147 EC2 instance types, 353 RDS instance types
7
+ */
8
+ import type { ComputeInstance, DatabasePricing } from '../../types.js';
9
+ /**
10
+ * Fetch all EC2 instance pricing from instances.vantage.sh
11
+ */
12
+ export declare function fetchAWSEC2Pricing(options?: {
13
+ region?: string;
14
+ family?: string;
15
+ architecture?: 'x86' | 'arm';
16
+ maxResults?: number;
17
+ includeSpot?: boolean;
18
+ includeReserved?: boolean;
19
+ }): Promise<{
20
+ instances: ComputeInstance[];
21
+ totalCount: number;
22
+ timestamp: string;
23
+ source: string;
24
+ }>;
25
+ /**
26
+ * Fetch AWS RDS database pricing
27
+ */
28
+ export declare function fetchAWSRDSPricing(options?: {
29
+ region?: string;
30
+ engine?: string;
31
+ maxResults?: number;
32
+ }): Promise<{
33
+ instances: DatabasePricing[];
34
+ totalCount: number;
35
+ timestamp: string;
36
+ source: string;
37
+ }>;
38
+ /**
39
+ * Get AWS Lightsail bundle pricing
40
+ */
41
+ export declare function getAWSLightsailPricing(options?: {
42
+ region?: string;
43
+ }): {
44
+ bundles: ComputeInstance[];
45
+ notes: string[];
46
+ };
47
+ /**
48
+ * Get available AWS regions from the data
49
+ */
50
+ export declare function getAWSRegions(): Promise<string[]>;
51
+ /**
52
+ * Check if AWS data source is accessible
53
+ */
54
+ export declare function checkAWSAPIStatus(): Promise<{
55
+ available: boolean;
56
+ message: string;
57
+ }>;
58
+ /**
59
+ * Get instance families/categories available
60
+ */
61
+ export declare function getAWSInstanceFamilies(): Promise<{
62
+ family: string;
63
+ count: number;
64
+ }[]>;
65
+ //# sourceMappingURL=aws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../../../src/data/fetchers/aws.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAmB,MAAM,gBAAgB,CAAC;AAuExF;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAoED;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAsED;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG;IACF,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CA0BA;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAcvD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB1F;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAmB3F"}
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Cloud Cost MCP - AWS Real-Time Pricing Fetcher
3
+ * Uses instances.vantage.sh API (no auth required)
4
+ * Data source: https://instances.vantage.sh/instances.json
5
+ *
6
+ * Coverage: 1,147 EC2 instance types, 353 RDS instance types
7
+ */
8
+ import { pricingCache } from '../cache.js';
9
+ // Data source endpoints (public, no auth required)
10
+ const EC2_INSTANCES_URL = 'https://instances.vantage.sh/instances.json';
11
+ const RDS_INSTANCES_URL = 'https://instances.vantage.sh/rds/instances.json';
12
+ // AWS Lightsail pricing (manually curated - AWS doesn't expose this via API)
13
+ const LIGHTSAIL_BUNDLES = [
14
+ { name: 'nano', vcpus: 1, memoryGB: 0.5, storageGB: 20, transferTB: 1, hourlyPrice: 0.0047, monthlyPrice: 3.50 },
15
+ { name: 'micro', vcpus: 1, memoryGB: 1, storageGB: 40, transferTB: 2, hourlyPrice: 0.0067, monthlyPrice: 5.00 },
16
+ { name: 'small', vcpus: 1, memoryGB: 2, storageGB: 60, transferTB: 3, hourlyPrice: 0.0134, monthlyPrice: 10.00 },
17
+ { name: 'medium', vcpus: 2, memoryGB: 4, storageGB: 80, transferTB: 4, hourlyPrice: 0.0268, monthlyPrice: 20.00 },
18
+ { name: 'large', vcpus: 2, memoryGB: 8, storageGB: 160, transferTB: 5, hourlyPrice: 0.0536, monthlyPrice: 40.00 },
19
+ { name: 'xlarge', vcpus: 4, memoryGB: 16, storageGB: 320, transferTB: 6, hourlyPrice: 0.1072, monthlyPrice: 80.00 },
20
+ { name: '2xlarge', vcpus: 8, memoryGB: 32, storageGB: 640, transferTB: 7, hourlyPrice: 0.2144, monthlyPrice: 160.00 },
21
+ ];
22
+ // Cache keys
23
+ const CACHE_KEY_EC2 = 'AWS_EC2_REALTIME';
24
+ const CACHE_KEY_RDS = 'AWS_RDS_REALTIME';
25
+ const CACHE_TTL_MINUTES = 60; // Cache for 1 hour
26
+ /**
27
+ * Fetch all EC2 instance pricing from instances.vantage.sh
28
+ */
29
+ export async function fetchAWSEC2Pricing(options) {
30
+ const region = options?.region || 'us-east-1';
31
+ const maxResults = options?.maxResults || 500;
32
+ // Check cache first
33
+ const cacheKey = `${CACHE_KEY_EC2}_${region}`;
34
+ const cached = pricingCache.get(cacheKey);
35
+ if (cached) {
36
+ return {
37
+ instances: filterAndLimit(cached, options, maxResults),
38
+ totalCount: cached.length,
39
+ timestamp: new Date().toISOString(),
40
+ source: 'cache',
41
+ };
42
+ }
43
+ try {
44
+ const response = await fetch(EC2_INSTANCES_URL);
45
+ if (!response.ok) {
46
+ throw new Error(`Failed to fetch EC2 data: ${response.status}`);
47
+ }
48
+ const data = await response.json();
49
+ const instances = [];
50
+ for (const item of data) {
51
+ const regionPricing = item.pricing[region];
52
+ if (!regionPricing?.linux?.ondemand)
53
+ continue;
54
+ const hourlyPrice = parseFloat(regionPricing.linux.ondemand);
55
+ if (isNaN(hourlyPrice))
56
+ continue;
57
+ const category = mapFamilyToCategory(item.family);
58
+ const architecture = item.arch?.includes('arm64') ? 'arm' : 'x86';
59
+ const instance = {
60
+ provider: 'aws',
61
+ name: item.instance_type,
62
+ displayName: `${item.instance_type} (${item.family})`,
63
+ vcpus: item.vCPU,
64
+ memoryGB: item.memory,
65
+ hourlyPrice,
66
+ monthlyPrice: Math.round(hourlyPrice * 730 * 100) / 100,
67
+ region,
68
+ category,
69
+ architecture,
70
+ gpuCount: item.GPU || undefined,
71
+ notes: buildNotes(item, regionPricing, options),
72
+ };
73
+ instances.push(instance);
74
+ }
75
+ // Sort by monthly price
76
+ instances.sort((a, b) => a.monthlyPrice - b.monthlyPrice);
77
+ // Cache the full result
78
+ pricingCache.set(cacheKey, instances, CACHE_TTL_MINUTES);
79
+ return {
80
+ instances: filterAndLimit(instances, options, maxResults),
81
+ totalCount: instances.length,
82
+ timestamp: new Date().toISOString(),
83
+ source: EC2_INSTANCES_URL,
84
+ };
85
+ }
86
+ catch (error) {
87
+ throw new Error(`Failed to fetch AWS EC2 pricing: ${error instanceof Error ? error.message : 'Unknown error'}`);
88
+ }
89
+ }
90
+ /**
91
+ * Fetch AWS RDS database pricing
92
+ */
93
+ export async function fetchAWSRDSPricing(options) {
94
+ const region = options?.region || 'us-east-1';
95
+ const engine = options?.engine || 'PostgreSQL';
96
+ const maxResults = options?.maxResults || 100;
97
+ // Check cache first
98
+ const cacheKey = `${CACHE_KEY_RDS}_${region}_${engine}`;
99
+ const cached = pricingCache.get(cacheKey);
100
+ if (cached) {
101
+ return {
102
+ instances: cached.slice(0, maxResults),
103
+ totalCount: cached.length,
104
+ timestamp: new Date().toISOString(),
105
+ source: 'cache',
106
+ };
107
+ }
108
+ try {
109
+ const response = await fetch(RDS_INSTANCES_URL);
110
+ if (!response.ok) {
111
+ throw new Error(`Failed to fetch RDS data: ${response.status}`);
112
+ }
113
+ const data = await response.json();
114
+ const instances = [];
115
+ for (const item of data) {
116
+ const regionPricing = item.pricing[region];
117
+ if (!regionPricing)
118
+ continue;
119
+ // Try to find pricing for the requested engine
120
+ const engineKey = Object.keys(regionPricing).find(k => k.toLowerCase().includes(engine.toLowerCase()));
121
+ if (!engineKey)
122
+ continue;
123
+ const enginePricing = regionPricing[engineKey];
124
+ if (!enginePricing?.ondemand)
125
+ continue;
126
+ const hourlyPrice = parseFloat(enginePricing.ondemand);
127
+ if (isNaN(hourlyPrice))
128
+ continue;
129
+ instances.push({
130
+ provider: 'aws',
131
+ name: `RDS ${item.instance_type}`,
132
+ type: 'relational',
133
+ engine,
134
+ vcpus: item.vCPU,
135
+ memoryGB: item.memory,
136
+ hourlyPrice,
137
+ monthlyPrice: Math.round(hourlyPrice * 730 * 100) / 100,
138
+ notes: `Single-AZ, ${engine}`,
139
+ });
140
+ }
141
+ // Sort by monthly price
142
+ instances.sort((a, b) => a.monthlyPrice - b.monthlyPrice);
143
+ // Cache the result
144
+ pricingCache.set(cacheKey, instances, CACHE_TTL_MINUTES);
145
+ return {
146
+ instances: instances.slice(0, maxResults),
147
+ totalCount: instances.length,
148
+ timestamp: new Date().toISOString(),
149
+ source: RDS_INSTANCES_URL,
150
+ };
151
+ }
152
+ catch (error) {
153
+ throw new Error(`Failed to fetch AWS RDS pricing: ${error instanceof Error ? error.message : 'Unknown error'}`);
154
+ }
155
+ }
156
+ /**
157
+ * Get AWS Lightsail bundle pricing
158
+ */
159
+ export function getAWSLightsailPricing(options) {
160
+ const region = options?.region || 'us-east-1';
161
+ const bundles = LIGHTSAIL_BUNDLES.map(bundle => ({
162
+ provider: 'aws',
163
+ name: `Lightsail ${bundle.name}`,
164
+ displayName: `Lightsail ${bundle.name.charAt(0).toUpperCase() + bundle.name.slice(1)} (${bundle.memoryGB}GB RAM)`,
165
+ vcpus: bundle.vcpus,
166
+ memoryGB: bundle.memoryGB,
167
+ hourlyPrice: bundle.hourlyPrice,
168
+ monthlyPrice: bundle.monthlyPrice,
169
+ region,
170
+ category: 'general',
171
+ architecture: 'x86',
172
+ notes: `Includes ${bundle.storageGB}GB SSD, ${bundle.transferTB}TB transfer`,
173
+ }));
174
+ return {
175
+ bundles,
176
+ notes: [
177
+ 'Lightsail is a simplified VPS service with fixed monthly pricing',
178
+ 'Includes SSD storage, data transfer, and static IP',
179
+ 'Prices are consistent across most regions',
180
+ 'Windows instances cost approximately 60% more',
181
+ ],
182
+ };
183
+ }
184
+ /**
185
+ * Get available AWS regions from the data
186
+ */
187
+ export async function getAWSRegions() {
188
+ try {
189
+ const response = await fetch(EC2_INSTANCES_URL);
190
+ if (!response.ok)
191
+ return [];
192
+ const data = await response.json();
193
+ if (data.length === 0)
194
+ return [];
195
+ // Get regions from first instance
196
+ const regions = Object.keys(data[0].pricing || {});
197
+ return regions.sort();
198
+ }
199
+ catch {
200
+ return [];
201
+ }
202
+ }
203
+ /**
204
+ * Check if AWS data source is accessible
205
+ */
206
+ export async function checkAWSAPIStatus() {
207
+ try {
208
+ const response = await fetch(EC2_INSTANCES_URL, { method: 'HEAD' });
209
+ if (response.ok) {
210
+ return {
211
+ available: true,
212
+ message: `instances.vantage.sh API is accessible (1,147+ EC2 instances available)`
213
+ };
214
+ }
215
+ return { available: false, message: `API returned status ${response.status}` };
216
+ }
217
+ catch (error) {
218
+ return {
219
+ available: false,
220
+ message: `API check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
221
+ };
222
+ }
223
+ }
224
+ /**
225
+ * Get instance families/categories available
226
+ */
227
+ export async function getAWSInstanceFamilies() {
228
+ try {
229
+ const response = await fetch(EC2_INSTANCES_URL);
230
+ if (!response.ok)
231
+ return [];
232
+ const data = await response.json();
233
+ const familyCounts = new Map();
234
+ for (const item of data) {
235
+ const count = familyCounts.get(item.family) || 0;
236
+ familyCounts.set(item.family, count + 1);
237
+ }
238
+ return Array.from(familyCounts.entries())
239
+ .map(([family, count]) => ({ family, count }))
240
+ .sort((a, b) => b.count - a.count);
241
+ }
242
+ catch {
243
+ return [];
244
+ }
245
+ }
246
+ // Helper functions
247
+ function mapFamilyToCategory(family) {
248
+ const familyLower = family.toLowerCase();
249
+ if (familyLower.includes('compute'))
250
+ return 'compute';
251
+ if (familyLower.includes('memory'))
252
+ return 'memory';
253
+ if (familyLower.includes('storage'))
254
+ return 'storage';
255
+ if (familyLower.includes('accelerated') || familyLower.includes('gpu'))
256
+ return 'gpu';
257
+ return 'general';
258
+ }
259
+ function filterAndLimit(instances, options, maxResults) {
260
+ let filtered = instances;
261
+ if (options?.family) {
262
+ filtered = filtered.filter(i => i.displayName?.toLowerCase().includes(options.family.toLowerCase()));
263
+ }
264
+ if (options?.architecture) {
265
+ filtered = filtered.filter(i => i.architecture === options.architecture);
266
+ }
267
+ return filtered.slice(0, maxResults);
268
+ }
269
+ function buildNotes(item, regionPricing, options) {
270
+ const notes = [];
271
+ if (item.physical_processor) {
272
+ notes.push(item.physical_processor);
273
+ }
274
+ if (item.generation === 'previous') {
275
+ notes.push('Previous generation');
276
+ }
277
+ if (options?.includeSpot && regionPricing.linux?.spot_avg) {
278
+ const spotPrice = parseFloat(regionPricing.linux.spot_avg);
279
+ const ondemandPrice = parseFloat(regionPricing.linux.ondemand || '0');
280
+ if (!isNaN(spotPrice) && !isNaN(ondemandPrice) && ondemandPrice > 0) {
281
+ const savings = Math.round((1 - spotPrice / ondemandPrice) * 100);
282
+ notes.push(`Spot: $${spotPrice.toFixed(4)}/hr (${savings}% savings)`);
283
+ }
284
+ }
285
+ if (options?.includeReserved && regionPricing.linux?.reserved) {
286
+ const reserved1yr = regionPricing.linux.reserved['yrTerm1Standard.noUpfront'];
287
+ if (reserved1yr) {
288
+ const reservedPrice = parseFloat(reserved1yr);
289
+ const ondemandPrice = parseFloat(regionPricing.linux.ondemand || '0');
290
+ if (!isNaN(reservedPrice) && !isNaN(ondemandPrice) && ondemandPrice > 0) {
291
+ const savings = Math.round((1 - reservedPrice / ondemandPrice) * 100);
292
+ notes.push(`1yr Reserved: $${reservedPrice.toFixed(4)}/hr (${savings}% savings)`);
293
+ }
294
+ }
295
+ }
296
+ return notes.join('. ') || 'Linux on-demand pricing';
297
+ }
298
+ //# sourceMappingURL=aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.js","sourceRoot":"","sources":["../../../src/data/fetchers/aws.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Cloud Cost MCP - Azure Real-Time Pricing Fetcher
3
+ * Uses Azure Retail Prices API (public, no auth required)
4
+ * https://learn.microsoft.com/en-us/rest/api/cost-management/retail-prices/azure-retail-prices
5
+ */
6
+ import type { ComputeInstance, StoragePricing } from '../../types.js';
7
+ export interface AzureRetailPrice {
8
+ currencyCode: string;
9
+ tierMinimumUnits: number;
10
+ retailPrice: number;
11
+ unitPrice: number;
12
+ armRegionName: string;
13
+ location: string;
14
+ effectiveStartDate: string;
15
+ meterId: string;
16
+ meterName: string;
17
+ productId: string;
18
+ skuId: string;
19
+ productName: string;
20
+ skuName: string;
21
+ serviceName: string;
22
+ serviceId: string;
23
+ serviceFamily: string;
24
+ unitOfMeasure: string;
25
+ type: string;
26
+ isPrimaryMeterRegion: boolean;
27
+ armSkuName: string;
28
+ }
29
+ export interface AzureRetailResponse {
30
+ BillingCurrency: string;
31
+ CustomerEntityId: string;
32
+ CustomerEntityType: string;
33
+ Items: AzureRetailPrice[];
34
+ NextPageLink: string | null;
35
+ Count: number;
36
+ }
37
+ /**
38
+ * Fetch Azure VM pricing from the Retail Prices API
39
+ */
40
+ export declare function fetchAzureComputePricing(options?: {
41
+ region?: string;
42
+ vmSeries?: string;
43
+ maxResults?: number;
44
+ }): Promise<ComputeInstance[]>;
45
+ /**
46
+ * Fetch Azure Storage pricing
47
+ */
48
+ export declare function fetchAzureStoragePricing(options?: {
49
+ region?: string;
50
+ }): Promise<StoragePricing[]>;
51
+ /**
52
+ * Check if Azure API is accessible
53
+ */
54
+ export declare function checkAzureAPIStatus(): Promise<{
55
+ available: boolean;
56
+ message: string;
57
+ }>;
58
+ /**
59
+ * Fetch comprehensive Azure VM pricing from vantage.sh (1,199 instance types)
60
+ */
61
+ export declare function fetchAzureVantagePricing(options?: {
62
+ region?: string;
63
+ category?: string;
64
+ includeSpot?: boolean;
65
+ maxResults?: number;
66
+ }): Promise<{
67
+ instances: ComputeInstance[];
68
+ totalCount: number;
69
+ timestamp: string;
70
+ source: string;
71
+ }>;
72
+ /**
73
+ * Get available Azure regions from vantage.sh data
74
+ */
75
+ export declare function getAzureVantageRegions(): Promise<string[]>;
76
+ /**
77
+ * Get Azure instance categories from vantage.sh
78
+ */
79
+ export declare function getAzureCategories(): Promise<{
80
+ category: string;
81
+ count: number;
82
+ }[]>;
83
+ //# sourceMappingURL=azure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure.d.ts","sourceRoot":"","sources":["../../../src/data/fetchers/azure.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAItE,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,OAAO,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,CAAC,EAAE;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAqE7B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,CAAC,EAAE;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAoD5B;AAoGD;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAa5F;AAqCD;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,CAAC,EAAE;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CA4ED;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAahE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAmBzF"}