> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobilerun.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Variables

> Pass dynamic data to your Mobilerun agents using the `variables` parameter. Variables enable parameterized workflows and reusable automation.

Custom variables are accessible in:

* **Agent prompts** via custom Jinja2 templates
* **Custom tools** via `ctx.shared_state.custom_variables`

***

## Quick Start

```python theme={null}
from mobilerun import MobileAgent, MobileConfig

# Define custom prompts that render variables
custom_prompts = {
    "manager_system": """
{{ instruction }}

{% if variables %}
Available variables:
{% for key, value in variables.items() %}
- {{ key }}: {{ value }}
{% endfor %}
{% endif %}
    """
}

# Create agent with variables
config = MobileConfig()

agent = MobileAgent(
    goal="Send email to recipient with subject",
    config=config,
    variables={"recipient": "john@example.com", "subject": "Update"},
    prompts=custom_prompts  # Required to see variables
)

result = await agent.run()
```

**Important:** Default prompts don't render variables. You must provide custom prompts via the `prompts` parameter.

***

## How Variables Work

When you pass `variables` to `MobileAgent`:

1. **Stored** in `MobileAgentState.custom_variables`
2. **Passed** to prompt templates as `variables` dict
3. **Rendered** in Jinja2 templates via `{% if variables %}` blocks
4. **Available** to all child agents throughout the workflow

**Access Summary:**

* ✅ Agent prompts (via custom Jinja2 templates)
* ✅ Agents can read and pass to tools as arguments
* ✅ Custom tools (via `ctx.shared_state.custom_variables`)

***

## Basic Usage

```python theme={null}
from mobilerun import MobileAgent, MobileConfig

# Define variables
variables = {
    "recipient": "alice@example.com",
    "message": "Hello from Mobilerun!"
}

# Custom prompt to render variables
custom_prompts = {
    "fast_agent_system": """
You are an agent that controls Android devices.

{% if variables %}
Available variables:
{% for key, value in variables.items() %}
- {{ key }}: {{ value }}
{% endfor %}
{% endif %}

Use these variables when executing tasks.
    """
}

# Create agent
config = MobileConfig()

agent = MobileAgent(
    goal="Send message to recipient",
    config=config,
    variables=variables,
    prompts=custom_prompts
)

result = await agent.run()
```

### Available Prompt Keys

Customize these prompts to render variables:

* `manager_system` - Manager agent system prompt
* `executor_system` - Executor agent system prompt
* `fast_agent_system` - FastAgent system prompt
* `fast_agent_user` - FastAgent user prompt

***

## Accessing Variables in Custom Tools

Custom tools can access variables via the `ctx` keyword argument (an `ActionContext` instance injected automatically):

```python theme={null}
from mobilerun import MobileAgent, MobileConfig

async def send_notification(title: str, *, ctx, **kwargs):
    """Send a notification using channel from custom variables.

    Args:
        title: Notification title
        ctx: ActionContext (injected automatically by the registry)
    """
    # Access custom variables via ctx.shared_state
    channel = ctx.shared_state.custom_variables.get("notification_channel", "default")
    return f"Sent '{title}' to {channel}"

custom_tools = {
    "send_notification": {
        "parameters": {
            "title": {"type": "string", "required": True},
        },
        "description": "Send a notification with title. Usage: {\"action\": \"send_notification\", \"title\": \"Alert\"}",
        "function": send_notification
    }
}

config = MobileConfig()

agent = MobileAgent(
    goal="Send notification with title 'Alert'",
    config=config,
    custom_tools=custom_tools,
    variables={"notification_channel": "alerts"}
)
```

***

## Use Cases

### Parameterized Workflows

```python theme={null}
# Define reusable workflow with different variables
for user in ["alice@example.com", "bob@example.com"]:
    agent = MobileAgent(
        goal="Send welcome email",
        config=config,
        variables={"recipient": user},
        prompts=custom_prompts
    )
    await agent.run()
```

### Configuration Data

```python theme={null}
variables = {
    "api_endpoint": "https://api.example.com/v2",
    "timeout": 30
}

agent = MobileAgent(
    goal="Call API endpoint",
    config=config,
    variables=variables,
    prompts=custom_prompts
)
```

***

## Key Points

1. **Custom prompts required** - Default prompts don't render variables in agent context
2. **Direct access in tools** - Custom tools access `ctx.shared_state.custom_variables` via the `ActionContext`
3. **Available to all agents** - Manager, Executor, FastAgent all receive variables
4. **Jinja2 templates** - Use `{% if variables %}` blocks in custom prompts
5. **Auto-injection** - `ctx` (ActionContext) is injected automatically by the tool registry

## Related Documentation

* [Custom Prompts](/framework/concepts/prompts) - How to customize agent prompts
* [Custom Tools](/framework/features/custom-tools) - Creating custom tool functions
* [MobileAgent SDK](/framework/sdk/droid-agent) - Complete API reference
