Skip to main content
Glama

start_2fa

Start a two-factor authentication challenge for a sensitive operation. Sends a verification code via the chosen channel. Returns a session ID, and for messaging channels: deep_link, qr_code (base64 PNG), and qr_text (UTF-8 text QR for terminal display).

Agent usage — full 2FA flow: (1) Call start_2fa with the appropriate action_type and channel. (2) Present the challenge, and do NOT announce a message the server did not send: email is the ONLY channel it dispatches on. On telegram/whatsapp the user opens deep_link and sends the message themselves; on sms they send sms_message to a number from sms_dids; the response's own instructions field says which. On email, a 200 carrying requires_email_selection: true and available_emails means nothing was sent and no session exists — ask which address and call again with email_id. For telegram/whatsapp, pass deep_link to render_auth_link; for sms, show sms_message. Never hand qr_text to a link renderer — it is the link already rendered as QR art, so print it verbatim inside a fenced code block only when a real terminal needs the QR. (3) Poll get_2fa_status with the returned session_id until status is "verified" (the user enters the code on their device) or "expired". (4) If verified, proceed with the protected operation (e.g. create_api_key). If expired, inform the user and offer to restart. Typical channels: "telegram" or "email". For email, the user may receive a magic link instead of a code — the backend handles this automatically.

The user does not see tool results — most clients fold them away, render_auth_link's output included. Before you wait or poll, put what the user must act on into your own reply text: the link itself (not a sentence announcing it), the SMS text and number, or a note to check their inbox.

ACCESS: needs a Proof account. Authenticate this client (Claude Code: /mcp → Authenticate), or sign in with start_login — a session opens this tool — then call this tool again.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "action_type": "<action_type>",
      "channel": "<channel>"
    },
    "name": "start_2fa"
  }
}

Input Schema

NameRequiredDescriptionDefault
channelYesChannel to receive the verification code
targetsNoThe ids the step-up is FOR — the grant is bound to exactly these and refused for any other request (`reason: target_mismatch`). revocation_bulk: the asset id you will pass to revoke_asset (one code per asset); phone_remove / email_remove: the phone or email record id; domain_remove: the domain id; profile_delete: the sub-account id; account_delete: your own user id (get_current_user). Leave out for the other action types.
email_idNoSpecific email ID for email channel (optional)
phone_idNoOptional: specific UserPhone id for phone-channel 2FA
single_useNoWhether the grant is consumed on first use. Server forces true for destructive action types. Defaults to true.
action_typeYesThe sensitive action requiring 2FA: any action type the API documents
ttl_secondsNoRequested grant lifetime in seconds. Server caps to 300s for destructive action types, 86400s for configuration scopes. Defaults to 300 if omitted.

Output Schema

