Это API кота (amazing.cat) — поисковика по судебной практике, ведомственным актам и законам РФ для ИИ-агентов. Программы вызывают инструменты кота напрямую по MCP; чтобы искать через ИИ-агента, подключите в агент бесплатный MCP amazingcat («кот») по инструкции.
YOUR_AMAZINGCAT_TOKEN — ваш токен из формы; в Python и TypeScript он читается из переменной окружения AMAZINGCAT_TOKEN. Передавайте его в Authorization: Bearer. Держите токен на сервере, не вставляйте в URL или код браузера. ИИ-приложения с OAuth подключаются через браузерное подтверждение доступа.
Доступ
За 60 секунд
В сутки UTC
Бесплатный
60
300
Окно 60 секунд скользящее; сутки UTC начинаются в 00:00 UTC. Суточный лимит считается на ключ; со всех бесплатных ключей одной сети — тоже не больше 300 запросов за сутки. Один запрос может вернуть несколько документов.
При ограничении сервер сообщает Retry-After. tools/call может вернуть ограничение с HTTP 200: это не результат поиска. Проверяйте HTTP-статус, Retry-After и ошибки внутри ответа.
MCP и ответы
Адрес Streamable HTTP: https://mcp.amazingcat.net/mcp. Для POST передавайте Content-Type: application/json и Accept: application/json, text/event-stream. JSON-RPC возвращает result; ответ инструмента — в result.content[].text. Это строка с JSON, которую нужно разобрать второй раз.
При text/event-stream соберите строки data: одного события и разберите JSON события с id вашего запроса. notifications/initialized отправляется без id и получает HTTP 202. Имена и параметры инструментов перечислены в tools/list.
HTTP
Что делать
401
Проверьте Authorization: Bearer и токен.
404
Сессия неизвестна или закрыта: initialize заново, затем notifications/initialized.
429
Подождите Retry-After и повторите запрос.
200
Проверяйте Retry-After, JSON-RPC error и ошибки инструмента; HTTP 200 может содержать отказ по лимиту.
Сессия: что такое YOUR_MCP_SESSION_ID и где его взять
YOUR_MCP_SESSION_ID — значение заголовка Mcp-Session-Id в ответе на initialize. Это идентификатор подключения, а не токен доступа. Скопируйте его без имени заголовка и пробелов. Передавайте его вместе с Bearer во всех следующих вызовах этой сессии.
Последовательность ниже ищет Воздушный кодекс: initialize с выводом заголовков (-D -), сохранение идентификатора, notifications/initialized, затем tools/call.
Идентификатор читается через response.headers["Mcp-Session-Id"].
"""Python 3.10+: pip install requests; set AMAZINGCAT_TOKEN from the browser form."""
import json, os
import requests
http = requests.Session()
http.headers.update({"Authorization": "Bearer " + os.environ["AMAZINGCAT_TOKEN"],
"Accept": "application/json, text/event-stream"})
URL = "https://mcp.amazingcat.net/mcp"
def rpc(method, params=None, notification=False):
body = {"jsonrpc": "2.0", "method": method, "params": params or {}}
if not notification: body["id"] = method
with http.post(URL, json=body, stream=True, timeout=(15, 120)) as response:
response.raise_for_status()
if response.headers.get("Retry-After"): raise RuntimeError("Quota pause: " + response.headers["Retry-After"])
# initialize returns this response header; subsequent calls send it back.
if "Mcp-Session-Id" in response.headers:
http.headers["Mcp-Session-Id"] = response.headers["Mcp-Session-Id"]
if response.status_code == 202: return None
if "text/event-stream" in response.headers.get("Content-Type", ""):
response.encoding = "utf-8"; data = []; message = None
for line in response.iter_lines(decode_unicode=True):
if line.startswith("data:"): data.append(line[5:].lstrip())
elif not line and data:
event = json.loads("\n".join(data)); data = []
if event.get("id") == body.get("id"): message = event; break
if message is None: raise RuntimeError("No matching JSON-RPC response")
else: message = response.json()
if "error" in message: raise RuntimeError(message["error"])
return message["result"]
init = rpc("initialize", {"protocolVersion": "2025-06-18", "capabilities": {},
"clientInfo": {"name": "cat-session", "version": "1"}})
session_id = http.headers["Mcp-Session-Id"]
http.headers["MCP-Protocol-Version"] = init["protocolVersion"]
rpc("notifications/initialized", notification=True)
reply = rpc("tools/call", {"name": "law_find", "arguments": {"query": "Воздушный кодекс", "limit": 5}})
if reply.get("isError"): raise RuntimeError(reply)
law = json.loads(next(b["text"] for b in reply["content"] if b["type"] == "text"))
if law.get("error") or law.get("ошибка"): raise RuntimeError(law)
print(json.dumps({"session_received": bool(session_id), "candidates": len(law["candidates"]),
"first": law["candidates"][0]["name"]}, ensure_ascii=False))
http.close()
Фиксированный срок жизни сессии не объявлен. После закрытия сессии или перезапуска сервера нужен новый initialize. Неверный или уже закрытый идентификатор возвращает HTTP 404 с JSON-RPC error.code=-32600; проверенные сообщения: «Session not found» и «Not Found: Session has been terminated». Удалите старый Mcp-Session-Id, выполните initialize и notifications/initialized заново, затем повторите вызов.
Вызовы в сессии расходуют лимит запросов: в частности, notifications/initialized, tools/list и tools/call. initialize не расходует лимит. Число возвращённых актов не меняет стоимость одного вызова.
Клиенты
Все четыре клиента выполняют один первый шаг примера про сумму взыскания: находят Воздушный кодекс, чтобы затем прочитать статьи 103, 105, 107 и 108. limit=5 нужен для выбора кодекса по названию.
"""Small synchronous MCP client. pip install requests"""
import itertools
import json
import os
import random
import time
import requests
class MCP:
def __init__(self, token, endpoint="https://mcp.amazingcat.net/mcp", rpm=60):
self.endpoint = endpoint
self.rpm = min(60, rpm)
self.last = 0.0
self.ids = itertools.count(1)
self.http = requests.Session()
self.http.headers.update({
"Authorization": f"Bearer {token}",
"Accept": "application/json, text/event-stream",
"Content-Type": "application/json",
})
def rpc(self, method, params=None, notification=False):
payload = {"jsonrpc": "2.0", "method": method}
if params is not None:
payload["params"] = params
if not notification:
payload["id"] = next(self.ids)
for attempt in range(5):
time.sleep(max(0, 60 / self.rpm - (time.monotonic() - self.last)))
self.last = time.monotonic()
try:
with self.http.post(self.endpoint, json=payload, stream=True,
timeout=(15, 120)) as response:
# This API also signals tool-call quota exhaustion with HTTP 200.
wait = response.headers.get("Retry-After")
if wait or response.status_code in (429, 502, 503, 504):
delay = int(wait) if wait and wait.isdigit() else min(30, 2 ** attempt)
if attempt == 4:
raise RuntimeError(f"Retry budget exhausted; HTTP {response.status_code}")
# A daily limit must be scheduled for later, not kept in a retry loop.
if delay > 120:
raise RuntimeError(f"Quota exhausted; retry after {delay} seconds")
time.sleep(delay + random.uniform(0, 0.5))
continue
if response.status_code == 404 and method != "initialize" and self.http.headers.get("Mcp-Session-Id") and attempt < 4:
self.http.headers.pop("Mcp-Session-Id", None)
self.initialize()
continue
response.raise_for_status() # 401: replace/refresh credentials, do not retry.
sid = response.headers.get("Mcp-Session-Id")
if sid:
self.http.headers["Mcp-Session-Id"] = sid
if response.status_code == 202:
return None
if "text/event-stream" in response.headers.get("Content-Type", ""):
response.encoding = "utf-8"
data = []
message = None
for line in response.iter_lines(decode_unicode=True, delimiter="\n"):
line = line.rstrip("\r")
if line.startswith("data:"):
data.append(line[5:].lstrip(" "))
elif not line and data:
event = json.loads("\n".join(data))
data = []
if event.get("id") == payload.get("id"):
message = event
break
if message is None:
raise RuntimeError("SSE ended without the matching JSON-RPC response")
else:
message = response.json()
except (requests.ConnectionError, requests.Timeout):
if attempt == 4:
raise
time.sleep(min(30, 2 ** attempt) + random.uniform(0, 0.5))
continue
if "error" in message:
raise RuntimeError(message["error"])
return message["result"]
raise RuntimeError("Retry budget exhausted")
def initialize(self):
result = self.rpc("initialize", {
"protocolVersion": "2025-06-18", "capabilities": {},
"clientInfo": {"name": "amazingcat-api-example", "version": "1.0"},
})
self.http.headers["MCP-Protocol-Version"] = result["protocolVersion"]
self.rpc("notifications/initialized", notification=True)
return result
def call(self, name, arguments):
for attempt in range(5):
result = self.rpc("tools/call", {"name": name, "arguments": arguments})
if result.get("isError"):
raise RuntimeError(result.get("content"))
blocks = [b["text"] for b in result.get("content", []) if b.get("type") == "text"]
if not blocks:
raise RuntimeError("No text content; inspect the MCP result")
try:
value = json.loads(blocks[0])
except json.JSONDecodeError:
# Plain text can be a quota message, never interpret it as zero results.
raise RuntimeError(blocks[0]) from None
if isinstance(value, dict) and value.get("error") == "server_busy":
if attempt < 4:
time.sleep(value.get("retry_after_seconds", 5) + random.uniform(0, 0.5))
continue
if isinstance(value, dict) and (value.get("error") or value.get("ошибка")):
raise RuntimeError(value)
return value
raise RuntimeError("Server busy; retry later")
def close(self):
if "Mcp-Session-Id" in self.http.headers:
self.http.delete(self.endpoint, timeout=(15, 30)).close()
self.http.close()
def main():
client = MCP(os.environ["AMAZINGCAT_TOKEN"])
try:
client.initialize()
result = client.call("law_find", {"query": "Воздушный кодекс", "limit": 5})
print(json.dumps({"tool": "law_find", "candidates": len(result["candidates"]),
"first": result["candidates"][0]["name"]}, ensure_ascii=False))
finally:
client.close()
if __name__ == "__main__":
main()
"""Python 3.10+. pip install -r requirements.txt; set AMAZINGCAT_TOKEN."""
import asyncio
import json
import os
from datetime import timedelta
import httpx
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client
async def main():
# Keep the token on your server. Never embed it in a browser bundle.
async with httpx.AsyncClient(
headers={"Authorization": f"Bearer {os.environ['AMAZINGCAT_TOKEN']}"},
timeout=httpx.Timeout(120.0, connect=15.0),
) as http:
async with streamable_http_client(
"https://mcp.amazingcat.net/mcp", http_client=http
) as (read, write, session_id):
async with ClientSession(
read, write, read_timeout_seconds=timedelta(seconds=120)
) as session:
# initialize() also sends notifications/initialized.
# The transport handles session/version headers and JSON/SSE.
initialized = await session.initialize()
result = await session.call_tool(
"law_find", {"query": "Воздушный кодекс", "limit": 5}
)
if result.isError:
raise RuntimeError("Tool returned an MCP error; inspect it privately")
text = next((b.text for b in result.content if b.type == "text"), None)
# HTTP 200 does not by itself prove success: plain text can be a quota error.
if text is None:
raise RuntimeError("Tool returned no text content")
try:
data = json.loads(text)
except json.JSONDecodeError:
raise RuntimeError("Tool returned non-JSON text; check quota/errors") from None
if not isinstance(data, dict) or data.get("error") or data.get("ошибка"):
raise RuntimeError("Tool returned an application error")
# Print counters, avoiding personal names in the sample output.
print(json.dumps({"tool": "law_find", "candidates": len(data["candidates"]),
"first": data["candidates"][0]["name"]}, ensure_ascii=False))
# terminate_on_close=True (the default) sends DELETE for the MCP session.
if __name__ == "__main__":
asyncio.run(main())
Python SDK: скачайте sdk.py и requirements.txt, затем python -m pip install -r requirements.txt. TypeScript: скачайте client.ts и package.json, затем npm install и npm start. raw.py и session.py требуют requests; curl.sh — curl, awk и Python 3. requirements.txt · package.json.
Сквозные примеры
Человек ставит задачу ИИ-агенту. Агент читает описания инструментов, выделяет нормы, выбирает фильтры и получает идентификаторы из ответов кота. MCP принимает структурированные параметры tools/call. Ниже показаны выбранные поля ответов; многоточие означает сокращённый фрагмент текста.
Решение по номеру дела и суду
Подключите кота
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Попроси кота показать, что решил Омский областной суд по делу № 33-2696/2024, и дать ссылку на определение.
Агент готовит поиск
Нужен один конкретный акт, а не подборка. Агент сначала находит код Омского областного суда по названию, затем карточку по номеру. Для ответа о результате читает резолютивную часть; нормы материального права для этого поиска задавать не нужно.
Шаг 1 · oblsud_courts
Из справочника выбирается именно Омский областной суд: код 55OS0000. Поиск по фрагменту также возвращает названия других судов.
{
"act_id": 1963772,
"act_key": "55OS0000|doc|27016959|1",
"номер": "33-2696/2024",
"суд": "Омский областной суд (Омская область)",
"дата": "2024-05-06",
"часть": "resolution",
"текст": " Руководствуясь статьями 328, 329 Гражданского процессуального кодекса Российской Федерации, судебная коллегия\n ОПРЕДЕЛИЛА:\n решение Кировского районного суда г. Омска от 26 декабря 2023 года оставить без изменения, апелляционную жалобу К*******а А.В. - без удовлетворения.…\nМотивированное определение изготовлено в окончательной форме 14.06.2024.",
"источник": "https://oblsud.oms.sudrf.ru/modules.php?name=sud_delo&name_op=doc&number=27016959&delo_id=5&new=5&text_number=1&srv_num=1"
}
Агент отвечает человеку
Решение Кировского районного суда г. Омска от 26 декабря 2023 года оставлено без изменения, апелляционная жалоба — без удовлетворения. Номер дела — 33-2696/2024. Мотивированное определение изготовлено 14 июня 2024 года. Ссылка на документ — в поле «источник» ответа.
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Попроси кота найти иск Кузнецова Алексея Валерьевича к ПАО «Аэрофлот» в Кировском районном суде г. Омска, который рассматривала судья Бондаренко.
Агент готовит поиск
Агент выделяет истца, ответчика, суд и судью. Сначала находит код суда, затем party_id истца и judge_id судьи. raysud_search принимает эти фильтры и слова из текста; raysud_case открывает найденное дело по act_id. Для установления номера дела нормы права не нужны. ФИО в ответе сохраняются в маске.
Шаг 1 · raysud_courts
Агент выбирает Кировский районный суд г. Омска. Код 55RS0001 берётся из строки справочника.
{
"case_id": 28067732,
"номер": "2-249/2026 (2-5812/2025;) ~ М-4929/2025",
"судья": "Бондаренко Е.В.",
"стороны": "Отношения, связанные с защитой прав потребителей → О защите прав потребителей → - из договоров в сфере: → транспортных услуг ИСТЕЦ(ЗАЯВИТЕЛЬ): К******в А*****й В********ч ОТВЕТЧИК: ПАО Аэрофлот",
"результат": "Иск (заявление, жалоба) УДОВЛЕТВОРЕН ЧАСТИЧНО",
"ссылка_на_карточку": "https://kirovcourt--oms.sudrf.ru/modules.php?name=sud_delo&srv_num=1&name_op=case&case_id=330839593&case_uid=1a022b3b-f02a-45f3-aa4b-ecee9fab773c&delo_id=1540005&new="
}
Агент отвечает человеку
Найдено дело № 2-249/2026 (2-5812/2025;) ~ М-4929/2025. Судья — Бондаренко Е.В., ответчик — ПАО «Аэрофлот», истец — «К******в А*****й В********ч». Иск удовлетворён частично. Ссылка на карточку — в ответе кота. Совпадение маски имени само по себе не устанавливает личность.
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Сколько дел ПАО «Аэрофлот» проиграл в районных судах по искам об аннулировании бронирований Екатеринбург — Пхукет? Попроси кота сначала показать распределение исходов и проверить пять решений.
Агент готовит поиск
Агент понимает спор об аннулировании авиабронирования и сначала проверяет нормы: ВК РФ 103 и 105 — договор и билет; 107 — прекращение договора перевозчиком; 108 — отказ пассажира. Эти основания различаются. Также проверяет ГК РФ 310, 393, 786 и Закон о защите прав потребителей 13, 15. Затем ищет напрямую через raysud_search и группирует исходы через raysud_aggregate. Агрегация считает акты, а не уникальные дела; для числа проигранных дел агент сверяет стороны и резолютивные части, объединяя акты одного дела. Нормы помогают оценить спор, но не заменяют название перевозчика и маршрут в поиске.
Шаг 1 · law_find
До пяти кандидатов для выбора нужного кодекса; название из candidates[0].name идёт в следующий вызов.
Название кодекса — из law_find. Запрошены четыре статьи, необходимые для различения договора и двух оснований прекращения; размер окна рассчитан на эти статьи.
{
"articles": [
{
"article": "103",
"text": "Статья 103. Договор воздушной перевозки пассажира. Договор воздушной перевозки груза. Договор воздушной перевозки почты\n1. По договору воздушной перевозки пассажира перевозчик обязуется перевезти пассажира воздушного судна в пункт назначения с предоставлением ему места на воздушном судне, совершающем рейс, указанный в билете, а в случае сдачи пассажиром воздушного судна багажа …"
},
{
"article": "105",
"text": "Статья 105. Перевозочные документы\n1. К перевозочным документам относятся билет, багажная квитанция, грузовая накладная, почтовая накладная, иные документы, используемые при оказании услуг по воздушной перевозке пассажиров, багажа, груза, почты и предусмотренные нормативными правовыми актами федерального органа исполнительной власти, уполномоченного в области транспорта.\n2. Дог…"
},
{
"article": "107",
"text": "Статья 107. Прекращение по инициативе перевозчика действия договора воздушной перевозки пассажира, договора воздушной перевозки груза\n1. Перевозчик может в одностороннем порядке расторгнуть договор воздушной перевозки пассажира, договор воздушной перевозки груза в следующих случаях:\n1) нарушение пассажиром, грузовладельцем, грузоотправителем паспортных, таможенных, санитарных и…"
},
{
"article": "108",
"text": "Статья 108. Прекращение по инициативе пассажира действия договора воздушной перевозки пассажира\n1. В случае отказа пассажира от воздушной перевозки по причинам, не предусмотренным пунктом 2 настоящей статьи, возврат пассажиру провозной платы осуществляется в следующем порядке:\n1) если пассажиром заключен договор воздушной перевозки пассажира, предусматривающий условие о возврат…"
}
]
}
Шаг 3 · law_get_text
Статьи об одностороннем отказе, убытках и договоре перевозки пассажира. ГК — название кодекса, а не скрытый идентификатор.
{
"articles": [
{
"article": "310",
"text": "Статья 310. Недопустимость одностороннего отказа от исполнения обязательства\n1. Односторонний отказ от исполнения обязательства и одностороннее изменение его условий не допускаются, за исключением случаев, предусмотренных настоящим Кодексом, другими законами или иными правовыми актами.\n2. Одностороннее изменение условий обязательства, связанного с осуществлением всеми его сторо…"
},
{
"article": "393",
"text": "Статья 393. Обязанность должника возместить убытки\n1. Должник обязан возместить кредитору убытки, причиненные неисполнением или ненадлежащим исполнением обязательства.\nЕсли иное не установлено законом, использование кредитором иных способов защиты нарушенных прав, предусмотренных законом или договором, не лишает его права требовать от должника возмещения убытков, причиненных не…"
},
{
"article": "786",
"text": "Статья 786. Договор перевозки пассажира\n1. По договору перевозки пассажира перевозчик обязуется перевезти пассажира в пункт назначения, а в случае сдачи пассажиром багажа также доставить багаж в пункт назначения и выдать его управомоченному на получение багажа лицу; пассажир обязуется уплатить установленную плату за проезд, а при сдаче багажа и за провоз багажа.\n2. Заключение д…"
}
]
}
Шаг 4 · law_get_text
Проверяются ответственность и компенсация морального вреда; применимость к обстоятельствам оценивает агент.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "law_get_text",
"arguments": {
"act": "Закон о защите прав потребителей",
"articles": "13,15",
"max_chars": 13000
}
}
}
Ответ кота — выбранные поля:
{
"articles": [
{
"article": "13",
"text": "Статья 13. Ответственность изготовителя (исполнителя, продавца, уполномоченной организации или уполномоченного индивидуального предпринимателя, импортера , владельца агрегатора ) за нарушение прав потребителей\n(Наименование в редакции федеральных законов от 21.12.2004 № 171-ФЗ , от 31.07.2025 № 290-ФЗ )\n1. За нарушение прав потребителей изготовитель (исполнитель, продавец, упол…"
},
{
"article": "15",
"text": "Статья 15. Компенсация морального вреда\nМоральный вред, причиненный потребителю вследствие нарушения изготовителем (исполнителем, продавцом, уполномоченной организацией или уполномоченным индивидуальным предпринимателем, импортером , владельцем агрегатора ) прав потребителя, предусмотренных законами и правовыми актами Российской Федерации, регулирующими отношения в области защи…"
}
]
}
Шаг 5 · raysud_aggregate
Тот же текстовый запрос группируется по исходу. limit=10 ограничивает число групп. Единица здесь — акт: распределение ещё нельзя назвать числом проигранных дел.
Агент ищет решения с названием перевозчика, маршрутом и бронированием. Человек попросил начать с пяти решений, поэтому limit=5. Номера дел и act_id приходят в ответе.
Список act_ids составляется из пяти результатов. Резолютивные части показывают, кто ответчик, что присуждено и кому. Агент сравнивает пары «суд — номер дела», чтобы не считать несколько актов одного дела отдельными поражениями.
{
"показано": 5,
"акты": [
{
"act_id": 37900030,
"номер_дела": "2-2268/2024 ~ М-1224/2024",
"текст": "…Взыскать с публичного акционерного общества «Аэрофлот -Российские авиалинии» (ОГРН № ) в пользу К******а Д****а В*********а ( ДД.ММ.ГГГГ года рождения, СНИЛС № ) компенсацию морального вреда в размере 10 000 руб., штраф в размере 5 000 руб.\n Взыскать с публичного акционерного общества «Аэрофлот - Российские авиалинии» (ОГРН № ) в пользу С*******й М***и С*******ы ( ДД.ММ.ГГГГ года рождения, СНИЛС № ) компенсацию морального вреда в размере 10 000 руб., штраф в размере 5 000 руб.\n Взыскать с публичного акционерного общества «Аэрофлот - Российские авиалинии» (ОГРН № ) государственную пошлину в размере 600 руб.\n Возложить обязанность на К******а Д****а В*********а, С******у М***ю С*******у оплатить договоры воздушной перевозки пассажиров общей стоимостью 39 574 руб.\n В удовлетворении остальной части исковых требований отказать.\n Решение может быть обжаловано в апелляционном порядке в Пермский краевой суд в месячный срок со дня составления мо…"
},
{
"act_id": 19299446,
"номер_дела": "2-1455/2024 ~ М-923/2024",
"текст": "…Взыскать с Публичного акционерного общества «Аэрофлот» (ИНН 7712040126) в пользу З******й И. Д. (паспорт РФ [паспортные данные скрыты]) убытки в сумме 32 968,00 руб., неустойку за просрочку возмещения убытков в сумме 32 968,00 руб., компенсацию морального вреда в сумме 5 000,00 руб., штраф в размере 36 468,00 руб., а всего 107 404,00 руб.\n Взыскать с Публичного акционерного общества «Аэрофлот» (ИНН 7712040126) в пользу З*****а В. Л. (паспорт РФ [паспортные данные скрыты]) убытки в сумме 32 968,00 руб., неустойку за просрочку возмещения убытков в сумме 32 968,00 руб., компенсацию морального вреда в сумме 5 000,00 руб., штраф в размере 36 468,00 руб., а всего 107 404,00 руб.\n В удовлетворении остальной части исковых требований о взыскании морального вреда – отказать. \n Взыскать с Публичного акционерного общества «Аэрофлот» (ИНН 7712040126) в доход местного бюджета государственную пошлину в размере 4 137,00 руб.\n Решение может быть обжалов…"
},
{
"act_id": 21221376,
"номер_дела": "2-1284/2024 ~ М-375/2024",
"текст": "…Взыскать с Публичного акционерного общества «Аэрофлот – российские авиалинии» (ОГРН 1027700092661) в пользу Д***********й С.А. компенсацию морального вреда в размере 10 000 руб., штраф в сумме 5 000 руб.\n Взыскать с Публичного акционерного общества «Аэрофлот – Российские авиалинии» (ОГРН 1027700092661) в доход бюджета государственную пошлину в размере 600 руб.\n Возложить обязанность на Д**********у С.А. оплатить договор воздушной перевозки пассажиров общей стоимостью 29955 руб.\n В удовлетворении остальной части исковых требований Д***********й С.А. отказать.\n Решение в течение месяца со дня принятия в окончательной форме может быть обжаловано в апелляционном порядке в Пермский краевой суд через Кировский районный суд г.Перми.\n Судья Н.М. Швец \n Мотивированное решение составлено 01 августа 2024 года"
},
{
"act_id": 16201876,
"номер_дела": "2-1208/2024 ~ М-2945/2023",
"текст": "…Взыскать с Публичного акционерного общества «Аэрофлот - российские авиалинии» (ПАО «Аэрофлот») (ИНН 7712040126, ОГРН 1027700092661) в пользу Б****а ФИО12 …сумму убытков в размере 115 879 руб., неустойку, предусмотренную ч.5 ст. 28 Закона РФ от 07.02.1992 № 2300-1 «О защите прав потребителей», в размере 76 480 руб. 14 коп., компенсацию морального вреда в размере 5 000 руб., штраф в размере 98 679 руб. 57 коп., а также судебные расходы по направлению почтовых отправлений в размере 425 руб. 10 коп., итого 296 463 (двести девяносто шесть тысяч четыреста шестьдесят три) рубля 81 копейка. \n В удовлетворении остальной части заявленных требований истцам отказать.\n Взыскать с Публичного акционерного общества «Аэрофлот - российские авиалинии» (ПАО «Аэрофлот») (ИНН 7712040126, ОГРН 1027700092661) в пользу местного бюджета госпошлину в размере 5 347 (пять тысяч триста сорок семь) рублей 18 копеек.\n Решение может быть обжаловано в Свердловский областной суд в течение месяца со дня принятия решения суда в окончательной форме путем подачи апелляционной жалобы через Сысертский районный суд, вынесший реше…"
},
{
"act_id": 32036828,
"номер_дела": "2-1083/2024 (2-5747/2023;) ~ М-5033/2023",
"текст": "…Взыскать с публичного акционерного общества «Аэрофлот - российские авиалинии» в пользу ФИО3 , ФИО2 компенсацию морального вреда по 10 000 руб. в пользу каждого, штраф по 5000 руб. в пользу каждого.\n Взыскать с публичного акционерного общества «Аэрофлот - российские авиалинии» в доход местного бюджета государственную пошлину в размере 300 руб.\n Обязать ФИО3 , ФИО2 оплатить договоры воздушной перевозки стоимостью 18 625 руб. каждый.\n Решение суда может быть обжаловано в Пермский краевой суд через Ленинский районный суд г. Перми в течение месяца со дня принятия решения в окончательной форме.\n Копия верна\n Судья Ю.Н.Шпигарь\n Мотивированное решение изготовлено 07.03.2024"
}
],
"next_cursor": null
}
Агент отвечает человеку
Первый этап: текстовый запрос дал 201 акт. Из них 118 относятся к делам с частичным удовлетворением иска, 18 — с удовлетворением, 4 — с отказом, 61 — с иным исходом. В пяти прочитанных решениях требования к «Аэрофлоту» удовлетворены в части: это пять разных дел с взысканием в пользу истца. Число 136 (118 + 18) нельзя выдать за число проигранных дел: сначала нужно объединить акты по делу и проверить ответчика и содержание каждого решения. Следующая страница поиска начинается с next_cursor из ответа.
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Какая самая большая сумма взыскана в пользу одного истца по искам к ПАО «Аэрофлот» об аннулированных бронированиях Екатеринбург — Пхукет? Попроси кота начать со сравнения пяти районных решений.
Агент готовит поиск
Агент выделяет перевозчика, маршрут и сумму именно присуждённого взыскания. Проверяет те же нормы о договоре перевозки, прекращении договора, убытках и защите потребителя. raysud_aggregate группирует акты по исходу, но не вычисляет денежный максимум. Поэтому агент ищет пять решений через raysud_search и читает их резолютивные части через raysud_acts. Идентификаторы берёт из поиска; одному делу и одному истцу соответствует одна сравниваемая сумма.
Шаг 1 · law_find
До пяти кандидатов для выбора нужного кодекса; название из candidates[0].name идёт в следующий вызов.
Название кодекса — из law_find. Запрошены четыре статьи, необходимые для различения договора и двух оснований прекращения; размер окна рассчитан на эти статьи.
{
"articles": [
{
"article": "103",
"text": "Статья 103. Договор воздушной перевозки пассажира. Договор воздушной перевозки груза. Договор воздушной перевозки почты\n1. По договору воздушной перевозки пассажира перевозчик обязуется перевезти пассажира воздушного судна в пункт назначения с предоставлением ему места на воздушном судне, совершающем рейс, указанный в билете, а в случае сдачи пассажиром воздушного судна багажа …"
},
{
"article": "105",
"text": "Статья 105. Перевозочные документы\n1. К перевозочным документам относятся билет, багажная квитанция, грузовая накладная, почтовая накладная, иные документы, используемые при оказании услуг по воздушной перевозке пассажиров, багажа, груза, почты и предусмотренные нормативными правовыми актами федерального органа исполнительной власти, уполномоченного в области транспорта.\n2. Дог…"
},
{
"article": "107",
"text": "Статья 107. Прекращение по инициативе перевозчика действия договора воздушной перевозки пассажира, договора воздушной перевозки груза\n1. Перевозчик может в одностороннем порядке расторгнуть договор воздушной перевозки пассажира, договор воздушной перевозки груза в следующих случаях:\n1) нарушение пассажиром, грузовладельцем, грузоотправителем паспортных, таможенных, санитарных и…"
},
{
"article": "108",
"text": "Статья 108. Прекращение по инициативе пассажира действия договора воздушной перевозки пассажира\n1. В случае отказа пассажира от воздушной перевозки по причинам, не предусмотренным пунктом 2 настоящей статьи, возврат пассажиру провозной платы осуществляется в следующем порядке:\n1) если пассажиром заключен договор воздушной перевозки пассажира, предусматривающий условие о возврат…"
}
]
}
Шаг 3 · law_get_text
Статьи об одностороннем отказе, убытках и договоре перевозки пассажира. ГК — название кодекса, а не скрытый идентификатор.
{
"articles": [
{
"article": "310",
"text": "Статья 310. Недопустимость одностороннего отказа от исполнения обязательства\n1. Односторонний отказ от исполнения обязательства и одностороннее изменение его условий не допускаются, за исключением случаев, предусмотренных настоящим Кодексом, другими законами или иными правовыми актами.\n2. Одностороннее изменение условий обязательства, связанного с осуществлением всеми его сторо…"
},
{
"article": "393",
"text": "Статья 393. Обязанность должника возместить убытки\n1. Должник обязан возместить кредитору убытки, причиненные неисполнением или ненадлежащим исполнением обязательства.\nЕсли иное не установлено законом, использование кредитором иных способов защиты нарушенных прав, предусмотренных законом или договором, не лишает его права требовать от должника возмещения убытков, причиненных не…"
},
{
"article": "786",
"text": "Статья 786. Договор перевозки пассажира\n1. По договору перевозки пассажира перевозчик обязуется перевезти пассажира в пункт назначения, а в случае сдачи пассажиром багажа также доставить багаж в пункт назначения и выдать его управомоченному на получение багажа лицу; пассажир обязуется уплатить установленную плату за проезд, а при сдаче багажа и за провоз багажа.\n2. Заключение д…"
}
]
}
Шаг 4 · law_get_text
Проверяются ответственность и компенсация морального вреда; применимость к обстоятельствам оценивает агент.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "law_get_text",
"arguments": {
"act": "Закон о защите прав потребителей",
"articles": "13,15",
"max_chars": 13000
}
}
}
Ответ кота — выбранные поля:
{
"articles": [
{
"article": "13",
"text": "Статья 13. Ответственность изготовителя (исполнителя, продавца, уполномоченной организации или уполномоченного индивидуального предпринимателя, импортера , владельца агрегатора ) за нарушение прав потребителей\n(Наименование в редакции федеральных законов от 21.12.2004 № 171-ФЗ , от 31.07.2025 № 290-ФЗ )\n1. За нарушение прав потребителей изготовитель (исполнитель, продавец, упол…"
},
{
"article": "15",
"text": "Статья 15. Компенсация морального вреда\nМоральный вред, причиненный потребителю вследствие нарушения изготовителем (исполнителем, продавцом, уполномоченной организацией или уполномоченным индивидуальным предпринимателем, импортером , владельцем агрегатора ) прав потребителя, предусмотренных законами и правовыми актами Российской Федерации, регулирующими отношения в области защи…"
}
]
}
Шаг 5 · raysud_search
Агент ищет решения с названием перевозчика, маршрутом и бронированием. Человек попросил начать с пяти решений, поэтому limit=5. Номера дел и act_id приходят в ответе.
act_ids — из поискового ответа. Агент читает пять резолютивных частей и складывает суммы одному истцу: убытки, неустойку, компенсацию морального вреда, штраф и присуждённые расходы. Суммы, которые истец должен уплатить за билеты, и госпошлину в бюджет не включает.
{
"показано": 5,
"акты": [
{
"act_id": 37900030,
"номер_дела": "2-2268/2024 ~ М-1224/2024",
"текст": "…Взыскать с публичного акционерного общества «Аэрофлот -Российские авиалинии» (ОГРН № ) в пользу К******а Д****а В*********а ( ДД.ММ.ГГГГ года рождения, СНИЛС № ) компенсацию морального вреда в размере 10 000 руб., штраф в размере 5 000 руб.\n Взыскать с публичного акционерного общества «Аэрофлот - Российские авиалинии» (ОГРН № ) в пользу С*******й М***и С*******ы ( ДД.ММ.ГГГГ года рождения, СНИЛС № ) компенсацию морального вреда в размере 10 000 руб., штраф в размере 5 000 руб.\n Взыскать с публичного акционерного общества «Аэрофлот - Российские авиалинии» (ОГРН № ) государственную пошлину в размере 600 руб.\n Возложить обязанность на К******а Д****а В*********а, С******у М***ю С*******у оплатить договоры воздушной перевозки пассажиров общей стоимостью 39 574 руб.\n В удовлетворении остальной части исковых требований отказать.\n Решение может быть обжаловано в апелляционном порядке в Пермский краевой суд в месячный срок со дня составления мо…"
},
{
"act_id": 19299446,
"номер_дела": "2-1455/2024 ~ М-923/2024",
"текст": "…Взыскать с Публичного акционерного общества «Аэрофлот» (ИНН 7712040126) в пользу З******й И. Д. (паспорт РФ [паспортные данные скрыты]) убытки в сумме 32 968,00 руб., неустойку за просрочку возмещения убытков в сумме 32 968,00 руб., компенсацию морального вреда в сумме 5 000,00 руб., штраф в размере 36 468,00 руб., а всего 107 404,00 руб.\n Взыскать с Публичного акционерного общества «Аэрофлот» (ИНН 7712040126) в пользу З*****а В. Л. (паспорт РФ [паспортные данные скрыты]) убытки в сумме 32 968,00 руб., неустойку за просрочку возмещения убытков в сумме 32 968,00 руб., компенсацию морального вреда в сумме 5 000,00 руб., штраф в размере 36 468,00 руб., а всего 107 404,00 руб.\n В удовлетворении остальной части исковых требований о взыскании морального вреда – отказать. \n Взыскать с Публичного акционерного общества «Аэрофлот» (ИНН 7712040126) в доход местного бюджета государственную пошлину в размере 4 137,00 руб.\n Решение может быть обжалов…"
},
{
"act_id": 21221376,
"номер_дела": "2-1284/2024 ~ М-375/2024",
"текст": "…Взыскать с Публичного акционерного общества «Аэрофлот – российские авиалинии» (ОГРН 1027700092661) в пользу Д***********й С.А. компенсацию морального вреда в размере 10 000 руб., штраф в сумме 5 000 руб.\n Взыскать с Публичного акционерного общества «Аэрофлот – Российские авиалинии» (ОГРН 1027700092661) в доход бюджета государственную пошлину в размере 600 руб.\n Возложить обязанность на Д**********у С.А. оплатить договор воздушной перевозки пассажиров общей стоимостью 29955 руб.\n В удовлетворении остальной части исковых требований Д***********й С.А. отказать.\n Решение в течение месяца со дня принятия в окончательной форме может быть обжаловано в апелляционном порядке в Пермский краевой суд через Кировский районный суд г.Перми.\n Судья Н.М. Швец \n Мотивированное решение составлено 01 августа 2024 года"
},
{
"act_id": 16201876,
"номер_дела": "2-1208/2024 ~ М-2945/2023",
"текст": "…Взыскать с Публичного акционерного общества «Аэрофлот - российские авиалинии» (ПАО «Аэрофлот») (ИНН 7712040126, ОГРН 1027700092661) в пользу Б****а ФИО12 …сумму убытков в размере 115 879 руб., неустойку, предусмотренную ч.5 ст. 28 Закона РФ от 07.02.1992 № 2300-1 «О защите прав потребителей», в размере 76 480 руб. 14 коп., компенсацию морального вреда в размере 5 000 руб., штраф в размере 98 679 руб. 57 коп., а также судебные расходы по направлению почтовых отправлений в размере 425 руб. 10 коп., итого 296 463 (двести девяносто шесть тысяч четыреста шестьдесят три) рубля 81 копейка. \n В удовлетворении остальной части заявленных требований истцам отказать.\n Взыскать с Публичного акционерного общества «Аэрофлот - российские авиалинии» (ПАО «Аэрофлот») (ИНН 7712040126, ОГРН 1027700092661) в пользу местного бюджета госпошлину в размере 5 347 (пять тысяч триста сорок семь) рублей 18 копеек.\n Решение может быть обжаловано в Свердловский областной суд в течение месяца со дня принятия решения суда в окончательной форме путем подачи апелляционной жалобы через Сысертский районный суд, вынесший реше…"
},
{
"act_id": 32036828,
"номер_дела": "2-1083/2024 (2-5747/2023;) ~ М-5033/2023",
"текст": "…Взыскать с публичного акционерного общества «Аэрофлот - российские авиалинии» в пользу ФИО3 , ФИО2 компенсацию морального вреда по 10 000 руб. в пользу каждого, штраф по 5000 руб. в пользу каждого.\n Взыскать с публичного акционерного общества «Аэрофлот - российские авиалинии» в доход местного бюджета государственную пошлину в размере 300 руб.\n Обязать ФИО3 , ФИО2 оплатить договоры воздушной перевозки стоимостью 18 625 руб. каждый.\n Решение суда может быть обжаловано в Пермский краевой суд через Ленинский районный суд г. Перми в течение месяца со дня принятия решения в окончательной форме.\n Копия верна\n Судья Ю.Н.Шпигарь\n Мотивированное решение изготовлено 07.03.2024"
}
],
"next_cursor": null
}
Агент отвечает человеку
Среди пяти прочитанных решений наибольшее взыскание одному истцу — 296 463,81 руб., дело № 2-1208/2024 Сысертского районного суда: 115 879 руб. убытков + 76 480,14 руб. неустойки + 5 000 руб. морального вреда + 98 679,57 руб. штрафа + 425,10 руб. почтовых расходов. Госпошлина 5 347,18 руб. в бюджет в эту сумму не входит. Это результат сравнения пяти решений; чтобы назвать максимум по найденным делам, агент продолжает с next_cursor и сверяет последующее обжалование.
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Попроси кота найти практику Верховного Суда по статье 112 ГПК РФ: когда позднее получение судебного акта позволяет восстановить срок кассационной жалобы? Разбери одно подходящее определение.
Агент готовит поиск
Агент выделяет процессуальный срок, кассационную жалобу и норму 112 ГПК. Для подборки выбирает search_practice с фильтром article и Верховным Судом, просит до пяти карточек, затем читает одну карточку через get_case. Идентификатор берётся из поиска; вывод относится к обстоятельствам прочитанного определения.
Шаг 1 · search_practice
Пять карточек — рабочая подборка для поиска без указанного количества. Для разбора выбирается первая релевантная карточка из results. ВС — поддерживаемый код корпуса Верховного Суда.
{
"query": "восстановление срока кассационной жалобы позднее получение копии судебного акта",
"article": "112 ГПК",
"court_filter": "ВС",
"results": [
{
"doc_id": 1993400,
"court": "ВС",
"date": "2021-04-06",
"case_number": "56-КГ21-1-К9",
"position": "ВС РФ, руководствуясь ст. 46 Конституции РФ, ст. 112, 329, 376.1 ГПК РФ, разъяснениями постановления Пленума ВС РФ №29 и Обзора судебной практики №4 (2019), указал, что позднее получение мотивированного судебного акта (апелляционное определение направлено сторонам только 20.05.2020) при добросовестности заявителя и разумности сроков последующих действий является уважительной причиной для восстановления срока. Отказ в восстановлении противоречит п…",
"source_url": "https://www.vsrf.ru/lk/practice/stor_pdf/1993400"
},
{
"doc_id": 2065454,
"court": "ВС",
"date": "2021-11-30",
"case_number": "5-КГ21-138-К2",
"position": "ВС, сославшись на ст.46 Конституции РФ, ст.112, 329, 376.1, 67, 71 ГПК РФ и разъяснения (п.15 постановления Пленума ВС №17, Обзор судебной практики ВС №4 (2019)), указал, что позднее получение мотивированного судебного акта при добросовестности заявителя и разумности сроков может быть уважительной причиной. По делу резолютивная часть апелляционного определения вынесена 28.09.2020, дело поступило в суд первой инстанции 09.12.2020, истица получила …",
"source_url": "https://www.vsrf.ru/lk/practice/stor_pdf/2065454"
}
]
}
Ответ сокращён: ещё 3 элементов не показаны.
Шаг 2 · get_case
doc_id берётся из results[0]. Это определение № 56-КГ21-1-К9 от 06.04.2021.
{
"doc_id": 1993400,
"court": "ВС",
"case_number": "56-КГ21-1-К9",
"date": "2021-04-06",
"position": "ВС РФ, руководствуясь ст. 46 Конституции РФ, ст. 112, 329, 376.1 ГПК РФ, разъяснениями постановления Пленума ВС РФ №29 и Обзора судебной практики №4 (2019), указал, что позднее получение мотивированного судебного акта (апелляционное определение направлено сторонам только 20.05.2020) при добросовестности заявителя и разумности сроков последующих действий является уважительной причиной для восстановления срока. Отказ в восстановлении противоречит праву на судебную защиту.",
"result": "Определения Девятого КСОЮ от 30.07.2020 и от 08.09.2020 отменены. Восстановлен ООО СПК «ГлавМонтажОбъединение» пропущенный процессуальный срок подачи кассационной жалобы. Дело направлено в Девятый КСОЮ для выполнения действий по ст. 378 ГПК РФ.",
"source_url": "https://www.vsrf.ru/lk/practice/stor_pdf/1993400"
}
Агент отвечает человеку
В определении № 56-КГ21-1-К9 от 06.04.2021 Верховный Суд восстановил срок: апелляционное определение направили только 20.05.2020. Суд оценивал позднее получение акта, добросовестность заявителя и разумность срока последующих действий. Это обоснование для проверки обстоятельств, а не автоматическое восстановление срока в другом деле. Документ: https://www.vsrf.ru/lk/practice/stor_pdf/1993400.
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Попроси кота показать статью 219 КАС РФ в редакции на 1 января 2025 года: какой срок для оспаривания действий или бездействия судебного пристава?
Агент готовит поиск
Агент выделяет административный иск по КАС, а не производство по КоАП, статью 219 и дату 2025-01-01. Сначала находит кодекс; для исторического текста использует law_get_text(as_of), а не get_norm_text с текущей редакцией. В ответе проверяет дату редакции статьи.
Шаг 1 · law_find
Выбирается название КАС РФ из candidates[0].name. До пяти вариантов достаточно для распознавания кодекса.
{
"as_of": "2025-01-01",
"articles": [
{
"article": "219",
"as_of": "2025-01-01",
"redaction_date": "20240819",
"valid_until": "20250108",
"text": "…\n3. Административное исковое заявление о признании незаконными решений Федеральной службы судебных приставов, а также решений , действий (бездействия) судебного пристава-исполнителя может быть подано в суд в течение десяти дней со дня, когда гражданину, организации, иному лицу стало известно о нарушении их прав, свобод и законных интересов. (В редакции Федерального закона от 21.12.2021 № 417-ФЗ )\n4. Административное исковое заявление об оспаривании решений, действий (бездействия) исполнительного органа субъекта Российской Федерации, органа местного самоуправления по вопросам, связанным с согласованием места и времени проведения публичного мероприятия (собрания, митинга, демонстрации, шествия, пикетирования), а также с вынесенным этими органами предупреждением в отношении целей такого публичного мероприятия и формы его проведения, может быть подано в суд в течение десяти дней со дня, когда гражданину, организации, иному лицу стало известно о нарушении их прав, свобод и законных интересов. (В редакции Федерального закона от 08.08.2024 № 232-ФЗ )\n5. Пропуск установленного срока обращения в суд не является основанием для отказа в принят…"
}
]
}
Агент отвечает человеку
Часть 3 статьи 219 КАС РФ устанавливает для административного иска об оспаривании решений, действий или бездействия судебного пристава-исполнителя десять дней со дня, когда стало известно о нарушении прав, свобод и законных интересов. Дата запроса редакции — 01.01.2025. Для конкретного дела отдельно устанавливаются дата осведомлённости и основания восстановления пропущенного срока.
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Попроси кота вычитать фразу для жалобы по гражданскому делу: «Суд просто проигнорировал мои доводы, хотя они могли повлиять на результат дела». Дай три образца языка Верховного Суда и одну редакцию, сохранив смысл.
Агент готовит поиск
Агент отделяет вычитку от поиска правовой позиции. Проверяет допустимую длину через wording_stats, передаёт целое предложение в wording_review, выбирает гражданское производство и три образца. Образцы помогают заменить разговорные слова; факты, нормы и выводы чужого дела в жалобу не переносятся.
Шаг 1 · wording_stats
Лимиты относятся к вычитке текста: числу предложений и их длине.
sentences содержит текст человека; proceeding=civil задан видом жалобы; per_sentence=3 — числом образцов из просьбы. Частоты помогают оценить употребление слов, а не юридическую правильность.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "wording_review",
"arguments": {
"sentences": [
"Суд просто проигнорировал мои доводы, хотя они могли повлиять на результат дела."
],
"proceeding": "civil",
"per_sentence": 3,
"frequencies": true
}
}
}
Ответ кота — выбранные поля:
{
"status": "ok",
"results": [
{
"n": 1,
"sentence": "Суд просто проигнорировал мои доводы, хотя они могли повлиять на результат дела.",
"examples": [
{
"fragment": "Между тем эти доводы заявителя, имеющие существенное значение для правильного разрешения спора, суд оставил без внимания.",
"act": {
"court": "Верховный Суд Российской Федерации",
"act_number": "18-В10-43",
"act_date": "2010-07-13",
"source_url": "https://www.vsrf.ru/lk/practice/stor_pdf/320448"
}
},
{
"fragment": "Однако эти доводы сторон спора судом первой инстанции были проигнорированы.",
"act": {
"court": "Верховный Суд Российской Федерации",
"act_number": "4-КГ24-74-К1",
"act_date": "2025-01-20",
"source_url": "https://www.vsrf.ru/lk/practice/stor_pdf/2440836"
}
},
{
"fragment": "Данные обстоятельства имели существенное значение для правильного разрешения спора, но были проигнорированы судами.",
"act": {
"court": "Верховный Суд Российской Федерации",
"act_number": "18-КГ25-221-К4",
"act_date": "2025-07-18",
"source_url": "https://www.vsrf.ru/lk/practice/stor_pdf/2479318"
}
}
],
"words": [
{
"text": "дела",
"lemma": "деть",
"acts": 1
},
{
"text": "проигнорировал",
"lemma": "проигнорировать",
"acts": 145
},
{
"text": "повлиять",
"lemma": "повлиять",
"acts": 6667
},
{
"text": "результат",
"lemma": "результат",
"acts": 8792
},
{
"text": "могли",
"lemma": "мочь",
"acts": 14947
},
{
"text": "доводы",
"lemma": "довод",
"acts": 23589
},
{
"text": "дела",
"lemma": "дело",
"acts": 26381
}
]
}
]
}
Агент отвечает человеку
Вариант: «Суд оставил без внимания доводы заявителя, которые могли иметь значение для разрешения спора». Сохранены действующее лицо — суд — и предположение «могли»; утверждение о безусловной обязанности отменить решение не добавлено. Выше в ответе кота — три образца и ссылки на акты, из которых они взяты.
curl --fail-with-body 'https://mcp.amazingcat.net/mcp' \
-H 'Authorization: Bearer YOUR_AMAZINGCAT_TOKEN' \
-H 'Mcp-Session-Id: YOUR_MCP_SESSION_ID' \
-H 'MCP-Protocol-Version: 2025-06-18' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
--data-raw '{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "wording_review", "arguments": {"sentences": ["Суд просто проигнорировал мои доводы, хотя они могли повлиять на результат дела."], "proceeding": "civil", "per_sentence": 3, "frequencies": true}}}'
Вычитка текста
wording_review подбирает образцы языка из актов Верховного Суда и частоты выражений; агент убирает неудачные формулировки и предлагает редакцию. wording_stats сообщает допустимые размеры текста.
Кот возвращает QR-код, который удобно вставить в сноску внизу страницы PDF или DOCX. Камера телефона открывает документ по ссылке, записанной в QR.
Карточки практики Верховного Суда Российской Федерации, Конституционного Суда РФ, Пленума Верховного Суда, исторического корпуса Высшего Арбитражного Суда РФ и обзоров Верховного Суда содержат source_url и объект qr. Их возвращают find_term, search_practice, find_by_norm и get_case.
Поле
Значение
source_url
Адрес документа на сайте суда: PDF или страница с документом.
qr.qr_image_url
Адрес PNG; картинку можно скачать без Bearer-токена.
qr.qr_encodes
URL, записанный внутри QR. В этом примере равен source_url.
qr.qr_note
Краткая подпись к QR.
find_term и search_practice возвращают карточки в results[i]; find_by_norm — в corpora[corpus]["документы"][i], где corpus — ключ группы корпуса; get_case — в карточке верхнего уровня. Другие семейства читаются по своим схемам: адрес PNG берите именно из qr.qr_image_url.
Подключите кота
Подключите в ваш агент бесплатный MCP amazingcat («кот») по инструкции. Без подключения агент не сможет обратиться к коту.
Человек пишет агенту
Попроси кота найти практику Верховного Суда по судебным расходам и дать QR на одно подходящее определение для сноски в PDF.
Агент готовит поиск
Агент ищет подборку, а не один заранее известный акт: запрашивает пять карточек. Затем выбирает одну карточку, читает её по doc_id из ответа и берёт ссылку и PNG из полей source_url и qr.
Шаг 1 · find_term
Пять карточек для подбора по теме; doc_id первого подходящего определения находится в results[0].
Для сноски агент скачивает PNG из qr.qr_image_url и вставляет его вместе с подписью «Источник: определение Верховного Суда Российской Федерации», датой, номером и ссылкой source_url. Камера открывает адрес qr.qr_encodes.
После разбора ответа берите card["source_url"] для подписи и ссылки, card["qr"]["qr_image_url"] для картинки. Скачайте PNG и вложите его в файл.
Сноска в PDF · HTML для WeasyPrint
Рекомендуемый размер — 24 × 24 мм, с белым полем 2 мм вокруг. Сохраняйте квадратную форму картинки. В этом примере исходный PNG — 148 × 148 px; размер в пикселях зависит от длины URL.
<!doctype html><html lang="ru"><meta charset="utf-8">
<title>QR в сноске</title>
<style>
@page { size: A4; margin: 22mm 25mm;
@footnote { border-top: .25pt solid; padding-top: 3mm; } }
body { font: 12pt/1.5 "DejaVu Sans", sans-serif; }
.note { float: footnote; font-size: 8pt; line-height: 1.3; }
.note::footnote-call { content: counter(footnote); vertical-align: super; font-size: 8pt; }
.note::footnote-marker { content: counter(footnote) ". "; }
.note img { width: 24mm; height: 24mm; padding: 2mm; background: white;
vertical-align: top; margin-right: 3mm; }
.source { display: inline-block; width: 115mm; vertical-align: top; overflow-wrap: anywhere; }
</style>
<h1>Ссылка на судебный акт</h1>
<p>Судебный акт указан в сноске<span class="note"><img src="qr.png" alt="QR на источник">
<span class="source">Источник: Определение Верховного Суда Российской Федерации от 02.10.2026 № 305-ЭС26-10137. <a href="https://www.vsrf.ru/lk/practice/stor_pdf_ec/2571526">https://www.vsrf.ru/lk/practice/stor_pdf_ec/2571526</a></span></span>.</p>
<p>QR-код внизу страницы содержит прямую ссылку на документ на сайте суда.</p>
</html>
float: footnote переносит сноску к низу страницы с её номером. Локальный qr.png попадает внутрь PDF; ссылка в подписи остаётся кликабельной.
Сноска в DOCX
В Word выберите «Ссылки → Вставить сноску». Вставьте скачанный PNG в текст сноски, задайте ширину и высоту 2,4 см, оставьте белое поле и добавьте подпись «Источник: …» со ссылкой на документ.
У kas_search court=1…9 — номер кассационного суда; court=0 — поиск без выбора конкретного суда. У oblsud_* и raysud_* court — код ГАС из *_courts. Для дела задавайте и суд, и номер: номер сам по себе не уникален между судами.
kind=civil — гражданское производство, admin — административный иск по КАС, koap — дело об административном правонарушении. Параметры разных семейств проверяйте по inputSchema. Обозначение «session» внутри аргументов некоторых инструментов не заменяет заголовок Mcp-Session-Id.
query — тематическая формулировка; text и phrase задают текстовый поиск, norms — ссылки на нормы. У kas_search и oblsud_search следующий cursor берётся из page.next_cursor; у raysud_search — из next_cursor на верхнем уровне ответа. Повторяйте запрос с теми же фильтрами и новым cursor. Для law_get_text используйте pagination.next_request, если ответ сообщает truncated.
Имена участников в выдаче кота маскируются; маску сохраняйте как получена. Имена судей могут оставаться открытыми. Источник акта берите из его ответа; QR не следует предполагать у каждого семейства.
Пакетная интеграция
Выгрузить в CSV определения Седьмого кассационного суда общей юрисдикции с упоминанием статьи 112 ГПК РФ за 2023–2025 годы.
batch.py · Python 3.10+, пакет requests. Один процесс; запустите в отдельной папке.
"""Python 3.10+: pip install requests; export AMAZINGCAT_TOKEN='your browser-issued token'."""
import csv, json, os, time
from datetime import datetime, timezone
from pathlib import Path
import requests
URL = "https://mcp.amazingcat.net/mcp"
# Seventh cassation court, civil acts mentioning Article 112 GPK, dated 2023–2025.
QUERY = {"court": 7, "kind": "civil", "norms": "ГПК 112", "year_from": 2023,
"year_to": 2025, "limit": 10, "detail": "brief"}
state_path, csv_path = Path("kas-export.state.json"), Path("kas-export.csv")
state = json.loads(state_path.read_text()) if state_path.exists() else {"cursor": 0, "calls": 0}
if time.time() < state.get("retry_not_before", 0):
raise SystemExit("Quota pause; resume in " + str(int(state["retry_not_before"] - time.time()) + 1) + " seconds")
http = requests.Session()
http.headers.update({"Authorization": "Bearer " + os.environ["AMAZINGCAT_TOKEN"],
"Accept": "application/json, text/event-stream"})
last = 0.0
def save():
tmp = state_path.with_suffix(".tmp")
tmp.write_text(json.dumps(state)); tmp.replace(state_path)
def rpc(method, params=None):
global last
body = {"jsonrpc": "2.0", "method": method, "params": params or {}}
if method != "notifications/initialized": body["id"] = method
for attempt in range(5):
day = datetime.now(timezone.utc).date().isoformat()
if state.get("day") != day: state.update(day=day, calls=0)
# Count every attempt except initialize; include the initialized notification.
if method != "initialize":
if state["calls"] >= 300: raise SystemExit("300 requests reached; resume on the next UTC day")
state["calls"] += 1; save()
time.sleep(max(0, 1.05 - (time.monotonic() - last))); last = time.monotonic()
with http.post(URL, json=body, stream=True, timeout=(15, 120)) as r:
# The server can signal a quota delay with HTTP 429 or HTTP 200 + Retry-After.
if r.status_code == 429 or r.headers.get("Retry-After"):
delay = int(r.headers.get("Retry-After", "60"))
state["retry_not_before"] = time.time() + delay; save()
if delay > 60: raise SystemExit("Quota pause; checkpoint saved. Resume after Retry-After: " + str(delay))
time.sleep(delay); continue
if r.status_code == 404: raise SystemExit("Session lost; run the script again to initialize and resume")
r.raise_for_status()
if r.headers.get("Mcp-Session-Id"): http.headers["Mcp-Session-Id"] = r.headers["Mcp-Session-Id"]
if r.status_code == 202: return None
if "text/event-stream" in r.headers.get("Content-Type", ""):
r.encoding = "utf-8"; data = []; reply = None
for line in r.iter_lines(decode_unicode=True):
if line.startswith("data:"): data.append(line[5:].lstrip())
elif not line and data:
event = json.loads("\n".join(data)); data = []
if event.get("id") == body.get("id"): reply = event; break
if reply is None: raise RuntimeError("SSE ended without a response")
else: reply = r.json()
if "error" in reply: raise RuntimeError(reply["error"])
return reply["result"]
raise SystemExit("Retry limit reached; checkpoint saved")
if state.get("done"): raise SystemExit("Export already completed: " + str(csv_path))
if state.get("cursor", 0) and not csv_path.exists(): raise SystemExit("CSV missing; restore it before resuming")
init = rpc("initialize", {"protocolVersion": "2025-06-18", "capabilities": {},
"clientInfo": {"name": "cat-csv", "version": "1"}})
http.headers["MCP-Protocol-Version"] = init["protocolVersion"]
rpc("notifications/initialized")
seen = {row["act_id"] for row in csv.DictReader(csv_path.open(encoding="utf-8"))} if csv_path.exists() else set()
with csv_path.open("a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["act_id", "суд", "дата", "номер_определения", "класс_исхода"])
if f.tell() == 0: writer.writeheader()
pages = 0
while True:
result = rpc("tools/call", {"name": "kas_search", "arguments": {**QUERY, "cursor": state["cursor"]}})
if result.get("isError"): raise RuntimeError(result)
data = json.loads(next(b["text"] for b in result["content"] if b["type"] == "text"))
if data.get("error") or data.get("ошибка") or data.get("частично"): raise RuntimeError("Search failed; cursor unchanged")
for row in data["результаты"]:
if str(row["act_id"]) not in seen:
writer.writerow({k: row.get(k, "") for k in writer.fieldnames}); seen.add(str(row["act_id"]))
f.flush(); os.fsync(f.fileno()) # Save rows before advancing the checkpoint; deduplicate on resume.
cursor = data["page"]["next_cursor"]
if cursor is not None and cursor <= state["cursor"]: raise RuntimeError("Cursor did not advance; checkpoint unchanged")
state.update(cursor=cursor or 0, done=cursor is None); save()
pages += 1; print(f"rows={len(seen)} found={data['найдено']} next_cursor={cursor}")
if state["done"] or pages == int(os.environ.get("AMAZINGCAT_MAX_PAGES", "0")): break
Малый прогон: две страницы по десять актов. AMAZINGCAT_MAX_PAGES=2 останавливает демонстрацию после двух страниц; без этой переменной цикл идёт до конца выдачи или паузы по лимиту. Повторный запуск продолжает с сохранённого cursor.
Считается запрос, а не строка CSV; уведомление initialized тоже расходует лимит.
При 429 или Retry-After повторяйте ту же страницу после указанной паузы; долгую паузу скрипт сохраняет для последующего запуска.
kas-export.state.json хранит cursor и счёт запросов скрипта за день UTC; kas-export.csv — строки. Сохраняйте оба файла и запускайте с теми же фильтрами.
Скрипт выдерживает паузу 1,05 с и останавливается после 300 учитываемых попыток за сутки UTC. Другие обращения с тем же токеном тоже расходуют общую квоту; ответ сервера имеет приоритет.