AWS Cost Explorer and Bedrock Usage Analytics MCP server

Integrates with AWS Cost Explorer and CloudWatch to analyze cloud spending patterns and Bedrock model usage statistics for detailed cost monitoring and optimization.
Back to servers
Provider
Amit Arora
Release date
Mar 12, 2025
Language
Python
Stats
111 stars

The AWS Cost Explorer and Bedrock Model Invocation Logs MCP Server provides access to AWS spending data and Bedrock usage information through Anthropic's Model Control Protocol (MCP). This tool allows you to analyze your AWS costs using natural language queries via Claude.

Installation

Prerequisites

  1. Install uv:

    # On macOS and Linux
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
    # On Windows
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
    
  2. Clone the repository:

    git clone https://github.com/aarora79/aws-cost-explorer-mcp.git
    cd aws-cost-explorer-mcp
    
  3. Set up the Python virtual environment:

    uv venv --python 3.12 && source .venv/bin/activate && uv pip install --requirement pyproject.toml
    
  4. Configure AWS credentials:

    mkdir -p ~/.aws
    # Set up your credentials in ~/.aws/credentials and ~/.aws/config
    

Usage Setup

Required Configuration

  1. Set up model invocation logs in Amazon CloudWatch.

  2. Ensure your IAM user/role has read-only access to Amazon Cost Explorer and Amazon CloudWatch.

  3. For cross-account access, set the CROSS_ACCOUNT_ROLE_NAME parameter when starting the server.

Running the MCP Server

Local Server Setup

To run the server locally:

export MCP_TRANSPORT=stdio
export BEDROCK_LOG_GROUP_NAME=YOUR_BEDROCK_CW_LOG_GROUP_NAME
export CROSS_ACCOUNT_ROLE_NAME=ROLE_NAME_FOR_THE_ROLE_TO_ASSUME_IN_OTHER_ACCOUNTS
python server.py

Claude Desktop Configuration

Option 1: Using Docker

Edit your Claude Desktop configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "aws-cost-explorer": {
      "command": "docker",
      "args": [ "run", "-i", "--rm", "-e", "AWS_ACCESS_KEY_ID", "-e", "AWS_SECRET_ACCESS_KEY", "-e", "AWS_REGION", "-e", "BEDROCK_LOG_GROUP_NAME", "-e", "MCP_TRANSPORT", "-e", "CROSS_ACCOUNT_ROLE_NAME", "aws-cost-explorer-mcp:latest" ],
      "env": {
        "AWS_ACCESS_KEY_ID": "YOUR_ACCESS_KEY_ID",
        "AWS_SECRET_ACCESS_KEY": "YOUR_SECRET_ACCESS_KEY",
        "AWS_REGION": "us-east-1",
        "BEDROCK_LOG_GROUP_NAME": "YOUR_CLOUDWATCH_BEDROCK_MODEL_INVOCATION_LOG_GROUP_NAME",
        "CROSS_ACCOUNT_ROLE_NAME": "ROLE_NAME_FOR_THE_ROLE_TO_ASSUME_IN_OTHER_ACCOUNTS",
        "MCP_TRANSPORT": "stdio"
      }
    }
  }
}

Option 2: Using UV (without Docker)

{
  "mcpServers": {
    "aws_cost_explorer": {
      "command": "uv",
      "args": [
          "--directory",
          "/path/to/aws-cost-explorer-mcp-server",
          "run",
          "server.py"
      ],
      "env": {
        "AWS_ACCESS_KEY_ID": "YOUR_ACCESS_KEY_ID",
        "AWS_SECRET_ACCESS_KEY": "YOUR_SECRET_ACCESS_KEY",
        "AWS_REGION": "us-east-1",
        "BEDROCK_LOG_GROUP_NAME": "YOUR_CLOUDWATCH_BEDROCK_MODEL_INVOCATION_LOG_GROUP_NAME",
        "CROSS_ACCOUNT_ROLE_NAME": "ROLE_NAME_FOR_THE_ROLE_TO_ASSUME_IN_OTHER_ACCOUNTS",
        "MCP_TRANSPORT": "stdio"
      }
    }
  }
}

Remote Server Setup

For a remote server (not supported by Claude Desktop):

export MCP_TRANSPORT=sse
export BEDROCK_LOG_GROUP_NAME=YOUR_BEDROCK_CW_LOG_GROUP_NAME
export CROSS_ACCOUNT_ROLE_NAME=ROLE_NAME_FOR_THE_ROLE_TO_ASSUME_IN_OTHER_ACCOUNTS
python server.py

