← Back to the AI Series
Standard Co · Monthly AI Series

How to Build Your Own MCP

Adding an MCP server on top of an API you already have
September 17, 2026

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.

Slides from this session

How to Build Your Own MCPHow to Build Your Own MCPHow to Build Your Own MCP

Frequently asked questions

Why build an MCP server if you already have an API?

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.

Does an MCP server need its own database?

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.

How do you keep an MCP server read-only?

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.

How do users sign in to an MCP server?

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.

What's the hardest part of building an MCP server?

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.

Want to sit in on a session?

We run these every month. Email me and I'll add you to the invite.

Email TJ