Skip to main content
Glama
sebdroid

AWS Pricing MCP Server

by sebdroid

get_pricing

Read-only

Retrieve AWS pricing for any service using filters for region, attributes, and output options to compare costs and optimize spending.

Instructions

Get detailed pricing information from AWS Price List API with optional filters.

**PARAMETERS:**
- service_code (required): AWS service code (e.g., 'AmazonEC2', 'AmazonS3', 'AmazonES')
- region (optional): AWS region string (e.g., 'us-east-1') OR list for multi-region comparison (e.g., ['us-east-1', 'eu-west-1']). Omit for global services like DataTransfer or CloudFront that don't have region-specific pricing.
- filters (optional): List of filter dictionaries in format {'Field': str, 'Type': str, 'Value': str}
- max_allowed_characters (optional): Response size limit in characters (default: 100,000, use -1 for unlimited)
- output_options (optional): OutputOptions object for response transformation and size reduction
- max_results (optional): Maximum number of results to return per page (default: 100, min: 1, max: 100)
- next_token (optional): Pagination token from previous response to get next page of results

**MANDATORY WORKFLOW - ALWAYS FOLLOW:**

**Step 1: Discover Available Options**
```python
service_codes = get_pricing_service_codes()                              # Find correct service (skip if known)
attributes = get_pricing_service_attributes('AmazonEC2')                 # Discover filterable dimensions
attribute_values = get_pricing_attribute_values('AmazonEC2', 'memory')   # Get valid values for filtering
```

**Step 2: Build Precise Filters**
```python
# Use ONLY values discovered in Step 1
filters = [
   {"Field": "memory", "Value": ["8 GiB", "16 GiB", "32 GiB"], "Type": "ANY_OF"},     # Multiple options
   {"Field": "instanceType", "Value": "m5", "Type": "CONTAINS"},                      # Pattern matching
   {"Field": "instanceType", "Value": ["t2", "m4"], "Type": "NONE_OF"}                # Exclude older

] ```

**Step 3: Execute Query**
```python
pricing = get_pricing('AmazonEC2', 'us-east-1', filters)
```

**FILTER TYPES:**
- **EQUALS**: Exact match (default) - `{"Field": "instanceType", "Value": "m5.large"}`
- **ANY_OF**: Multiple options - `{"Field": "memory", "Value": ["8 GiB", "16 GiB"], "Type": "ANY_OF"}`
- **CONTAINS**: Pattern match - `{"Field": "instanceType", "Value": "m5", "Type": "CONTAINS"}`
- **NONE_OF**: Exclusion - `{"Field": "instanceType", "Value": ["t2", "m4"], "Type": "NONE_OF"}`

**CRITICAL: ANY_OF FILTER VALUE LIMITS:**
- **1024 CHARACTER LIMIT**: Total length of all values in ANY_OF arrays cannot exceed 1024 characters
- **PROGRESSIVE FILTERING**: Start with minimal qualifying options, expand if needed
- **EXAMPLE VIOLATION**: `["8 GiB", "16 GiB", "32 GiB", "64 GiB", "96 GiB", "128 GiB", ...]` (TOO LONG)
- **CORRECT APPROACH**: `["8 GiB", "16 GiB", "32 GiB", "36 GiB", "48 GiB"]` (TARGETED LIST)

**COMMON USE CASES:**

**COST OPTIMIZATION - EXHAUSTIVE MINIMUM-FIRST APPROACH:** When users ask for "lowest price", "cheapest", or cost optimization
- **LOWER = CHEAPER ASSUMPTION**: For cost optimization, assume lower capabilities cost less than higher ones
  * 32 GB storage is cheaper than 300 GB storage
  * 8 GiB RAM is cheaper than 64 GiB RAM
- **CRITICAL FOR COST QUERIES**: Start IMMEDIATELY above minimum requirement and test ALL options incrementally
- **EXHAUSTIVE ENUMERATION REQUIRED**: Each storage/memory tier is MUTUALLY EXCLUSIVE - must list each one explicitly
- **STOP AT REASONABLE UPPER BOUND**: For cost optimization, limit upper bound to 2-3x minimum requirement to avoid expensive options
- **exclude_free_products**: ESSENTIAL for cost analysis - removes $0.00 reservation placeholders, SQL licensing variants, and special pricing entries that obscure actual billable instances when finding cheapest options
- Use ANY_OF for efficient multi-option comparison in single API call
- Multi-attribute capability filtering for minimum requirements
- Combine CONTAINS + NONE_OF for refined discovery

