Atonom
Web Developer at a 30-person AI-agent startup. I own the infrastructure and deployment for three products, I build the internal tools our marketing team runs on, and I built the MCP server that puts our CRM inside Claude.
Claude, connected to our CRM
The thing I am proudest of here is a remote MCP server that lets a sales rep ask Claude about our CRM in plain language and get a real answer from live data. Reps add it to their own Claude account, which means inference runs on their subscription and costs the company nothing.
The interesting part is not the tools. It is that a connector like this is a bearer of someone's CRM access, so it had to be built like one.
- Self-hosted OAuth 2.1. PKCE required, dynamic client registration, and a consent screen that names the client before any grant.
- Authorization on every call. Not just at login, so revoking access takes effect immediately rather than whenever a token expires.
- Read-only, metadata only. The connector can see that an email happened, never what it said. Bodies and transcripts are blocked at the query layer, not by asking the model nicely.
Infrastructure and deployment
I own the code, the pull requests, and the deployment for three products, across Netlify, Render, Supabase, and Cloudflare. Nobody reviews my work, which is the reason a lot of what follows exists.
- The marketing site. Migrated from a Vite SPA to Next.js 15 on the App Router, and I own its infrastructure and database.
- The CRM. It started life on a no-code AI builder. I moved it onto our own deployment, squashed 279 auto-generated migrations into a single readable baseline, removed roughly 52,000 lines of dead code, and hardened access control.
- The email orchestration service. Greenfield, mine from the first commit. Node/TypeScript on Postgres, deployed as two processes on Render against Supabase.
Internal tools
Most of what I build is internal tooling for our marketing team. I sit on that team as its engineer rather than as a marketer, and over time these have grown into one internal workspace behind login, with around nine tools in it.
- An analytics dashboard. Site traffic, acquisition, conversions, forms, CTAs, and funnels in one place, with a natural-language mode where every number in the model's answer is checked against a separately computed set of facts before it returns.
- A/B testing. Compares button and CTA variants by click rate per arm, with lift and significance.
- UTM and short-link governance. One source of truth for campaign tracking links and attribution, so links stay consistent instead of hand-built.
- Outreach and data enrichment. Tooling to prepare and launch email campaigns across sender mailboxes, and to pull, enrich, and export contact batches from our data providers.
- Admin surfaces. Content, catalog, and event management, including a CMS for the public site, so non-engineers can make updates without me in the loop.
- A from-scratch backend service. Node/TypeScript on Postgres: 18 tables, 15 job queues with tuned retry and expiry, 9 scheduled jobs, and 50 endpoints.
What I would do differently
In May I moved a hardcoded analytics ID into an environment variable. Good change, correct code, and it silently stopped all data collection for thirty-one days, because an empty string is falsy and the gate returned quietly. Nothing threw. The site looked perfect.
I did not fix it by setting the variable. I moved the conversions that matter to the server, where no client-side toggle can kill them, and added a capture-gap metric that goes red when the client and server counts diverge. You cannot alert on an absence, but you can alert on a ratio.