---
title: "TypeScript skeleton, an MCP server in 40 lines — StudioMeyer Academy"
description: "Minimal code. Not the best architecture, but the clearest entry point."
canonical: "https://studiomeyer.academy/en/lernwege/fuer-entwickler/lektionen/02-typescript-skeleton"
language: en
image: "https://studiomeyer.academy/og/academy-og-share.png"
publisher: "StudioMeyer Academy, https://studiomeyer.academy (llms.txt: https://studiomeyer.academy/llms.txt)"
---

## What you install

```bash
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/node
```

- `@modelcontextprotocol/sdk` is the official Anthropic library.
- `zod` is for input validation (mandatory, not optional).
- `tsx` lets you run TypeScript directly without a build step.

## The minimal server

File `src/index.ts`:

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

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

const EchoSchema = z.object({
  message: z.string(),
});

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "echo",
      description: "Returns the passed message.",
      inputSchema: {
        type: "object",
        properties: { message: { type: "string" } },
        required: ["message"],
      },
    },
  ],
}));

server.setRequestHandler(CallToolRequestSchema, async (req) => {
  if (req.params.name === "echo") {
    const { message } = EchoSchema.parse(req.params.arguments);
    return { content: [{ type: "text", text: `Echo: ${message}` }] };
  }
  throw new Error(`Unknown tool: ${req.params.name}`);
});

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

That's it. 30 lines of code, a fully functional MCP server.

## What the code does

1. Imports the SDK.
2. Creates a server with name + version.
3. Tells the client: "I have a tool called `echo`."
4. When the client calls `echo`, validates input with Zod and returns an echo.
5. Connects via stdin/stdout to the client.

That's the basis. Every MCP server follows this pattern, no matter how complex it gets.

## Testing

In `package.json` add this script:

```json
"scripts": { "dev": "tsx src/index.ts" }
```

Then configure Claude Code:

```bash
claude mcp add my-server -s user -- npx -y tsx /path/to/project/src/index.ts
```

Restart Claude Code, type `/mcp`, you should see "my-server". Type:

> Use my-server's echo tool with the message "Hello"

Claude calls `echo`, returns "Echo: Hello".

## The two beginner traps

**1\. console.log as debug.** Doesn't work for stdio servers. console.log lands on stdout, the client reads that as a protocol message, the server crashes. Instead: use `console.error(...)`, that goes to stderr and doesn't interfere.

**2\. Missing input validation.** If the client sends something wrong and you don't validate, your server crashes. The agent sees the crash as "Tool failed", does weird things. Always Zod schemas. Always.

## What's missing now

This is the skeleton. For a real server you need:

- More tools (instead of `echo`, something useful)
- External API calls (with error handling, retry, rate limit)
- Auth if needed (API keys, OAuth)
- Tests
- Logging
- Deployment (npm publish or Docker)

That's coming in the next lessons. The skeleton is the body, not the sprint.

## Next lesson

Tool design. How you write good tools that the model uses correctly. That's the difference between "my server exists" and "my server gets used".

You can read everything freely. An account keeps your progress saved.

[Sign in](https://studiomeyer.academy/en/login?next=%2Fen%2Flernwege%2Ffuer-entwickler%2Flektionen%2F02-typescript-skeleton)

For developers · Module 1 of 1

## For developers

[Back to learning path](https://studiomeyer.academy/en/lernwege/fuer-entwickler)

## Your notes

Sign in to save your own notes for this lesson.

[Sign in](https://studiomeyer.academy/en/login?next=%2Fen%2Flernwege%2Ffuer-entwickler%2Flektionen%2F02-typescript-skeleton)

## Sitemap

Public pages of this site as Markdown: [sitemap](https://studiomeyer.academy/sitemap.md). Curated entry point: [llms.txt](https://studiomeyer.academy/llms.txt), full text: [llms-full.txt](https://studiomeyer.academy/llms-full.txt).
