Запуск сервера
Машинний переклад
Цю сторінку перекладено автоматично з англомовної документації, і основною версією є англомовна сторінка. Якщо щось читається неправильно, на сторінці Переклади пояснено, як про це повідомити.
mcp.run() запускає сервер.
Єдине рішення, яке доводиться ухвалити, — це транспорт: як саме рухаються байти між сервером і його клієнтом.
Вибір транспорту
| Транспорт | Що це | Коли |
|---|---|---|
stdio |
Хост запускає ваш файл як підпроцес і спілкується через його stdin та stdout. | Локальні сервери. Значення за замовчуванням. |
streamable-http |
Справжній HTTP-сервер, що слухає порт. | Усе, що ви розгортаєте. |
sse |
Старіший HTTP-транспорт. | Ніколи. |
Warning
У ревізії протоколу 2025-03-26 SSE поступився місцем Streamable HTTP.
mcp.run(transport="sse") досі працює, зі своїми параметрами sse_path= і message_path=,
але існує лише для клієнтів, які ще не перейшли. Не будуйте на ньому нічого нового.
mcp.run()
from mcp.server import MCPServer
mcp = MCPServer("Bookshop")
@mcp.tool()
def search_books(query: str) -> str:
"""Search the catalog by title or author."""
return f"Found 3 books matching {query!r}."
if __name__ == "__main__":
mcp.run()
run()синхронний. Він блокує виконання на весь час життя сервера.- Без аргументу транспорт —
stdio. - Він стоїть під
if __name__ == "__main__":, бо все, що завантажує сервер (mcp dev,mcp run,mcp install, ваші тести), імпортує цей файл. Ця умова не дає імпорту перетворитися на запущений сервер.
stdio
Налаштовувати нічого. Хост запускає ваш файл як дочірній процес, пише запити в його stdin і читає відповіді з його stdout.
Запустіть його самі — і побачите наслідок:
python server.py
Нічого не виводиться, і керування не повертається. Сервер чекає на stdin, поки хост заговорить першим.
Це також означає, що stdout і є каналом передачі даних. Під час обслуговування SDK переносить цей канал на приватний дескриптор, а вивід, що скидається (flush) у stdout (підпроцес, який пише в успадкований stdout, print() зі скиданням буфера), перенаправляє в stderr, де він не може зіпсувати потік. Вивід, скинутий у stdout до початку обслуговування (скрипт-обгортка з echo, небуферизований print під час імпорту), усе одно потрапляє в канал — як і print(), що лишається в буфері, доки інтерпретатор не спорожнить його під час завершення. Для виводу, який справді потрібен, правильний інструмент — модуль logging: його обробник скидає кожен запис у stderr одразу, щойно той з'являється. Докладніше — на сторінці Логування.
Спробуйте самі
uv run mcp dev server.py
Inspector робить рівно те саме, що й справжній хост: запускає server.py як підпроцес і під'єднується до нього через stdio.
Порт ви йому не вказували. Його й немає.
Streamable HTTP
Щоб натомість виставити той самий сервер на порт, вкажіть транспорт (і його параметри) в run():
from mcp.server import MCPServer
mcp = MCPServer("Bookshop")
@mcp.tool()
def search_books(query: str) -> str:
"""Search the catalog by title or author."""
return f"Found 3 books matching {query!r}."
if __name__ == "__main__":
mcp.run(transport="streamable-http", port=3001)
Цей один рядок будує застосунок Starlette і обслуговує його через uvicorn. Клієнти під'єднуються до http://127.0.0.1:3001/mcp.
Кожен транспорт має власні іменовані аргументи, усі — в run():
host/port: де слухати. За замовчуванням127.0.0.1і8000.streamable_http_path: де розташована кінцева точка MCP. За замовчуванням/mcp.json_response=True: відповідати на кожен POST одним JSON-тілом замість SSE-потоку. У такому тілі є місце для відповіді й ні для чого іншого, тож інструмент, який посеред запиту звертається назад до клієнта (ctx.elicit(), семплювання (sampling)), на цьому відрізку викидаєNoBackChannelError, а сповіщення, прив'язані до поточного виклику (перебіг виконання відctx.report_progress(), повідомлення журналу окремого виклику), відкидаються; окремий потікGETі далі несе не пов'язані з ним.stateless_http=True: новий транспорт на кожен запит, без відстеження сесій.max_request_body_size: найбільший прийнятний розмір тіла POST у байтах. За замовчуванням 4 МіБ; більші запити отримують HTTP 413 ще до розбору чи створення сесії. Збільшуйте його лише тоді, коли легітимні MCP-повідомлення перевищують цей розмір.event_store,retry_interval,transport_security: відновлюваність і захист від DNS-rebinding. Вони можуть зачекати, доки ви не розгорнете сервер деінде, крім localhost;transport_securityописано на сторінці Розгортання та масштабування.
Warning
Параметри транспорту передаються в run(), а не в MCPServer(...). Конструктор описує, чим
ваш сервер є: ім'я, версія, інструкції. run() описує, як його обслуговувати. Переплутайте —
і Python відповість ще до того, як у справу взагалі втрутиться MCP:
TypeError: MCPServer.__init__() got an unexpected keyword argument 'port'
run() — це короткий шлях. Щойно знадобиться більше (сервер, змонтований у наявний застосунок, два сервери в одному процесі, CORS для браузерних клієнтів), ви будуєте ASGI-застосунок самі й віддаєте його будь-якому ASGI-хосту. Про це — Додавання до наявного застосунку.
Налаштування сервера
Кілька речей, що стосуються запуску, до транспорту не належать. Це аргументи конструктора:
from mcp.server import MCPServer
mcp = MCPServer("Bookshop", log_level="DEBUG")
@mcp.tool()
def search_books(query: str) -> str:
"""Search the catalog by title or author."""
return f"Found 3 books matching {query!r}."
if __name__ == "__main__":
mcp.run()
log_level: передається вlogging.basicConfig()тієї ж миті, коли створюєтьсяMCPServer(...). Це налаштовує кореневий логер, тож задає рівень і для ваших власних логерів, а не лише для логерів SDK. За замовчуванням"INFO".debug: передається далі в застосунок Starlette, який будують HTTP-транспорти. За замовчуваннямFalse.
Обидва потрапляють у mcp.settings, звідки їх можна прочитати під час виконання.
Команда mcp
Необов'язковий набір залежностей [cli] встановлює невеличкий інструмент командного рядка поверх усього цього.
mcp dev запускає сервер під MCP Inspector:
uv run mcp dev server.py
uv run mcp dev server.py --with pandas --with numpy
uv run mcp dev server.py --with-editable .
--with додає пакети до середовища, яке вона будує; --with-editable встановлює в нього ваш власний пакет. Потрібен npx у PATH: Inspector — це застосунок на Node.js.
mcp run імпортує файл, знаходить об'єкт сервера (mcp, server або app на рівні модуля) і викликає на ньому run():
uv run mcp run server.py
uv run mcp run server.py:bookshop
Суфікс після : називає об'єкт, якщо його ім'я не mcp, server чи app.
Блок if __name__ == "__main__": тут ніколи не виконується: mcp run викликає run() сама, і єдиний параметр, який вона передає далі, — --transport.
mcp install реєструє сервер у Claude Desktop, щоб застосунок запускав його за вас:
uv run mcp install server.py --name "Bookshop"
uv run mcp install server.py -v API_KEY=abc123 -f .env
-v KEY=VALUE і -f .env записують змінні середовища в цей запис. Claude Desktop запускає ваш сервер у власному процесі. Середовища вашої оболонки там немає.
Claude Desktop — єдиний хост, який знає mcp install. Кожен інший хост (Claude Code, Cursor, VS Code) приймає ту саму команду запуску у власному файлі конфігурації; кожен із них описано на сторінці Під'єднання до справжнього хоста.
mcp version виводить версію встановленого SDK.
Tip
mcp dev і mcp run розуміють лише MCPServer. Якщо ви будуєте на низькорівневому Server,
запускати його доведеться самостійно. Див. Низькорівневий Server.
Підсумки
- Транспорт — це спосіб, у який байти дістаються сервера:
stdioдля локального підпроцесу,streamable-httpдля порту. SSE замінено. mcp.run()обирає транспорт. Без аргументу цеstdio, і виклик блокує виконання.- Кожен параметр транспорту (
host,port,streamable_http_path, ...) — це аргументrun()і ніколи неMCPServer(...). - Тримайте
run()підif __name__ == "__main__":. Усе, що завантажує сервер, спершу імпортує файл. log_level=іdebug=— аргументи конструктора; вони потрапляють уmcp.settings.mcp devдля Inspector,mcp runщоб виконати файл,mcp installдля Claude Desktop,mcp versionдля версії.- Транспорт ніколи не змінює того, чим ваш сервер є: усі три файли на цій сторінці надають ідентичний інструмент.
Коли обмеженням стає сам run() (сервер усередині застосунку, що вже існує), — це Додавання до наявного застосунку. Справжнє ім'я хоста й більше ніж один робочий процес — це Розгортання та масштабування. А якщо частина ваших клієнтів досі на версії специфікації 2025-11-25 чи ранішій, добра новина — на сторінці Обслуговування клієнтів старого покоління.