<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: EQVPS</title>
    <description>The latest articles on DEV Community by EQVPS (@eqvps).</description>
    <link>https://dev.to/eqvps</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3985877%2F020dd65e-580c-4e07-97d4-e4f641cce059.png</url>
      <title>DEV Community: EQVPS</title>
      <link>https://dev.to/eqvps</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eqvps"/>
    <language>en</language>
    <item>
      <title>Running a mail server on a VPS: what actually keeps you out of spam</title>
      <dc:creator>EQVPS</dc:creator>
      <pubDate>Sat, 04 Jul 2026 09:15:59 +0000</pubDate>
      <link>https://dev.to/eqvps/running-a-mail-server-on-a-vps-what-actually-keeps-you-out-of-spam-2hop</link>
      <guid>https://dev.to/eqvps/running-a-mail-server-on-a-vps-what-actually-keeps-you-out-of-spam-2hop</guid>
      <description>&lt;p&gt;Your mail server works. Postfix starts, the logs look clean, you send a test message to your Gmail — and it lands in spam. Or it just disappears. Nothing in your config is broken. The software did exactly what you told it to.&lt;/p&gt;

&lt;p&gt;The problem is that the server on the other end doesn't trust your IP yet, and email hides a whole stack of small trust checks that all have to line up before a stranger's inbox lets you in. Get those right and delivery mostly takes care of itself. Miss one and you're shouting into a spam folder.&lt;/p&gt;

&lt;p&gt;Three things carry most of the weight: reverse DNS, sender authentication, and whether your host even lets you talk on port 25. None of them are hard. They're just easy to forget, and each one is a quiet veto.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one everyone forgets: reverse DNS
&lt;/h2&gt;

&lt;p&gt;Forward DNS is the part you know — a name points to an IP. Reverse DNS is the mirror: an IP points back to a name. That record is called a PTR, and it lives with whoever controls the IP, not in your domain's zone.&lt;/p&gt;

&lt;p&gt;Here's why it matters. When your server opens a connection to Gmail's SMTP, one of the first things the receiving side does is a reverse lookup on your IP — &lt;em&gt;who is this?&lt;/em&gt; Run it yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig &lt;span class="nt"&gt;-x&lt;/span&gt; 203.0.113.19 +short
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that comes back with something like &lt;code&gt;static.203-0-113-19.rev.example-isp.net&lt;/code&gt;, or comes back empty, you've already lost points. That generic name says "some random VPS," and worse, it doesn't match the hostname your server introduces itself as in the HELO greeting. Receiving servers flag that mismatch hard. Some reject outright.&lt;/p&gt;

&lt;p&gt;What they want to see is a PTR that matches your mail hostname. If your server says &lt;code&gt;HELO mail.example.com&lt;/code&gt;, the reverse lookup on its IP should return &lt;code&gt;mail.example.com&lt;/code&gt;. Forward and reverse agree, the story is consistent, and you look like a real mail server instead of a hijacked box.&lt;/p&gt;

&lt;p&gt;Setting a PTR has traditionally meant opening a support ticket with whoever owns the IP block and waiting. On EQVPS dedicated-IP plans it's a field in your dashboard — type the hostname, it writes straight to the registry through the provider's API, and it's live in seconds. That's the whole point of doing it self-serve: reverse DNS is the step people skip because it used to be annoying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication: SPF, DKIM, DMARC
&lt;/h2&gt;

&lt;p&gt;These three DNS records tell receiving servers that mail claiming to be from your domain really is. Skip them and you're an unverified stranger.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPF&lt;/strong&gt; is a TXT record listing which servers are allowed to send for your domain. Gmail checks it and asks: did this message come from an IP you authorized?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DKIM&lt;/strong&gt; cryptographically signs each outgoing message. The receiver pulls your public key from DNS and verifies the signature wasn't forged in transit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DMARC&lt;/strong&gt; ties the two together and tells receivers what to do when a check fails — nothing, quarantine, or reject — and where to send reports.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You want all three. SPF and DKIM prove the mail is legitimately yours; DMARC turns that proof into a policy. It's maybe twenty minutes of DNS edits, and it's the difference between "verified sender" and "who?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Port 25, and why it's shut
&lt;/h2&gt;

&lt;p&gt;Here's the one that surprises people. Outbound port 25 — the port mail servers use to talk to each other — is blocked by default on essentially every VPS host. Us too.&lt;/p&gt;

