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.
- package/LICENSE +190 -0
- package/NOTICE +15 -0
- package/README.md +232 -0
- package/dist/data/bundled/aws-pricing.json +379 -0
- package/dist/data/bundled/azure-pricing.json +367 -0
- package/dist/data/bundled/gcp-pricing.json +383 -0
- package/dist/data/bundled/oci-pricing.json +290 -0
- package/dist/data/cache.d.ts +53 -0
- package/dist/data/cache.d.ts.map +1 -0
- package/dist/data/cache.js +95 -0
- package/dist/data/cache.js.map +1 -0
- package/dist/data/fetchers/aws.d.ts +65 -0
- package/dist/data/fetchers/aws.d.ts.map +1 -0
- package/dist/data/fetchers/aws.js +298 -0
- package/dist/data/fetchers/aws.js.map +1 -0
- package/dist/data/fetchers/azure.d.ts +83 -0
- package/dist/data/fetchers/azure.d.ts.map +1 -0
- package/dist/data/fetchers/azure.js +369 -0
- package/dist/data/fetchers/azure.js.map +1 -0
- package/dist/data/fetchers/gcp.d.ts +44 -0
- package/dist/data/fetchers/gcp.d.ts.map +1 -0
- package/dist/data/fetchers/gcp.js +182 -0
- package/dist/data/fetchers/gcp.js.map +1 -0
- package/dist/data/fetchers/oci.d.ts +65 -0
- package/dist/data/fetchers/oci.d.ts.map +1 -0
- package/dist/data/fetchers/oci.js +130 -0
- package/dist/data/fetchers/oci.js.map +1 -0
- package/dist/data/loader.d.ts +56 -0
- package/dist/data/loader.d.ts.map +1 -0
- package/dist/data/loader.js +149 -0
- package/dist/data/loader.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +715 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/calculator.d.ts +36 -0
- package/dist/tools/calculator.d.ts.map +1 -0
- package/dist/tools/calculator.js +271 -0
- package/dist/tools/calculator.js.map +1 -0
- package/dist/tools/compare.d.ts +64 -0
- package/dist/tools/compare.d.ts.map +1 -0
- package/dist/tools/compare.js +243 -0
- package/dist/tools/compare.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,369 @@
|
|
|
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 { pricingCache } from '../cache.js';
|
|
7
|
+
const AZURE_RETAIL_API = 'https://prices.azure.com/api/retail/prices';
|
|
8
|
+
/**
|
|
9
|
+
* Fetch Azure VM pricing from the Retail Prices API
|
|
10
|
+
*/
|
|
11
|
+
export async function fetchAzureComputePricing(options) {
|
|
12
|
+
const region = options?.region || 'eastus';
|
|
13
|
+
const maxResults = options?.maxResults || 100;
|
|
14
|
+
// Build OData filter
|
|
15
|
+
const filters = [
|
|
16
|
+
`armRegionName eq '${region}'`,
|
|
17
|
+
"serviceName eq 'Virtual Machines'",
|
|
18
|
+
"priceType eq 'Consumption'",
|
|
19
|
+
"currencyCode eq 'USD'",
|
|
20
|
+
];
|
|
21
|
+
if (options?.vmSeries) {
|
|
22
|
+
filters.push(`contains(armSkuName, '${options.vmSeries}')`);
|
|
23
|
+
}
|
|
24
|
+
const filterQuery = filters.join(' and ');
|
|
25
|
+
const url = `${AZURE_RETAIL_API}?$filter=${encodeURIComponent(filterQuery)}&$top=${maxResults}`;
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetch(url);
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
throw new Error(`Azure API request failed: ${response.status}`);
|
|
30
|
+
}
|
|
31
|
+
const data = await response.json();
|
|
32
|
+
// Transform Azure response to unified ComputeInstance format
|
|
33
|
+
const instances = [];
|
|
34
|
+
const seenSkus = new Set();
|
|
35
|
+
for (const item of data.Items) {
|
|
36
|
+
// Skip non-VM items and duplicates
|
|
37
|
+
if (!item.armSkuName || seenSkus.has(item.armSkuName)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Skip low priority, spot, and Windows (focus on Linux pay-as-you-go)
|
|
41
|
+
if (item.skuName.includes('Low Priority') ||
|
|
42
|
+
item.skuName.includes('Spot') ||
|
|
43
|
+
item.productName.includes('Windows')) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
// Extract vCPU and memory from SKU name (rough estimates)
|
|
47
|
+
const vmSpecs = parseAzureVMSpecs(item.armSkuName);
|
|
48
|
+
if (!vmSpecs)
|
|
49
|
+
continue;
|
|
50
|
+
seenSkus.add(item.armSkuName);
|
|
51
|
+
instances.push({
|
|
52
|
+
provider: 'azure',
|
|
53
|
+
name: item.armSkuName,
|
|
54
|
+
displayName: `${item.armSkuName} (${item.productName})`,
|
|
55
|
+
vcpus: vmSpecs.vcpus,
|
|
56
|
+
memoryGB: vmSpecs.memoryGB,
|
|
57
|
+
hourlyPrice: item.retailPrice,
|
|
58
|
+
monthlyPrice: item.retailPrice * 730,
|
|
59
|
+
region: item.armRegionName,
|
|
60
|
+
category: vmSpecs.category,
|
|
61
|
+
architecture: vmSpecs.architecture,
|
|
62
|
+
notes: `Real-time from Azure API - ${new Date().toISOString().split('T')[0]}`,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return instances.sort((a, b) => a.monthlyPrice - b.monthlyPrice);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw new Error(`Failed to fetch Azure pricing: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Fetch Azure Storage pricing
|
|
73
|
+
*/
|
|
74
|
+
export async function fetchAzureStoragePricing(options) {
|
|
75
|
+
const region = options?.region || 'eastus';
|
|
76
|
+
const filters = [
|
|
77
|
+
`armRegionName eq '${region}'`,
|
|
78
|
+
"(serviceName eq 'Storage' or serviceName eq 'Azure Blob Storage')",
|
|
79
|
+
"priceType eq 'Consumption'",
|
|
80
|
+
"currencyCode eq 'USD'",
|
|
81
|
+
];
|
|
82
|
+
const filterQuery = filters.join(' and ');
|
|
83
|
+
const url = `${AZURE_RETAIL_API}?$filter=${encodeURIComponent(filterQuery)}&$top=100`;
|
|
84
|
+
try {
|
|
85
|
+
const response = await fetch(url);
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
throw new Error(`Azure API request failed: ${response.status}`);
|
|
88
|
+
}
|
|
89
|
+
const data = await response.json();
|
|
90
|
+
const storage = [];
|
|
91
|
+
const seenProducts = new Set();
|
|
92
|
+
for (const item of data.Items) {
|
|
93
|
+
const key = `${item.productName}-${item.skuName}`;
|
|
94
|
+
if (seenProducts.has(key))
|
|
95
|
+
continue;
|
|
96
|
+
// Only include per-GB storage pricing
|
|
97
|
+
if (!item.unitOfMeasure.includes('GB'))
|
|
98
|
+
continue;
|
|
99
|
+
seenProducts.add(key);
|
|
100
|
+
const tier = parseAzureStorageTier(item.skuName, item.productName);
|
|
101
|
+
const type = parseAzureStorageType(item.productName);
|
|
102
|
+
storage.push({
|
|
103
|
+
provider: 'azure',
|
|
104
|
+
name: `${item.productName} - ${item.skuName}`,
|
|
105
|
+
type,
|
|
106
|
+
tier,
|
|
107
|
+
pricePerGBMonth: item.retailPrice,
|
|
108
|
+
region: item.armRegionName,
|
|
109
|
+
redundancy: parseAzureRedundancy(item.skuName),
|
|
110
|
+
notes: `Real-time from Azure API`,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return storage;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`Failed to fetch Azure storage pricing: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse Azure VM specs from SKU name
|
|
121
|
+
*/
|
|
122
|
+
function parseAzureVMSpecs(skuName) {
|
|
123
|
+
// Common Azure VM naming patterns
|
|
124
|
+
// Standard_D2s_v5 -> D series, 2 vCPUs
|
|
125
|
+
// Standard_E4s_v5 -> E series (memory), 4 vCPUs
|
|
126
|
+
// Standard_F8s_v2 -> F series (compute), 8 vCPUs
|
|
127
|
+
const match = skuName.match(/Standard_([A-Z]+)(\d+)/i);
|
|
128
|
+
if (!match)
|
|
129
|
+
return null;
|
|
130
|
+
const series = match[1].toUpperCase();
|
|
131
|
+
const size = parseInt(match[2], 10);
|
|
132
|
+
// Estimate vCPUs (usually matches the number in the name)
|
|
133
|
+
const vcpus = size;
|
|
134
|
+
// Estimate memory based on series
|
|
135
|
+
let memoryGB;
|
|
136
|
+
let category;
|
|
137
|
+
let architecture = 'x86';
|
|
138
|
+
switch (series.charAt(0)) {
|
|
139
|
+
case 'D': // General purpose
|
|
140
|
+
memoryGB = vcpus * 4;
|
|
141
|
+
category = 'general';
|
|
142
|
+
break;
|
|
143
|
+
case 'E': // Memory optimized
|
|
144
|
+
memoryGB = vcpus * 8;
|
|
145
|
+
category = 'memory';
|
|
146
|
+
break;
|
|
147
|
+
case 'F': // Compute optimized
|
|
148
|
+
memoryGB = vcpus * 2;
|
|
149
|
+
category = 'compute';
|
|
150
|
+
break;
|
|
151
|
+
case 'B': // Burstable
|
|
152
|
+
memoryGB = vcpus * 4;
|
|
153
|
+
category = 'general';
|
|
154
|
+
break;
|
|
155
|
+
case 'N': // GPU
|
|
156
|
+
memoryGB = vcpus * 4;
|
|
157
|
+
category = 'gpu';
|
|
158
|
+
break;
|
|
159
|
+
default:
|
|
160
|
+
memoryGB = vcpus * 4;
|
|
161
|
+
category = 'general';
|
|
162
|
+
}
|
|
163
|
+
// Check for ARM (ps suffix)
|
|
164
|
+
if (skuName.toLowerCase().includes('ps')) {
|
|
165
|
+
architecture = 'arm';
|
|
166
|
+
category = 'arm';
|
|
167
|
+
}
|
|
168
|
+
return { vcpus, memoryGB, category, architecture };
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Parse Azure storage tier from SKU name
|
|
172
|
+
*/
|
|
173
|
+
function parseAzureStorageTier(skuName, productName) {
|
|
174
|
+
const combined = `${skuName} ${productName}`.toLowerCase();
|
|
175
|
+
if (combined.includes('archive'))
|
|
176
|
+
return 'archive';
|
|
177
|
+
if (combined.includes('cold'))
|
|
178
|
+
return 'cold';
|
|
179
|
+
if (combined.includes('cool'))
|
|
180
|
+
return 'cool';
|
|
181
|
+
return 'hot';
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Parse Azure storage type
|
|
185
|
+
*/
|
|
186
|
+
function parseAzureStorageType(productName) {
|
|
187
|
+
const name = productName.toLowerCase();
|
|
188
|
+
if (name.includes('blob'))
|
|
189
|
+
return 'object';
|
|
190
|
+
if (name.includes('disk') || name.includes('managed'))
|
|
191
|
+
return 'block';
|
|
192
|
+
if (name.includes('file'))
|
|
193
|
+
return 'file';
|
|
194
|
+
if (name.includes('archive'))
|
|
195
|
+
return 'archive';
|
|
196
|
+
return 'object';
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Parse Azure storage redundancy
|
|
200
|
+
*/
|
|
201
|
+
function parseAzureRedundancy(skuName) {
|
|
202
|
+
const sku = skuName.toUpperCase();
|
|
203
|
+
if (sku.includes('GZRS'))
|
|
204
|
+
return 'GZRS';
|
|
205
|
+
if (sku.includes('GRS'))
|
|
206
|
+
return 'GRS';
|
|
207
|
+
if (sku.includes('ZRS'))
|
|
208
|
+
return 'ZRS';
|
|
209
|
+
if (sku.includes('LRS'))
|
|
210
|
+
return 'LRS';
|
|
211
|
+
return 'LRS';
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Check if Azure API is accessible
|
|
215
|
+
*/
|
|
216
|
+
export async function checkAzureAPIStatus() {
|
|
217
|
+
try {
|
|
218
|
+
const response = await fetch(`${AZURE_RETAIL_API}?$top=1`);
|
|
219
|
+
if (response.ok) {
|
|
220
|
+
return { available: true, message: 'Azure Retail Prices API + instances.vantage.sh accessible (1,199 instance types)' };
|
|
221
|
+
}
|
|
222
|
+
return { available: false, message: `API returned status ${response.status}` };
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
return {
|
|
226
|
+
available: false,
|
|
227
|
+
message: `API check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// =============================================================================
|
|
232
|
+
// VANTAGE.SH DATA SOURCE (1,199 Azure Instance Types)
|
|
233
|
+
// =============================================================================
|
|
234
|
+
const AZURE_VANTAGE_URL = 'https://instances.vantage.sh/azure/instances.json';
|
|
235
|
+
const CACHE_KEY_AZURE_VANTAGE = 'AZURE_VANTAGE_REALTIME';
|
|
236
|
+
const CACHE_TTL_MINUTES = 60;
|
|
237
|
+
/**
|
|
238
|
+
* Fetch comprehensive Azure VM pricing from vantage.sh (1,199 instance types)
|
|
239
|
+
*/
|
|
240
|
+
export async function fetchAzureVantagePricing(options) {
|
|
241
|
+
const region = options?.region || 'us-east';
|
|
242
|
+
const maxResults = options?.maxResults || 500;
|
|
243
|
+
// Check cache first
|
|
244
|
+
const cacheKey = `${CACHE_KEY_AZURE_VANTAGE}_${region}`;
|
|
245
|
+
const cached = pricingCache.get(cacheKey);
|
|
246
|
+
if (cached) {
|
|
247
|
+
return {
|
|
248
|
+
instances: filterAzureInstances(cached, options, maxResults),
|
|
249
|
+
totalCount: cached.length,
|
|
250
|
+
timestamp: new Date().toISOString(),
|
|
251
|
+
source: 'cache',
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
const response = await fetch(AZURE_VANTAGE_URL);
|
|
256
|
+
if (!response.ok) {
|
|
257
|
+
throw new Error(`Failed to fetch Azure data: ${response.status}`);
|
|
258
|
+
}
|
|
259
|
+
const data = await response.json();
|
|
260
|
+
const instances = [];
|
|
261
|
+
for (const item of data) {
|
|
262
|
+
const regionPricing = item.pricing[region];
|
|
263
|
+
if (!regionPricing?.linux?.ondemand)
|
|
264
|
+
continue;
|
|
265
|
+
const hourlyPrice = regionPricing.linux.ondemand;
|
|
266
|
+
if (isNaN(hourlyPrice) || hourlyPrice === 0)
|
|
267
|
+
continue;
|
|
268
|
+
const category = mapAzureCategoryToComputeCategory(item.category);
|
|
269
|
+
const gpuCount = parseInt(item.GPU) || 0;
|
|
270
|
+
let notes = item.pretty_name;
|
|
271
|
+
if (gpuCount > 0) {
|
|
272
|
+
notes += ` (${gpuCount}x GPU)`;
|
|
273
|
+
}
|
|
274
|
+
if (options?.includeSpot && regionPricing.linux?.spot_min) {
|
|
275
|
+
const spotPrice = regionPricing.linux.spot_min;
|
|
276
|
+
const savings = Math.round((1 - spotPrice / hourlyPrice) * 100);
|
|
277
|
+
notes += ` | Spot: $${spotPrice.toFixed(4)}/hr (${savings}% off)`;
|
|
278
|
+
}
|
|
279
|
+
instances.push({
|
|
280
|
+
provider: 'azure',
|
|
281
|
+
name: item.pretty_name,
|
|
282
|
+
displayName: `${item.pretty_name} (${item.category})`,
|
|
283
|
+
vcpus: item.vcpu,
|
|
284
|
+
memoryGB: item.memory,
|
|
285
|
+
hourlyPrice,
|
|
286
|
+
monthlyPrice: Math.round(hourlyPrice * 730 * 100) / 100,
|
|
287
|
+
region,
|
|
288
|
+
category,
|
|
289
|
+
architecture: 'x86', // Default, would need to check for ARM
|
|
290
|
+
gpuCount: gpuCount > 0 ? gpuCount : undefined,
|
|
291
|
+
notes,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
// Sort by monthly price
|
|
295
|
+
instances.sort((a, b) => a.monthlyPrice - b.monthlyPrice);
|
|
296
|
+
// Cache the full result
|
|
297
|
+
pricingCache.set(cacheKey, instances, CACHE_TTL_MINUTES);
|
|
298
|
+
return {
|
|
299
|
+
instances: filterAzureInstances(instances, options, maxResults),
|
|
300
|
+
totalCount: instances.length,
|
|
301
|
+
timestamp: new Date().toISOString(),
|
|
302
|
+
source: AZURE_VANTAGE_URL,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
throw new Error(`Failed to fetch Azure pricing: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Get available Azure regions from vantage.sh data
|
|
311
|
+
*/
|
|
312
|
+
export async function getAzureVantageRegions() {
|
|
313
|
+
try {
|
|
314
|
+
const response = await fetch(AZURE_VANTAGE_URL);
|
|
315
|
+
if (!response.ok)
|
|
316
|
+
return [];
|
|
317
|
+
const data = await response.json();
|
|
318
|
+
if (data.length === 0)
|
|
319
|
+
return [];
|
|
320
|
+
const regions = Object.keys(data[0].pricing || {});
|
|
321
|
+
return regions.sort();
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
return [];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Get Azure instance categories from vantage.sh
|
|
329
|
+
*/
|
|
330
|
+
export async function getAzureCategories() {
|
|
331
|
+
try {
|
|
332
|
+
const response = await fetch(AZURE_VANTAGE_URL);
|
|
333
|
+
if (!response.ok)
|
|
334
|
+
return [];
|
|
335
|
+
const data = await response.json();
|
|
336
|
+
const categoryCounts = new Map();
|
|
337
|
+
for (const item of data) {
|
|
338
|
+
const count = categoryCounts.get(item.category) || 0;
|
|
339
|
+
categoryCounts.set(item.category, count + 1);
|
|
340
|
+
}
|
|
341
|
+
return Array.from(categoryCounts.entries())
|
|
342
|
+
.map(([category, count]) => ({ category, count }))
|
|
343
|
+
.sort((a, b) => b.count - a.count);
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return [];
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// Helper functions for vantage.sh data
|
|
350
|
+
function mapAzureCategoryToComputeCategory(category) {
|
|
351
|
+
const cat = category.toLowerCase();
|
|
352
|
+
if (cat.includes('compute'))
|
|
353
|
+
return 'compute';
|
|
354
|
+
if (cat.includes('memory'))
|
|
355
|
+
return 'memory';
|
|
356
|
+
if (cat.includes('storage'))
|
|
357
|
+
return 'storage';
|
|
358
|
+
if (cat.includes('gpu') || cat.includes('accelerated'))
|
|
359
|
+
return 'gpu';
|
|
360
|
+
return 'general';
|
|
361
|
+
}
|
|
362
|
+
function filterAzureInstances(instances, options, maxResults) {
|
|
363
|
+
let filtered = instances;
|
|
364
|
+
if (options?.category) {
|
|
365
|
+
filtered = filtered.filter(i => i.displayName?.toLowerCase().includes(options.category.toLowerCase()));
|
|
366
|
+
}
|
|
367
|
+
return filtered.slice(0, maxResults);
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=azure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azure.js","sourceRoot":"","sources":["../../../src/data/fetchers/azure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Cost MCP - GCP Real-Time Pricing Fetcher
|
|
3
|
+
* Uses instances.vantage.sh API (no auth required)
|
|
4
|
+
* Data source: https://instances.vantage.sh/gcp/instances.json
|
|
5
|
+
*
|
|
6
|
+
* Coverage: 287 GCP instance types across 40+ regions
|
|
7
|
+
*/
|
|
8
|
+
import type { ComputeInstance } from '../../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Fetch all GCP compute instance pricing
|
|
11
|
+
*/
|
|
12
|
+
export declare function fetchGCPComputePricing(options?: {
|
|
13
|
+
region?: string;
|
|
14
|
+
family?: string;
|
|
15
|
+
includeSpot?: boolean;
|
|
16
|
+
maxResults?: number;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
instances: ComputeInstance[];
|
|
19
|
+
totalCount: number;
|
|
20
|
+
timestamp: string;
|
|
21
|
+
source: string;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Get available GCP regions from the data
|
|
25
|
+
*/
|
|
26
|
+
export declare function getGCPRegions(): Promise<{
|
|
27
|
+
code: string;
|
|
28
|
+
name: string;
|
|
29
|
+
}[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Get GCP instance families with counts
|
|
32
|
+
*/
|
|
33
|
+
export declare function getGCPInstanceFamilies(): Promise<{
|
|
34
|
+
family: string;
|
|
35
|
+
count: number;
|
|
36
|
+
}[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if GCP data source is accessible
|
|
39
|
+
*/
|
|
40
|
+
export declare function checkGCPAPIStatus(): Promise<{
|
|
41
|
+
available: boolean;
|
|
42
|
+
message: string;
|
|
43
|
+
}>;
|
|
44
|
+
//# sourceMappingURL=gcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcp.d.ts","sourceRoot":"","sources":["../../../src/data/fetchers/gcp.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,gBAAgB,CAAC;AAyCvE;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,CAAC,EAAE;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,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,CAiFD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAsB/E;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAmB3F;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB1F"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Cost MCP - GCP Real-Time Pricing Fetcher
|
|
3
|
+
* Uses instances.vantage.sh API (no auth required)
|
|
4
|
+
* Data source: https://instances.vantage.sh/gcp/instances.json
|
|
5
|
+
*
|
|
6
|
+
* Coverage: 287 GCP instance types across 40+ regions
|
|
7
|
+
*/
|
|
8
|
+
import { pricingCache } from '../cache.js';
|
|
9
|
+
// Data source endpoint (public, no auth required)
|
|
10
|
+
const GCP_INSTANCES_URL = 'https://instances.vantage.sh/gcp/instances.json';
|
|
11
|
+
// Cache settings
|
|
12
|
+
const CACHE_KEY_GCP = 'GCP_COMPUTE_REALTIME';
|
|
13
|
+
const CACHE_TTL_MINUTES = 60;
|
|
14
|
+
/**
|
|
15
|
+
* Fetch all GCP compute instance pricing
|
|
16
|
+
*/
|
|
17
|
+
export async function fetchGCPComputePricing(options) {
|
|
18
|
+
const region = options?.region || 'us-central1';
|
|
19
|
+
const maxResults = options?.maxResults || 300;
|
|
20
|
+
// Check cache first
|
|
21
|
+
const cacheKey = `${CACHE_KEY_GCP}_${region}`;
|
|
22
|
+
const cached = pricingCache.get(cacheKey);
|
|
23
|
+
if (cached) {
|
|
24
|
+
return {
|
|
25
|
+
instances: filterAndLimit(cached, options, maxResults),
|
|
26
|
+
totalCount: cached.length,
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
source: 'cache',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const response = await fetch(GCP_INSTANCES_URL);
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
throw new Error(`Failed to fetch GCP data: ${response.status}`);
|
|
35
|
+
}
|
|
36
|
+
const data = await response.json();
|
|
37
|
+
const instances = [];
|
|
38
|
+
for (const item of data) {
|
|
39
|
+
const regionPricing = item.pricing[region];
|
|
40
|
+
if (!regionPricing?.linux?.ondemand)
|
|
41
|
+
continue;
|
|
42
|
+
const hourlyPrice = parseFloat(regionPricing.linux.ondemand);
|
|
43
|
+
if (isNaN(hourlyPrice) || hourlyPrice === 0)
|
|
44
|
+
continue;
|
|
45
|
+
const category = mapGCPFamilyToCategory(item.family);
|
|
46
|
+
let notes = item.pretty_name || item.instance_type;
|
|
47
|
+
if (item.GPU && item.GPU > 0) {
|
|
48
|
+
notes += ` (${item.GPU}x ${item.GPU_model || 'GPU'})`;
|
|
49
|
+
}
|
|
50
|
+
if (item.shared_cpu) {
|
|
51
|
+
notes += ' - Shared CPU';
|
|
52
|
+
}
|
|
53
|
+
if (options?.includeSpot && regionPricing.linux?.spot) {
|
|
54
|
+
const spotPrice = parseFloat(regionPricing.linux.spot);
|
|
55
|
+
if (!isNaN(spotPrice)) {
|
|
56
|
+
const savings = Math.round((1 - spotPrice / hourlyPrice) * 100);
|
|
57
|
+
notes += ` | Spot: $${spotPrice.toFixed(4)}/hr (${savings}% off)`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
instances.push({
|
|
61
|
+
provider: 'gcp',
|
|
62
|
+
name: item.instance_type,
|
|
63
|
+
displayName: `${item.instance_type} (${item.family})`,
|
|
64
|
+
vcpus: item.vCPU,
|
|
65
|
+
memoryGB: item.memory,
|
|
66
|
+
hourlyPrice,
|
|
67
|
+
monthlyPrice: Math.round(hourlyPrice * 730 * 100) / 100,
|
|
68
|
+
region,
|
|
69
|
+
category,
|
|
70
|
+
architecture: 'x86', // GCP doesn't have ARM yet in this dataset
|
|
71
|
+
gpuCount: item.GPU || undefined,
|
|
72
|
+
gpuType: item.GPU_model || undefined,
|
|
73
|
+
notes,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Sort by monthly price
|
|
77
|
+
instances.sort((a, b) => a.monthlyPrice - b.monthlyPrice);
|
|
78
|
+
// Cache the full result
|
|
79
|
+
pricingCache.set(cacheKey, instances, CACHE_TTL_MINUTES);
|
|
80
|
+
return {
|
|
81
|
+
instances: filterAndLimit(instances, options, maxResults),
|
|
82
|
+
totalCount: instances.length,
|
|
83
|
+
timestamp: new Date().toISOString(),
|
|
84
|
+
source: GCP_INSTANCES_URL,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
throw new Error(`Failed to fetch GCP pricing: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get available GCP regions from the data
|
|
93
|
+
*/
|
|
94
|
+
export async function getGCPRegions() {
|
|
95
|
+
try {
|
|
96
|
+
const response = await fetch(GCP_INSTANCES_URL);
|
|
97
|
+
if (!response.ok)
|
|
98
|
+
return [];
|
|
99
|
+
const data = await response.json();
|
|
100
|
+
if (data.length === 0)
|
|
101
|
+
return [];
|
|
102
|
+
// Get regions from first instance that has the regions map
|
|
103
|
+
const firstWithRegions = data.find(d => d.regions);
|
|
104
|
+
if (!firstWithRegions?.regions) {
|
|
105
|
+
// Fallback: get region codes from pricing keys
|
|
106
|
+
const regions = Object.keys(data[0].pricing || {});
|
|
107
|
+
return regions.map(code => ({ code, name: code })).sort((a, b) => a.code.localeCompare(b.code));
|
|
108
|
+
}
|
|
109
|
+
return Object.entries(firstWithRegions.regions)
|
|
110
|
+
.map(([code, name]) => ({ code, name }))
|
|
111
|
+
.sort((a, b) => a.code.localeCompare(b.code));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get GCP instance families with counts
|
|
119
|
+
*/
|
|
120
|
+
export async function getGCPInstanceFamilies() {
|
|
121
|
+
try {
|
|
122
|
+
const response = await fetch(GCP_INSTANCES_URL);
|
|
123
|
+
if (!response.ok)
|
|
124
|
+
return [];
|
|
125
|
+
const data = await response.json();
|
|
126
|
+
const familyCounts = new Map();
|
|
127
|
+
for (const item of data) {
|
|
128
|
+
const count = familyCounts.get(item.family) || 0;
|
|
129
|
+
familyCounts.set(item.family, count + 1);
|
|
130
|
+
}
|
|
131
|
+
return Array.from(familyCounts.entries())
|
|
132
|
+
.map(([family, count]) => ({ family, count }))
|
|
133
|
+
.sort((a, b) => b.count - a.count);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Check if GCP data source is accessible
|
|
141
|
+
*/
|
|
142
|
+
export async function checkGCPAPIStatus() {
|
|
143
|
+
try {
|
|
144
|
+
const response = await fetch(GCP_INSTANCES_URL, { method: 'HEAD' });
|
|
145
|
+
if (response.ok) {
|
|
146
|
+
return {
|
|
147
|
+
available: true,
|
|
148
|
+
message: 'instances.vantage.sh GCP API is accessible (287 instance types, 40+ regions)',
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return { available: false, message: `API returned status ${response.status}` };
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
return {
|
|
155
|
+
available: false,
|
|
156
|
+
message: `API check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Helper functions
|
|
161
|
+
function mapGCPFamilyToCategory(family) {
|
|
162
|
+
const familyLower = family.toLowerCase();
|
|
163
|
+
if (familyLower.includes('compute'))
|
|
164
|
+
return 'compute';
|
|
165
|
+
if (familyLower.includes('memory'))
|
|
166
|
+
return 'memory';
|
|
167
|
+
if (familyLower.includes('storage'))
|
|
168
|
+
return 'storage';
|
|
169
|
+
if (familyLower.includes('accelerator') || familyLower.includes('gpu'))
|
|
170
|
+
return 'gpu';
|
|
171
|
+
if (familyLower.includes('machine learning') || familyLower.includes('asic'))
|
|
172
|
+
return 'gpu';
|
|
173
|
+
return 'general';
|
|
174
|
+
}
|
|
175
|
+
function filterAndLimit(instances, options, maxResults) {
|
|
176
|
+
let filtered = instances;
|
|
177
|
+
if (options?.family) {
|
|
178
|
+
filtered = filtered.filter(i => i.displayName?.toLowerCase().includes(options.family.toLowerCase()));
|
|
179
|
+
}
|
|
180
|
+
return filtered.slice(0, maxResults);
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=gcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcp.js","sourceRoot":"","sources":["../../../src/data/fetchers/gcp.ts"],"names":[],"mappings":"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"}
|