# Building an MCP Server from Scratch: A Practical Developer Guide

> Step-by-step guide to building a Model Context Protocol server with real tools, authentication, and production deployment — using the official TypeScript SDK.

URL: https://www.matthewswong.com/en/blog/mcp-server-development-guide/

- Author: Matthews Wong (https://www.matthewswong.com/en/about/)
- Published: 2025-06-10
- Updated: 2026-10-17
- Category: AI

Model Context Protocol (MCP) is Anthropic's open standard for connecting AI models to external tools and data sources. Think of it as a USB-C standard for AI integrations — instead of every AI assistant implementing its own custom plugin system, MCP gives you one protocol that any compliant client (Claude Desktop, Cursor, Continue, and others) can speak. Building MCP servers for internal tools, and exposing ERP data to Claude through a proper MCP server, can bring a significant productivity gain. This guide covers the full lifecycle: server setup, tool definition, authentication, error handling, and deployment.

## MCP Architecture: How It Works

MCP defines a client-server protocol over stdio or HTTP/SSE. The AI model (client) discovers available tools and resources from your MCP server, then calls those tools during conversations. Your server handles tool execution and returns results. The protocol is JSON-RPC 2.0 based, stateful (the client maintains a session with the server), and supports three primitives: Tools (executable functions), Resources (readable data), and Prompts (reusable prompt templates). For most use cases, you will primarily implement Tools — these are what enable Claude to take actions in your systems.

### Setting Up the TypeScript MCP Server SDK

Anthropic provides official SDKs for TypeScript and Python. The TypeScript SDK is the most mature and what I use in production. Install with npm install @modelcontextprotocol/sdk. The SDK handles protocol negotiation, session management, and serialization. You focus on defining your tools and implementing their handlers. The server can run as a standalone process communicating over stdio (for Claude Desktop integration) or as an HTTP server with SSE for remote deployments.

> From my experience building MCP servers for ERP integrations: define your tool schemas strictly using Zod validation. The AI model relies on your JSON Schema descriptions to understand what parameters to pass. Vague descriptions lead to incorrect tool calls. Write descriptions as if explaining to a smart junior developer who has never seen your system — be specific about data formats, required fields, and expected value ranges.

## Building Your First MCP Tool

A complete MCP server with a real tool that queries an ERP database. This example implements a tool to look up invoice status — a common ERP integration use case that demonstrates authentication, database queries, and structured response formatting.

### Tool Definition and Handler Pattern

Each tool needs a name, description, input schema (JSON Schema), and a handler function. The handler receives validated inputs and returns a content array. Return structured data as JSON strings inside a text content block — this gives the AI model machine-readable data while maintaining protocol compatibility. Always include error handling: return error content rather than throwing exceptions so the model can understand what went wrong and communicate it to the user.

> **Security Warning**

> MCP servers running locally via stdio have access to your full user account permissions. A malicious MCP server (or a legitimate server that gets compromised through indirect prompt injection) can read files, execute commands, and make network requests as your user. Always review MCP server code before installing it. For production remote MCP servers, implement authentication (OAuth 2.0 is the MCP spec recommendation), enforce HTTPS, and apply the principle of least privilege — the server should only have access to the specific resources its tools need.

## Authentication and Authorization

Remote MCP servers must implement authentication. The MCP spec recommends OAuth 2.0 with PKCE for client authentication. For internal tools, a simpler approach is bearer token authentication validated per request. I implement a middleware layer that extracts the Authorization header, validates the token against our user database, and attaches user context to the request before tool handlers execute. This ensures tool calls are scoped to the authenticated user's permissions — critical for ERP data where different users can see different records.

## Deployment and Production Considerations

For Claude Desktop integration, your MCP server runs as a local stdio process — configure it in claude_desktop_config.json. For team or multi-client deployments, run your server as an HTTP+SSE endpoint behind nginx with TLS. Use PM2 or systemd for process management. Implement health checks, structured logging with request IDs, and rate limiting per authenticated user. Monitor tool call latency — if a tool consistently takes more than 5 seconds, the user experience degrades significantly. Cache expensive lookups (database queries, API calls) with appropriate TTLs.

## What I Actually Ship

A production MCP server for an ERP might expose tools for: querying sales orders and invoices, checking inventory levels, running approval status queries, and generating report summaries. It can run behind an nginx reverse proxy with Let's Encrypt TLS, authenticated via JWT tokens tied to employee accounts. The biggest productivity win is Claude being able to answer specific ERP questions without employees needing to navigate the UI — a query like 'what invoices are overdue for client X' that takes several clicks in the UI can be answered in one conversation turn.

## Sources & Further Reading

- Anthropic — Model Context Protocol Specification — https://modelcontextprotocol.io/docs
- Anthropic — MCP TypeScript SDK — https://github.com/modelcontextprotocol/typescript-sdk
- Anthropic — Tool Use Documentation — https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview

## Source links

- https://modelcontextprotocol.io/docs
- https://github.com/modelcontextprotocol/typescript-sdk
- https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview

## FAQ

### What transport options does MCP support, and when should you choose each one?

MCP supports two transports: stdio and HTTP/SSE. Stdio is used for local Claude Desktop integrations where the server runs as a subprocess on the user's machine. HTTP/SSE is the right choice for team or multi-client deployments — you run the server as a remote endpoint behind nginx with TLS so multiple users can connect.

### Why does the post recommend using Zod for tool schema validation?

The AI model relies entirely on your JSON Schema descriptions to decide which parameters to pass when calling a tool. Vague or loose schemas lead to incorrect tool calls. Strict Zod validation ensures the server enforces the exact shape it expects, and the post advises writing descriptions as if explaining to a smart junior developer who has never seen your system.

### What authentication approach does the post recommend for remote MCP servers?

The MCP specification recommends OAuth 2.0 with PKCE for client authentication on remote servers. For internal tooling a simpler bearer token approach is practical: a middleware layer extracts the Authorization header, validates the token against the user database, and attaches user context before any tool handler executes — scoping every tool call to the authenticated user's permissions.

### What security risks should developers know before running an MCP server locally?

A local MCP server running over stdio inherits the full permissions of the user account — it can read files, execute commands, and make network requests. A malicious server, or a legitimate server compromised through indirect prompt injection, can abuse those permissions silently. The post advises always reviewing MCP server code before installation and, for production remote servers, enforcing HTTPS and applying the principle of least privilege.

### What productivity gain can an MCP server bring to an ERP?

An MCP server can expose tools for querying sales orders, invoices, inventory levels, approval statuses, and report summaries. A query such as finding overdue invoices for a specific client, which normally requires several clicks of UI navigation, can resolve in a single conversation turn. The size of the gain depends on how much of your team's time currently goes to navigating the ERP UI.

---

- HTML version: https://www.matthewswong.com/en/blog/mcp-server-development-guide/
- Bahasa Indonesia: https://www.matthewswong.com/id/blog/mcp-server-development-guide/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
