@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/portfolio/lh-mcp-buddypress-actions/>
  a sioc:Post ;
  dc:title "MCP abilities" ;
  dcterms:identifier 153119 ;
  dc:modified "2026-11-01T22:12:07Z"^^xsd:dateTime ;
  dc:created "2026-11-01T22:12:07Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-mcp-buddypress-actions/mcp-abilities/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded "<ul class=\"lh_portfolio-meta\"><li><strong>Part of:</strong> <a href=\"https://lhero.org/portfolio/lh-mcp-buddypress-actions/\">LH MCP BuddyPress Actions</a></li></ul><div class=\"lh_portfolio-ability-reference\"><ul class=\"lh_portfolio-ability-reference-index\"><li><a href=\"#ability-add-group-members\"><code>add-group-members</code></a> Add Group Members</li><li><a href=\"#ability-remove-group-members\"><code>remove-group-members</code></a> Remove Group Members</li><li><a href=\"#ability-set-group-member-role\"><code>set-group-member-role</code></a> Set Group Member Role</li></ul><section class=\"lh_portfolio-ability-reference-ability\" id=\"ability-add-group-members\"><h2>Add Group Members</h2><p class=\"lh_portfolio-ability-reference-meta\"><code>lh-mcp-buddypress-actions/add-group-members</code> <span class=\"lh_portfolio-ability-reference-annotation lh_portfolio-ability-reference-annotation-idempotent\">Idempotent</span></p><p>Adds users to a BuddyPress group through BuddyPress, so group hooks run, and reports the outcome per user. A pending membership request or invitation is accepted rather than duplicated (BuddyPress fires its usual accept actions); otherwise the user joins with <code>groups_join_group</code>. role makes new members mods or admins; existing members are reported as <code>already_member</code> with their role unchanged (use set-group-member-role). Only members of the site the call runs on (the connector&#039;s site, or <code>site_id</code>) can be added: with LH Membership, approved members only. The site&#039;s own rules come first: they can refuse any join through the <code>lh_mcp_buddypress_actions_refuse_change</code> filter, and a real run is refused while the site has plugins this call did not load (a <code>site_id</code> call from another site), so use that site&#039;s own connector. Statuses: added, <code>would_add</code> (dry run), <code>already_member</code>, banned (left banned), <code>not_site_member</code>, <code>not_found</code> (no such user, or spam or deleted) and refused (a site rule, BuddyPress or a join hook turned it down, or an unconfirmed membership row exists). Callers with <code>install_plugins</code> are not restricted: the site member requirement, site rules and the refusal for unloaded site plugins are skipped, and warnings still say when site plugins were not loaded. <code>dry_run</code> defaults to true. note is recorded in LH Audit Trail with each join. Requires <code>bp_moderate</code>, or being an admin of the group. Pass <code>site_id</code> to act on another site you belong to.</p><figure class=\"wp-block-table lh_portfolio-ability-reference-params\"><table><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>group_id</code></td><td>integer</td><td>Yes</td><td></td><td>The BuddyPress group ID.</td></tr><tr><td><code>user_ids</code></td><td>array of integer</td><td>Yes</td><td></td><td>WordPress user IDs to act on, at most 100.</td></tr><tr><td><code>dry_run</code></td><td>boolean</td><td>No</td><td><code>true</code></td><td>Default true: report what would happen and change nothing. Pass false to make the change.</td></tr><tr><td><code>note</code></td><td>string</td><td>No</td><td></td><td>Optional. Why this was done, recorded with each change in LH Audit Trail.</td></tr><tr><td><code>role</code></td><td>string</td><td>No</td><td><code>&quot;member&quot;</code></td><td>Role for users who are added: member (default), mod or admin. Existing members keep their role. One of: <code>member</code>, <code>mod</code>, <code>admin</code>.</td></tr><tr><td><code>task_id</code></td><td>integer</td><td>No</td><td></td><td>Optional. The lh-tasks task this call is working on. Pass with <code>claim_token</code>: the call is refused unless you hold that claim, and a successful call renews it.</td></tr><tr><td><code>claim_token</code></td><td>string</td><td>No</td><td></td><td>Optional. The <code>claim_token</code> from claim-next-task for <code>task_id</code>. Required when <code>task_id</code> is given.</td></tr><tr><td><code>site_id</code></td><td>integer</td><td>No</td><td></td><td>Optional. ID of another site in the network to act on; list-my-sites gives the sites you belong to. Permissions are checked on that site. Omit for this site.</td></tr></tbody></table></figure></section><section class=\"lh_portfolio-ability-reference-ability\" id=\"ability-remove-group-members\"><h2>Remove Group Members</h2><p class=\"lh_portfolio-ability-reference-meta\"><code>lh-mcp-buddypress-actions/remove-group-members</code> <span class=\"lh_portfolio-ability-reference-annotation lh_portfolio-ability-reference-annotation-destructive\">Destructive</span> <span class=\"lh_portfolio-ability-reference-annotation lh_portfolio-ability-reference-annotation-idempotent\">Idempotent</span></p><p>Removes or bans users from a BuddyPress group through BuddyPress, so group hooks run, and reports the outcome per user. Uses <code>groups_remove_member</code>, or <code>groups_ban_member</code> with ban. Never leaves a group without an admin: removing or banning its last admin is refused, and a group admin must be demoted with set-group-member-role before being banned. Statuses: removed, banned, <code>would_remove</code> and <code>would_ban</code> (dry run), <code>not_member</code>, <code>already_banned</code>, <code>not_found</code> (no such user, or spam or deleted), refused (last admin, an admin to ban, a site rule, or BuddyPress turned it down). The site&#039;s own rules come first: they can refuse any change through the <code>lh_mcp_buddypress_actions_refuse_change</code> filter, and a real run is refused while the site has plugins this call did not load (a <code>site_id</code> call from another site), so use that site&#039;s own connector. Callers with <code>install_plugins</code> are not restricted: site rules and the refusal for unloaded site plugins are skipped, and warnings still say when site plugins were not loaded. <code>dry_run</code> defaults to true. note is recorded in LH Audit Trail with each change. Requires <code>bp_moderate</code>, or being an admin of the group. Pass <code>site_id</code> to act on another site you belong to.</p><figure class=\"wp-block-table lh_portfolio-ability-reference-params\"><table><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>group_id</code></td><td>integer</td><td>Yes</td><td></td><td>The BuddyPress group ID.</td></tr><tr><td><code>user_ids</code></td><td>array of integer</td><td>Yes</td><td></td><td>WordPress user IDs to act on, at most 100.</td></tr><tr><td><code>dry_run</code></td><td>boolean</td><td>No</td><td><code>true</code></td><td>Default true: report what would happen and change nothing. Pass false to make the change.</td></tr><tr><td><code>note</code></td><td>string</td><td>No</td><td></td><td>Optional. Why this was done, recorded with each change in LH Audit Trail.</td></tr><tr><td><code>ban</code></td><td>boolean</td><td>No</td><td><code>false</code></td><td>Ban instead of remove, so the user cannot rejoin. Default false.</td></tr><tr><td><code>task_id</code></td><td>integer</td><td>No</td><td></td><td>Optional. The lh-tasks task this call is working on. Pass with <code>claim_token</code>: the call is refused unless you hold that claim, and a successful call renews it.</td></tr><tr><td><code>claim_token</code></td><td>string</td><td>No</td><td></td><td>Optional. The <code>claim_token</code> from claim-next-task for <code>task_id</code>. Required when <code>task_id</code> is given.</td></tr><tr><td><code>site_id</code></td><td>integer</td><td>No</td><td></td><td>Optional. ID of another site in the network to act on; list-my-sites gives the sites you belong to. Permissions are checked on that site. Omit for this site.</td></tr></tbody></table></figure></section><section class=\"lh_portfolio-ability-reference-ability\" id=\"ability-set-group-member-role\"><h2>Set Group Member Role</h2><p class=\"lh_portfolio-ability-reference-meta\"><code>lh-mcp-buddypress-actions/set-group-member-role</code> <span class=\"lh_portfolio-ability-reference-annotation lh_portfolio-ability-reference-annotation-idempotent\">Idempotent</span></p><p>Promotes or demotes existing members of a BuddyPress group between member, mod and admin, and reports the outcome per user. Goes through BuddyPress (<code>groups_promote_member</code> and <code>groups_demote_member</code>), so group hooks run. Only confirmed, unbanned members change; it never adds anyone (use add-group-members). Demoting the group&#039;s last admin is refused. Statuses: changed, <code>would_change</code> (dry run), unchanged (already that role), <code>not_member</code>, banned, <code>not_found</code> (no such user, or spam or deleted) and refused (last admin, a site rule, or BuddyPress turned it down). The site&#039;s own rules come first: they can refuse any change through the <code>lh_mcp_buddypress_actions_refuse_change</code> filter, and a real run is refused while the site has plugins this call did not load (a <code>site_id</code> call from another site), so use that site&#039;s own connector. Callers with <code>install_plugins</code> are not restricted: site rules and the refusal for unloaded site plugins are skipped, and warnings still say when site plugins were not loaded. <code>dry_run</code> defaults to true. note is recorded in LH Audit Trail with each change. Requires <code>bp_moderate</code>, or being an admin of the group. Pass <code>site_id</code> to act on another site you belong to.</p><figure class=\"wp-block-table lh_portfolio-ability-reference-params\"><table><thead><tr><th>Parameter</th><th>Type</th><th>Required</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>group_id</code></td><td>integer</td><td>Yes</td><td></td><td>The BuddyPress group ID.</td></tr><tr><td><code>user_ids</code></td><td>array of integer</td><td>Yes</td><td></td><td>WordPress user IDs to act on, at most 100.</td></tr><tr><td><code>dry_run</code></td><td>boolean</td><td>No</td><td><code>true</code></td><td>Default true: report what would happen and change nothing. Pass false to make the change.</td></tr><tr><td><code>note</code></td><td>string</td><td>No</td><td></td><td>Optional. Why this was done, recorded with each change in LH Audit Trail.</td></tr><tr><td><code>role</code></td><td>string</td><td>Yes</td><td></td><td>The role to set: member, mod or admin. One of: <code>member</code>, <code>mod</code>, <code>admin</code>.</td></tr><tr><td><code>task_id</code></td><td>integer</td><td>No</td><td></td><td>Optional. The lh-tasks task this call is working on. Pass with <code>claim_token</code>: the call is refused unless you hold that claim, and a successful call renews it.</td></tr><tr><td><code>claim_token</code></td><td>string</td><td>No</td><td></td><td>Optional. The <code>claim_token</code> from claim-next-task for <code>task_id</code>. Required when <code>task_id</code> is given.</td></tr><tr><td><code>site_id</code></td><td>integer</td><td>No</td><td></td><td>Optional. ID of another site in the network to act on; list-my-sites gives the sites you belong to. Permissions are checked on that site. Omit for this site.</td></tr></tbody></table></figure></section></div>"^^rdf:XMLLiteral ;
  sioc:content "Part of: LH MCP BuddyPress Actionsadd-group-members Add Group Membersremove-group-members Remove Group Membersset-group-member-role Set Group Member RoleAdd Group Memberslh-mcp-buddypress-actions/add-group-members IdempotentAdds users to a BuddyPress group through BuddyPress, so group hooks run, and reports the outcome per user. A pending membership request or invitation is accepted rather than duplicated (BuddyPress fires its usual accept actions); otherwise the user joins with groups_join_group. role makes new members mods or admins; existing members are reported as already_member with their role unchanged (use set-group-member-role). Only members of the site the call runs on (the connector&#039;s site, or site_id) can be added: with LH Membership, approved members only. The site&#039;s own rules come first: they can refuse any join through the lh_mcp_buddypress_actions_refuse_change filter, and a real run is refused while the site has plugins this call did not load (a site_id call from another site), so use that site&#039;s own connector. Statuses: added, would_add (dry run), already_member, banned (left banned), not_site_member, not_found (no such user, or spam or deleted) and refused (a site rule, BuddyPress or a join hook turned it down, or an unconfirmed membership row exists). Callers with install_plugins are not restricted: the site member requirement, site rules and the refusal for unloaded site plugins are skipped, and warnings still say when site plugins were not loaded. dry_run defaults to true. note is recorded in LH Audit Trail with each join. Requires bp_moderate, or being an admin of the group. Pass site_id to act on another site you belong to.ParameterTypeRequiredDefaultDescriptiongroup_idintegerYesThe BuddyPress group ID.user_idsarray of integerYesWordPress user IDs to act on, at most 100.dry_runbooleanNotrueDefault true: report what would happen and change nothing. Pass false to make the change.notestringNoOptional. Why this was done, recorded with each change in LH Audit Trail.rolestringNo&quot;member&quot;Role for users who are added: member (default), mod or admin. Existing members keep their role. One of: member, mod, admin.task_idintegerNoOptional. The lh-tasks task this call is working on. Pass with claim_token: the call is refused unless you hold that claim, and a successful call renews it.claim_tokenstringNoOptional. The claim_token from claim-next-task for task_id. Required when task_id is given.site_idintegerNoOptional. ID of another site in the network to act on; list-my-sites gives the sites you belong to. Permissions are checked on that site. Omit for this site.Remove Group Memberslh-mcp-buddypress-actions/remove-group-members Destructive IdempotentRemoves or bans users from a BuddyPress group through BuddyPress, so group hooks run, and reports the outcome per user. Uses groups_remove_member, or groups_ban_member with ban. Never leaves a group without an admin: removing or banning its last admin is refused, and a group admin must be demoted with set-group-member-role before being banned. Statuses: removed, banned, would_remove and would_ban (dry run), not_member, already_banned, not_found (no such user, or spam or deleted), refused (last admin, an admin to ban, a site rule, or BuddyPress turned it down). The site&#039;s own rules come first: they can refuse any change through the lh_mcp_buddypress_actions_refuse_change filter, and a real run is refused while the site has plugins this call did not load (a site_id call from another site), so use that site&#039;s own connector. Callers with install_plugins are not restricted: site rules and the refusal for unloaded site plugins are skipped, and warnings still say when site plugins were not loaded. dry_run defaults to true. note is recorded in LH Audit Trail with each change. Requires bp_moderate, or being an admin of the group. Pass site_id to act on another site you belong to.ParameterTypeRequiredDefaultDescriptiongroup_idintegerYesThe BuddyPress group ID.user_idsarray of integerYesWordPress user IDs to act on, at most 100.dry_runbooleanNotrueDefault true: report what would happen and change nothing. Pass false to make the change.notestringNoOptional. Why this was done, recorded with each change in LH Audit Trail.banbooleanNofalseBan instead of remove, so the user cannot rejoin. Default false.task_idintegerNoOptional. The lh-tasks task this call is working on. Pass with claim_token: the call is refused unless you hold that claim, and a successful call renews it.claim_tokenstringNoOptional. The claim_token from claim-next-task for task_id. Required when task_id is given.site_idintegerNoOptional. ID of another site in the network to act on; list-my-sites gives the sites you belong to. Permissions are checked on that site. Omit for this site.Set Group Member Rolelh-mcp-buddypress-actions/set-group-member-role IdempotentPromotes or demotes existing members of a BuddyPress group between member, mod and admin, and reports the outcome per user. Goes through BuddyPress (groups_promote_member and groups_demote_member), so group hooks run. Only confirmed, unbanned members change; it never adds anyone (use add-group-members). Demoting the group&#039;s last admin is refused. Statuses: changed, would_change (dry run), unchanged (already that role), not_member, banned, not_found (no such user, or spam or deleted) and refused (last admin, a site rule, or BuddyPress turned it down). The site&#039;s own rules come first: they can refuse any change through the lh_mcp_buddypress_actions_refuse_change filter, and a real run is refused while the site has plugins this call did not load (a site_id call from another site), so use that site&#039;s own connector. Callers with install_plugins are not restricted: site rules and the refusal for unloaded site plugins are skipped, and warnings still say when site plugins were not loaded. dry_run defaults to true. note is recorded in LH Audit Trail with each change. Requires bp_moderate, or being an admin of the group. Pass site_id to act on another site you belong to.ParameterTypeRequiredDefaultDescriptiongroup_idintegerYesThe BuddyPress group ID.user_idsarray of integerYesWordPress user IDs to act on, at most 100.dry_runbooleanNotrueDefault true: report what would happen and change nothing. Pass false to make the change.notestringNoOptional. Why this was done, recorded with each change in LH Audit Trail.rolestringYesThe role to set: member, mod or admin. One of: member, mod, admin.task_idintegerNoOptional. The lh-tasks task this call is working on. Pass with claim_token: the call is refused unless you hold that claim, and a successful call renews it.claim_tokenstringNoOptional. The claim_token from claim-next-task for task_id. Required when task_id is given.site_idintegerNoOptional. ID of another site in the network to act on; list-my-sites gives the sites you belong to. Permissions are checked on that site. Omit for this site." ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1>, <https://lhero.org/?taxonomy=lh_object_key&term=lh-portfolio_doc_20261101t111500-bpa-mcp-abilities> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=lh_object_key&term=lh-portfolio_doc_20261101t111500-bpa-mcp-abilities> rdfs:seeAlso <https://lhero.org/?taxonomy=lh_object_key&term=lh-portfolio_doc_20261101t111500-bpa-mcp-abilities&feed=lhrdf&format=turtle> .
