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

Новый MCP-сервер стоит проверять так же тщательно, как новый исполняемый файл, которому вы разрешаете работать в своей учетной записи разработчика. Файл конфигурации может выглядеть безобидно: в нем всего одна команда и несколько аргументов. Но на практике эта запись решает, какой код запустится, какую среду он получит, к каким каталогам сможет обращаться и какие описания инструментов будут показаны агенту.
Я часто вижу одну и ту же ошибку: люди считают слово «локальный» границей доверия. Это не так. Локальный сервер обычно запускается с вашими правами, может начать действовать еще до публикации первого инструмента и унаследовать учетные данные, которыми никто не собирался с ним делиться. Проверьте условия запуска до подключения клиента. Затем проверьте заявленные действия до того, как агент сможет их вызвать.
Локальный сервер работает с последствиями вашей учетной записи
Локальный MCP-сервер - это дочерний процесс, а не безобидный объект конфигурации. Если клиент запускает его под вашей обычной учетной записью macOS, сервер может читать доступные файлы проектов, записывать данные в домашний каталог, отправлять запросы во внешнюю сеть и просматривать переменные среды, доступные этому процессу. MCP не изолирует сервер в песочнице. Протокол передает сообщения, но не ограничивает действия исполняемого файла между сообщениями.
Это особенно важно, когда сервер устанавливается командой пакета. Такая конфигурация:
{
"command": "npx",
"args": ["-y", "some-mcp-server"]
}
делает больше, чем запускает известный локальный бинарный файл. Она просит средство запуска пакетов найти пакет, установить или повторно использовать код из кэша и запустить его. На чистой машине, при прогретом кэше и после изменения тега пакета могут выполняться разные версии кода. Знакомая команда заставляет пропустить главный вопрос: какой именно исполняемый файл запустится сегодня?
То же относится к серверу, который клонировали рядом с проектом. Репозиторий может содержать честную реализацию MCP, но вредоносный установочный хук, обертку или зависимость времени выполнения. Проверяйте путь, который запускает процесс, а не только исходный файл, название которого указано в инструкции по настройке.
Считайте учетную запись операционной системы первым решением по ограничению доступа. Одноразовое рабочее пространство, отдельная учетная запись с небольшими правами или виртуальная машина дадут серверу для первичной проверки меньше доступа, чем учетная запись с исходным кодом продакшена и облачными ключами. Это не заменяет проверку кода. Зато ограничивает ущерб, если вы что-то пропустили.
Поле command нужно читать буквально
Читайте команду и аргументы ровно так, как клиент их выполнит. Не заменяйте их в уме дружелюбным описанием из README.
Более безопасный вариант использует фиксированный путь к исполняемому файлу и массив аргументов:
{
"command": "/Users/dev/tools/acme-mcp/bin/server",
"args": ["--config", "/Users/dev/review/acme-mcp.json"],
"env": {
"HOME": "/Users/dev/review-home",
"PATH": "/usr/bin:/bin"
}
}
Такой формат дает конкретные точки для проверки. Существует ли исполняемый файл по этому пути? Кому он принадлежит? Находится ли файл конфигурации за пределами репозитория, который могут изменить другие люди? Нужен ли процессу HOME вообще? Действительно ли ему требуются компилятор, менеджер пакетов или широкий PATH?
Обертка меняет ход проверки. Рассмотрим другой вариант:
{
"command": "sh",
"args": ["-c", "npx -y acme-mcp --token $SERVICE_TOKEN"]
}
Теперь оболочка раскрывает $SERVICE_TOKEN, обрабатывает синтаксис оболочки и может запустить больше одной ожидаемой программы. Средство запуска пакетов может загрузить код. Сервер получает секрет в аргументе команды, который может попасть в список процессов и диагностический вывод. Каждый дополнительный уровень добавляет поведение, которого не будет при прямом запуске исполняемого файла.
Не считайте, что все клиенты одинаково выполняют command. Некоторые напрямую создают процесс с массивом аргументов. Другие предлагают режим работы через оболочку или позволяют использовать скрипт-обертку. Прочитайте документацию клиента и сначала проверьте запуск с безопасной командой, прежде чем одобрять настоящую. Если формат поддерживает и прямой запуск, и оболочку, выбирайте прямой запуск, если только серверу не нужна оболочка по конкретной причине, которую вы можете объяснить.
Проверяйте обертки построчно. В небольших скриптах часто скрывается самое рискованное поведение: загрузка релиза, чтение файла с токеном, смена рабочего каталога, экспорт всех переменных среды или незаметный перезапуск через другой runtime. Скрипт запуска на двадцать строк может требовать больше внимания, чем основная реализация сервера.
Унаследованная среда - это утечка учетных данных, которую часто не замечают
Блок env не обязательно означает «это вся среда». Во многих API запуска процессов среда родительского процесса передается дальше, если средство запуска намеренно ее не заменяет. Тогда записи в env только добавляют или переопределяют отдельные значения. Сам MCP-клиент мог быть запущен из терминала, графического лаунчера, редактора или сервиса автоматизации, и каждый путь может передавать свой набор переменных.
Так возникает неприятный разрыв между тем, что видит проверяющий, и тем, что получает сервер. В JSON может быть указана только LOG_LEVEL, а процесс при этом получит токен реестра пакетов, токен системы контроля версий, облачные учетные данные, настройки прокси, сведения об SSH-агенте и внутренний URL сервиса, унаследованные от клиента.
До подключения сформулируйте контракт среды простыми словами: этому процессу нужны такой endpoint, такая настройка без секрета и, возможно, одна учетная запись с узкими правами. Все остальное - случайно полученные полномочия.
Для первой проверки запустите сам клиент из оболочки с минимальной средой. Эта команда macOS и Unix сохраняет только несколько обычных переменных:
env -i HOME="$HOME/review-home" PATH="/usr/bin:/bin" LANG="${LANG:-C}" \
YOUR_MCP_CLIENT
Замените YOUR_MCP_CLIENT фактической командой клиента. Если сервер не запускается, добавляйте по одной переменной и записывайте, зачем она нужна. Не решайте проблему, возвращая всю среду входа в систему. Из-за такого сокращения уже утекло больше учетных данных, чем многие думают.
Сохраненную конфигурацию можно также проверить, не выполняя ни одной команды. Следующий фрагмент Python выводит имена серверов, команды, аргументы и названия явно указанных переменных среды. Значения переменных он намеренно не выводит.
python3 - "$HOME/.config/your-client/mcp.json" <<'PY'
import json, sys
with open(sys.argv[1], encoding="utf-8") as f:
data = json.load(f)
for name, spec in data.get("mcpServers", {}).items():
print(f"server: {name}")
print(f" command: {spec.get('command', '')}")
print(" args:")
for arg in spec.get("args", []):
print(f" - {arg}")
print(" explicit env names:")
for env_name in sorted(spec.get("env", {})):
print(f" - {env_name}")
PY
Результат будет выглядеть примерно так:
server: issue-tracker
command: /Users/dev/tools/issue-mcp/server
args:
- --read-only
explicit env names:
- ISSUE_TRACKER_URL
Если вы видите имена вроде AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, SSH_AUTH_SOCK или SERVICE_TOKEN, остановитесь и спросите, зачем серверу они нужны. Секреты не становятся безопасными только потому, что хранятся в JSON-файле, а не в исходном коде. Файлы конфигурации копируют в резервные копии, прикладывают к обращениям в поддержку, случайно отправляют в репозиторий, а прочитать их может любой процесс с соответствующим доступом.
Список инструментов заявляет о возможностях, но не выдает разрешения
Спецификация Model Context Protocol определяет tools/list для обнаружения инструментов и tools/call для их вызова. Это удобно: клиент может проверить предложенный сервером интерфейс до того, как агент выберет инструмент. Но такая проверка не сертифицирует сервер, его описания или побочные эффекты вызова.
Считайте каждый рекламируемый инструмент заявленной возможностью. Читайте вместе его название, описание, схему входных данных и аннотации. Инструмент с именем search_issues может выполнять запрос только на чтение, а может собирать файлы проекта и отправлять их третьей стороне перед поиском. deploy_preview может создавать ресурсы, менять DNS или использовать учетную запись с более широкими правами, чем следует из названия.
Спецификация MCP позволяет серверу передавать аннотации с намеками на поведение, например указать, читает ли инструмент данные, изменяет их или взаимодействует с внешней системой. Такие подсказки помогают клиенту показать удобный интерфейс, но спецификация не превращает их в средство контроля. Нечестный или небрежно написанный сервер может пометить разрушительный инструмент как доступный только для чтения. Операционная система и учетные данные сервера не проверят эту метку перед выполнением действия.
Составьте небольшой инвентарный список для каждого одобренного сервера:
- Название инструмента и заявленное действие.
- Входные данные, способные содержать пути к файлам, URL, фрагменты команд оболочки или произвольные запросы.
- Системы, к которым инструмент может обращаться, и используемые учетные данные.
- Побочные эффекты, включая косвенные, например отправку данных во внешний API.
- Точную версию или ревизию исходного кода, которую вы проверили.
Храните инвентаризацию рядом с конфигурацией. Изменения становятся понятными, когда обновление добавляет delete_repository, превращает query в execute или добавляет входное поле с произвольным URL. Без прежнего списка люди часто одобряют изменившийся набор инструментов, потому что название сервера осталось знакомым.
К описаниям нужно относиться с тем же недоверием, что и к любому другому непроверенному тексту, который программа передает агенту. Сервер может назвать один инструмент обязательным, заявить, что одобрение не нужно, или попросить агента передать в аргументах посторонние секреты. Агент не должен считать текст сервера более авторитетным, чем запрос пользователя и правила одобрения клиента.
Для учетных данных нужна граница за пределами процесса агента
Не передавайте серверу долгоживущий API-токен или закрытый SSH-ключ только потому, что он работает на том же ноутбуке. Получив секрет, процесс сервера может записать его в журнал, переслать, сохранить на диске или раскрыть через результат инструмента. После чтения секрета клиент уже не сможет забрать его обратно.
Разделяйте два решения, которые команды часто смешивают. Разрешение запустить сервер означает разрешение выполнить код. Разрешение использовать продакшен-учетные данные означает разрешение действовать во внешней системе. Серверу можно дать первое разрешение в тестовом рабочем пространстве и одновременно отказать во втором.
Для простых задач разработки выдайте ограниченную краткоживущую учетную запись, которая работает только с тестовыми данными. Запишите область ее действия. Формулировка «используется сервером задач» слишком расплывчата. А фраза «может читать тикеты в тестовом проекте, но не может создавать записи, комментировать их или менять состав участников» дает проверяющим конкретный критерий.
Для действий, которым нужны серьезные права, храните секрет в локальной границе учетных данных и открывайте только узкую операцию. Sallyport использует такой подход для действий HTTP и SSH: агент не получает API- или SSH-ключ, приложение выполняет действие и возвращает результат.
Такая граница меняет обращение с секретами, но не отменяет проверку сервера. Вредоносный сервер все еще может попросить агента выполнить опасный, но формально разрешенный вызов. Размещайте одобрение там, где возникает последствие, ограничивайте учетные данные минимально необходимыми полномочиями и читайте каждый запрос, который выходит в важную для вас систему.
Не передавайте учетные данные в аргументах команды. Их могут раскрыть списки процессов, отчеты о сбоях, диагностические средства и родительские процессы. По той же причине избегайте открытых секретов в файлах конфигурации. Если инструкция по настройке требует секрет в одном из этих мест, сначала выясните, может ли сервер использовать системное хранилище учетных данных, краткоживущий токен или внешний сервис действий.
Первое подключение должно проходить в скучной тестовой учетной записи
Передайте незнакомому серверу проект, широкую среду или настоящие учетные данные только после запуска в контролируемой учетной записи. Такая проверка отвечает на узкий вопрос: что программа делает при запуске и когда клиент запрашивает список инструментов?
Создайте новый каталог с безвредными файлами, названия которых сразу покажут неожиданные обращения. Дайте процессу временный HOME. Начните с ограниченного PATH. Не подключайте каталог с исходным кодом только потому, что собираетесь проверить сервер системы контроля версий. Начните с фиктивного репозитория или копии без учетных данных.
Наблюдайте за поведением до первого вызова инструмента. Если сервер при запуске открывает сетевое соединение, сканирует домашний каталог, читает данные браузера или создает файлы для закрепления в системе, он уже делает больше, чем требуется большинству сценариев MCP. Некоторые серверы действительно проверяют endpoint или загружают локальную конфигурацию. Такое поведение должно быть легко объяснить и отключить.
Затем запросите список инструментов, изучите его и выполните один безвредный вызов с известными входными данными. Зафиксируйте запрос, результат, вывод процесса и измененные файлы в тестовом каталоге. Если инструмент возвращает данные из другой системы, используйте заметные тестовые данные, чтобы понять, обратился ли он именно туда, куда нужно.
Базовая последовательность проверки выглядит так:
- Проверьте путь к исполняемому файлу, версию пакета, контрольную сумму или ревизию исходного кода и каждый скрипт запуска.
- Запустите сервер с минимальной средой в тестовой учетной записи или изолированном рабочем пространстве.
- Сохраните первый результат
tools/listи сопоставьте каждый инструмент с предполагаемой задачей. - Выполните безвредную операцию чтения с фиктивными данными и наблюдайте за файлами, дочерними процессами и сетевыми адресами.
- Добавляйте только те учетные данные и доступ к каталогам, необходимость которых подтверждена поведением.
Не путайте успешный ответ с безопасностью сервера. Он может вернуть ожидаемый результат, одновременно копируя файлы или используя унаследованный токен в другом месте. Тест дает свидетельства, а не доказательство. Он помогает обнаружить небрежную реализацию и очевидные сюрпризы до предоставления доступа к продакшену.
Удобство пакетов создает путь обновления, за который отвечаете вы
Менеджеры пакетов и средства запуска runtime делают настройку MCP приятно короткой. Но они также создают путь обновления. Диапазон версий, плавающий тег пакета или одно имя пакета могут изменить сервер, который запустится на следующей неделе, без единого изменения в конфигурации.
Фиксируйте версию, если это поддерживает ваша экосистема, и записывайте источник пакета рядом с инвентаризацией инструментов. Еще лучше использовать проверенный локальный артефакт или lockfile, который ваша команда уже проверяет. Практическая цель проста: следующий запуск должен обратиться к коду, который можно однозначно определить.
Не позволяйте агенту устанавливать собственный MCP-сервер в рамках задачи. Так приобретение программы, ее запуск и разрешение на использование инструментов объединяются в один разговорный запрос. Человек должен добавить конфигурацию сервера после проверки исходного кода и условий запуска. Если рабочему процессу нужно много серверов, ведите проверенный каталог, а не принимайте фрагменты настройки из комментариев к задачам или вывода инструментов.
Обновления требуют короткой повторной проверки. Сравните исполняемый файл или lockfile зависимостей, команду и аргументы, названия явно передаваемых переменных среды и инвентаризацию tools/list. Добавление инструмента может быть безобидным. Но оно же может открыть запись, которую прежняя проверка не рассматривала. То же относится к изменению учетных данных сервера, endpoint или библиотеки аутентификации.
Популярная рекомендация «всегда используйте последнюю версию пакета ради исправлений безопасности» неполна для MCP-серверов. Исправления безопасности нужно устанавливать быстро, но непроверенное автоматическое изменение может поменять код, работающий рядом с вашими учетными данными. Используйте управляемый процесс обновления, который позволяет изучить изменения и откатить их, если новый сервер ведет себя иначе.
Одобрение должно зависеть от действия, а не от названия сервера
Однократное одобрение процесса сервера отвечает только на один вопрос: может ли этот исполняемый файл участвовать в текущей сессии? Оно не может безопасно ответить на все последующие вопросы об удалении удаленной ветки, отправке данных клиентов или выполнении команды SSH на продакшен-хосте.
Разделяйте обычное обнаружение и действия с последствиями. Просмотр доступных проектов, чтение публичной задачи и получение локальной схемы обычно требуют меньшего внимания, чем изменение записей или отправка данных за пределы компьютера. Клиент или граница учетных данных должны запрашивать новое одобрение человека, когда вызов пересекает эту границу. Если каждый вызов чтения требует внимания, люди начнут автоматически нажимать кнопку. Если один клик при запуске дает неограниченный доступ к продакшену, об этом рано или поздно пожалеют.
Важна и личность процесса. В запросе на одобрение должно быть указано, какой подписанный процесс запросил доступ, а не просто показано выбранное сервером название. Название вроде database-helper может скопировать любая программа. Лучше проверять путь к исполняемому файлу, идентификатор подписи, если он доступен, и аргументы запуска.
Храните записи на двух уровнях: сессия агента, запросившая работу, и отдельное действие, в котором использовались учетные данные или внешний сервис. Запись сессии понадобится, чтобы выяснить, почему у агента были полномочия. Запись действия нужна, чтобы понять, что именно изменилось. Один журнал не сможет четко ответить на оба вопроса, если в нем отсутствует либо вызывающая сторона, либо точный запрос.
Защищенная от незаметного изменения запись помогает, когда сервер, клиент или оператор позже спорят о произошедшем. Но сама по себе она не делает опасное действие безопасным в момент одобрения. Прочитайте цель, метод, команду и существенные параметры перед разрешением действия, которое трудно отменить.
Отклоненный сервер нужно не только удалить, но и проверить его следы
Если после подключения вы решили, что серверу нельзя доверять, сразу удалите его запись из клиента, но не останавливайтесь на этом. Процесс мог записать файлы, изменить настройки оболочки, создать запланированные задания, изменить хук репозитория или скопировать учетные данные во время работы.
Сохраните свидетельства до полной очистки. Зафиксируйте конфигурацию, версию пакета или ревизию исходного кода, вывод процесса и журналы действий. Затем проверьте тестовый HOME, рабочий каталог сервера, кэш пакетов, файлы запуска оболочки, launch agents, хуки репозитория и все каталоги, доступные серверу для записи. Пока свидетельства еще доступны, проверьте активные процессы и недавние сетевые соединения.
Смените все секреты, которые процесс мог прочитать, а не только тот, который вы намеренно ему передали. Сюда входят унаследованные токены, доступ к SSH-агенту, учетные данные пакетов и связанные с браузером сессии разработки, если они применимы. Удаление строки из файла конфигурации не отзывает скопированный токен.
Затем усильте процесс проверки, который позволил подключение. Если проблема возникла из-за унаследованной среды, используйте запуск с минимальным набором переменных. Если причиной стало неожиданное обновление пакета, фиксируйте версии и проверяйте артефакты. Если вас ввело в заблуждение описание инструмента, требуйте сохранить инвентаризацию до одобрения. Полезный результат - измененный механизм контроля, а не расплывчатое обещание быть осторожнее в следующий раз.
Новый MCP-сервер получает доступ в самый опасный момент, еще до того, как заслужит доверие. Сделайте его команду буквальной, среду небольшой, список инструментов проверенным, а учетные данные отдельными от агента. Именно тогда результат все еще зависит от вас.
Вопросы и ответы
Безопасен ли локальный MCP-сервер по умолчанию?
Нет. Локальный MCP-сервер запускается как процесс от имени вашей учетной записи, поэтому может читать все доступные ей данные, если операционная система или средство запуска не ограничивают его. Локальный запуск убирает один сетевой переход, но не превращает загруженный код в доверенный.
Что проверить перед добавлением MCP-сервера в клиент?
Проверьте путь к исполняемому файлу, каждый аргумент, рабочий каталог, передаваемую среду, сетевое поведение и список рекламируемых инструментов. Сначала запустите сервер с намеренно пустой средой и под учетной записью с минимальными правами или в одноразовом рабочем пространстве. Список инструментов остается лишь заявлением, пока вы не увидите реальные вызовы.
Может ли MCP-сервер читать переменные среды из моей оболочки?
Считайте, что сервер унаследует их, если в документации клиента не сказано, что он запускается с чистой средой. Многие клиенты не заменяют среду, а добавляют объект env к собственной среде процесса. Так сервер может получить токены реестров пакетов, систем контроля версий, облачных аккаунтов и внутренних сервисов, даже если в конфигурации MCP о них нет ни слова.
Безопаснее ли передавать аргументы MCP-команды, чем строку команды оболочки?
Массив обычных аргументов не допускает разбора оболочкой в клиентах, которые напрямую запускают процесс. Риск возвращается, если конфигурация вызывает sh -c, bash -lc, средство запуска пакетов или скрипт-обертку: эти уровни могут раскрывать переменные, менять пути и выполнять дополнительные команды. Предпочитайте абсолютный путь к исполняемому файлу и явные аргументы.
Можно ли доверять описаниям инструментов MCP-сервера?
Считайте описания инструментов недоверенными данными от программы, которую вы еще не одобрили. Они могут точно описывать инструмент, но также могут побуждать агента раскрыть данные, обойти проверку или вызвать несвязанные инструменты. Сравните заявленные действия и входные данные с репозиторием и с задачей, для которой вы запускаете сервер.
Стоит ли хранить API-токены в файле конфигурации MCP?
По возможности не храните долгосрочные секреты в конфигурации клиента. Используйте хранилище учетных данных, краткоживущий токен или шлюз действий, который держит секрет за пределами процессов агента и сервера. Если токен уже попал в файл конфигурации, историю оболочки или репозиторий, отзовите его, а не просто удаляйте строку.
Как безопасно проверять обновления MCP-сервера?
После обновления сервер может добавить, удалить или переопределить инструменты, а тег пакета позже может указывать на другой код. Зафиксируйте проверенную версию или неизменяемый артефакт, если это поддерживает ваша система пакетов, сохраните инвентаризацию инструментов и повторяйте проверку после каждого изменения. Автоматические обновления в сочетании с правами агента создают опасную комбинацию.
Что означают tools/list и tools/call в MCP?
Клиент запрашивает у сервера tools/list, а затем вызывает выбранный инструмент через tools/call. Такой обмен не делает доверенным ни сервер, ни результат инструмента. Спецификация Model Context Protocol определяет формат сообщений, но вам по-прежнему нужно решить, какой исполняемый файл можно запускать и какие действия могут использовать учетные данные.
Нужен ли шлюз учетных данных для MCP-серверов?
Да, если серверу нужны учетные данные, которые вы не передали бы непроверенному локальному процессу. Шлюз может хранить секрет и выполнять ограниченное действие HTTP или SSH после одобрения человеком, возвращая только результат. Это уменьшает риск раскрытия секрета, но сервер все равно нужно проверять: он может запрашивать опасные действия или неправильно использовать доступные ему данные.
Что делать, если я уже подключил ненадежный MCP-сервер?
Отзовите или удалите запись сервера, смените все раскрытые учетные данные и сохраните конфигурацию с журналами до очистки. Проверьте рабочий каталог сервера, кэш пакетов, файлы запуска оболочки, запланированные задания, учетные данные системы контроля версий и недавние сетевые соединения. Удаление записи MCP не отменяет изменений, которые процесс уже внес.