Role & Group Tools

A role is the permission set one collaborator holds; a group is a bundle several collaborators share.

A role is the permission set one collaborator holds; a group is a bundle several collaborators share. These tools create and edit both, with permissions written as the same ability strings a token carries.

Tools

create_group

DESTRUCTIVE

Create a permission group on a team. Starts empty; add people with sync_group_members.

Creates a group: a named permission bundle several collaborators in a team can share. Someone can be in more than one.

The distinction from a role is what each attaches to. A role is what one collaborator is — everyone holds exactly one. A group is a bundle a set of people share. Both carry permissions. Neither bundles projects.

A group starts empty. Add people with sync_group_members — membership is deliberately not a field here, because naming a group and deciding who it applies to are different operations with different consequences.

Choose the code deliberately

code is unique within the team and cannot be changed afterwards — permissions are addressed by it. Only name and the permission set stay mutable.

Growth-tier capability. On a lower tier this returns TEAM_TIER_REQUIRED and creates nothing.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

team_id*string

UUID of the team the group belongs to.

code*string

Stable identifier, alpha-dash. Unique per team and immutable once created.

name*string

Human-readable group name.

permissionsarrayoptional

Permission codes (entity:action) the group grants.

What it returns

{  "data": {    "id": "1f68d92a-04c5-4e83-97b1-3d6a05e2f847",    "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",    "code": "billing-team",    "name": "Billing Team",    "permissions": ["project-subscription:view-any"]  }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks group:create.

TEAM_TIER_REQUIRED

the caller's platform tier does not include Teams.

RESOURCE_NOT_FOUND

no such team, or the caller is not a member.

VALIDATION_FAILED

code already used on that team, malformed code, or an unknown permission string.

create_role

DESTRUCTIVE

Create a role on a team with a permission set. The code is immutable.

Creates a role on a team. A role is what one collaborator is — everyone in a team holds exactly one. For a named bundle several people share, use create_group instead.

Subscriby seeds admin, manager and viewer on every new team; this adds your own.

Choose the code deliberately

code is unique within the team and cannot be changed afterwards — invitations and role assignments address it. Only name, description and the permission set stay mutable.

Growth-tier capability. On a lower tier this returns TEAM_TIER_REQUIRED and creates nothing.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

team_id*string

UUID of the team the role belongs to.

code*string

Stable identifier, alpha-dash. Unique per team and immutable once created.

name*string

Human-readable role name.

descriptionstringoptional

Optional description of what the role is for.

permissionsarrayoptional

Permission codes (entity:action) to grant. Omit for a role with none.

What it returns

{  "data": {    "id": "d05e1a83-7c46-4f29-b613-8ae407c9d251",    "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",    "code": "auditor",    "name": "Auditor",    "description": "Read-only access to subscriptions and payments",    "permissions": ["project:view-any", "project-subscription:view-any"]  }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks role:create.

TEAM_TIER_REQUIRED

the caller's platform tier does not include Teams.

RESOURCE_NOT_FOUND

no such team, or the caller is not a member.

VALIDATION_FAILED

code already used on that team, malformed code, or a permission string that is not in the catalog.

delete_group

DESTRUCTIVE

Delete a group. Members stay in the team but lose what it granted.

Deletes a group. Everyone in it loses whatever it granted, all at once, but stays in the team.

Not tier-gated, unlike creating and updating. A creator whose tier lapsed has to be able to take access away. See what the tier gates.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

group_id*string

UUID of the group to delete. Irreversible.

What it returns

{  "data": {    "id": "1f68d92a-04c5-4e83-97b1-3d6a05e2f847",    "deleted": true  }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks group:delete.

RESOURCE_NOT_FOUND

no such group in any team the caller belongs to.

delete_role

DESTRUCTIVE

Delete a role. Collaborators holding it stay in the team.

Deletes a role. Anyone holding it stays in the team but loses whatever the role granted.

Not tier-gated, unlike creating and updating. A creator whose tier lapsed has to be able to take access away. See what the tier gates.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

role_id*string

UUID of the role to delete. Irreversible.

What it returns

{  "data": {    "id": "d05e1a83-7c46-4f29-b613-8ae407c9d251",    "deleted": true  }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks role:delete.

RESOURCE_NOT_FOUND

no such role in any team the caller belongs to.

List groups across every team the caller owns or belongs to. Lighter-weight than roles — no permission payload.

List groups across every team the caller owns or belongs to. Groups cluster users without a permission payload — lighter-weight than roles. Ordered newest-first.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Annotations

Read-only

It reads and never changes anything.

Arguments

This tool takes no arguments.

What it returns

{  "data": [    {      "id": "1f68d92a-04c5-4e83-97b1-3d6a05e2f847",      "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",      "code": "ops",      "name": "Ops",      "created_at": "2026-05-18T10:05:00Z"    }  ],  "meta": { "total": 1 }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks group:view-any.

List roles across every team the caller owns or belongs to. Each role carries a flat permission list.

List roles across every team the caller owns or belongs to. Each role carries a flat permissions array — the same ability codes a token would use. Ordered newest-first.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Annotations

Read-only

It reads and never changes anything.

Arguments

This tool takes no arguments.

What it returns

{  "data": [    {      "id": "d05e1a83-7c46-4f29-b613-8ae407c9d251",      "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",      "code": "manager",      "name": "Manager",      "description": "Manage plans, resources, and subscribers",      "permissions": ["project:view", "project:update", "project-user:update"],      "created_at": "2026-05-18T10:05:00Z"    }  ],  "meta": { "total": 3 }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks role:view-any.

Replace a group's membership wholesale. A sync, not an add.

Replaces a group's membership with exactly the supplied user ids.

This is a sync, not an add

Anyone absent from user_ids is removed, and an empty array empties the group. Read the current membership with list_groups and send the full intended list — not just the people you want to add.

Every id must already belong to the group's team. A group grants permissions inside one tenant, so an outsider is refused rather than silently skipped — and the whole call fails rather than partly applying, so you never end up with a membership you did not ask for.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

group_id*string

UUID of the group whose membership is being replaced.

user_ids*array

Complete list of user UUIDs the group should contain. An empty array clears it.

What it returns

{  "data": {    "id": "1f68d92a-04c5-4e83-97b1-3d6a05e2f847",    "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",    "member_ids": [      "2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80",      "6f9b2e37-c184-4a05-8d72-30e16bc9f458"    ]  }}

Emits group.members_synced, carrying added_ids and removed_ids as well as the final list — an access-control mirror should not have to diff two snapshots to work out what moved.

A sync that changes nothing emits nothing.

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks group:update.

TEAM_TIER_REQUIRED

the sync adds somebody and the caller's tier does not include Teams. Nothing changes.

RESOURCE_NOT_FOUND

no such group in any team the caller belongs to.

VALIDATION_FAILED

one or more ids are not in the group's team. The offending ids are named, and nothing is applied.

Tier

Gated on Growth only when the sync adds somebody. A sync that only removes people succeeds on any tier.

This is the one write in the identity surface whose gate depends on its argument. Deciding from the tool alone would leave a lapsed creator unable to take one person out of a group without deleting the whole group — and deleting is not gated, so the gate would only be pushing them toward the more destructive option. See what the tier gates.

update_group

DESTRUCTIVE

Rename a group or replace its permission set. Membership is a separate tool.

Renames a group or replaces the permissions it grants. code is immutable, so a rename never breaks a reference.

Who is in the group is sync_group_members, not this — a rename is cosmetic, while changing the permission set silently re-scopes everyone already in the group.

Permissions replace, they do not merge

Sending permissions sets the group's permissions to exactly that list. Omit the key entirely to leave the existing set untouched while changing only the name.

Growth-tier capability. On a lower tier this returns TEAM_TIER_REQUIRED and changes nothing.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

group_id*string

UUID of the group to update.

namestringoptional

New group name. Omit to keep the current one.

permissionsarrayoptional

Complete replacement permission set. Omit to leave permissions untouched.

What it returns

{  "data": {    "id": "1f68d92a-04c5-4e83-97b1-3d6a05e2f847",    "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",    "code": "billing-team",    "name": "Billing & Finance",    "permissions": ["project-subscription:view-any", "payment:view-any"]  }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks group:update.

TEAM_TIER_REQUIRED

the caller's platform tier does not include Teams.

RESOURCE_NOT_FOUND

no such group in any team the caller belongs to.

VALIDATION_FAILED

an unknown permission string.

update_role

DESTRUCTIVE

Rename a role or replace its permission set. The code stays fixed.

Renames a role, changes its description, or replaces the permissions it grants. code is immutable, so a rename never breaks an assignment.

Permissions replace, they do not merge

Sending permissions sets the role's permissions to exactly that list. Omit the key entirely to leave the existing set untouched while changing only the name — sending an empty array strips every permission from everyone holding the role.

Growth-tier capability. On a lower tier this returns TEAM_TIER_REQUIRED and changes nothing.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

Runs the same action as

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

role_id*string

UUID of the role to update.

namestringoptional

New role name. Omit to keep the current one.

descriptionstringoptional

New description. Omit to keep the current one.

permissionsarrayoptional

Complete replacement permission set. Omit to leave permissions untouched.

What it returns

{  "data": {    "id": "d05e1a83-7c46-4f29-b613-8ae407c9d251",    "team_id": "a83f0d51-4c92-4b7e-8615-2fd9e70a3c86",    "code": "auditor",    "name": "Auditor & Finance",    "description": "Read-only access to subscriptions and payments",    "permissions": ["project:view-any", "project-subscription:view-any"]  }}

How it fails

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks role:update.

TEAM_TIER_REQUIRED

the caller's platform tier does not include Teams.

RESOURCE_NOT_FOUND

no such role in any team the caller belongs to.

VALIDATION_FAILED

a permission string that is not in the catalog.

How is this guide?

On this page

Subscriby is a product designed by you — for you.No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request