NameRequiredDescriptionDefault
emailNoThe address the code went to, masked (`email` only)
statusNo
channelNo
messageNo
qr_codeNoBase64-encoded PNG QR code for `deep_link`
qr_textNoUTF-8 text QR for `deep_link`, for terminal/agent rendering
sms_codeNoThe short code the person texts (`sms` only)
sms_didsNoOur SMS numbers, one entry per region and always all three. A region with no number configured carries an empty `did` and no QR code.
deep_linkNoOpens Telegram or WhatsApp with what the person sends (`telegram`, `whatsapp`)
email_sentNo`true` when the code was emailed (`email` only)
expires_atNo
session_idNo
sms_messageNoThe message to send (`sms` only)
instructionsNoOne line telling the person what to do
available_emailsNoThe addresses the code may go to; call again with one of their ids as `email_id`
requires_email_selectionNoAlways `true`: no session was started, pick an address and start again
second_method_recommendedNoPresent (true) when the step-up uses the channel the account signed in with, because the account has no other; adding a second channel is recommended

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedInput schema / properties / action_type / description
      Previous value: -"The sensitive action requiring 2FA"New value: +"The sensitive action requiring 2FA: any action type the API documents"
    • changedInput schema / properties / action_type / enum
      Previous value: -[
      -  "api_key_view",
      -  "api_key_create",
      -  "api_key_revoke",
      -  "api_key_regenerate",
      -  "phone_add",
      -  "phone_remove",
      -  "email_add",
      -  "email_remove",
      -  "account_delete",
      -  "revocation_bulk",
      -  "domain_remove",
      -  "profile_delete",
      -  "phone_primary",
      -  "email_primary"
      -]New value: +[
      +  "api_key_view",
      +  "api_key_create",
      +  "api_key_revoke",
      +  "api_key_regenerate",
      +  "phone_add",
      +  "phone_remove",
      +  "phone_primary",
      +  "email_add",
      +  "email_remove",
      +  "email_primary",
      +  "account_delete",
      +  "master_key_change",
      +  "hitl_key_rotate",
      +  "revocation_bulk",
      +  "settings_write",
      +  "profile_update",
      +  "templates_write",
      +  "webhook_write",
      +  "delegation_lifecycle",
      +  "company_update",
      +  "domain_remove",
      +  "profile_delete",
      +  "account_delete_cancel",
      +  "plan_change",
      +  "auto_top_up_change"
      +]
    • addedInput schema / properties / phone_id
      Added value: +{
      +  "description": "Optional: specific UserPhone id for phone-channel 2FA",
      +  "type": "string"
      +}
    • addedInput schema / properties / single_use
      Added value: +{
      +  "description": "Whether the grant is consumed on first use. Server forces true for destructive action types. Defaults to true.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / targets / description
      Previous value: -"The ids the step-up is FOR — the grant is bound to exactly these and refused for any other request (`reason: target_mismatch`). revocation_bulk: the asset id you will pass to revoke_asset (one code per asset); phone_remove / email_remove: the phone or email record id; domain_remove: the domain id; profile_delete: the project id; account_delete: your own user id (get_current_user). Leave out for the other action types."New value: +"The ids the step-up is FOR — the grant is bound to exactly these and refused for any other request (`reason: target_mismatch`). revocation_bulk: the asset id you will pass to revoke_asset (one code per asset); phone_remove / email_remove: the phone or email record id; domain_remove: the domain id; profile_delete: the sub-account id; account_delete: your own user id (get_current_user). Leave out for the other action types."
    • addedInput schema / properties / ttl_seconds
      Added value: +{
      +  "description": "Requested grant lifetime in seconds. Server caps to 300s for destructive action types, 86400s for configuration scopes. Defaults to 300 if omitted.",
      +  "maximum": 86400,
      +  "minimum": 60,
      +  "type": "integer"
      +}
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": {},
      +  "properties": {
      +    "available_emails": {
      +      "description": "The addresses the code may go to; call again with one of their ids as `email_id`"
      +    },
      +    "channel": {},
      +    "deep_link": {
      +      "description": "Opens Telegram or WhatsApp with what the person sends (`telegram`, `whatsapp`)"
      +    },
      +    "email": {
      +      "description": "The address the code went to, masked (`email` only)"
      +    },
      +    "email_sent": {
      +      "description": "`true` when the code was emailed (`email` only)"
      +    },
      +    "expires_at": {},
      +    "instructions": {
      +      "description": "One line telling the person what to do"
      +    },
      +    "message": {},
      +    "qr_code": {
      +      "description": "Base64-encoded PNG QR code for `deep_link`"
      +    },
      +    "qr_text": {
      +      "description": "UTF-8 text QR for `deep_link`, for terminal/agent rendering"
      +    },
      +    "requires_email_selection": {
      +      "description": "Always `true`: no session was started, pick an address and start again"
      +    },
      +    "second_method_recommended": {
      +      "description": "Present (true) when the step-up uses the channel the account signed in with, because the account has no other; adding a second channel is recommended"
      +    },
      +    "session_id": {},
      +    "sms_code": {
      +      "description": "The short code the person texts (`sms` only)"
      +    },
      +    "sms_dids": {
      +      "description": "Our SMS numbers, one entry per region and always all three. A region with no number configured carries an empty `did` and no QR code."
      +    },
      +    "sms_message": {
      +      "description": "The message to send (`sms` only)"
      +    },
      +    "status": {}
      +  },
      +  "type": "object"
      +}
  2. Changed1 schema field changed
    • removedInput schema / additionalProperties
      Removed value: -false
  3. Changed2 schema fields changed
    • changedInput schema / properties / action_type / enum
      Previous value: -[
      -  "api_key_view",
      -  "api_key_create",
      -  "api_key_revoke",
      -  "api_key_regenerate",
      -  "phone_add",
      -  "phone_remove",
      -  "email_add",
      -  "email_remove",
      -  "account_delete"
      -]New value: +[
      +  "api_key_view",
      +  "api_key_create",
      +  "api_key_revoke",
      +  "api_key_regenerate",
      +  "phone_add",
      +  "phone_remove",
      +  "email_add",
      +  "email_remove",
      +  "account_delete",
      +  "revocation_bulk",
      +  "domain_remove",
      +  "profile_delete",
      +  "phone_primary",
      +  "email_primary"
      +]
    • addedInput schema / properties / targets
      Added value: +{
      +  "description": "The ids the step-up is FOR — the grant is bound to exactly these and refused for any other request (`reason: target_mismatch`). revocation_bulk: the asset id you will pass to revoke_asset (one code per asset); phone_remove / email_remove: the phone or email record id; domain_remove: the domain id; profile_delete: the project id; account_delete: your own user id (get_current_user). Leave out for the other action types.",
      +  "items": {
      +    "maxLength": 256,
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 25,
      +  "minItems": 1,
      +  "type": "array"
      +}
  4. First observed

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it reveals that email is the ONLY channel the server dispatches on, that a 200 with requires_email_selection means nothing was sent and no session exists, and that clients fold away tool results so the agent must restate links/SMS text in its own reply. It also states the auth prerequisite (Proof account, /mcp authenticate or start_login).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and return shape, then the flow — a sensible ordering for a multi-step tool. It is long, but most of the length is load-bearing procedural detail; a few passages (the qr_text warning, the repeated render_auth_link guidance) restate the same constraint more than once.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter, multi-step, auth-gated tool this covers the full lifecycle: prerequisites, per-channel behavior, session polling, failure branches, and a caveat about result visibility that would otherwise cause silent task failure. Return fields are partially described even though an output schema exists, so nothing an agent needs is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description rises above it by explaining what channel choice actually implies operationally and by flagging email_id as the fix for the email-selection failure. The action_type enum's large set and targets/ttl_seconds semantics are left entirely to the schema, so it is not a full 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

A specific verb and resource (start a 2FA challenge) plus the immediate consequences (sends a code, returns a session ID and channel-specific artifacts). However, it never distinguishes itself from the near-duplicate sibling start_2fa_for_action, nor from start_add_email/start_add_phone, so an agent cannot resolve the overlap from this text alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a numbered end-to-end flow (start → present challenge → poll get_2fa_status → proceed or restart) and names the exact tools for each step. It also spells out the channel-specific branching (email dispatches; telegram/whatsapp need deep_link; sms needs sms_message), including the requires_email_selection recovery path and the expired-session alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.