Skip to main content
Glama
PiwikPRO

Piwik PRO MCP Server

Official
by PiwikPRO

variables_create

Create new variables in Piwik PRO Tag Manager by specifying attributes like name and type. Supports data layer, custom JavaScript, and other variable templates for analytics configuration.

Instructions

Create a new variable in Piwik PRO Tag Manager using JSON attributes.

    Only variable types listed by `templates_list_variables()` are supported. Any other type will be refused.

    This tool uses a simplified interface with 2 parameters: app_id and attributes.
    Use tools_parameters_get("variables_create") to get the complete JSON schema
    with all available fields, types, and validation rules.

    💡 TIP: Use these tools to discover available templates and their requirements:
    - templates_list_variables() - List all available variable templates
    - templates_get_variable(template_name='data_layer') - Get complete template info with field mutability

    Args:
        app_id: UUID of the app
        attributes: Dictionary containing variable attributes for creation. Required fields are
                   'name' and 'variable_type'. Field 'is_active' is optional.

    Returns:
        Dictionary containing created variable information including:
        - data: Created variable object with id, name, template, and attributes
        - Variable configuration and value settings

    Parameter Discovery:
        Use tools_parameters_get("variables_create") to get the complete JSON schema
        for all available fields. This returns validation rules, field types, and examples.

    Template Discovery:
        Use piwik_get_available_variable_templates() to see all available templates, then
        use piwik_get_variable_template(template_name) for detailed template information.

    Examples:
        # Get available parameters first
        schema = tools_parameters_get("variables_create")

        # Discover available templates
        templates = templates_list_variables()
        template_info = templates_get_variable(template_name='data_layer')

        # Create data layer variable
        attributes = {
            "name": "Order Total",
            "variable_type": "data_layer",
            "data_layer_variable_name": "ecommerce.purchase.value",
            "default_value": "0"
        }

        # Create custom JavaScript variable
        attributes = {
            "name": "User Status",
            "variable_type": "custom_javascript",
            "value": "return localStorage.getItem('userId') ? 'logged_in' : 'guest';"
        }
    

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
app_idYes
attributesYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataYes

