Skip to main content

Your AI Agent Can Restart Production Now: What a Coolify MCP Bridge Teaches About Infrastructure Context vs Code Context

12 min readDora NodaDora Noda
Share
On this page

"Restart the PostgreSQL database container immediately."

That is not a runbook step. It is a sample chat prompt from the README of coolify-anythingllm-mcp, a community Model Context Protocol server that plugs a self-hosted AnythingLLM agent straight into the Coolify API. Type the sentence, and the agent lists your apps, reads the deployment logs, diagnoses the failure, and triggers the restart — on your home lab or VPS, over infrastructure you own.

The project's pitch is that giving AI agents code context was great, but giving them infrastructure context is the game-changer. It is right. It is also, by its own admission, experimental: the same README that advertises one-prompt restarts recommends human-in-the-loop confirmations and disclaims responsibility for "any server downtime, data loss, or accidental resource deletion caused by your AI model."

That tension — a demo that works today and a disclaimer that concedes it probably should not run unsupervised — is the most honest summary of where agent-operated infrastructure stands in late 2026. So let us take the bridge seriously as a case study: what does a "secure bridge between agent framework and infra API" concretely require, what does this wiring actually provide, and why is infrastructure context a fundamentally different security boundary than code context?

The gap, up front​

Here is the whole article in one table. Left column: what a secure agent-to-infrastructure bridge needs. Right column: what the demo wiring — AnythingLLM's @agent plus a stdio MCP server holding one static Coolify API token — actually gives you.

RequirementSecure bridgeDemo wiring
Scoped authorityToken grants only what the agent's job needs (read vs. deploy)One COOLIFY_API_TOKEN; README never mentions Coolify's read / read:sensitive / write / deploy / root permission split
AuthenticationPer-request, audience-bound credentials (OAuth 2.1 per the current MCP spec)A long-lived static token in an env file; stdio transport has no auth layer at all
Permission granularityPer-call approval for mutations; read-only and mutating tools separatedAnythingLLM supports MCP Tools only, and the spec defines no per-call permission model — once connected, every tool is callable
AuditabilityEvery tool call logged: who asked, what ran, what changedWhatever Coolify logs server-side; the agent's reasoning and tool-call trail live in a chat UI
Blast radiusA confused or hijacked agent can only reach its sandboxA confused or hijacked agent holds production deploy, restart, and rollback over every app the token's team can see

Nothing in the right column is a bug in the bridge. It is what you get when a demo optimizes for "it works in five minutes" and security is defined, as this README defines it, as "no hardcoded credentials — everything runs via environment variables." That definition was already thin for code agents. For infrastructure agents, it misses every load-bearing wall. The rest of this post fills in why, with the receipts from a year of MCP security research.

What the bridge actually wires up​

The architecture has three parts, and each one matters for the analysis:

  1. AnythingLLM is the agent and the UI. Its MCP support covers Tools only — Resources, Prompts, and Sampling are not supported — and it auto-starts your configured MCP servers when you open the Agent Skills page or invoke @agent. Notably, AnythingLLM's own hosted cloud offers no MCP support at all, citing "security concerns" plus the general limitations of running arbitrary code in a hosted environment. MCP is a self-host-or-desktop-only feature even in the product that ships it.
  2. The MCP server runs locally over stdio (node /path/to/dist/index.js) and translates between the agent and the Coolify API. Its tool surface is the whole deploy-ops loop: list applications, check container status, fetch application and deployment logs, trigger builds, restart services, roll back.
  3. The Coolify API (/api/v1, Bearer token) executes the tasks. Coolify's tokens are team-scoped with genuinely granular permissions — read, read:sensitive, write, deploy, root — and a default rate limit of 200 requests per minute. The granularity the bridge needs already exists server-side. The bridge just does not ask you to use it.

