Metadata-Version: 2.4
Name: aws-extended-support-calculator
Version: 1.0.2
Summary: MCP server that calculates AWS Extended Support costs for RDS/Aurora, ElastiCache, EKS, OpenSearch, and DocumentDB
Project-URL: Homepage, https://github.com/aws-samples/aws-extended-support-calculator
License: MIT
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: boto3>=1.26.0
Requires-Dist: mcp[cli]>=1.0.0
Requires-Dist: requests>=2.28.0
Description-Content-Type: text/markdown

# AWS Extended Support Cost Calculator — MCP Server

> **Note:** This tool calculates only the additional Extended Support charges. Standard usage costs (compute, storage, I/O, etc.) are separate and not included in these calculations.

## What This MCP Does

This MCP server gives Kiro (IDE or CLI) the ability to answer questions and generate reports about AWS Extended Support across 5 services: RDS/Aurora, ElastiCache, EKS, OpenSearch, and DocumentDB.

You can ask Kiro things like:
- "Which EKS versions are currently in extended support?"
- "When does PostgreSQL 14 enter extended support?"
- "What's the extended support cost for a db.r6g.xlarge Aurora MySQL instance in us-east-1?"

And you can generate cost reports from CSV inventories:
- "Calculate extended support costs for /path/to/rds_inventory.csv and save the report to ~/Downloads"

The reports categorize your resources by support status (already in extended support, entering this year, entering next year) and project costs for the current and next calendar year based on exact extended support start dates.

| Service | Pricing Model |
|---------|---------------|
| **RDS / Aurora** | Per-vCPU-hour × Year tier (from AWS RDS Pricing API) |
| **ElastiCache** | On-demand + premium (80% Y1-2, 160% Y3) (from AWS ElastiCache Pricing API) |
| **EKS** | Additional per-cluster-hour rate (from AWS EKS Pricing API) |
| **OpenSearch / Elasticsearch** | Per NIH — Normalized Instance Hour (from AWS OpenSearch Pricing API) |
| **DocumentDB** | Per-vCPU-hour × Year tier (from AWS DocumentDB Pricing API) |

