Qlik Sense MCP Server
The Qlik Sense MCP Server provides a unified interface for interacting with Qlik Sense Enterprise APIs, enabling comprehensive application management, data analysis, and administrative operations.
Core Capabilities:
Application Management: Retrieve application lists with filtering and pagination (
get_apps), detailed metadata including object counts (get_app_details,get_app_metadata), and load scripts (engine_get_script)Data Analysis & Extraction: Extract field values with frequency (
engine_get_field_values), generate statistical analysis including min/max/median/standard deviation (engine_get_field_statistics), create hypercubes for advanced analysis (engine_create_hypercube), and export data in JSON/CSV formats (engine_create_data_export)Administrative Management: Access users (
get_users), streams (get_streams), data connections (get_data_connections), tasks (get_tasks), extensions (get_extensions), and content libraries (get_content_libraries)Task Automation: Execute specific tasks by ID (
start_task) for automated workflowsEngine API Integration: Direct interaction with Qlik Sense Engine API for document listing (
engine_get_doc_list), application operations, sheet retrieval (engine_get_sheets), and table data extraction (engine_get_table_data)Security & Performance: Certificate-based authentication for secure access, optimized queries, and pagination for efficient data retrieval
Uses .ENV files for configuration management of Qlik Sense connection details, authentication credentials, and API settings.
Integrates with GitHub Actions for automated build and publication processes to PyPI when new version tags are pushed.
Supports installation from PyPI and automated publication of new versions through GitHub Actions workflows.
Provides unified interface for Qlik Sense Enterprise Repository API and Engine API operations, enabling access to applications, users, data models, analytics, and data export functionality through 21 specialized tools.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Qlik Sense MCP Serverlist all applications with their metadata"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Qlik Sense MCP Server
Model Context Protocol server for
Qlik Sense Enterprise. Exposes Qlik's Repository (HTTP) and Engine
(WebSocket) APIs as 28 MCP tools so an LLM client can discover apps,
inspect data models, query data, and manage reload tasks through a
single uniform interface. In JWT and form (login/password) mode the 14
reload-task tools are hidden by default: QRS task administration needs an
admin role in the QMC, which a JWT analyst or a form login usually does
not hold. That is a property of the identity, not of how it authenticated,
so QLIK_TASK_TOOLS=true turns them on for an identity that does hold it.
What's in the box
Area | Tools | Used for |
Repository (apps & metadata) |
| Discover apps, list tables and fields with cardinalities |
Engine (data & script) |
| Query data, read load script, list visualizations, inspect field values |
Reload tasks (certificate mode by default; opt-in elsewhere, see below) |
| Inspect, trigger and manage reload tasks |
Full list with descriptions: docs/tools.md.
The main analysis call takes the question, not the Qlik syntax for it:
// engine_query — "revenue by region for 2024, biggest first"
{
"app_id": "<app guid>",
"group_by": ["region_name"],
"metrics": [{"field": "amount", "agg": "sum", "label": "Revenue"}],
"filters": [{"field": "order_date", "period": "2024"}],
"sort_by": "Revenue",
"limit": 10
}The server writes the set analysis, checks that the filter selects
something, and answers with period_check — the earliest and latest
date actually in the result — so a filter that failed to apply is
visible instead of hiding behind a plausible number. Independent
questions go in one call as queries and share three round-trips.
Harder questions stay in the same form. A share of the whole, with the numerator narrowed and the denominator not:
{
"group_by": ["region_name"],
"metrics": [{"label": "Share", "op": "divide", "of": [
{"field": "amount", "agg": "sum",
"filters": [{"field": "category", "values": ["Alpha"]}]},
{"field": "amount", "agg": "sum", "total": true}]}]
}The same form states an aggregation over an aggregation
("inner_agg": "sum", "per": "order_id", "agg": "median"), the clients
who bought in one year and not the next (matching / not_matching),
counting over a bookmark or ignoring selections (scope), and values
kept, dropped, added or intersected on any field.
engine_create_hypercube takes the same shape with the expressions
written by hand, for calculations the typed form cannot state.
Related MCP server: Looker Admin MCP
Quick start
uvx qlik-sense-mcp-serverThe server starts in Streamable HTTP
mode on http://127.0.0.1:8000/mcp. Configure it via environment
variables — see docs/configuration.md.
For stdio mode (legacy MCP transport), pass --stdio.
Three authentication modes are supported: client certificate (legacy,
full QRS access), JWT via virtual proxy (per-analyst, no on-disk
secrets), and login/password against a "Form based" virtual proxy
(e.g. the in-box Windows credentials login page). See
docs/AUTH_JWT.md and
docs/AUTH_FORM.md for setup.
Documentation
Document | What's inside |
Requirements, install via | |
All | |
JWT authentication via virtual proxy: key generation, virtual proxy setup, | |
Login/password authentication via a "Form based" virtual proxy: how the login flow works, | |
Transports, server start commands, recommended call order, hard limits enforced by this server | |
Inventory of all 28 tools, response/error envelope, error categories | |
Project layout, components, connection caching, strict id-matching, two-tier timeout | |
| |
Common errors, hypercube planning failures, verbose logging, configuration self-test | |
What models actually do with this server, measured: calls per question, where they go wrong, session limits, how to benchmark honestly | |
Release notes |
Key facts
A wrong query is refused, not answered. Qlik evaluates an unknown field name as an expression worth 0, so a hypercube grouped by a typo came back as a single row holding the grand total — a plausible number with nothing to mark it as wrong. Every query is checked by Engine before it runs:
ExpandExpressionresolves variables,CheckExpressionreports syntax and unknown names,GetFieldsFromExpressionreports the fields a set modifier actually filters on. The four checks cost about 4ms in one batch, against 75ms for the smallest hypercube.A period filter is measured, not assumed. Comparison inside a set modifier runs against the text Qlik displays for a value, so a serial number range returns 0 on a field displayed as
01.01.2024and works on one displayed as45292— with no error either way. State the period as a filter and the server tries the cheap numeric form against a reference count, falls back to the form that always works, and reports the period the result actually covers.One value, one writing. A date in a query result reads as the text Qlik displays for it, the same as the sample values in
get_app_detailsand the bounds fromengine_get_field_range.A field name is always written in brackets. A bare
Тип ставкиis read by Qlik's parser as two tokens — "Garbage after expression: 'ставки'" — which used to refuse queries Qlik itself runs happily.Aggregating over groups, not rows.
perandinner_aggstate "sum per issue, then the 85th percentile across issues", which is a different question from a percentile over rows and gives a different number.A measure can narrow itself. Its own
filtersoverride the query's, so a KPI carries its numerator and its denominator in one answer.Objects say which fields they use.
get_app_sheet_objectsreturnsfields_used, including fields reached through master measures and the ones inside a filter pane's listboxes — so "what does this sheet work with" is one call.Paging is done by Qlik, not after it. App and task listings read
/{entity}/tablewithskip/takeand take the total from/{entity}/count, so nothing past the QRS record limit goes missing andtotal_foundis the real total. Field search and field paging likewise happen in Engine — verified on a field with 200,000 distinct values, where the old local scan simply could not see a match.A failure is never an empty answer. A QRS 500, a refused connection or an Engine error used to arrive as
[],""or "no schedule", which reads as a tidy, empty Qlik. Every such path now returns anerror_categoryand the original cause.Column meanings, not just column names. Fields and tables commented in the load script (
COMMENT FIELD/COMMENT TABLE) carry that text intoget_app_detailsascomment, and intoget_app_fieldasfield_comment, so the model reads what a column means instead of guessing from its name. Added in 1.7.2.Runs on both MCP SDK lines. SDK 2.0 dropped
FastMCP; the server now picksMCPServer(2.x) orFastMCP(1.x) at import time, somcp>=1.8.0,<3.0.0all work. Both lines are covered by the test suite and were verified end to end against a live Qlik app.Ranked queries (top-N) in one call.
engine_create_hypercubetakessort_by(a measure label, a measure expression or a dimension field),sort_order(desc/asc) andlimit, so "the 10 clients with the highest GGR" is a single request. Before v1.6.0 sorting by a measure silently did nothing —qInterColumnSortOrderwas hard-coded to the dimensions, so the server returned the alphabetically first rows instead of the largest ones.NULL groups are visible, not hidden. Facts with no value for the grouping field collapse into Qlik's
"-"row, which often holds a large total and can take first place in a top-N. It is kept by default — a fact with no grouping value is still a fact — andexclude_null_dimensions=trueleaves it out.Compact, LLM-friendly results. The hypercube response is
columns+rowswith real numbers, plusgrand_totaland per-steptimings. Passinclude_raw_layout=truefor the full Qlik layout.Failures name the query that failed. Every error reply, timeouts included, echoes
toolandrequestwith the exact arguments sent.Fewer useless tools in JWT/form mode, by default. Reload-task administration needs QRS admin rights — a QMC role, not a property of the authentication method — so those 14 tools default to on in certificate mode and off in JWT/form mode: 28 tools with a certificate, 14 with a JWT or a login/password.
QLIK_TASK_TOOLS=trueturns them on in JWT/form mode too, for an identity verified to hold those rights.One Qlik session per server. Qlik's per-user limit (5 by default) counts proxy sessions, and in JWT/form mode one is created by the session bootstrap itself — before any WebSocket. The server therefore bootstraps once and reuses that session for every call; restarting it in a loop is what exhausts the quota, not the number of queries.
JWT authentication via virtual proxy. Set
QLIK_JWT_TOKENinstead of certificate paths and the server will authenticate every Repository and Engine call as the analyst encoded in the token. No certificates or private keys live on the host. The legacy certificate mode is unchanged and still required for full QRS access. Setup guide:docs/AUTH_JWT.md.Login/password authentication via a "Form based" virtual proxy. Set
QLIK_PASSWORD(plusQLIK_USER_IDand optionallyQLIK_USER_DIRECTORY) instead of a certificate or a JWT and the server logs into the proxy's login page the way a browser would, then reuses the resulting session cookie exactly like JWT mode does after its own bootstrap. Setup guide:docs/AUTH_FORM.md.Cached Engine WebSocket connections. Once an app is opened, every subsequent tool call against the same
app_idreuses the same WebSocket and the same open document. Switchingapp_idcloses the old document and opens the new one on the same socket. Dropped connections are reopened transparently. Implementation:engine/connection.pyanddocs/architecture.md.Streamable HTTP transport by default. The server is a long-lived process; multiple MCP clients can talk to it in parallel. The legacy stdio mode still works behind
--stdio.tool_call_secondsis injected as the first key of every tool response — wall-clock time of the call in milliseconds. Use it to spot slow tools.Hard hypercube limits.
engine_create_hypercuberejects requests withmax_rows > 5000orcolumns * max_rows > 9900immediately, with a structured error and a hint pointing at set-analysis or top-N patterns. Qlik Engine itself returns error 7009calc-pages-too-largefor any single page over 10000 cells.Single timeout knob.
QLIK_WS_TIMEOUT(default180.0seconds) controls both the WebSocket handshake and every Engine API call.
Requirements
Python 3.12 (the package is built and tested against this version; see
pyproject.toml)Qlik Sense Enterprise (Repository on port 4242, Engine on port 4747 — the standard ports)
Client certificate, private key and root CA from the Qlik Sense node (certificate mode only - JWT and form mode need nothing on disk beyond the token or the password)
Network access from the host running this server to Qlik
Disclaimer
This project is an independent, community-built integration. It is NOT affiliated with, endorsed by, sponsored by, or supported by Qlik Technologies Inc., QlikTech International AB, or any other Qlik entity. "Qlik", "Qlik Sense", "QlikView" and all related product names are trademarks of their respective owners.
All information about Qlik Sense APIs, port allocations, error codes, protocol behavior and usage patterns used in this project was obtained exclusively from publicly available sources — the Qlik Developer Portal (help.qlik.com, qlik.dev), the Qlik Community forums, and other public documentation. No proprietary, confidential or reverse-engineered material is used.
License
MIT © 2025-2026 Stanislav Chernov
Available Tools
10 toolsengine_create_hypercubeA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application ID | |
| dimensions | No | List of dimension definitions with optional sorting | |
| measures | No | List of measure definitions with optional sorting | |
| max_rows | No | Maximum rows to return |
TDQS
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 adds valuable context beyond the input schema by explaining that 'Measure sorting is ignored by Qlik Engine' and providing specific guidance on how to achieve top-N results using qSortByExpression. This clarifies important behavioral traits not evident from the schema alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized with two sentences that are front-loaded with the main purpose. The second sentence provides crucial implementation details without unnecessary elaboration. Every sentence earns its place, though it could be slightly more structured for clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the tool (4 parameters with nested objects, no output schema, and no annotations), the description is somewhat complete but has gaps. It explains key behavioral aspects like the engine's handling of measure sorting, but doesn't cover other potential behaviors such as error conditions, performance implications, or what the created hypercube output entails. This is adequate but with clear room for improvement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds some semantic value by explaining the purpose of qSortByExpression for top-N results and clarifying that measure sorting is ignored, but it doesn't provide significant additional meaning beyond what's in the schema descriptions. This meets the baseline of 3 for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool creates a hypercube for data analysis with custom sorting options, providing a specific verb ('create') and resource ('hypercube'). However, it doesn't explicitly differentiate this tool from its siblings (which are all 'get' operations), though the distinction is implied by the 'create' action versus their 'get' actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides implicit usage guidance by mentioning 'To get top-N records, use qSortByExpression: 1 in dimension sorting,' which suggests when to use certain parameters. However, it doesn't explicitly state when to use this tool versus alternatives (e.g., compared to sibling 'get' tools) or provide clear exclusions, leaving some context to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_detailsB
Get compact application info with filters by guid or name (case-insensitive). Returns metainfo, tables/fields list, master items, sheets and objects with used fields.
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | No | Application GUID (preferred if known) | |
| name | No | Case-insensitive fuzzy search by app name |
TDQS
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 describes the return content ('metainfo, tables/fields list, master items, sheets and objects with used fields'), which adds useful context beyond basic retrieval. However, it lacks details on permissions, rate limits, error handling, or whether this is a read-only operation (though 'Get' implies read). The description compensates somewhat but leaves gaps for a tool with no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense sentence that efficiently covers purpose, filters, and return values. It's front-loaded with the core action ('Get compact application info') and avoids redundancy. However, it could be slightly more structured (e.g., separating filtering from returns) for better readability, but it earns its place with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and 2 parameters with full schema coverage, the description is moderately complete. It explains what the tool does and what it returns, which is essential for understanding. However, for a tool with no output schema, it doesn't detail the structure of returned data (e.g., format of 'metainfo'), and with no annotations, it misses behavioral aspects like safety or constraints. It's adequate but has clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters (app_id and name) with descriptions. The description adds marginal value by noting 'case-insensitive fuzzy search by app name' and 'preferred if known' for app_id, but doesn't provide additional syntax, format, or examples beyond what the schema offers. Baseline 3 is appropriate as the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Get compact application info' with specific filtering capabilities by 'guid or name (case-insensitive)'. It distinguishes itself from siblings like 'get_apps' (likely listing apps) by focusing on detailed info for a single app, though it doesn't explicitly name alternatives. The verb 'Get' and resource 'application info' are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by mentioning filters 'by guid or name', suggesting this tool is for retrieving details of a specific app rather than listing all apps. However, it doesn't explicitly state when to use this vs. siblings like 'get_apps' (for listing) or 'get_app_object' (for specific objects), nor does it provide exclusions or prerequisites. The guidance is implied but not comprehensive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_fieldC
Return values of a single field from app with pagination and wildcard search (supports * and %).
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application GUID | |
| field_name | Yes | Field name | |
| limit | No | Max values to return (default: 10, max: 100) | |
| offset | No | Offset for pagination (default: 0) | |
| search_string | No | Wildcard text search mask (* and % supported), case-insensitive by default | |
| search_number | No | Wildcard numeric search mask (* and % supported) | |
| case_sensitive | No | Case sensitive matching for search_string |
TDQS
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 mentions pagination and wildcard search support, which adds some context beyond basic retrieval. However, it lacks details on permissions, rate limits, error handling, or response format (e.g., structure of returned values), leaving significant gaps for a tool with 7 parameters and no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core purpose ('Return values of a single field from app') and appends key features ('with pagination and wildcard search'). Every word earns its place, with no redundancy or unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, no output schema, and no annotations), the description is insufficient. It doesn't explain the return format, error conditions, or behavioral nuances like how wildcards interact with pagination. For a data retrieval tool with multiple search options, more context is needed to ensure proper agent usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all 7 parameters with details like defaults and constraints. The description adds minimal value by mentioning 'pagination and wildcard search', which loosely relates to 'limit', 'offset', 'search_string', and 'search_number', but doesn't provide additional semantic context beyond what's in the schema. Baseline 3 is appropriate given high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Return values') and resource ('a single field from app'), specifying the scope of retrieval. It distinguishes itself from siblings like 'get_app_details' or 'get_apps' by focusing on field values rather than app metadata or lists. However, it doesn't explicitly contrast with 'get_app_field_statistics', which might handle aggregated data instead of raw values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is provided on when to use this tool versus alternatives like 'get_app_field_statistics' or 'get_app_object'. The description mentions pagination and wildcard search features, but doesn't clarify scenarios where this tool is preferred over other field-related or app-related tools in the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_field_statisticsC
Get comprehensive statistics for a field
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application ID | |
| field_name | Yes | Field name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions 'comprehensive statistics' but doesn't specify what types of statistics (e.g., counts, averages, distributions), whether it's a read-only operation, potential rate limits, or authentication requirements. This leaves significant gaps for a tool that likely involves data analysis.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no wasted words. It's front-loaded with the core action ('Get comprehensive statistics'), making it easy to scan and understand quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of annotations and output schema, the description is incomplete. It doesn't explain what 'comprehensive statistics' entail or the format of the return value, which is critical for a statistical tool. With 2 required parameters and no behavioral context, more detail is needed for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with clear documentation for 'app_id' and 'field_name'. The description adds no additional parameter details beyond implying statistics are for a specific field in an app, which is already inferred from the parameter names. This meets the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Get') and resource ('comprehensive statistics for a field'), making the purpose understandable. However, it doesn't distinguish this tool from sibling tools like 'get_app_field' or 'get_app_details', which might retrieve related but different information about fields or apps.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. With siblings like 'get_app_field' and 'get_app_details', it's unclear if this tool is for statistical summaries, usage metrics, or other field-specific data, leaving the agent to guess based on the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_objectC
Get specific object layout by calling GetObject and GetLayout sequentially via WebSocket.
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application GUID | |
| object_id | Yes | Object ID to retrieve |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It mentions the tool calls 'GetObject and GetLayout sequentially via WebSocket', which implies network operations and potential latency, but doesn't disclose critical behavioral traits like error handling, rate limits, authentication needs, or what 'layout' entails. The description is insufficient for a tool with no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is front-loaded with the main action ('Get specific object layout') and includes implementation detail. It's efficient with zero waste, though the implementation detail might be unnecessary for clarity. Structure is appropriate for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and a tool that performs retrieval operations (implied by 'Get'), the description is incomplete. It doesn't explain what 'object layout' returns, error conditions, or behavioral constraints. For a tool with 2 parameters and no structured support, more context is needed to be adequately helpful.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both parameters ('app_id' and 'object_id') documented in the schema as 'Application GUID' and 'Object ID to retrieve'. The description adds no meaning beyond this, as it doesn't explain parameter relationships or usage context. Baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool 'Get specific object layout' which indicates a retrieval action on an object layout resource. However, it's vague about what 'object layout' means (e.g., UI layout, data structure) and doesn't clearly distinguish it from sibling tools like 'get_app_sheet_objects' or 'get_app_field'. The phrase 'by calling GetObject and GetLayout sequentially via WebSocket' adds implementation detail but doesn't clarify the purpose further.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The description doesn't mention when this tool is appropriate (e.g., for retrieving layout details vs. other object properties) or refer to sibling tools like 'get_app_sheet_objects' for different use cases. It lacks context about prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_appsA
Get list of Qlik Sense applications with essential fields and filters (name, stream, published) and pagination.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of apps to return (default: 25, max: 50) | |
| offset | No | Number of apps to skip for pagination (default: 0) | |
| name | No | Wildcard case-insensitive search in application name | |
| stream | No | Wildcard case-insensitive search in stream name | |
| published | No | Filter by published status (true/false or 1/0). Default: true | true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It mentions pagination behavior and filtering capabilities, which is helpful. However, it doesn't disclose authentication requirements, rate limits, error conditions, or what 'essential fields' specifically includes, leaving gaps in behavioral understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that efficiently conveys the tool's core functionality, key filters, and pagination support. Every element earns its place with no wasted words, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with 5 parameters and no output schema, the description adequately covers the basic purpose and filtering. However, without annotations or output schema, it should ideally mention more about return format (e.g., what 'essential fields' includes) and any critical constraints to be fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all 5 parameters. The description adds minimal value beyond the schema by mentioning filters (name, stream, published) and pagination, but doesn't provide additional context like wildcard syntax examples or interaction effects between parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Get list of Qlik Sense applications' with specific resources (applications) and essential fields/filters (name, stream, published). It distinguishes from siblings like get_app_details by focusing on listing rather than detailed retrieval, but doesn't explicitly contrast with other list-like siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for listing applications with filtering and pagination, suggesting when to use it for bulk retrieval vs. detailed sibling tools. However, it lacks explicit guidance on when to choose this over alternatives like get_app_sheets or get_app_variables for specific needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_scriptC
Get load script from app
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states 'Get load script from app', which implies a read-only operation, but doesn't clarify permissions, rate limits, error conditions, or what the output looks like (e.g., script format, size limits). For a tool with zero annotation coverage, this leaves significant gaps in understanding its behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise at four words, with zero wasted language. It's front-loaded with the core action ('Get load script from app'), making it easy to parse quickly. Every word earns its place by conveying the essential purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (a read operation with one parameter) and lack of annotations or output schema, the description is incomplete. It doesn't explain what a 'load script' is, how it's returned, or any behavioral traits like error handling. For a tool that likely retrieves code or configuration data, more context is needed to use it effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with 'app_id' documented as 'Application ID'. The description adds no additional meaning beyond this, as it doesn't explain what an 'app_id' is or provide context like valid formats. With high schema coverage, the baseline score of 3 is appropriate, as the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Get load script from app' states a clear verb ('Get') and resource ('load script from app'), but it's vague about what a 'load script' is and doesn't distinguish this tool from its siblings like 'get_app_details' or 'get_app_object'. It provides a basic purpose but lacks specificity about the script's nature or format.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no guidance on when to use this tool versus alternatives. With siblings like 'get_app_details' and 'get_app_object', there's no indication of when to retrieve a load script specifically, nor any prerequisites or exclusions mentioned. Usage is implied by the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_sheet_objectsC
Get list of objects from specific sheet with object ID, type and description.
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application GUID | |
| sheet_id | Yes | Sheet GUID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool retrieves a list but doesn't describe key behaviors: whether it's paginated, rate-limited, requires specific permissions, returns empty lists for invalid inputs, or handles errors. For a read operation with zero annotation coverage, this leaves significant gaps in understanding how the tool behaves.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core action ('Get list of objects') and specifies key details (source, returned fields). There is no wasted verbiage, repetition, or unnecessary elaboration—every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (a read operation with 2 required parameters) and lack of annotations and output schema, the description is incomplete. It doesn't cover behavioral aspects (e.g., pagination, error handling), usage context, or return format details. While concise, it fails to provide sufficient context for an agent to use the tool effectively beyond basic parameter passing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, with both parameters ('app_id' and 'sheet_id') documented as GUIDs for application and sheet. The description adds no additional meaning beyond the schema—it doesn't explain parameter relationships (e.g., sheet must belong to app) or provide examples. With high schema coverage, the baseline is 3, as the description doesn't compensate but also doesn't detract.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('Get list of objects') and resource ('from specific sheet'), and specifies the returned fields ('object ID, type and description'). It distinguishes from some siblings like 'get_app_object' (singular) and 'get_app_sheets' (lists sheets, not objects), but doesn't explicitly differentiate from all potential alternatives like 'get_app_field' or 'get_app_field_statistics'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing valid app and sheet IDs), compare with siblings like 'get_app_object' (for single objects) or 'get_app_field' (for fields), or specify use cases (e.g., for auditing or data exploration). The context is implied but not articulated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_sheetsC
Get list of sheets from application with title and description.
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | Yes | Application GUID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden for behavioral disclosure. While 'Get list' implies a read-only operation, it doesn't specify whether this requires authentication, what format the list returns (e.g., paginated, filtered), or any rate limits. The description is minimal and lacks important operational context for a tool with no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that communicates the core purpose without unnecessary words. It's appropriately sized for a simple retrieval tool, though it could potentially be more front-loaded with additional context about when to use it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations and no output schema, the description is insufficiently complete. It doesn't explain what format the returned list takes, whether it includes all sheets or is filtered, or what happens with invalid app_ids. The description should provide more operational context given the lack of structured metadata.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with the single parameter 'app_id' fully documented as 'Application GUID'. The description doesn't add any parameter-specific information beyond what the schema provides, but with complete schema coverage, the baseline score of 3 is appropriate as the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get list of sheets') and resource ('from application'), specifying what information is retrieved ('with title and description'). It distinguishes this from general app retrieval tools like 'get_apps' by focusing specifically on sheets, but doesn't explicitly differentiate from the sibling 'get_app_sheet_objects' which might retrieve different sheet-related data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention when to prefer this over 'get_app_sheet_objects' or other sheet-related tools, nor does it specify prerequisites or context for usage beyond the basic parameter requirement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_app_variablesB
Return variables split by source (script/ui) with pagination and wildcard search.
| 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 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It mentions pagination and wildcard search, which are useful behavioral traits, but fails to disclose critical information: whether this is a read-only operation, what authentication is needed, rate limits, error conditions, or the structure of returned data. For a tool with 7 parameters and no output schema, this leaves significant gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core purpose and mentions key features. Every word earns its place with no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, no output schema, no annotations), the description is insufficient. It doesn't explain the return format, how variables are 'split by source', what the pagination response looks like, or error handling. For a data retrieval tool with filtering and pagination, more context is needed for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all 7 parameters. The description adds minimal value beyond the schema—it mentions 'wildcard search' which aligns with search_string/search_number parameters, and 'pagination' which aligns with limit/offset. However, it doesn't provide additional context like typical use cases for created_in_script or interaction between parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Return') and resource ('variables'), and specifies they are 'split by source (script/ui)'. It distinguishes from siblings like get_app_details or get_app_field by focusing on variables rather than other app components. However, it doesn't explicitly differentiate from all possible variable-related tools that might exist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through mentioning 'pagination and wildcard search', suggesting this tool is for browsing/filtering variables. However, it provides no explicit guidance on when to use this versus alternatives like get_app_field or get_app_script, nor does it mention prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v1.0.0- Changed
engine_create_hypercube9 fields changed- changed
Input schema / properties / dimensions / descriptionPrevious value: -"List of dimension fields"New value: +"List of dimension definitions with optional sorting" - added
Input schema / properties / dimensions / items / additionalPropertiesAdded value: +false - added
Input schema / properties / dimensions / items / propertiesAdded value: +{ + "field": { + "description": "Field name for dimension", + "type": "string" + }, + "label": { + "description": "Optional label for dimension", + "type": "string" + }, + "sort_by": { + "additionalProperties": false, + "properties": { + "qExpression": { + "default": "", + "description": "Expression for custom sorting. For top-N: 'Count(field)' for ascending, '-Count(field)' for descending", + "type": "string" + }, + "qSortByAscii": { + "default": 1, + "description": "Sort by ASCII value (-1 desc, 0 none, 1 asc)", + "type": "integer" + }, + "qSortByExpression": { + "default": 0, + "description": "Use expression for sorting (0/1). For top-N results, set to 1 and use qExpression with measure formula", + "type": "integer" + }, + "qSortByNumeric": { + "default": 0, + "description": "Sort by numeric value (-1 desc, 0 none, 1 asc)", + "type": "integer" + } + }, + "type": "object" + } +} - changed
Input schema / properties / dimensions / items / typePrevious value: -"string"New value: +"object" - changed
Input schema / properties / measures / descriptionPrevious value: -"List of measure expressions"New value: +"List of measure definitions with optional sorting" - added
Input schema / properties / measures / items / additionalPropertiesAdded value: +false - added
Input schema / properties / measures / items / propertiesAdded value: +{ + "expression": { + "description": "Measure expression", + "type": "string" + }, + "label": { + "description": "Optional label for measure", + "type": "string" + }, + "sort_by": { + "additionalProperties": false, + "properties": { + "qSortByNumeric": { + "default": -1, + "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", + "type": "integer" + } + }, + "type": "object" + } +} - changed
Input schema / properties / measures / items / typePrevious value: -"string"New value: +"object" - changed
Input schema / requiredPrevious value: -[ - "app_id", - "dimensions", - "measures" -]New value: +[ + "app_id" +]
- Removed
engine_get_field_statistics - Removed
engine_get_script - Added
get_app_field_statistics - Added
get_app_object - Added
get_app_script - Added
get_app_sheet_objects - Added
get_app_sheets - Changed
get_app_variables1 field changed- changed
Input schema / properties / created_in_script / typePrevious value: -[ - "boolean", - "integer", - "string" -]New value: +"string"
- Changed
get_apps2 fields changed- changed
Input schema / properties / published / defaultPrevious value: -trueNew value: +"true" - changed
Input schema / properties / published / typePrevious value: -[ - "boolean", - "integer", - "string" -]New value: +"string"
7 tool updates
- First observed
engine_create_hypercube - First observed
engine_get_field_statistics - First observed
engine_get_script - First observed
get_app_details - First observed
get_app_field - First observed
get_app_variables - First observed
get_apps
TDQS
Scored across 10 tools
Every tool has a clearly distinct purpose targeting specific Qlik Sense resources like apps, fields, objects, sheets, variables, or hypercubes, with no overlap in functionality. The descriptions reinforce this by detailing unique operations such as retrieving field statistics versus field values, ensuring agents can easily differentiate between tools.
All tool names follow a consistent verb_noun pattern with 'get_' or 'engine_' prefixes, using snake_case uniformly (e.g., get_app_details, get_app_field, engine_create_hypercube). This predictability makes the tool set easy to navigate and understand at a glance.
With 10 tools, the server is well-scoped for interacting with Qlik Sense applications, covering essential operations like listing apps, retrieving details, fields, objects, sheets, variables, scripts, and creating hypercubes. Each tool serves a distinct role without redundancy, fitting the domain appropriately.
The tool set provides comprehensive read and analysis capabilities for Qlik Sense apps, including data retrieval, statistics, and hypercube creation, but lacks write operations (e.g., updating or deleting apps, fields, or objects). This minor gap may limit agents in full lifecycle management but supports core query and analysis workflows effectively.
Maintenance
Related MCP Connectors
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Read and edit GA4, Search Console and Google Tag Manager from any MCP client. 29 tools.
Unified gateway exposing 150+ tools across all NexGenData MCP servers via one endpoint.
Related MCP Servers
- AlicenseBqualityCmaintenanceConnects AI assistants like Claude to Qlik Cloud and Qlik Sense Enterprise environments, enabling natural language interactions for analytics, app management, reloads, user administration, and data governance across 34 tools.3416MIT
- FlicenseNot gradedqualityDmaintenanceProvides over 60 administrative tools for managing users, groups, roles, schedules, alerts, and content access within Looker through the Model Context Protocol. It enables full administration of Looker environments, including permission management and system configuration.1-
- AlicenseAqualityDmaintenanceA comprehensive MCP server that provides complete access to Qlik Sense applications and their detailed information for AI assistants and other MCP clients.915MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI applications to interact with Power BI through the Model Context Protocol, supporting comprehensive API operations including data retrieval and management.-