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.
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"
Clone the repository:
git clone https://github.com/aarora79/aws-cost-explorer-mcp.git
cd aws-cost-explorer-mcp
Set up the Python virtual environment:
uv venv --python 3.12 && source .venv/bin/activate && uv pip install --requirement pyproject.toml
Configure AWS credentials:
mkdir -p ~/.aws
# Set up your credentials in ~/.aws/credentials and ~/.aws/config
Set up model invocation logs in Amazon CloudWatch.
Ensure your IAM user/role has read-only access to Amazon Cost Explorer and Amazon CloudWatch.
For cross-account access, set the CROSS_ACCOUNT_ROLE_NAME
parameter when starting the server.
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
Edit your Claude Desktop configuration file:
{
"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"
}
}
}
}
{
"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"
}
}
}
}
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.
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
Run the included Chainlit chatbot:
chainlit run app.py --port 8080
Visit localhost:8080
to interact with the chatbot.
The server provides these tools:
get_ec2_spend_last_day()
: Retrieves EC2 spending for the previous dayget_detailed_breakdown_by_day(days=7)
: Analyzes costs by region, service, and instance typeget_bedrock_daily_usage_stats(days=7, region='us-east-1', log_group_name='BedrockModelInvocationLogGroup')
: Shows per-day breakdown of model usageget_bedrock_hourly_usage_stats(days=7, region='us-east-1', log_group_name='BedrockModelInvocationLogGroup')
: Shows per-hour breakdown of model usagedocker build -t aws-cost-explorer-mcp .
docker run -v ~/.aws:/root/.aws aws-cost-explorer-mcp
To run the MCP server with HTTPS:
Enable access to TCP port 443 in your EC2 security group.
Obtain an SSL certificate for your domain.
Install nginx:
sudo apt-get install nginx
sudo nginx -t
sudo systemctl reload nginx
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
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;
}
}
Restart nginx:
sudo systemctl start nginx
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
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.
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"
]
}
}
}
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.
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.