Skip to main content
Glama
@proof-holdings/mcp-server

@proof-holdings/mcp-server

Official

create_session

Create a phone verification session and get a deep link, QR code, or SMS text so a user can prove control of their number through a hosted flow.

Instructions

Create a new phone verification session. Returns deep_link, qr_code (base64 PNG), and qr_text (UTF-8 text QR for terminal display). Sessions provide a hosted verification flow with callbacks.

Agent usage: After creating a session, pass the response's deep_link to render_auth_link so the user can open or scan it. Never hand qr_text to a link renderer — it is that link already rendered as QR art. Print it verbatim inside a fenced code block only when a real terminal needs the QR. On sms the person texts a short code from the number being proven, as in SMS login: deep_link is an sms: link to our default number with the message pre-filled, so render it the same way, and also show sms_message (what they send) with the numbers in sms_dids (one per region, each with its own QR), because a person reading on a computer texts from their phone. They get no reply SMS. An SMS proof can still be revoked about a minute after the session completes, if the delayed spoof check finds the sender was not a real mobile line, so before relying on it check it with validate_proof. Then use wait_for_session to poll until the session reaches a terminal state (verified, failed, or expired).

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. Set PROOF_API_KEY and restart this server, then call this tool again. start_login does NOT open this tool.

Input Schema

NameRequiredDescriptionDefault
channelYesHow the person proves the number: telegram or whatsapp (the bot reads it from their account) or sms (they text a short code from it). No phone number is sent
contextNo
profile_idNoSub-account whose name and templates the bot uses; omitted: the key's sub-account, else the primary
client_metadataNoYour own key-value data, stored with the session

Output Schema

NameRequiredDescriptionDefault
idNoSession id
statusNo
channelNoHow the person proves the number: `telegram` or `whatsapp` (the bot reads the number from their account), or `sms` (they text a short code from the number to one of ours).
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_didsNoEvery number an `sms` session's code can be texted to, one per configured region (a region with no number is absent), each with its own QR code. `deep_link` uses the default region's number; the request comes from your server, so nothing in it says where the person is.
deep_linkNoOpens the messenger (`https://t.me/…`, `https://wa.me/…`) or the messaging app (`sms:<number>?body=…`) with what the person sends
expires_atNo
sms_messageNoThe message to send, as pre-filled in the links (`sms` only)
instructionsNoOne line telling the person what to do

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed13 schema fields changedv1.7.2
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / callback_url
      Removed value: -{
      -  "description": "URL to redirect after verification",
      -  "type": "string"
      -}
    • changedInput schema / properties / channel / description
      Previous value: -"Verification channel"New value: +"How the person proves the number: telegram or whatsapp (the bot reads it from their account) or sms (they text a short code from it). No phone number is sent"
    • changedInput schema / properties / channel / enum
      Previous value: -[
      -  "sms",
      -  "whatsapp",
      -  "telegram"
      -]New value: +[
      +  "telegram",
      +  "whatsapp",
      +  "sms"
      +]
    • addedInput schema / properties / client_metadata
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Your own key-value data, stored with the session",
      +  "propertyNames": {
      +    "type": "string"
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / context
      Added value: +{
      +  "properties": {
      +    "action": {
      +      "description": "Picks the bot's wording: log in, 2FA, account recovery, or plain verification (the default)",
      +      "enum": [
      +        "login",
      +        "2fa",
      +        "verification",
      +        "recovery"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • removedInput schema / properties / external_user_id
      Removed value: -{
      -  "description": "Your application user ID",
      -  "type": "string"
      -}
    • removedInput schema / properties / metadata
      Removed value: -{
      -  "additionalProperties": {
      -    "type": "string"
      -  },
      -  "description": "Custom key-value metadata",
      -  "type": "object"
      -}
    • removedInput schema / properties / phone_number
      Removed value: -{
      -  "description": "Phone number in E.164 format",
      -  "type": "string"
      -}
    • addedInput schema / properties / profile_id
      Added value: +{
      +  "description": "Sub-account whose name and templates the bot uses; omitted: the key's sub-account, else the primary",
      +  "pattern": "^[0-9a-fA-F]{24}$",
      +  "type": "string"
      +}
    • removedInput schema / properties / template_id
      Removed value: -{
      -  "description": "Custom template ID",
      -  "type": "string"
      -}
    • changedInput schema / required
      Previous value: -[
      -  "channel",
      -  "phone_number"
      -]New value: +[
      +  "channel"
      +]
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": {},
      +  "properties": {
      +    "channel": {
      +      "description": "How the person proves the number: `telegram` or `whatsapp` (the bot reads the number from their account), or `sms` (they text a short code from the number to one of ours)."
      +    },
      +    "deep_link": {
      +      "description": "Opens the messenger (`https://t.me/…`, `https://wa.me/…`) or the messaging app (`sms:<number>?body=…`) with what the person sends"
      +    },
      +    "expires_at": {},
      +    "id": {
      +      "description": "Session id"
      +    },
      +    "instructions": {
      +      "description": "One line telling the person what to do"
      +    },
      +    "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"
      +    },
      +    "sms_code": {
      +      "description": "The short code the person texts (`sms` only)"
      +    },
      +    "sms_dids": {
      +      "description": "Every number an `sms` session's code can be texted to, one per configured region (a region with no number is absent), each with its own QR code. `deep_link` uses the default region's number; the request comes from your server, so nothing in it says where the person is."
      +    },
      +    "sms_message": {
      +      "description": "The message to send, as pre-filled in the links (`sms` only)"
      +    },
      +    "status": {}
      +  },
      +  "type": "object"
      +}
  2. First observedv1.1.0

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, destructiveHint=false), the description discloses the response shape, the fact that the user never sees tool results, the SMS flow's quirks (no reply SMS, delayed spoof check that can revoke a proof about a minute after completion), and the authentication prerequisite (PROOF_API_KEY plus restart, and that start_login does not open this tool). That is substantial behavior an agent could not get from the structured fields.

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?

Purpose and return values are front-loaded and every paragraph carries operational content, but the draft is long and slightly redundant — the 'user does not see tool results' point is made once about render_auth_link's output and again as a directive before waiting/polling. The SMS paragraph in particular is dense enough that a reader may need a second pass.

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 multi-step, stateful creation tool with nested parameters, the definition covers creation, rendering, polling, revocation risk, and credential setup. An output schema exists, so the description's return-value summary is a convenience rather than a necessity, and nothing an agent needs in order to call this correctly appears to be 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 75% and the description adds real meaning about channel behavior: telegram/whatsapp are read from the account by a bot while sms requires the person to text a short code from the number being proven, and no phone number is submitted. It does not elaborate on profile_id, client_metadata, or the context.action enum, leaving those to the schema.

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?

The opening sentence gives a specific verb and resource ('Create a new phone verification session') and immediately names the returned artifacts (deep_link, qr_code, qr_text) plus the hosted-flow-with-callbacks model. It does not explicitly contrast itself with adjacent siblings such as create_verification, start_2fa, or create_multi_channel_verification, so an agent must infer the boundary from the word 'session'.

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?

It gives an explicit ordered workflow: create, hand deep_link to render_auth_link, then poll with wait_for_session until verified/failed/expired, and check validate_proof before relying on an SMS proof. It also states a prohibition ('Never hand qr_text to a link renderer') and the exact condition under which qr_text should be printed verbatim, which is the kind of when/when-not guidance that prevents misuse.

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

Deploy Server

Other Tools