Skip to main content
Glama
bintocher

Qlik Sense MCP Server

Qlik Sense MCP Server

PyPI version PyPI downloads License: MIT Python versions

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)

get_about, get_apps, get_app_details

Discover apps, list tables and fields with cardinalities

Engine (data & script)

engine_query, engine_create_hypercube, get_app_script, get_app_variables, get_app_sheets, get_app_sheet_objects, get_app_object, search_app, get_app_field, engine_get_field_range, get_app_field_statistics

Query data, read load script, list visualizations, inspect field values

Reload tasks (certificate mode by default; opt-in elsewhere, see below)

get_tasks, get_task_details, get_task_dependencies, get_task_schedule, get_task_executions, get_task_script_log, get_failed_tasks_with_logs, start_task, create_task, update_task, delete_task, create_task_schedule, update_task_schedule, delete_task_schedule

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-server

The 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

docs/installation.md

Requirements, install via uvx / pip / source, certificate setup

docs/configuration.md

All QLIK_* environment variables, sample .env, MCP client config snippet

docs/AUTH_JWT.md

JWT authentication via virtual proxy: key generation, virtual proxy setup, QLIK_JWT_TOKEN usage

docs/AUTH_FORM.md

Login/password authentication via a "Form based" virtual proxy: how the login flow works, QLIK_PASSWORD usage, overrides for non-default login pages

docs/usage.md

Transports, server start commands, recommended call order, hard limits enforced by this server

docs/tools.md

Inventory of all 28 tools, response/error envelope, error categories

docs/architecture.md

Project layout, components, connection caching, strict id-matching, two-tier timeout

docs/development.md

make targets, tests, versioning, how to add a new tool

docs/troubleshooting.md

Common errors, hypercube planning failures, verbose logging, configuration self-test

docs/llm-behaviour.md

What models actually do with this server, measured: calls per question, where they go wrong, session limits, how to benchmark honestly

CHANGELOG.md

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: ExpandExpression resolves variables, CheckExpression reports syntax and unknown names, GetFieldsFromExpression reports 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.2024 and works on one displayed as 45292 — 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_details and the bounds from engine_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. per and inner_agg state "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 filters override the query's, so a KPI carries its numerator and its denominator in one answer.

  • Objects say which fields they use. get_app_sheet_objects returns fields_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}/table with skip/take and take the total from /{entity}/count, so nothing past the QRS record limit goes missing and total_found is 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 an error_category and the original cause.

  • Column meanings, not just column names. Fields and tables commented in the load script (COMMENT FIELD / COMMENT TABLE) carry that text into get_app_details as comment, and into get_app_field as field_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 picks MCPServer (2.x) or FastMCP (1.x) at import time, so mcp>=1.8.0,<3.0.0 all 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_hypercube takes sort_by (a measure label, a measure expression or a dimension field), sort_order (desc / asc) and limit, so "the 10 clients with the highest GGR" is a single request. Before v1.6.0 sorting by a measure silently did nothing — qInterColumnSortOrder was 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 — and exclude_null_dimensions=true leaves it out.

  • Compact, LLM-friendly results. The hypercube response is columns + rows with real numbers, plus grand_total and per-step timings. Pass include_raw_layout=true for the full Qlik layout.

  • Failures name the query that failed. Every error reply, timeouts included, echoes tool and request with 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=true turns 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_TOKEN instead 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 (plus QLIK_USER_ID and optionally QLIK_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_id reuses the same WebSocket and the same open document. Switching app_id closes the old document and opens the new one on the same socket. Dropped connections are reopened transparently. Implementation: engine/connection.py and docs/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_seconds is 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_hypercube rejects requests with max_rows > 5000 or columns * max_rows > 9900 immediately, with a structured error and a hint pointing at set-analysis or top-N patterns. Qlik Engine itself returns error 7009 calc-pages-too-large for any single page over 10000 cells.

  • Single timeout knob. QLIK_WS_TIMEOUT (default 180.0 seconds) 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 tools
engine_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication ID
dimensionsNoList of dimension definitions with optional sorting
measuresNoList of measure definitions with optional sorting
max_rowsNoMaximum rows to return

TDQS

A3.6/5.0
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 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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idNoApplication GUID (preferred if known)
nameNoCase-insensitive fuzzy search by app name

TDQS

B3.4/5.0
Behavior3/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 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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 %).

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication GUID
field_nameYesField name
limitNoMax values to return (default: 10, max: 100)
offsetNoOffset for pagination (default: 0)
search_stringNoWildcard text search mask (* and % supported), case-insensitive by default
search_numberNoWildcard numeric search mask (* and % supported)
case_sensitiveNoCase sensitive matching for search_string

