You are three files into a payments service. It needs a queue for retries, a bucket for uploaded documents, and a Postgres instance. Claude Code can write all of that Terraform in about forty seconds.
Then you stop, because writing it was never the slow part.
The slow part is everything after: find the right infrastructure repo, work out which directory this belongs in, copy the code across, guess the variable names your platform team settled on last quarter, open a pull request, wait for CI, get told the tag block is missing a cost centre, fix it, wait again.
Connecting the agent to your cloud through an MCP server removes most of that loop. This post is the practical version. What you need, what the connection looks like, what the first request actually produces, and the four ways it goes wrong.
If you want the design argument first, what an MCP server is, what it should refuse to expose, and why authorization is the whole problem, that is a separate post. This one assumes you have one and want to use it.
What do you need before you connect anything?
Four things, and only the last one is a decision.
An MCP server that speaks to your cloud. Either a local one launched on your machine over stdio, or a remote one your team shares over HTTP. Local is simpler and runs as you. Remote is the one that needs real authorization, and it is the one most teams end up with.
An account on the platform behind it. The server does not grant you permissions. It uses the ones you already have, which is the point.
A recent Claude Code. Remote server support and the OAuth flow have both moved in the last year, so an old version will fail in ways that look like server problems.
Somewhere for the output to land. If the server opens pull requests, it needs a repository and a branch it is allowed to push to. Decide this before you connect, not during your first request.
One thing not on that list: a production account. Do not wire an agent to a server that can apply to production on the day you are still learning what it does.
How does Claude Code connect to a remote server?
You register the server once, then authenticate in the session.
claude mcp add --transport http devlift https://your-host.example.com/mcp
Flags move between versions, so run claude mcp add --help and trust that over any blog post, this one included. The shape is stable even when the flag names are not: a name you choose, a transport, and a URL.
Scope is the part worth thinking about. A server added at project scope is written into a .mcp.json file in the repository, which means it is committed and every teammate who opens the project gets prompted to enable it. That is either exactly what you want or a surprise for eleven people, depending on whether you told them.
Then, inside a session, run /mcp. If the server requires authorization you get a browser window, a consent screen listing what the server is asking for, and a redirect back. Claude Code stores the token and reuses it.
The consequence is the whole reason to prefer this over an access key in an environment variable: the token is yours. Every action the agent takes through that server is attributed to you and bounded by your permissions. If you cannot create resources in production, neither can the agent while it is working for you. Not because it was instructed not to, but because the token does not permit it.
Run /mcp again afterwards and you should see the server connected with its tools listed. If the tool list is empty, the connection succeeded and the authorization did not.
What does the first request look like?
You do not call a tool. You write a sentence.
Create an SQS queue called payments-retry in staging, owned by the payments service, with a dead letter queue after five attempts.
What happens next is worth watching once, because it tells you whether the server was designed properly.
A well built one makes the agent do this:
- Ask what exists. Something like
list_supported_resources, which returns the resource types your platform actually supports. This is the step that prevents a confident request for a service nobody at your company has ever provisioned. - Ask what it needs.
describe_resourcefor the queue type, which returns the required parameters. Some are AWS parameters. The interesting ones are yours: environment, owning team, cost centre, retention policy. - Submit.
provision_resourcewith those parameters filled in. This should return a job identifier, not a success message. - Check.
get_deployment_statusagainst that identifier.
The first two steps are the ones people skip when evaluating this, and they are where most of the value sits. An agent that asks what is supported before asking for something is an agent that fails validation instead of inventing infrastructure. Those are very different failure modes and only one of them wastes your afternoon.
What comes back?
On a server worth using: a pull request.
Not a queue. A branch with generated infrastructure as code on it, a diff you can read, and whatever CI already runs on that repository running against it.
This matters more than it sounds. The review process you spent two years building does not know or care that a model wrote the change. The Terraform plan still runs. The policy check still runs. The person who has to be on call for the thing still has to approve it.
A server that applies directly skips all of that. It is faster and it is a genuinely different risk profile, and it should be a deliberate choice rather than something you discover on the day something goes wrong.
What is the agent not allowed to do?
Short list, because the reasoning is covered elsewhere:
- No raw command escape hatch. If the server exposes something like
run_aws_command, every constraint above it is decoration. - No deletes on the same path as creates. Creating is recoverable. Destroying frequently is not.
- No credentials in the conversation. The server holds them. The model never sees them, so they cannot reach a log, a context window, or a screen recording.
Check these before your first real request rather than after.
Where does it go wrong?
Four failure modes, in the order you are likely to hit them.
The request that was too vague. "Set up the infrastructure for my new service" gives the agent nothing to work from, so it guesses an environment, a naming convention and a size. Name the environment and the owning service every time. It costs six words and removes most of the guessing.
The expired token. Symptom: things worked this morning and now the tools have quietly vanished from /mcp, or a call fails with an authorization error partway through a sequence. Re-run /mcp and re-authenticate. Worth recognising immediately, because it does not look like an auth problem, it looks like the server broke.
Treating submitted as done. A provisioning request can be accepted and then fail during apply, several minutes later. If you read the agent's "created the queue" message as fact, you will build the next thing on top of something that does not exist. Ask for the status. Better, use a server that returns a job identifier so there is nothing to mistake.
Too many servers connected at once. Tool selection degrades as the menu grows. If you have a filesystem server, a database server, a ticketing server and an infrastructure server all live, the model is choosing from a long list rather than following an obvious path. Turn off the ones you are not using for this task.
Is it actually faster?
Honestly: yes, but not for the reason it gets sold on.
The Terraform was never the bottleneck. A competent engineer writes an SQS module in twenty minutes and a model writes it in forty seconds, and neither number is what makes provisioning feel slow.
What is slow is the context switch. Deciding you need a queue, then leaving the problem you were actually solving to go and get one, then coming back an hour later having lost the thread. Closing that gap is the real saving, and it does not show up in any benchmark.
Two places it does not help:
Novel infrastructure. The first time your organisation provisions a new class of thing, someone has to make decisions nobody has made before. An agent working from a catalogue of what already exists is exactly the wrong tool for that.
Review capacity. You now generate pull requests faster than before. Somebody still reads them. If your review queue was already the constraint, this makes it worse, not better.
A reasonable way to start
- Read only for a week. Connect the server, use only the describe and list tools. You learn what your own platform actually supports, which is frequently a surprise.
- One non production service. Provision something small in staging. Read every line of the pull request.
- Keep reading the diffs for the first ten. Not forever, but long enough to know what a normal one looks like. You cannot spot an unusual change if you have never looked at a usual one.
- Then widen. More resource types, more of the team, and only then any conversation about production.
That sequence is slower than it needs to be for about two weeks and considerably faster than the alternative for everything after.
DevLift exposes its platform to Claude Code and other AI coding agents through an MCP server with OAuth 2.1, so the agent provisions as the developer driving it rather than as a shared account, and every change arrives as a pull request instead of an applied resource. Book a walkthrough against your own account, or read what an MCP server for AWS actually does.