**OUTPUT OPTIONS (Response Size & Performance Control):**
- **PURPOSE**: Transform and optimize API responses for ALL services, especially critical for large services (EC2, RDS)
- **IMMEDIATE COMBINED APPROACH**: `{"pricing_terms": ["OnDemand", "FlatRate"], "product_attributes": ["instanceType", "location", "memory"]}`
- **ATTRIBUTE DISCOVERY**: Use get_pricing_service_attributes() - same names for filters and output_options
- **SIZE REDUCTION**: 80%+ reduction with combined pricing_terms + product_attributes
- **exclude_free_products**: Remove products with $0.00 OnDemand pricing (useful when you know service has paid tiers)
- **WHEN TO USE**: Always for large services, recommended for all services to improve performance

**CRITICAL REQUIREMENTS:**
- **NEVER GUESS VALUES**: Always use get_pricing_attribute_values() to discover valid options
- **EXHAUSTIVE ENUMERATION**: For cost optimization, list ALL qualifying tiers individually - they are mutually exclusive
- **USE SPECIFIC FILTERS**: Large services (EC2, RDS) require 2-3 filters minimum
- **NEVER USE MULTIPLE CALLS**: When ANY_OF can handle it in one call
- **VERIFY EXISTENCE**: Ensure all filter values exist in the service before querying
- **FOR "CHEAPEST" QUERIES**: Focus on lower-end options that meet minimum requirements, test incrementally
- **EXPLORE ALTERNATIVES**: When response includes "alternatives" field, MUST fetch their pricing if applicable to the use case before answering

**CONSTRAINTS:**
- **CURRENT PRICING ONLY**: Use get_price_list_urls for historical data
- **NO SPOT/SAVINGS PLANS**: Only OnDemand, FlatRate, and Reserved Instance pricing available (ANY combination possible)
- **CHARACTER LIMIT**: 100,000 characters default response limit (use output_options to reduce)
- **REGION AUTO-FILTER**: Region parameter automatically creates regionCode filter

**ANTI-PATTERNS:**
- DO NOT make multiple API calls that could be combined with ANY_OF
- DO NOT build cross-products manually when API can handle combinations
- DO NOT call get_pricing_service_codes() when service code is already known (e.g., "AmazonEC2")
- DO NOT use EQUALS without first checking get_pricing_attribute_values()
- DO NOT skip discovery workflow for any use case
- DO NOT use broad queries without specific filters on large services
- DO NOT assume attribute values exist across different services/regions
- DO NOT skip intermediate tiers: Missing 50GB, 59GB options when testing 32GB → 75GB jump
- DO NOT set upper bounds too high: Including 500GB+ storage when user needs ≥30GB (wastes character limit)
- DO NOT ignore alternatives field or use only ["OnDemand"] in output_options

**EXAMPLE USE CASES:**

**1. Cost-Optimized Multi-Attribute Filtering (CORRECT APPROACH):**
```python
# Find cheapest EC2 instances meeting minimum requirements (>= 8 GiB memory, >= 30 GB storage)
# EXHAUSTIVE ENUMERATION of qualifying tiers - each is mutually exclusive
filters = [
   {"Field": "memory", "Value": ["8 GiB", "16 GiB", "32 GiB"], "Type": "ANY_OF"},  # All tiers ≥8GB up to reasonable limit
   {"Field": "storage", "Value": ["1 x 32 SSD", "1 x 60 SSD", "1 x 75 NVMe SSD"], "Type": "ANY_OF"},  # All tiers ≥30GB up to reasonable limit
   {"Field": "instanceType", "Value": ["t2", "m4"], "Type": "NONE_OF"},  # Exclude older generations
   {"Field": "tenancy", "Value": "Shared", "Type": "EQUALS"}  # Exclude more expensive dedicated
]
pricing = get_pricing('AmazonEC2', 'us-east-1', filters)
```