&lt;p&gt;That's deliberate. Port 25 is the classic spam cannon, so it stays closed until you ask for it and say what you're actually sending. We open it per request rather than leaving it open for anyone who spins up a server.&lt;/p&gt;

&lt;p&gt;And there's an honest caveat here worth stating plainly: with an open port 25 comes responsibility. One compromised script or a misconfigured relay pumping out spam, and your IP's reputation is gone — sometimes for weeks. On a shared subnet that mess splashes onto your neighbors, which is exactly why hosts are cautious about it. If you ask us to open 25, keep your server clean, because the reputation you're protecting is partly ours too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the dedicated IP isn't optional
&lt;/h2&gt;

&lt;p&gt;All of this circles back to one requirement: the IP has to be yours. On a NAT setup or a shared address you can't set your own PTR, because the address isn't exclusively yours to point. You also inherit whatever reputation the shared IP already carries — and you have no idea what the last tenant did with it.&lt;/p&gt;

&lt;p&gt;A dedicated IP gives you a PTR you control, a reputation that's yours to build, and a clean starting point. For outbound mail that's not a nice-to-have; it's the floor.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest bottom line
&lt;/h2&gt;

&lt;p&gt;Self-hosting email in 2026 is real, ongoing work. It's not set-and-forget — you'll watch blocklists, rotate DKIM keys, and occasionally figure out why one specific provider started greylisting you. If this is a low-stakes side project, honestly, forwarding through an existing mail provider will save you headaches.&lt;/p&gt;

&lt;p&gt;But if you want actual control — your data, your domain, nobody else reading the headers — it's very doable on a small VPS. The trust plumbing above is about 90% of the battle, and none of it is exotic. Get a dedicated IP, set the PTR to match your hostname, publish SPF/DKIM/DMARC, ask us to open port 25, then send a test through a tool like mail-tester.com and fix whatever it flags. Do that and you're not shouting into a spam folder anymore — you're a mail server people's inboxes actually trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need a dedicated IP to run a mail server?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Effectively yes. Deliverability depends on a reverse DNS (PTR) record that matches your mail hostname, and you can only set a PTR on an IP that is exclusively yours. On a shared or NAT address you don't control the PTR, so receiving servers see a generic or mismatched hostname and treat you as suspicious. A dedicated IP is the baseline for outbound mail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a PTR record and why does email need it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A PTR record is reverse DNS — it maps your IP back to a hostname, the opposite of a normal A record. When your server connects to Gmail or Outlook, the receiving side looks up who owns your IP. If the PTR is missing or generic (like static.203-0-113-19.rev.example-isp.net), that's an immediate strike against you. Mail servers expect the PTR to match the name your server announces in HELO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is outbound port 25 blocked by default on most VPS hosts?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Port 25 is the single biggest spam vector, so hosts keep it closed until you ask and explain what you're sending. It's not a bug — it's abuse prevention. One compromised script blasting spam can burn an IP's reputation, and on a shared subnet that damage spills onto other customers. Reputable hosts, EQVPS included, open it per request rather than by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run a mail server on a NAT or shared IP?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can receive mail through port forwarding, but sending reliably is another story. Without your own IP you can't set a matching PTR, and you inherit whatever reputation the shared address already has — good or bad. For anything you need delivered, use a dedicated IP with a clean history and a PTR you control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is self-hosting email actually worth it in 2026?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It depends on why. If you want control over your data and your domain with no third party in the loop, it's very doable on a small VPS. But deliverability is ongoing work — you watch blocklists, rotate DKIM keys, and keep the IP clean. For a low-stakes side project, forwarding through an existing provider is less pain. Self-host when control matters more than convenience.&lt;/p&gt;

</description>
      <category>vps</category>
      <category>devops</category>
      <category>email</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Self-host n8n on a VPS with Docker</title>
      <dc:creator>EQVPS</dc:creator>
      <pubDate>Thu, 25 Jun 2026 09:12:20 +0000</pubDate>
      <link>https://dev.to/eqvps/self-host-n8n-on-a-vps-with-docker-5ep3</link>
      <guid>https://dev.to/eqvps/self-host-n8n-on-a-vps-with-docker-5ep3</guid>
      <description>&lt;p&gt;n8n is the kind of tool you start using lightly and then quietly route half your operations through. At which point "it's running on someone's cloud seat, metered per execution, with my API keys living on their servers" starts to feel less great. Self-hosting fixes all three — flat cost, no execution cap, and your keys stay on a box you own. With Docker it's a fifteen-minute job.&lt;/p&gt;

