MCP (Model Context Protocol) is the mechanism that lets Claude Code connect to external tools. An MCP server exposes functions that Claude can invoke, similar to how an LLM invokes function calls in the OpenAI API, but with a standardized protocol that works with any MCP client.

What an MCP server actually is

An MCP server is a process that exposes a set of tools via a JSON-RPC protocol. Claude Code connects to it at startup and can invoke those tools during the session.

The most useful use cases: connect Claude to your database, expose internal APIs, give it access to services it doesn’t have natively (Slack, Jira, your own CMS).

Initial setup

mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript @types/node ts-node
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "CommonJS",
    "outDir": "dist",
    "strict": true
  }
}

The minimal server

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
  { name: "my-tools", version: "1.0.0" },
  { capabilities: { tools: {} } }
);

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "get_timestamp",
      description: "Returns the current timestamp in ISO format",
      inputSchema: { type: "object", properties: {}, required: [] },
    },
  ],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "get_timestamp") {
    return {
      content: [{ type: "text", text: new Date().toISOString() }],
    };
  }
  throw new Error(`Tool not found: ${request.params.name}`);
});

const transport = new StdioServerTransport();
await server.connect(transport);

Connecting it to Claude Code

In your .claude/settings.json:

{
  "mcpServers": {
    "my-tools": {
      "command": "node",
      "args": ["./dist/index.js"]
    }
  }
}

After npx tsc && claude, Claude Code has access to your get_timestamp tool. From there, add whatever tools you need: database queries, API calls, reading config files.

The MCP SDK handles all the protocol. Your job is just to define the tools and their logic.