AI Filters
This page documents the filters of the AI chat and MCP: who can use them, the chat's prompts, agents and skills, its models and request settings.
The chat runs on your site's AI provider, so your site pays for each request. Three filters keep the cost in hand: ai/chat/can_use (who may chat), ai/model_preference (which model answers) and ai/max_tokens (how long an answer may be).
| Filter | Description |
|---|---|
unblock/ai/chat/can_use | Who can use the AI chat |
unblock/ai/mcp/can_use | Who can use MCP, OAuth sign-in included |
unblock/ai/prompts | System prompt parts before assembly |
unblock/ai/agents | Chat agents configuration |
unblock/ai/skills | Chat skills configuration |
unblock/ai/capabilities | What the site and user can do, for the skills that need it |
unblock/ai/timeout | AI request timeout |
unblock/ai/max_tokens | Maximum tokens for an answer |
unblock/ai/temperature | Temperature of a chat request |
unblock/ai/max_tool_rounds | Maximum agent-loop rounds per chat call |
unblock/ai/model_preference | Model of a chat request |
unblock/ai/image/model_preference | Image-generation model override |
ai/chat/can_use
Filter whether the current user can use the AI chat. Gates the chat REST endpoints and hides the Chat tab of the Unblock AI sidebar from excluded users.
apply_filters( 'unblock/ai/chat/can_use', bool $allowed );
| Parameter | Type | Description |
|---|---|---|
$allowed | bool | Whether the current user can use the chat |
Default: current_user_can( 'edit_posts' ), anyone who can open the block editor.
Helper: unbk_ai_chat_can_use()
Example: Restrict the Chat to Editors
add_filter( 'unblock/ai/chat/can_use', fn( $allowed ) => current_user_can( 'edit_others_posts' ) );
The filter narrows who gets the chat inside an enabled feature. When AI assistant is turned off in the Unblock settings, nobody gets it, whatever the filter returns.
Each tool then follows the capability of the action it persists, exactly like manual editing: unblock-update-css needs css/can_write, unblock-update-block-script needs unfiltered_html, and unblock-generate-image needs upload_files. A user missing one of them chats without that tool.
ai/mcp/can_use
Filter whether a user can use MCP. Gates the MCP REST endpoints, every Unblock ability registered on the Abilities API, the MCP view of the AI sidebar, and the OAuth sign-in of AI clients and each of their requests.
apply_filters( 'unblock/ai/mcp/can_use', bool $allowed, WP_User $user );
| Parameter | Type | Description |
|---|---|---|
$allowed | bool | Whether the user can use MCP |
$user | WP_User | The user checked: the current user, or the user an OAuth client acts as |
Default: user_can( $user, 'manage_options' ), administrators only.
Helper: unbk_ai_mcp_can_use( ?WP_User $user = null ), for the current user when none is given.
Example: Open MCP to Editors
add_filter( 'unblock/ai/mcp/can_use', fn( $allowed, $user ) => $allowed || user_can( $user, 'edit_others_posts' ), 10, 2 );
Test $user with user_can(), not current_user_can(): OAuth checks the user a client acts as before signing them in, so the current user may be nobody.
An MCP session lets an external client drive the editor with the permissions of the user who opened it. Keep it to roles you trust with automation, and remember the MCP Adapter's own transport permission applies on top. A user the filter stops allowing loses their OAuth clients at their next request.
The unblock/update-css ability additionally requires css/can_write: a user allowed to open MCP sessions but not to write CSS gets every other ability, and the editor drops the CSS of unblock/insert-blocks / unblock/replace-blocks calls.
ai/prompts
Filter AI system prompt parts before assembly.
apply_filters( 'unblock/ai/prompts', array $parts, string $agent );
| Parameter | Type | Description |
|---|---|---|
$parts | string[] | Array of prompt instruction strings |
$agent | string | Agent identifier ('builder', 'designer', 'content') |
Example: Add Custom Instruction
add_filter( 'unblock/ai/prompts', function( $parts, $agent ) {
$parts[] = 'Use {{ product.price|currency }} for product prices.';
return $parts;
}, 10, 2 );
Example: Agent-Specific Prompt
add_filter( 'unblock/ai/prompts', function( $parts, $agent ) {
if ( 'content' === $agent ) {
$parts[] = 'Always write in British English.';
}
return $parts;
}, 10, 2 );
ai/agents
Filter the chat's agents.
apply_filters( 'unblock/ai/agents', array $agents );
| Parameter | Type | Description |
|---|---|---|
$agents | array | Agents, keyed by identifier |
Each agent supports:
| Key | Type | Description |
|---|---|---|
label | string | Name shown in the agent selector |
description | string | What the agent does |
role | string | Prompt that sets the agent's role, by name |
prompts | string[] | Prompts added after the role, by name |
tools | string[] | Tools the agent may call, by the names MCP clients see, such as unblock-insert-blocks or unblock-update-css |
A prompt name is a file of the plugin's includes/ai/prompts/ folder, such as css-guidelines, or the absolute path of a PHP file that returns the prompt's text.
Built-in agents: builder, designer, content (the Writer). A request naming an agent that doesn't exist uses builder. When the filter leaves a single agent, the chat hides the agent selector.
Up to 1.0.0-rc.3, the chat named its tools in snake_case, such as update_styles. A filter that still uses those names gives the agent no tool, with no error. Write unblock-update-css.
Example: Restrict Designer Tools
add_filter( 'unblock/ai/agents', function( $agents ) {
// Only allow style changes, no attribute updates.
$agents['designer']['tools'] = [ 'unblock-update-css' ];
return $agents;
} );
ai/skills
Filter the chat's skills, the ones you add to a message with /.
apply_filters( 'unblock/ai/skills', array $skills );
| Parameter | Type | Description |
|---|---|---|
$skills | array | Skills, keyed by slug |
The slug is what the skill menu shows after the /. Each skill supports:
| Key | Type | Description |
|---|---|---|
label | string | Name shown on the skill's chip, and matched when you type after / |
description | string | Line under the slug in the skill menu |
icon | string | image, wand, pointer, smartphone, cursor, database or search. Any other value shows no icon |
prompts | string[] | Prompts added while the skill is on, by name, as for agents |
tools | string[] | Tools the skill adds to the agent's, such as unblock-generate-image |
capability | string | Key of the ai/capabilities map. The skill shows only when that key is true |
review_only | bool | Removes the agent's tools while the skill is on, so the AI answers without changing the page |
Example: Register Custom Skill
add_filter( 'unblock/ai/skills', function( $skills ) {
$skills['product-page'] = [
'label' => 'Product page',
'description' => 'Build WooCommerce product layouts',
'icon' => 'database',
'prompts' => [ get_stylesheet_directory() . '/ai/product-page.php' ],
'tools' => [],
'capability' => 'woocommerce',
];
return $skills;
} );
The prompt file returns its text:
<?php
// ai/product-page.php in your theme.
return 'Show the price with {{ product.price|currency }} and the add-to-cart button in the first screen.';
The woocommerce capability doesn't exist by default: add it with ai/capabilities, or the skill never shows.
Example: Remove a Built-in Skill
add_filter( 'unblock/ai/skills', function( $skills ) {
unset( $skills['generate-images'] );
return $skills;
} );
ai/capabilities
Filter what the site and the current user can do, for the skills that need it. A skill whose capability key is missing from the map, or false, doesn't show in the skill menu.
apply_filters( 'unblock/ai/capabilities', array $capabilities );
| Parameter | Type | Description |
|---|---|---|
$capabilities | array | Capability name => whether it's available (bool) |
Default: image_generation is true when a provider set up in Connectors can generate images and the current user can upload_files. The Generate images skill depends on it.
Example: Turn Off Image Generation
add_filter( 'unblock/ai/capabilities', fn( $capabilities ) => [ 'image_generation' => false ] + $capabilities );
Example: Add a Capability for a Custom Skill
add_filter( 'unblock/ai/capabilities', function( $capabilities ) {
$capabilities['woocommerce'] = class_exists( 'WooCommerce' );
return $capabilities;
} );
ai/timeout
Filter the AI request timeout.
apply_filters( 'unblock/ai/timeout', int $timeout );
| Parameter | Type | Description |
|---|---|---|
$timeout | int | Timeout in seconds. Default: 600 |
Example: Reduce Timeout
add_filter( 'unblock/ai/timeout', fn( $timeout ) => 120 );
ai/max_tokens
Filter the maximum tokens of a chat answer. It receives the response limit picked in the chat.
apply_filters( 'unblock/ai/max_tokens', int $max_tokens );
| Parameter | Type | Description |
|---|---|---|
$max_tokens | int | 4096 (Short), 16384 (Medium), 32768 (Long, the default) or 128000 (Unlimited) |
Example: Cap Every Answer at 16K Tokens
add_filter( 'unblock/ai/max_tokens', fn( $max_tokens ) => min( $max_tokens, 16384 ) );
ai/temperature
Filter the temperature of a chat request. It receives the temperature picked in the chat.
apply_filters( 'unblock/ai/temperature', ?float $temperature );
| Parameter | Type | Description |
|---|---|---|
$temperature | float | null | 0.2 (Precise), 0.5 (Balanced), 0.8 (Creative), or null with Auto |
Return null to leave the temperature to the model.
Example: Give Auto a Temperature
add_filter( 'unblock/ai/temperature', fn( $temperature ) => $temperature ?? 0.4 );
Some Google models refuse a custom temperature. A value returned for Auto reaches them too, and their requests fail.
ai/max_tool_rounds
Filter the maximum number of agent-loop rounds per chat call. The AI assistant re-prompts the model after each server-side tool execution (e.g. image generation) until the request is fully resolved or this budget is exhausted. Set to 1 to disable the loop entirely (single round, no continuation).
apply_filters( 'unblock/ai/max_tool_rounds', int $max_rounds );
| Parameter | Type | Description |
|---|---|---|
$max_rounds | int | Maximum round count. Default: 5. Minimum: 1 |
Example: Tighten the budget on rate-limited providers
add_filter( 'unblock/ai/max_tool_rounds', fn() => 3 );
ai/model_preference
Filter the model of a chat request. It receives the model picked in the chat. Return a model ID, a list of IDs in order of preference, or an empty string to let the provider choose. The filter runs for each round of an answer.
apply_filters( 'unblock/ai/model_preference', string $model );
| Parameter | Type | Description |
|---|---|---|
$model | string | ID of the model picked in the chat, or '' for Model (Auto) |
Returns: string|string[]. Model IDs are the provider's, as the chat's model list holds them.
Example: Use a Specific Model
add_filter( 'unblock/ai/model_preference', fn( $model ) => 'claude-sonnet-5' );
Example: Keep the User's Pick Within a List
add_filter( 'unblock/ai/model_preference', function( $model ) {
$allowed = [ 'claude-sonnet-5', 'claude-haiku-4-5-20251001' ];
return in_array( $model, $allowed, true ) ? $model : $allowed;
} );
ai/image/model_preference
Filter the model preference for AI image generation. Return a model identifier, or an array of identifiers for ordered fallback. Empty string lets the SDK pick any compatible model.
apply_filters( 'unblock/ai/image/model_preference', string|string[] $model );
| Parameter | Type | Description |
|---|---|---|
$model | string | string[] | Model identifier or ordered list. Default: '' |
Example: Force Gemini multimodal
add_filter( 'unblock/ai/image/model_preference', fn() => 'gemini-2.5-flash-image' );
Example: Fallback list
add_filter(
'unblock/ai/image/model_preference',
fn() => [ 'gemini-2.5-flash-image', 'dall-e-3', 'imagen-4.0-generate-001' ]
);
Next steps
- Chat skills: the built-in skills these filters change
- Data filters: register custom providers and functions
- Actions: plugin lifecycle hooks