Metadata-Version: 2.4
Name: opencloudcosts
Version: 0.8.12
Summary: Open source MCP server for accurate public and effective cloud pricing (AWS, GCP, Azure)
Project-URL: Homepage, https://github.com/x7even/cloudcostmcp
Project-URL: Repository, https://github.com/x7even/cloudcostmcp
Project-URL: Issues, https://github.com/x7even/cloudcostmcp/issues
Author-email: x7even <x7sima@gmail.com>
License: MIT
License-File: LICENSE
Keywords: aws,azure,cloud,cost,finops,gcp,mcp,pricing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: aiosqlite>=0.20
Requires-Dist: boto3>=1.34
Requires-Dist: httpx>=0.27
Requires-Dist: mcp[cli]>=1.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: tenacity>=8.0
Provides-Extra: dev
Requires-Dist: boto3-stubs[ce,pricing,savingsplans]>=1.34; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=9.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: tenacity>=8.0; extra == 'dev'
Provides-Extra: gcp
Requires-Dist: google-auth[requests]>=2.38; extra == 'gcp'
Description-Content-Type: text/markdown

# OpenCloudCosts MCP

An open source MCP server that gives AI assistants accurate cloud pricing data for AWS, GCP, and Azure.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![PyPI version](https://badge.fury.io/py/opencloudcosts.svg)](https://pypi.org/project/opencloudcosts/)
[![Tests](https://github.com/x7even/cloudcostmcp/actions/workflows/tests.yml/badge.svg)](https://github.com/x7even/cloudcostmcp/actions/workflows/tests.yml)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)

Supports both **public list pricing** (no credentials needed for AWS and Azure; GCP requires a free API key) and **effective/bespoke pricing** (post-discount: Reserved Instances, Savings Plans, CUDs, EDPs).

## Key Use Cases

- "What is the on-demand price of an m5.xlarge in us-east-1 vs ap-southeast-2, and what's the % delta?"
- "Give me a TCO estimate for this architecture: 3x m5.xlarge + 1x 500GB gp3 EBS in us-east-1"
- "What's the cost per user if I run this stack for 50,000 MAUs?"
- "List all c6g instances in eu-west-1 with >= 8 vCPUs"
- "What's my effective hourly rate on m5.xlarge after Savings Plans?"

## Tools (v0.8.8 — 15 tools)

**Pricing**

| Tool | Description |
|------|-------------|
| `get_price` | Unified pricing dispatcher — compute, storage, database, AI, networking, serverless, analytics, observability |
| `get_prices_batch` | Prices for multiple instance types in one call (concurrent) |
| `compare_prices` | Compare a spec across multiple regions with optional baseline deltas |
| `search_pricing` | Free-text search across the pricing catalog |

**Discovery**

| Tool | Description |
|------|-------------|
| `describe_catalog` | Full support matrix or targeted field guidance + copy-paste `example_invocation` for `get_price` |
| `list_regions` | All regions with friendly names |
| `list_instance_types` | Available instance types with vCPU/memory filters |

**Region Analysis**

| Tool | Description |
|------|-------------|
| `find_cheapest_region` | Cheapest region for any service spec, concurrently |
| `find_available_regions` | Every region where a service is available, sorted by price |
| `get_spot_history` | AWS spot price history and stability analysis (requires credentials) |

**FinOps**

| Tool | Description |
|------|-------------|
| `get_discount_summary` | Account-wide RI / Savings Plan / CUD utilisation (requires credentials) |
| `estimate_bom` | TCO for a multi-resource Bill of Materials |
| `estimate_unit_economics` | Cost per user/request/transaction |

**Cache**

| Tool | Description |
|------|-------------|
| `refresh_cache` | Invalidate pricing cache |
| `cache_stats` | Cache entry counts and DB size |

See [docs/tools.md](docs/tools.md) for full parameter reference and [docs/finops-guide.md](docs/finops-guide.md) for usage examples.

## Setup

### Quick install (recommended)

```bash
# Run directly from PyPI — no clone needed
uvx opencloudcosts

# Or install permanently
pip install opencloudcosts
opencloudcosts
```

### Prerequisites (for development / clone-based install)
- [uv](https://docs.astral.sh/uv/) installed (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
- AWS credentials (optional — public pricing works without them)

### Clone & configure

```bash
git clone https://github.com/x7even/cloudcostmcp opencloudcosts
cd opencloudcosts
cp .env.example .env
# Edit .env if you want effective pricing / Cost Explorer
```

### Test it works

```bash
uv run pytest
```

### Run the server

```bash
uv run opencloudcosts
```

### Run as HTTP server

HTTP transport enables shared/remote deployments — one server, many clients.

```bash
# Localhost only (default)
uv run opencloudcosts --transport http --port 8080

# Bind to all interfaces (e.g. for Docker or remote access)
uv run opencloudcosts --transport http --host 0.0.0.0 --port 8080
```

Environment variable equivalents: `OCC_HTTP_HOST` and `OCC_HTTP_PORT`.

Connect to Claude Code via `.mcp.json`:

```json
{
  "mcpServers": {
    "cloudcost": {
      "transport": "http",
      "url": "http://localhost:8080/mcp/v1"
    }
  }
}
```

### Docker

```bash
# Pull from registry (recommended)
docker pull ghcr.io/x7even/opencloudcosts:latest
docker run -p 8080:8080 \
  -e OCC_GCP_API_KEY=AIza... \
  -v ~/.aws:/root/.aws:ro \
  ghcr.io/x7even/opencloudcosts:latest

# Or build locally
docker build -t opencloudcosts .
docker run -p 8080:8080 opencloudcosts
```

The container starts in HTTP transport mode by default (bound to `0.0.0.0:8080`).
Pass cloud credentials via `-e` flags or mount your AWS credentials directory.

### Connect to Claude Code

Add to your project's `.mcp.json`:

```json
{
  "mcpServers": {
    "cloudcost": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/opencloudcosts", "opencloudcosts"],
      "env": {
        "AWS_PROFILE": "default",
        "OCC_GCP_API_KEY": "AIza..."
      }
    }
  }
}
```

Or to `~/.claude/settings.json` for global access:

```json
{
  "mcpServers": {
    "cloudcost": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/opencloudcosts", "opencloudcosts"]
    }
  }
}
```

### Test with MCP Inspector

```bash
npx @modelcontextprotocol/inspector uv run --directory /path/to/opencloudcosts opencloudcosts
```

## AWS Credentials

| Feature | Credentials needed |
|---------|--------------------|
| Public pricing (EC2, EBS, RDS list prices) | None |
| Effective pricing (RI / SP discounts) | AWS credentials + `OCC_AWS_ENABLE_COST_EXPLORER=true` |

Minimal IAM policy for public pricing:
```json
{
  "Effect": "Allow",
  "Action": ["pricing:GetProducts", "pricing:DescribeServices", "pricing:GetAttributeValues"],
  "Resource": "*"
}
```

Add these for effective pricing:
```json
"ce:GetCostAndUsage", "savingsplans:DescribeSavingsPlans", "savingsplans:DescribeSavingsPlanRates"
```

## Configuration

All settings via environment variables (prefix `OCC_`) or `.env` file:

| Variable | Default | Description |
|----------|---------|-------------|
| `OCC_CACHE_TTL_HOURS` | 24 | Public price cache TTL |
| `OCC_AWS_ENABLE_COST_EXPLORER` | false | Enable AWS effective pricing (costs $0.01/call) |
| `OCC_DEFAULT_REGIONS` | us-east-1,us-west-2 | Default regions |
| `AWS_PROFILE` | (default chain) | AWS credentials profile |
| `OCC_GCP_BILLING_ACCOUNT_ID` | (none) | GCP billing account ID for contract/effective pricing |

## Caching

Prices are cached in SQLite at `~/.cache/opencloudcosts/pricing.db`. Public list prices are cached for 24 hours — AWS pricing changes infrequently. Use the `refresh_cache` tool to force a refresh.

## GCP Setup

Unlike AWS (which has public bulk pricing endpoints), GCP's pricing API always requires at least a free API key. No credit card or billing account is needed.

**Option A — Free API key (recommended, 2 min setup):**
1. Go to [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
2. Create a Project if you don't have one (free)
3. Click **Create Credentials → API key**
4. Set the key:

```bash
export OCC_GCP_API_KEY=AIza...
```

Or add `OCC_GCP_API_KEY=AIza...` to your `.env` file.

**Option B — Application Default Credentials** (if you already use `gcloud`):
```bash
gcloud auth application-default login
# or set GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
```

**GCP instance type format:** `{family}-{series}-{vcpus}` e.g. `n2-standard-4`, `e2-highmem-8`, `c2-standard-16`

### GCP Contract / Effective Pricing

If you have a negotiated pricing contract with Google Cloud, you can retrieve your actual discounted rates (EDP, custom pricing) via the Cloud Billing Pricing API v1beta. This requires:

1. ADC credentials: `gcloud auth application-default login`
2. `billing.billingAccountPrice.get` IAM permission on your billing account
3. Your billing account ID:

```bash
export OCC_GCP_BILLING_ACCOUNT_ID=012345-567890-ABCDEF
```

With this configured, `get_price` responses for GCP compute will include an `effective_price` block showing your contract rate and discount percentage. Without it, public list prices are returned unchanged.

## Azure Setup

Azure pricing is fully public — no credentials, API key, or subscription needed.

```bash
# No configuration needed — works out of the box
uv run opencloudcosts
```

**Azure instance type format:** ARM SKU names e.g. `Standard_D4s_v3`, `Standard_E8s_v3`, `Standard_B2ms`

**Azure pricing terms:** `on_demand` (default), `reserved_1yr`, `reserved_3yr`, `spot`

**Azure regions:** ARM region names e.g. `eastus`, `westeurope`, `southeastasia` (use `list_regions` for full list)

**Azure supported services (v0.8.12):**

| Domain | Service | Description |
|--------|---------|-------------|
| compute | vm | Virtual Machines — all families, Linux/Windows, on-demand/spot/reserved |
| storage | managed_disks | Premium SSD, Standard SSD, Standard HDD, Ultra Disk |
| storage | blob | Blob Storage |
| database | sql | Azure SQL Database, Azure DB for MySQL/PostgreSQL — vCore tiers, HA, reserved |
| database | cosmos | Cosmos DB — provisioned (per 100 RU/s), serverless, autoscale |
| container | aks | AKS cluster management fee (free tier or $0.10/hr Standard) |
| serverless | azure_functions | Functions Consumption plan — per GB-second + per execution |
| ai | openai | Azure OpenAI — GPT-4o, GPT-4, GPT-3.5-Turbo, o1, embeddings |
| inter_region_egress | — | Outbound data transfer — internet and inter-region, Zone 1 rates, 5 GB/month free |

**GCP pricing terms:** `on_demand` (default), `spot` (preemptible), `cud_1yr`, `cud_3yr`

## Security

OpenCloudCosts can access sensitive billing data when configured with cloud credentials (AWS Cost Explorer, GCP billing, Azure contract pricing). Follow these guidelines to keep that data safe.

**Credential hygiene**
- Use dedicated, least-privilege credentials — read-only access scoped to pricing and billing APIs only. Never use root, owner, or admin credentials.
- AWS: create an IAM user/role with only `ce:GetCostAndUsage`, `pricing:GetProducts`, and `savingsplans:Describe*` permissions.
- Store credentials in `.env` (see `.env.example`) and never commit that file to version control.

**Transport security**
- The default `stdio` transport is safe — the server runs as a local process with no network exposure.
- If you use `--transport http`, never expose it publicly without a reverse proxy and authentication in front of it. Treat it as an internal service.

**MCP client trust**
- Only add this server to MCP client configs you control.
- Avoid running it alongside untrusted third-party MCP servers — a malicious server can craft prompts that cause the LLM to call your billing tools and relay the results.

**What this server can access**
With credentials configured: actual spend, contract/negotiated pricing, reservation and savings plan data. Understand this before granting access in shared or multi-user environments.

## Phases

- **Phase 1** ✅ AWS public pricing (EC2, EBS, list instances)
- **Phase 2** ✅ AWS effective pricing (Cost Explorer, Savings Plans, Reserved Instances)
- **Phase 3** ✅ GCP public pricing (Compute Engine families, Persistent Disk, CUDs)
- **Phase 4** ✅ Azure public pricing (Retail Prices API, no credentials)
- **Phase 4** ✅ Streamable-HTTP transport (`--transport http`), Dockerfile
- **Phase 4** ✅ Spot price history tool (`get_spot_history`), GCP Windows pricing
- **Phase 5** ✅ GCP managed services — GKE, Memorystore, BigQuery, Vertex AI, Gemini
- **Phase 5** ✅ GCP networking — Cloud LB, CDN, NAT, Cloud Armor, Cloud Monitoring
- **Phase 5** ✅ GCP Cloud SQL; Azure reserved pricing
- **v0.8.0** ✅ Consolidated to 15-tool surface; unified `get_price(spec)` dispatcher; `describe_catalog` discovery; 123/123 (100%) harness pass rate
- **v0.8.2** ✅ Provider protocol cleanup — `major_regions()`, `default_region()`, `bom_advisories()` on all providers; zero provider-string conditionals in tool layer
- **v0.8.3** ✅ Trust metadata on `NormalizedPrice` (`fetched_at`, `source_url`, `cache_age_seconds`); inter-region egress domain + AWS data transfer pricing
- **v0.8.4** ✅ Numeric price fields — structured `{amount, unit, currency, display}` dicts replace formatted strings at all tool boundaries
- **v0.8.5** ✅ Service→domain inference (`fill_domain`); structured `invalid_spec` error hints; 123/123 harness (up from 84%)
- **v0.8.8** ✅ Azure breadth: SQL Database, Cosmos DB, AKS, Azure Functions, Azure OpenAI; 151/151 harness (28 new test scenarios)
- **v0.8.9** ✅ GCP effective/contract pricing via Cloud Billing Pricing API v1beta (`OCC_GCP_BILLING_ACCOUNT_ID`); GCP now at parity with AWS effective pricing
- **v0.8.10** ✅ `GcpAuthProvider` — multi-source OAuth (SA JSON B64, WIF, ADC, metadata server, raw token); `google-auth[requests]` optional `[gcp]` extra; event-loop-safe refresh; no gcloud required in containers
- **v0.8.11** ✅ GCP storage and database contract pricing — GCS, Persistent Disk, Cloud SQL (all engines/sizes/HA), Memorystore; `effective_price` on `StoragePricingSpec` and `DatabasePricingSpec` when billing account configured
- **v0.8.12** ✅ Azure egress pricing (`inter_region_egress` domain) — internet and inter-region outbound transfer, Zone 1 rates from Retail Prices API, 5 GB/month free tier, monthly estimate in response
