Cursor's Agent Mode is where AWS MCP feels most like "in-editor infrastructure awareness" rather than a separate CLI session — you're already looking at the code that provisions or calls a resource, and the agent can check that resource's live state without you leaving the file. This topic covers the connection, the code-to-cloud correlation workflow that's Cursor's real strength, generating infra fixes from live state, and where to be careful about credentials inside an IDE process.
Connecting AWS MCP to Cursor Agent Mode
Cursor reads MCP config from .cursor/mcp.json (project-scoped) or ~/.cursor/mcp.json (global). For AWS, use the global file — same reasoning as every other client in this module: profile names shouldn't live in a repo-committed config.
{
"mcpServers": {
"aws-api": {
"command": "uvx",
"args": ["awslabs.aws-api-mcp-server@latest"],
"env": {
"AWS_PROFILE": "dev-readonly",
"AWS_REGION": "us-east-1"
}
},
"aws-cloudwatch": {
"command": "uvx",
"args": ["awslabs.cloudwatch-mcp-server@latest"],
"env": {
"AWS_PROFILE": "dev-readonly",
"AWS_REGION": "us-east-1"
}
}
}
}
Enable and verify from Cursor Settings → MCP, where each server shows a toggle and a live tool count once connected. Cursor's UI here is genuinely convenient — you see per-tool descriptions without needing to ask the agent to list them, which is useful for confirming exactly what aws-api-mcp-server exposes before you start relying on it in a session.
Cursor also supports per-tool auto-run allowlisting under Settings → Features → Agent Mode. For AWS MCP tools, be deliberate here: allow read-only tools (call_aws restricted to describe/list/get patterns isn't something Cursor enforces automatically — that enforcement lives in your IAM policy, not the client) to run without confirmation, but leave anything that could resolve to a mutating CLI command on manual confirmation.
Settings → Features → Agent Mode → MCP Tools Auto-Run
aws-cloudwatch: get_metric_data ✓ auto-run
aws-cloudwatch: execute_log_insights_query ✓ auto-run
aws-api: call_aws ✗ confirm each call
Tips
- Use Cursor's per-tool auto-run allowlist deliberately: CloudWatch read tools are safe to auto-run, but the genericcall_awstool can express both read and write commands as free text, so leave it on manual confirmation unless your IAM policy already makes mutation impossible.
- Check the tool descriptions shown in Settings → MCP before your first real session — it's the fastest way to know exactly what a server exposes without spending a turn asking the agent to enumerate its own tools.
Correlating Application Code with Live AWS Resource Configuration
This is Cursor's actual differentiator for AWS work: the agent has your whole repo open as context alongside the MCP tools, so it naturally cross-references application code against live cloud config without you having to paste either one manually.
Open serverless.yml and check whether the memory and timeout settings for
the `image-resize` function match what's actually deployed. If they've
drifted, tell me which one is the source of truth.
functions:
image-resize:
handler: src/handlers/image_resize.handler
memorySize: 512
timeout: 30
aws lambda get-function-configuration \
--function-name image-resize-prod \
--query "[MemorySize,Timeout]" \
--profile dev-readonly
A real, common finding here: the deployed function shows memorySize: 1024, timeout: 60 — someone bumped it manually in the console during an incident six months ago and the IaC file was never updated. The agent flags the drift and — correctly — treats the live deployment as more likely to reflect actual production requirements than the stale YAML, recommending you update serverless.yml to match reality rather than redeploying and silently reverting someone's incident-time fix.
A second common pattern: checking that environment variables referenced in code actually exist in the deployed function.
Grep the codebase for every os.environ.get() call in src/handlers/payment_webhook.py,
then check the deployed Lambda's environment variables and tell me if
anything referenced in code is missing from the deployment config.
aws lambda get-function-configuration \
--function-name payment-webhook-handler \
--query "Environment.Variables" \
--profile dev-readonly
This catches a specific, recurring class of bug: a new environment variable added to code in a PR, deployed via CI, but the deployment pipeline's IaC template wasn't updated with the new variable — so the function silently falls back to a None default it wasn't designed for. Cross-referencing code and live config in one session catches this before it becomes a production incident, not after.
Tips
- Point the agent at the specific IaC file (serverless.yml,template.yaml,main.tf) explicitly rather than letting it search for infra config on its own — large repos often have several plausible-looking config files, and you want to be certain which one it's treating as source of truth.
- When code and live config disagree, don't assume either one is automatically correct — ask the agent to checkgit blame/ CloudTrail timestamps on both to establish which change is more recent and more likely intentional.
Generating Infrastructure Fixes from Real Account State in Cursor
Once drift or a bug is identified, Cursor Agent Mode can propose the actual diff — to Terraform, CDK, or Serverless Framework config — informed by the real resource state it just inspected, rather than a generic best-practice guess.
Update serverless.yml so the image-resize function's memorySize and timeout
match what's currently deployed (1024 MB, 60s), and add a comment noting
this was corrected to match a manual production change made during an
incident. Don't touch any other function definitions.
functions:
image-resize:
handler: src/handlers/image_resize.handler
# Corrected 2026-08-21 to match manual prod change made during INC-2044
memorySize: 1024
timeout: 60
For a Terraform-managed security group fix identified earlier in an investigation:
The orders-db RDS security group (sg-0ccc333) is missing an ingress rule
allowing 5432 from the checkout-api security group (sg-0bbb222). Find where
this security group is defined in our Terraform and add the missing rule
as a new aws_security_group_rule resource, not by modifying the existing
inline ingress block.
resource "aws_security_group_rule" "orders_db_allow_checkout_api" {
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
security_group_id = aws_security_group.orders_db.id
source_security_group_id = aws_security_group.checkout_api.id
description = "Allow checkout-api to reach orders-db (INC-2044)"
}
Asking for a separate aws_security_group_rule resource instead of an inline rule edit is a deliberate ask worth making explicitly — inline ingress {} blocks in an aws_security_group resource get fully replaced on every apply if Terraform detects any drift in that block, which is a common source of "why did my manually-added rule disappear" surprises. The agent won't necessarily default to the safer pattern unless you specify it.
Always run terraform plan yourself before apply, even when the diff looks obviously correct:
terraform plan -target=aws_security_group_rule.orders_db_allow_checkout_api
Tips
- Explicitly request the separate-resource pattern (aws_security_group_ruleinstead of inlineingressblocks) when asking for security group fixes — it avoids a real, common Terraform footgun the agent won't necessarily avoid on its own.
- Never skipterraform planbecause the agent's explanation sounds confident — a scoped-targetplan takes seconds and catches unintended resource replacement before it happens.
Known Limitations and Credential Safety in Cursor
A few things worth knowing before you lean on this setup for anything sensitive:
- Cursor's cloud-synced features and local MCP credentials are separate, but be deliberate about it. Cursor's Privacy Mode and Tab/Chat cloud processing don't interact with your local
~/.awscredentials directly — MCP servers run as local subprocesses using your local credential chain — but if your org has restrictions on where AWS-sourced data can be transmitted, understand that any tool output Cursor sends to its own backend for the chat/agent completion is a data flow you should have your security team sign off on, same as you would for Claude Code or any other MCP-integrated IDE assistant. - No native secret-scrubbing on tool output. If a
describe-instancesorget-function-configurationcall happens to surface something sensitive in a tag or environment variable name (not the value, if you followed the least-privilege guidance in this module's first topic, but names can leak intent), that goes into the same context as everything else in the session — there's no automatic redaction layer. - Agent Mode auto-run allowlists are per-tool, not per-parameter. You can allow
call_awsto auto-run, but you can't restrict it to "onlydescribe-*andlist-*commands" at the Cursor config level — that granularity has to come from IAM, not from Cursor's UI. - Long agentic loops can drift off the original ask. In multi-step "investigate and fix" sessions, Cursor Agent Mode occasionally over-scopes a fix beyond what was asked (e.g., "fixing" adjacent Terraform resources that weren't part of the original drift). Review diffs line by line before applying, not just the summary.
Tips
- Treat any AWS tool output that reaches Cursor's chat backend the same way you'd treat it reaching any third-party LLM API — get security sign-off on the data flow before running this against production-sensitive accounts, not just dev.
- Review the full diff on every agent-proposed infra change, not just the summary description — over-scoped fixes in long agentic sessions are a real, recurring failure mode worth explicitly guarding against.
Tips
Tips
- Lean into Cursor specifically for code-to-cloud drift detection — checking IaC against live resource state is the workflow where having your whole repo and AWS MCP in the same context window pays off most clearly.
- Keepcall_awson manual confirmation in Agent Mode's auto-run settings; Cursor can't restrict it to read-only patterns at the config level, so that boundary has to come from your IAM policy.
- Insist on the safer Terraform pattern (separateaws_security_group_ruleresources, not inline blocks) when asking for security group fixes, and always run a scopedterraform planbeforeapply.