--- title: "1.39.4 — Signing-in view, themed bot check and delegated MCP execution" description: "Hosted sign-in now shows a clean \"Signing you in…\" view when people return from Google, Apple or GitHub, and the bot check is rebuilt on the hosted sign-in theme. MCP clients can ask for explicit consent to run ordinary tools directly, parent groups can let their own admins create sub-groups, and em…" date: "2026-10-21" tags: ["release"] canonical: "https://django-mojo.sitesmojo.com/changelog/1-39-4/" --- Hosted sign-in now shows a clean "Signing you in…" view when people return from Google, Apple or GitHub, and the bot check is rebuilt on the hosted sign-in theme. MCP clients can ask for explicit consent to run ordinary tools directly, parent groups can let their own admins create sub-groups, and email templates can brand the sender name. ### Added - MCP clients can request `scope=mcp mcp:execute` at the exact MCP resource. After a separate consent screen, eligible ordinary tools run within the person's live permissions. Plain `mcp` grants still propose changes for approval in Admin, and protected tools keep their per-action confirmation. - A parent group can opt in to letting the people who manage it as members create sub-groups directly under it, without a global group permission. System admins turn this on or off with `POST /api/group/` `{"allow_member_subgroups": true|false}`, and each change is logged as `group:subgroup_policy_changed`. - Database email templates can set `metadata.sender_name` to brand the sender display name. The verified mailbox address and reply-to are unchanged. ### Changed - The hosted bot check ("One quick check") is rebuilt on the hosted sign-in theme. It now uses the tenant's accent, light/dark appearance, logo, brand and custom CSS. A failure shows one plain sentence with Try again, asking for a review is its own step, and the reference appears once with a copy button. Bouncer decisions and the signals sent are unchanged. - Push registration keeps one registration per token. The newest authenticated registration takes the token, and the previous holder's row and delivery history are removed. A move between accounts is audited as `push:token_reassigned`. An empty or over-long token or device ID now returns 400, and a concurrent conflict returns 409 so the client retries. - After a successful hosted magic-link request, the form becomes an inbox confirmation with a one-minute resend wait, and duplicate sends are prevented. The wording still never reveals whether an account exists. - The hosted sign-in button for text-message codes now reads "SMS code". - Hosted static assets are versioned by content hash. A request whose `?v=` does not match the file is served `no-store`, so a half-rolled-out deploy cannot cache an old script for a day. ### Fixed - Returning from an OAuth provider no longer shows the username and password form while sign-in completes. A full-screen view shows progress, greets the person by name on success, and on failure offers Try again or another method. After 15 s it also offers Start over. The one-time code is removed from the URL after the single completion call, so a reload never resends it. - A signed-out visitor was treated as a request user in group membership checks, so some signed-out requests returned 500 instead of 401. - The hosted button hover colour now follows a tenant's custom accent instead of the default blue. - Health snapshots: roster hostnames come from the stored site names, cached worker samples last through the snapshot interval, and an unenrolled server's health cron no longer aborts maintenance. ### Security - The protected-metadata guard now treats a dotted `protected.` inside a JSON field as a change to `protected`, closing a way to write protected keys through a merge. ### Upgrade notes - If you never set `BOUNCER_CHALLENGE_LOGO_URL` or `BOUNCER_CHALLENGE_BRAND`, the bot check now shows the sign-in page's branding instead of the MojoVerify logo and "MOJO VERIFY". Set them to keep a separate bot-check brand. An explicitly set `BOUNCER_CHALLENGE_BRAND` now takes effect when the tenant has no title of its own. - A project that overrides the hosted sign-in or bot-check templates must update their `?v=` values to the new content hashes. Otherwise a day-cached old script can run against the new markup. - Existing MCP grants keep their scopes. To get delegated execution, the person reconnects and approves `mcp mcp:execute`.