@jadenrazo/cloudcost-mcp 1.0.0 → 1.2.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/CHANGELOG.md +56 -5
- package/README.md +70 -115
- package/VERSIONING.md +99 -0
- package/data/aws-pricing/metadata.json +8 -0
- package/data/azure-pricing/metadata.json +8 -0
- package/data/gcp-pricing/metadata.json +4 -2
- package/dist/{chunk-E7KOWAMW.js → chunk-CGMU4ETN.js} +2010 -1209
- package/dist/{chunk-TRRAOOVF.js → chunk-LWTVE7UY.js} +31 -1
- package/dist/cli.d.ts +41 -0
- package/dist/cli.js +63 -22
- package/dist/index.js +391 -145
- package/dist/{loader-VXYJYDIH.js → loader-CMBV7346.js} +6 -2
- package/package.json +34 -21
- package/MIGRATION.md +0 -40
- package/STABILITY.md +0 -71
package/CHANGELOG.md
CHANGED
|
@@ -4,13 +4,64 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [1.2.0] - 2026-08-07
|
|
10
|
+
|
|
11
|
+
> Released as 1.2.0, not 1.1.0. The `v1.1.0` tag was already taken by an earlier
|
|
12
|
+
> 2026-04-16 release that was superseded by the `v1.0.1` hotfix and never
|
|
13
|
+
> published to npm; npm therefore goes `1.0.1` → `1.2.0`.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`check_cost_budget` MCP tool**: agent-ready cost guardrail that returns `allow` / `warn` / `block` with `blocking_resources` populated. Designed to be called by an AI agent between generating IaC and writing it to disk, so a model can't silently commit a runaway configuration. Promotes the budget primitives that previously only lived inside `detect_anomalies`. See [docs/guardrails.md](./docs/guardrails.md) for integration patterns.
|
|
18
|
+
- New env vars: `CLOUDCOST_GUARDRAIL_MAX_MONTHLY`, `CLOUDCOST_GUARDRAIL_MAX_PER_RESOURCE`, `CLOUDCOST_GUARDRAIL_WARN_RATIO`. Thresholds cascade: per-call params → `guardrail` env → `budget` env.
|
|
19
|
+
- New `GuardrailConfig` type on `CloudCostConfig`.
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
|
|
23
|
+
- Defense-in-depth on outbound HTTP: the AWS pricing fetchers (`bulk-loader`, `reserved-client`) now validate region and service against a strict allowlist, pin fetches to `pricing.us-east-1.amazonaws.com`, enforce HTTPS, and cap response bodies at 512 MiB. Extends the v1.0.1 MCP-surface hardening down into the network layer. Closes URL-injection via attacker-controlled region/service strings and caps OOM risk from a misbehaving upstream.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- MCP tools migrated from the deprecated `server.tool()` to `server.registerTool()`. Every tool now advertises `annotations.readOnlyHint: true`, and handler failures return a JSON `{error}` text payload with `isError: true` instead of a protocol-level failure. `check_cost_budget`'s structured error results (`provider_unresolved`, `non_finite_total`) also set `isError`. Result payloads remain JSON text in `content[0].text` — no client-facing format change.
|
|
28
|
+
- Graceful shutdown: SIGINT/SIGTERM now close the MCP server connection and the SQLite pricing cache before exit; `unhandledRejection` logs, closes, and exits instead of hard-exiting.
|
|
29
|
+
- Per-resource `monthly_cost` / `yearly_cost` on every `CostEstimate` are now consistently rounded to cents via the new shared estimate factory (previously only data-transfer estimates were rounded; totals were already rounded).
|
|
30
|
+
- Data-transfer (egress) estimates now read regional multipliers from the shared `data/region-price-multipliers.json` instead of drifted per-provider in-file tables; estimates in non-baseline regions shift slightly.
|
|
31
|
+
- Azure and GCP pricing normalizers validate/canonicalize upstream effective dates the same way AWS does (invalid dates fall back to "now"; valid ones normalize to ISO `.000Z` form).
|
|
32
|
+
- Coverage thresholds in `vitest.config.ts` set to 75 / 71 / 80 / 75 (statements / branches / functions / lines) and now enforced in CI: the test job runs `npm run test:coverage`, so a regression below the floor fails the build. 71 is the measured branch-coverage floor at gate-enable time; the other thresholds were already met.
|
|
33
|
+
- Lint upgraded to typescript-eslint `recommendedTypeChecked` for `src/` with `@typescript-eslint/no-explicit-any` promoted to error; the publish workflow now runs `npm run lint` before publishing and attaches a CycloneDX SBOM (`sbom.cdx.json`) to each GitHub release.
|
|
34
|
+
- README: corrected the Limitations bullet that implied AWS Savings Plans were supported via `optimize_cost`. Savings Plans are not yet supported and are tracked in [docs/roadmap.md](./docs/roadmap.md).
|
|
35
|
+
|
|
36
|
+
### Tests
|
|
37
|
+
|
|
38
|
+
- `src/reporting/csv-escape.ts` extracted out of `csv-report` and `focus-report`; dedicated `csv-escape.test.ts` covers the formula-injection defense surface.
|
|
39
|
+
- `test/helpers/factories.ts` + `setup.ts` centralise test fixture construction; `test/integration/full-stack.test.ts` replaces the older end-to-end test with wider tool coverage.
|
|
40
|
+
- New unit tests: `api-gateway`, `messaging`, `ml-ai`, `search`, `waf`, `csv-parser`, `resource-extractor`, `markdown-report`, `check-cost-budget`.
|
|
41
|
+
- New `register-tools` suite locks the MCP surface: all 12 tools register, names match VERSIONING.md's locked table, every tool carries `readOnlyHint`, and the error envelope (`isError` + JSON `{error}`) is exercised end-to-end over an in-memory transport.
|
|
42
|
+
|
|
43
|
+
## [1.0.1] - 2026-04-18
|
|
44
|
+
|
|
45
|
+
### Security
|
|
46
|
+
|
|
47
|
+
Hardened the MCP tool surface against the attack classes catalogued in the OWASP MCP Top 10 (2025) and recent SDK advisories. No breaking API changes.
|
|
48
|
+
|
|
49
|
+
- **Path traversal in module resolution (HIGH)**: A `module { source = "../../../etc" }` declaration in user-supplied HCL previously resolved without any containment check, turning any file-accepting tool into an arbitrary `*.tf` read primitive. All resolved paths are now confined to `process.cwd()` by default (configurable), symlinks are rejected, and `modules.json` entries are re-validated against the boundary. Added `src/parsers/path-safety.ts`.
|
|
50
|
+
- **MCP SDK floor (MED)**: Bumped `@modelcontextprotocol/sdk` minimum from `^1.12.1` to `^1.25.2` so fresh installs cannot resolve a version affected by CVE-2025-66414 (DNS rebinding, `< 1.24.0`) or CVE-2026-0621 (UriTemplate ReDoS, `< 1.25.2`).
|
|
51
|
+
- **Prototype pollution in `plan_json` / `state_json` (MED)**: Raw `JSON.parse` on user input followed by deep-merge was vulnerable to `__proto__` / `constructor` / `prototype` payloads. Added `safeJsonParse` with a reviver that strips these keys, applied to the Terraform plan and state parsers and to the HCL-JSON merge in `module-resolver`.
|
|
52
|
+
- **Output-channel prompt injection ("Poison Everywhere", MED)**: User-supplied filenames, module names, and error strings were echoed verbatim into error responses and warnings. Added `sanitizeForMessage` which strips ASCII control characters, zero-width / bidi-override characters, and caps length; applied at every point where tool results flow back to the MCP client.
|
|
53
|
+
- **Input-size DoS (LOW-MED)**: Tool inputs had no size limits. Added Zod `.max()` on every accepting schema — 5 MiB per file, 20 MiB per plan/state payload, 1 KiB per path, max 2000 files per request.
|
|
54
|
+
|
|
55
|
+
### Tests
|
|
56
|
+
|
|
57
|
+
- Added `test/unit/security/mcp-hardening.test.ts` with 19 regression tests covering sanitisation, prototype-pollution guards, path-boundary enforcement, symlink rejection, and every new Zod size limit.
|
|
58
|
+
|
|
7
59
|
## [1.0.0] - 2026-04-15
|
|
8
60
|
|
|
9
|
-
First stable release. No breaking API changes from 0.5 — this version ratifies the existing surface as SemVer-locked. See [`
|
|
61
|
+
First stable release. No breaking API changes from 0.5 — this version ratifies the existing surface as SemVer-locked. See [`VERSIONING.md`](./VERSIONING.md#migration-notes) for details.
|
|
10
62
|
|
|
11
63
|
### Added
|
|
12
|
-
- **`
|
|
13
|
-
- **`MIGRATION.md`**: 0.x → 1.0 migration guide and forward-looking support policy.
|
|
64
|
+
- **`VERSIONING.md`**: Formal stability contract defining the SemVer-locked public surface (12 MCP tools, CLI binaries, package entry points), the change-classification policy, and the 0.x → 1.0 migration notes. (At release this lived in two files, `STABILITY.md` and `MIGRATION.md`; they were later consolidated.)
|
|
14
65
|
- **Smoke integration tests**: Live-API smoke coverage for AWS Bulk Pricing, Azure Retail Prices, and GCP Cloud Billing Catalog, gated behind `RUN_INTEGRATION=1`. New `integration-smoke` CI job runs on manual dispatch and weekly schedule (Mondays 12:00 UTC).
|
|
15
66
|
- **Publish workflow gates**: `npm audit --audit-level=high` and `npm test` now run before `npm publish`, preventing broken or vulnerable releases.
|
|
16
67
|
|
|
@@ -23,7 +74,7 @@ First stable release. No breaking API changes from 0.5 — this version ratifies
|
|
|
23
74
|
- `npm audit --audit-level=high` now reports zero vulnerabilities.
|
|
24
75
|
|
|
25
76
|
### Packaging
|
|
26
|
-
- `
|
|
77
|
+
- `VERSIONING.md` and `CHANGELOG.md` are now included in the published npm tarball. (Originally shipped as `STABILITY.md` + `MIGRATION.md`, now merged.)
|
|
27
78
|
|
|
28
79
|
## [0.4.0] - 2026-03-28
|
|
29
80
|
|
|
@@ -44,7 +95,7 @@ First stable release. No breaking API changes from 0.5 — this version ratifies
|
|
|
44
95
|
- **Performance benchmarks**: Parsing, pricing cache, and calculator benchmarks via `vitest bench`
|
|
45
96
|
- **CI hardening**: Security audit job, Prettier format check, concurrency groups, job timeouts
|
|
46
97
|
- **SECURITY.md**: Vulnerability reporting policy and security design documentation
|
|
47
|
-
-
|
|
98
|
+
- **`docs/architecture.md`**: Layered architecture documentation with extension guides (originally at repo root, moved to `docs/` in a later cleanup).
|
|
48
99
|
|
|
49
100
|
### Changed
|
|
50
101
|
- Refactored `bulk-loader.ts` (929 -> 708 lines) into focused modules: csv-parser, fallback-data
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://github.com/jadenrazo/CloudCostMCP/actions/workflows/ci.yml"><img src="https://github.com/jadenrazo/CloudCostMCP/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
11
11
|
<a href="https://www.npmjs.com/package/@jadenrazo/cloudcost-mcp"><img src="https://img.shields.io/npm/v/@jadenrazo/cloudcost-mcp.svg" alt="npm version" /></a>
|
|
12
12
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
|
|
13
|
-
<img src="https://img.shields.io/badge/node-%3E%
|
|
13
|
+
<img src="https://img.shields.io/badge/node-%3E%3D24-brightgreen" alt="Node.js" />
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p align="right">
|
|
@@ -53,28 +53,55 @@ CloudCost MCP is a [Model Context Protocol](https://modelcontextprotocol.io) ser
|
|
|
53
53
|
| Pulumi | `.json` (stack export) | Yes |
|
|
54
54
|
| Bicep/ARM | `.json` (ARM template) | Yes |
|
|
55
55
|
|
|
56
|
+
### How this compares to Infracost
|
|
57
|
+
|
|
58
|
+
Infracost is the mature choice for **Terraform-on-AWS cost estimation in CI** — PR-comment cost deltas, threshold gating, deep Terragrunt support. If that's your workflow, use it.
|
|
59
|
+
|
|
60
|
+
CloudCostMCP targets a different surface:
|
|
61
|
+
|
|
62
|
+
- **Agent-native via MCP.** Models call it as a tool *during* generation. `check_cost_budget` returns `allow` / `warn` / `block` with the specific blocking resources named, fast enough on a warm pricing cache for an agent to veto an expensive config before writing it to disk.
|
|
63
|
+
- **Multi-IaC in one server.** Terraform, CloudFormation, Pulumi, Bicep/ARM — one tool, not four.
|
|
64
|
+
- **Zero credentials.** All pricing comes from public endpoints. No account, no cloud IAM, no API keys.
|
|
65
|
+
- **Optimization + what-if scenarios built in.** Right-sizing, reserved-pricing, cross-provider switching, and spot modeling are first-class tools.
|
|
66
|
+
|
|
67
|
+
The two are complementary. Use Infracost in CI; use CloudCostMCP inside your agent or editor.
|
|
68
|
+
|
|
56
69
|
---
|
|
57
70
|
|
|
58
71
|
## Installation
|
|
59
72
|
|
|
60
73
|
Requires **Node.js 20** or later.
|
|
61
74
|
|
|
75
|
+
### 60-second quick start (Claude Code)
|
|
76
|
+
|
|
62
77
|
```bash
|
|
78
|
+
npm install -g @jadenrazo/cloudcost-mcp
|
|
79
|
+
claude mcp add cloudcost -- cloudcost-mcp
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then, inside a project directory with Terraform files, ask Claude:
|
|
83
|
+
|
|
84
|
+
> *"Use cloudcost to estimate the monthly AWS cost of this Terraform config, then check it against a $2000/month budget with check_cost_budget."*
|
|
85
|
+
|
|
86
|
+
No API keys, no cloud credentials, no separate account. For other MCP clients (Claude Desktop, Cursor, any MCP-compatible agent), see the detailed setup below.
|
|
87
|
+
|
|
88
|
+
### All install options
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# From source
|
|
63
92
|
git clone https://github.com/jadenrazo/CloudCostMCP.git
|
|
64
93
|
cd CloudCostMCP
|
|
65
94
|
npm install
|
|
66
95
|
npm run build
|
|
67
96
|
```
|
|
68
97
|
|
|
69
|
-
Or install from npm:
|
|
70
|
-
|
|
71
98
|
```bash
|
|
99
|
+
# Global npm install
|
|
72
100
|
npm install -g @jadenrazo/cloudcost-mcp
|
|
73
101
|
```
|
|
74
102
|
|
|
75
|
-
Or run directly without installing:
|
|
76
|
-
|
|
77
103
|
```bash
|
|
104
|
+
# One-shot, no install
|
|
78
105
|
npx -y @jadenrazo/cloudcost-mcp
|
|
79
106
|
```
|
|
80
107
|
|
|
@@ -127,7 +154,9 @@ node dist/index.js
|
|
|
127
154
|
|
|
128
155
|
## Tools
|
|
129
156
|
|
|
130
|
-
The server exposes
|
|
157
|
+
The server exposes twelve MCP tools. Each accepts JSON input and returns structured JSON output. For agent-centric workflows, `check_cost_budget` is the headline tool: it returns an `allow` / `warn` / `block` verdict fast enough to be called between IaC generation and disk write — see [docs/guardrails.md](./docs/guardrails.md).
|
|
158
|
+
|
|
159
|
+
Cost-reporting tools (`estimate_cost`, `compare_providers`, `check_cost_budget`, `analyze_plan`, `compare_actual`) also include a `pricing_metadata` block — `{ source, as_of, age_days, staleness }` — describing the vintage of the bundled pricing data behind the numbers (`fresh` < 14 days, `aging` < 45 days, `stale` ≥ 45 days; `compare_providers` reports one block per compared provider). When a non-USD `currency` is requested, responses additionally carry `exchange_rate: { rate, rate_as_of }` — conversions use a static rate snapshot (currently `2026-03`), not a live FX feed.
|
|
131
160
|
|
|
132
161
|
### `analyze_terraform`
|
|
133
162
|
|
|
@@ -262,6 +291,21 @@ Cost anomaly detection with budget checks, price changes, concentration risk, an
|
|
|
262
291
|
| `budget_monthly` | `number` | No | Monthly budget cap in USD |
|
|
263
292
|
| `currency` | `string` | No | Output currency (default: `USD`) |
|
|
264
293
|
|
|
294
|
+
### `check_cost_budget`
|
|
295
|
+
|
|
296
|
+
Fast cost-safety guardrail designed for AI agents. Returns `allow` / `warn` / `block` with the specific blocking resources named, so an agent can veto an expensive IaC generation before writing it to disk. Thresholds cascade: per-call params → `CLOUDCOST_GUARDRAIL_*` env → `CLOUDCOST_BUDGET_*` env. See [docs/guardrails.md](./docs/guardrails.md) for integration patterns.
|
|
297
|
+
|
|
298
|
+
| Parameter | Type | Required | Description |
|
|
299
|
+
|-----------|------|----------|-------------|
|
|
300
|
+
| `files` | `{path, content}[]` | Yes | IaC files to evaluate |
|
|
301
|
+
| `tfvars` | `string` | No | Variable overrides |
|
|
302
|
+
| `provider` | `aws \| azure \| gcp` | No | Target provider (auto-detected if omitted) |
|
|
303
|
+
| `region` | `string` | No | Target region (auto-detected if omitted) |
|
|
304
|
+
| `currency` | `string` | No | Output currency (default: `USD`) |
|
|
305
|
+
| `max_monthly` | `number` | No | Aggregate monthly threshold. Over = `block`. |
|
|
306
|
+
| `max_per_resource` | `number` | No | Per-resource threshold. One over = `block`. |
|
|
307
|
+
| `warn_ratio` | `number` (0–1) | No | Fraction of limit that triggers `warn` (default `0.8`) |
|
|
308
|
+
|
|
265
309
|
---
|
|
266
310
|
|
|
267
311
|
## How Pricing Works
|
|
@@ -374,12 +418,15 @@ All configuration is optional. The server works out of the box with sensible def
|
|
|
374
418
|
| `CLOUDCOST_CACHE_PATH` | `~/.cloudcost/cache.db` | SQLite cache file location |
|
|
375
419
|
| `CLOUDCOST_LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error` |
|
|
376
420
|
| `CLOUDCOST_MONTHLY_HOURS` | `730` | Hours per month for cost calculations |
|
|
377
|
-
| `CLOUDCOST_INCLUDE_DATA_TRANSFER` | `
|
|
421
|
+
| `CLOUDCOST_INCLUDE_DATA_TRANSFER` | `true` | Include a synthetic default estimate of 100 GB/month internet egress per provider+region. Its share of the total is surfaced separately as `estimated_egress_monthly` (still included in `total_monthly`) |
|
|
378
422
|
| `CLOUDCOST_PRICING_MODEL` | `on_demand` | Default pricing model: `on_demand`, `spot`, or `reserved` |
|
|
379
423
|
| `CLOUDCOST_RESOLVE_MODULES` | `true` | Expand referenced Terraform modules during parsing |
|
|
380
424
|
| `CLOUDCOST_BUDGET_MONTHLY` | | Monthly budget cap in USD. Triggers a warning when exceeded |
|
|
381
425
|
| `CLOUDCOST_BUDGET_PER_RESOURCE` | | Per-resource monthly budget cap in USD |
|
|
382
426
|
| `CLOUDCOST_BUDGET_WARN_PCT` | `80` | Percentage of budget at which a warning is surfaced (default: 80%) |
|
|
427
|
+
| `CLOUDCOST_GUARDRAIL_MAX_MONTHLY` | | Aggregate monthly ceiling for `check_cost_budget`. Over = `block` verdict |
|
|
428
|
+
| `CLOUDCOST_GUARDRAIL_MAX_PER_RESOURCE` | | Per-resource ceiling for `check_cost_budget`. One over = `block` verdict |
|
|
429
|
+
| `CLOUDCOST_GUARDRAIL_WARN_RATIO` | `0.8` | Fraction of guardrail threshold that triggers `warn` instead of `allow` |
|
|
383
430
|
|
|
384
431
|
### Config File
|
|
385
432
|
|
|
@@ -441,13 +488,7 @@ Configuration priority: environment variables > config file > built-in defaults.
|
|
|
441
488
|
CSV (public) (public, no auth) (bundled files)
|
|
442
489
|
```
|
|
443
490
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
- **Zero API keys.** All pricing comes from public endpoints. AWS uses the unauthenticated Bulk Pricing files. Azure uses the free Retail Prices REST API. GCP queries the Cloud Billing Catalog API with bundled fallback.
|
|
447
|
-
- **SQLite cache.** A single `better-sqlite3` database caches all pricing lookups with configurable TTL. Shared across all tools per server lifetime.
|
|
448
|
-
- **Streaming for large files.** AWS EC2 pricing data (~267 MB CSV) is streamed line-by-line rather than loaded into memory. Prices for a region are extracted in one pass and cached.
|
|
449
|
-
- **Graceful degradation.** If any live pricing source is unavailable, the server falls back to built-in tables with size-interpolation. Every response includes the pricing source so the consumer knows the confidence level.
|
|
450
|
-
- **ESM-only.** Requires Node 20+. All internal imports use `.js` extensions.
|
|
491
|
+
Highlights: zero API keys (all providers exposed via public endpoints), SQLite-backed price cache shared across tool calls, streaming ingest for the 267 MB AWS bulk CSV, and a graceful live → fallback → interpolated-table chain so every response carries a `pricing_source` and `confidence` field. Full layer-by-layer walkthrough and extension guides in [docs/architecture.md](./docs/architecture.md).
|
|
451
492
|
|
|
452
493
|
---
|
|
453
494
|
|
|
@@ -475,113 +516,27 @@ Instance type mapping covers 70+ AWS instance types (including Graviton/ARM fami
|
|
|
475
516
|
|
|
476
517
|
## Limitations
|
|
477
518
|
|
|
478
|
-
- **On-demand pricing only** by default. Prices reflect pay-as-you-go rates. The `optimize_cost` tool
|
|
519
|
+
- **On-demand pricing only** by default. Prices reflect pay-as-you-go rates. The `optimize_cost` tool recommends reserved instances; AWS Savings Plans are not yet supported (tracked in [docs/roadmap.md](./docs/roadmap.md)). Pass `pricing_model: "spot"` in `what_if` scenarios to model spot/preemptible pricing.
|
|
479
520
|
- **GCP live pricing** is fetched from the Cloud Billing Catalog API with automatic fallback to bundled data when the API is unreachable. Bundled prices may lag slightly behind actual rates.
|
|
521
|
+
- **Fallback-data signaling.** When a live pricing API is unreachable and `estimate_cost` / `compare_providers` / `get_pricing` serve data from bundled or fallback tables, the response includes a `warnings` entry ("using fallback/bundled pricing data for …") so callers can flag stale estimates. Bundled data is refreshed weekly via CI.
|
|
522
|
+
- **Synthetic egress line item.** Unless `CLOUDCOST_INCLUDE_DATA_TRANSFER=false`, every breakdown includes an assumed 100 GB/month of internet egress per provider+region. `total_monthly` includes it (unchanged behavior); its share is reported separately as `estimated_egress_monthly` with an explanatory warning so the composition is visible.
|
|
523
|
+
- **Static FX rates.** Non-USD output is converted with a bundled rate table, not a live feed. Every converted response carries `exchange_rate: { rate, rate_as_of }` so consumers know which snapshot produced the figures.
|
|
480
524
|
- **First request latency**. The initial EC2 pricing lookup for a new AWS region may take 30-120 seconds as the CSV file is streamed. Subsequent lookups for the same region are instant (cached for 24 hours).
|
|
481
525
|
- **Specialty instance types**. GPU instances (p4d, g5, etc.), high-memory (x2idn), and bare-metal types may fall back to interpolated pricing if not in the built-in tables and live fetch fails.
|
|
482
526
|
|
|
483
527
|
---
|
|
484
528
|
|
|
485
|
-
##
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
**
|
|
490
|
-
|
|
491
|
-
**
|
|
492
|
-
|
|
493
|
-
**
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
## GitHub Actions
|
|
498
|
-
|
|
499
|
-
A reusable composite action is included at `.github/actions/cost-estimate/`. It detects changed `.tf` files, runs a cost comparison, and posts the result as a PR comment.
|
|
500
|
-
|
|
501
|
-
```yaml
|
|
502
|
-
# .github/workflows/cost-estimate.yml
|
|
503
|
-
name: Terraform Cost Estimate
|
|
504
|
-
|
|
505
|
-
on:
|
|
506
|
-
pull_request:
|
|
507
|
-
types: [opened, synchronize]
|
|
508
|
-
|
|
509
|
-
jobs:
|
|
510
|
-
cost-estimate:
|
|
511
|
-
runs-on: ubuntu-latest
|
|
512
|
-
permissions:
|
|
513
|
-
contents: read
|
|
514
|
-
pull-requests: write
|
|
515
|
-
steps:
|
|
516
|
-
- uses: actions/checkout@v4
|
|
517
|
-
with:
|
|
518
|
-
fetch-depth: 0
|
|
519
|
-
|
|
520
|
-
- uses: ./.github/actions/cost-estimate
|
|
521
|
-
with:
|
|
522
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
523
|
-
# terraform_dir: "./terraform"
|
|
524
|
-
# providers: "aws,azure,gcp"
|
|
525
|
-
# format: "markdown"
|
|
526
|
-
# currency: "USD"
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
The action auto-detects the directory containing changed `.tf` files and skips gracefully when no Terraform changes are present in the PR.
|
|
530
|
-
|
|
531
|
-
---
|
|
532
|
-
|
|
533
|
-
## Development
|
|
534
|
-
|
|
535
|
-
```bash
|
|
536
|
-
npm run dev # Run with tsx (hot reload, no build needed)
|
|
537
|
-
npm test # Run all tests (vitest)
|
|
538
|
-
npm run test:watch # Watch mode
|
|
539
|
-
npm run build # Production build (tsup → dist/)
|
|
540
|
-
npm run lint # Type check (tsc --noEmit)
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
### Project Structure
|
|
544
|
-
|
|
545
|
-
```
|
|
546
|
-
src/
|
|
547
|
-
├── index.ts # Entry point (process error handlers + start)
|
|
548
|
-
├── server.ts # MCP server setup, tool registration
|
|
549
|
-
├── config.ts # Config loader (defaults → file → env vars)
|
|
550
|
-
├── logger.ts # Structured logger
|
|
551
|
-
├── currency.ts # Multi-currency conversion and formatting
|
|
552
|
-
├── tools/
|
|
553
|
-
│ ├── ... # MCP tool handlers + Zod schemas
|
|
554
|
-
│ └── what-if.ts # Hypothetical scenario modeling
|
|
555
|
-
├── parsers/
|
|
556
|
-
│ ├── ... # HCL parsing, variable resolution
|
|
557
|
-
│ ├── module-resolver.ts # Terraform module expansion
|
|
558
|
-
│ └── dependency-graph.ts # Resource dependency graph builder
|
|
559
|
-
├── pricing/
|
|
560
|
-
│ ├── pricing-engine.ts # Router: dispatches to provider adapters
|
|
561
|
-
│ ├── cache.ts # SQLite-backed pricing cache
|
|
562
|
-
│ ├── aws/ # Bulk CSV streaming + JSON + fallback
|
|
563
|
-
│ ├── azure/ # Retail Prices REST API + fallback
|
|
564
|
-
│ └── gcp/
|
|
565
|
-
│ ├── bundled-loader.ts # Static bundled pricing fallback
|
|
566
|
-
│ └── cloud-billing-client.ts # Live GCP Cloud Billing Catalog API
|
|
567
|
-
├── calculator/
|
|
568
|
-
│ ├── ... # Cost calculations per resource type
|
|
569
|
-
│ ├── projection.ts # Multi-horizon cost projections
|
|
570
|
-
│ ├── container-registry.ts
|
|
571
|
-
│ ├── secrets.ts
|
|
572
|
-
│ └── dns.ts
|
|
573
|
-
├── mapping/ # Cross-provider resource/instance mapping
|
|
574
|
-
├── reporting/
|
|
575
|
-
│ ├── ... # Markdown, JSON, CSV formatters
|
|
576
|
-
│ └── focus-report.ts # FOCUS-compliant export format
|
|
577
|
-
└── types/ # Shared TypeScript interfaces
|
|
578
|
-
|
|
579
|
-
data/
|
|
580
|
-
├── instance-map.json # Bidirectional instance type mappings
|
|
581
|
-
├── storage-map.json # Cross-provider storage type mappings
|
|
582
|
-
├── gcp-pricing/ # Bundled GCP pricing data
|
|
583
|
-
└── instance-types/ # Instance type metadata
|
|
584
|
-
```
|
|
529
|
+
## More docs
|
|
530
|
+
|
|
531
|
+
- **[docs/guardrails.md](./docs/guardrails.md)** — `check_cost_budget` integration patterns for Claude Code, Cursor, and other agents.
|
|
532
|
+
- **[docs/architecture.md](./docs/architecture.md)** — internal layers, design decisions, extension guides.
|
|
533
|
+
- **[docs/ci-integration.md](./docs/ci-integration.md)** — GitHub Actions cost-estimate composite action for PR comments.
|
|
534
|
+
- **[docs/development.md](./docs/development.md)** — local setup, npm scripts, source layout.
|
|
535
|
+
- **[docs/troubleshooting.md](./docs/troubleshooting.md)** — `$0` estimates, slow first request, cache issues, fallback warnings.
|
|
536
|
+
- **[docs/roadmap.md](./docs/roadmap.md)** — what's shipped, in flight, backlog, and explicitly not planned.
|
|
537
|
+
- **[VERSIONING.md](./VERSIONING.md)** — SemVer-locked public surface and support policy.
|
|
538
|
+
- **[CONTRIBUTING.md](./CONTRIBUTING.md)** — PR guidelines and code style.
|
|
539
|
+
- **[SECURITY.md](./SECURITY.md)** — vulnerability reporting.
|
|
585
540
|
|
|
586
541
|
---
|
|
587
542
|
|
package/VERSIONING.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Versioning & Stability
|
|
2
|
+
|
|
3
|
+
Starting with v1.0.0, CloudCostMCP follows [Semantic Versioning](https://semver.org/). This document defines the **stable public surface** covered by that guarantee, the change-classification rules that determine major/minor/patch bumps, the support policy, and notes for anyone migrating from v0.x.
|
|
4
|
+
|
|
5
|
+
## Stable surface (SemVer-locked)
|
|
6
|
+
|
|
7
|
+
Changes to anything in this section are breaking and require a major version bump.
|
|
8
|
+
|
|
9
|
+
### MCP tools
|
|
10
|
+
|
|
11
|
+
The following 12 tools and their input schemas are locked. Their names, required fields, and the type shape of their output are stable. See `src/tools/*.ts` for the Zod schemas.
|
|
12
|
+
|
|
13
|
+
| Tool | Purpose |
|
|
14
|
+
| -------------------- | ------------------------------------------------------------------------- |
|
|
15
|
+
| `analyze_terraform` | Parse Terraform HCL and extract a resource inventory |
|
|
16
|
+
| `estimate_cost` | Estimate monthly/yearly cost for a Terraform resource set on one provider |
|
|
17
|
+
| `compare_providers` | Full multi-cloud cost comparison with savings analysis |
|
|
18
|
+
| `get_equivalents` | Map Terraform resource types and instance sizes across providers |
|
|
19
|
+
| `get_pricing` | Direct pricing lookup for a service/resource/region |
|
|
20
|
+
| `optimize_cost` | Right-sizing and reserved-pricing recommendations |
|
|
21
|
+
| `what_if` | Scenario cost modeling without modifying source files |
|
|
22
|
+
| `analyze_plan` | Cost-of-change analysis from a Terraform plan JSON |
|
|
23
|
+
| `compare_actual` | `.tfstate` vs planned cost drift detection |
|
|
24
|
+
| `price_trends` | Historical pricing trend query |
|
|
25
|
+
| `detect_anomalies` | Budget and concentration-risk anomaly detection |
|
|
26
|
+
| `check_cost_budget` | Agent-side cost guardrail with allow/warn/block verdict |
|
|
27
|
+
|
|
28
|
+
### CLI
|
|
29
|
+
|
|
30
|
+
The `cloudcost-mcp` and `cloudcost` binaries and their documented flags in the README are stable.
|
|
31
|
+
|
|
32
|
+
### Package entry points
|
|
33
|
+
|
|
34
|
+
- `main`: `dist/index.js`
|
|
35
|
+
- `types`: `dist/index.d.ts`
|
|
36
|
+
- `bin`: `cloudcost-mcp`, `cloudcost`
|
|
37
|
+
- Node engine: `>=20.0.0`
|
|
38
|
+
|
|
39
|
+
## Not stable (may change in any release)
|
|
40
|
+
|
|
41
|
+
- Internal parser implementations under `src/parsers/`
|
|
42
|
+
- Pricing adapter internals under `src/pricing/aws`, `src/pricing/azure`, `src/pricing/gcp`
|
|
43
|
+
- The on-disk SQLite cache schema (cache is rebuilt on upgrade)
|
|
44
|
+
- Bundled fallback pricing tables under `data/`
|
|
45
|
+
- Log line format and log levels
|
|
46
|
+
- Exit codes beyond `0` (success) and `1` (failure)
|
|
47
|
+
- Benchmark scripts and unreleased helper modules
|
|
48
|
+
|
|
49
|
+
## Change classification
|
|
50
|
+
|
|
51
|
+
| Change | Bump |
|
|
52
|
+
| ------------------------------------------------ | ----- |
|
|
53
|
+
| Remove or rename a tool | Major |
|
|
54
|
+
| Remove a required input field from a tool schema | Major |
|
|
55
|
+
| Change the type of an existing output field | Major |
|
|
56
|
+
| Raise the minimum Node.js version | Major |
|
|
57
|
+
| Add a new tool | Minor |
|
|
58
|
+
| Add an optional input field | Minor |
|
|
59
|
+
| Add a new output field | Minor |
|
|
60
|
+
| Add a new provider/region/resource | Minor |
|
|
61
|
+
| Bugfix | Patch |
|
|
62
|
+
| Performance improvement | Patch |
|
|
63
|
+
| Pricing data refresh | Patch |
|
|
64
|
+
| Dependency bump without API change | Patch |
|
|
65
|
+
|
|
66
|
+
## Deprecation
|
|
67
|
+
|
|
68
|
+
Before a tool or field is removed in a future major, it will be marked deprecated in its description for at least one minor release, with the replacement documented in `CHANGELOG.md`.
|
|
69
|
+
|
|
70
|
+
## Support policy
|
|
71
|
+
|
|
72
|
+
- The latest minor line receives security and bug fixes.
|
|
73
|
+
- The previous minor line receives security fixes only, for 6 months after the next minor is released.
|
|
74
|
+
- CVE reports: see [`SECURITY.md`](./SECURITY.md).
|
|
75
|
+
|
|
76
|
+
## Migration notes
|
|
77
|
+
|
|
78
|
+
### 0.x → 1.0
|
|
79
|
+
|
|
80
|
+
**There are no breaking API changes.** v1.0 ratifies the existing v0.5 surface as stable under SemVer. If your integration works on v0.5.x it will work on v1.0.0 without modification.
|
|
81
|
+
|
|
82
|
+
What v1.0 added beyond the v0.5 surface:
|
|
83
|
+
|
|
84
|
+
- Formal stability contract (this document).
|
|
85
|
+
- Security advisories in transitive dependencies (hono, `@hono/node-server`, path-to-regexp, vite) resolved via npm overrides.
|
|
86
|
+
- Smoke integration tests against live provider pricing APIs, runnable via `RUN_INTEGRATION=1` and scheduled weekly in CI.
|
|
87
|
+
- Hardened npm publish workflow (tests + audit gate releases).
|
|
88
|
+
|
|
89
|
+
Node 20 remains the minimum. No change from v0.5.
|
|
90
|
+
|
|
91
|
+
### Pinning
|
|
92
|
+
|
|
93
|
+
Once on v1.0 you can safely pin with a caret range:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
"@jadenrazo/cloudcost-mcp": "^1.0.0"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
This accepts bugfixes, pricing refreshes, and additive features, and will not pull in breaking changes.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"last_updated": "2026-04-
|
|
2
|
+
"last_updated": "2026-04-15",
|
|
3
3
|
"source": "Google Cloud Pricing Calculator",
|
|
4
4
|
"currency": "USD",
|
|
5
|
-
"notes": "Bundled pricing data for offline/zero-auth usage"
|
|
5
|
+
"notes": "Bundled pricing data for offline/zero-auth usage",
|
|
6
|
+
"refresh_script_version": "2.0.0",
|
|
7
|
+
"sku_count": 1197
|
|
6
8
|
}
|