Implementation Reference

  • MCP tool handler for 'variables_create': decorated with @mcp.tool and delegates to the create_variable helper function.
    @mcp.tool(annotations={"title": "Piwik PRO: Create Variable"})
    def variables_create(app_id: str, attributes: dict) -> TagManagerSingleResponse:
        """Create a new variable in Piwik PRO Tag Manager using JSON attributes.
    
        Only variable types listed by `templates_list_variables()` are supported. Any other type will be refused.
    
        This tool uses a simplified interface with 2 parameters: app_id and attributes.
        Use tools_parameters_get("variables_create") to get the complete JSON schema
        with all available fields, types, and validation rules.
    
        💡 TIP: Use these tools to discover available templates and their requirements:
        - templates_list_variables() - List all available variable templates
        - templates_get_variable(template_name='data_layer') - Get complete template info with field mutability
    
        Args:
            app_id: UUID of the app
            attributes: Dictionary containing variable attributes for creation. Required fields are
                       'name' and 'variable_type'. Field 'is_active' is optional.
    
        Returns:
            Dictionary containing created variable information including:
            - data: Created variable object with id, name, template, and attributes
            - Variable configuration and value settings
    
        Parameter Discovery:
            Use tools_parameters_get("variables_create") to get the complete JSON schema
            for all available fields. This returns validation rules, field types, and examples.
    
        Template Discovery:
            Use piwik_get_available_variable_templates() to see all available templates, then
            use piwik_get_variable_template(template_name) for detailed template information.
    
        Examples:
            # Get available parameters first
            schema = tools_parameters_get("variables_create")
    
            # Discover available templates
            templates = templates_list_variables()
            template_info = templates_get_variable(template_name='data_layer')
    
            # Create data layer variable
            attributes = {
                "name": "Order Total",
                "variable_type": "data_layer",
                "data_layer_variable_name": "ecommerce.purchase.value",
                "default_value": "0"
            }
    
            # Create custom JavaScript variable
            attributes = {
                "name": "User Status",
                "variable_type": "custom_javascript",
                "value": "return localStorage.getItem('userId') ? 'logged_in' : 'guest';"
            }
        """
        return create_variable(app_id, attributes)
  • Helper function that handles validation with VariableCreateAttributes schema, type checking, and API call to create the variable.
    def create_variable(app_id: str, attributes: dict) -> TagManagerSingleResponse:
        try:
            client = create_piwik_client()
    
            # Validate attributes directly against the variable create model
            validated_attrs = validate_data_against_model(attributes, VariableCreateAttributes)
    
            # Convert to dictionary and filter out None values
            create_kwargs = {k: v for k, v in validated_attrs.model_dump(exclude_none=True).items()}
    
            # Extract required fields
            name = create_kwargs.pop("name")
            variable_type = create_kwargs.pop("variable_type")
    
            # Enforce assets-driven allowlist via model validation (retained as a safety check)
            allowed_variable_types = set(list_template_names("tag_manager/variables"))
            if variable_type not in allowed_variable_types:
                raise RuntimeError(
                    f"Unsupported variable type '{variable_type}'. Use templates_list_variables() to discover options."
                )
    
            response = client.tag_manager.create_variable(
                app_id=app_id, name=name, variable_type=variable_type, **create_kwargs
            )
            return TagManagerSingleResponse(**response)
        except BadRequestError as e:
            raise RuntimeError(
                f"Failed to create variable: API request failed (HTTP {e.status_code}): {e.message}. "
                f"Full response: {e.response_data}"
            )
        except Exception as e:
            raise RuntimeError(f"Failed to create variable: {str(e)}")
  • Pydantic model used for input validation of 'variables_create' tool parameters, enforcing structure and template-based variable_type validation.
    class VariableCreateAttributes(BaseModel):
        """Attributes for creating variables with template-specific fields."""
    
        model_config = {"extra": "allow"}  # Allow additional fields for template-specific attributes
    
        name: str = Field(..., description="Variable name")
        variable_type: str = Field(..., description="Variable type")
        is_active: Optional[bool] = Field(None, description="Whether variable is active")
    
        # Data Layer variable fields
        data_layer_variable_name: Optional[str] = Field(None, description="Data layer property name to access")
        data_layer_version: Optional[str] = Field(None, description="Data layer version (1 or 2)")
        default_value: Optional[str] = Field(None, description="Fallback value when property is undefined")
        decode_uri_component: Optional[bool] = Field(None, description="Whether to decode URI components")
        # Custom JavaScript variable fields
        code: Optional[str] = Field(None, description="JavaScript code to execute")
        # Constant variable fields
        value: Optional[str] = Field(None, description="Constant value for constant variables")
        # URL variable fields
        url_component: Optional[str] = Field(None, description="URL component to extract (host, path, query, etc.)")
        # Cookie variable fields
        cookie_name: Optional[str] = Field(None, description="Name of cookie to read")
        # Random number variable fields
        min_value: Optional[int] = Field(None, description="Minimum value for random number")
        max_value: Optional[int] = Field(None, description="Maximum value for random number")
    
        @field_validator("variable_type")
        @classmethod
        def _validate_variable_type(cls, v: str) -> str:
            allowed = set(list_template_names("tag_manager/variables"))
            if v not in allowed:
                raise ValueError(f"Unsupported variable type '{v}'. Use templates_list_variables() to discover options.")
            return v
  • Registration call to register_variable_tools(mcp), which defines and registers the 'variables_create' handler with the MCP server.
    register_variable_tools(mcp)
  • Mapping of 'variables_create' tool name to its VariableCreateAttributes schema model for dynamic schema retrieval.
    "variables_create": VariableCreateAttributes,
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key traits: it's a creation tool (implying mutation), specifies constraints (only supported variable types, refusal of others), and outlines the simplified interface. However, it doesn't mention permissions, rate limits, or error handling, leaving some behavioral aspects uncovered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with key information but includes extensive examples and repeated directives (e.g., 'Parameter Discovery' and 'Template Discovery' sections reiterate earlier tips). While informative, this redundancy and length reduce efficiency, making it less concise than ideal for an agent's quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (creation tool with nested objects, 0% schema coverage, no annotations, but with output schema), the description is highly complete. It covers purpose, usage, parameters, constraints, discovery methods, and examples, and since an output schema exists, it needn't detail return values. This provides all necessary context for effective tool use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Given 0% schema description coverage, the description fully compensates by explaining both parameters: app_id is a 'UUID of the app', and attributes is a 'Dictionary containing variable attributes for creation' with required fields 'name' and 'variable_type' and optional 'is_active'. It also provides examples and directs to tools_parameters_get for complete schema details, adding significant value beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Create a new variable') and resource ('in Piwik PRO Tag Manager'), distinguishing it from sibling tools like variables_get, variables_list, and variables_update. It specifies the interface ('using JSON attributes') and constraints ('Only variable types listed by templates_list_variables() are supported'), making the purpose highly specific and differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool versus alternatives: it directs users to templates_list_variables() for supported types and tools_parameters_get('variables_create') for the complete schema. It also mentions prerequisites like required fields ('name' and 'variable_type') and offers tips for discovery, clearly outlining the workflow and alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PiwikPRO/mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server