Build a working custom MCP server that connects Claude to a real API. Learn the security model that keeps your credentials and data safe. Understand where MCP and agentic AI are heading — and how to stay ahead of it.
When to build a custom MCP server
The 200+ community MCP servers cover the major tools. You need a custom server when:
- You use an internal tool that has no public MCP server
- You have a private API that Claude should be able to call
- You need Claude to interact with a system in a very specific, controlled way
- You want to expose internal company data to Claude without it leaving your network
Custom MCP servers are small Node.js programs. You don't need to be a senior engineer. If you can write basic JavaScript, you can build one in under an hour.
Build a custom MCP server from scratch
We'll build a server that gives Claude access to a simple REST API — in this case, a weather API and a custom note-taking function. This template works for any API.
Step 1: Initialize the project
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
Step 2: Create the server file
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import fs from 'fs';
// Create the MCP server
const server = new Server(
{ name: 'my-tools', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
// Define available tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'save_note',
description: 'Save a note to a local file for later reference',
inputSchema: {
type: 'object',
properties: {
title: { type: 'string', description: 'Note title' },
content: { type: 'string', description: 'Note content' }
},
required: ['title', 'content']
}
},
{
name: 'get_weather',
description: 'Get current weather for a city',
inputSchema: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name' }
},
required: ['city']
}
}
]
}));
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === 'save_note') {
const filename = `./notes/${args.title.replace(/\s+/g,'-')}.md`;
fs.mkdirSync('./notes', { recursive: true });
fs.writeFileSync(filename, `# ${args.title}\n\n${args.content}`);
return { content: [{ type: 'text', text: `Saved note to ${filename}` }] };
}
if (name === 'get_weather') {
// Replace with your actual weather API key + endpoint
const apiKey = process.env.WEATHER_API_KEY;
const url = `https://api.openweathermap.org/data/2.5/weather?q=${args.city}&appid=${apiKey}&units=imperial`;
const res = await fetch(url);
const data = await res.json();
const summary = `${data.name}: ${data.main.temp}°F, ${data.weather[0].description}`;
return { content: [{ type: 'text', text: summary }] };
}
throw new Error(`Unknown tool: ${name}`);
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
Step 3: Update package.json for ES modules
{
"name": "my-mcp-server",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
Step 4: Register with Claude Desktop
{
"mcpServers": {
"my-tools": {
"command": "node",
"args": ["/absolute/path/to/my-mcp-server/index.js"],
"env": {
"WEATHER_API_KEY": "your_api_key_here"
}
}
}
}
Restart Claude Desktop. You'll now see your custom tools in the tool list. Ask Claude: "Save a note titled 'Meeting Notes' with the content 'Discussed Q2 roadmap.'" Claude will call your save_note tool and create the file.
Security: what to know before you connect anything
MCP servers run with your user permissions. A malicious MCP server could read, write, or delete files, make network requests, or exfiltrate data. Only install servers from sources you trust. Treat MCP servers like browser extensions.
- Filesystem access: Only grant access to specific directories, never your whole home folder
- API keys: Store in environment variables, never hardcode in scripts that get committed to git
- Network access: Know what external endpoints your MCP servers call
- Community servers: Check the GitHub repo, look at the source code before installing
- Work credentials: Be especially careful with servers that access work systems — check your company's AI policy first
For a home or personal development environment, the official Anthropic-maintained servers are safe. For corporate environments, discuss with your IT/security team before deploying MCP servers that access internal systems.
The future: agentic desktop AI
MCP is 6 months old as of early 2026. The ecosystem is expanding fast:
- Computer use: Claude can already control a computer — clicking, typing, navigating. Expect this to integrate more tightly with Desktop.
- Long-running agents: Background tasks that run for hours, check in with you, and complete complex multi-step work autonomously.
- Multi-agent coordination: Claude Desktop routing tasks to specialized sub-agents — one for research, one for writing, one for code review.
- Memory: Persistent knowledge that accumulates across sessions without you having to re-explain context.
The people who learn MCP now will have a significant advantage as these capabilities arrive. The concepts are the same: tools, context, agent loops. The scope just gets bigger.
You've completed the course.
You can now install Claude Desktop, build Projects with custom instructions, install and configure MCP servers, run advanced workflows, and build your own MCP server from scratch. That's more than most people with months of Claude experience.
Take the Live Bootcamp — $1,490