One more structural detail worth knowing: Coolify API responses are extremely verbose. A single application object can carry 91 fields including embedded server blobs and full docker-compose files, so a fleet listing can exceed 200KB — enough to exhaust an agent's context window. A sibling project, coolify-mcp (42 tools), exists largely to return optimized summaries instead of raw payloads. That verbosity is not just a cost problem; as we will see, it is a security problem too, because everything the agent reads is content a prompt-injection attacker can potentially shape.

Why infrastructure context is a different boundary than code context​

Code assistants read your repository and propose diffs. The worst case is usually a bad suggestion a human reviews. Infrastructure agents act: they restart databases, roll back deploys, and read live production logs. Two asymmetries make that a different boundary, not a bigger version of the same one.

Reads leak runtime secrets, not just source. A codebase contains secrets occasionally and by accident. Production infrastructure contains them structurally: environment variables, database connection strings, S3 credentials, all retrievable through the same "fetch the logs / describe the app" tools the agent uses for diagnostics. Coolify's token model acknowledges this with a dedicated read:sensitive scope distinct from plain read.

An agent holding an unscoped token does not distinguish between "read the log line about the crash" and "read the env block above it" — both are just context. OWASP's MCP Top 10 (beta) names this failure mode directly: context over-sharing (MCP10), alongside excessive privilege and token mismanagement.

Mutations execute from a probabilistic planner. A restart issued because a chat model inferred the database was the problem is not the same as a restart issued by a runbook step or a reviewed CI job, even when the API call is byte-identical. The authorization decision moved from "did an authenticated principal with the deploy role approve this change" to "did a language model produce a plausible-sounding plan." OWASP's 2026 agentic guidance frames this as Excessive Agency (LLM06) compounded by Tool Misuse (ASI02): the agent has legitimate access to a dangerous tool and no principal but itself deciding when the tool is appropriate. The bridge README's answer — enable human-in-the-loop confirmations — is correct and also the entire safety story: one checkbox in a chat UI standing between a probabilistic planner and production mutations.

The 2026 threat catalog, applied to this exact wiring​

This is not hypothetical. The last twelve months produced a steady stream of MCP-specific attacks, and uncomfortably many of them land directly on a self-hosted deploy-ops bridge.

Poisoning through tools and data. In January 2026, a Cyata researcher published an exploit chain against Anthropic's official Git MCP server: path traversal, argument injection, and a repository-scoping bypass, all reachable from text the model read — remote code execution from a prompt. The same class of attack applies to tool descriptions (an MCP server's metadata can carry instructions the model follows but the user never sees) and to tool outputs: deployment logs are attacker-influenceable text rendered into the agent's context.

In August 2026, researchers filed MCP-2026-008 (cache poisoning) and MCP-2026-015 (prompt injection) as a pair describing a working cross-user attack built on the spec's new caching behavior. Your agent reads logs to diagnose failures; those logs are now part of your prompt-attack surface.

Static tokens with no audience binding. The bridge authenticates to Coolify with one long-lived Bearer token sitting in a .env file, and the stdio hop between AnythingLLM and the MCP server has no authentication at all. The current MCP authorization spec (2026-07-28) moved the protocol to OAuth 2.1 with protected-resource metadata (RFC 9728), resource indicators (RFC 8707), and issuer validation (RFC 9207) — and it explicitly forbids token passthrough, where a server forwards a token it received to a downstream API, because that recreates the confused-deputy problem.

A single static token that the agent's server holds forever is the pre-spec pattern the spec authors spent a year trying to retire. And note what the spec still does not define: a per-call permission model. Authorization happens at connect time; after that, tools/call is unrestricted within the granted scope. "Confirm at connect" is the whole model.

Supply chain and rug pulls. Snyk's February 2026 finding of 1,467 malicious payloads in the ClawHub MCP marketplace, the mcp-remote OS-command-injection CVE (CVE-2025-6514, CVSS 9.6, at 437,000 downloads), and Palo Alto Unit 42's December 2025 research on MCP attack vectors all point the same way: an MCP server is arbitrary code you install into your agent's trust boundary, and the ecosystem's distribution channels are young. One 2026 analysis attributes roughly 43% of MCP CVEs to command injection — the unglamorous bug that does real damage when the server holding your deploy token shells out.

