MCP-токен — це пароль від акаунта, до якого прикрутили API. Віддали його агенту — і маєте користувача, який не втомлюється, читає будь-яку сторінку, на яку його спрямували, і робить рівно те, що сказала остання інструкція в його контексті. Здебільшого саме це й потрібно. Ця сторінка — про решту випадків.
Усе нижче звірено з живим сервером на дату вгорі сторінки: список інструментів узято з tools/list на https://mcp.eqvps.com/mcp, ліміти — із самого API. Якщо ви тільки починаєте, спершу подивіться підключення MCP-клієнта і API-токени, а потім повертайтеся.
Модель загроз: що насправді йде не так
Три сценарії — у тому порядку, в якому ми їх бачимо:
- Агент неправильно зрозумів. «Почисть тестовий сервер» перетворюється на перевстановлення не того сервера. Злого наміру немає, модель просто домислила недомовлене.
- Prompt injection. Агент читає текст, який писали не ви (README, відповідь у тікеті, сторінку з інтернету), і цей текст каже йому щось зробити. Якщо в агента токен з повними правами, вони є й у підкинутої інструкції.
- Токен витік. В історію shell, у публічний репозиторій, у спільний конфіг MCP або в рядок логу.
MCP-сервер перевіряє, що токен дійсний і що сервер належить цьому акаунту (або делегований йому). Чого ви насправді хотіли, він не знає. Усі запобіжники нижче відповідають на одне питання: скільки можна наламати, якщо інструкція хибна?
Усі MCP-інструменти за рівнями ризику
Клієнтський токен бачить 45 інструментів (MCP-сервер 1.6.0). Реселерський токен (rk_…) бачить окремий набір із 30 реселерських інструментів і жодного з цих, тож усього на ендпоінті 75. tools/list віддає клієнту лише його набір.
Тут інструменти розкладено за рівнем ризику. Параметри й приклади викликів кожного — у довіднику параметрів; усі інструменти одним рядком, зокрема 30 реселерських, — у повному списку.
Анотацій MCP-інструментів (readOnlyHint, destructiveHint) у нас поки немає, тому клієнт сам їх не розсортує. Налаштуйте підтвердження вручну за рівнями нижче.
Рівень 0 — публічні, без токена (5)
| Інструмент | Що робить |
|---|---|
get_started | Увесь сценарій в одній відповіді: які інструменти викликати і в якому порядку |
list_plans | Тарифи, ціни, образи ОС |
sandbox_pricing | Тарифи пісочниць |
register_account | Створює новий акаунт і повертає його токен |
login | Email + пароль → токен |
Рівень 1 — читання акаунта, без побічних ефектів (15)
| Інструмент | Що робить | На що зважати |
|---|---|---|
whoami | id, ім'я, email акаунта | |
get_balance | Передплачений баланс | |
list_vps | Активні, ті, що створюються, і призупинені сервери | |
get_vps_status | Статус, характеристики, дані доступу | З reveal: true повертає root-пароль |
get_vps_metrics | CPU, пам'ять, мережа, диск за період | |
get_upgrade_options | На які тарифи сервер можна перевести без перевстановлення | |
list_delegations | Кому ви видали доступ | |
list_delegated_to_me | Сервери, делеговані вам | |
list_tickets | Ваші тікети в підтримку | |
get_ticket | Один тікет із листуванням | Текст тікета для агента — недовірений ввід |
list_sandboxes | Ваші пісочниці | |
get_sandbox | Одна пісочниця та її витрати | |
get_task | Вивід фонового завдання | |
download_file | Читає невеликий файл із пісочниці | |
get_download_url | Тимчасове посилання на один файл пісочниці | Завантажити може будь-хто з посиланням, доки воно не сплило |
Рівень 2 — змінюють стан, нічого не витрачають (17)
| Інструмент | Що робить | На що зважати |
|---|---|---|
power_vps | start / stop / reboot | stop — це stop: сервіси ляжуть |
set_hostname | Змінює ім'я сервера | Змінює те саме значення, яке звіряє confirm |
undo_cancel | Знімає заплановане скасування в кінці періоду | |
refresh_token | Новий токен, старий відкликається одразу | Оновіть статичний конфіг після цього |
set_password | Задає пароль акаунта, якщо його ще немає | Той, у кого токен, може встигнути першим |
topup_balance | Рахунок на поповнення + посилання на криптооплату | Для оплати потрібен гаманець |
pay_invoice | Посилання на оплату неоплаченого рахунку | Те саме |
accept_delegation | Приймає запрошення | |
revoke_delegation | Завершує делегування | |
create_ticket / reply_ticket / close_ticket | Тікети в підтримку | Агент пише в підтримку від вашого імені |
run_code / exec_command | Запускає код у пісочниці | Лише в пісочниці, не на вашому VPS |
kill_task | Зупиняє фонове завдання пісочниці | |
upload_file / get_upload_url | Кладе файл у пісочницю |
Рівень 3 — витрачають гроші, знищують дані або видають доступ (8)
| Інструмент | Що робить | Перевірка на сервері |
|---|---|---|
order_vps | Замовляє сервер, оплата з балансу | Бракує балансу → неоплачений рахунок, нічого не списано |
change_plan | Зміна тарифу без перевстановлення, різниця списується з балансу | confirm: true; бракує балансу → 402 |
create_sandbox | Запускає платну пісочницю | Порожній баланс → 402 |
reinstall_vps | Стирає диск і ставить нову ОС | confirm = точний hostname або DELETE; 4 виклики/хв |
reset_password | Новий root-пароль, старий перестає працювати | confirm = hostname або DELETE; 6 викликів/хв |
cancel_service | end_of_period (за замовчуванням, можна скасувати) або immediate (видаляє сервер одразу) | для immediate потрібен confirm = hostname |
kill_sandbox | Видаляє пісочницю разом із файлами | немає |
delegate_service | Дає іншій людині операторський доступ до сервера | Лише власник; запрошений має прийняти |
Журнал змін набору інструментів
| Дата | Версія сервера | Зміна | Вплив на ризик |
|---|---|---|---|
| 2026-10-03 | 1.6.0 | Додано refresh_token; токени за замовчуванням живуть 1 рік | Рівень 2 |
| 2026-10-03 | 1.5.0 | undo_cancel, get_upgrade_options, change_plan | change_plan витрачає баланс → рівень 3 |
| 2026-10-03 | 1.1.0 | 13 інструментів пісочниць | create_sandbox витрачає, kill_sandbox знищує → рівень 3 |
Поточна версія публічна: curl -s https://mcp.eqvps.com/healthz. Зміниться вона — оновиться й ця таблиця.
Баланс — це стеля витрат
EQVPS працює за передплатою. Прив'язаної картки, кредитної лінії і мінусового балансу немає, тож більше, ніж лежить на балансі, агент не витратить ніколи. Витрачають три інструменти: order_vps, change_plan і create_sandbox. Продовження ваших поточних серверів списуються з того самого балансу.
Створювати запити на гроші агент може, оплачувати — ні. topup_balance і pay_invoice повертають посилання на криптооплату, а без гаманця посилання нічого не робить. Ендпоінта для виведення коштів теж немає: гроші з балансу можна витратити на послуги у вашому акаунті, вивести їх назовні не можна. Повернення при негайному скасуванні теж приходить на баланс.
Одне застереження, і воно серйозне. Якщо тримати баланс зовсім малим, щоб обмежити агента, почнуть зриватися продовження ваших же серверів, і вони підуть у grace-період. Наше правило: один цикл продовження того, що у вас уже працює, плюс бюджет поточного завдання агента. Як це порахувати, розібрано в гайді з бюджету агента. А якщо дати агенту власний гаманець із грошима, він стане другою стелею, за якою теж доведеться стежити.
Мінімальні права: токена лише на читання (поки) немає
Якщо прямо: будь-який клієнтський токен має ті самі права, що й акаунт у кабінеті. Ім'я і строк життя токена налаштовуються, області доступу (scopes) — ні.
Найвужче, що є сьогодні, — делегування. Заводите агенту власний акаунт із нульовим балансом і делегуєте йому один сервер:
delegate_service { "service_id": "EQ-XXXX", "email": "agent@yourdomain.com", "expires_days": 30 }
Те саме через REST:
curl -s -X POST "https://api.eqvps.com/api/v1/eqvps/services/EQ-XXXX/delegations" \
-H "Authorization: Bearer $EQVPS_TOKEN" -H "Content-Type: application/json" \
-d '{"email":"agent@yourdomain.com","expires_days":30}'
Запрошення треба прийняти, увійшовши під цим email (accept_delegation), а expires_days — від 1 до 365. Покроково зі скриншотами: делегування доступу і розділ «Доступ» у документації.
| Делегований акаунт може | Делегований акаунт не може |
|---|---|
| Бачити статус, метрики та історію цього одного сервера | Бачити інші ваші сервери, баланс і рахунки |
| Вмикати, вимикати, перезавантажувати | Скасовувати, продовжувати, змінювати тариф |
| Змінювати hostname і зворотний DNS | Купувати доповнення та IP |
| Скидати root-пароль | Відкривати веб-консоль |
| Перевстановлювати ОС | Передавати сервер комусь іще |
Зверніть увагу на два останні рядки ліворуч. Витратити ваші гроші делегат не може, а от стерти сервер — може. Увімкніть бекапи на кожному сервері, який агент здатен перевстановити.
Гігієна токенів
Один токен на агента, з іменем. Створіть його в Кабінет → Налаштування → API-токени для агентів або так:
curl -s -X POST "https://api.eqvps.com/api/v1/eqvps/auth/tokens" \
-H "Authorization: Bearer $EQVPS_TOKEN" -H "Content-Type: application/json" \
-d '{"name":"backup-agent","expires_in_days":90}'
Токен показується один раз. Строк життя — від 1 до 1825 днів, за замовчуванням 365. Для агентів ми ставили б 90.
Зберігайте його у файлі, який читаєте лише ви — не в репозиторії, не в промпті і не в змінній shell, яку копіюєте туди-сюди:
mkdir -p ~/.config/eqvps && chmod 700 ~/.config/eqvps
( umask 077; read -rsp 'EQVPS token: ' T; echo; printf 'EQVPS_TOKEN=%s\n' "$T" > ~/.config/eqvps/agent.env )
ls -l ~/.config/eqvps/agent.env # очікуємо -rw-------
Далі підключіть його в сервісі агента через EnvironmentFile= (systemd) або set -a; . ~/.config/eqvps/agent.env; set +a.
Ротуйте до закінчення строку. Інструмент refresh_token або POST /auth/tokens/{id}/refresh видає новий токен із тим самим іменем і одразу відкликає старий. Якщо токен вписаний у конфіг MCP-клієнта, оновіть його відразу після цього, інакше наступна сесія отримає 401.
Перевіряйте, хто чим користується: GET /auth/tokens показує всі токени з іменем, строком і last_used_at. Незнайомий токен або токен, яким користувалися після вимкнення агента, — це сигнал.
Якщо токен витік
По черзі:
- Відкличте його. Кабінет → Налаштування → API-токени для агентів → відкликати, або
curl -s -X DELETE -H "Authorization: Bearer $EQVPS_TOKEN" https://api.eqvps.com/api/v1/eqvps/auth/tokens/<id>. Він перестає працювати з наступного запиту. - Пошукайте нові токени, які створювали не ви, і відкличте їх теж.
- Оцініть, що могли зачепити: «Історія послуги» кожного сервера, рахунки й баланс,
list_delegations— чи немає доступу, якого ви не видавали. - Змініть root-паролі на всіх серверах, які бачив цей токен.
get_vps_statusзreveal: trueвіддає root-пароль, тож токен після витоку — це root-пароль після витоку. Заодно перевірте~/.ssh/authorized_keys. - Зачиніть двері з паролем. Якщо в акаунта ніколи не було пароля, той, у кого був токен, міг задати його через
set_password. Увійдіть за кодом із листа і змініть пароль.
Профілактика для п'ятого пункту нічого не коштує: задайте пароль акаунта самі просто зараз, і set_password для всіх інших повертатиме 409.
Підтвердження людиною
Що сервер перевіряє сам:
reinstall_vps,reset_passwordіcancel_serviceзtype: immediateвимагаютьconfirm, що дорівнює точному hostname (для перевстановлення і скидання пароля підходить іDELETE).change_planвимагаєconfirm: true.- За замовчуванням скасування —
end_of_period: сервер працює до кінця оплаченого періоду, аundo_cancelусе повертає. - Ліміти на акаунт: перевстановлення 4/хв, скидання пароля 6/хв, живлення 20/хв, замовлення 20/хв. Цього досить, щоб зациклений агент не зробив одне й те саме п'ятдесят разів, але одну хибну команду ліміт не зупинить.
Важливо розуміти, що таке confirm. Він не дає агенту виконати розмите «почисть там». Зловмисника він не зупинить: hostname видобувається одним викликом get_vps_status. Справжнє підтвердження живе у вашому MCP-клієнті. Більшість клієнтів уміють питати перед кожним викликом: рівні 0 і 1 пускайте вільно, рівень 3 — лише з питанням. У клієнтах із правами на окремі інструменти, наприклад у settings.json у Claude Code (сервер зареєстровано як eqvps):
{
"permissions": {
"ask": ["mcp__eqvps__order_vps", "mcp__eqvps__change_plan", "mcp__eqvps__create_sandbox", "mcp__eqvps__reset_password", "mcp__eqvps__delegate_service"],
"deny": ["mcp__eqvps__reinstall_vps", "mcp__eqvps__cancel_service", "mcp__eqvps__kill_sandbox"]
}
}
І додайте рядок до інструкцій агента. Сам по собі це не захист, але випадків «не так зрозумів» стане менше (залиште його англійською — моделі розуміють його однаково):
Never call reinstall_vps, reset_password, cancel_service (type=immediate), change_plan,
order_vps, create_sandbox, kill_sandbox or delegate_service unless the human has typed
the target server's hostname in this conversation for that specific action.
Якщо агент входить за кодом із листа, а не тримає довгоживучий токен, дивіться вхід агента через MCP.
Аудит: що видно потім
- Список токенів (
GET /auth/tokensабо Налаштування → API-токени для агентів): ім'я, дата створення, строк,last_used_at. Ось навіщо давати токенам імена за агентами. - «Історія послуги» (кабінет, сторінка сервера): вмикання і вимикання, перевстановлення, скидання пароля, зміни тарифу, платежі — з часом і джерелом: ви, підтримка чи автоматично. Який саме токен або делегат це зробив, вона не покаже — лише що дія прийшла з вашого боку.
- Рахунки й баланс: кожне списання і повернення.
list_delegations: у кого є доступ, до чого і до якої дати.
Ця прогалина в «Історії послуги» — чесна межа серверного аудиту на сьогодні. Якщо треба знати, який агент що зробив, логуйте кожен виклик інструмента з аргументами (без секретів) на боці агента.
Яку схему обрали б ми
Для агента, який обслуговує один бойовий сервер:
- Окремий акаунт для агента з нульовим балансом, сервер делеговано з
expires_days: 90. - Ваш токен власника лишається у вас і не лежить у жодному конфігу агента.
- Бекапи на цьому сервері — делегат може його перевстановити.
- Інструменти рівня 3 у клієнті — на «ask» або «deny».
- Токен агента у файлі з правами
600, оновлюється до закінчення строку.
Агенту, якому треба замовляти сервери чи запускати пісочниці, делегування замало — йому потрібен баланс. Тоді стеля — баланс: поповнюйте його під завдання, давайте токену ім'я і раз на тиждень дивіться last_used_at. Якщо токен лише на читання змінив би те, як ви запускаєте агентів, напишіть нам у підтримку: саме такі відгуки вирішують, що ми робимо далі.
Коментарі
Поки немає коментарів. Будьте першим.