OpenCode's MCP support is functional but noticeably less polished than Claude Code's for AWS-specific work — mostly around how it surfaces large tool outputs and how it handles long-running credential refresh. This topic covers getting it connected, the inspection workflows that work well, and the ones you should route to a different client instead.
Installing and Connecting AWS MCP to OpenCode
OpenCode reads MCP server config from opencode.json (project root) or the global ~/.config/opencode/opencode.json. Unlike Claude Code, OpenCode doesn't have a dedicated mcp add command — you hand-edit the JSON directly, which means it's on you to get the env var scoping right.
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"aws-api": {
"type": "local",
"command": ["uvx", "awslabs.aws-api-mcp-server@latest"],
"environment": {
"AWS_PROFILE": "dev-readonly",
"AWS_REGION": "us-east-1"
},
"enabled": true
},
"aws-cloudwatch": {
"type": "local",
"command": ["uvx", "awslabs.cloudwatch-mcp-server@latest"],
"environment": {
"AWS_PROFILE": "dev-readonly",
"AWS_REGION": "us-east-1"
},
"enabled": true
}
}
}
Put this in ~/.config/opencode/opencode.json rather than a project-level file for the same reason as Claude Code: you don't want an AWS profile name checked into a repo. If your team shares an opencode.json at the project root for other MCP servers (GitHub, filesystem, etc.), keep AWS servers out of it and reference them only from the global config.
Start OpenCode and confirm the servers loaded:
opencode
/mcp
A connected server shows a green status indicator with its tool count. If aws-api shows zero tools or a red indicator, check the OpenCode logs first — ~/.local/share/opencode/log/ on Linux, ~/Library/Application Support/opencode/log/ on macOS — before assuming it's an AWS-side problem. In practice, the most common failure here is uvx not being resolvable because OpenCode was launched from a GUI app rather than a shell with your full PATH loaded; launching from a terminal fixes it.
AWS_PROFILE=dev-readonly uvx awslabs.aws-api-mcp-server@latest &
sleep 2 && kill %1
Tips
- Keep AWS MCP entries in the global~/.config/opencode/opencode.json, not a project file, and double-checkenabled: true— OpenCode silently skips a server left atenabled: falsewithout a loud error.
- If OpenCode was installed via a package manager that isolates itsPATH(some Homebrew or Nix setups), verifyuvxresolves from inside OpenCode's actual runtime environment, not just your interactive shell —echo $PATHfrom a/bashtool call inside a session is a fast way to check.
Listing and Inspecting AWS Resources from OpenCode
Basic inspection prompts work about as well in OpenCode as anywhere else, since the underlying tool calls are identical — the difference shows up in how results get rendered and how much you have to steer follow-up turns.
List every Lambda function in this account with its runtime and last
modified date, sorted by last modified ascending. Flag anything on a
runtime that's past AWS's deprecation date.
aws lambda list-functions \
--query "Functions[].[FunctionName,Runtime,LastModified]" \
--profile dev-readonly
OpenCode tends to paste large JSON tool outputs into the visible transcript more verbosely than Claude Code does, which is fine for a short list-functions call but gets unwieldy fast on something like describe-instances across a large fleet. Add explicit --query JMESPath filters in your prompts more aggressively than you would with other clients — it's less about correctness and more about keeping the session readable and the context window from filling with EC2 JSON blobs you don't need re-echoed every turn.
Get the security groups for EC2 instance i-0abc123def456789, but only show
me the GroupId, GroupName, and inbound rules — skip tags and other metadata.
For IAM and S3, the same call_aws command patterns from the Claude Code topic apply unchanged:
aws iam get-role --role-name lambda-analytics-ingest-role --profile dev-readonly
aws s3api get-bucket-policy --bucket analytics-events --profile dev-readonly
Tips
- Add--queryJMESPath filters proactively in OpenCode prompts, more than you'd bother with elsewhere — its transcript rendering makes large unfiltered JSON blobs noticeably harder to scroll past than Claude Code's collapsible tool-output view.
- If a singlecall_awsresponse looks truncated mid-JSON, it's usually OpenCode's own output buffer, not the AWS API — re-run with a narrower--queryrather than assuming the API call itself failed.
Practical Example: Tracing a Failed Lambda Invocation in OpenCode
Same investigation as the Claude Code CloudWatch workflow, run through OpenCode to show where behavior diverges. Function: payment-webhook-handler, symptom: intermittent 500s reported by a downstream partner.
Query CloudWatch Logs Insights for /aws/lambda/payment-webhook-handler over
the last 3 hours. Find all invocations that took longer than 10 seconds
or errored, and group them by error type.
fields @timestamp, @duration, @message
| filter @duration > 10000 or @message like /ERROR/
| stats count(*) as occurrences by bin(5m)
| sort @timestamp desc
OpenCode executes this via execute_log_insights_query identically to Claude Code — the tool call itself is client-agnostic since it's the MCP server, not the client, doing the work. Where it diverges is multi-step reasoning across tool calls: in a few real sessions, OpenCode needed a more explicit nudge to actually correlate the Logs Insights output with the function's code, versus Claude Code inferring the connection on its own. Being specific closes the gap:
Now pull the source of the Lambda's handler function from ./src/handlers/payment_webhook.py
and tell me which line is most likely responsible for the timeout pattern
you just found — the errors cluster around calls to the downstream fraud-check API.
This second, more explicit prompt reliably gets a useful answer: a synchronous requests.post() call to the fraud-check API with no timeout parameter set, which under partner-side slowness exceeds the Lambda's own configured timeout. The fix (add an explicit timeout= and retry/backoff) is the same regardless of client — the point is that OpenCode benefits more from decomposed, explicit prompts than from one large "investigate and fix this" instruction.
Tips
- Break multi-step AWS investigations into explicit prompts in OpenCode rather than one broad instruction — it's noticeably more reliable when told "now do X with the result of Y" than when asked to chain the reasoning itself.
- Cross-reference log findings against actual source file paths in your prompt (./src/handlers/payment_webhook.py) rather than assuming the agent will locate the right file from function name alone in a large repo.
Known Limitations for AWS MCP in OpenCode
Worth being upfront about, since choosing the wrong client for a given AWS task wastes more time than any config issue:
- No built-in credential refresh nudge. Claude Code doesn't auto-refresh SSO tokens either, but its error surfacing is clearer about why a tool call failed. In OpenCode, an expired SSO token often surfaces as a generic tool-execution error in the transcript, and you'll want to habitually run
aws sso login --profile dev-readonlyproactively at the start of a session rather than waiting for a cryptic failure. - Large JSON tool outputs render less cleanly. As noted above, this is a UX issue, not a correctness one, but it meaningfully affects how usable long EC2/CloudFormation inspection sessions feel.
- Weaker implicit multi-step chaining. Complex investigations (correlate logs → find code → propose fix → check IAM before suggesting a permission change) benefit from being broken into explicit steps more than they do in Claude Code.
- No first-party AWS MCP extension for an IDE panel. OpenCode's story here is CLI/TUI-first; if you want an in-editor AWS-aware panel, Cursor or the Claude Code VS Code extension are currently ahead.
- Cost Analysis server less exercised in practice.
awslabs.cost-analysis-mcp-serverworks from any MCP client in principle, but the multi-turn "narrow down cost drivers" workflow (see the Gemini CLI topic) tends to need more manual steering in OpenCode than elsewhere.
None of these are blockers for genuine use — teams do run AWS MCP through OpenCode successfully — but if your primary AWS workflow is long, multi-step incident investigation, expect to write more explicit prompts than you would in Claude Code.
Tips
- Start every OpenCode + AWS session with an explicitaws sso loginreminder to yourself (or a pre-session shell alias) — don't rely on OpenCode surfacing an expired-token error clearly.
- For genuinely complex, multi-hour incident work, consider Claude Code or Cursor as the primary driver and OpenCode as a secondary/parallel session for isolated lookups — play to each client's actual strengths rather than forcing one tool through everything.
Tips
Tips
- Hand-editopencode.jsoncarefully — there's nomcp addsafety net, so a typo in thecommandarray fails silently rather than with a clear CLI error.
- Lean on explicit--queryJMESPath filtering and step-by-step prompts more than you would in other clients; both compensate directly for OpenCode's current UX and multi-step-reasoning gaps.
- Treat OpenCode as a solid choice for direct, single-step AWS inspection and a weaker one for long autonomous multi-step incident chains — route accordingly rather than fighting the tool.