&lt;h2&gt;
  
  
  How much server it actually needs
&lt;/h2&gt;

&lt;p&gt;Honest numbers first, so you don't over- or under-buy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;~2 GB RAM&lt;/strong&gt; is the sweet spot — n8n plus its Postgres database plus normal workflows sit comfortably here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 GB&lt;/strong&gt; works if your workflows are light, but you'll notice it on bigger runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 GB&lt;/strong&gt; if you do heavy parallel executions or push large payloads through.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;n8n isn't CPU-hungry at rest; it spikes during runs. A 2-core box is fine for most setups. (More on matching specs to workload in the &lt;a href="https://dev.to/blog/vps-sizing-for-ai-agents"&gt;sizing guide&lt;/a&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Docker setup
&lt;/h2&gt;

&lt;p&gt;On a fresh Ubuntu/Debian box, install Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.docker.com | &lt;span class="nb"&gt;sudo &lt;/span&gt;sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a folder and a &lt;code&gt;docker-compose.yml&lt;/code&gt; — n8n with a persistent volume and Postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;n8n&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.n8n.io/n8nio/n8n&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:5678:5678"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;N8N_HOST=n8n.yourdomain.com&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;N8N_PROTOCOL=https&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WEBHOOK_URL=https://n8n.yourdomain.com/&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB_TYPE=postgresdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB_POSTGRESDB_HOST=db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB_POSTGRESDB_PASSWORD=change-me&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./n8n-data:/home/node/.n8n&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=change-me&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=n8n&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./db-data:/var/lib/postgresql/data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things worth pointing out: the volumes (&lt;code&gt;n8n-data&lt;/code&gt;, &lt;code&gt;db-data&lt;/code&gt;) are what keep your workflows alive across restarts and upgrades — don't skip them. And n8n is bound to &lt;code&gt;127.0.0.1&lt;/code&gt;, not &lt;code&gt;0.0.0.0&lt;/code&gt; — it's &lt;strong&gt;not&lt;/strong&gt; exposed to the internet directly. That's deliberate; the next step handles access safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access: HTTPS or a tunnel
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public URL (needed for OAuth nodes and webhooks):&lt;/strong&gt; point a subdomain at the server and run a reverse proxy (Caddy is the least-effort — automatic HTTPS) in front of &lt;code&gt;127.0.0.1:5678&lt;/code&gt;. This is where a &lt;a href="https://dev.to/blog/best-vps-for-ai-agents-2026"&gt;dedicated-IP plan&lt;/a&gt; fits, since you control ports and DNS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Just for yourself, no domain:&lt;/strong&gt; skip the proxy and reach it over an SSH tunnel — &lt;code&gt;ssh -L 5678:127.0.0.1:5678 user@server&lt;/code&gt;, then open &lt;code&gt;localhost:5678&lt;/code&gt;. Works fine on a NAT VPS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lock it down and keep it up
&lt;/h2&gt;

&lt;p&gt;n8n holds your API keys and credentials, so the box must be tight: do the &lt;a href="https://dev.to/blog/secure-new-vps-checklist"&gt;security checklist&lt;/a&gt; (SSH keys, firewall, no password login) before you put real credentials in. &lt;code&gt;restart: always&lt;/code&gt; in the compose file already means Docker brings n8n back after a crash or reboot — that's your uptime handled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is it worth it?
&lt;/h2&gt;

&lt;p&gt;Be honest with yourself about volume. If you run automations constantly, self-hosting wins on cost (flat vs per-execution) and removes any workflow/run limits. If you trigger a few flows a month, a hosted seat is less hassle. But the control argument stands regardless: &lt;strong&gt;your workflows, your data, your keys — on your server, not rented.&lt;/strong&gt; For most people who got serious about n8n, that's the deciding factor.&lt;/p&gt;

&lt;p&gt;A 2 GB box, a compose file, a domain (or a tunnel), and you're running your own automation hub — payable in &lt;a href="https://dev.to/blog/crypto-vps-no-kyc"&gt;crypto with no KYC&lt;/a&gt;, live in minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much RAM does self-hosted n8n need?
&lt;/h3&gt;

