# Sample Aws Pricing Calculator Mcp

> MCP server for creating, reading, updating AWS Pricing Calculator estimates through natural language.

- **Type:** MCP server
- **Install:** `agentstack add mcp-aws-samples-sample-aws-pricing-calculator-mcp`
- **Verified:** Pending review
- **Seller:** [aws-samples](https://agentstack.voostack.com/s/aws-samples)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT-0
- **Upstream author:** [aws-samples](https://github.com/aws-samples)
- **Source:** https://github.com/aws-samples/sample-aws-pricing-calculator-mcp

## Install

```sh
agentstack add mcp-aws-samples-sample-aws-pricing-calculator-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# AWS Pricing Calculator MCP Server

[Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that creates, reads, and updates [AWS Pricing Calculator](https://calculator.aws/#/estimate) estimates through natural language.

[](https://kiro.dev/launch/mcp/add?name=aws-pricing-calculator-mcp-server&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22sample-aws-pricing-calculator-mcp%40latest%22%5D%7D) [](https://cursor.com/en/install-mcp?name=aws-pricing-calculator-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInNhbXBsZS1hd3MtcHJpY2luZy1jYWxjdWxhdG9yLW1jcEBsYXRlc3QiXX0%3D) [](https://insiders.vscode.dev/redirect/mcp/install?name=aws-pricing-calculator-mcp-server&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22sample-aws-pricing-calculator-mcp%40latest%22%5D%7D)

## Key Features

- **Build estimates from natural language** - agent constructs the estimate via MCP tools; the server saves it to AWS Pricing Calculator and returns a shareable URL.
- **No AWS credentials required** - uses public, unauthenticated calculator.aws CDN endpoints.
- **Live service definitions** - fetches the AWS Pricing Calculator manifest at runtime (~436 services).
- **Verified Configs Catalog** - 18 per-service entries declaring the smallest config that produces a priced estimate, with documented gotchas.
- **Lint refusal before save** - refuses estimates the calculator would render read-only or required-input, with actionable recovery hints.
- **Import existing estimates** - download by URL or ID as JSON (for region swaps, modifications) or Markdown (for LLM analysis).
- **Two transport modes** - stdio (default, for local clients like Claude Desktop, Kiro, Cursor) and optional HTTP (`MCP_TRANSPORT=http`) for hosted deployments.

## Example

Prompt:
> Create an AWS Pricing Calculator estimate for a common Wordpress environment on AWS (Dev, Quality, Production).

Output:

## Quick Start

Requires [Node.js®](https://nodejs.org/en/download).

### Via npx (recommended)

The published package on npm runs without cloning:

```json
{
  "mcpServers": {
    "aws-pricing-calculator-mcp-server": {
      "command": "npx",
      "args": ["-y", "sample-aws-pricing-calculator-mcp@latest"]
    }
  }
}
```

Add this to your MCP client config (e.g. `~/.kiro/settings/mcp.json`, Claude Desktop's `claude_desktop_config.json`, Cursor's MCP settings, or the VS Code MCP config). The install badges above generate the right config automatically.

### From source

```bash
git clone https://github.com/aws-samples/sample-aws-pricing-calculator-mcp.git
cd sample-aws-pricing-calculator-mcp
npm install
npm run build
```

Then point your client at the built bundle:

```json
{
  "mcpServers": {
    "aws-pricing-calculator-mcp-server": {
      "command": "node",
      "args": ["/path/to/sample-aws-pricing-calculator-mcp/dist/mcp-server.js"]
    }
  }
}
```

## MCP Tools

| Tool | Description |
|---|---|
| `search_services` | Search AWS services by name or key. Supports comma-separated queries. |
| `get_service_fields` | Get input field IDs, types, labels, valid options, and selector values for one or more services. For curated services, the response includes a `catalog` block (`minimalConfig`, required-field hints, traps). For deprecated parent service codes (currently `amazonS3`), returns a `redirect_to_parent` status with `child_service_codes` listing the actual service codes to use instead. |
| `create_estimate` | Create a new empty estimate. Returns an estimate ID. |
| `add_service` | Add one or more services to an estimate. Validates field IDs and values against the live service definition (dropdowns, fileSize unit format, numeric/frequency types, region whitelist). Auto-corrects unambiguous mistakes (case mismatches, typos, number-to-string coercion) and returns a `corrections` array on the per-service result. Partial entries return a `partial: true` warning when required inputs are missing. |
| `validate_estimate` | Dry-run preflight: builds the would-be saved payload and runs a static check, without calling the save API. Returns `{lint_verdict, next_step, lint_services, would_be_payload}`. Use to confirm an estimate would render correctly before saving. |
| `build_estimate` | One-shot create + add services + lint preflight + save. Returns the shareable URL on success, or a structured envelope identifying which services need field discovery before retry. |
| `export_estimate` | Save the in-flight estimate to calculator.aws and return a shareable URL. Refuses with an actionable `next_step` if the static linter predicts the saved blob would rehydrate read-only. |
| `import_estimate` | Download an existing estimate by URL or ID. Returns JSON (raw) or Markdown. |
| `get_server_info` | Return version and capability information. |

## Project Structure

```
mcp-server.js              # Entry point — registers the 9 MCP tools, stdio + HTTP transports
lib/
  aws-client.js            # Manifest loading, service definitions, save/read APIs
  estimate-builder.js      # In-memory estimate model, AWS payload assembly
  ec2.js                   # EC2 agent-friendly → ec2Enhancement transform
  validation.js            # Pre-save config validation (field-id, value-shape, region, auto-correct)
  can-rehydrate.js         # Static rehydration linter (12 predicates, pure)
  can-rehydrate-fetch.js   # Network wrapper around the linter
  lint-hints.js            # Translates lint failures into agent-actionable next_step text
  catalog.js               # Loader for catalog/services/*.json curated entries
  pct-config.js            # PCT-based field suggestion
  surfaceability.js        # PCT-driven surfaceability index
  agent-fields.js          # Synthetic field surfacing for fields hidden in composite widgets
  dom-cost.js              # Playwright DOM scrape of the calculator's rendered cost
  handler-helpers.js       # Shared internals for the MCP tool handlers
  tool-descriptions.js     # Long agent-facing tool descriptions (separated from wiring)
  estimate-store.js        # Pluggable in-flight estimate store (memory default)
  estimate-store-dynamodb.js # DynamoDB-backed store for stateless multi-replica deployments
  trace-logger.js          # Structured JSON trace events on stderr
  trace-events.js          # Trace event name registry
  request-context.js       # Per-request session id propagation
catalog/
  schema.json              # JSON Schema for catalog entries
  services/                # Verified configs catalog (minimalConfig, traps, subServices)
test/                      # node:test suite
eval/                      # Scenario-driven behavior eval (87 stdio + LLM scenarios)
scripts/                   # Maintainer tools (catalog authoring, sweep, diagnostic)
dist/                      # Build output: mcp-server.js bundle, aws-calculator.zip, bundle-contract.json
```

The `lib/` listing is exhaustive at 1.2.0. The architecture diagram below highlights the load-bearing modules; minor helpers are not shown.

## Build

```bash
npm run build
```

Produces:
- `dist/mcp-server.js` — single-file esbuild bundle (CJS, minified, Node platform)
- `dist/aws-calculator.zip` — the bundle plus catalog files and runtime libs, zipped for hosted deployment
- `dist/bundle-contract.json` — describes the bundle's environment-variable surface (name, type, default, enum values) so downstream consumers can typecheck their CDK/Terraform against the actual surface

## Tests

Three layers, no overlap:

- **`npm test`** — node:test suite (424/429 pass with mocked I/O). Per-commit gate. Covers pure functions (validation, lint, surfaceability), payload construction, EC2 transforms, catalog schema.
- **`npm run validate-catalog:cost`** — sweeps verified catalog entries against the live cost oracle. Catches stale URLs and pricing-engine drift.
- **`python eval/run.py`** — 87 YAML scenarios (scripted MCP calls + LLM-driven). Each does a real save, then asserts on the saved blob (DOM-rendered cost, structural field equality, lint-must-pass). Run on demand (~1-2 min for stdio scenarios; LLM scenarios cost a few cents on Bedrock Haiku).

424/429 tests pass with mocked I/O (5 skipped, network-dependent). Set `SKIP_NETWORK=1` for offline runs.

## Architecture

```
┌─────────────────┐  stdio (default)    ┌──────────────────────────────────────┐
│   MCP Client    │◄───────────────────►│         MCP Server                   │
│ (Kiro, Claude,  │   JSON-RPC over     │                                      │
│  Cursor, etc.)  │   stdin/stdout      │  mcp-server.js (entry point)         │
│                 │   — or, with        │    ├── lib/aws-client.js             │
│                 │   MCP_TRANSPORT     │    ├── lib/estimate-builder.js       │
│                 │   =http, JSON-RPC   │    ├── lib/ec2.js (EC2 transform)    │
│                 │   over HTTPS        │    ├── lib/validation.js             │
└─────────────────┘                     │    ├── lib/can-rehydrate.js (lint)   │
                                        │    └── lib/catalog.js                │
                                        └──────┬─────────┬─────────┬──────────┘
                                               │         │         │
                                          GET  │     GET │    POST │
                                               ▼         ▼         ▼
                                       ┌─────────┐ ┌─────────┐ ┌─────────────┐
                                       │ CDN     │ │ CDN     │ │ Calculator  │
                                       │ manifest│ │ saved   │ │ Save API    │
                                       │ + svc   │ │ estimate│ │             │
                                       │ defs    │ │ read    │ │ POST        │
                                       │         │ │         │ │ /v2/saveAs  │
                                       │ d1qsj…  │ │ d3knq…  │ │ dnd5z…      │
                                       └─────────┘ └─────────┘ └─────────────┘
```

- **Default transport is stdio.** The MCP server runs as a local child process spawned by the MCP client; it is not network-accessible by default. Set `MCP_TRANSPORT=http` to expose it on `PORT` (default `8000`, `HOST` default `127.0.0.1`) for hosted deployments — the operator is responsible for placing it behind appropriate authentication and network controls.
- All outbound requests are **HTTPS to public, unauthenticated AWS CloudFront distributions** — the same hosts the calculator.aws website uses. No AWS credentials are required for the default in-memory store. The optional DynamoDB store opens a fourth outbound path to DynamoDB and requires AWS credentials with the IAM permissions noted in [Estimate persistence](#estimate-persistence).
- Estimate data is held **in memory only by default** (lost when the process exits). Switch to `ESTIMATES_STORE=dynamodb` to persist in-flight estimates across replicas.

## How It Works

### Service discovery

On first use, the server fetches the AWS Calculator manifest from CloudFront (~436 services with their keys, names, and definition URLs). Service definitions are fetched on demand and cached. The `get_service_fields` tool parses these definitions to extract input field IDs, types, labels, and valid options into a flat, usable format.

### Estimate building

`EstimateBuilder` holds services and groups in memory (or in DynamoDB if configured). When `add_service` is called, the config is validated against the live service definition and stored using the AWS field IDs. Services can be organized into named groups, and multiple instances of the same service are supported via composite keys (e.g. `aWSLambda:Compute`).

### EC2 handling

EC2 uses a custom config transform (`lib/ec2.js`) that converts agent-friendly fields (instance type, OS, pricing strategy) into the `ec2Enhancement` format the calculator expects. Supports On-Demand, Savings Plans, Reserved Instances, and Spot pricing.

### Partition support

The server supports the following AWS partitions:
- `aws` — standard commercial regions
- `aws-iso` — US ISO East/West
- `aws-iso-b` — US ISOB East
- `aws-eusc` (Experimental) AWS European Sovereign Cloud

### Export to calculator.aws

When `export_estimate` is called, the server:

1. Resolves each service name against the manifest.
2. Fetches the service definition to get the correct `version`, `serviceCode`, and template ID.
3. Maps config keys to `calculationComponents` in the AWS payload format.
4. Runs the rehydration linter against the would-be saved blob. If it predicts read-only, the call is refused with an actionable recovery hint instead of a URL.
5. POSTs the payload to the AWS Calculator save API.
6. Returns the shareable `calculator.aws` URL.

AWS recalculates the actual costs when someone opens the link.

## Environment Variables

All optional. The full set is also documented machine-readably in `dist/bundle-contract.json` after build.

| Variable | Default | Purpose |
|---|---|---|
| `AWS_SAVE_URL` | CloudFront save URL | Override the AWS Calculator save endpoint (testing only). |
| `MCP_TRANSPORT` | `stdio` | `stdio` or `http`. HTTP listens on `PORT` (default `8000`) bound to `HOST` (default `127.0.0.1`). |
| `ESTIMATES_STORE` | `memory` | In-flight estimate store. See [Estimate persistence](#estimate-persistence). |
| `ESTIMATES_TABLE` | — | DynamoDB table name. Required when `ESTIMATES_STORE=dynamodb`. |
| `ESTIMATES_TTL_SECONDS` | `0` | TTL for DynamoDB-stored estimates in seconds. `0` = no TTL. |
| `TRACE` | `off` | Set to `on` (or `1`/`true`/`yes`) to enable structured stderr trace events. See [Trace events](#trace-events). |
| `TRACE_RESULT_TEXT_MAX` | `500` | Cap on `resultText` length when tracing is enabled. |

## Estimate persistence

The MCP server keeps in-flight estimates (between `create_estimate` and `export_estimate`) in a pluggable store. Configure with `ESTIMATES_STORE`:

| Value | Description |
| --- | --- |
| `memory` (default) | In-process `Map`. State is lost when the process exits. Suitable for stdio and single-process deployments. |
| `dynamodb` | Persists snapshots in a DynamoDB table. Required for any deployment where `create_estimate` and `add_service` may run in different processes (multi-replica HTTP, Lambda, container runtimes with non-sticky session routing). |

### `dynamodb` configuration

The AWS SDK packages are NOT bundled with the published artifact (they are declared as optional peer dependencies). Before running with `ESTIMATES_STORE=dynamodb`, install them in your deployment image:

```bash
npm install @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb
```

Required env vars when `ESTIMATES_STORE=dynamodb`:

| Variable | Required | Description |
| --- | --- | --- |
| `ESTIMATES_TABLE` | Yes | DynamoDB table name. |
| `AWS_REGION` | Yes | AWS region for the DynamoDB client. |
| `ESTIMATES_TTL_SECONDS` | No | If set, items are written with an `expiresAt` attribute equal to `now + ESTIMATES_TTL_SECONDS`. Pair this with a TTL configuration on the table (TTL attribute name: `expiresAt`) to expire abandoned estimates automatically. |

### Table schema

```
TableName: 
PartitionKey: id (String)
Attributes:
  id        (String)  the estimate's UUID
  snapshot  (String)  JSON-encoded snapshot of the estimate
  expiresAt (Number)  optional epoch seconds, populated when ESTIMATES_TTL_SECONDS is set
TTL attribute: expiresAt  (configure on the table if you set ESTIMATES_TTL_SECONDS)
```

The IAM role running the server needs `dynamodb:GetItem`, `dynamodb:PutItem`, and `dynamodb:DeleteItem` on the table.

### Implementation notes

- Each estimate is stored as a single JSON string under one item. Estimates that approach DynamoDB's 400 KB per-item cap (hundreds of services) will fail to write — use S3 or chunk-encoding if you need that.
- The store is constructed once at process start. Switching backends requires restarting the process.

## Verified Configs Catalog

The catalog (`catalog/ser

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [aws-samples](https://github.com/aws-samples)
- **Source:** [aws-samples/sample-aws-pricing-calculator-mcp](https://github.com/aws-samples/sample-aws-pricing-calculator-mcp)
- **License:** MIT-0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** yes

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-aws-samples-sample-aws-pricing-calculator-mcp
- Seller: https://agentstack.voostack.com/s/aws-samples
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
