Skip to content

Use the declarative tool surface

The declarative surface is the recommended model-facing API. It is a shape over the granular tools, not a second permission system. Each call resolves to the granular capability needed for its operation.

MCP name REST route Purpose
email_query POST …/email.query Select and read messages
email_act POST …/email.act File, mark, reply, forward, compose, or request deletion
email_await POST …/email.await Wait for matching mail or request state changes
email_requests POST /api/v1/approvals/email.requests List, inspect, approve, deny, or cancel requests

These names are not valid scope names. A grant uses the granular scopes that a particular operation resolves to.

{
"select": {
"mailbox_id": "mbx_…",
"folder": "inbox",
"filter": {
"from_contains": "@customer.example",
"seen": false
},
"order_by": "received_desc",
"limit": 25
},
"view": "summary"
}

view is metadata, summary (default), or full. Use fields to project only the values the model needs. Alcarta refuses filters that the provider cannot express instead of downloading the folder and scanning it locally.

{
"operation": {
"type": "message_actions",
"select": {
"mailbox_id": "mbx_…",
"message_ids": ["mh2.…"]
},
"actions": [{"type": "move", "destination": "archive"}]
},
"authorization": {
"mode": "execute_or_request_approval",
"reason": "Customer thread is resolved"
},
"cardinality": {"min": 1, "max": 1},
"idempotency_key": "case-4471-archive"
}

Authorization modes are:

  • execute_or_request_approval — act when directly authorized; otherwise file a request.
  • execute_or_fail — act now or return insufficient scope; never file silently.
  • request_approval — ask for review even when direct authority exists.
  • preview — resolve the selector and change nothing.

Use cardinality constraints whenever natural-language intent implies an expected count. Alcarta checks them before writing or acting.

Supported message actions are move, copy, trash, spam, archive, mark, delete_permanently, reply, and forward. A compose operation can send or create_draft. Permanent deletion always files a request. A folder action can request that a folder be emptied, bounded to the messages it held when the request was created.

{
"event": {
"type": "request_state_changed",
"request_ids": ["chk_…"]
},
"timeout_seconds": 14400,
"delivery": "poll"
}

For mail, use type: "message_received" and put the same selector under where. Return next_cursor as since_cursor on the next call so arrivals during model thinking time are not lost. A timeout is a successful result with timed_out: true.

{"op":"list","filter":{"state":["awaiting_approval"]},"limit":25}

op can be list, get, approve, deny, or cancel. The last four take ids; approve and deny require an idempotency key. Batch decisions report one outcome per ID, preserving tenant and visibility rules for every item.