Как сделать свой MCP-сервер: пошагово
Собственный MCP-сервер нужен, когда агенту надо работать с вашей системой: внутренним API, базой, CRM. Ниже — минимальный рабочий сервер на TypeScript и на Python, проверка, подключение к клиенту и правила, по которым модель будет правильно пользоваться вашими инструментами.
Что будет делать сервер
Сделаем сервер с одним инструментом get_forecast: он принимает город и возвращает прогноз. Вместо заглушки вы подставите вызов своего API. Сервер будет работать по транспорту stdio — клиент запускает его как процесс на вашем компьютере. Это самый простой вариант для начала.
Вариант 1: TypeScript
Нужен Node.js 18 или новее. Создайте проект и установите официальный SDK:
mkdir weather-mcp && cd weather-mcp
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/sdk zodФайл server.js:
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: 'weather', version: '1.0.0' });
server.registerTool('get_forecast', {
title: 'Прогноз погоды',
description: 'Возвращает прогноз погоды на завтра для указанного города.',
inputSchema: { city: z.string().describe('Название города, например «Казань»') },
annotations: { readOnlyHint: true },
}, async ({ city }) => ({
// Здесь вызов вашего API.
content: [{ type: 'text', text: `В городе ${city} завтра +18 °C и солнечно.` }],
}));
await server.connect(new StdioServerTransport());Важно: в stdio-сервере нельзя писать в стандартный вывод (console.log) — он занят протоколом. Для отладки используйте console.error.
Вариант 2: Python и FastMCP
Установите официальный пакет:
pip install "mcp[cli]"Файл server.py:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
@mcp.tool()
def get_forecast(city: str) -> str:
"""Возвращает прогноз погоды на завтра для указанного города."""
# Здесь вызов вашего API.
return f"В городе {city} завтра +18 °C и солнечно."
if __name__ == "__main__":
mcp.run()FastMCP берёт описание инструмента из docstring, а схему параметров — из аннотаций типов.
Проверка в MCP Inspector
Перед подключением к агенту проверьте сервер в официальном инспекторе — он показывает инструменты и позволяет вызвать их вручную:
npx @modelcontextprotocol/inspector node server.js
# или для Python:
npx @modelcontextprotocol/inspector python server.pyПодключение к Claude Code и Cursor
Claude Code:
claude mcp add weather -- node /полный/путь/weather-mcp/server.jsCursor — в ~/.cursor/mcp.json:
{
"mcpServers": {
"weather": {
"command": "node",
"args": [
"/полный/путь/weather-mcp/server.js"
]
}
}
}Спросите агента «какая погода завтра в Казани?» — он вызовет ваш инструмент.
Как писать инструменты, которыми модель пользуется правильно
- Описание — для модели. Пишите, что делает инструмент и когда его вызывать, а не как он устроен внутри.
- Узкие инструменты. Лучше
create_cardиmove_card, чем одинmanage_card(action, …). - Описывайте каждый параметр. Формат дат, допустимые значения, где взять идентификатор.
- Ошибки — понятным текстом. «Колонка не найдена, вызовите get_board» помогает агенту исправиться.
- Аннотации.
readOnlyHintиdestructiveHintподсказывают клиенту, какие вызовы безопасны. - Небольшие ответы. Возвращайте нужные поля, а не весь объект из базы: контекст модели не бесконечен.
Удалённый сервер: Streamable HTTP
Чтобы сервер был доступен из Claude.ai, ChatGPT и с любого компьютера, его размещают в интернете с транспортом Streamable HTTP. В Python достаточно указать транспорт:
mcp.run(transport="streamable-http")В TypeScript SDK для этого есть StreamableHTTPServerTransport. Удалённому серверу обязательна авторизация: ключи доступа или OAuth 2.1 — без неё любой, кто знает адрес, получит ваши инструменты.
Если ваша задача — дать агенту доску задач и заметки, свой сервер писать не нужно: облачный MCP MCP Kanbanуже работает по адресу https://mcpkanban.ru/mcp, с OAuth, ключами «только чтение» и журналом действий агента.
Вопросы и ответы
На каком языке лучше писать MCP-сервер?
Официальные SDK есть для TypeScript, Python, Java, Kotlin, C#, Go, Ruby и других языков. Берите тот, на котором написана система, к которой подключаетесь.
Чем инструменты отличаются от ресурсов?
Инструмент (tool) — действие, которое модель вызывает сама: создать, найти, изменить. Ресурс (resource) — данные, которые клиент может приложить к контексту, например файл. Большинству серверов хватает инструментов.