MCP Server for Qlik Sense Enterprise APIs
Project description
Qlik Sense MCP Server
Model Context Protocol (MCP) server for integration with Qlik Sense Enterprise APIs. Provides unified interface for Repository API and Engine API operations through MCP protocol.
Table of Contents
- Overview
- Features
- Installation
- Configuration
- Usage
- API Reference
- Architecture
- Development
- Troubleshooting
- License
Overview
Qlik Sense MCP Server bridges Qlik Sense Enterprise with systems supporting Model Context Protocol. Server provides 6 essential tools for application metadata retrieval and data analysis operations.
Key Features
- Unified API: Single interface for Qlik Sense Repository and Engine APIs
- Security: Certificate-based authentication support
- Performance: Optimized queries and direct API access
- Analytics: Advanced data analysis and hypercube creation
- Metadata: Comprehensive application and field information
Features
Available Tools
| Tool | Description | API | Status |
|---|---|---|---|
get_apps |
Get comprehensive list of applications with metadata | Repository | ✅ |
get_app_details |
Get detailed application analysis including data model | Engine | ✅ |
engine_get_script |
Extract load script from application | Engine | ✅ |
engine_get_field_values |
Get field values with frequency information | Engine | ✅ |
engine_get_field_statistics |
Get comprehensive field statistics | Engine | ✅ |
engine_create_hypercube |
Create hypercube for data analysis | Engine | ✅ |
Installation
Quick Start with uvx (Recommended)
The easiest way to use Qlik Sense MCP Server is with uvx:
uvx qlik-sense-mcp-server
This command will automatically install and run the latest version without affecting your system Python environment.
Alternative Installation Methods
From PyPI
pip install qlik-sense-mcp-server
From Source (Development)
git clone https://github.com/bintocher/qlik-sense-mcp.git
cd qlik-sense-mcp
make dev
System Requirements
- Python 3.12+
- Qlik Sense Enterprise
- Valid certificates for authentication
- Network access to Qlik Sense server (ports 4242, 4747)
Setup
- Setup certificates
mkdir certs
# Copy your Qlik Sense certificates to certs/ directory
- Create configuration
cp .env.example .env
# Edit .env with your settings
Configuration
Environment Variables (.env)
# Server connection
QLIK_SERVER_URL=https://your-qlik-server.company.com
QLIK_USER_DIRECTORY=COMPANY
QLIK_USER_ID=your-username
# Certificate paths (absolute paths)
QLIK_CLIENT_CERT_PATH=/path/to/certs/client.pem
QLIK_CLIENT_KEY_PATH=/path/to/certs/client_key.pem
QLIK_CA_CERT_PATH=/path/to/certs/root.pem
# API ports (standard Qlik Sense ports)
QLIK_REPOSITORY_PORT=4242
QLIK_ENGINE_PORT=4747
# SSL settings
QLIK_VERIFY_SSL=false
MCP Configuration
Create mcp.json file for MCP client integration:
{
"mcpServers": {
"qlik-sense": {
"command": "uvx",
"args": ["qlik-sense-mcp-server"],
"env": {
"QLIK_SERVER_URL": "https://your-qlik-server.company.com",
"QLIK_USER_DIRECTORY": "COMPANY",
"QLIK_USER_ID": "your-username",
"QLIK_CLIENT_CERT_PATH": "/path/to/certs/client.pem",
"QLIK_CLIENT_KEY_PATH": "/path/to/certs/client_key.pem",
"QLIK_CA_CERT_PATH": "/path/to/certs/root.pem",
"QLIK_REPOSITORY_PORT": "4242",
"QLIK_ENGINE_PORT": "4747",
"QLIK_VERIFY_SSL": "false"
},
"disabled": false,
"autoApprove": [
"get_apps",
"get_app_details",
"engine_get_script",
"engine_get_field_values",
"engine_get_field_statistics",
"engine_create_hypercube"
]
}
}
}
Usage
Start Server
# Using uvx (recommended)
uvx qlik-sense-mcp-server
# Using installed package
qlik-sense-mcp-server
# From source (development)
python -m qlik_sense_mcp_server.server
Example Operations
Get Applications List
# Via MCP client - get first 50 apps (default)
result = mcp_client.call_tool("get_apps")
print(f"Showing {result['pagination']['returned']} of {result['pagination']['total_found']} apps")
# Search for specific apps
result = mcp_client.call_tool("get_apps", {
"name_filter": "Sales",
"limit": 10
})
# Get more apps (pagination)
result = mcp_client.call_tool("get_apps", {
"offset": 50,
"limit": 50
})
Analyze Application
# Get comprehensive app analysis
result = mcp_client.call_tool("get_app_details", {
"app_id": "your-app-id"
})
print(f"App has {len(result['data_model']['tables'])} tables")
Create Data Analysis Hypercube
# Create hypercube for sales analysis
result = mcp_client.call_tool("engine_create_hypercube", {
"app_id": "your-app-id",
"dimensions": ["Region", "Product"],
"measures": ["Sum(Sales)", "Count(Orders)"],
"max_rows": 1000
})
Get Field Statistics
# Get detailed field statistics
result = mcp_client.call_tool("engine_get_field_statistics", {
"app_id": "your-app-id",
"field_name": "Sales"
})
print(f"Average: {result['avg_value']['numeric']}")
API Reference
get_apps
Retrieves comprehensive list of Qlik Sense applications with metadata, pagination and filtering support.
Parameters:
limit(optional): Maximum number of apps to return (default: 50, max: 1000)offset(optional): Number of apps to skip for pagination (default: 0)name_filter(optional): Filter apps by name (case-insensitive partial match)app_id_filter(optional): Filter by specific app ID/GUIDinclude_unpublished(optional): Include unpublished apps (default: true)
Returns: Object containing paginated apps, streams, and pagination metadata
Example (default - first 50 apps):
{
"apps": [...],
"streams": [...],
"pagination": {
"limit": 50,
"offset": 0,
"returned": 50,
"total_found": 1598,
"has_more": true,
"next_offset": 50
},
"filters": {
"name_filter": null,
"app_id_filter": null,
"include_unpublished": true
},
"summary": {
"total_apps": 1598,
"published_apps": 857,
"private_apps": 741,
"total_streams": 40,
"showing": "1-50 of 1598"
}
}
Example (with name filter):
# Search for apps containing "dashboard"
result = mcp_client.call_tool("get_apps", {
"name_filter": "dashboard",
"limit": 10
})
# Get specific app by ID
result = mcp_client.call_tool("get_apps", {
"app_id_filter": "e2958865-2aed-4f8a-b3c7-20e6f21d275c"
})
# Get next page of results
result = mcp_client.call_tool("get_apps", {
"limit": 50,
"offset": 50
})
get_app_details
Gets comprehensive application analysis including data model, object counts, and metadata.
Parameters:
app_id(required): Application identifier
Returns: Detailed application object with data model structure
Example:
{
"app_metadata": {...},
"data_model": {
"tables": [...],
"total_tables": 2,
"total_fields": 45
},
"object_counts": {...}
}
engine_get_script
Retrieves load script from application.
Parameters:
app_id(required): Application identifier
Returns: Object containing script text and metadata
Example:
{
"qScript": "SET DateFormat='DD.MM.YYYY';\n...",
"app_id": "app-id",
"script_length": 2830
}
engine_get_field_values
Gets field values with frequency information.
Parameters:
app_id(required): Application identifierfield_name(required): Field namemax_values(optional): Maximum values to return (default: 100)include_frequency(optional): Include frequency data (default: true)
Returns: Field values with statistics and dimension information
Example:
{
"field_name": "state_name",
"values": [
{"value": "Найден, жив", "state": "O"},
{"value": "Найден, погиб", "state": "O"}
],
"total_values": 10
}
engine_get_field_statistics
Retrieves comprehensive field statistics.
Parameters:
app_id(required): Application identifierfield_name(required): Field name
Returns: Statistical analysis including min, max, average, median, mode, standard deviation
Example:
{
"field_name": "age",
"min_value": {"numeric": 0},
"max_value": {"numeric": 2023},
"avg_value": {"numeric": 40.98},
"median_value": {"numeric": 38},
"std_deviation": {"numeric": 24.88}
}
engine_create_hypercube
Creates hypercube for data analysis.
Parameters:
app_id(required): Application identifierdimensions(required): Array of dimension fieldsmeasures(required): Array of measure expressionsmax_rows(optional): Maximum rows to return (default: 1000)
Returns: Hypercube data with dimensions, measures, and total statistics
Example:
{
"hypercube_data": {
"qDimensionInfo": [...],
"qMeasureInfo": [...],
"qDataPages": [...]
},
"total_rows": 30,
"total_columns": 4
}
Architecture
Project Structure
qlik-sense-mcp/
├── qlik_sense_mcp_server/
│ ├── __init__.py
│ ├── server.py # Main MCP server
│ ├── config.py # Configuration management
│ ├── repository_api.py # Repository API client (HTTP)
│ ├── engine_api.py # Engine API client (WebSocket)
│ └── utils.py # Utility functions
├── certs/ # Certificates (git ignored)
│ ├── client.pem
│ ├── client_key.pem
│ └── root.pem
├── .env.example # Configuration template
├── mcp.json.example # MCP configuration template
├── pyproject.toml # Project dependencies
└── README.md
System Components
QlikSenseMCPServer
Main server class handling MCP protocol operations, tool registration, and request routing.
QlikRepositoryAPI
HTTP client for Repository API operations including application metadata and administrative functions.
QlikEngineAPI
WebSocket client for Engine API operations including data extraction, analytics, and hypercube creation.
QlikSenseConfig
Configuration management class handling environment variables, certificate paths, and connection settings.
Development
Development Environment Setup
# Setup development environment
make dev
# Show all available commands
make help
# Build package
make build
Version Management
# Bump patch version and create PR
make version-patch
# Bump minor version and create PR
make version-minor
# Bump major version and create PR
make version-major
Adding New Tools
- Add tool definition in server.py
# In tools_list
Tool(name="new_tool", description="Tool description", inputSchema={...})
- Add handler in server.py
# In handle_call_tool()
elif name == "new_tool":
result = await asyncio.to_thread(self.api_client.new_method, arguments)
return [TextContent(type="text", text=json.dumps(result, indent=2))]
- Implement method in API client
# In repository_api.py or engine_api.py
def new_method(self, param: str) -> Dict[str, Any]:
"""Method implementation."""
return result
Troubleshooting
Common Issues
Certificate Errors
SSL: CERTIFICATE_VERIFY_FAILED
Solution:
- Verify certificate paths in
.env - Check certificate expiration
- Set
QLIK_VERIFY_SSL=falsefor testing
Connection Errors
ConnectionError: Failed to connect to Engine API
Solution:
- Verify port 4747 accessibility
- Check server URL correctness
- Verify firewall settings
Authentication Errors
401 Unauthorized
Solution:
- Verify
QLIK_USER_DIRECTORYandQLIK_USER_ID - Check user exists in Qlik Sense
- Verify user permissions
Diagnostics
Test Configuration
python -c "
from qlik_sense_mcp_server.config import QlikSenseConfig
config = QlikSenseConfig.from_env()
print('Config valid:', config and hasattr(config, 'server_url'))
print('Server URL:', getattr(config, 'server_url', 'Not set'))
"
Test Repository API
python -c "
from qlik_sense_mcp_server.server import QlikSenseMCPServer
server = QlikSenseMCPServer()
print('Server initialized:', server.config_valid)
"
Performance
Optimization Recommendations
- Use filters to limit data volume
- Limit result size with
max_rowsparameter - Use Repository API for metadata (faster than Engine API)
Benchmarks
| Operation | Average Time | Recommendations |
|---|---|---|
| get_apps | 0.5s | Use filters |
| get_app_details | 2-5s | Analyze specific apps |
| engine_create_hypercube | 1-10s | Limit dimensions and measures |
| engine_get_field_statistics | 0.5-2s | Use for numeric fields |
Security
Recommendations
- Store certificates securely - exclude from git
- Use environment variables for sensitive data
- Limit user permissions in Qlik Sense
- Update certificates regularly
- Monitor API access
Access Control
Create user in QMC with minimal required permissions:
- Read applications
- Access Engine API
- View data (if needed for analysis)
License
MIT License
Copyright (c) 2025 Stanislav Chernov
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Project Status: Production Ready | 6/6 Tools Working | v1.1.1
Installation: uvx qlik-sense-mcp-server
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qlik_sense_mcp_server-1.1.1.tar.gz.
File metadata
- Download URL: qlik_sense_mcp_server-1.1.1.tar.gz
- Upload date:
- Size: 39.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f50aa6bbe31e4d8a2e2ea6aa59c5fe56673fb98b2ea125d8d2a98d6529ee0235
|
|
| MD5 |
06f6419e3380b691e4572b19c5034470
|
|
| BLAKE2b-256 |
05cba47966c323bbc4627b2c2af292906b2d32327aac5f424e2d7215e4b0059a
|
File details
Details for the file qlik_sense_mcp_server-1.1.1-py3-none-any.whl.
File metadata
- Download URL: qlik_sense_mcp_server-1.1.1-py3-none-any.whl
- Upload date:
- Size: 39.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5bfd192cd6c9697218fc07de8b32599379c351ce7e52095d8c6b2258f59107f0
|
|
| MD5 |
c179d1a9c470791acc495a110406b793
|
|
| BLAKE2b-256 |
972646301e44ee05a394a10a56d6f8ac08d6ec58785168981e3133f25abec9f3
|