Reference

What is an MCP server? A practical introduction

The short answer: an MCP server is a small program that exposes your tools, data, or APIs to an AI agent in a structured, typed way. The agent (Claude, GPT-based assistants, Cursor, Continue, etc.) connects to your MCP server, discovers what it can do, and calls those capabilities as part of its reasoning.

This post is the short, plain-English version of what MCP is, what an MCP server actually does, and the design choices that matter when you ship one for your product.

What MCP is and isn't

MCP stands for Model Context Protocol. It is:

  • A standard (originally from Anthropic, now broadly adopted) for how AI agents discover and call external capabilities.
  • A JSON-RPC wire protocol with three primitives: tools (functions the agent can call), resources (data the agent can read), and prompts (templates the agent can use).
  • A client/server architecture: the AI client (Claude Desktop, Cursor, Continue, etc.) connects to one or more MCP servers and asks them what they offer.

It is not:

  • A new LLM. The model is whichever one your client uses; MCP just exposes capabilities to the model.
  • A replacement for a public API. MCP is one consumer surface among many. You can have a REST API and an MCP server in the same product; they expose the same underlying capabilities through different protocols.
  • A finished standard. The spec evolves; new transport and authentication options are appearing regularly.

What an MCP server actually does

An MCP server is a process that responds to JSON-RPC messages over stdio, HTTP, or a streaming transport. At a minimum, it implements:

  • initialize — handshake, capability declaration.
  • tools/list — what functions the server exposes.
  • tools/call — invoke a tool with arguments.

If you want resources or prompts, you implement those endpoints too.

The simplest possible MCP server (in pseudocode):

import { Server } from "@modelcontextprotocol/sdk/server";

const server = new Server({ name: "acme-api", version: "0.1.0" });

server.tool("send_message", "Send an SMS message", {
  number: "string",
  content: "string",
}, async ({ number, content }) => {
  const result = await fetch("https://api.acme.example.com/messages", {
    method: "POST",
    headers: { "X-API-Key": process.env.ACME_API_KEY },
    body: JSON.stringify({ number, content }),
  });
  return result.json();
});

server.connect(/* transport */);

That's it conceptually. The AI agent connects, sees a send_message tool, and can call it like any other function during reasoning.

How MCP relates to your existing API

If you already ship a REST API with OpenAPI 3.x, the MCP surface is largely a translation layer:

  • Each OpenAPI operation becomes an MCP tool.
  • The operation's request schema becomes the tool's argument schema.
  • Auth flows through environment variables or per-tool parameters.
  • Pagination, errors, and rate limits are preserved — the MCP tool just wraps the HTTP call.

This is why teams that maintain a clean OpenAPI spec ship MCP servers cheaply: most of the work is already done.

Design choices that matter

1. Tool granularity

Should you expose every API endpoint as a tool? Probably not. AI agents work better with fewer, higher-level tools than with hundreds of CRUD primitives. A tool named lookup_customer_by_email is more useful than list_customers + get_customer + client-side filtering.

The rule of thumb: each tool should accomplish one thing a user would ask the agent to do. Not one CRUD operation.

2. Argument schemas

The agent uses your argument schemas to plan calls. Keep them descriptive:

  • Name fields after what they mean (recipient_phone_number, not n).
  • Include unit hints in descriptions (amount_cents, "Always in cents, not dollars").
  • Mark required vs optional explicitly.
  • Use enums for closed sets — agents handle enums better than free-form strings.

3. Error semantics

Return structured errors. An agent should be able to distinguish "rate limited, retry later" from "argument was invalid, don't retry."

4. Authentication

Two common patterns:

  • Per-server credentials in env: the server reads the customer's API key from an environment variable. Suitable for self-hosted MCP servers (Claude Desktop runs the server as a child process).
  • Per-call OAuth: the agent passes a token in each call. Suitable for hosted MCP servers where multiple users share the same instance.

The first is simpler and more common today; the second is where the spec is heading for multi-tenant deployments.

5. Streaming and progress

Long-running tools (image generation, batch jobs) should support progress events. The MCP spec includes notifications/progress for this.

Where Bloom fits

Bloom does not generate MCP servers today. SDK generation for TypeScript and Python is the current product. MCP is on the roadmap — the same OpenAPI spec that drives a Bloom-generated SDK will eventually drive a Bloom-generated MCP server.

If you need an MCP server now, the practical options are:

  • Hand-write it using @modelcontextprotocol/sdk for TypeScript or mcp for Python. For an API with <20 operations, this is a day of work.
  • Use Stainless's MCP target if you're already on Stainless. It's the most mature OpenAPI-to-MCP generator today.
  • Use OpenAPI Generator's MCP template if one matches your stack (still emerging).

The OpenAPI work you're doing pays off either way. A clean spec (best practices post) translates cleanly to an MCP server whenever you ship one.

What to do this week

  • If you don't have an MCP server yet, audit your OpenAPI spec for the patterns above — tool-friendly operation names, descriptive argument schemas, structured errors.
  • If you ship a developer-facing product, MCP is increasingly table stakes for AI-integrated workflows. Customers using Claude / Cursor / Continue will look for it.
  • If you're choosing tools, plan for the MCP surface alongside your REST API and SDKs — don't treat it as an afterthought.

The standard is young but already production-shaped. The teams that ship MCP servers early have a real distribution advantage in 2026 as AI-driven integration becomes the default.