Skip to content
Tech News
← Back to articles

Show HN: I put an AI agent on a $7/month VPS with IRC as its transport layer

read original get AI Chatbot Development Kit → more articles
Why This Matters

This project demonstrates a cost-effective and secure way to deploy an AI-powered digital assistant that provides detailed, code-backed answers about a developer's work, moving beyond generic resume rephrasing. It highlights how tailored infrastructure and open protocols like IRC can enhance transparency and security in AI integrations for the tech industry and consumers.

Key Takeaways

← home

building a digital doorman I put an AI agent on a $7/month VPS, connected it to my own IRC server, and pointed it at my GitHub repos. Visitors can ask it about my work and get answers backed by actual code, not rephrased resume text.

the problem with "ask my resume" Every portfolio site with an AI chatbot does the same thing: feed the resume into a model and let visitors rephrase it. It's a parlor trick. The model can't tell you anything the resume doesn't already say. I wanted something different. If a hiring manager asks "how does George handle test coverage?" the answer shouldn't be "George values comprehensive testing." It should clone the repo, count the tests, read the CI config, and come back with specifics. So I built the infrastructure to make that work.

the architecture Two agents, two boxes, two security boundaries. visitor (browser) │ └─ georgelarson.me/chat/ │ └─ gamja web IRC client │ └─ wss://nullclaw.georgelarson.me:443 │ └─ Cloudflare (proxy, TLS termination, bot protection) │ └─ ergo IRC server (LarsonNet) │ └─ #lobby │ └─ nully (nullclaw agent) ├── reads public GitHub repos ├── preloaded portfolio context └── routes to ironclaw via #backoffice │ └─ #backoffice (private IRC channel) │ └─ ironclaw (separate box, via Tailscale) ├── email access ├── calendar └── private context nullclaw is the public-facing doorman. It runs on a minimal perimeter box, a 678 KB Zig binary using about 1 MB of RAM. It handles greetings, answers questions about my projects, and can clone repos to substantiate claims with real code. ironclaw is the private agent on a separate, more powerful system. It has access to email, deeper personal context, and handles complex inquiries routed from nullclaw. That boundary is deliberate: the public box has no access to private data.

why IRC I could have used Discord, Telegram, or a custom WebSocket chat. IRC is the right choice for three reasons: It fits the aesthetic. My portfolio site has a terminal UI. An IRC client embedded in it is on-brand. Discord would feel wrong. I own the entire stack. Ergo IRC server, gamja web client, nullclaw agent, all on my infrastructure. No third-party API that changes its terms, no platform that decides to deprecate bot access. It's a 30-year-old protocol. IRC is simple, well-understood, and has zero vendor lock-in. The same agent that talks to visitors via the web client can talk to me via irssi from a terminal.

model selection as a design decision This is where most people reach for the biggest model they can afford. That's the wrong instinct for a doorman. conversational layer: Haiku 4.5 Greetings, triage, simple questions about my background. Sub-second responses. Pennies per conversation. Speed matters more than depth here. tool-use layer: Sonnet 4.6 (fallback) When nully needs to clone a repo, read code, or synthesize findings across files, Sonnet steps in. You pay for reasoning only when reasoning is needed. cost cap: $2/day A public-facing agent without a spending limit is a liability. The cap prevents both runaway conversations and abuse. If someone tries to burn through my inference budget, they hit a wall. the portfolio signal Using Opus for a concierge would signal the opposite of model understanding. If Haiku can handle it, don't send it to Sonnet. Tiered inference (cheap for the hot path, capable for the heavy lifting) is how I keep this under $2/day.

security posture This box is a public-facing perimeter. It should be hardened like one. SSH: Non-root user with key-only auth on a non-standard port. Root login disabled.

Non-root user with key-only auth on a non-standard port. Root login disabled. Firewall: UFW with only three ports open: SSH, IRC (TLS), and HTTPS (WebSocket via Cloudflare).

UFW with only three ports open: SSH, IRC (TLS), and HTTPS (WebSocket via Cloudflare). Cloudflare proxy: Web visitors never hit the box directly. WebSocket traffic goes through CF's edge, which handles TLS termination, rate limiting, and bot filtering.

Web visitors never hit the box directly. WebSocket traffic goes through CF's edge, which handles TLS termination, rate limiting, and bot filtering. Agent sandboxing: nullclaw runs in supervised mode with workspace-only file access, a restricted command allowlist (read-only tools), and 10 actions per hour max.

... continue reading