Skip to main content
Glama

Invite members

well_invite_members

Invite one or more teammates into a workspace, or into a workspace group. Use it after well_list_member_candidates, on the people the user chose.

Pass invites — 1 to 20 entries, each { email, role } or { phone, role }, role admin or member — and a target: { kind: "workspace" } for this workspace, or { kind: "group", group_id } for a group you belong to. Only a workspace owner or admin may invite; a caller without that role is refused. A demo workspace refuses both targets with DEMO_WORKSPACE.

Returns one results entry per invite, named by its email or its phone: status sent (a new invitation), reissued (an already-pending address got a fresh link), or refused — with refusal_reason naming why, ALREADY_WORKSPACE_MEMBER when the address already has access, INSUFFICIENT_PERMISSIONS when the caller may not invite, and DEMO_WORKSPACE when the workspace holds sample data. invitation_email_sent is false when the invite persisted but the email did not leave, so offer a resend. Each successful result carries person_id for the invited address. Never invite an address already active in the workspace.

Pass notify: false (workspace target only) to create or reissue the pending membership WITHOUT emailing — for the assign-then-invite flow where an owner is assigned by a typed email now and the invitation is sent later from the invite card. Use the returned person_id to assign that person as an owner without a second lookup.

Pass delivery: "link" (workspace target only) when the user asks for an invitation link to forward instead of an email. Well creates the pending invitation for each named address and sends NO email. Each successful result then carries invite_url (the accept link) and role. The link works once and has no expiry. Every link call mints a NEW link: for an address that already holds a pending invitation (reissued), the new link replaces any earlier link or invitation email for it, which stops working. The invitation is made out to the named address, so always ask for the teammate's email first and never mint a link for a name alone.

