Перейти к содержанию

Подключение к настоящему хосту

Машинный перевод

Эта страница переведена с английской документации автоматически, и основной версией остаётся английская страница. Если что-то читается неправильно, на странице Переводы объясняется, как об этом сообщить.

Хост — это приложение, внутри которого в итоге оказывается ваш сервер: Claude Desktop, Claude Code, IDE. Именно с хостом говорит пользователь. Внутри него MCP-клиент запускает ваш сервер как дочерний процесс и общается с ним через stdin и stdout этого процесса.

А значит, подключение к хосту сводится к одному действию: сообщить ему команду, которая запускает сервер. Всё на этой странице (две команды CLI, три JSON-файла) — это разные места, куда кладётся одна и та же команда.

Один сервер, любой хост

server.py
from mcp.server import MCPServer

mcp = MCPServer("Bookshop")

CATALOG = {
    "Dune": "Frank Herbert",
    "Neuromancer": "William Gibson",
    "The Left Hand of Darkness": "Ursula K. Le Guin",
}


@mcp.tool()
def search_books(query: str) -> list[str]:
    """Search the catalog by title or author."""
    needle = query.lower()
    return [title for title, author in CATALOG.items() if needle in title.lower() or needle in author.lower()]


@mcp.tool()
def get_author(title: str) -> str:
    """Look up the author of a book in the catalog."""
    if title not in CATALOG:
        raise ValueError(f"No book titled {title!r} in the catalog.")
    return CATALOG[title]


@mcp.resource("catalog://titles")
def titles() -> str:
    """Every title in the catalog, one per line."""
    return "\n".join(sorted(CATALOG))


if __name__ == "__main__":
    mcp.run()

Два инструмента и ресурс, один файл. Три вещи в этом файле важны для каждого хоста ниже:

  • mcp.run() без аргументов запускает stdio-сервер: он блокируется, читает сообщения протокола из stdin и пишет их в stdout. Это тот транспорт, на котором говорят все хосты на этой странице. Хост запускает ваш файл как дочерний процесс и владеет обоими каналами, поэтому подключение всегда сводится к «вот команда». Порт выбирать не нужно, и ничто на нём не слушает.
  • run() стоит под if __name__ == "__main__":. Всё, что ниже, импортирует этот файл, а не выполняет его, так что незащищённый run() запускал бы сервер в тот момент, когда что-нибудь загружает модуль.
  • Объект сервера — глобальная переменная уровня модуля с именем mcp. Это имя ищет mcp run (server и app тоже подходят). Назовёте иначе — придётся указать имя явно: mcp run server.py:bookshop.

Это последняя строка Python на этой странице. Дальше — только настройка хостов.

Команда запуска

Каждый хост ниже получает одну и ту же команду:

uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

Одна команда для всех, потому что uv run --with прямо на месте разворачивает SDK в свежем окружении: она работает из любого каталога, не требует проекта и не требует активировать виртуальное окружение. Здесь это важнее, чем где бы то ни было, потому что хост запускает сервер из своего рабочего каталога с почти пустым окружением, а не из вашей оболочки.

Это же команда, которую mcp install записывает за вас в конфигурацию Claude Desktop (ниже), так что набранное вручную и сгенерированное инструментом совпадают, если не считать точной фиксации версии, которую добавляет инструмент.

Если хост не находит uv

Хост порождает ваш сервер с минимальным PATH, и uv в нём может не оказаться. Замените голое uv абсолютным путём из which uv (macOS/Linux) или where uv (Windows). Именно это и записывает mcp install.

Эта страница — про локальный сценарий

Всё здесь запускает сервер на той же машине, где находится хост: хост запускает ваш файл через stdio. Это в точности то, что нужно для личного инструмента или инструмента на одну машину. Чтобы отдать сервер людям, у которых нет вашего файла, раздают URL, а не команду: тот же объект mcp, обслуживаемый по Streamable HTTP. Запуск сервера сводит это решение в одну таблицу, а Развёртывание и масштабирование — дорога оттуда к настоящему имени хоста.

А хост — это всего лишь приложение с MCP-клиентом внутри, так что роль хоста может сыграть ваш собственный код на Python: Клиентские транспорты запускают этот же файл как подпроцесс через stdio_client(...), а Тестирование подключается к нему в памяти вообще без процесса.

Claude Desktop

Единственный хост, который SDK умеет настроить за вас:

uv run mcp install server.py

Вот и всё. mcp install импортирует файл, чтобы прочитать имя сервера, находит файл конфигурации Claude Desktop и записывает в него команду запуска. Попутно она превращает ваш путь в абсолютный, чтобы этого не пришлось делать вам.

Никакой магии здесь нет. Вот запись, которую она создаёт:

{
  "mcpServers": {
    "Bookshop": {
      "command": "/absolute/path/to/uv",
      "args": [
        "run",
        "--frozen",
        "--with",
        "mcp[cli]==2.0.0",
        "mcp",
        "run",
        "/absolute/path/to/server.py"
      ]
    }
  }
}

Это команда запуска из раздела выше с тремя добавлениями: абсолютный путь к uv, --frozen, чтобы uv никогда не переписывал lock-файл, рядом с которым случайно окажется, и точная фиксация установленной у вас версии mcp. Запись попадает в claude_desktop_config.json, который лежит здесь:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Этот файл можно написать и вручную. mcp install существует затем, чтобы вы при этом не допустили классической ошибки (относительного пути).

