Pulumi Neo doesn't autocomplete infrastructure code — it reads your organization's live state, decides what needs to change, and executes the change itself, inside guardrails you configure. It's generally available now, and it works against Terraform, CloudFormation, and hand-created resources you never touched with Pulumi in the first place. No migration required before Neo can reason about a stack it didn't create.
That's a genuinely different bet than the one bex is making with its own MCP server: a fixed, documented set of deploy/restart/scale verbs that all call the exact same internal method the REST and GraphQL APIs call. Neo gets its power from open-ended access to whatever state already exists. bex's tools get their trustworthiness from being enumerable in advance. Both are defensible. They are not the same shape, and an agent that can create and destroy production infrastructure should not be pointed at either one without understanding which shape it's actually operating under.
What Neo Actually Does
The mechanism matters more than the pitch. When Neo migrates a team off Terraform, CDK, CloudFormation, or Azure ARM, it doesn't just generate equivalent Pulumi code from scratch — it runs a dual-layer process. First it reads the source tool's own state: a Terraform state file, a CloudFormation stack's resource metadata, an Azure deployment history. From that, it discovers each resource's physical identity — the actual ARN or resource ID, not a name Neo invented. Only then does it generate the matching Pulumi code, translating tool-specific patterns (Terraform's count and for_each, ARM template functions evaluated against real parameter values) into idiomatic equivalents. A pulumi preview run confirms zero infrastructure changes before anything ships, and the result lands as a pull request a human still approves.
That same "read state, decide, act" loop is how Neo operates day to day, not just during migration — and Pulumi gates how much of that loop runs unsupervised through three approval modes:
| Mode | What requires your approval |
|---|---|
| Review (default) | The task plan, pulumi preview, pulumi up, and opening the PR |
| Balanced | Only pulumi up |
| Auto | Nothing — Neo runs the full loop unattended |
A separate read-only permission mode strips Neo's ability to change anything regardless of task mode, and an opt-in Plan Mode adds a fourth gate ahead of all three, running through four distinct phases before any of the three approval modes above even engage: discovery (Neo examines the environment, reads relevant code, checks dependencies), synthesis (it produces a written plan citing what it found — specific stack configs, specific dependency chains, not a generic summary), refinement (the team pushes back in conversation, challenges an assumption, asks for a different approach), and only then approval, at which point execution starts and carries the discovered context forward. That sequencing matters for exactly the cases a single approval prompt doesn't cover well: a multi-stack operation or infrastructure Neo has never touched benefits from a team seeing the plan go wrong before any command runs, not from rejecting a pulumi up after the fact.
Pulumi's own rollout — preview in September 2025, Plan Mode in April 2026, CLI/GitHub/Slack access in May, code-review automation reaching GA in July, usage dollar-caps shipping the same month at $3 per million Neo tokens — reads less like a single feature launch and more like a vendor incrementally widening how much of its own product an agent is trusted to touch.
The Actual Tension: Open-Ended State Access vs. an Enumerable Verb Set
Strip away the approval modes and the underlying architecture is what actually matters: Neo's authority is bounded by policy, not by shape. Its access to Pulumi Cloud's state graph is structurally open-ended — any resource type, on any cloud, that Pulumi's providers can represent, is something Neo can read and potentially write. Auto mode doesn't add capability Review mode lacks; it just removes the human checkpoints in front of a capability that was already there. An operator auditing Neo's blast radius has to reason about the entire space of what a live state graph could contain, not a fixed list.
bex's MCP server takes the opposite bet on purpose. It ships thirteen tools — list_services, restart_service, suspend_service, scale_service, update_service_plan, list_logs, get_metrics, the Postgres and API-key set — and every one of them calls the identical internal Service method the REST handler and GraphQL resolver call for that same action. There is no fourteenth thing an agent can do by finding an undocumented corner of a state graph, because there is no state graph exposed to the agent at all — only the verbs a human explicitly wired up. The permission surface an operator has to reason about is the tool list itself, and it's fully enumerable before an agent ever calls one. That's the deliberate tradeoff: bex gives up Neo's ability to make sense of infrastructure nobody designed for it, in exchange for a blast radius that's knowable in advance, not discovered by an incident review after the fact.
Where Neo's Bet Genuinely Wins
That tradeoff isn't free, and it's worth being honest about where a fixed verb set structurally can't compete. A team with years of hand-written Terraform, CloudFormation stacks nobody's touched since 2021, and drift nobody's reconciled has infrastructure that predates any API a vendor could have designed to consume it. There is no way to enumerate a fixed tool list — import_resource, reconcile_drift, migrate_stack — that anticipates every shape that infrastructure could be in, because the whole problem is that nobody designed it with a consumer in mind. Open-ended state access isn't a shortcut Pulumi took instead of building a proper API; it's the only shape that can generalize across infrastructure a platform never provisioned and doesn't control the schema of. Neo reading a CloudFormation stack's metadata and reverse-engineering physical resource IDs from it is doing something a fixed API genuinely cannot do.
That's precisely why it's the wrong model for bex. Every resource an agent can touch through bex's MCP server is something bex itself provisioned, on a schema bex itself controls — a service, a Postgres instance, a plan, an API key. There's no heterogeneous legacy infrastructure to reverse-engineer, because bex is the thing that created the infrastructure in the first place. Reaching for Neo's open-ended-state-access model to operate a platform's own owned, uniform resources would be importing a solution to a problem bex doesn't have, at the cost of a blast radius that's no longer enumerable in advance.
What This Should Actually Change on bex's Roadmap
bex's MCP server already has a gap Neo's approval-mode design speaks directly to: there's no deploy_app tool yet, because in-cluster builds and git-triggered deploys are still open roadmap items, not because the tool table wasn't wide enough. deploy_app will be the single highest-blast-radius verb bex ships — the one that takes a repo and a bex.yml to a live URL — and it's the one tool in the future lineup that should not inherit the same default as list_services or get_metrics.
The fix isn't to open-end bex's state model to match Neo. It's to borrow Neo's approval-mode split as a per-tool setting inside the fixed verb set bex already has:
- Auto by default: read-only tools —
list_services,get_service,list_logs,get_metrics,list_postgres_instances— carry no destructive potential regardless of who calls them. - Balanced by default:
restart_service,suspend_service,resume_service,scale_service— reversible, bounded operations where an agent acting alone is a nuisance, not an outage, if it guesses wrong. - Review by default, no exceptions:
update_service_plan(billing impact),create_api_key/revoke_api_key(credential blast radius), and the still-unshippeddeploy_app— the one action that can put an entirely new, unreviewed codebase in front of the public internet.
That's a much smaller lift than anything Neo's architecture requires, because bex isn't trying to reason about arbitrary state — it's assigning a trust tier to a tool list that's already finite and already known. The MCP spec's destructiveHint annotation (already used by competitors shipping deploy verbs) is the mechanical hook: a client can surface an approval prompt automatically once the annotation says a tool needs one, without bex having to build Pulumi's plan/preview/apply pipeline from scratch.
The Verdict
Neither "the agent reads real infrastructure state directly" nor "the agent calls a purpose-built, enumerable API" is the universally correct shape — they're the correct shape for different infrastructure. Open-ended state access earns its complexity when the infrastructure is heterogeneous, pre-existing, and outside the platform's own schema — Neo's actual job. A fixed, documented verb set earns its trust when the infrastructure is uniform and self-provisioned, and the whole point is that an operator can know the entire space of what an agent could possibly do before that agent ever runs. bex's bet is the second one, and Pulumi Neo's own architecture — not its marketing — is the clearest argument for why that bet is correct for a platform whose only infrastructure is the infrastructure it built.
bex is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with an MCP server whose entire tool surface is enumerable before an agent ever calls it. Star the repo on GitHub or point an agent at /mcp today.



