Permissions API
ToolPermissionContext
Passed to the can_use_tool callback as the third argument.
ToolPermissionContext(
signal: Any | None, # reserved for future abort-signal support; always None
suggestions: list[PermissionUpdate], # advisory rule changes accumulated by the framework
)
The tool name and input are passed as the first two positional arguments to the callback, not via the context object:
async def my_guard(
tool_name: str, # first arg — the tool being requested
tool_input: dict, # second arg — the tool's input dict
ctx: ToolPermissionContext,
) -> PermissionResult:
...
PermissionResultAllow
Allow the tool to execute, optionally with a modified input:
from agentix import PermissionResultAllow
# Simple allow
return PermissionResultAllow()
# Allow with input modification
return PermissionResultAllow(
updated_input={**original_input, "command": sanitized_command}
)
| Field | Type | Default | Description |
|---|---|---|---|
updated_input | dict | None | None | Replacement input; None = use original |
updated_permissions | any | None | Advisory permission state changes |
PermissionResultDeny
Deny the tool from executing:
from agentix import PermissionResultDeny
# Soft deny — agent receives the message and may retry
return PermissionResultDeny(message="Shell access is disabled.")
# Hard deny — raises AgentixInterruptedError immediately
return PermissionResultDeny(message="Blocked.", interrupt=True)
| Field | Type | Default | Description |
|---|---|---|---|
message | str | "" | Reason shown to the agent |
interrupt | bool | False | True = hard abort |
CanUseTool protocol
The can_use_tool callback type:
from typing import Awaitable, Callable
from agentix import PermissionResultAllow, PermissionResultDeny, ToolPermissionContext
CanUseTool = Callable[
[str, dict, ToolPermissionContext],
Awaitable[PermissionResultAllow | PermissionResultDeny]
]
PermissionUpdate
Advisory rule change carried in ToolPermissionContext.suggestions and returnable via PermissionResultAllow.updated_permissions:
PermissionUpdate(
type: str | None, # "addRules" | "replaceRules" | "removeRules"
# | "setMode" | "addDirectories" | "removeDirectories"
rules: list[PermissionRuleValue] | None,
behavior: str | None, # "allow" | "deny" | "ask"
mode: str | None,
directories: list[str] | None,
)
Permission modes
See Tools & Permissions guide for the full table.
Change permission mode at runtime:
client.set_permission_mode("bypassPermissions")
PermissionHookContext
Fired via the PermissionRequest hook when a permission decision is made:
PermissionHookContext(
tool_name: str,
decision: str, # "allow" | "deny"
session_id: str,
)