Безпека та обмеження

Що таке персональний токен доступу

Токен має вигляд fpat_ + 43 символи + 6-символова контрольна сума — 54 символи разом. Це не JWT застосунку: він діє лише на ендпоінті /v1/mcp і ніде більше — GraphQL, WebSocket і чат Fealthy такий токен не приймають. Без токена або з недійсним сервер відповідає 401 із заголовком WWW-Authenticate: Bearer realm="fealthy", error="invalid_token".

Область дії — лише ваші дані

Токен привʼязаний до одного користувача, і це перевіряється на сервері для кожного виклику. Спроба звернутися до чужого запису (наприклад, підставити чужий uid) повертає ту саму помилку not_found, що й запит до неіснуючого запису. Це навмисно: сама відповідь сервера ніколи не підказує, чи чужий запис узагалі існує.

Доступ лише на Premium

MCP доступний тільки на Premium-плані Fealthy. Демо-акаунти заблоковані завжди, незалежно від інших налаштувань. На Free-плані виклик повертає JSON-RPC-помилку forbidden із причиною plan_restricted — і саме на HTTP 200. Це навмисно: довідковий MCP-клієнт шукає JSON-RPC-помилку лише у відповідях з кодом 2xx. Якби сервер відповів іншим статусом, агент прочитав би це як непрозору помилку транспорту, а не як пояснення.

Рівні токена

Токен видається одного з двох рівнів:

  • Write — усі 70 інструментів;
  • Read — лише list_*/get_*, 29 інструментів; спроба викликати інструмент запису відхиляється, а tools/list для такого токена й не покаже нічого, крім читання.

Ліміт запитів

50 операцій на 60 секунд на обліковий запис користувача, спільно для всіх його токенів — другий токен не додає бюджету. Пакетний виклик із N елементами (наприклад, create_transaction з кількома рядками одразу) рахується як N операцій; але create_transfer і create_exchange, попри те що кожен створює дві транзакції, рахуються як одна операція. Залишок бюджету повертається в полі _meta["ua.fealthy/rateLimit"] кожної відповіді. Перевищення ліміту повертає помилку rate_limited із полем retryAfterSeconds — саме стільки треба почекати перед повтором.

uid, а не числові id

Усі записи ідентифікуються лише uid (рядок UUID); числових id у цьому API не існує. Сервер сам генерує uid нового запису — виклик створення з підставленим uid відхиляється помилкою validation_error.

Глобальні (системні) записи

Вбудовані категорії й бізнеси спільні для всіх користувачів і доступні лише для читання: спроба видалити такий запис повертає forbidden із причиною global_read_only. Перейменувати чи змінити іконку системної категорії все ж можна — це створює особисту заміну лише для вас: інші користувачі й сам спільний запис лишаються незмінними, а англійська назва категорії не змінюється ніколи. Приховати системну категорію (той самий перемикач-«око», що в налаштуваннях застосунку) теж можна — і повернути назад.

Формат помилок

Помилка інструмента повертається не як HTTP-помилка, а всередині звичайної успішної JSON-RPC-відповіді: isError: true і код у structuredContent.error.code. Реальні HTTP-помилки лишаються за автентифікацією, методом запиту і форматом тіла (401, 405, і подібні).

КодКоли трапляється
unauthorizedТокен відсутній або недійсний
forbiddenДія заборонена; причина — у полі reason (global_read_only, plan_restricted, demo_user, write_access_required для Read-токена, feature_disabled)
not_founduid не існує або належить іншому користувачу
validation_errorНекоректні параметри виклику; назва поля — в error.field
conflictДія суперечить наявному стану запису
rate_limitedПеревищено ліміт запитів; час очікування — в retryAfterSeconds
internalВнутрішня помилка сервера; повторити виклик пізніше має сенс

Часовий пояс і мова

Часовий пояс визначається так: налаштування вашого профілю Fealthy → інакше заголовок запиту app-timezone → інакше Europe/Kyiv. Дата чи час без явного зсуву, які ви надсилаєте, інтерпретуються саме в цьому поясі; кожна дата у відповіді сервера завжди приходить зі зсувом.

Мова відповіді — мова інтерфейсу вашого профілю Fealthy (українська чи англійська): сервер прямо доручає агенту відповідати нею.

Що сервер каже агенту

Разом з переліком інструментів сервер надсилає агенту явні інструкції — правила, які він має виконувати:

  1. Записи мають лише uid; числових id не існує — ніколи їх не вигадувати й не просити.
  2. Спершу шукати наявний запис через list_*/get_* і використовувати його — створювати лише те, чого справді бракує.
  3. uid нового запису генерує сервер; передавати свій — помилка.
  4. Перед будь-яким delete_* чи іншою незворотною зміною — сказати вам точно, що буде видалено чи змінено, і почекати явного підтвердження.
  5. Глобальні записи можна читати й на них посилатися, але не змінювати й не видаляти.
  6. Дати без зсуву — у вашому часовому поясі; кожна дата у відповіді має зсув.
  7. Відповідати мовою вашого профілю Fealthy.
  8. Не перевищувати ліміт запитів і не повторювати виклик одразу після rate_limited — почекати retryAfterSeconds.
  9. Не повторювати без змін виклик, що впав із validation_error чи forbidden.
  10. Памʼятати рівень власного токена (Write чи Read) і не пропонувати дій, яких він не дозволяє.

Відкликання токена

Самостійного відкликання в застосунку поки немає — попросіть команду Fealthy відкликати токен. Відкликаний токен перестає працювати не пізніше ніж за 60 секунд (це час життя внутрішнього кешу перевірки токена).

Де залишаються дані

MCP-ендпоінт віддає ваші власні дані напряму тому клієнту, якого ви самі підключили, — одним HTTP-викликом, без проміжних сервісів. Fealthy логує сам факт виклику (який інструмент, вдалий чи ні, скільки він коштував за лімітом запитів, тривалість) — не аргументи виклику й не вміст відповіді. Що клієнт чи агент роблять з отриманими даними далі — поза межами Fealthy: обирайте клієнта, якому довіряєте, і зберігайте токен так само дбайливо, як пароль.