How to Build MCP Servers with mcp-builder
Purpose
I wanted to build an MCP server to connect my AI assistant to a custom data source. But I kept wondering: what’s the right way to structure it? Which framework should I use? How do I make it work across different AI tools?
This post shows how I approached MCP server development using the mcp-builder skill.
What is MCP?
MCP (Model Context Protocol) solves a real problem in AI development: integration fragmentation.
Before MCP, if I wanted my AI assistant to access my database, I needed:
- One integration for Claude
- Another for Cursor
- Yet another for Copilot
Each AI tool had its own plugin system. Different APIs. Different patterns.
MCP creates a universal plugin layer:
+------------------+ +------------------+ +------------------+| MCP Host | | MCP Server | | External || (Claude Code) | --stdio | (Your Plugin) | ------> | System || | or | | | (API, DB) || MCP Client | HTTP | Tools | | |+------------------+ +------------------+ +------------------+Write once, use everywhere. Any MCP-compatible AI tool can use your server.
Core Capabilities
MCP servers provide three things:
| Capability | What It Does | Example |
|---|---|---|
| Tools | Functions the AI can call | query_database, send_email |
| Resources | Data the AI can read | File contents, database records |
| Prompts | Predefined templates | Common workflows, query patterns |
The mcp-builder Skill
I found out about mcp-builder from Anthropic’s skills repository. It’s an Agent Skill that guides you through the entire MCP server development cycle.
Installation
npx skills add anthropics/skills --skill mcp-builderOnce installed, my coding assistant gained expertise in MCP patterns. It knows:
- How to structure tool definitions
- Best practices for error messages
- Transport options and when to use each
- Testing with MCP Inspector
The Four-Phase Cycle
mcp-builder follows a structured approach:
Phase 1: Research and Planning
I started by defining what my server should do:
- What external system am I connecting to?
- What tools does the AI need?
- What data should be exposed as resources?
Phase 2: Implementation
Two framework options:
| Framework | Language | Best For |
|---|---|---|
| MCP SDK | TypeScript | Full control, OAuth support |
| FastMCP | TypeScript/Python | Rapid development, less boilerplate |
Phase 3: Review and Testing
Use MCP Inspector to validate your server works correctly.
Phase 4: Evaluation Creation
Create tests for tool correctness and document usage patterns.
Choosing a Framework
I tried both frameworks to understand the differences.
FastMCP Approach
FastMCP offers a simpler API with less code:
import { FastMCP } from "fastmcp";import { z } from "zod";
const server = new FastMCP({ name: "my-server", version: "1.0.0"});
server.addTool({ name: "add", description: "Add two numbers", parameters: z.object({ a: z.number(), b: z.number() }), execute: async ({ a, b }) => String(a + b),});
server.start({ transportType: "httpStream", httpStream: { port: 3000 }});Clean and straightforward. I liked how the tool definition is self-contained.
MCP SDK Approach
The official SDK gives more control:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";import { z } from "zod";
const server = new McpServer({ name: "my-server", version: "1.0.0"});
server.tool("add", { a: z.number(), b: z.number()}, async ({ a, b }) => ({ content: [{ type: "text", text: String(a + b) }],}));The SDK is better when you need OAuth or want to integrate with Express.js.
Transport Types: stdio vs HTTP
I had to decide between two transport options:
| Feature | stdio | HTTP |
|---|---|---|
| Use case | Local clients | Remote access, cloud |
| Protocol | stdin/stdout | HTTP/SSE |
| OAuth | No | Yes |
| Docker | No | Yes |
When I Use stdio
- Personal development on my laptop
- Claude Desktop integration
- Data that shouldn’t leave my machine
When I Use HTTP
- Sharing with my team
- Cloud deployment
- Need authentication
Quick Start with create-mcp-server
Instead of starting from scratch, I used the create-mcp-server scaffolding tool:
# Interactive modenpx @agentailor/create-mcp-server
# Or specify options directlynpx @agentailor/create-mcp-server --name=my-server --stdioThis generated a complete project structure:
my-mcp-server/+-- src/| +-- server.ts # MCP server (tools, prompts, resources)| +-- index.ts # Express app and transport setup| +-- auth.ts # OAuth middleware (if enabled)+-- Dockerfile # Production-ready Docker build+-- package.json+-- tsconfig.json+-- .gitignore+-- .env.example+-- README.mdThe generated project includes everything I needed:
- TypeScript configuration
- Docker support
- Development scripts
- MCP Inspector integration
Configuration
For Local Use
I added my server to ~/.claude.json:
{ "mcpServers": { "my-server": { "command": "node", "args": ["/path/to/my-server/dist/index.js"], "env": { "API_KEY": "${API_KEY}" } } }}For Remote Deployment
For HTTP servers, I configured the URL:
{ "mcpServers": { "my-remote-server": { "url": "https://my-server.example.com/mcp", "headers": { "Authorization": "Bearer ${API_KEY}" } } }}Best Practices I Learned
1. Write Clear Tool Descriptions
The AI reads your descriptions to decide which tool to use. Make them specific:
// Good: Clear, specific, actionableserver.addTool({ name: "search_docs", description: "Search documentation for a specific term. Returns matching sections with context.", // ...});
// Bad: Vague, unhelpfulserver.addTool({ name: "search", description: "Searches things", // ...});2. Provide Actionable Error Messages
When something fails, tell the user what to do:
// Good: Tells user what to dothrow new Error("API key not found. Set the API_KEY environment variable or pass it in the config.");
// Bad: Cryptic errorthrow new Error("Auth failed");3. Validate All Inputs
Use Zod schemas to validate parameters:
server.addTool({ name: "query_database", description: "Execute a SQL query on the database", parameters: z.object({ query: z.string().min(1).max(1000), limit: z.number().min(1).max(100).default(10), }), // ...});4. Never Hardcode Secrets
Always use environment variables:
{ "env": { "API_KEY": "${API_KEY}" }}Testing with MCP Inspector
The generated project includes an inspect script:
npm run inspectThis opens MCP Inspector in my browser. I can:
- See all tools, resources, and prompts
- Test each tool interactively
- View request/response logs
- Debug errors
A Complete Example
Here’s a weather server I built:
import { FastMCP } from "fastmcp";import { z } from "zod";
const server = new FastMCP({ name: "weather-server", version: "1.0.0"});
server.addTool({ name: "get_weather", description: "Get current weather for a city", parameters: z.object({ city: z.string().describe("City name"), units: z.enum(["celsius", "fahrenheit"]).default("celsius"), }), execute: async ({ city, units }) => { const response = await fetchWeatherData(city, units); return JSON.stringify(response); },});
server.addResource({ uri: "weather://cities", name: "Supported Cities", mimeType: "application/json", async load() { return { text: JSON.stringify(["San Francisco", "New York", "London"]), }; },});
server.start({ transportType: "httpStream", httpStream: { port: 3000 }});Summary
In this post, I showed how to build MCP servers using mcp-builder. The key takeaways:
- MCP solves fragmentation: Write integrations once, use across any MCP-compatible AI tool
- mcp-builder guides development: Install with
npx skills add anthropics/skills --skill mcp-builder - Two framework options: FastMCP for simplicity, MCP SDK for full control
- Two transport types: stdio for local, HTTP for remote
- Use scaffolding:
npx @agentailor/create-mcp-servergenerates production-ready projects
The combination of mcp-builder (knowledge) and create-mcp-server (scaffolding) gave me everything I needed to build MCP servers that work across Claude Code, Cursor, and any other MCP-compatible tool.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Model Context Protocol Official Docs
- 👨💻 anthropics/skills GitHub Repository
- 👨💻 create-mcp-server Scaffolding Tool
- 👨💻 FastMCP GitHub Repository
- 👨💻 MCP TypeScript SDK
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments