DEV Community

ThankGod Chibugwum Obobo
ThankGod Chibugwum Obobo

Posted on Originally published at actocodes.hashnode.dev

Custom MCP Servers Explained: Give Your LLM Access to Private Data & Tools

Large language models are only as useful as the context they can reach. Out of the box, an LLM knows nothing about your internal database, your company's ticketing system, or the CSV file sitting on your laptop. The Model Context Protocol (MCP), an open standard introduced by Anthropic in late 2024 and now governed by the Linux Foundation, solves this by giving models a single, standardized way to connect to external tools and data sources.

In this guide, you'll learn what MCP servers actually do, why they matter, and how to build your own from scratch.

What Is MCP, and Why Should You Care?

Before MCP, connecting an AI model to an external system meant writing a custom integration for every model-tool pairing. Five models and ten data sources meant up to fifty bespoke integrations, the classic "N x M problem."

MCP fixes this with a simple client-server architecture:

  • MCP Clients - AI applications (Claude Desktop, Claude Code, Cursor, VS Code, custom agents) that connect to servers
  • MCP Servers - Lightweight programs that expose specific capabilities, tools, resources, and prompts
  • Transport - Communication over stdio (local processes) or HTTP/SSE (remote servers)

Build one MCP server for your database, and every MCP-compliant client can use it immediately, no per-model rework required.

Core Building Blocks of an MCP Server

Every MCP server is built from three primitives:

  1. Tools - Functions the model can call to take action (e.g., create_ticket, run_query, send_email)
  2. Resources - Data the model can read (e.g., a file, a database record, a document)
  3. Prompts - Reusable, parameterized prompt templates the server exposes to clients

You don't need all three. Most custom servers start with just a handful of tools.

Step-by-Step: Building a Basic MCP Server

Here's a minimal walkthrough using TypeScript, one of the most common languages for MCP development (a Python SDK is equally viable).

1. Set Up Your Project

mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
Enter fullscreen mode Exit fullscreen mode

2. Define the Server

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "my-custom-data-server",
  version: "1.0.0",
});
Enter fullscreen mode Exit fullscreen mode

3. Register a Tool

Tools are the most common way to extend LLM capabilities, they let the model query your data on demand.

server.tool(
  "get_customer_orders",
  "Fetch recent orders for a given customer ID",
  { customerId: z.string() },
  async ({ customerId }) => {
    const orders = await db.query(
      "SELECT * FROM orders WHERE customer_id = ?",
      [customerId]
    );
    return {
      content: [{ type: "text", text: JSON.stringify(orders) }],
    };
  }
);
Enter fullscreen mode Exit fullscreen mode

4. Expose a Resource

Resources let clients read data without necessarily invoking a tool call, useful for static or semi-static content like docs or config.

server.resource(
  "product-catalog",
  "catalog://products",
  async () => ({
    contents: [
      {
        uri: "catalog://products",
        text: await fetchProductCatalog(),
      },
    ],
  })
);
Enter fullscreen mode Exit fullscreen mode

5. Connect the Transport

const transport = new StdioServerTransport();
await server.connect(transport);
Enter fullscreen mode Exit fullscreen mode

That's a working server. Point Claude Desktop, Claude Code, or any compatible client at it, and the model can now call get_customer_orders or read your product catalog directly.

Local vs. Remote Servers

  • stdio (local) - Best for personal tools, local databases, or file access. Simple to build and debug.
  • HTTP/SSE (remote) - Best for team or production use, where multiple users or agents need shared access. Requires handling authentication (typically OAuth) and hosting.

Start local while prototyping, then move to a remote deployment once you need multi-user access or production reliability.

Best Practices for Production-Ready MCP Servers

  • Scope tools narrowly. A tool called run_sql that accepts arbitrary queries is a security liability. Prefer specific, purpose-built tools like get_order_status.
  • Validate inputs strictly. Use schema validation (Zod, Pydantic) on every tool parameter, never trust model-generated input blindly.
  • Return structured, minimal output. Don't dump entire database rows when the model needs three fields. Smaller responses mean lower latency and token cost.
  • Write clear tool descriptions. The model chooses which tool to call based on its description, vague descriptions lead to misuse or missed calls.
  • Handle errors gracefully. Return descriptive error messages the model can reason about and recover from, rather than raw stack traces.
  • Log and rate-limit. Especially for remote servers, track usage and guard against runaway tool-calling loops.
  • Test with a real client. Claude Code and Claude Desktop both support local MCP servers out of the box, making them a fast feedback loop for development.

Common Use Cases for Custom MCP Servers

  • Connecting an LLM to an internal CRM or ticketing system
  • Giving a coding assistant access to your private repositories or documentation
  • Letting an agent query a proprietary database in natural language
  • Exposing internal APIs (billing, inventory, analytics) as callable tools
  • Bridging legacy systems that have no modern API into agentic workflows

Final Thoughts

MCP turns "connect my AI to my data" from a custom engineering project into a standardized, reusable pattern. Once you've built one server, extending it, or building the next one, is dramatically faster. If your team is repeatedly wiring the same data source into different AI tools, a custom MCP server is very likely worth the afternoon it takes to build.

MCP #AIagents #LLM #ClaudeAI #DeveloperTools

Top comments (0)