Problem: You Don't Know Where to Start
Too Many Options, No Clear Path
Cutting through the noise to set up your first MCP server
You have decided to build an MCP server. But when you look at the documentation, you are immediately faced with choices: TypeScript or Python? stdio or HTTP? What SDK version? What project structure? It is easy to get lost before writing a single line of code.
Let us cut through the noise and get you set up in the simplest way possible.
Choosing Your Language
| Feature | TypeScript | Python |
|---|---|---|
| SDK Package | @modelcontextprotocol/sdk | mcp[cli] |
| Best for | Web APIs, Node.js ecosystems | Data processing, scripting, Odoo |
| Type safety | Zod schemas (excellent) | Type hints + Pydantic |
| Quick start | npx @anthropic-ai/create-mcp | uvx create-mcp-server |
Our Recommendation
If you are connecting to web APIs or building something from scratch, use TypeScript. If you are working with data, scripts, or Odoo (like in the VaryShop ecosystem), use Python.
TypeScript Setup
# Create project directory mkdir my-mcp-server cd my-mcp-server # Initialize project npm init -y npm install @modelcontextprotocol/sdk zod npm install -D typescript @types/node # Create tsconfig.json npx tsc --init --target ES2022 --module Node16 \ --moduleResolution Node16 --outDir dist
Now create your server file src/index.ts:
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-first-server",
version: "1.0.0",
});
server.tool(
"greet",
"Greet a person by name",
{ name: z.string().describe("The person's name") },
async ({ name }) => ({
content: [{ type: "text", text: `Hello, ${name}!` }],
})
);
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main();Just 20 Lines
That is it — 20 lines of code for a working MCP server. It registers one tool called greet that takes a name and returns a greeting.
Python Setup
# Create project mkdir my-mcp-server cd my-mcp-server # Set up with uv (recommended) uv init uv add "mcp[cli]" httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-first-server")
@mcp.tool()
def greet(name: str) -> str:
"""Greet a person by name."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run()Even More Concise
Python FastMCP is just 12 lines. The decorator @mcp.tool() automatically converts the function signature and docstring into a tool definition.
Transport: stdio vs Streamable HTTP
stdio (Standard I/O)
The server runs as a local process. Input/output goes through stdin/stdout. Simplest and most common transport for local development.
Streamable HTTP
The server runs as a web service. Communication over HTTP with server-sent events. Use this for remote or shared servers.
Start Simple
Start with stdio. It is simpler, requires no network setup, and is what Claude Code uses by default. You can always add HTTP later.
Your First Test
# TypeScript npx @modelcontextprotocol/inspector node dist/index.js # Python mcp dev server.py
The inspector opens a web UI where you can see your registered tools, call them manually, and verify they work correctly.
Key Takeaway
Setting up an MCP server is surprisingly simple. In 20 lines of TypeScript or 12 lines of Python, you have a working server with a registered tool. The hard part is not the setup — it is deciding what tools to build. We will tackle that next.
There are no comments for now.