TDQS

C2.9/5.0
Behavior2/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 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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication ID
field_nameYesField name

TDQS

C2.9/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication GUID
object_idYesObject ID to retrieve

TDQS

C2.6/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose3/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of apps to return (default: 25, max: 50)
offsetNoNumber of apps to skip for pagination (default: 0)
nameNoWildcard case-insensitive search in application name
streamNoWildcard case-insensitive search in stream name
publishedNoFilter by published status (true/false or 1/0). Default: truetrue

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication ID

TDQS

C2.7/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose3/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication GUID
sheet_idYesSheet GUID

TDQS

C2.9/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication GUID

TDQS

C2.9/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
app_idYesApplication GUID
limitNoMax variables to return (default: 10, max: 100)
offsetNoOffset for pagination (default: 0)
created_in_scriptNoReturn only variables created in script (true/false). If omitted, return both
search_stringNoWildcard search by variable name or text value (* and % supported), case-insensitive by default
search_numberNoWildcard search among numeric variable values (* and % supported)
case_sensitiveNoCase sensitive matching for search_string

TDQS

B3.2/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

  1. 10 tool updatesv1.0.0
    • Changedengine_create_hypercube9 fields changed
      • changedInput schema / properties / dimensions / description
        Previous value: -"List of dimension fields"New value: +"List of dimension definitions with optional sorting"
      • addedInput schema / properties / dimensions / items / additionalProperties
        Added value: +false
      • addedInput schema / properties / dimensions / items / properties
        Added 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"
        +  }
        +}
      • changedInput schema / properties / dimensions / items / type
        Previous value: -"string"New value: +"object"
      • changedInput schema / properties / measures / description
        Previous value: -"List of measure expressions"New value: +"List of measure definitions with optional sorting"
      • addedInput schema / properties / measures / items / additionalProperties
        Added value: +false
      • addedInput schema / properties / measures / items / properties
        Added 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"
        +  }
        +}
      • changedInput schema / properties / measures / items / type
        Previous value: -"string"New value: +"object"
      • changedInput schema / required
        Previous value: -[
        -  "app_id",
        -  "dimensions",
        -  "measures"
        -]New value: +[
        +  "app_id"
        +]
    • Removedengine_get_field_statistics
    • Removedengine_get_script
    • Addedget_app_field_statistics
    • Addedget_app_object
    • Addedget_app_script
    • Addedget_app_sheet_objects
    • Addedget_app_sheets
    • Changedget_app_variables1 field changed
      • changedInput schema / properties / created_in_script / type
        Previous value: -[
        -  "boolean",
        -  "integer",
        -  "string"
        -]New value: +"string"
    • Changedget_apps2 fields changed
      • changedInput schema / properties / published / default
        Previous value: -trueNew value: +"true"
      • changedInput schema / properties / published / type
        Previous value: -[
        -  "boolean",
        -  "integer",
        -  "string"
        -]New value: +"string"
  2. 7 tool updates
    • First observedengine_create_hypercube
    • First observedengine_get_field_statistics
    • First observedengine_get_script
    • First observedget_app_details
    • First observedget_app_field
    • First observedget_app_variables
    • First observedget_apps

TDQS

A3.5/5.0

Scored across 10 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    Connects 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.
    34
    16
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides 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
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI applications to interact with Power BI through the Model Context Protocol, supporting comprehensive API operations including data retrieval and management.
    -