&lt;p&gt;Around 2 GB is the comfortable sweet spot for n8n plus its Postgres database and normal workflows. It runs in 1 GB if workflows are light, but you'll feel it during bigger runs. Heavy parallel executions or large payloads — go to 4 GB.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need Docker to self-host n8n?
&lt;/h3&gt;

&lt;p&gt;It's by far the easiest way — one compose file gives you n8n, a database and persistent storage, and upgrades are a single pull. You can install via npm instead, but Docker saves you the dependency and upgrade headaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is self-hosting n8n cheaper than n8n cloud?
&lt;/h3&gt;

&lt;p&gt;If you run a steady stream of automations, yes — a flat monthly VPS beats per-execution pricing, and there's no workflow or execution cap. For a handful of runs a month, a hosted seat may be simpler. The other reason people self-host is control: your data and API keys never leave your server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a domain for n8n?
&lt;/h3&gt;

&lt;p&gt;For OAuth-based nodes (Google, etc.) and clean HTTPS, yes — point a domain at the server and put n8n behind a reverse proxy with a certificate. For purely internal use you can reach it over an SSH tunnel without a domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can n8n run on a NAT VPS or do I need a dedicated IP?
&lt;/h3&gt;

&lt;p&gt;Internal/SSH-tunnel use works on a NAT box. If you want a public URL with your own domain and HTTPS (needed for some OAuth callbacks and webhooks), a dedicated-IP plan is the cleaner fit since you control all ports.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://eqvps.com/en/blog/self-host-n8n-on-vps" rel="noopener noreferrer"&gt;eqvps.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>selfhosting</category>
      <category>n8n</category>
      <category>docker</category>
      <category>automation</category>
    </item>
    <item>
      <title>How an AI agent buys and runs its own server over MCP</title>
      <dc:creator>EQVPS</dc:creator>
      <pubDate>Wed, 24 Jun 2026 11:54:21 +0000</pubDate>
      <link>https://dev.to/eqvps/how-an-ai-agent-buys-and-runs-its-own-server-over-mcp-33fm</link>
      <guid>https://dev.to/eqvps/how-an-ai-agent-buys-and-runs-its-own-server-over-mcp-33fm</guid>
      <description>&lt;p&gt;An AI agent can write a scraper, debug it, and tell you exactly where to deploy it. Then it stops. Because the next step — &lt;em&gt;actually renting the server&lt;/em&gt; — almost always needs a human: open an account, maybe pass an identity check, type a card number into a checkout. The agent did the hard part and now waits on you for the boring part.&lt;/p&gt;

&lt;p&gt;That gap is the whole reason this exists. We took the human out of the middle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where autonomy usually breaks
&lt;/h2&gt;

&lt;p&gt;Think about what "renting a server" really involves on a normal host. A signup form. An email to confirm. Billing details, sometimes ID. A card at checkout. A dashboard to find the IP. Every one of those assumes a person sitting there.&lt;/p&gt;

&lt;p&gt;An agent can't sit there. It can call an API, hold a token, make decisions — but it can't receive a verification email or pull out a credit card. So the moment infrastructure enters the picture, the autonomous workflow turns back into a human workflow with extra steps. You wanted an agent that ships; you got an agent that files a ticket.&lt;/p&gt;

&lt;h2&gt;
  
  
  The flow, end to end
&lt;/h2&gt;

&lt;p&gt;On EQVPS the same actions are &lt;a href="https://dev.to/blog/eqvps-mcp-tools-reference"&gt;MCP tools&lt;/a&gt; (16 of them) plus a REST API — and crucially, the agent can get its own credentials. Here's the actual sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Get an account — token comes back immediately, no email, no human&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;register_account(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ada"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ada@example.com"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;//    → { token: "..." }   send it as Authorization: Bearer &amp;lt;token&amp;gt; from here on&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;// 2. See what's available&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;list_plans()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;//    → plans with specs, prices, and OS image ids&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;// 3. Make sure there's money on the balance&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;get_balance()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;//    → { balance: 25, currency: "USD" }&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;// 4. Order — this debits the balance and provisions the box&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;order_vps(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nano"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;os_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ada-worker"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;//    → { service_id, paid_from_balance: true }&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;// 5. Read the keys to its own new server&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;get_vps_status(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;service_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;//    → { ip, ssh_port, password }   ~60 seconds after ordering&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five calls and the agent is SSH'd into a machine it rented itself. No dashboard, nobody approving each step. If you'd rather drive it from plain HTTP, the same endpoints exist over REST — &lt;a href="https://dev.to/blog/mcp-vs-rest-for-ai-agents"&gt;MCP or REST, your call&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest part: what's automated, what isn't
&lt;/h2&gt;

