Публичный контракт: OpenAPI (YAML).
Эндпоинты /v1/* и OAuth /oauth/* проксируются с домена на бэкенд (см. Worker).
MCP не «подключается» самой нейросетью. Протокол MCP обслуживает только те клиенты, которые явно зарегистрировали сервер:
в Cursor это настройки MCP (URL https://…/mcp и заголовок Authorization: Bearer …), в Claude Desktop — свой конфиг.
Модель в чате получает только те инструменты, которые хост приложения передал в сессию; без записи в настройках Cursor инструментов mp_v1_* не существует для агента — это не баг Movie Planner.
Тот же доступ даёт обычный REST /v1 с тем же Bearer.
POST /oauth/authorize с client_id, redirect_uri, PKCE code_challenge (S256).POST /oauth/token с grant_type=authorization_code, code, code_verifier, client_id (+ client_secret если задан у клиента).Authorization: Bearer <access_token> (opaque OAuth).grant_type=refresh_token + refresh_token, client_id, client_secret.POST /oauth/revoke с JSON {"token":"..."} или тем же Bearer.POST /oauth/clients с заголовком X-OAuth-Admin-Secret = переменная окружения
OAUTH_CLIENT_REGISTRATION_SECRET. Тело: name, redirect_uris (строка с URI через запятую).
В ответе один раз приходит client_secret.
В POST /oauth/authorize передайте поле scope через пробел, например:
profile.read movies.read movies.write plans.read plans.write calendar.read groups.read groups.write tv.launch.
JWT и site session на это не смотрят. Если у OAuth-токена scope пустой — доступ к /v1 как раньше (полный).
Если scope указан — для каждого эндпоинта нужен свой scope:
profile.read — GET /v1/me, GET /v1/agent/eventsmovies.read — GET /v1/library/unwatchedmovies.write — POST /v1/moviesplans.read — GET /v1/plansplans.write — POST /v1/planscalendar.read — GET /v1/plans/<id>.ics; один из calendar.read / plans.read —
GET /v1/plans/<id>/google-calendar, GET …/calendar-linksgroups.read — GET /v1/groupsgroups.write — POST /v1/groupstv.launch — POST /v1/tv/launchЦепочка REST (тот же Bearer, что для /v1). Перед push в Google пользователь один раз привязывает аккаунт
в миниаппе или приложении (OAuth Google Calendar на стороне Movie Planner).
Билеты — только у планов plan_type: cinema. Если пользователь просит «добавить билет» / «в кино с билетом»,
сначала создайте кино-план, затем POST .../tickets. Адрес кинотеатра передавайте в POST /v1/plans (cinema_address / cinema_name); при отсутствии координат сервер может нормализовать адрес через геокодер (см. OpenAPI).
POST /v1/movies — добавить фильм в базу по kp_id (или найти существующий через библиотеку / поиск).POST /v1/plans — создать план: для кино plan_type: cinema, дата/время сеанса (ISO 8601), кинотеатр (имя/адрес, опционально lat/lon).POST /v1/plans/<id>/tickets — прикрепить билет (изображение в base64 по описанию API); тот же список, что GET .../tickets, и вложения в Google читают эти файлы.POST /v1/plans/<id>/calendar/google/push — создать событие в Google Календаре (описание с ссылкой на Кинопоиск, кинотеатр, Яндекс.Карты; тело запроса пустое).GET /v1/plans/<id>.ics — универсальный файл для Apple Calendar, Outlook и др.MCP (stdio или /mcp): те же шаги инструментами mp_v1_movies_add, mp_v1_plans_create,
mp_v1_plan_tickets_add, затем mp_v1_plan_google_calendar_push — билеты на диске прикрепятся к событию в Google (OAuth с правами Calendar + Drive).
См. moviebot/mcp_server/tools_core.py.
/mcp — MCP по HTTPS (Streamable HTTP): те же инструменты, что у локального stdio MCP; заголовок Authorization: Bearer … как для /v1.GET/PUT /api/site/agent-integration и /api/miniapp/agent-integration — URL webhook: сервер шлёт JSON при тех же событиях, что и мобильный push (подпись опционально: заголовок X-MP-Signature: sha256=…).POST /v1/plans/<id>/calendar/google/push — событие в Google Календарь (нужен OAuth Google у пользователя в Movie Planner + переменные GOOGLE_CALENDAR_* на сервере).GET /v1/health — проверка API.GET /v1/me, GET /v1/plans, POST /v1/plans, POST /v1/movies, GET /v1/library/unwatched, GET/POST /v1/groups, POST /v1/groups/<chat_id>/invite, POST /v1/tv/launchGET /v1/plans/<id>.ics (или с ?subscribe_token= из …/calendar-links); GET …/google-calendar, GET …/calendar-links.GET /v1/plans/<id>/tickets — список билетов; GET …/tickets/<n> — файл; ?format=base64 — JSON с data_base64 для ботов и ИИ.POST /v1/plans/<id>/tickets — загрузить билет в base64 (JPEG/PNG/GIF), сохраняется в план.docs/tool-schemas/openai_v1_me_plans.json,
docs/tool-schemas/anthropic_v1_tools.json,
docs/tool-schemas/generic_tools_v1.json,
заготовка Zapier/Make: docs/automation/zapier_make_http.json.
In-memory лимиты на процесс: API_RATE_LIMIT_ENABLED (по умолчанию 1),
API_RATE_LIMIT_RPM_V1, API_RATE_LIMIT_RPM_OAUTH.
Исключения без лимита: /v1/capabilities, /v1/health.
pip install -r requirements.txt -r requirements-dev.txt export MP_BASE_URL="https://…railway…" export MP_BEARER_TOKEN="…" python -m moviebot.mcp_server