Pass { phone, role } (workspace target only) to invite a teammate by mobile number, with no email address. Give the number as the user typed it or as a shared contact card gives it; Well normalises it, and reads a number with no country code as a French number. The role is required: when the user named none, ask, and never choose it. Well creates the member's seat in the workspace, pending, for that number and that role, and sends NOTHING to the number itself: notify and delivery do not apply to it, and invitation_email_sent is false. The result carries phone (the number in international form), role, and invite_url, the invitation link that the user sends to that number by WhatsApp or SMS. The teammate opens the link, signs in and accepts, and is then in the workspace with that role: accepting is their consent, and nobody joins without it. Whoever opens the link can accept it, so it goes to that number only. The link works once and for seven days. reissued means the number already held a pending invitation here: the new invite_url replaces the earlier link, which stops working, the seven days start again, and the role stays the one the invitation already had. refused with INVITE_PHONE_NUMBER_INVALID means the text is not a valid phone number: ask the user for it again with its country code. ALREADY_WORKSPACE_MEMBER means a member of the workspace already verified that number.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
notifyNoSend the invitation email now. Defaults to true. Pass false to create or reissue the pending membership WITHOUT emailing, when a later explicit step sends it — e.g. assigning an owner by a typed email, then sending the invite from the invite card. Applies to a workspace target only; a group invite always notifies.
targetYesWhere the invites land: this workspace, or a workspace group.
invitesYesThe people to invite, 1 to 20 per call. Each entry names the teammate by exactly one key: `email` or `phone`.
deliveryNoHow the invitation reaches the teammate. Defaults to "email", which emails it. Pass "link" when the user asks for a link to forward: no email is sent, each result returns a new invite_url, and that link replaces any earlier link for the address. Applies to a workspace target only, and never with notify: true.
workspace_idNoTarget workspace. Omit when the token authorizes one workspace. Required when it authorizes several — a write lands in exactly one workspace and this call would not say which.
conversation_idNoThe conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation.
idempotency_keyNoOptional client-supplied key. A retried write with the same key returns the original result instead of re-applying the operation.
workspace_scopeNoRestrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNo
resultsYesOne result per invite, in the order they were sent.
successYes
workspace_idNo
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
newly_connectedNoTools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later.
conversation_id_noteNoPresent only when the server opened a fresh lane, stating that no choice recorded earlier was read.
conversation_id_sourceNoWhere the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / properties / newly_connected / description
      Previous value: -"Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. Start the reply with one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later."New value: +"Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later."
  2. Changed13 schema fields changed
    • addedInput schema / properties / delivery
      Added value: +{
      +  "description": "How the invitation reaches the teammate. Defaults to \"email\", which emails it. Pass \"link\" when the user asks for a link to forward: no email is sent, each result returns a new invite_url, and that link replaces any earlier link for the address. Applies to a workspace target only, and never with notify: true.",
      +  "enum": [
      +    "email",
      +    "link"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / invites / description
      Previous value: -"The people to invite, 1 to 20 per call."New value: +"The people to invite, 1 to 20 per call. Each entry names the teammate by exactly one key: `email` or `phone`."
    • removedInput schema / properties / invites / items / additionalProperties
      Removed value: -false
    • addedInput schema / properties / invites / items / anyOf
      Added value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "email": {
      +        "description": "The teammate's email address.",
      +        "format": "email",
      +        "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
      +        "type": "string"
      +      },
      +      "role": {
      +        "description": "The role to grant on acceptance: admin or member.",
      +        "enum": [
      +          "admin",
      +          "member"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "email",
      +      "role"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "phone": {
      +        "description": "The teammate's mobile number, as the user typed it or as a shared contact card gives it, with its country code when there is one (+33 6 00 00 00 01, 0033600000001). Well normalises it. A number with no country code is read as a French number.",
      +        "maxLength": 40,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "role": {
      +        "description": "The role the seat gives: admin or member. Required: ask the user, never choose it.",
      +        "enum": [
      +          "admin",
      +          "member"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "phone",
      +      "role"
      +    ],
      +    "type": "object"
      +  }
      +]
    • removedInput schema / properties / invites / items / properties
      Removed value: -{
      -  "email": {
      -    "description": "The teammate's email address.",
      -    "format": "email",
      -    "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
      -    "type": "string"
      -  },
      -  "role": {
      -    "description": "The role to grant on acceptance: admin or member.",
      -    "enum": [
      -      "admin",
      -      "member"
      -    ],
      -    "type": "string"
      -  }
      -}
    • removedInput schema / properties / invites / items / required
      Removed value: -[
      -  "email",
      -  "role"
      -]
    • removedInput schema / properties / invites / items / type
      Removed value: -"object"
    • addedInput schema / properties / workspace_scope
      Added value: +{
      +  "description": "Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace.",
      +  "enum": [
      +    "family"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / results / items / properties / email / description
      Added value: +"The invited address. Present on an email invite."
    • addedOutput schema / properties / results / items / properties / invite_url
      Added value: +{
      +  "description": "Present on a successful delivery \"link\" invite and on a successful phone invite: the accept link of the invitation. Give it to the user exactly as returned so they send it to the teammate. It works once. On a delivery \"link\" invite it has no expiry and stops only when a new link is made for the address or the invitation is cancelled. On a phone invite it works for seven days, and a new ask for the number replaces it.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / results / items / properties / phone
      Added value: +{
      +  "description": "Present on a phone invite: the number the seat is made for, in international form (+33600000001). On a refusal for an invalid number it is the number as it was given.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / results / items / properties / role
      Added value: +{
      +  "description": "Present on a successful delivery \"link\" invite (the role the link grants) and on a successful phone invite (the role the seat gives; on `reissued` it is the role of the invitation that already stood, which this call did not change).",
      +  "enum": [
      +    "admin",
      +    "member"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / properties / results / items / required
      Previous value: -[
      -  "email",
      -  "status",
      -  "invitation_email_sent"
      -]New value: +[
      +  "status",
      +  "invitation_email_sent"
      +]
  3. Changed1 schema field changed
    • addedOutput schema / properties / newly_connected
      Added value: +{
      +  "description": "Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. Start the reply with one line per entry, in the person's language: \"<name> is connected.\". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "name": {
      +        "type": "string"
      +      },
      +      "service_id": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "service_id"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  4. Changed1 schema field changed
    • changedOutput schema / properties / results / items / properties / refusal_reason / description
      Previous value: -"Present only when status is refused. Named reasons include ALREADY_WORKSPACE_MEMBER (the address already has access) and INSUFFICIENT_PERMISSIONS (the caller is not an owner or admin)."New value: +"Present only when status is refused. Named reasons include ALREADY_WORKSPACE_MEMBER (the address already has access), INSUFFICIENT_PERMISSIONS (the caller is not an owner or admin), and DEMO_WORKSPACE (the workspace holds sample data, so invite the team in the user's own workspace)."
  5. Changed4 schema fields changed
    • addedInput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_note
      Added value: +{
      +  "description": "Present only when the server opened a fresh lane, stating that no choice recorded earlier was read.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_source
      Added value: +{
      +  "description": "Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.",
      +  "enum": [
      +    "host_meta",
      +    "argument",
      +    "minted"
      +  ],
      +  "type": "string"
      +}
  6. Changed2 schema fields changed
    • addedInput schema / properties / notify
      Added value: +{
      +  "description": "Send the invitation email now. Defaults to true. Pass false to create or reissue the pending membership WITHOUT emailing, when a later explicit step sends it — e.g. assigning an owner by a typed email, then sending the invite from the invite card. Applies to a workspace target only; a group invite always notifies.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / results / items / properties / person_id
      Added value: +{
      +  "description": "The invitee's person id on a successful workspace invite (sent or reissued). Use it to assign the person as an owner right after inviting, with no second lookup. Absent on a refusal and on a group invite.",
      +  "type": "string"
      +}
  7. Added

TDQS

Score is being calculated.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources