# Свои MCP-серверы

> Сервер MCP из архива, репозитория GitHub или по адресу: что запустится, ваше согласие и только читающие инструменты — по вашей отметке.

Кроме интеграций из [каталога](/docs/connector/marketplace) коннектор умеет запускать
**сервер MCP, который вы принесли сами**: сервер вашего вендора, сервер из открытого
репозитория, сервер, написанный вашей командой под внутреннюю систему. Его инструменты
модель получает так же, как инструменты интеграций из каталога — по тем же правилам и по
тому же пути.

Разница в одном: этот код **никто не проверял**. Интеграции из каталога подписаны нами,
ходят в сеть только через ядро коннектора и только по адресам, которые вы указали. Свой
сервер запускается как есть — под отдельным пользователем ОС, но в сеть ходит сам, и
коннектор его обращения не видит и не ограничивает. Поэтому такое подключение вы
подтверждаете явно, оно везде помечено как **пользовательское**, а что из его инструментов
считать читающим — решаете вы, а не сам сервер.

_Иллюстрация: В приложении такое подключение помечено, и подсказка объясняет, что это значит. Инструменты — только те, что администратор отметил как читающие._

## Три способа принести сервер

Все три — на [локальной странице коннектора](/docs/connector/web-setup), в разделе
**«Свои MCP»**. Код оказывается на машине коннектора и нигде больше; подтверждает
установку тот, кто сидит за этой страницей.

_Иллюстрация: Раздел «Свои MCP»: перетащить архив, назвать репозиторий или адрес. Сверху страница говорит, что есть на машине — Node.js, Python._

**Архив.** Перетащите на страницу файл — коннектор распакует его и прочитает, как этот
сервер запускается, из его же упаковки:

| Формат | Что читается |
|---|---|
| `.mcpb`, `.dxt` — MCP Bundle | `manifest.json`: команда, аргументы, переменные окружения, настройки, которые сервер просит у пользователя (`user_config`), список инструментов. Зависимости в комплекте уже лежат |
| `.zip`, `.tar.gz`, `.tgz` с исходником на Node.js | `package.json`: точка входа (`bin`, иначе `main`), зависимости ставятся `npm install` (или `npm ci`, если есть lockfile); если точка входа собирается — `npm run build` |
| архив с исходником на Python | `pyproject.toml`: сервер ставится в собственное окружение `.venv`, запускается его скриптом из `[project.scripts]` или как модуль |
| архив с `server.json` реестра MCP | имя, версия, переменные окружения, которые сервер требует; способ запуска — из лежащего рядом `package.json`/`pyproject.toml`, а без них — пакет из реестра через `npx`/`uvx` |

Папку верхнего уровня, которую добавляет GitHub или архиватор, коннектор снимает сам.
Ссылки, абсолютные пути и выход из каталога в архиве не допускаются — такой архив
отклоняется целиком, а не «чистится».

**Репозиторий GitHub.** Вставьте адрес — с веткой, тегом или коммитом, если нужно
(`…/tree/release-2`). Приватному репозиторию нужен токен: он используется один раз для
скачивания и не сохраняется. Дальше всё как с архивом.

**Удалённый сервер.** Сервер, который уже работает где-то по адресу (транспорт
Streamable HTTP). Укажите адрес и, если сервер того требует, заголовок `Authorization` —
он хранится в каталоге секретов коннектора и отправляется с каждым запросом. Код на вашу
машину при этом не попадает. Вход по OAuth для удалённых серверов не поддерживается.

## Что нужно на машине

Серверу на Node.js нужен Node.js, серверу на Python — Python 3 (или `uv`). Коннектор
ищет их в `PATH` **так, как их увидит пользователь подключения** — интерпретатор в
домашнем каталоге root ему недоступен. Страница говорит, что нашлось, до того как вы
что-то перетащите; если нужного нет, черновик скажет об этом сразу, и ничего не
сохранится. Для серверов на Python подойдёт и среда, которую коннектор держит для
интеграций из каталога.

<Callout>
Зависимости ставятся **под пользователем подключения**, в его каталоге, а не под
коннектором: `npm install` чужого проекта запускает чужие скрипты, и это первое место,
где чужой код получает управление. Журнал установки — слово в слово то, что напечатали
`npm` или `pip`, — остаётся в черновике.
</Callout>

## Что будет запущено

Черновик показывает **всё, что запустится**: команду, аргументы, переменные окружения,
настройки, которые сервер просит. Это отправная точка, а не приговор: любое поле можно
поправить, и запустится ровно то, что написано в форме.

_Иллюстрация: Черновик после распаковки: что запустится, что попросил сервер, журнал установки — и согласие, без которого ничего не сохраняется._

- Слова упаковки `node`, `npx`, `python`, `uvx` коннектор заменяет на то, что нашёл на
  этой машине.
- `${__dirname}` — каталог с кодом сервера, `${user_config.имя}` — значение настройки из
  формы. Так пишет свои манифесты MCP Bundle; так же можно писать и руками.
- Настройка, которую упаковка пометила как секретную, хранится как секрет — в файле с
  правами `0600`, а в файле настроек остаётся только ссылка — и доходит до сервера
  только там, где на неё есть `${user_config.…}`. Секрет, о котором упаковка ничего не
  сказала (токен для API, который сервер читает из окружения), добавляется в поле
  «Секреты в окружении» — он попадёт серверу переменной под своим именем.
- Настройка, которой не хватает, — ошибка запуска, где она названа по имени, а не пустая
  строка, переданная серверу.

Название на кириллице модель увидеть не может — в имена инструментов попадает
[слаг](/docs/connector/tools#регистрирует-коннектор-а-не-вы), и для такого названия он
берётся из имени сервера в его упаковке (`weather-mcp` → `weather_mcp`).

## Согласие

Сохранить подключение можно только с галочкой: вы принимаете, что код не проверялся
Buff, что его обращения в сеть коннектор не ограничивает, и что модели достанутся только
инструменты, которые вы отметите как читающие. Это не формальность интерфейса: согласие
записывается в [файл настроек](/docs/connector/yaml#mcp--свой-сервер) как поле
`accepted`, и без него коннектор такое подключение **не запустит** — даже если его вписали
в YAML руками.

Изолируется сервер как любое подключение: [свой процесс под своим пользователем ОС](/docs/connector/isolation),
свой рабочий каталог, ни ключа коннектора, ни чужих секретов он не видит. Без привилегии
на смену пользователя (не root, Windows) свои серверы, как и интеграции из каталога, не
запускаются.

## Только чтение — ваше решение

Инструменты доходят до модели [только читающие](/docs/connector/tools#пишущие-инструменты-не-отдаются-модели-никогда) —
в «Спросить» и в глубоком исследовании, как и у интеграций из каталога.
У интеграции из каталога, какой инструмент читающий, говорит её подписанный манифест.
У своего сервера подписи нет — есть его собственное слово (`readOnlyHint` в описании
инструмента), и слово непроверенного кода о собственной безобидности — ровно то, чему
правило «читать можно, писать нельзя» не должно верить.

_Иллюстрация: Инструменты своего сервера — галочки. «Сервер: чтение» — его слова; отметка — ваше решение. Без отметки инструмент модели не достаётся._

Поэтому у своего сервера инструменты — галочки. Как только сервер запустился и объявил
их, отметьте те, что только читают, и нажмите **«Сохранить отметки чтения»**. Кнопка
**«Отметить как предлагает сервер»** ставит галочки по его подсказке — проверьте их
глазами. Отметки применяются сразу, без перезапуска сервера; **неотмеченный инструмент
не достаётся модели ни на одной стадии**.

## Проверка связи и журнал

**«Проверить связь»** у своего сервера — это удавшееся рукопожатие: имя и версия, которыми
сервер представился, и число инструментов. **«Журнал»** — то, что сервер пишет в
стандартный поток ошибок; упавший при старте сервер оставляет там причину.

## Чего не делает

- **События, опрос, вебхуки** — нет: свой сервер даёт модели инструменты, и только их.
  Обращения из трекера ждут [интеграций из каталога](/docs/connector/trackers).
- **Ресурсы и промпты MCP** — не читаются; используются только `tools`.
- **Обновления** — не отслеживаются. Новую версию приносят так же, как первую; старое
  подключение можно удалить.
- **OAuth** для удалённых серверов и устаревший транспорт HTTP+SSE — не поддерживаются.
- **Ограничение сети** чужого кода — не обещается. Это и есть причина пометки.
