Capabilities

A capability is one operation your product exposes to a customer. Nothing becomes one by default, risk is decided by rules rather than by a model, and anything that mutates data is approved twice.

Anatomy of a capability

name
The tool name a customer's client sees. Stable, unique within the product, and derived deterministically from the source.
description
What it does, in the customer's vocabulary. A model may draft this. A model never decides anything else about the capability.
input schema
JSON Schema for the arguments. Enforced on every call before anything reaches your backend.
risk
read, write or destructive. Decides whether a second approval is required.
binding
How to execute it: which source, and the method, path or tool name behind it. Never exposed to the customer.
requires user identity
Set when the operation acts on behalf of a specific person. A call without a verified subject is refused rather than run as somebody generic.

Risk classification

Every discovered operation gets exactly one risk level. The level is not cosmetic: it decides the approval path, it is shown to the customer on the installation portal before they authorize anything, and it appears in the security review their team reads.

LevelMeansApproval
readReturns information and changes nothing.Approved when you select it.
writeCreates or modifies something in the customer's systems.Requires a second, explicit approval.
destructiveRemoves, revokes, cancels or otherwise takes something away.Requires a second, explicit approval.

The rules, in order

Classification takes the highest risk any rule produces. Ranking is read below write below destructive, so no rule can talk another one down.

  1. HTTP method. For an operation with one: GET, HEAD and OPTIONS are read. POST, PUT and PATCH are write. DELETE is destructive.
  2. Destructive verbs in the name. Tokens such as delete, destroy, drop, erase, purge, remove, revoke, terminate, truncate, uninstall, wipe, cancel and deactivate classify as destructive regardless of method. An MCP tool called purge_workspace carries no HTTP method at all, and it is still the most dangerous thing in the list.
  3. Write verbs in the name. Tokens such as create, update, send, post, share, invite, grant, assign, publish, upload, refund and pay classify as write.
  4. Identity markers. Names containing me, my, self, current_user, profile, inbox or assigned_to_me mark the capability as requiring a verified user identity, so it cannot be executed without one.

The name is tokenized before matching, so deleteAccount, delete_account and accounts.delete all classify the same way.

Selection and the second approval

Two separate calls, deliberately.

Shell
# Select. For a read capability this is the whole story.
curl -X POST \
  "$MEETEXT_API/v1/products/$PRODUCT_ID/capabilities/$CAP_ID/selection" \
  -H "authorization: Bearer $MEETEXT_API_KEY" \
  -H "content-type: application/json" \
  -d '{"enabled": true}'

# Approve. Required before a write or destructive capability ships.
curl -X POST \
  "$MEETEXT_API/v1/products/$PRODUCT_ID/capabilities/$CAP_ID/approval" \
  -H "authorization: Bearer $MEETEXT_API_KEY" \
  -H "content-type: application/json" \
  -d '{"approved": true}'

Both calls are recorded in the audit history with the actor who made them. When a customer's security team later asks who decided that their workspace could be posted into, the answer is a name and a timestamp rather than a policy document.

A capability that no longer exists in the source cannot be enabled. The call returns a conflict rather than quietly succeeding against a row that will never execute.

Re-approval when a source changes

Sources change. An argument becomes required, a field is renamed, an operation starts returning something else. Meetext detects this by comparing the discovery fingerprint against the one stored on the source.

When a capability's contract has changed:

  • Its approval is revoked.
  • It is flagged for a human to look at, with the change named rather than implied.
  • Publishing will not include it until somebody approves it again.
  • Every customer already installed keeps serving the package they were given. Nothing changes underneath them.

The deployment package

Publishing freezes the approved set into a versioned package: names, schemas, risk levels, and the MCP endpoint the package is served from. Installing a customer gives them that package.

The hosted MCP runtime answers tools/list from the calling environment's package, never from live capability rows. That is what makes the previous section true. Two customers on two different versions of your product are a normal state, not a bug.

Capabilities that act as a user

Some operations only make sense on behalf of a person: list_my_tasks means nothing without knowing whose. When a capability is marked as requiring user identity, the executor refuses the call unless the destination supplied a verified subject.

It is refused, not defaulted. Running it as a service account would return a plausible answer to the wrong question, which is the kind of failure nobody reports because nothing looked broken.

The refusal comes back as a tool result carrying isError, so the calling model can read it and say something useful. See the hosted MCP endpoint.