Управление агентами
Эта страница описывает административные resources /api/agents* и /api/tables/agents.
Они не используются для чтения заказов, клиентов или других бизнес-данных. Рабочие методы MCP перечислены в разделе «MCP: как агент работает с Gigma ERP», а получение первого токена через владельца — в разделе [«Получение доступа»](/mcp/Получение доступа/).
Agent account хранится в таблице пользователей, но имеет is_agent = true. Поэтому:
- агенты исключены из
/api/users; - обычные сотрудники не открываются через
/api/agents/{agent}; - agent routes ограничивают целевой объект проектом текущего actor;
- отключение не удаляет запись, а устанавливает
is_banned = trueи отзывает все токены.
Кто может вызывать административные endpoints
Backend не вводит единый запрет «agent actor не может администрировать агентов».
- list, show и table-list проверяют соответствующий agent permission;
- create проверяет
create-agentsи допустимость назначаемой роли/permissions; - update и disable проверяют
edit-agents, проект и текущий набор прав целевого агента; - token operations дополнительно требуют, чтобы actor не был агентом.
Следовательно, технически agent account с административными permissions может читать, создавать, изменять и отключать другие agent accounts. Обычному MCP-помощнику такие permissions выдавать не следует. Для выпуска, просмотра и отзыва токенов в любом случае нужен Bearer человека.
Permissions
| Permission | Операции |
|---|---|
view-agents | список, table-list и карточка |
create-agents | создание |
edit-agents | изменение и отключение |
manage-agent-tokens | список, выпуск и отзыв токенов; только human actor |
view-users, create-users и edit-users не заменяют agent permissions.
Дополнительная проверка текущего агента
Одного permission edit-agents или manage-agent-tokens недостаточно. Перед update, disable и token operations policy проверяет уже назначенные агенту роль и permissions:
- для агента с ролью
ownerилиadminactor должен иметьedit-adminsлибоedit-permissions; - без
edit-permissionsactor может управлять только агентом, чей текущий permission set является подмножеством permissions actor; - если агент уже сильнее actor, backend вернёт
403даже при попытке уменьшить его права, отключить его или отозвать токен.
Список агентов
Список агентов проекта
- Метод
- GET
- URL
https://api.gigma.ru/api/agents- Авторизация
- Bearer actor с view-agents
- Headers
Accept: application/json; Authorization: Bearer {actor_token}- Успешный ответ
200
Параметры запроса
role_id[](integer[], необязательно) — роли агентов;branch_id[](integer[], необязательно) — филиалы;department_id[](integer[], необязательно) — отделы;is_banned(boolean, необязательно) — состояние блокировки;date_from(date, необязательно) — дата создания от;date_to(date, необязательно) — дата создания по;query(string, необязательно) — поиск по имени или login, от 3 до 255 символов.
Фильтры не расширяют project scope: backend всегда подставляет project_id текущего actor.
Пример запроса
GET /api/agents?is_banned=false&role_id[]=14&query=order
Authorization: Bearer <actor_token>
Accept: application/json Ответ
{
"agents": [
{
"id": 214,
"code": "12345678901",
"name": "Order Assistant",
"login": "order-assistant",
"role": {
"id": 14,
"name": "employee"
},
"branch": null,
"department": null,
"agent_description": "Готовит сводки по заказам",
"is_agent": true,
"is_banned": false,
"creator": {
"id": 7,
"avatar": "https://api.gigma.ru/storage/uploads/default.svg",
"first_name": "Артём",
"last_name": "Полищук",
"middle_name": null,
"name": "Полищук Артём"
},
"last_activity_at": null,
"permissions": [
{
"name": "view-orders"
}
],
"created_at": "2026-08-16T16:00:00.000000Z",
"updated_at": "2026-08-16T16:00:00.000000Z"
}
],
"agentsCount": 1
} code генерируется backend как случайная уникальная строка из 11 цифр. Endpoint возвращает всю отфильтрованную коллекцию без стандартного pagination wrapper.
Табличный список агентов
- Метод
- GET
- URL
https://api.gigma.ru/api/tables/agents- Авторизация
- Bearer actor с view-agents
- Headers
Accept: application/json; Authorization: Bearer {actor_token}- Успешный ответ
200
Параметры запроса
Поддерживаются те же фильтры, что у GET /api/agents, и параметры табличной пагинации:
role_id[](integer[], необязательно) — роли агентов;branch_id[](integer[], необязательно) — филиалы;department_id[](integer[], необязательно) — отделы;is_banned(boolean, необязательно) — состояние блокировки;date_from(date, необязательно) — дата создания от;date_to(date, необязательно) — дата создания по;query(string, необязательно) — поиск по имени или login, от 3 до 255 символов;page(integer, необязательно) — номер страницы;per_page(integer, необязательно) — размер страницы.
Пример запроса
GET /api/tables/agents?page=1&per_page=20&is_banned=false
Authorization: Bearer <actor_token>
Accept: application/json Ответ
{
"columns": [
{
"id": 1,
"table_id": 1,
"order": 0,
"key": "id",
"has_icon": 0,
"text": "№"
}
],
"agents": [
{
"id": {
"icon": null,
"value": 214,
"url": "<frontend_url>/agents/list-agents/214"
},
"code": "12345678901",
"name": {
"icon": null,
"value": "Order Assistant",
"url": "<frontend_url>/agents/list-agents/214"
},
"branch": null,
"department": null,
"role": "Сотрудник",
"login": "order-assistant",
"is_banned": false,
"last_activity_at": "Ожидание входа"
}
],
"pagination": {
"total": 1,
"per_page": 20,
"current_page": 1,
"last_page": 1,
"from": 1,
"to": 1
}
} Для server-to-server интеграции обычно достаточно ресурсного GET /api/agents; table-list нужен, когда действительно требуются UI-колонки и табличная пагинация.
Карточка агента
Получение агента
- Метод
- GET
- URL
https://api.gigma.ru/api/agents/{agent}- Авторизация
- Bearer actor с view-agents
- Headers
Accept: application/json; Authorization: Bearer {actor_token}- Успешный ответ
200
Параметры пути
agent(integer, обязательно) — ID agent account из проекта actor.
Пример запроса
GET /api/agents/214
Authorization: Bearer <actor_token>
Accept: application/json Ответ
{
"agent": {
"id": 214,
"code": "12345678901",
"name": "Order Assistant",
"login": "order-assistant",
"role": {
"id": 14,
"name": "employee"
},
"branch": null,
"department": null,
"agent_description": "Готовит сводки по заказам",
"is_agent": true,
"is_banned": false,
"creator": {
"id": 7,
"avatar": "https://api.gigma.ru/storage/uploads/default.svg",
"first_name": "Артём",
"last_name": "Полищук",
"middle_name": null,
"name": "Полищук Артём"
},
"last_activity_at": null,
"permissions": [
{
"name": "view-orders"
}
],
"created_at": "2026-08-16T16:00:00.000000Z",
"updated_at": "2026-08-16T16:00:00.000000Z"
}
} Возможные ошибки
403— нетview-agents;404— ID не существует, относится к человеку или agent account другого проекта.
Не перебирайте соседние ID после 404.
Создать agent account вручную
Создание агента
- Метод
- POST
- URL
https://api.gigma.ru/api/agents- Авторизация
- Bearer actor с create-agents
- Headers
Accept: application/json; Content-Type: application/json; Authorization: Bearer {actor_token}- Успешный ответ
200
Параметры запроса
name(string, обязательно) — имя агента, от 1 до 255 символов;login(string, обязательно) — уникальный среди всех users технический login, от 3 до 255 символов;role_id(integer, обязательно) — роль текущего проекта;branch_id(integer, необязательно) — филиал текущего проекта илиnull;department_id(integer, необязательно) — отдел текущего проекта илиnull;permissions(string[], необязательно) — permissions сguard_name = user, которые actor вправе делегировать;agent_description(string, необязательно) — назначение агента, до 5000 символов, илиnull;is_banned(boolean, необязательно) — создать агента сразу отключённым.
Для роли owner или admin actor должен иметь edit-admins либо edit-permissions. Другие роли текущего проекта отдельной иерархией не сравниваются.
Без edit-permissions каждое передаваемое permission должно уже принадлежать actor. С edit-permissions можно выбирать любое существующее permission с guard_name = user.
project_id, creator_id, code и is_agent backend назначает сам.
Пример запроса
{
"name": "Order Assistant",
"login": "order-assistant",
"role_id": 14,
"branch_id": null,
"department_id": null,
"permissions": [
"view-orders",
"view-counterparties"
],
"agent_description": "Готовит сводки по заказам",
"is_banned": false
} Ответ
{
"agent": {
"id": 214,
"code": "12345678901",
"name": "Order Assistant",
"login": "order-assistant",
"role": {
"id": 14,
"name": "employee"
},
"branch": null,
"department": null,
"agent_description": "Готовит сводки по заказам",
"is_agent": true,
"is_banned": false,
"creator": {
"id": 7,
"avatar": "https://api.gigma.ru/storage/uploads/default.svg",
"first_name": "Артём",
"last_name": "Полищук",
"middle_name": null,
"name": "Полищук Артём"
},
"last_activity_at": null,
"permissions": [
{
"name": "view-orders"
},
{
"name": "view-counterparties"
}
],
"created_at": "2026-08-16T16:00:00.000000Z",
"updated_at": "2026-08-16T16:00:00.000000Z"
}
} AgentService::create() возвращает повторно загруженную через fresh() модель. Поэтому AgentResource получает HTTP 200, а не автоматический 201. Токен автоматически не создаётся: после создания его отдельно выпускает человек через POST /api/agents/{agent}/tokens.
Изменить агента
Изменение агента
- Метод
- PATCH
- URL
https://api.gigma.ru/api/agents/{agent}- Авторизация
- Bearer actor с edit-agents и правом управлять текущим агентом
- Headers
Accept: application/json; Content-Type: application/json; Authorization: Bearer {actor_token}- Успешный ответ
200
Параметры запроса
Все поля необязательны. Передавайте только изменяемые значения:
name(string, необязательно) — новое имя, от 1 до 255 символов;login(string, необязательно) — новый уникальный login, от 3 до 255 символов;role_id(integer, необязательно) — новая роль текущего проекта;branch_id(integer, необязательно) — филиал текущего проекта илиnullдля очистки;department_id(integer, необязательно) — отдел текущего проекта илиnullдля очистки;permissions(string[], необязательно) — полный новый набор permissions; пустой массив илиnullочищает права;agent_description(string, необязательно) — новое описание илиnull;is_banned(boolean, необязательно) — состояние блокировки.
Если поле отсутствует, его текущее значение сохраняется. До валидации нового payload policy проверяет текущие роль и permissions агента. Поэтому actor, который не вправе управлять текущим набором, получает 403 и не сможет использовать update как способ сначала понизить агента.
Пример запроса
{
"name": "Order Assistant v2",
"login": "order-assistant",
"role_id": 14,
"branch_id": null,
"department_id": null,
"permissions": [
"view-orders"
],
"agent_description": "Готовит только сводки заказов",
"is_banned": false
} Ответ
{
"agent": {
"id": 214,
"code": "12345678901",
"name": "Order Assistant v2",
"login": "order-assistant",
"role": {
"id": 14,
"name": "employee"
},
"branch": null,
"department": null,
"agent_description": "Готовит только сводки заказов",
"is_agent": true,
"is_banned": false,
"creator": {
"id": 7,
"avatar": "https://api.gigma.ru/storage/uploads/default.svg",
"first_name": "Артём",
"last_name": "Полищук",
"middle_name": null,
"name": "Полищук Артём"
},
"last_activity_at": null,
"permissions": [
{
"name": "view-orders"
}
],
"created_at": "2026-08-16T16:00:00.000000Z",
"updated_at": "2026-08-16T16:10:00.000000Z"
}
} Если is_banned становится true, backend сразу удаляет все Agent Token. Последующее включение через is_banned: false не восстанавливает прежние токены.
Отключить агента
Отключение агента
- Метод
- DELETE
- URL
https://api.gigma.ru/api/agents/{agent}- Авторизация
- Bearer actor с edit-agents и правом управлять текущим агентом
- Headers
Accept: application/json; Authorization: Bearer {actor_token}- Успешный ответ
200
Параметры пути
agent(integer, обязательно) — ID agent account из проекта actor.
Endpoint не удаляет строку пользователя. Он устанавливает is_banned = true, удаляет все personal access tokens агента и оставляет agent account в административном списке.
Пример запроса
DELETE /api/agents/214
Authorization: Bearer <actor_token>
Accept: application/json Ответ
{
"message": "Агент успешно отключён"
} Чтобы вернуть агента в работу:
PATCH /api/agents/{agent}с{"is_banned": false};- человек вызывает
POST /api/agents/{agent}/tokens; - новый Bearer безопасно передаётся MCP-серверу.
Токены агента: только human actor
UserPolicy::manageAgentTokens() первым делом проверяет is_agent. Agent actor получает 403 независимо от наличия manage-agent-tokens.
Список токенов агента
- Метод
- GET
- URL
https://api.gigma.ru/api/agents/{agent}/tokens- Авторизация
- Bearer человека с manage-agent-tokens и правом управлять текущим агентом
- Headers
Accept: application/json; Authorization: Bearer {user_token}- Успешный ответ
200
Параметры пути
agent(integer, обязательно) — ID agent account из проекта actor.
Пример запроса
GET /api/agents/214/tokens
Authorization: Bearer <user_token>
Accept: application/json Ответ
{
"agent_tokens": [
{
"id": 901,
"name": "production-mcp",
"created_at": "2026-08-16T16:00:00+00:00",
"last_used_at": null,
"expires_at": "2027-08-16T16:00:00+00:00"
}
],
"agentTokensCount": 1
} Поле value в списке отсутствует. Уже выпущенный Bearer нельзя прочитать повторно.
Выпуск Agent Token
- Метод
- POST
- URL
https://api.gigma.ru/api/agents/{agent}/tokens- Авторизация
- Bearer человека с manage-agent-tokens и правом управлять текущим агентом
- Headers
Accept: application/json; Content-Type: application/json; Authorization: Bearer {user_token}- Успешный ответ
201
Параметры запроса
name(string, обязательно) — назначение токена, от 3 до 100 символов;expires_at(date-time, необязательно) — дата истечения в будущем, не дальше одного года.
Если expires_at не передан, backend устанавливает срок один год. Отключённому агенту новый токен не выдаётся: 422.
Пример запроса
{
"name": "production-mcp",
"expires_at": "2027-02-16T16:00:00+00:00"
} Ответ
{
"agent_token": {
"id": 901,
"name": "production-mcp",
"created_at": "2026-08-16T16:00:00+00:00",
"last_used_at": null,
"expires_at": "2027-02-16T16:00:00+00:00",
"value": "<agent_bearer>"
}
} value показывается только один раз. Сохраните его в secret storage до завершения операции.
Созданный AgentTokenResource получает HTTP 201: underlying PersonalAccessToken передаётся в resource без повторного fresh(). Токен имеет Sanctum abilities *; рабочие права по-прежнему берутся из permissions agent account.
Отзыв Agent Token
- Метод
- DELETE
- URL
https://api.gigma.ru/api/agents/{agent}/tokens/{token}- Авторизация
- Bearer человека с manage-agent-tokens и правом управлять текущим агентом
- Headers
Accept: application/json; Authorization: Bearer {user_token}- Успешный ответ
200
Параметры пути
agent(integer, обязательно) — ID agent account из проекта actor;token(integer, обязательно) — ID токена изGET /api/agents/{agent}/tokens.
Backend ищет token только внутри выбранного агента. Чужой token ID возвращает 404.
Пример запроса
DELETE /api/agents/214/tokens/901
Authorization: Bearer <user_token>
Accept: application/json Ответ
{
"message": "Токен агента успешно отозван"
} После отзыва MCP-сервер должен прекратить использование секрета. Для ротации сначала выпустите новый токен и проверьте его через GET /api/user, затем отзовите старый.
Границы административного API
/api/users*не управляет agent accounts:UserPolicyотклоняет целевые модели сis_agent = true;- все agent и token endpoints проверяют принадлежность целевого агента проекту actor;
- наличие Agent Token само по себе не даёт agent permissions;
- текущий backend не запрещает agent actor list/create/update/disable, если ему фактически выданы соответствующие permissions;
- управление токенами agent actor запрещено policy независимо от выданного permission;
- разные токены одного агента не имеют разных business permissions: права меняются на самом agent account.