&lt;p&gt;Ordering is fully autonomous. Funding the balance isn't — not yet. Right now someone puts crypto on the balance once (USDC/USDT, or a card on-ramp), and from that point the agent orders, scales and cancels on its own, spending only what's there.&lt;/p&gt;

&lt;p&gt;The end state everyone pictures — an agent paying on-chain, per request, with no pre-funding — is the &lt;a href="https://www.x402.org" rel="noopener noreferrer"&gt;x402&lt;/a&gt; style, and we think it's where this goes. We haven't wired it up. It needs USDC-settled rails and a few things we don't run today, so rather than slap "fully autonomous payments" on the box, here's the truth: &lt;strong&gt;autonomous ordering now, autonomous funding later.&lt;/strong&gt; The prepaid balance is the bridge, and honestly it doubles as a spend cap you probably want anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  A couple of real details
&lt;/h2&gt;

&lt;p&gt;The MCP server speaks &lt;strong&gt;Streamable HTTP&lt;/strong&gt; at &lt;code&gt;https://mcp.eqvps.com/mcp&lt;/code&gt;, so it drops into any MCP client without a local shim. Auth is a Bearer token the agent mints itself with &lt;code&gt;register_account&lt;/code&gt; — the same token works across MCP and REST, against the same account and balance. Sessions are tracked server-side, so a long-running agent can hold one connection and keep calling tools.&lt;/p&gt;

&lt;p&gt;One practical note from running this: treat the token and the returned root password like the secrets they are. The agent should store them, not echo them into logs or chat. The balance caps the financial blast radius; basic secret hygiene caps the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;For now most of our actual customers are humans who happen to like paying in crypto — we're not going to pretend the web is overrun with autonomous agents buying servers. But the direction is clear. As agents take on longer, real tasks, "can it get and run its own infrastructure?" stops being a party trick and becomes a requirement. When that day fully arrives, the rails need to already be there.&lt;/p&gt;

&lt;p&gt;They are. Add the MCP server to your agent — start with &lt;a href="https://dev.to/blog/connect-eqvps-mcp-client"&gt;connecting an MCP client&lt;/a&gt; — fund a small balance, and let it rent its first server. About a minute to root.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can an AI agent really buy a server on its own?
&lt;/h3&gt;

&lt;p&gt;Yes — the ordering part is fully autonomous. Over our MCP server the agent calls register_account to get a token, then order_vps, which spends from a prepaid balance and provisions the VPS. It reads back SSH access from get_vps_status. No human clicks through a checkout. The one thing a human (or a funded agent wallet) does first is put crypto on the balance; after that the agent runs on its own.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the agent pay?
&lt;/h3&gt;

&lt;p&gt;From a prepaid balance. You fund it once with USDC or USDT (or a card via the on-ramp), and order_vps debits that balance per order. The agent never holds your wallet keys, and it can't spend more than what's on the balance — which is also your safety cap.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is MCP provisioning?
&lt;/h3&gt;

&lt;p&gt;MCP (Model Context Protocol) lets an agent call tools directly inside clients like Claude, Cursor or Cline. 'MCP provisioning' just means the whole rent-a-server flow — register, pay, order, get root — is exposed as MCP tools the agent calls itself, instead of a web dashboard a person clicks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this fully hands-off?
&lt;/h3&gt;

&lt;p&gt;Ordering is. Funding isn't quite there yet: today someone tops up the balance with crypto, and then the agent is autonomous. Fully on-chain per-request payment (the x402 style) is on our radar but not wired up — we'd rather say that plainly than pretend.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does the agent need to get started?
&lt;/h3&gt;

&lt;p&gt;Just the MCP server URL (&lt;a href="https://mcp.eqvps.com/mcp" rel="noopener noreferrer"&gt;https://mcp.eqvps.com/mcp&lt;/a&gt;) added to its client. It calls register_account and gets a Bearer token in the response — no email confirmation, no human step. From there every action is a tool call.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://eqvps.com/en/blog/ai-agent-buys-own-server-mcp" rel="noopener noreferrer"&gt;eqvps.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>vps</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
