Building an MCP Server Inside Your Rails App
A hands-on guide to exposing your Rails app's data and actions to AI assistants with the official Ruby MCP SDK: tools, authentication, Streamable HTTP and testing.
All of my thoughts on programming, product design, and more, collected in chronological order.
A hands-on guide to exposing your Rails app's data and actions to AI assistants with the official Ruby MCP SDK: tools, authentication, Streamable HTTP and testing.
A Rubyist's guide to uv, the fast Python tool that covers what Bundler, rbenv and gem-installed CLIs do in Ruby, with direct command mappings and a working Flask setup.
Anyone hiring one engineer has the same question and almost nobody asks it: what happens after he leaves? This is the honest answer. The two hosts, the checks that run on them, the tool I built to close the two gaps nothing else covered, and what 'supported after launch' actually means when one person is on the hook.
Buyers of AI built software all ask the same question: who checks it? This is my honest answer, using Interlock, the approval gate I am building for my own automated work, as the worked example. Not may I run this, yes or no, but here is a draft, fix the second paragraph, ship what I edited.
Retries, idempotency keys, and dead letters as an evidence problem, how to build Rails webhook delivery that survives a HIPAA audit, not just a happy-path integration test.
Hospital networks that allow nothing in, devices in the field you cannot brick, conformance requirements you cannot negotiate, and stakeholders who need it in plain English. What engineering discipline looks like when the environment sets the rules. From a clinical alerting platform used by NHS trusts and a fielded detection product.
If you run production at an event agency, you know the shape of this problem. The client has bought an interactive idea for their stand. A touchscreen, a photo experience, some kind of engagement measurement. You have sold it, you have a date, and...
"Fixed scope, fixed price" sounds like a line from a brochure until you watch one run from start to finish. So here is one. Last September I built EventScope for Johnson & Johnson Medical: an engagement analytics platform that ran across their...
Most writing about LLMs in Rails apps stops at architecture: RAG, MCP, "AI as a multiplier." The part that actually bites is smaller and more concrete: a model takes eight seconds to answer, and HTTP gives you one response. You either stare at a s...
Our default stack answers most frontend questions with "server-rendered HTML and Tailwind." That works right up until a client asks for two things in the same sprint: a dashboard that updates itself while people are looking at it, and an app in th...
Finishing the Redis Eviction: Solid Cache and Solid Cable in Production If you followed the Kamal runbook off Heroku and replaced Sidekiq with Solid Queue, there's a good chance you're still paying for a Redis instance that now does almost nothing...
You didn't leave Heroku because it was bad. You left because a two-dyno app with a Standard-0 database and a Redis add-on crossed some threshold where the invoice stopped looking like infrastructure and started looking like a subscription. Rails 8...
A pattern I've fallen into across more client codebases than I'd like to admit: write a feature, push the branch, switch to something else, get pinged ten minutes later that CI failed on a typo or a missing migration. Fix it. Push again. Wait. Rep...
A familiar scene from fractional work: you've been brought in on a Rails app that's been around for six or seven years. The team is small, the test suite is patchy in the older corners, and somewhere in app/models/user.rb there's a has_many :legac...
Rails 8.1 shipped on 22 October 2025, and Rails 8.1.3, released on 24 March 2026, is the current stable release as of writing (April 2026). After a few months of using Active Job Continuations on a couple of client projects, I want to write down w...
Managing secrets well is a common hallmark of production grade Rails applications. Get it wrong and you're one misplaced commit away from exposing API keys, database passwords, or encryption tokens. Get it right and your team can deploy confidentl...
Ruby 4.0 landed in December 2025. Rails 8.1.3 followed in March 2026. If you're running a production Rails application and haven't looked closely at either release yet, this post is for you. Not a feature dump — a practical take on what matters, w...
On February 6, 2026, Heroku announced it is transitioning to a "sustaining engineering model," focused on stability, security, reliability, and support, rather than introducing new features. Heroku describes itself as remaining "actively supported...
Rails has supported TailwindCSS via the --css tailwind flag since Rails 7, but it's with Rails 8 that the pairing has really hit its stride. By the time Rails 8.1.2 arrived in January 2026, the combination had become - in my experience at least - ...
You need Rails expertise. You don't necessarily need another full time engineer If your Rails application needs attention, whether it's an overdue upgrade, a performance bottleneck, or a critical feature that's been sitting in your backlog, the in...
Background job processing is the backbone of any serious Rails application. Whether you're sending emails, processing payments, generating reports, or handling webhooks, the choice of background job system directly affects reliability, performance...
A few months ago, I was debugging a memory issue in a Sidekiq worker that processed CSV exports. The job was straightforward: iterate through a few hundred thousand records, transform them, and write to a file. Memory usage should have been stable...
Part 1 of a series on making the transition from Ruby on Rails to Flask If you've spent years in the warm embrace of Rails—where convention rules, generators abound, and rails new gives you everything but the kitchen sink, stepping into Flask can ...
Spam is a frustrating reality - fake registrations, bot comments, bogus form submissions - but there's no one-size-fits-all fix. Let’s walk through spam control options from the most lightweight and free to more comprehensive paid services, with a ...
While building EstateSync, I created many tables of varying complexity and length, but they still shared a lot of common patterns. Maintaining a consistent UI became increasingly challenging as I was using Tailwind, and I noticed that view code wa...
When working on multiple local projects, each running on different ports, it becomes inconvenient to remember port numbers and manually update /etc/hosts for every new project. Our goal was to make development feel like production — where each pro...
As a senior software engineer primarily working in Ruby but with experience across Go, Node.js, and Python, I’m always evaluating tools and frameworks that promise to make our systems smarter, faster, or more adaptive. Recently, two acronyms from ...
Every production-grade Rails project should proactively address security and code quality. The Ruby ecosystem offers a rich collection of gems that help you do just that - catching bugs early, enforcing best practices, and protecting your users an...
While working on a Rails app recently, I stumbled across a frustrating bug that only appeared in the test environment. Everything worked perfectly in the development console. Models loaded fine. Associations were intact. My concern methods behaved...
Alberto Fortin’s recent post on dialing back LLM usage resonated with me. Like many developers, I’ve found AI to be both a productivity godsend and a source of friction. It can feel like magic — until it quietly leads you down the wrong path. Here...
As a software developer, I have had the opportunity to work in various organizations, each with its own approach to team communication and collaboration. Through these experiences, I have come to realize the significant impact that regular one-to-...
When developing applications using Rails, efficient database interaction is crucial for maintaining high performance. ActiveRecord provides several methods to optimize database queries. In this post, we’ll explore how using specific ActiveRecord m...
If you've ever encountered a situation where your Rails model associations work perfectly in the console but mysteriously fail in your test suite, you're not alone. I recently ran into this exact issue and wanted to share the solution along with s...
Series: The Effective Engineer by Edmond Lau Welcome to the final post in my series on The Effective Engineer by Edmond Lau. So far, we’ve explored how to prioritise effectively, leverage tools, iterate quickly, and measure what matters. Now, let’...
Series: The Effective Engineer by Edmond Lau Welcome back to my series on The Effective Engineer by Edmond Lau. So far, we’ve covered how to prioritize high-impact work, leverage tools, and iterate quickly. Now it’s time to talk about something th...
Series: The Effective Engineer — by Edmond Lau Welcome back to my series on The Effective Engineer by Edmond Lau. In the last post, we explored how leveraging tools and automation can multiply your productivity. Today, we’ll look at another essent...
In today's fast-paced and competitive world, organizations are increasingly realizing the importance of teamwork and collaboration. While assembling a team with diverse skills and expertise is crucial, it is equally important to create an environm...
Series: The Effective Engineer — by Edmond Lau Welcome back to my series on The Effective Engineer by Edmond Lau. In previous posts, we discussed the importance of focusing on high impact work through prioritisation. Today, we’ll explore another k...
Dotfiles are configuration files for applications and shell environments, often prefixed with a dot (.), making them hidden by default. Managing these files across different systems can be challenging. GNU Stow helps by creating symbolic links fro...
Series: The Effective Engineer — by Edmond Lau In software engineering, there’s always more to do than time allows. From bug fixes to features, code reviews to meetings, the to-do list never ends. That’s why prioritisation is one of the most valua...
Welcome to my series on “The Effective Engineer” by Edmond Lau. If you’re a software engineer aiming to make a meaningful impact in your career, I believe this book is a must-read. Over the next few weeks, I’ll delve deep into the core principles ...
Introduction The term "Senior Engineer" is often used in the tech industry, but what does it really mean? What separates a Senior Engineer from a Junior or Mid-Level Engineer? In this post, we'll explore the key characteristics that define a Senio...
Sorting Algorithms Bubble Sort Bubble sort is one of the simplest sorting algorithms. It works by repeatedly stepping through the list, comparing each pair of adjacent items and swapping them if they are in the wrong order. This process continues ...
Merge Sort in Ruby Merge sort is one of the fundamental sorting algorithms used in computer science. It belongs to the divide and conquer category of algorithms, where a problem is divided into smaller sub-problems that are solved recursively. In ...