{"slug": "i-gave-an-ai-two-empty-servers-and-one-prompt-kimi-k3", "title": "I Gave an AI Two Empty Servers and One Prompt (Kimi K3)", "summary": "Developer jhd3197 built Agent Bridge in Faro, an SFTP/SSH client, to let AI agents operate on remote servers without exposing credentials. The bridge uses an HTTP endpoint speaking MCP, requiring a bearer token and per-session opt-in, with approval prompts for side-effect commands. In a test, the agent installed ServerKit on two DigitalOcean droplets in parallel using a single prompt, demonstrating fleet management without installing daemons on remote machines.", "body_md": "Every setup I found for letting an AI agent work on a server asked for one of two things. Either I paste a private key somewhere the agent can read it, or I install a daemon on the box and leave it running. I wasn't willing to do the first and didn't want to maintain the second, so for about a year I just didn't use agents for ops work. I'd have one open in a window, describing a problem to it, then type the commands myself.\n\nWhat eventually bothered me about that: I already have an authenticated SSH session open. It's sitting in the file manager I use every day, connected, host key verified, ready. The agent doesn't need credentials. It needs *that session*, and it should have to ask me before it touches it.\n\nThat's the Agent Bridge in Faro, the SFTP/SSH client I maintain. I'd been using it for read-only things, mostly tailing logs and diffing config between staging and prod. Last week I pointed it at something with more consequences: two brand new DigitalOcean droplets, one prompt, install a full server control panel on both.\n\nTwo minutes, no narration. [Faro](https://github.com/jhd3197/faro) and [ServerKit](https://serverkit.ai) are both MIT if you want to follow along.\n\nThe Bridge is an HTTP endpoint that speaks MCP. It binds to `127.0.0.1`\n\non a random port, requires a bearer token generated fresh each launch, and serves nothing to anything that isn't already on the machine. Connecting an agent is one command:\n\n```\nclaude mcp add --transport http faro http://127.0.0.1:<port>/mcp \\\n  --header \"Authorization: Bearer <token>\"\n```\n\nFrom there the agent gets 25 tools. `faro_exec`\n\nis the one people react to, but most of the useful work is `faro_list_dir`\n\n, `faro_read_file`\n\n, `faro_search`\n\n, `faro_tail`\n\n, `faro_diff`\n\n— inspection, not mutation. Being able to say \"read the nginx config on both boxes and tell me what's different\" turns out to be worth more day to day than remote execution.\n\nThree things stand between a tool call and my server. Sessions are opted in one at a time, so a saved connection I haven't granted access to isn't in the list the agent receives; it can't act on a box it can't see. Anything with side effects raises a prompt in the Faro window showing the exact command, and the call blocks until I answer or it times out after two minutes. And every call, approved or denied, lands in a running activity log.\n\nNone of that involves the agent holding a secret. It talks to localhost. Faro holds the SSH session, and nothing gets installed on the remote side, which is the part I care about most across a fleet.\n\nThis is the entire thing I typed:\n\n```\nInstall ServerKit on serverkit-test-server-1 and serverkit-test-server-2\nin parallel using faro-cli: curl -fsSL https://serverkit.ai/install.sh | bash\nReturn me the 2 admin URLs.\n```\n\nNo IPs, no usernames, no key paths. Two names, the same ones I saved in Faro months ago.\n\nThat works because of `faro-cli`\n\n, a standalone binary that talks to the same Bridge the GUI is running. It reads the URL and token out of Faro's local discovery file, so a script never handles either one:\n\n```\nfaro-cli agent sessions\n# → serverkit-test-server-1  sftp  159.223.187.83\n# → serverkit-test-server-2  sftp  157.230.230.92\n\nfaro-cli agent exec serverkit-test-server-1 'hostname'\n```\n\nCommands that arrive this way still hit the approval gate and still show up in the console. The CLI is a different door into the same room, not a way around the lock.\n\nOne server would have been an easier demo and a less honest one. Everything interesting about fleet work starts at two: the second box is where drift begins, where you paste the wrong IP, where you do six steps correctly and forget the seventh.\n\nSo I set them up deliberately differently. `serverkit-test-server-1`\n\nuses an SSH key. `serverkit-test-server-2`\n\nuses the root password DigitalOcean emails you. Both end up as ordinary entries in the same connection list, and by the time the agent sees them the difference has stopped mattering. It got two names and treated them identically.\n\nIt listed the fleet, fired at both profiles, and two install streams ran side by side. About a minute each. Then it handed back two URLs, I opened both, and there were two working panels on hardware that had been empty when I started recording.\n\nApproval fatigue is the real problem, and I don't think I've solved it. Watching an installer means clicking approve over and over, and clicking approve over and over is training yourself to stop reading. There are relaxed policies — allow-all, auto-approve read-only operations, auto-approve commands matched as safe and read-only — stored per profile so they survive a restart. Each one is a security decision, and I'd rather people make it deliberately at the start than drift into it around the fortieth prompt.\n\nThe more uncomfortable limitation: approval covers the command, not what the command does. I approved `curl … | bash`\n\n. Whatever that script did afterward was between me and my trust in that URL. The Bridge removes credential exposure and the remote daemon. It does not remove judgment, and I'd be suspicious of anyone claiming otherwise about a tool in this category.\n\nBeyond that: it's localhost-only by design, which suits an operator at a desk and does nothing for CI. The desktop builds are unsigned because I don't have an Apple or Windows certificate yet, so every OS objects the first time you launch. And both droplets in the video were throwaways, destroyed afterward.\n\nFaro is a desktop client for SFTP, FTP, SSH, S3-compatible storage, WebDAV and a handful of clouds, written in Rust on Tauri 2: [github.com/jhd3197/faro](https://github.com/jhd3197/faro). ServerKit is the panel it installed, self-hosted, one command:\n\n```\ncurl -fsSL https://serverkit.ai/install.sh | bash\n```\n\nBoth MIT, both free, neither one phones home.\n\nThe open question I keep changing my mind about is where auto-approval should stop. Read-only inspection is clearly fine. `apt install`\n\nfeels fine until the day it isn't. If you've given an agent this kind of access, I'd like to know where you drew the line, because I'm about to ship defaults and I'd rather not invent them alone.", "url": "https://wpnews.pro/news/i-gave-an-ai-two-empty-servers-and-one-prompt-kimi-k3", "canonical_source": "https://dev.to/juandenis/i-gave-an-ai-two-empty-servers-and-one-prompt-kimi-k3-11il", "published_at": "2026-08-03 04:36:26+00:00", "updated_at": "2026-08-03 05:09:39.697001+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-infrastructure"], "entities": ["Faro", "ServerKit", "DigitalOcean", "jhd3197", "Claude"], "alternates": {"html": "https://wpnews.pro/news/i-gave-an-ai-two-empty-servers-and-one-prompt-kimi-k3", "markdown": "https://wpnews.pro/news/i-gave-an-ai-two-empty-servers-and-one-prompt-kimi-k3.md", "text": "https://wpnews.pro/news/i-gave-an-ai-two-empty-servers-and-one-prompt-kimi-k3.txt", "jsonld": "https://wpnews.pro/news/i-gave-an-ai-two-empty-servers-and-one-prompt-kimi-k3.jsonld"}}