Version eligibility is fetched live from AWS APIs (RDS, EKS) or sourced from AWS documentation (ElastiCache, OpenSearch, DocumentDB). See [How Calculations Work](#how-calculations-work) for details.

## Installation

### Prerequisites

- Python 3.10+ with [uv](https://docs.astral.sh/uv/getting-started/installation/) installed
- An AWS profile with read-only access (see [AWS Credentials](#aws-credentials) below)
- Kiro IDE or Kiro CLI

### Install

Add to your Kiro MCP config (`~/.kiro/settings/mcp.json`):

```json
{
  "mcpServers": {
    "aws-extended-support": {
      "command": "uvx",
      "args": ["aws-extended-support-calculator@latest"],
      "env": {
        "AWS_PROFILE": "your-aws-profile"
      },
      "disabled": false,
      "autoApprove": [
        "rds_cost", "elasticache_cost", "eks_cost", "opensearch_cost", "documentdb_cost",
        "rds_report", "elasticache_report", "eks_report", "opensearch_report", "documentdb_report",
        "list_services", "list_versions", "check_data", "refresh_data"
      ]
    }
  }
}
```

Restart Kiro. The server is downloaded automatically on first use — no `pip install` needed.

**Prerequisite:** [uv](https://docs.astral.sh/uv/getting-started/installation/) must be installed (`brew install uv` on Mac).

## AWS Credentials

The MCP server uses an AWS profile for API calls. Make sure you have a profile configured with access to an AWS account.

If you don't have a profile yet, set one up:

```bash
aws configure --profile my-profile-name
```

This will prompt for your access key, secret key, and default region.

### What permissions are needed?

The server needs **read-only** access to three APIs:

| API Call | Purpose |
|----------|---------|
| `ec2:DescribeInstanceTypes` | Look up vCPU counts for instance types |
| `rds:DescribeDBMajorEngineVersions` | Fetch RDS/Aurora version lifecycle dates |
| `eks:DescribeClusterVersions` | Fetch EKS version lifecycle dates |

Minimum IAM policy:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstanceTypes",
        "rds:DescribeDBMajorEngineVersions",
        "eks:DescribeClusterVersions"
      ],
      "Resource": "*"
    }
  ]
}
```

### What works without credentials?

All pricing data is fetched from public AWS Pricing APIs — no credentials needed:
- RDS, ElastiCache, DocumentDB, EKS, and OpenSearch pricing
- ElastiCache and DocumentDB version dates (hardcoded from AWS docs)
- OpenSearch version dates (hardcoded from AWS blog)

Only vCPU lookups and version lifecycle dates (RDS, EKS) require credentials. Once cached (24-hour TTL), the server works without credentials until the cache expires.

## CSV Format Requirements

The batch report tools auto-detect columns by matching header names (case-insensitive). Your CSV must include headers that match one of the recognized names below.

### RDS / Aurora / DocumentDB

| Field | Required | Recognized Column Names |
|-------|----------|------------------------|
| Instance type | Yes | `Instance Type`, `InstanceType`, `DBInstanceClass`, `class` |
| Engine | Yes (RDS only) | `DB Engine`, `Engine`, `DatabaseEngine` |
| Version | Yes | `Engine Version`, `Engine Full Version`, `EngineVersion`, `Version` |
| Region | Yes | `Instance Region`, `Region`, `RegionCode` |
| Instance name | No | `Instance Name`, `DBInstanceId`, `Identifier`, `Label` |
| Multi-AZ | No | `Multi-AZ`, `MAZ Flag`, `MultiAZ` |

### ElastiCache

| Field | Required | Recognized Column Names |
|-------|----------|------------------------|
| Node type | Yes | `Node Type`, `NodeType`, `CacheNodeType`, `Instance Type` |
| Region | Yes | `Region`, `Location` |
| Version | No | `Version`, `EngineVersion`, `Engine Version` |
| Node count | No | `NumNodes`, `NumCacheNodes`, `Node Count`, `Nodes` |
| Cluster name | No | `Cluster`, `Name`, `CacheClusterId` |

### EKS

| Field | Required | Recognized Column Names |
|-------|----------|------------------------|
| Version | Yes | `clusterVersion`, `KubernetesVersion`, `k8sVersion`, `Version` |
| End of support date | Recommended | `endOfSupportDate`, `end_of_support` |
| End of extended support | No | `endOfExtendedSupportDate`, `end_of_extended_support` |
| Region | No | `Region` |
| Cluster name | No | `clusterName`, `cluster_name`, `Cluster`, `Name` |

### OpenSearch / Elasticsearch

| Field | Required | Recognized Column Names |
|-------|----------|------------------------|
| Instance type | Yes | `Instance Type`, `InstanceType`, `Node Type` |
| Region | Yes | `Region`, `Location` |
| Version | Recommended | `Version`, `EngineVersion`, `Engine Version` |
| Node count | No | `NumNodes`, `Node Count`, `DataNodes`, `Nodes` |
| Domain name | No | `Domain`, `Name`, `DomainName`, `Cluster` |

## Usage Examples

### Generate reports from CSV inventories

```
"Calculate extended support costs for /path/to/rds_inventory.csv and save the report to /tmp/reports"
```

```
"Generate an EKS extended support report for /path/to/eks_clusters.csv and save to ~/Downloads"
```

```
"Process my ElastiCache inventory at /path/to/redis_clusters.csv and give me the cost breakdown"
```

```
"Calculate DocumentDB extended support costs for /path/to/docdb_instances.csv and save reports to ~/Desktop"
```

### Quick single-instance cost checks

```
"What's the extended support cost for a db.r6g.xlarge PostgreSQL instance in us-east-1 with Multi-AZ?"
```

```
"How much would extended support cost for 10 EKS clusters over 6 months?"
```

```
"Calculate ElastiCache extended support for cache.r6g.large in eu-west-1 with 3 nodes"
```

```
"What's the OpenSearch extended support cost for an m7g.medium.search instance in us-west-2 with 5 nodes?"
```

### Version lifecycle questions

```
"Which EKS versions are currently in extended support?"
```

```
"Show me all RDS and Aurora version extended support dates"
```

```
"When does PostgreSQL 14 enter extended support?"
```

```
"What OpenSearch versions have announced extended support dates?"
```

```
"Is Redis 6 eligible for ElastiCache extended support? When does it start?"
```

```
"List all services and versions that are entering extended support this year"
```

### Data management

```
"Is the pricing data fresh?"
```

```
"Refresh the extended support pricing data"
```

```
"What services does the extended support calculator cover?"
```

## Example Outputs

### Single instance cost check

**You:** "What's the extended support cost for a db.r6g.xlarge PostgreSQL instance in us-east-1 with Multi-AZ?"

**Kiro:** The db.r6g.xlarge has 4 vCPUs. With Multi-AZ (2× multiplier), the effective vCPU count is 8.

| | Per-vCPU Hourly Rate | Monthly | Yearly |
|---|---|---|---|
| Year 1 | $0.10 | $584 | $7,008 |
| Year 2 | $0.10 | $584 | $7,008 |
| Year 3 | $0.20 | $1,168 | $14,016 |
| **Total 3-Year** | | | **$28,032** |

### Version lifecycle query

**You:** "Which EKS versions are currently in extended support?"

**Kiro:** Here are the current EKS version support statuses:

| Version | Standard Support End | Extended Support End | Status |
|---------|---------------------|---------------------|--------|
| EKS 1.30 | Jul 22, 2025 | Jul 22, 2026 | In Extended Support |
| EKS 1.31 | Nov 25, 2025 | Nov 25, 2026 | In Extended Support |
| EKS 1.32 | Mar 22, 2026 | Mar 22, 2027 | In Extended Support |
| EKS 1.33 | Jul 28, 2026 | Jul 28, 2027 | In Standard Support |
| EKS 1.34 | Dec 1, 2026 | Dec 1, 2027 | In Standard Support |
| EKS 1.35 | Mar 26, 2027 | Mar 26, 2028 | In Standard Support |

### Batch report

**You:** "Calculate extended support costs for /path/to/rds_inventory.csv and save the report to ~/Downloads"

**Kiro:** Processed 5,836 RDS/Aurora instances (130 skipped — unsupported engines).

**2026 Extended Support Cost: $4,738,358**
**2027 Projected Cost: $17,260,574**

| Engine Version | Instances | Status | 2026 Cost | 2027 Projected |
|---|---|---|---|---|
| Aurora MySQL 5.7 | 130 | In Extended Support | $1,596,755 | $1,596,755 |
| RDS MySQL 5.7 | 45 | In Extended Support | $718,565 | $791,343 |
| RDS MySQL 8.0 | 828 | Entering Aug 2026 | $2,047,935 | $4,915,043 |
| RDS PostgreSQL 13 | 56 | In Extended Support | $188,749 | $226,499 |
| RDS PostgreSQL 14 | 2,032 | Entering Mar 2027 | $0 | $8,619,869 |
| ... | | | | |

Reports saved:
- CSV: `~/Downloads/inventory_extended_support_20260427.csv`
- HTML: `~/Downloads/inventory_extended_support_20260427.html`

### HTML report

The batch tools generate a styled HTML report that can be opened in any browser. It includes:
- Summary cards with current year and next year projected costs
- Category summary table (already in extended support / entering this year / entering next year)
- Version detail tables per category with instance counts, dates, and costs
- Region breakdown table

## Tools

### Single Instance Calculators

Quick cost estimates for individual resources.

| Tool | Description |
|------|-------------|
| `rds_cost` | RDS/Aurora instance — per-vCPU-hour, Year 1/2/3 breakdown |
| `elasticache_cost` | ElastiCache Redis cluster — on-demand + premium tiers |
| `eks_cost` | EKS cluster(s) — extended vs standard support cost comparison |
| `opensearch_cost` | OpenSearch domain — NIH-based pricing |
| `documentdb_cost` | DocumentDB instance — per-vCPU-hour, Year 1/2/3 breakdown |

### Batch Report Generators

Process CSV inventories and generate executive-level CSV + HTML reports.

| Tool | Description |
|------|-------------|
| `rds_report` | RDS/Aurora inventory → cost by engine/version, region, with current year + next year projections |
| `elasticache_report` | ElastiCache inventory → cost by version with premium tier projections |
| `eks_report` | EKS inventory → cost by version using end-of-support dates |
| `opensearch_report` | OpenSearch inventory → cost by engine version with NIH pricing |
| `documentdb_report` | DocumentDB inventory → cost with grace period handling |

All batch tools accept an `output_dir` parameter. When provided, they save:
- **CSV report** — summary, version breakdown, region breakdown, instance detail
- **HTML report** — styled executive report with summary cards, category tables, version detail

Reports categorize versions into:
- Already in Extended Support
- Entering Extended Support this year
- Entering Extended Support next year
- Future / Still in Standard Support

### Utilities

| Tool | Description |
|------|-------------|
| `list_services` | Show all supported services and pricing models |
| `list_versions` | List version lifecycle dates — shows which versions are in standard support, extended support, or future extended support with exact dates. Accepts a service name or "all" |
| `check_data` | Check freshness of cached pricing and version data |
| `refresh_data` | Force re-download all cached data |

## How Calculations Work

### RDS / Aurora

1. **Version eligibility**: Fetched live from `rds.describe_db_major_engine_versions()` — returns exact standard support end, extended support start/end dates for each engine+version
2. **Pricing**: Fetched from the public AWS RDS Pricing API — extracts ExtendedSupport SKUs with per-vCPU-hour rates by region, engine, and year
3. **vCPU count**: Looked up via `ec2.describe_instance_types()`
4. **Cost formula**: `vCPUs × per-vCPU-hour rate × 730 hours/month × Multi-AZ multiplier (1 or 2)`
5. **Year determination**: Month-by-month from the exact extended support start date. Year 1 = months 0-11, Year 2 = 12-23, Year 3 = 24+. Year 3 rates are typically 2× Year 1-2 for PostgreSQL/MySQL

### ElastiCache

1. **Version eligibility**: Hardcoded — Redis 4.x/5.x (ext start Feb 1, 2026), Redis 6.x (ext start Feb 1, 2027). Source: [AWS docs](https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/extended-support-versions.html)
2. **Pricing**: On-demand price fetched from public ElastiCache Pricing API, then premium applied
3. **Premium tiers**: Year 1-2: 80% of on-demand price. Year 3: 160% of on-demand price
4. **Cost formula**: `on-demand hourly × premium % × num_nodes × 730 hours/month`

### EKS

1. **Version eligibility**: Fetched live from `eks.describe_cluster_versions()` — returns `endOfStandardSupportDate`, `endOfExtendedSupportDate`, and `status` per version
2. **Pricing**: Additional hourly rate per region fetched from public AWS EKS Pricing API — no credentials needed. Currently $0.50/cluster/hour additional across all regions
3. **Cost formula**: `extended_support_rate × 730 hours/month` (only for months after end-of-support date)
4. **CSV dates**: The batch tool reads `endOfSupportDate` and `endOfExtendedSupportDate` columns from the CSV (if present) to determine per-cluster support timelines. These columns are typically populated by data collection tools like Dante/TSC

### OpenSearch / Elasticsearch

1. **Version eligibility**: Hardcoded from [AWS blog post](https://aws.amazon.com/blogs/big-data/amazon-opensearch-service-announces-standard-and-extended-support-dates-for-elasticsearch-and-opensearch-versions/). No API available for lifecycle dates
2. **Pricing**: NIH rate per region fetched from public AWS OpenSearch Pricing API — no credentials needed
3. **Cost formula**: `NIH_rate × normalization_factor × num_nodes × 730 hours/month`
4. **Normalization factors**: nano=0.25, micro=0.5, small=1, medium=2, large=4, xlarge=8, 2xlarge=16, etc. Source: [AWS blog post](https://aws.amazon.com/blogs/big-data/amazon-opensearch-service-announces-standard-and-extended-support-dates-for-elasticsearch-and-opensearch-versions/)

### DocumentDB

1. **Version eligibility**: Hardcoded — only v3.6 eligible. Source: [AWS docs](https://docs.aws.amazon.com/documentdb/latest/developerguide/extended-support.html)
2. **Pricing**: Fetched from public DocumentDB Pricing API
3. **Grace period**: Standard support ends Mar 30, 2026 but extended support billing starts Jul 1, 2026 (3-month grace)
4. **Cost formula**: `vCPUs × per-vCPU-hour rate × 730 hours/month × Multi-AZ multiplier`
5. **Premium tiers**: Year 1-2: 80% premium. Year 3: 160% premium

## Data Freshness

All fetched data is cached locally for **24 hours** in a `cache/` directory next to the server script.

| Data | Source | Requires Credentials | Cache TTL |
|------|--------|---------------------|-----------|
| RDS extended support pricing | AWS Pricing API (public) | No | 24 hours |
| ElastiCache on-demand pricing | AWS Pricing API (public) | No | 24 hours |
| DocumentDB extended support pricing | AWS Pricing API (public) | No | 24 hours |
| OpenSearch NIH rates | AWS Pricing API (public) | No | 24 hours |
| EKS extended support rate | AWS Pricing API (public) | No | 24 hours |
| EC2 vCPU counts | `ec2.describe_instance_types()` | Yes | 24 hours |
| RDS version lifecycle | `rds.describe_db_major_engine_versions()` | Yes | 24 hours |
| EKS version lifecycle | `eks.describe_cluster_versions()` | Yes | 24 hours |
| ElastiCache ext support dates | Hardcoded from AWS docs | No | N/A (embedded) |
| DocumentDB ext support dates | Hardcoded from AWS docs | No | N/A (embedded) |
| OpenSearch ext support dates | Hardcoded from AWS blog | No | N/A (embedded) |

Use `check_data` to see cache status. Use `refresh_data` to force re-download.

First tool call on a fresh install triggers automatic data fetch — no manual setup needed.
