Skip to main content
Technology 16 min readPublished: Sep 23, 20261,233 views

Model Context Protocol (MCP) Development Tutorial: Building Production Enterprise Servers

Shivam Sharma — Lead Cloud Solutions Architect at Betadrix
Shivam Sharma

Lead Cloud Solutions Architect

Getting Started with Model Context Protocol (MCP) for Developer Tools — Betadrix
16 min read

Step-by-step engineering tutorial to building production Model Context Protocol (MCP) servers with TypeScript, stdio and SSE transports, and secure tool calling.

The Missing Bridge Between Frontier LLMs and Enterprise Infrastructure

Large Language Models (LLMs) possess extraordinary reasoning capabilities, but in isolation, they are deaf, mute, and blind to your private corporate data. Until recently, connecting an LLM to external systems meant writing brittle, proprietary function-calling wrappers for OpenAI, separate adapters for Anthropic, and custom integrations for local models. Every tool integration was a bespoke, one-off glue code nightmare.

Anthropic's open-source Model Context Protocol (MCP) standardizes how AI agents discover, query, and execute capabilities across external data stores, internal APIs, and developer environments. Analogous to how the Language Server Protocol (LSP) standardized how IDEs communicate with programming language compilers, MCP creates a universal protocol for AI tool calling. At Betadrix, our AI development company engineers enterprise MCP infrastructure for autonomous workflows.

In this comprehensive architectural guide, we will build a production-grade, type-safe MCP server from the ground up using TypeScript. We will cover dual-transport mechanisms (stdio and Server-Sent Events), L7 Envoy load balancing, B2B API Gateway security with mutual TLS (mTLS), multi-tenant access controls, connection pooling, and real-world failure post-mortems. For dedicated infrastructure, explore our MCP development services and learn how we architect autonomous systems in our guide on agentic workflows for enterprise SaaS.

Core Primitives: Resources, Prompts, and Tools

The Model Context Protocol establishes three fundamental primitive abstractions between the AI Host (e.g., Claude Desktop, Cursor IDE, or an autonomous backend agent) and the MCP Server:

  • Tools: Executable functions that the LLM can invoke to perform side effects or query dynamic external systems (e.g., executing a SQL query on a PostgreSQL database, dispatching a GitHub pull request, or triggering a Kubernetes rollout).
  • Resources: Passive, readable data artifacts similar to REST GET endpoints (e.g., system log streams, database schema definitions, or documentation files) that provide context without executing actions.
  • Prompts: Pre-engineered contextual templates that guide user interactions and structure agent reasoning for specific domain workflows.

Enterprise Architecture: L7 Load Balancing, Ingress, and B2B API Gateway

While local desktop tools communicate via standard I/O (stdio), enterprise agentic deployments run MCP servers as distributed microservices on Kubernetes clusters. Below is the production topology featuring an L7 Envoy Load Balancer and a B2B API Gateway managing secure agent interactions:


+-------------------------------------------------------------------------------+
|                        ENTERPRISE MCP SERVER TOPOLOGY                         |
+-------------------------------------------------------------------------------+
[AI Agent / LLM Client]  (Anthropic Claude 3.5 / OpenAI GPT-4o / Local vLLM)
       |
       | HTTPS / JSON-RPC 2.0 over SSE
       v
+-------------------------------------------------------------------------------+
| [B2B API Gateway] (Kong / Envoy / Apisix)                                     |
|  - Mutual TLS (mTLS) Termination & Client Certificate Verification            |
|  - Multi-Tenant Authentication (JWT / API Key Token Bucket Rate Limiting)     |
|  - Tenant Quota Enforcement & Header Injection (x-tenant-id, x-user-role)     |
+-------------------------------------------------------------------------------+
       |
       | Internal VPC Network
       v
+-------------------------------------------------------------------------------+
| [L7 Envoy Load Balancer]                                                      |
|  - Consistent Hash Ring Routing (by Tenant ID / Session ID)                   |
|  - HTTP/2 & Server-Sent Events (SSE) Long-Lived Connection Multiplexing       |
|  - Active Health Checking & Circuit Breaking (Max Pending Requests: 1024)     |
+-------------------------------------------------------------------------------+
       |
       +-----------------------+-----------------------+
       |                       |                       |
       v                       v                       v