Полностью завершите Claude Desktop (а не просто закройте окно) и откройте заново.

Warning

mcp install завершается ошибкой Claude app not found, если каталога конфигурации Claude Desktop ещё не существует. Установите Claude Desktop и запустите его один раз: именно это создаёт каталог.

Tip

Claude Desktop запускает сервер в собственном процессе, так что переменных окружения вашей оболочки там нет. uv run mcp install server.py -v API_KEY=abc123 (или -f .env) записывает их в поле env записи. --name переопределяет имя записи; по умолчанию берётся name сервера.

Claude Code

Редактировать никакой файл не нужно. Зарегистрируйте сервер через CLI claude; всё после -- — это команда запуска.

claude mcp add bookshop -- uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

Выполните /mcp внутри сессии Claude Code, чтобы убедиться, что bookshop подключён и его инструменты перечислены.

Cursor

Создайте .cursor/mcp.json в корне проекта.

{
  "mcpServers": {
    "bookshop": {
      "command": "uv",
      "args": ["run", "--with", "mcp[cli]", "mcp", "run", "/absolute/path/to/server.py"]
    }
  }
}

Те же command и args под тем же ключом mcpServers, что использует Claude Desktop. Сервер появляется в настройках MCP Cursor с обоими инструментами в списке.

VS Code

Создайте .vscode/mcp.json в корне проекта.

{
  "servers": {
    "bookshop": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--with", "mcp[cli]", "mcp", "run", "/absolute/path/to/server.py"]
    }
  }
}

Два отличия от файла Cursor, и только эти два: ключ-обёртка — servers, а не mcpServers, и каждая запись объявляет свой type. Подтвердите запрос о доверии, после чего MCP: List Servers в палитре команд покажет запущенный bookshop.

Note

Нужен VS Code 1.99 или новее с расширением GitHub Copilot, в котором выполнен вход (достаточно Copilot Free), и Copilot Chat должен быть в режиме Agent, потому что никакой другой режим не вызывает инструменты.

Сервер не появляется

Прежде чем трогать конфигурацию какого-либо хоста, выполните команду запуска сами:

uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

Ничего не печатается, и команда не завершается. Эта тишина правильна: stdio-сервер ждёт, пока хост первым заговорит через stdin (Ctrl-C, чтобы остановить). Настоящая ошибка — это трассировка или немедленный выход, и теперь её можно прочитать, а не угадывать через хост.

Когда эта команда спокойно ждёт, остаётся почти всегда одно из трёх:

  • Относительный путь. Хост запускает сервер из своего рабочего каталога, а не из того, где вы его регистрировали. server.py там, где нужен /absolute/path/to/server.py, — самая распространённая ошибка. Если хост не находит и uv, этот путь тоже должен быть абсолютным.
  • Хост всё ещё работает со старой конфигурацией. Хосты читают конфигурацию при запуске. Claude Desktop в особенности нужно полностью завершить (а не просто закрыть окно) и открыть заново, прежде чем правка в claude_desktop_config.json вступит в силу.
  • Что-то попало в stdout вне перенаправляемого окна. На stdio stdout и есть протокол. SDK на время обслуживания перенаправляет сброшенный посторонний вывод в stderr, но вывод, сброшенный в stdout до этого (скрипт-обёртка с echo, print() при импорте в небуферизованном процессе), или буферизованный print(), слитый при завершении интерпретатора, отдаёт хосту испорченное сообщение, и тот разрывает соединение. Пишите логи с конфигурацией logging по умолчанию, чей stderr-обработчик сбрасывает каждую запись; пользовательские обработчики тоже должны избегать stdout. Подробнее — на странице Логирование.

Claude Desktop ведёт лог для каждого сервера: mcp-server-<NAME>.log — это stderr вашего сервера, рядом с mcp.log для подключений, в ~/Library/Logs/Claude на macOS и %APPDATA%\Claude\logs на Windows.

Всё, что выходит за рамки этих трёх случаев, — на странице Устранение неполадок.

Итоги

  • Хост (Claude Desktop, IDE) содержит MCP-клиент, который запускает ваш сервер как дочерний процесс через stdio. Подключиться — значит дать ему одну команду запуска.
  • Эта команда — uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py: не нужно активировать venv, работает из любого каталога.
  • Claude Desktop — единственный хост, который mcp install настраивает за вас. Она записывает ту же команду (плюс абсолютный путь к uv, --frozen и точную фиксацию установленной у вас версии) в claude_desktop_config.json, чтобы этого никогда не пришлось делать вам.
  • Claude Code — это claude mcp add bookshop -- <launch command>. Cursor.cursor/mcp.json под ключом mcpServers. VS Code.vscode/mcp.json под ключом servers, каждая запись с type.
  • Везде абсолютные пути, перезапуск хоста после правки его конфигурации, и ничто, кроме SDK, не должно писать в stdout.

Каждый хост на этой странице подключился к одному и тому же файлу одной и той же командой. То, что этот файл может предоставлять, — остальная документация: Инструменты, Ресурсы и все транспорты, кроме stdio, на странице Запуск сервера.