Browse API 1 documentation
GroveAPI 1preview

Capabilities

Requested permissions and the API each permission unlocks.

Mango 3.1+View Markdown

Capabilities are native permissions requested in manifest.json and accepted by the user. A requested capability is not authority by itself: Mango stores the grant and checks it for every delivered event and accepted bridge call.

Channel and query capabilities remain bound to the instance’s scope. A server-scoped instance does not turn channel.send into permission to send anywhere. network.send accepts only a modeled, explicit target that Mango confirms is currently joined; no capability in API 1 grants arbitrary IRC lines.

An application-scoped Root is deliberately outside every IRC session. IRC message delivery, sends, notices, typing, presence, filters, slash commands, cards, and member actions remain unavailable even if its manifest requests those capabilities. Application Roots may use storage, settings, host-attributed status badges, and declared app-wide contributions such as upload providers.

Implemented capabilities

Capability API 1 access
channel.read Receive message events for the bound channel, or live messages from all confirmed joined channels when the extension is server-scoped. A server-scoped reader also receives the retained channels roster event.
channel.send Use grove.send(text) and channel-scoped grove.typing(...).
channel.notice Use grove.notice(text) for the bound channel.
query.read Receive direct-message-shaped message events in a granted query scope.
query.send Use targeted grove.send in an existing query, direct-message grove.reply, and direct-message typing. A channel-message grove.reply instead requires channel.send in conversation scope or network.send in server scope.
query.open Add { open: true } to an explicit { to } send so Mango creates and selects that private conversation. Requires query.send too.
query.notice Use targeted grove.notice.
presence.set Set or clear the connection-wide IRC away state with grove.away.
storage Use a persistent per-extension WebKit data store. Without it web storage is ephemeral.
storage.secure Use Keychain-backed grove.secrets namespaces and the legacy Blowfish interoperability helper.
oauth.authorize Open a user-visible system authentication session through grove.oauth.authorize(...). Mango owns the callback, random state, and PKCE challenge; the extension exchanges the resulting one-time code.
network.request Make bounded native HTTPS requests to accepted hostPermissions origins when an API does not support browser CORS. Redirects are returned but never followed automatically; cookies, unsafe headers, and undeclared destinations are rejected.
commands.register Register slash commands and publish their native output cards. An exclusive composer utility may use this capability for manifest-declared commands that launch it on demand and return draft text.
ui.member-actions Register bounded, host-attributed actions in channel member menus.
ui.web-pane From a server-scoped headless Root, open or replace one isolated packaged HTML pane beside an explicit confirmed channel. Data requests use accepted hostPermissions; the page receives no Grove bridge or IRC context. Remote executable pages are rejected.
ui.member-badges Publish bounded, host-attributed badges beside members from retained snapshots.
ui.channel-actions Register bounded, host-attributed actions in joined-channel menus.
ui.channel-badges Publish bounded, host-attributed badges beside joined channels.
channel.members Receive the retained authoritative member roster for confirmed joined channels through channelSnapshots.
channel.metadata Receive retained channel topic and boolean channel modes through channelSnapshots. Sensitive argument-bearing values such as channel keys are never exposed.
statusbar Publish host-attributed native status-bar badges.
uploads.provide Register manifest-declared upload handlers from a headless Root.
uploads.use From a user-invoked composer utility, hand one bounded in-memory file to Mango’s configured native uploader.
microphone.record Record a bounded voice clip through Mango’s native microphone bridge, only from a visible composer utility. Apple microphone permission is also required. See composer audio.
messages.filter.inbound Inspect and allow, deny, or transform messages before Mango displays them.
messages.filter.outbound Inspect and allow, deny, or transform messages before Mango sends them.
messages.protect From a server-scoped Root or tab, return terminal protected message transforms with bounded ordered frames. Security protocols may also publish host-owned fail-closed policy through grove.protection.set(...): queries are protected in both directions, while channel policies fail closed on outbound sends and continue accepting mixed inbound plaintext. Requires the matching inbound/outbound filter grants.
network.send From a server-scoped instance, use grove.send, channel-message grove.reply, or grove.typing with an explicit { channel }. The target must be one confirmed joined channel and cannot be combined with { to }. It does not grant server-wide NOTICE. This is modeled output, not raw IRC access.

Request only the permissions needed by the current release. Additional capabilities change what the user is consenting to and should correspond to a visible feature.

Reserved capabilities

These names are recognized by API 1 manifests but do not currently expose a corresponding bridge getter, event, or command:

Capability Intended area
identity The user’s identity on the network.
notifications Native user notifications.
server.events Whole-session registration, numeric, or raw-event delivery.

Do not request a reserved capability in expectation that an undocumented JavaScript API exists. Unknown capability strings fail manifest decoding; reserved strings decode but grant no API beyond what is documented.

Host permissions are separate

hostPermissions controls browser network egress and is shown separately during consent. It does not grant IRC data or native bridge operations. Conversely, channel.read does not let an extension exfiltrate messages to an undeclared host.

An extension that processes data entirely locally should use an empty network allow-list:

json
"capabilities": ["messages.filter.inbound", "storage"],
"hostPermissions": []

An extension that fetches one API should declare only that origin:

json
"capabilities": ["commands.register"],
"hostPermissions": ["https://api.example.com"]

When a service intentionally assigns one direct subdomain per user, a complete leftmost-label wildcard is available:

json
"hostPermissions": ["https://*.example.com"]

It matches alice.example.com, but not the apex, a deeper subdomain, another scheme, or an undeclared port. Prefer an exact origin whenever possible.

Mango attributes grants to the immutable package identifier. Installing replacement bytes or an update stops the old instance and clears its prior grant so new code cannot silently inherit consent. The user reviews capabilities again before starting the replacement.

Removing an extension removes its installed bytes and associated storage. Revoking or losing a grant stops new bridge access immediately; an extension must not assume a registration remains active after its authority changes.