Approval policies tools
MCP tools for Approval policies: approval_policies_get, approval_policies_overrides_delete, approval_policies_overrides_set, approval_policies_update.
approval_policies_get: Get the approval policyapproval_policies_overrides_delete: Delete an approval policy overrideapproval_policies_overrides_set: Set an approval policy overrideapproval_policies_update: Update the approval policy
approval_policies_get
Get the approval policy. Operation approval_policies.get · Organization level · permission approvals:read · risk tier read · since M2
Returns the organization's approval policy:
tiers: what agents, apps and MCP clients may do per risk tier (allow,require_approvalordeny). Until the policy is saved: write and financialallow, compliance and securityrequire_approval.twoPersonFor: the operations that need a second person's approval, whoever calls.amountLimits: for operations that move money, the amount per currency at or below which a call runs at once (micros as a string).overrides: stricter rules for single entities, agents and apps. The strictest applicable rule wins.
Without a saved policy id is null and version 0. availableOperations lists every operation a policy
can name. The policy applies in both modes.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
This tool takes no arguments.
- Read-only: changes nothing;
idempotency_keyis ignored.
Errors
permission_denied: You can't see the approval policy here.
Examples
Brand changes need a second person; one agent may not move money
Arguments:
{}
Result output:
{
"object": "approval_policy",
"id": "apol_01m4ttwd3veh9apbewxheq5xh9",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "allow",
"financial": "allow",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": ["brands.update"],
"amountLimits": [],
"version": 2,
"updatedAt": "2026-10-13T14:30:00.000Z",
"overrides": [
{
"id": "apol_01m4ttwd3veh9apbewxheq5xhb",
"object": "approval_policy_override",
"entityId": null,
"agentId": "agt_01m4ttwd3veh9apbewxheq5xhc",
"clientId": null,
"tiers": {
"write": null,
"financial": "deny",
"compliance": null,
"security": null
},
"twoPersonFor": [],
"amountLimits": [],
"version": 1,
"updatedAt": "2026-10-13T14:30:00.000Z"
}
],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}
No policy saved yet
Arguments:
{}
Result output:
{
"object": "approval_policy",
"id": null,
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "allow",
"financial": "allow",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": [],
"amountLimits": [],
"version": 0,
"updatedAt": null,
"overrides": [],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}
approval_policies_overrides_delete
Delete an approval policy override. Operation approval_policies.overrides.delete · Organization level · permission approvals:admin · risk tier security · since M10
Deletes one approval policy override (apol_…, from overrides in approval_policies.get). Calls at its
entity, or by its agent or app, follow the organization's policy (and any other override that applies)
again. Send the override's version to avoid deleting a change you haven't seen. The organization's own
policy can't be deleted; change it with approval_policies.update. Returns the whole approval policy.
Owners and admins only, with a sign-in in the last 15 minutes.
Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (apol_…) | yes | – |
version | integer | no | (1–9007199254740991) |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
resource_not_found: No override with this ID exists in the organization (the organization's own policy isn't one).version_conflict: The override changed since you read it (version); read it again.fresh_auth_required: You last signed in more than 15 minutes ago.permission_denied: Only owners and admins change the approval policy.
Example
Remove an agent's override
Arguments:
{
"id": "apol_01m4ttwd3veh9apbewxheq5xhb",
"version": 1,
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "approval_policy",
"id": "apol_01m4ttwd3veh9apbewxheq5xh9",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "allow",
"financial": "allow",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": ["brands.update"],
"amountLimits": [],
"version": 2,
"updatedAt": "2026-10-13T14:30:00.000Z",
"overrides": [],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}
approval_policies_overrides_set
Set an approval policy override. Operation approval_policies.overrides.set · Organization level · permission approvals:admin · risk tier security · since M10
Creates or changes the approval policy override for one legal entity (entityId), one agent (agentId)
or one app (clientId, its OAuth client). Send exactly one of them.
An override has the same parts as the organization's policy: tiers (each tier you send replaces the
current one; null removes it), twoPersonFor and amountLimits (each list you send replaces the current
one). The strictest applicable rule wins: a call is checked against the organization's policy and every
override for its entity, its agent and its app, so an override can only tighten what the organization
allows, never loosen it.
Agents and apps are referenced by ID; the entity must belong to the organization. Returns the whole approval policy. Owners and admins only, with a sign-in in the last 15 minutes.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
entityId | ID (ent_…) | no | – |
agentId | ID (agt_…) | no | – |
clientId | ID (ocl_…) | no | – |
tiers | object | no | – |
twoPersonFor | array of string | no | (at most 50 items) |
amountLimits | array of object | no | (at most 100 items) |
version | integer | no | (0–9007199254740991) |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: The override names no subject or several, an unknown or ineligible operation, compliance or security set to allow, or amount limits that don't fit (details.issues).resource_not_found: No legal entity with this ID exists in the organization.approval_policy_override_limit_reached: The organization already has 100 overrides.version_conflict: The override changed since you read it (version); read it again.fresh_auth_required: You last signed in more than 15 minutes ago.permission_denied: Only owners and admins change the approval policy.
Examples
One agent may not move money
Arguments:
{
"agentId": "agt_01m4ttwd3veh9apbewxheq5xhc",
"tiers": {
"financial": "deny"
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "approval_policy",
"id": "apol_01m4ttwd3veh9apbewxheq5xh9",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "allow",
"financial": "allow",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": ["brands.update"],
"amountLimits": [],
"version": 2,
"updatedAt": "2026-10-13T14:30:00.000Z",
"overrides": [
{
"id": "apol_01m4ttwd3veh9apbewxheq5xhb",
"object": "approval_policy_override",
"entityId": null,
"agentId": "agt_01m4ttwd3veh9apbewxheq5xhc",
"clientId": null,
"tiers": {
"write": null,
"financial": "deny",
"compliance": null,
"security": null
},
"twoPersonFor": [],
"amountLimits": [],
"version": 1,
"updatedAt": "2026-10-13T14:30:00.000Z"
}
],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}
Refunds at one legal entity need a person above EUR 200
Arguments:
{
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"amountLimits": [
{
"operationId": "refunds.create",
"perCall": {
"amount": "200000000",
"currency": "EUR"
}
}
],
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "approval_policy",
"id": "apol_01m4ttwd3veh9apbewxheq5xh9",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "allow",
"financial": "allow",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": ["brands.update"],
"amountLimits": [],
"version": 2,
"updatedAt": "2026-10-13T14:30:00.000Z",
"overrides": [
{
"id": "apol_01m4ttwd3veh9apbewxheq5xhb",
"object": "approval_policy_override",
"entityId": "ent_01m4ttwd3veh9apbewxheq5xh4",
"agentId": null,
"clientId": null,
"tiers": {
"write": null,
"financial": null,
"compliance": null,
"security": null
},
"twoPersonFor": [],
"amountLimits": [
{
"operationId": "refunds.create",
"perCall": {
"amount": "200000000",
"currency": "EUR"
}
}
],
"version": 1,
"updatedAt": "2026-10-13T14:30:00.000Z"
}
],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}
approval_policies_update
Update the approval policy. Operation approval_policies.update · Organization level · permission approvals:admin · risk tier security · since M2
Changes the organization's approval policy. Each part you send replaces the current one; leave one out to keep it.
tiers: what agents, apps and MCP clients may do per risk tier:allow,require_approvalordeny(a denied call fails withapproval_policy_denied). Compliance and security arerequire_approvalordeny, neverallow: those calls always need a person.twoPersonFor: operations that need a second person's approval, whoever calls. For a call by an agent or app, two people approve.amountLimits: for operations that carry an amount, the amount per currency at or below which a call runs at once (micros as a string). Above it, in a currency without a limit, or without an amount, an agent's or app's call needs approval; for people the limits apply to the operations intwoPersonFor.
Only changes inside the organization that support dry runs can be named (availableOperations in
approval_policies.get), never the approvals operations themselves. Overrides for single entities, agents
and apps are set with approval_policies.overrides.set. Requests already waiting for approval keep their
requirement. Owners and admins only, with a sign-in in the last 15 minutes.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
tiers | object | no | – |
twoPersonFor | array of string | no | (at most 50 items) |
amountLimits | array of object | no | (at most 100 items) |
version | integer | no | (0–9007199254740991) |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: The policy names an unknown or ineligible operation, sets compliance or security to allow, or its amount limits don't fit (details.issues).version_conflict: The policy changed since you read it (version); read it again.fresh_auth_required: You last signed in more than 15 minutes ago.permission_denied: Only owners and admins change the approval policy.
Examples
Require a second person for brand changes
Arguments:
{
"twoPersonFor": ["brands.update"],
"version": 1,
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "approval_policy",
"id": "apol_01m4ttwd3veh9apbewxheq5xh9",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "allow",
"financial": "allow",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": ["brands.update"],
"amountLimits": [],
"version": 2,
"updatedAt": "2026-10-13T14:30:00.000Z",
"overrides": [],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}
Agents and apps may not change anything without approval
Arguments:
{
"tiers": {
"write": "require_approval",
"financial": "require_approval"
},
"version": 2,
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "approval_policy",
"id": "apol_01m4ttwd3veh9apbewxheq5xh9",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "require_approval",
"financial": "require_approval",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": ["brands.update"],
"amountLimits": [],
"version": 3,
"updatedAt": "2026-10-13T14:30:00.000Z",
"overrides": [],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}
Turn the two-person rule off
Arguments:
{
"twoPersonFor": [],
"amountLimits": [],
"version": 2,
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "approval_policy",
"id": "apol_01m4ttwd3veh9apbewxheq5xh9",
"orgId": "org_01m4ttwd3veh9apbewxheq5xh3",
"tiers": {
"write": "allow",
"financial": "allow",
"compliance": "require_approval",
"security": "require_approval"
},
"twoPersonFor": [],
"amountLimits": [],
"version": 3,
"updatedAt": "2026-10-13T14:30:00.000Z",
"overrides": [],
"availableOperations": [
{
"id": "brands.update",
"summary": "Update a brand",
"riskTier": "write",
"scope": "brand",
"amounts": false
},
{
"id": "members.remove",
"summary": "Remove a member",
"riskTier": "security",
"scope": "org",
"amounts": false
}
]
}