Jonathan Nesbitt walked through how we put MCP servers on top of two production Rails apps, ESPEN (WHO AFRO neglected-tropical-disease data) and NTDeliver (WHO NTD medicine delivery tracking), without writing a line of new data access.
The starting point is a plain question: why build an MCP if you already have an API? Because the API works fine and most people still can't use it. With an MCP, getting a number is two steps — paste a URL and sign in, then ask — in the tool they already have open all day.
We covered what the server actually is (a thin, read-only adapter between chat and your existing API, with no database connection and no second permission model), what a basic codebase looks like (nine files), and two ways to handle per-user sign-in: let Azure AD or Google issue tokens, or add OAuth to your Rails app with Doorkeeper. We also covered the part we got wrong twice — the translation layer that encodes your API's assumptions goes stale when the API changes upstream.
The whole pattern is now packaged as a reusable skill in our claude-standards repo: /mcp-server create and /mcp-server audit.
Because most people can't use an API. Getting one number out of it means finding the docs, getting a credential, working out the endpoint, parsing JSON, and pasting it into a spreadsheet. With an MCP server they paste a URL, sign in, and ask — inside the AI tool they already use. The server can also hand back the exact API call that produced an answer, so it's an on-ramp to the API rather than a replacement.
No. Ours have no database connection at all. Every answer comes back through the API you already expose, and your API keeps enforcing exactly the permissions it enforced before.
Route all outbound traffic through a single client with a single get() method, and add a test that fails if a write ever appears. Read-only becomes something you can enforce in code, not just a promise.
Two options. Let an identity provider such as Azure AD or Google issue tokens, with the MCP server only validating them — but expect the provider to require a verified domain, which can mean waiting on DNS changes. Or, for a Rails app, add the Doorkeeper gem alongside Devise so your app becomes its own OAuth provider. Either way the MCP server just validates a token.
Not the MCP part — the SDK code is about forty lines. The real work is writing down everything your API assumes its callers already know: which filters actually apply, what paginates, how errors read, and when results are truncated. That layer also goes stale whenever the upstream API changes, so it needs re-auditing when the API moves.
We run these every month. Email me and I'll add you to the invite.
Email TJ