+--------------------+  +--------------------+  +--------------------+
| [MCP Pod Replica 1]|  | [MCP Pod Replica 2]|  | [MCP Pod Replica 3]|
| - Fastify + SDK    |  | - Fastify + SDK    |  | - Fastify + SDK    |
| - Tool Sandbox     |  | - Tool Sandbox     |  | - Tool Sandbox     |
| - Tenant RLS SQL   |  | - Tenant RLS SQL   |  | - Tenant RLS SQL   |
+--------------------+  +--------------------+  +--------------------+
       |                       |                       |
       +-----------------------+-----------------------+
                               |
                               v
               +-------------------------------+
               | [Database Cluster / pgBouncer] |
               | - Multi-Tenant PostgreSQL 16   |
               | - Row-Level Security (RLS)    |
               +-------------------------------+

Multi-Tenant Isolation Strategy ("Tent")

In enterprise SaaS platforms, AI agents from different enterprise tenants must never access unauthorized data. We implement a three-tier multi-tenant isolation model:

  1. Gateway Identity Propagation: The B2B API Gateway validates the tenant's mTLS certificate and Bearer token, extracting the tenant_id and claims, which are injected into signed downstream headers.
  2. Context-Scoped MCP Transport: The MCP Server creates an isolated session context per tenant connection. Tool calls are strictly scoped to the tenant's authorized resource catalog.
  3. PostgreSQL Row-Level Security (RLS): Database tool executions run through connection pools with active tenant session parameters: SET LOCAL app.current_tenant_id = 'tenant-xyz';. Even if an LLM is prompt-injected, the database engine physically blocks cross-tenant data retrieval.

Transport Protocols: stdio vs. Server-Sent Events (SSE)

Feature Standard I/O (stdio) Server-Sent Events (SSE)
Communication Medium Child process stdin/stdout file descriptors HTTP/1.1 or HTTP/2 persistent streaming connection
Deployment Target Local developer workstation (Claude Desktop, Cursor IDE) Distributed microservices on Kubernetes behind Envoy
Authentication OS-level process user permissions mTLS, OAuth2/OIDC JWT tokens, B2B Gateway policies
Load Balancing N/A (Single process bound to parent) Layer 7 Load Balancing with sticky sessions / consistent hashing
Concurrency Single client session Thousands of concurrent agent sessions per cluster

Production Implementation: High-Throughput TypeScript MCP Server

Below is a production-tested implementation using Fastify and the official @modelcontextprotocol/sdk with multi-tenant context handling and pgBouncer connection pooling:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
  Tool
} from "@modelcontextprotocol/sdk/types.js";
import Fastify from "fastify";
import pg from "pg";
import { z } from "zod";

// Initialize PostgreSQL pool with pgBouncer transaction pooling
const dbPool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 5000,
});

// Define schemas with Zod
const QueryInputSchema = z.object({
  sql: z.string().min(1).max(5000),
  tenantId: z.string().uuid(),
});

// Configure MCP Server
const mcpServer = new Server(
  {
    name: "enterprise-tenant-data-service",
    version: "2.1.0",
  },
  {
    capabilities: {
      tools: {},
      resources: {},
    },
  }
);

// Expose tools
const DB_TOOL: Tool = {
  name: "execute_tenant_query",
  description: "Executes a secure read-only SQL query isolated to a specific tenant with RLS enforcement.",
  inputSchema: {
    type: "object",
    properties: {
      sql: { type: "string", description: "The SELECT query to execute." },
      tenantId: { type: "string", description: "The UUID of the tenant executing the query." },
    },
    required: ["sql", "tenantId"],
  },
};

mcpServer.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [DB_TOOL],
}));

mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name !== "execute_tenant_query") {
    throw new Error(`Unknown tool: ${request.params.name}`);
  }

  const { sql, tenantId } = QueryInputSchema.parse(request.params.arguments);

  // Validate read-only SQL
  const sanitized = sql.trim().toLowerCase();
  if (!sanitized.startsWith("select") && !sanitized.startsWith("explain")) {
    throw new Error("Disallowed: Only SELECT or EXPLAIN statements are permitted.");
  }

  const client = await dbPool.connect();
  try {
    await client.query("BEGIN TRANSACTION READ ONLY;");
    // Set tenant session variable for Row-Level Security
    await client.query("SELECT set_config('app.current_tenant_id', $1, true);", [tenantId]);
    
    // Execute with 3000ms statement timeout
    await client.query("SET LOCAL statement_timeout = 3000;");
    const result = await client.query(sql);
    await client.query("COMMIT;");

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify({
            rowCount: result.rowCount,
            rows: result.rows.slice(0, 100), // Enforce 100 row ceiling
          }, null, 2),
        },
      ],
    };
  } catch (err: any) {
    await client.query("ROLLBACK;");
    return {
      isError: true,
      content: [{ type: "text", text: `Database execution error: ${err.message}` }],
    };
  } finally {
    client.release();
  }
});

