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:
- Gateway Identity Propagation: The B2B API Gateway validates the tenant's mTLS certificate and Bearer token, extracting the
tenant_idand claims, which are injected into signed downstream headers. - 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.
- 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
- 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. - 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.
- 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 |
Related Services from Betadrix
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
Explore Categories
Browse More Technical Topics & Industry Guides
?Frequently Asked Questions
What is the difference between Model Context Protocol (MCP) and traditional REST APIs?
How do you secure MCP servers in a multi-tenant cloud environment?
Can MCP servers stream data back to the LLM agent?
What happens if an LLM tool call times out?
How does Envoy load balance long-lived MCP Server-Sent Events (SSE) connections?
Can an MCP server connect to local LLMs hosted on vLLM or Ollama?

Shivam Sharma
Lead Cloud Solutions ArchitectShivam Sharma is an AWS Certified Solutions Architect specializing in cloud infrastructure, high-availability microservices, and database performance tuning for scalable web clients.
Build Your Custom Project
Connect with technical architects for scope and estimation.
More Articles in Technology
Related services built to solve your specific challenges
Watch.
Learn.
Grow.
Discover how our engineered solutions transform industries and propel client operations forward.

Owning the Game, Not Renting It: Custom Crash Game Development for a Lahore-Based iGaming Operator
READ CASE STUDYTechnologies & Frameworks Powering This Service
Model Context Protocol (MCP) Development | Enterprise AI Agent Infrastructure | Betadrix
ai
Hire Specialized Developers For Your Service Project

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

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

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

Python Developers
Pre-vetted senior Python Developers ready to deploy into your existing architecture in 3-7 days.
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
Director of Operations, HealthFirst Clinics
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.
Request Free Technical Consultation
Let's build something serious.
Diagnose your system architecture, budget ranges, and roadmap parameters with an expert.
Scoping Diagnostic
Analyze your workflows in 60 seconds. A senior AI architect reviews every parameter personally.
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








