Building Custom MCP Servers: A Production-Ready Guide
Learn how to build, secure, and deploy custom Model Context Protocol servers for your organization's internal systems with TypeScript, including authentication, monitoring, and Kubernetes deployment.
Abstract
The Model Context Protocol (MCP) has rapidly become the standard for AI integration across major providers. While pre-built servers work well for common services like GitHub or Slack, organizations need custom servers to integrate internal APIs, enforce security policies, and encode domain-specific logic. This guide walks through building a production-ready custom MCP server using TypeScript, from initial setup to Kubernetes deployment, with working code examples for authentication, circuit breakers, audit logging, and monitoring.
The Custom Integration Challenge
Organizations adopting AI-assisted workflows quickly hit limitations with pre-built MCP servers. Your team uses proprietary internal APIs, custom databases, and legacy systems that lack public MCP servers. Generic servers can't encode your validation rules, security requirements, or compliance needs.
Consider an internal deployment system. The workflow requires checking prerequisites from a custom configuration service, validating user permissions via LDAP, triggering deployments through an internal API with circuit breakers, logging all actions for compliance, and handling multi-region coordination. No pre-built server understands this workflow.
Building custom MCP servers enables tailored integration, security enforcement at the protocol level, optimized responses that maximize context window efficiency, and compliance integration with audit systems.
Project Structure and Setup
Start with a well-organized project structure that separates concerns:
Initialize the project with required dependencies:
Configure TypeScript for modern Node.js:
Core Server Implementation
The server initialization handles transport setup, tool registration, and graceful shutdown:
Key patterns here: modular tool registration keeps the codebase maintainable, proper error handling prevents silent failures, and using console.error() for logging is critical: stdout is reserved for protocol messages, and any other output corrupts the JSON-RPC stream.
Implementing Tools with Domain Logic
Tools encode your organization's business rules. Here's a comprehensive example that validates deployment prerequisites:
This demonstrates several domain logic patterns: semantic version validation using Zod regex, multi-step prerequisite checks with clear pass/fail feedback, environment-specific rules like deployment windows for production, dependency health validation, and human-readable output optimized for AI consumption.
API Integration with Resilience
Robust integration with internal APIs requires retries, circuit breaking, and proper error handling:
This implementation includes circuit breakers preventing cascading failures, exponential backoff with jitter, token caching to reduce auth overhead, user-friendly error transformation, and timeout protection. I learned the importance of circuit breakers during a backend outage that took down the MCP server for 20 minutes before these patterns were implemented.
Security: Authentication and Audit Logging
Security cannot be bolted on later. Design authentication, authorization, and audit logging from the start:
HTTP Transport for Production
While stdio transport works for local development, production deployments need HTTP transport for multiple concurrent clients, independent server lifecycle, load balancing, and standard monitoring:
Kubernetes Deployment
Container deployment with Kubernetes provides high availability and scalability:
Kubernetes manifest for production deployment:
Testing Strategy
Test MCP tools effectively with unit tests that mock external dependencies:
Common Pitfalls and Lessons Learned
Stdout/Stderr Confusion
MCP uses stdout exclusively for JSON-RPC messages. Any other output corrupts the protocol stream:
If your client shows "Protocol error" or "Invalid JSON", check for stdout pollution.
Missing Input Validation
AI models can generate unexpected or malicious inputs. Use Zod refinements for strict validation:
Context Window Bloat
Every token consumes context window. AI can invoke tools dozens of times per conversation. Return only relevant fields:
This approach reduced token usage by approximately 70% in testing.
Synchronous Long Operations
Tools should return within 5-10 seconds. For longer operations, use a task-based pattern:
Cost Analysis
Development: 1-2 weeks for production-ready server (server development 3-5 days, security 1-2 days, testing 1 day, deployment 1-2 days, documentation 1 day).
Infrastructure (AWS example):
- Kubernetes: ~50, EC2 instances 20, secrets/logs $25)
- Serverless (Fargate): ~$50/month (lower cost, higher cold start latency)
When to build custom: Internal/proprietary systems, strict security/compliance requirements, domain-specific validation needed, context optimization critical, high integration volume.
When to use pre-built: Standard integrations (GitHub, Slack), quick prototyping, low security requirements, limited development resources.
Key Takeaways
Start simple with stdio transport and basic tools, then add security and production features incrementally. Design authentication, authorization, and audit logging from the start. Retrofitting security is painful.
Optimize every response. Return only relevant fields to maximize context window efficiency. Use Zod for strict input validation and validate backend responses. Don't trust AI-generated inputs or backend APIs.
Circuit breakers are essential for preventing cascading failures when backends become unhealthy. Build small, focused tools that are reusable and testable, letting AI orchestrate complex workflows through tool composition.
Production requires observability: metrics, logging, and alerting are not optional. Test in production-like environments using the same code with different configurations to catch issues before production.
MCP server development takes 1-2 weeks compared to 2-3 weeks for custom REST APIs. The standardization pays off through multi-provider support and growing ecosystem.
References
- typescriptlang.org - TypeScript Handbook and language reference.
- github.com - TypeScript project wiki (FAQ and design notes).
- spec.modelcontextprotocol.io - Model Context Protocol (MCP) specification.
- nodejs.org - Node.js official documentation.
- oauth.net - OAuth 2.0 community overview and links.
- kubernetes.io - Kubernetes documentation.
- 12factor.net - The Twelve-Factor App methodology.
- owasp.org - OWASP Top 10 (common web application risks).
- developer.mozilla.org - MDN Web Docs (web platform reference).
- semver.org - Semantic Versioning specification.