User Support Snapshot

What the platform knows about one user’s problem: their account, their failed sign-ins, and their failed requests.

The MCPServer’s staff-only user_support_snapshot tool (UserSupportSnapshotTool) uses this module to answer help desk questions about one person, such as “my login isn’t working” or “my prompt says there was a system error”. support_snapshot() gathers, for one email address:

  • the account: whether a user has the address, whether that user is active, when they joined and last signed in, how they can sign in (with a password, or only with Google or GitHub), and the Smarter accounts that they belong to (account_state()).

  • their failed sign-ins of the last 72 hours, from the pod logs. The platform never logs the email address that someone typed: it logs a keyed hash of it, login_identity(), with the reason, e.g. reason=wrong_password. This module computes the same hash, and searches the logs for it (failed_sign_ins()).

  • their recent failed requests, from the journal, which records every api call and chat prompt with its status code: each one with a status of 400 or more, with its error’s class and description (failed_requests()).

  • hints: what the findings suggest that the user can do, e.g. reset their password, or sign in with Google (hints()).

The snapshot is for the platform’s staff. It may say that no user has an address, which a reply to the person who asked must never repeat, so that the help desk cannot be used to find out who has an account. See smarter.apps.mcpserver.services.helpdesk.replies.

Nothing is written. Each part that cannot be read, e.g. the logs in local development, where there is no log store, is named in SupportSnapshot.errors, and the other parts are still returned.

Note

Experimental. The MCPServer was designed and coded by Claude Code (Anthropic’s Claude Opus 5.5), with Lawrence McDaniel as co-author. It is experimental, and will be documented.

class smarter.apps.mcpserver.services.helpdesk.users.AccountState(username, is_active, date_joined, last_login, has_password, social_providers=<factory>, accounts=<factory>, subscription_active=None)[source]

Bases: object

The state of the user who has an email address, as user_support_snapshot reports it.

account_state() builds it from the user and their profiles.

__init__(username, is_active, date_joined, last_login, has_password, social_providers=<factory>, accounts=<factory>, subscription_active=None)
accounts: list[str]

The Smarter accounts that the user belongs to, e.g. ["Acme Corp (1234-5678-9012)"].

date_joined: datetime | None

When the user signed up, in UTC.

has_password: bool

Whether the user has a password.

A user who signed up with Google or GitHub has none.

is_active: bool

Whether the user may sign in.

An inactive user is refused, whatever their password.

last_login: datetime | None

When the user last signed in, in UTC, or None if they never did.

social_providers: list[str]

The social sign-ins linked to the user, e.g. ["google-oauth2", "github"].

subscription_active: bool | None = None

On a hosted platform, whether the user’s subscription is active, or None if the platform has no subscriptions.

username: str

The user’s username.

class smarter.apps.mcpserver.services.helpdesk.users.FailedRequest(created_at, thing, command, status_code, error_class='', description='')[source]

Bases: object

One of the user’s requests that failed, from the journal, e.g. a chat prompt that answered 500.

failed_requests() builds it from a SAMJournal row.

__init__(created_at, thing, command, status_code, error_class='', description='')
command: str

What it did, e.g. prompt, apply or deploy.

created_at: datetime | None

When the request was made, in UTC.

description: str = ''

The error’s description, from the response, cut at MAX_DESCRIPTION characters.

error_class: str = ''

The class of the error, e.g. SmarterValueError, from the response, or empty if it names none.

status_code: int

The HTTP status that it answered, e.g. 400 or 500.

thing: str

What the request was about, e.g. prompt, LLMClient or Plugin.

class smarter.apps.mcpserver.services.helpdesk.users.SupportSnapshot(email, users_found=0, account=None, failed_sign_ins=<factory>, last_failed_sign_in=None, failed_requests=<factory>, errors=<factory>)[source]

Bases: object

What the platform knows about one user’s problem, as user_support_snapshot reports it.

support_snapshot() builds it.

__init__(email, users_found=0, account=None, failed_sign_ins=<factory>, last_failed_sign_in=None, failed_requests=<factory>, errors=<factory>)
account: AccountState | None = None

The state of the user who has the address, or None if no user has it.

email: str

The email address that the snapshot is about, as the staff member gave it.

errors: list[str]

The parts that could not be read, and why, e.g. sign-ins: the log store is not available.

failed_requests: list[FailedRequest]

The user’s failed requests of the period, newest first.

failed_sign_ins: dict[str, int]

The failed sign-ins of the last 72 hours with the address, counted by reason, e.g. {"wrong_password": 3}.

last_failed_sign_in: datetime | None = None

When the latest failed sign-in happened, in UTC, or None if there was none.

users_found: int = 0

How many users have the address.

Normally 0 or 1.

smarter.apps.mcpserver.services.helpdesk.users.account_state(user)[source]

Describe a user’s account: whether they can sign in, and how.

Side effects: a query of the user’s social sign-ins, a query of their profiles, and, on a hosted platform, a call to the Account Manager for their subscription (see subscription_active()).

Parameters:

user (User) – The user.

Return type:

AccountState

Returns:

The account’s state.

smarter.apps.mcpserver.services.helpdesk.users.failed_requests(snapshot, user, days)[source]

Add the user’s failed requests of the last days to the snapshot, newest first.

A failed request is a journal row of the user with a status code of 400 or more: a chat prompt, or an api call, that answered an error.

Side effects: one query of the journal.

Parameters:
Return type:

None

smarter.apps.mcpserver.services.helpdesk.users.failed_sign_ins(snapshot)[source]

Add the failed sign-ins of the last 72 hours with the snapshot’s email address to the snapshot.

The logs hold the keyed hash of the address that was typed, login_identity(), never the address, so the search is for identity=<hash>. Each line names its reason, e.g. reason=wrong_password, which is counted. A log store that cannot be read is named in the snapshot’s errors.

Side effects: one query of the log store, through smarter.apps.infrastructure.services.infrastructure .logs.

Parameters:

snapshot (SupportSnapshot) – The snapshot, whose failed_sign_ins and last_failed_sign_in this fills.

Return type:

None

smarter.apps.mcpserver.services.helpdesk.users.hints(snapshot)[source]

Suggest, for staff, what the findings mean, and what the user can do.

These are for the staff member, not for the user: e.g. “no user has this address” must never be repeated to the person who asked (see smarter.apps.mcpserver.services.helpdesk.replies).

Parameters:

snapshot (SupportSnapshot) – The snapshot.

Return type:

list[str]

Returns:

One sentence per finding that suggests something, or an empty list.

smarter.apps.mcpserver.services.helpdesk.users.support_snapshot(email, days=7)[source]

Gather what the platform knows about one user’s problem.

The user is found by their email address, case insensitively. Their failed sign-ins are searched for even when no user has the address, because someone may be trying to sign in with an address that is mistyped, or not registered.

Side effects: queries of the users, profiles, social sign-ins and journal, one query of the log store, and, on a hosted platform, a call to the Account Manager. Nothing is written.

Parameters:
  • email (str) – The email address of the person who asked for help, as staff verified it.

  • days (int) – How far back to read the journal, in days.

Return type:

SupportSnapshot

Returns:

The snapshot. A part that cannot be read is named in its errors.