Consent bypass on the OAuth path. Even doing auth "properly" has teeth: Obsidian Security's January 2026 research found three OAuth consent-bypass and token-relay vectors against MCP servers (shared client IDs, URL capture, cookie injection), with Square's MCP server exposing merchant and banking data as the headline example. Microsoft's June 2026 "State of MCP Security" writeup organizes all of this into six risk areas, with authorization/confused-deputy and credential aggregation high on the list. The bridge sidesteps OAuth entirely by using stdio plus a static token — which removes the consent-bypass class and replaces it with "no auth at the MCP layer and one God-token downstream." That is a trade, not a win.

The secure-bridge checklist​

So what would it take to promote this demo into something a self-hosted PaaS could actually endorse? Six concrete requirements, each mapped to a row in the gap table:

  1. Least-privilege tokens, plural. Mint one Coolify token with read for diagnostics and a separate token with deploy for mutations — never root, never one token for both. If the agent only diagnoses today, it holds only the read token. Coolify already supports this; the bridge should demand it in setup, not leave the permission choice to whoever pastes a token.
  2. Split read-only and mutating tools into separate servers. Run the diagnostics tools and the deploy/restart/rollback tools as two MCP servers with two different credentials, so revoking deploy authority is a server removal, not a prompt instruction. Prompt-level constraints ("never restart without asking") are suggestions to a planner, not access control.
  3. Human-in-the-loop on every mutation, enforced outside the model. AnythingLLM's confirmation setting is the right instinct, but approvals must be enforced by the tool layer (a deny-by-default gate the agent cannot talk its way past), not requested by it. An agent that asks permission and an agent that requires permission are different systems.
  4. Per-request, audience-bound auth for anything remote. stdio on localhost can lean on OS process boundaries; the moment the MCP server or the agent moves to another host, the 2026-07-28 OAuth 2.1 profile — resource indicators, audience validation, no passthrough — is the floor, not the ceiling.
  5. An audit log of every tool call. Record the prompt, the tool invoked, the arguments, and the result, outside the chat UI, in a store the agent cannot edit. "The agent says it only listed apps" is not an audit trail. Coolify's server-side logs cover what changed; you also need what the agent attempted, including denied calls.
  6. Secret redaction on the read path. The log-fetching and app-describing tools should strip env blocks, connection strings, and credential-shaped values before they enter agent context — enforcing the read vs read:sensitive distinction at the tool layer, so a diagnostics agent never holds secrets it does not need and injected log content has less to exfiltrate alongside.

None of these is exotic. Every one of them is standard practice for CI/CD pipelines, which solved "automated systems holding deploy authority" years ago with scoped tokens, approval gates, and immutable audit logs. The uncomfortable lesson of the bridge is that agent deploy-ops replays the entire CI security playbook debate — except the "pipeline" is non-deterministic and its definition is a chat transcript.

Agents deserve first-class operator interfaces​

The xlop bridge is worth studying precisely because it is honest: a genuinely useful demo whose own README tells you not to trust it unsupervised. Infrastructure context is the game-changer it claims — an agent that can see container status and deployment logs is qualitatively more useful than one that can only read code. But "secure bridge" has to mean more than env-var hygiene. It means scoped deploy authority, per-request authentication, tool-layer approval gates, and audit trails — the same controls we demand of every other system that can restart production, applied to a principal that reasons in prose.

For self-hosted platforms, the direction is clear: if AI agents are going to be first-class operators, they need first-class operator interfaces — machine-readable state, least-privilege credentials minted per task, and mutation paths that no prompt injection can silently widen. A chat box holding a root token is the prototype. The checklist above is the product.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. We are building for a world where AI agents deploy and operate apps as first-class citizens. Star the repo on GitHub or deploy your first app today.

Related articles

Give your agents a chain backend

Autonomous agents hit RPC endpoints very differently than people do. See what bex router handles on their behalf.

Read the agents guide