Letting AI Agents Deploy to Your Own Servers With MCP (Without Handing Them Root) A developer outlined a pattern for letting AI coding agents deploy to self-hosted servers through the Model Context Protocol (MCP) without granting them root or shell access, using per-person, per-workspace bearer tokens that inherit the issuing human's role-based permissions. The approach exposes a typed tool catalog — list_services, deploy, get_logs, set_env — so agents make scoped, loggable calls instead of improvising shell commands, and was tested against Peon's open source, self-hostable deployment platform and its built-in MCP endpoint. Coding agents got good at writing code long before they got safe at running it. The moment you ask Cursor or Claude to "deploy this and check the logs", you hit a real question: what exactly is the agent allowed to touch? The lazy answer is an SSH key or a cloud admin token pasted into a config file. It works, and it is also how you end up with an agent that can rm -rf a production volume because it misread a stack trace. This post walks through a better pattern for self-hosted infrastructure: expose deployment operations to agents through the Model Context Protocol MCP , and let the same role based access control that governs your human team govern the agent too. MCP is a standard way for an AI client to discover and call tools on a server. Instead of the agent improvising shell commands, it sees a typed catalog: list services , deploy , get logs , set env , and so on. Each tool has a schema, and the server decides what each call is allowed to do. That shift matters for operations work for three reasons: Before wiring anything up, write down what you are protecting against. For most small teams it looks like this: None of these are solved by a smarter model. They are solved by scoping. Whatever platform you use, these rules hold up well: Use a per-person, per-workspace token. Never share one token across a team, and never reuse your own admin token for an agent that works on a single project. If your platform supports it, create a separate user or membership for automation. Inherit roles, do not invent them. The agent should get exactly the permissions of the human who issued the token, or less. If a developer can only deploy to the staging project, their agent should hit the same wall. Leave out interactive shells. Shell access is the escape hatch that makes every other control pointless. Deployments, restarts, env changes, and log reads cover nearly everything an agent needs. Keep terminals for humans. Treat tokens like passwords. Keep them in your MCP client config or a secret manager, not in repos. Rotate by revoking and reissuing. Prefer reversible actions. Rollback should be one tool call. If an agent can deploy, it should also be able to undo its own deploy. I have been testing this pattern with Peon's MCP server docs https://peon.sh/docs/mcp as the reference setup, because it follows the checklist closely. Peon is an open source, self-hostable deployment platform, and its MCP endpoint is part of the app itself rather than a side script. The client configuration is short. In Cursor or Claude Desktop you add a streamable HTTP server with a bearer token: { "mcpServers": { "peon": { "url": "https://app.peon.sh/mcp", "headers": { "Authorization": "Bearer peon xxxxxxxx" } } } } If you self-host, the URL becomes https://your-domain/mcp . The token is created in the dashboard under Keys and Tokens, is scoped to one workspace, and inherits the creator's role. An owner or admin token can manage servers; a project member token only reaches the projects that member belongs to. The details are in the docs on workspace and project roles https://peon.sh/docs/workspaces-and-roles . Two design choices are worth copying even if you build your own server: Here is the kind of loop that works well once scoping is in place: blog project and tell me which one failed its last deploy." DATABASE URL , explains the fix, and asks before setting it. Nothing in that loop needed root. Every step is a typed call that your platform can log and deny. If you want a full example, there is a walkthrough of an agent shipping an app end to end https://peon.sh/blogs/ai-agents-deploy-apps-mcp-peon that covers the same flow with screenshots. Server side scoping is the foundation, but a few client habits help: Agents are great at the boring middle of operations: reading logs, correlating a failed deploy with a config change, and doing the obvious fix. They are a poor fit for: Keep those human, or at least human-approved step by step. MCP gives you a clean contract between an AI client and your infrastructure. The contract is only as safe as the permissions behind it, so start from the rules above: personal scoped tokens, inherited roles, no shell tools, reversible actions, and an audit trail. If you run your own servers, this is one of the few places where self-hosting makes AI tooling safer rather than riskier, because you control both the tool catalog and the permission model. I would love to hear how others are scoping agent access in their own stacks.