get_app_variables
Retrieve variables from Qlik Sense applications with pagination and search filters. Filter variables by source (script or UI) and search by name, text, or numeric values using wildcards.
Instructions
Return variables split by source (script/ui) with pagination and wildcard search.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application GUID | |
| limit | No | Max variables to return (default: 10, max: 100) | |
| offset | No | Offset for pagination (default: 0) | |
| created_in_script | No | Return only variables created in script (true/false). If omitted, return both | |
| search_string | No | Wildcard search by variable name or text value (* and % supported), case-insensitive by default | |
| search_number | No | Wildcard search among numeric variable values (* and % supported) | |
| case_sensitive | No | Case sensitive matching for search_string |
Implementation Reference
- qlik_sense_mcp_server/server.py:344-360 (registration)Registration of the 'get_app_variables' tool including its input schema definition in the list_tools handler.Tool( name="get_app_variables", description="Return variables split by source (script/ui) with pagination and wildcard search.", inputSchema={ "type": "object", "properties": { "app_id": {"type": "string", "description": "Application GUID"}, "limit": {"type": "integer", "description": "Max variables to return (default: 10, max: 100)", "default": 10}, "offset": {"type": "integer", "description": "Offset for pagination (default: 0)", "default": 0}, "created_in_script": {"type": "string", "description": "Return only variables created in script (true/false). If omitted, return both"}, "search_string": {"type": "string", "description": "Wildcard search by variable name or text value (* and % supported), case-insensitive by default"}, "search_number": {"type": "string", "description": "Wildcard search among numeric variable values (* and % supported)"}, "case_sensitive": {"type": "boolean", "description": "Case sensitive matching for search_string", "default": False} }, "required": ["app_id"], } ),
- qlik_sense_mcp_server/server.py:761-855 (handler)Main handler logic for executing the 'get_app_variables' tool in the call_tool handler, including parameter validation, filtering, pagination, searching, and calling the engine API helper.elif name == "get_app_variables": app_id = arguments["app_id"] limit = arguments.get("limit", 10) offset = arguments.get("offset", 0) created_in_script_arg = arguments.get("created_in_script", None) search_string = arguments.get("search_string") search_number = arguments.get("search_number") case_sensitive = arguments.get("case_sensitive", False) if limit is None or limit < 1: limit = 10 if limit > 100: limit = 100 if offset is None or offset < 0: offset = 0 def _to_bool(value: Any, default: Optional[bool] = None) -> Optional[bool]: if value is None: return default if isinstance(value, bool): return value if isinstance(value, int): return value != 0 if isinstance(value, str): v = value.strip().lower() if v in ("true", "1", "yes", "y"): return True if v in ("false", "0", "no", "n"): return False return default created_in_script = _to_bool(created_in_script_arg, None) def _wildcard_to_regex(pattern: str, case_sensitive_flag: bool): import re escaped = re.escape(pattern).replace("\\*", ".*").replace("%", ".*") regex = f"^{escaped}$" return re.compile(regex, 0 if case_sensitive_flag else re.IGNORECASE) def _get_variables(): try: self.engine_api.connect() app_result = self.engine_api.open_doc_safe(app_id, no_data=False) app_handle = app_result.get("qReturn", {}).get("qHandle", -1) if app_handle == -1: return {"error": "Failed to open app"} # Use the alternative method for getting variables var_list = self.engine_api._get_user_variables(app_handle) or [] prepared = [] for v in var_list: name = v.get("name", "") text_val = v.get("text_value", "") is_script = v.get("is_script_created", False) prepared.append({ "name": name, "text_value": text_val if text_val is not None else "", "is_script": is_script }) if created_in_script is True: prepared = [x for x in prepared if x["is_script"]] elif created_in_script is False: prepared = [x for x in prepared if not x["is_script"]] else: # По умолчанию показываем только переменные из UI prepared = [x for x in prepared if not x["is_script"]] if search_string: rx = _wildcard_to_regex(search_string, case_sensitive) prepared = [x for x in prepared if rx.match(x["name"]) or rx.match(x.get("text_value", ""))] from_script = [x for x in prepared if x["is_script"]] from_ui = [x for x in prepared if not x["is_script"]] def _slice_and_map(items): sliced = items[offset:offset + limit] result_map = {} for it in sliced: val = it.get("text_value", "") result_map[it["name"]] = val return result_map res_script = _slice_and_map(from_script) res_ui = _slice_and_map(from_ui) return { "variables_from_script": res_script if res_script else "", "variables_from_ui": res_ui if res_ui else "" } except Exception as e: return {"error": str(e)} finally: self.engine_api.disconnect() result = await asyncio.to_thread(_get_variables) return [TextContent(type="text", text=json.dumps(result, indent=2, ensure_ascii=False))]
- Helper method in QlikEngineAPI class that retrieves user-created variables (excluding system ones) using CreateSessionObject with VariableList, which is called by the main handler.def _get_user_variables(self, app_handle: int) -> List[Dict[str, Any]]: """Get only user-created variables (exclude system).""" try: # Create VariableList object variable_list_def = { "qInfo": {"qType": "VariableList"}, "qVariableListDef": { "qType": "variable", "qShowReserved": False, # Exclude system variables "qShowConfig": False, "qData": {"tags": "/tags"} } } variable_list_response = self.send_request("CreateSessionObject", [variable_list_def], handle=app_handle) if "qReturn" not in variable_list_response: return [] variable_list_handle = variable_list_response["qReturn"]["qHandle"] layout_response = self.send_request("GetLayout", [], handle=variable_list_handle) variables = layout_response.get("qLayout", {}).get("qVariableList", {}).get("qItems", []) user_variables = [] for variable in variables: # Additional filter for user variables only if not variable.get("qIsReserved", False) and not variable.get("qIsConfig", False): definition = variable.get("qDefinition", "") user_variables.append({ "name": variable.get("qName", ""), "text_value": definition, "is_script_created": variable.get("qIsScriptCreated", False) }) return user_variables except Exception as e: return []