Skip to main content
Glama

engine_create_hypercube

Generate hypercubes for structured data analysis by specifying dimensions, measures, and row limits within Qlik Sense applications.

Instructions

Create hypercube for data analysis

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication ID
dimensionsYesList of dimension fields
max_rowsNoMaximum rows to return
measuresYesList of measure expressions

Implementation Reference

  • Registration of the 'engine_create_hypercube' tool in the MCP server's list_tools handler, including its schema definition.
    Tool(name="engine_create_hypercube", description="Create hypercube for data analysis with custom sorting options. IMPORTANT: To get top-N records, use qSortByExpression: 1 in dimension sorting with qExpression containing the measure formula (e.g., 'Count(field)' for ascending, '-Count(field)' for descending). Measure sorting is ignored by Qlik Engine.", inputSchema={ "type": "object", "properties": { "app_id": {"type": "string", "description": "Application ID"}, "dimensions": { "type": "array", "items": { "type": "object", "properties": { "field": {"type": "string", "description": "Field name for dimension"}, "label": {"type": "string", "description": "Optional label for dimension"}, "sort_by": { "type": "object", "properties": { "qSortByNumeric": {"type": "integer", "description": "Sort by numeric value (-1 desc, 0 none, 1 asc)", "default": 0}, "qSortByAscii": {"type": "integer", "description": "Sort by ASCII value (-1 desc, 0 none, 1 asc)", "default": 1}, "qSortByExpression": {"type": "integer", "description": "Use expression for sorting (0/1). For top-N results, set to 1 and use qExpression with measure formula", "default": 0}, "qExpression": {"type": "string", "description": "Expression for custom sorting. For top-N: 'Count(field)' for ascending, '-Count(field)' for descending", "default": ""} }, "additionalProperties": False } }, "additionalProperties": False }, "description": "List of dimension definitions with optional sorting" }, "measures": { "type": "array", "items": { "type": "object", "properties": { "expression": {"type": "string", "description": "Measure expression"}, "label": {"type": "string", "description": "Optional label for measure"}, "sort_by": { "type": "object", "properties": { "qSortByNumeric": {"type": "integer", "description": "Sort by numeric value (-1 desc, 0 none, 1 asc). NOTE: Measure sorting is ignored by Qlik Engine - use dimension sorting with qSortByExpression for top-N results", "default": -1} }, "additionalProperties": False } }, "additionalProperties": False }, "description": "List of measure definitions with optional sorting" }, "max_rows": {"type": "integer", "description": "Maximum rows to return", "default": 1000} }, "required": ["app_id"] })
  • MCP tool handler that processes calls to 'engine_create_hypercube', opens the app via Engine API, invokes the create_hypercube method, and returns the result.
    elif name == "engine_create_hypercube": app_id = arguments["app_id"] dimensions = arguments.get("dimensions", []) measures = arguments.get("measures", []) max_rows = arguments.get("max_rows", 1000) def _create_hypercube(): try: self.engine_api.connect() app_result = self.engine_api.open_doc(app_id, no_data=False) app_handle = app_result.get("qReturn", {}).get("qHandle", -1) if app_handle != -1: return self.engine_api.create_hypercube(app_handle, dimensions, measures, max_rows) else: raise Exception("Failed to open app") except Exception as e: return {"error": str(e)} finally: self.engine_api.disconnect() result = await asyncio.to_thread(_create_hypercube) return [ TextContent( type="text", text=json.dumps(result, indent=2, ensure_ascii=False) ) ]
  • Core implementation of hypercube creation in QlikEngineAPI class. Constructs hypercube definition from dimensions and measures, creates session object, retrieves layout with data, handles sorting and pagination.
    def create_hypercube( self, app_handle: int, dimensions: List[Dict[str, Any]] = None, measures: List[Dict[str, Any]] = None, max_rows: int = 1000, ) -> Dict[str, Any]: """Create hypercube for data extraction with proper structure.""" try: # Handle empty dimensions/measures if dimensions is None: dimensions = [] if measures is None: measures = [] # Convert old format (list of strings) to new format (list of dicts) for backward compatibility converted_dimensions = [] for dim in dimensions: if isinstance(dim, str): # Old format - just field name converted_dimensions.append({ "field": dim, "sort_by": { "qSortByNumeric": 0, "qSortByAscii": 1, # Default: ASCII ascending "qSortByExpression": 0, "qExpression": "" } }) else: # New format - dict with field and sort options # Set defaults if not specified if "sort_by" not in dim: dim["sort_by"] = { "qSortByNumeric": 0, "qSortByAscii": 1, # Default: ASCII ascending "qSortByExpression": 0, "qExpression": "" } converted_dimensions.append(dim) converted_measures = [] for measure in measures: if isinstance(measure, str): # Old format - just expression converted_measures.append({ "expression": measure, "sort_by": { "qSortByNumeric": -1 # Default: numeric descending } }) else: # New format - dict with expression and sort options # Set defaults if not specified if "sort_by" not in measure: measure["sort_by"] = { "qSortByNumeric": -1 # Default: numeric descending } converted_measures.append(measure) # Create correct hypercube structure hypercube_def = { "qDimensions": [ { "qDef": { "qFieldDefs": [dim["field"]], "qSortCriterias": [ { "qSortByState": 0, "qSortByFrequency": 0, "qSortByNumeric": dim["sort_by"].get("qSortByNumeric", 0), "qSortByAscii": dim["sort_by"].get("qSortByAscii", 1), "qSortByLoadOrder": 0, "qSortByExpression": dim["sort_by"].get("qSortByExpression", 0), "qExpression": {"qv": dim["sort_by"].get("qExpression", "")}, } ], }, "qNullSuppression": False, "qIncludeElemValue": True, } for dim in converted_dimensions ], "qMeasures": [ { "qDef": {"qDef": measure["expression"], "qLabel": measure.get("label", f"Measure_{i}")}, "qSortBy": measure["sort_by"], } for i, measure in enumerate(converted_measures) ], "qInitialDataFetch": [ { "qTop": 0, "qLeft": 0, "qHeight": max_rows, "qWidth": len(converted_dimensions) + len(converted_measures), } ], "qSuppressZero": False, "qSuppressMissing": False, "qMode": "S", "qInterColumnSortOrder": list(range(len(converted_dimensions) + len(converted_measures))), } obj_def = { "qInfo": { "qId": f"hypercube-{len(converted_dimensions)}d-{len(converted_measures)}m", "qType": "HyperCube", }, "qHyperCubeDef": hypercube_def, } result = self.send_request( "CreateSessionObject", [obj_def], handle=app_handle ) if "qReturn" not in result or "qHandle" not in result["qReturn"]: return {"error": "Failed to create hypercube", "response": result} cube_handle = result["qReturn"]["qHandle"] # Получаем layout с данными layout = self.send_request("GetLayout", [], handle=cube_handle) if "qLayout" not in layout or "qHyperCube" not in layout["qLayout"]: return {"error": "No hypercube in layout", "layout": layout} hypercube = layout["qLayout"]["qHyperCube"] return { "hypercube_handle": cube_handle, "hypercube_data": hypercube, "dimensions": converted_dimensions, "measures": converted_measures, "total_rows": hypercube.get("qSize", {}).get("qcy", 0), "total_columns": hypercube.get("qSize", {}).get("qcx", 0), } except Exception as e: return {"error": str(e), "details": "Error in create_hypercube method"}

Other Tools

Related 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/bintocher/qlik-sense-mcp'

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