The server will listen on port 8000. Configure your EC2 security group to allow access to this port.

Testing with CLI Client

Test your remote server with:

# set the hostname for your MCP server
MCP_SERVER_HOSTNAME=YOUR_MCP_SERVER_EC2_HOSTNAME
# or localhost if your MCP server is running locally
# MCP_SERVER_HOSTNAME=localhost 
AWS_ACCOUNT_ID=AWS_ACCOUNT_ID_TO_GET_INFO_ABOUT
python mcp_sse_client.py --host $MCP_SERVER_HOSTNAME --aws-account-id $AWS_ACCOUNT_ID

Using the Chainlit App

Run the included Chainlit chatbot:

chainlit run app.py --port 8080

Visit localhost:8080 to interact with the chatbot.

Available Tools

The server provides these tools:

  1. get_ec2_spend_last_day(): Retrieves EC2 spending for the previous day
  2. get_detailed_breakdown_by_day(days=7): Analyzes costs by region, service, and instance type
  3. get_bedrock_daily_usage_stats(days=7, region='us-east-1', log_group_name='BedrockModelInvocationLogGroup'): Shows per-day breakdown of model usage
  4. get_bedrock_hourly_usage_stats(days=7, region='us-east-1', log_group_name='BedrockModelInvocationLogGroup'): Shows per-hour breakdown of model usage

Example Queries

  • "Help me understand my Bedrock spend over the last few weeks"
  • "What was my EC2 spend yesterday?"
  • "Show me my top 5 AWS services by cost for the last month"
  • "Analyze my spending by region for the past 14 days"
  • "Which instance types are costing me the most money?"

Docker Support

docker build -t aws-cost-explorer-mcp .
docker run -v ~/.aws:/root/.aws aws-cost-explorer-mcp

Setting Up Secure Remote MCP Server

To run the MCP server with HTTPS:

  1. Enable access to TCP port 443 in your EC2 security group.

  2. Obtain an SSL certificate for your domain.

  3. Install nginx:

    sudo apt-get install nginx
    sudo nginx -t
    sudo systemctl reload nginx
    
  4. Get your EC2 hostname:

    TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") && curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/public-hostname
    
  5. Create nginx configuration at /etc/nginx/conf.d/ec2.conf:

    server {
     listen 80;
     server_name YOUR_EC2_HOSTNAME;
     return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl;
        server_name YOUR_EC2_HOSTNAME;
        ssl_certificate     /etc/ssl/certs/cert.pem;
        ssl_certificate_key /etc/ssl/privatekey/privkey.pem; 
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
    
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    
  6. Restart nginx:

    sudo systemctl start nginx
    
  7. Connect to your server using:

    MCP_SERVER_HOSTNAME=YOUR_MCP_SERVER_DOMAIN_NAME
    AWS_ACCOUNT_ID=AWS_ACCOUNT_ID_TO_GET_INFO_ABOUT
    python mcp_sse_client.py --host $MCP_SERVER_HOSTNAME --port 443 --aws-account-id $AWS_ACCOUNT_ID
    

    Or with the Chainlit app:

    export MCP_SERVER_URL=YOUR_MCP_SERVER_DOMAIN_NAME
    export MCP_SERVER_PORT=443
    chainlit run app.py --port 8080
    

How to add this MCP server to Cursor

There are two ways to add an MCP server to Cursor. The most common way is to add the server globally in the ~/.cursor/mcp.json file so that it is available in all of your projects.

If you only need the server in a single project, you can add it to the project instead by creating or adding it to the .cursor/mcp.json file.

Adding an MCP server to Cursor globally

To add a global MCP server go to Cursor Settings > MCP and click "Add new global MCP server".

When you click that button the ~/.cursor/mcp.json file will be opened and you can add your server like this:

{
    "mcpServers": {
        "cursor-rules-mcp": {
            "command": "npx",
            "args": [
                "-y",
                "cursor-rules-mcp"
            ]
        }
    }
}

Adding an MCP server to a project

To add an MCP server to a project you can create a new .cursor/mcp.json file or add it to the existing one. This will look exactly the same as the global MCP server example above.

How to use the MCP server

Once the server is installed, you might need to head back to Settings > MCP and click the refresh button.

The Cursor agent will then be able to see the available tools the added MCP server has available and will call them when it needs to.

You can also explictly ask the agent to use the tool by mentioning the tool name and describing what the function does.

Want to 10x your AI skills?

Get a free account and learn to code + market your apps using AI (with or without vibes!).

Nah, maybe later