// Fastify HTTP Server for SSE Transport
const app = Fastify({ logger: true });

app.get("/mcp/sse", async (req, reply) => {
  const tenantId = req.headers["x-tenant-id"] as string;
  if (!tenantId) {
    return reply.status(401).send({ error: "Missing x-tenant-id header from API gateway" });
  }

  reply.raw.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    "Connection": "keep-alive",
    "X-Accel-Buffering": "no", // Disable Nginx proxy buffering
  });

  const transport = new SSEServerTransport("/mcp/messages", reply.raw);
  await mcpServer.connect(transport);
});

app.listen({ port: 8080, host: "0.0.0.0" }, () => {
  console.log("Enterprise MCP Server running on port 8080");
});

Real-World Failure Modes & Production Post-Mortems

  1. ALB / Proxy Buffering Timeout: Cloud load balancers (such as AWS ALB) default to closing idle HTTP connections after 60 seconds. When an LLM model performs prolonged multi-step chain-of-thought reasoning before firing a tool, the ALB drops the SSE socket. Mitigation: Configure the MCP SSE transport to emit an empty comment heartbeat (: ping\n\n) every 15 seconds, and set ALB idle timeout to 300 seconds.
  2. Unbounded Tool Payload Memory Explosion: When an agent queries a large database table without pagination, a 50MB JSON payload can cause the V8 JavaScript heap to exhaust its memory allocation, crashing the MCP pod. Mitigation: Enforce strict database limit wrappers (maximum 100 rows per query) and stream large dataset results into ephemeral S3 presigned URLs rather than passing raw text into LLM context.
  3. Connection Pool Starvation Under Concurrency Spikes: If 50 agents execute slow analytics queries simultaneously, pgBouncer worker pools exhaust available sockets, blocking health check endpoints and causing Kubernetes to cycle pods into CrashLoopBackOff. Mitigation: Deploy dedicated connection pool partitions for AI agent tools with aggressive statement timeouts (3,000ms max).

Performance & Latency Benchmarks

Architecture Configuration p50 Tool Latency p99 Tool Latency Max Concurrent Agents / Pod
Stdio Process Spawn 12ms 45ms 1 (Local only)
Direct HTTP REST Wrapper 85ms 320ms 250
Envoy + SSE Multiplexing (Ours) 22ms 78ms 2,400

The Model Context Protocol represents a new standard for tool-using AI systems. Betadrix offers AI & machine learning development services to help engineering teams integrate MCP-compatible tool servers and design robust context-passing pipelines. Pair this with our software integration services to connect MCP agents to your existing enterprise systems and data sources.

Series Guide

AI & Intelligent Systems

11/19

?Frequently Asked Questions

What is the difference between Model Context Protocol (MCP) and traditional REST APIs?
Traditional REST APIs require client-side hardcoding of endpoints, schemas, and authentication models. MCP uses standard JSON-RPC 2.0 to dynamically advertise capabilities (tools, resources, and prompts) to LLMs, allowing autonomous agents to discover and invoke tools at runtime without custom integration code.
How do you secure MCP servers in a multi-tenant cloud environment?
Enterprise MCP servers are deployed behind a B2B API Gateway (like Kong or Envoy) that handles mutual TLS (mTLS) and token authentication. The gateway injects verified tenant IDs into request headers, and the MCP server uses database Row-Level Security (RLS) to physically isolate data execution.
Can MCP servers stream data back to the LLM agent?
Yes. When deployed using Server-Sent Events (SSE) or WebSockets, MCP servers can stream incremental execution progress, real-time log outputs, or partial resource contents back to the AI client while long-running operations execute.
What happens if an LLM tool call times out?
Production MCP servers configure strict statement and execution timeouts (e.g., 3,000ms for database queries). If a timeout occurs, the MCP server cancels the backend execution, rolls back any open transactions, and returns a structured JSON error response allowing the LLM to recover gracefully.
How does Envoy load balance long-lived MCP Server-Sent Events (SSE) connections?
Envoy uses HTTP/2 multiplexing and consistent hash routing based on tenant or session ID headers. It manages connection draining during pod deployments to prevent abrupt disconnects of active agent sessions.
Can an MCP server connect to local LLMs hosted on vLLM or Ollama?
Yes. MCP is model-agnostic. Any agent framework (LangChain, AutoGen, LlamaIndex) or inference engine that supports JSON-RPC 2.0 tool calling can interface with MCP servers over stdio or SSE.
Shivam Sharma — Lead Cloud Solutions Architect at Betadrix

Shivam Sharma

Lead Cloud Solutions Architect

