delete_groups_by_id_members_by_userid
Calls DELETE /api/groups/{id}/members/{userId} as the signed-in person · REST reference
Remove a user from a group
SOFT REMOVAL. The MEMBER_OF edge is not deleted — the DAL stamps it status: REMOVED with removedAt / removedBy / removalReason, so the membership survives as its own audit record while conferring nothing (every permission reader applies an ALLOW-list of ACTIVE and APPROVED). The member drops off GET /api/groups/:id/members-derived rosters and out of the group's memberCount, both of which exclude REMOVED. NOT IDEMPOTENT against a non-member: removing someone who is not in the group answers 404 rather than reporting a removal it did not perform. On a revocation path, "removed nobody" must not read as "revoked access". Requires execute:UpdateGroupPermissionsCommand at this router — the same permission as ADDING a member — and membership of the group's organization (403 GROUP_MANAGE_DENIED); platform staff bypass both. The caller's own bearer token is forwarded to the DAL, which requires execute:RemoveGroupMemberCommand INSIDE the group's own organization (403 otherwise) and records the caller as removedBy.
Arguments
| Argument | Type | Description | |
|---|---|---|---|
idpath | string (uuid) | required | Group id. |
userIdpath | string (uuid) | required | User to remove. |
Example call
A client sends this over the MCP session; Claude and other agents build it for you. The values are placeholders — the shape is real.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_groups_by_id_members_by_userid",
"arguments": {
"id": "11111111-1111-4111-8111-111111111111",
"userId": "11111111-1111-4111-8111-111111111111"
}
}
}Result
On success (HTTP 200) the tool returns one text item holding the API's JSON, pretty-printed.
The membership was stamped REMOVED. The body is a fixed envelope; it does not carry the stamped membership.
{
"message": "Member removed from group successfully",
"success": true
}Fields
| Field | Type | Description |
|---|---|---|
message | "Member removed from group successfully" | |
success | true |
When it fails
A failed call returns isError: true with the API's message as text. A change the person declines, or lets time out, also comes back this way and nothing changes.
400idoruserIdis not a UUID.403Missing
execute:UpdateGroupPermissionsCommand, the caller does not belong to the group's org (code: GROUP_MANAGE_DENIED), or the DAL refused the caller (no code).404No such group (
code: GROUP_NOT_FOUND), or the user holds no membership in it — the removal is not idempotent against a non-member.409The group is its organization's OWNER group and the user is the org's owner. An org has exactly one owner, who leaves the OWNER group only by an ownership transfer.
What the model is shown
This is the tool exactly as the server lists it in tools/list. The description starts with the REST call it makes.
{
"name": "delete_groups_by_id_members_by_userid",
"description": "DELETE /api/groups/{id}/members/{userId} — SOFT REMOVAL. The `MEMBER_OF` edge is not deleted — the DAL stamps it `status: REMOVED` with `removedAt` / `removedBy` / `removalReason`, so the membership survives as its own audit record while conferring nothing (every permission reader applies an ALLOW-list of ACTIVE and APPROVED). The member drops off `GET /api/groups/:id/members`-derived rosters and out of the group's `memberCount`, both of which exclude `REMOVED`. NOT IDEMPOTENT against a non-member: removing someone who is not in the group answers 404 rather than reporting a removal it did not perform. On a revocation path, \"removed nobody\" must not read as \"revoked access\". Requires `execute:UpdateGroupPermissionsCommand` at this router — the same permission as ADDING a member — and membership of the group's organization (403 `GROUP_MANAGE_DENIED`); platform staff bypass both. The caller's own bearer token is forwarded to the DAL, which requires `execute:RemoveGroupMemberCommand` INSIDE the group's own organization (403 otherwise) and records the caller as `removedBy`.\n\nThis changes data. The person is asked to confirm it before it runs, and nothing happens if they decline.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Group id."
},
"userId": {
"type": "string",
"description": "User to remove."
}
},
"required": [
"id",
"userId"
]
},
"annotations": {
"readOnlyHint": false,
"destructiveHint": true,
"idempotentHint": true,
"openWorldHint": false
}
}