Усі уроки · 44
Створіть свій перший MCP-сервер
Покроковий MCP-сервер на Python з офіційним SDK: інструменти, ресурси, промпти, транспорт stdio та підключення до клієнта.
Спершу вирішіть, що надавати
MCP-сервер може пропонувати три види можливостей, і цей вибір важливіший за код:
- Інструменти (tools) — дії, які модель сама вирішує викликати: шукати, записувати, надсилати, створювати. Використовуйте їх для всього, що має побічні ефекти або потребує обчислень.
- Ресурси (resources) — дані, які застосунок читає й підставляє в контекст: конфігурації, схеми, документи. Використовуйте їх для довідкових матеріалів.
- Промпти (prompts) — готові шаблони, які постачає сервер; корисні, коли ваша команда має стандартний спосіб щось робити (рев’ю коду, розбір інциденту).
Хороший перший сервер робить одну невелику річ добре. Ми побудуємо сервер нотаток із двома інструментами: зберегти нотатку й показати список нотаток.
«Сервер» тут — не стійка в дата-центрі. Це невелика програма, яка тихо сидить, відповідає на запитання на кшталт «які у вас є інструменти?» та «запустіть цей інструмент із такими аргументами» і віддає відповідь. Ось і все.
Щоб повторювати за уроком, потрібні три речі: Python 3.10 або новіший, термінал і одна команда встановлення.
Скільки зусиль це забере. Код нижче займає близько сорока рядків, і
запустити його можна за десять хвилин. Але на перший сервер усе одно заплануйте
годину. Ось на що вона йде: налаштувати конфігураційний файл клієнта так,
щоб він вказував на правильний абсолютний шлях; перезапустити застосунок, щоб він
помітив зміну; навчитися налагоджувати програму, вивід якої ви не бачите.
Причина в тому, що print stdio-сервера потрапляє прямо в потік протоколу й ламає
його. Код пишеться легко, а труднощі починаються з підключення. Якщо ваш перший сервер не з’являється в клієнті,
це звичайна справа.
Мінімальний сервер
Офіційний Python SDK (pip install "mcp[cli]") дає вам FastMCP, де інструмент —
це просто функція Python із декоратором. Анотації типів стають JSON Schema, а
докстрінг — описом, який читає модель:
1# Одноразове налаштування, виконайте в терміналі:2# pip install "mcp[cli]"3# Це встановлює офіційний Python SDK для MCP.4 5# FastMCP — простий спосіб написати сервер: ви пишете звичайні функції6# Python, а він перетворює їх на інструменти MCP.7from mcp.server.fastmcp import FastMCP8 9# У кожного сервера є ім’я. Клієнт показує його користувачеві.10mcp = FastMCP(#98c379">"notes")11 12# Наша «база даних» — просто словник Python: заголовок нотатки -> текст нотатки.13# Він живе в пам’яті, тому нотатки зникають, коли сервер зупиняється.14_notes: dict[str, str] = {}15 16 17# @mcp.tool() реєструє цю функцію як інструмент, який може викликати модель.18# Докстрінг нижче читає МОДЕЛЬ — пишіть його для моделі,19# а не для рецензента-людини.20# Анотації типів (title: str, body: str) стають JSON Schema, за якою21# модель будує правильний виклик.22@mcp.tool()23def save_note(title: str, body: str) -> str:24 #98c379">"""Save a note under the given title. Overwrites if the title exists."""25 _notes[title] = body26 # Усе, що ви повернете, — єдине, що отримає модель.27 # Зрозуміле повідомлення краще за «сирий» дамп даних.28 return #98c379">"Saved: " + title29 30 31@mcp.tool()32def list_notes() -> str:33 #98c379">"""List all saved note titles."""34 if not _notes:35 # Корисне повідомлення про помилку дає змогу моделі виправитися самій.36 return #98c379">"No notes yet."37 return "\n".join(sorted(_notes))38 39 40# Ресурс — це довідковий матеріал, який ЗАСТОСУНОК може прочитати в контекст:41# викликати його вирішує не модель, а застосунок.42@mcp.resource(#98c379">"notes://help")43def help_text() -> str:44 #98c379">"""Short guide to the notes server."""45 return #98c379">"Ask the model to save or list notes by title."46 47 48# Транспорт stdio: клієнт сам запускає цей скрипт і спілкується з ним49# через стандартний ввід і вивід. Мережеві порти ніде не відкриваються.50if __name__ == #98c379">"__main__":51 mcp.run(transport=#98c379">"stdio")Три речі, на які варто звернути увагу:
- Докстрінг — це інтерфейс. Модель ніколи не бачить ваш код — лише ім’я функції, анотації типів і докстрінг. Пишіть докстрінг для моделі.
- Анотації типів задають схему виклику.
title: str, body: strстає JSON Schema, за якою модель будує правильний виклик інструмента. - Транспорт stdio означає, що клієнт запускає ваш скрипт і спілкується з ним через стандартний ввід і вивід. Ніщо не слухає мережевий порт.
Перевірте, перш ніж чіпати клієнт
Не пропускайте цей крок. Він відділяє «сервер зламаний» від «клієнт не знаходить мій файл» — а без нього ці дві ситуації виглядають однаково. У SDK є налагоджувач, який запускає ваш сервер і дає змогу викликати інструменти вручну в браузері:
# встановіть офіційний SDK (один раз)
pip install "mcp[cli]"
# запустіть сервер під Inspector, у браузері
mcp dev server.py
# ...або викличте його прямо з терміналу, без жодного клієнта
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python server.py
# Якщо ви бачите тут список зі своїх двох інструментів, сервер працює.
# Якщо ні, помилка в коді, а не в конфігурації клієнта.Дві речі, які ламають кожен перший сервер, і жодна не очевидна:
- Налагодження через print усе ламає. За транспорту stdio
print()пише в той самий потік, який використовує протокол, тож випадковий print псує розмову. Замість цього пишіть логи у файл (loggingізFileHandler) або в stderr. - Відносні шляхи не працюють. Клієнт запускає ваш скрипт із довільного робочого
каталогу. Використовуйте в конфігурації абсолютний шлях, а шляхи до файлів
будуйте відносно
__file__, а не поточного каталогу.
Зареєструйте його в клієнті
Конфігураційний файл вище — для Claude Desktop (Settings, потім Developer, потім
Edit Config). command разом з args кажуть: запусти цей скрипт як локальний
процес і підключися до нього через stdio. Після перезапуску застосунку обидва
інструменти автоматично з’являються в контексті моделі — попросіть її «зберегти
нотатку з назвою groceries: молоко та хліб» і подивіться, як відбувається виклик
інструмента.
Cursor, VS Code (агентний режим Copilot), Zed і Claude Code використовують схожу
структуру JSON або еквівалентну команду claude mcp add. У цьому й сенс
протоколу: той самий сервер працює скрізь. Але гладко буває не завжди:
клієнти відрізняються тим, де лежить конфігураційний файл, чи потрібен повний
перезапуск і наскільки голосно вони повідомляють, що сервер не запустився (часто —
узагалі ніяк). Спершу зазирніть у власну документацію клієнта з MCP, а потім
повертайтеся сюди за розбором серверної частини.
Локально чи віддалено
Поки що сервер працює на вашій машині й запускається клієнтом (stdio). Для команди його розміщують віддалено, через HTTP:
{
"mcpServers": {
"notes": {
"url": "https://notes.example.com/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}
Якщо в конфігурації вказано URL, клієнт підключається через Streamable HTTP, а не запускає процес. Обсяг роботи при цьому зростає стрибком. Віддалений сервер — це публічна точка доступу, а отже, вам знадобляться повноцінна автентифікація (у специфікації для цього передбачено OAuth), TLS, обмеження частоти запитів, логування, керування секретами й хтось, хто помітить, що сервер упав. Цей перелік не коротший, ніж у будь-якого API в реальній експлуатації. Практичне правило: поки розробляєте, починайте зі stdio, переходьте на HTTP, коли сервер потрібен більш ніж одній людині чи сервісу, і вважайте цей перехід окремим проєктом.
Найважливіші практики
- Чіткі описи інструментів. Скажіть, що робить інструмент, коли його використовувати і коли не використовувати. «Зберігає нотатку. Використовуйте для тексту, створеного користувачем; не використовуйте для фрагментів коду» краще, ніж «зберігає дані».
- Невеликі набори інструментів. Схема кожного інструмента займає місце в контексті, а надто багато схожих інструментів збиває модель з пантелику. Десять цілеспрямованих інструментів кращі за сорок, що перетинаються.
- Корисні повідомлення про помилки. Коли виклик не вдався, поверніть повідомлення, з якого модель зрозуміє, що робити далі: «Нотатку ‘groceries’ не знайдено. Доступні: milk-list, ideas», а не «сире» трасування стека. Зі зрозумілим повідомленням про помилку модель дає собі раду без допомоги людини.
- Повертайте структуровані, компактні результати. Обріжте дані до того, що потрібно моделі; величезні відповіді спалюють контекстне вікно.
- Робіть інструменти безпечними за замовчуванням. Підтверджуйте руйнівні операції, обмежуйте права облікових даних і ніколи не дозволяйте інструментові робити більше, ніж обіцяно в його описі.
Перевірте себе
Що робить докстрінг функції-інструмента в MCP-сервері?
Що на практиці означає транспорт stdio?
Ви хочете надати довідковий матеріал, який застосунок читає в контекст, а не те, що модель вирішує викликати. Яку можливість використати?
Куди йти далі
Тепер ви вмієте створювати, підключати й доводити до надійного стану MCP-сервер — затребувана навичка, адже команди вбудовують MCP у все підряд. Якщо ви пропустили теорію, урок MCP: USB-порт для ШІ пояснює три ролі й шлях запиту, а Інструменти та виклик функцій розкриває механізм, на якому побудований MCP.