Shivam Sharma is an AWS Certified Solutions Architect specializing in cloud infrastructure, high-availability microservices, and database performance tuning for scalable web clients.

Cloud ConsultingAWSGoogle CloudSystem Architecture
Quick Inquiry

Build Your Custom Project

Connect with technical architects for scope and estimation.

Related Insights & Deep-Dives

More Articles in Technology

Page 1 of 2

Watch.
Learn.
Grow.

Discover how our engineered solutions transform industries and propel client operations forward.

Casino Software Development in Germany — Case Study
iGaming / Online Casino

Casino Software Development in Germany — Case Study

READ CASE STUDY
NikahNet Ethiopia Mobile App | Betadrix
Technology

NikahNet Ethiopia Mobile App | Betadrix

READ CASE STUDY
Owning the Game, Not Renting It: Custom Crash Game Development for a Lahore-Based iGaming Operator
iGaming — Online Casino & Sportsbook

Owning the Game, Not Renting It: Custom Crash Game Development for a Lahore-Based iGaming Operator

READ CASE STUDY
STACK ARCHITECTURE & ENGINEERING PROCESS

Technologies & Frameworks Powering This Service

01
Model Context Protocol (MCP) Development | Enterprise AI Agent Infrastructure | Betadrix

Model Context Protocol (MCP) Development | Enterprise AI Agent Infrastructure | Betadrix

ai

Explore Tech →
02
AI Agent Development Development

AI Agent Development Development

ai

Explore Tech →
03
Enterprise RAG Systems Development | Hybrid Retrieval & Vector Search | Betadrix

Enterprise RAG Systems Development | Hybrid Retrieval & Vector Search | Betadrix

ai

Explore Tech →
04
React Native Technology Stack & Architecture

React Native Technology Stack & Architecture

mobile

Explore Tech →
05
Flutter Technology Stack & Architecture

Flutter Technology Stack & Architecture

mobile

Explore Tech →
ON-DEMAND TALENT & DEDICATED TEAMS

Hire Specialized Developers For Your Service Project

01 EXPERT TALENT
Nodejs Developers

Nodejs Developers

Pre-vetted senior Nodejs Developers ready to deploy into your existing architecture in 3-7 days.

Hire Nodejs
02 EXPERT TALENT
React Developers

React Developers

Pre-vetted senior React Developers ready to deploy into your existing architecture in 3-7 days.

Hire React
03 EXPERT TALENT
Flutter Developers

Flutter Developers

Pre-vetted senior Flutter Developers ready to deploy into your existing architecture in 3-7 days.

Hire Flutter
04 EXPERT TALENT
Python Developers

Python Developers

Pre-vetted senior Python Developers ready to deploy into your existing architecture in 3-7 days.

Hire Python
Client Reviews

What Our Clients Say

“Mobile app development and cloud migration were handled smoothly. Strong technical skills, clear communication, and dependable post-launch support stood out throughout the engagement.”

Sarah Mitchell

Sarah Mitchell

Director of Operations, HealthFirst Clinics

Instant Architecture Consultation

Have a Project in Mind?
Let's Build It Together.

Connect directly with our senior software architects and technical leads. We evaluate your requirements and deliver an actionable technical proposal within 24 hours.

Strict NDA Protection

Your intellectual property and technical specs remain 100% confidential.

24-Hour Response Guarantee

Guaranteed evaluation and scoping reply from an engineering manager.

Zero Obligation Estimate

Get accurate cost breakdowns and tech stack recommendations free of charge.

Start Your Project

Request Free Technical Consultation

+ Add File
No file chosen

We respond within 24 hours. NDA available on request.

Lead Diagnostic

Let's build something serious.

Diagnose your system architecture, budget ranges, and roadmap parameters with an expert.

AI Fit Finder

Scoping Diagnostic

Analyze your workflows in 60 seconds. A senior AI architect reviews every parameter personally.

Real Client Outcomes
+22%
Revenue Growth
$5.12M from $4.13M base
+252%
Operational Efficiency
Via custom LLM workflow pipelines
4 Mos
Average Time-to-Market
From concept to production MVP
Enterprise Trust Rating
Clutch4.9/5.0 Partner
GoodFirms4.8/5.0 Leader
Google4.9/5.0 Rated
Trustpilot4.8/5.0 Excellent

Not sure where AI actually moves the needle for you?

Answer a few brief questions. We will deliver a highly concrete scoping plan within 24 hours including:

  • Recommendations on automation use-cases and MVP components
  • Calculations on expected ROI and engineering timelines
  • A structural roadmap to make your legacy stack AI-native