**2. Efficient Multi-Region Comparison:**
```python
# Compare same configuration across regions - use region parameter for multi-region
filters = [{"Field": "instanceType", "Value": "m5.large", "Type": "EQUALS"}]
pricing = get_pricing('AmazonEC2', ['us-east-1', 'us-west-2', 'eu-west-1'], filters)
```

**3. Large service with output optimization (recommended approach):**
```python
output_options = {"pricing_terms": ["OnDemand", "FlatRate"], "product_attributes": ["instanceType", "location"], "exclude_free_products": true}
pricing = get_pricing('AmazonEC2', 'us-east-1', filters, output_options=output_options)
```

**4. Pattern-Based Discovery:**
```python
# Find all Standard storage tiers except expensive ones
filters = [
    {"Field": "storageClass", "Value": "Standard", "Type": "CONTAINS"},
    {"Field": "storageClass", "Value": ["Standard-IA"], "Type": "NONE_OF"}
]
```

**FILTERING STRATEGY:**
- **Large Services (EC2, RDS)**: ALWAYS use 2-3 specific filters to prevent 200+ record responses
- **Small Services**: May work with single filter or no filters
- **Multi-Option Analysis**: Use ANY_OF instead of multiple API calls
- **Pattern Discovery**: Use CONTAINS for finding families or tiers
- **Smart Exclusion**: Use NONE_OF for compliance or cost filtering

**SUCCESS CRITERIA:**
- Used discovery workflow (skip get_pricing_service_codes() if service known)
- Applied appropriate filters for the service size
- Used exact values from get_pricing_attribute_values()
- Used ANY_OF for multi-option scenarios instead of multiple calls
- For cost optimization: tested ALL qualifying tiers exhaustively (in a reasonable range)
- Included ["OnDemand", "FlatRate"] in output_options and explored all alternatives

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
regionNoAWS region(s) - single region string (e.g., "us-east-1") or list for multi-region comparison (e.g., ["us-east-1", "us-west-2", "eu-west-1"]). Optional: omit for global services like DataTransfer or CloudFront that don't have region-specific pricing.
filtersNoOptional list of filters to apply to the pricing query
next_tokenNoPagination token from previous response to get next page of results
max_resultsNoMaximum number of results to return per page (default: 100, max: 100)
service_codeYesAWS service code (e.g., "AmazonEC2", "AmazonS3", "AmazonES")
output_optionsNoOptional output filtering options to reduce response size. Use {"pricing_terms": ["OnDemand", "FlatRate"]} to significantly reduce response size for large services like EC2.
max_allowed_charactersNoMaximum response length in characters (default: 100,000, use -1 for unlimited)

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

While annotations already declare readOnlyHint=true, the description adds substantial behavioral context beyond that: character limits, region auto-filtering, limitations on spot/savings plans, the 1024-character ANY_OF limit, and the behavior of output_options for size reduction. This exceeds what annotations provide and covers critical operational details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely long and contains redundancy (e.g., repeated emphasis on exhaustive enumeration and exclude_free_products). While it is well-structured with clear sections and front-loaded summary, it could be significantly trimmed without losing important information. The length may overwhelm agents, despite the effective use of code examples and bullet points.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (7 parameters, nested filter objects, output_options transformation), the description covers all necessary context: discovery workflow, filter construction, output size control, constraints, anti-patterns, and success criteria. The output schema provides return structure, so the description appropriately focuses on methodology and edge cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description goes far beyond the schema. It explains filter types in detail (EQUALS, ANY_OF, CONTAINS, NONE_OF), the meaning of the output_options fields, the max_allowed_characters semantics, and provides concrete examples of valid filter structures and discovery workflows. This adds significant value beyond parameter names and default values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool's purpose: 'Get detailed pricing information from AWS Price List API with optional filters.' It uses a specific verb+resource combination and differentiates from siblings like get_pricing_service_codes and get_pricing_attribute_values, which serve the discovery workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage guidelines are exceptionally explicit: a mandatory discovery workflow, common use cases (cost optimization, multi-region comparison), anti-patterns, and filtering strategies. It also names alternatives like get_price_list_urls for historical data and explicitly states when to skip discovery steps.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sebdroid/aws-pricing-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server