关于 qseow-mcp
qseow-mcp 是面向使用客户端管理型 Qlik Sense Enterprise on Windows 的团队的 MCP 服务。它提供数据分析、故障排查、应用构建和治理工具,默认禁用变更操作,并支持按组配置工具。
主要功能
- 01通过 Engine/QIX 查询数据
- 02追踪应用对象和数据血缘
- 03构建并验证工作表
- 04管理脚本、重新加载和发布
- 05检查站点健康状况与治理
- 06限制变更操作并遮蔽凭据
适用场景
- 01沿应用链路追查 KPI 差异
- 02检查选择状态并验证表达式
- 03构建并验证可视化工作表
- 04检查重新加载故障或安全规则
MCP 相关
该服务将 Qlik Repository/QRS、Engine/QIX 和 Proxy API 暴露为 MCP 工具。默认不注册变更工具;可通过 `QSEOW_ALLOW_MUTATIONS=true` 启用。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y qseow-mcpQSEOW_HOSTHostname of the Qlik Sense node, no scheme (e.g. sense.example.com).QSEOW_AUTH_MODE密钥'certificate' (service identity via QMC-exported certs) or 'jwt' (per-user, through a JWT virtual proxy). Defaults to certificate.QSEOW_CERT_PATHPath to the QMC-exported client certificate (PEM). Required in certificate mode; also enables the Proxy-API session tools in jwt mode.QSEOW_CERT_KEY_PATH密钥Path to the client certificate private key (PEM).QSEOW_ROOT_CERT_PATHPath to the Qlik root CA (PEM). Supply it to keep TLS verification on.QSEOW_JWT密钥Signed JWT for the virtual proxy (jwt mode only).QSEOW_VP_PREFIXVirtual proxy prefix for jwt mode, e.g. 'jwt'.QSEOW_ALLOW_MUTATIONSSet true to register write tools. Default false: mutating tools are never registered, so the tool list is genuinely read-only.QSEOW_TOOL_GROUPSComma-separated personas to expose: analyst, developer, admin.QSEOW_TLS_VERIFYSet false only for self-signed lab certificates. Leave on in production.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
qseow-mcp
适用于 Qlik Sense Enterprise on Windows(客户端管理)的 MCP 服务。
Qlik 支持 Agent 的粘合层。 Qlik Cloud 提供原生 MCP 端点;而客户端管理的环境——仍有大量企业 Qlik 部署运行于此——没有同类功能。此服务将本地 API(Repository/QRS、Engine/QIX、Proxy)封装为 Model Context Protocol 工具,让 Agent 能像支持工程师一样,在数字有误时逐步排查:从 KPI → 对象 → 工作表 → 应用 → 脚本 → 来源,逐步评估每一处定义;还可针对站点进行治理、查询和构建。
状态:0.5.2,预发布版。 已在单节点站点的 Qlik Sense May 2026 (15.13.8) 上,使用证书和 JWT 两种身份验证模式端到端测试全部 44 个工具(包括完整的变更生命周期:copy → set_script → reload → publish → delete,以及从开始到完成的任务执行)。工具名称和形式仍可能变更。
qseow-mcp 是 Terenzi LLC 的独立开源项目。它与 QlikTech International AB 无关联,未获其认可或赞助。Qlik®、Qlik Sense® 及相关标识均为 QlikTech International AB 的商标,在此仅用于标识此服务可交互的软件。
安装
Claude Desktop — 一键安装。 从最新版本下载 qseow-mcp-<version>.mcpb,然后双击。Claude Desktop 会提示输入主机名和证书路径;无需编辑 JSON,也无需运行 npm install。
任何 MCP 客户端 — 使用 npx。 无需克隆,无需构建:
{
"mcpServers": {
"qseow": {
"command": "npx",
"args": ["-y", "qseow-mcp"],
"env": {
"QSEOW_HOST": "sense.example.com",
"QSEOW_CERT_PATH": "/absolute/path/to/client.pem",
"QSEOW_CERT_KEY_PATH": "/absolute/path/to/client_key.pem",
"QSEOW_ROOT_CERT_PATH": "/absolute/path/to/root.pem"
}
}
}
}
Claude Code 也一样,一行命令即可:
claude mcp add qseow --scope user \
-e QSEOW_HOST=sense.example.com \
-e QSEOW_CERT_PATH=/absolute/path/to/client.pem \
-e QSEOW_CERT_KEY_PATH=/absolute/path/to/client_key.pem \
-- npx -y qseow-mcp
证书可从 QMC → Certificates → Export 获取(选择 PEM)。如需使用 JWT 而非证书,请参阅身份验证。
默认以只读模式启动。 只有设置 QSEOW_ALLOW_MUTATIONS=true 后才会注册变更工具,因此在你决定启用之前,客户端看到的工具列表确实是只读的。
按角色划分的工具
使用 QSEOW_TOOL_GROUPS,仅公开特定部署所需的工具。
分析师 — 查询数据(Engine/QIX)
| 工具 | 用途 |
|---|---|
list_engine_apps | 会话可见的应用 |
get_app_data_model | 表、字段、行数、基数 |
evaluate_expression | 在当前选择状态下计算 Qlik 表达式 |
create_hypercube | 分组查询:维度 × 度量 → 行 |
get_field_values | 返回非重复值及选择状态,可选搜索 |
select_field_values / clear_selections / get_current_selections | 操作并检查选择状态 |
crosscheck_expression | 对抗式自检:总计与分组求和对比——在数字交给用户前,标记非可加度量和范围错误 |
每个返回值的分析工具都附带一个可信度信息包:表达式验证警告(拼错字段会返回 null/0,且不会报错——这是引擎最糟糕的习惯)以及计算该值时生效的选择项,因此经过筛选的数字绝不会被误认为未筛选的真实结果。
检查员 — 故障排查流程(随分析师工具组提供)
| 工具 | 用途 |
|---|---|
list_sheets / get_sheet_objects | 检查 UI 层:工作表及其上的对象 |
get_object_properties | 获取任意对象的完整 qProps——定义层 |
search_expressions | 在所有对象(包括所属工作表)、主项目、变量和脚本中查找字段、KPI 或表达式片段 |
list_master_measures / list_master_dimensions | 受治理的定义清单 |
evaluate_master_measure | 按 ID 或标题计算主度量(避开 [Name] 被解析为字段的陷阱) |
get_app_lineage | 列出每个 LOAD/STORE 源和目标,并标注类型(qvd、数据库、内联、驻留、存储) |
**已发布应用注意事项:**引擎会向用户身份隐藏已发布应用的脚本和血缘关系(内部证书身份不受此限制)。支持代理模式为 copy_app → 跟踪自有副本——该副本包含相同的脚本和定义。 |
开发者——构建和交付应用(Engine + QRS)
| 工具 | 用途 |
|---|---|
create_sheet / add_sheet_object | 构建 UI 层:工作表和可视化对象。创建时会运行渲染验证门禁并返回验证结果 |
validate_sheet | 质量门禁(只读):这些对象是否能实际渲染?检查定义错误、未知字段/类型、空立方体、数据透视表 qMode 陷阱、缺失的 nebula 属性块、单元格放置 lint |
get_script / set_script | 读取并替换应用的加载脚本 |
check_script | 检查语法,但不重新加载 |
reload_app | 重新加载并保存,返回进度日志末尾内容 |
create_app | 创建应用,可选择设置脚本并重新加载 |
copy_app / publish_app / delete_app | 复制;发布到流;删除 |
管理员——管理站点(QRS)
| 工具 | 用途 |
|---|---|
qrs_about / service_status | 版本;每个节点上所有服务的健康状态 |
license_summary | 序列号、版本、到期时间、专业版/分析师版授权分配情况 |
list_apps / list_streams / list_tasks / list_users | 清单,均可筛选 |
start_task | 触发重新加载任务 |
list_extensions / list_data_connections | 扩展和连接清单 |
qrs_search | 任意 QRS 实体 + 筛选表达式——治理利器 |
get_reload_log | 重新加载为何失败?上次执行结果 + 详细时间线 + 脚本日志末尾内容 |
engine_healthcheck | Engine 版本、饱和标志、内存/CPU、已加载应用、会话数 |
security_rule_audit | 所有安全规则及解码后的操作 + lint 发现的问题(禁用的默认规则、通配符筛选器、无条件写入授权) |
list_user_sessions / end_user_sessions | 每位用户的活动代理会话;强制注销。基于证书——见下方说明 |
修改类工具(set_script、reload_app、create_app、copy_app、publish_app、delete_app、start_task、end_user_sessions、create_sheet、add_sheet_object)会在注册时受到门禁控制:除非 QSEOW_ALLOW_MUTATIONS=true,否则这些工具绝不会注册,因此只读部署会在 tools/list 中展示真正只读的工具集。默认是只读。
每个工具都带有 MCP 工具注解(readOnlyHint、destructiveHint、idempotentHint、openWorldHint),以便遵循这些注解的客户端应用自己的策略——例如,reload_app / set_script / start_task 会标记为具有破坏性;选择工具则属于非破坏性的会话状态修改。
凭据脱敏适用于所有 QRS 出站路径:list_data_connections 和通用 qrs_search(任意实体类型、精简模式或 full:true)都会递归遮蔽包含凭据的字段(password、passphrase、clientsecret 等)以及连接字符串中嵌入的密钥(PWD=...、apikey=...)。空/ null 凭据字段不会脱敏——“不存在凭据”是有效信号。
所有列表工具都支持分页(offset/limit,封装格式为 {total, offset, returned, truncated, items}),因此即使站点有数千个应用或用户,也不会撑爆客户端的上下文窗口。
渲染验证
现代 Sense 可视化是由客户端渲染的 nebula.js supernova,而不是由引擎渲染——即使引擎能够完美接受并计算超立方体,如果 supernova 缺少默认属性块,渲染结果仍会是空白(浏览器中会抛出 Cannot read properties of undefined;引擎对此一无所知)。构建器会为每种类型提供这些属性块,而 validate_sheet 会标记缺少这些属性块的对象。
由于引擎端验证无法证明实际像素是否绘出,有两个脚本可以闭环验证:scripts/viz_matrix.mjs 会针对实时站点,为每种受支持的类型各创建一个对象;scripts/render_proof.mjs 会驱动真实的无头浏览器,以工作表平铺尺寸检查结果,并报告实际绘制情况。
所有 12 种受支持的类型都已在 Qlik Sense May 2026 上通过渲染验证,验证环境为真实浏览器客户端,尺寸为工作表平铺尺寸:kpi、gauge、barchart、linechart、combochart、piechart、scatterplot、treemap、table、pivot-table、listbox、text-image。
获取图表的真实属性契约
supernova 无法绘制时,不要根据错误消息反向推导其属性——有些图表不会抛出任何有用的信息。改为询问客户端会写入哪些属性:
node scripts/harvest_client_props.mjs treemap ./truth.json
此操作会扫描所有可读取的应用,查找由客户端创建的该类型对象,并导出其属性。Qlik 随附的监控应用(Content / Operations / License Monitor)是很好的来源。最后两种故障类型就是这样修复的:此前多次猜测均未成功,而每种类型都只需一次采集就解决了:
- treemap 需要
qMode: "K"(树模式——与 pivot-table 需要"P"属于同类陷阱),其属性集也比通用构建器生成的精简得多。采集自 Qlik 随附的 Content Monitor 应用。 - gauge 需要
gaugetype、angle、autoOrientation、paletteProgressColor和segmentInfo——这些属性从未出现在任何错误消息中,因为 gauge 会静默失败。采集自为此专门在 Sense 客户端中创建的 gauge。
如果你创建的图表显示空白或报错,请在客户端中创建一个,采集其属性并照此实现。这个过程只需几分钟;而根据崩溃消息反向推导需要数小时,并且图表静默失败时根本无法完成。
如果你要构建类似的东西,以下三条方法建议值得借鉴:
- 对象是在工作表平铺尺寸下渲染,而不是在完整视口尺寸下渲染——一个能在 900×620 尺寸下绘制的图表,可能无法在 640×150 的平铺中显示。
- 统计绘制出的 SVG 节点并不能作为证明。 故障图表仍可能绘制图例,这就是早期版本的验证脚本误报 treemap 通过的原因。
- 自动判定仅供参考;截图才是依据。 Qlik 会将某些错误状态绘制为阴影根中的 SVG 文本,而 DOM 抓取和 Playwright 文本定位器都无法可靠匹配——treemap 显示了“无法显示此图表。”,但所有自动探测都判定其已成功渲染。运行
render_proof.mjs时设置SHOTS=<dir>,然后查看图像。
身份验证
两种模式,都是标准的 QSEoW 模式。我们有意不支持基于标头身份验证的虚拟代理:任何能够访问代理的客户端都可以声明任意身份,这不是构建 Agent 工具的可靠基础。
certificate — 使用 QMC 导出的客户端证书访问 QRS :4242 和 Engine :4747。这是服务到服务的路径;支持全部工具。通过 QMC 导出,或调用 POST /qrs/certificatedistribution/exportcertificates。
jwt — 通过 :443 上的 JWT 虚拟代理传递已签名且会过期的令牌。它携带真实的用户身份,因此,当 Agent 应以某个人的身份操作并继承该用户的区段访问权限和安全规则时,这是合适的模式。
平台特例: Proxy Service REST API(:4243,对应 list_user_sessions/end_user_sessions)只支持证书身份验证——Qlik 未为其提供 JWT 路由。只要配置了证书材料(QSEOW_CERT_PATH/QSEOW_CERT_KEY_PATH),这两个工具就会在任一身份验证模式下注册;否则不会出现在 tools/list 中。其他所有工具在两种模式下的覆盖范围都相同。
JWT 与 Engine WebSocket(CSWSH)
除上述两个仅支持证书的 QPS 会话工具外,两种模式都支持全部工具。JWT 要通过 Engine 验证需要特定的握手流程,这里对此作出说明,因为很容易出错,而且失败时只会返回一个空响应体的 403,难以判断原因。
虚拟代理会使用跨站 WebSocket 劫持防护来保护 WebSocket 升级请求。在升级请求中将 JWT 作为 bearer token 发送会失败——代理期望的格式与浏览器发送的相同:
- 使用
Authorization: Bearer <jwt>请求GET /{prefix}/qps/csrftoken。响应会在qlik-csrf-token响应标头中携带令牌(而非 Cookie),并通过Set-Cookie返回会话。 - 打开
wss://host/{prefix}/app/engineData?qlik-csrf-token=<token>上的 WebSocket,并发送该会话 Cookie——不要发送 bearer token。
服务会自动处理并缓存结果。缓存不只是优化:每个经过 bearer 身份验证的请求都会创建一个新的 Qlik 会话,而用户的并行会话数有限制,因此每次调用都重新验证身份最终会导致 Engine 返回 OnMaxParallelSessionsExceeded。
如果你正在排查类似的 403,以下都不是原因:Origin(浏览器会发送带端口的值,且该值会被接受)、Host、端口、隧道或端口转发、xrfkey,以及虚拟代理中的 websocketCrossOriginWhiteList 条目——该列表接受不带端口的主机名,而且无论如何都不会影响结果。
任何脚本化设置都值得检查的一项实际配置错误是:通过 QRS API 创建的虚拟代理,其 loadBalancingServerNodes 为空,因此在添加服务器节点前,无法通过该代理访问任何 Engine。
如需调试代理身份验证,请启用调试日志:创建 %ProgramData%\Qlik\Sense\Proxy\LocalLogConfig.xml,其中配置一个 threshold=debug 的 QSRollingFileAppender,并将其绑定到 Audit.Proxy、System.Proxy 和 Security.Proxy 日志记录器,然后重启代理。它会记录代理实际收到的每个请求标头,这是对比正常浏览器升级请求与客户端请求最快的方法。
生成测试 JWT
JWT 模式由你自带令牌:你通过 QSEOW_JWT(或 QSEOW_JWT_PATH)提供经过签名的 JWT,而 JWT 虚拟代理的配置决定哪些声明映射到 Qlik 身份。在常见配置中,VP 将 sub 映射到用户 ID,将目录声明映射到用户目录,并根据粘贴到 VP 中的证书验证签名。要生成短期测试令牌,请使用匹配的私钥进行签名(RS256):
// mint-jwt.mjs — node >=20, no deps. Usage: node mint-jwt.mjs > token.jwt
import { createSign } from "node:crypto";
import { readFileSync } from "node:fs";
const key = readFileSync(process.env.JWT_PRIVATE_KEY_PATH, "utf8"); // PEM the VP trusts
const b64u = (o) => Buffer.from(JSON.stringify(o)).toString("base64url");
const now = Math.floor(Date.now() / 1000);
const header = { alg: "RS256", typ: "JWT" };
const payload = {
sub: process.env.QLIK_USER_ID || "svc_agent", // → VP "User ID" claim
directory: process.env.QLIK_USER_DIRECTORY || "QSEOW", // → VP "User directory" claim
iat: now,
exp: now + 3600,
};
const unsigned = `${b64u(header)}.${b64u(payload)}`;
const sig = createSign("RSA-SHA256").update(unsigned).sign(key).toString("base64url");
process.stdout.write(`${unsigned}.${sig}`);
请根据你的虚拟代理属性映射设置声明名称——这些名称可在 QMC 中配置。你为其生成令牌的身份必须持有 Professional(或相应的)许可证分配,否则引擎会以不透明的套接字关闭方式拒绝 OpenDoc。
信任模型——在将其用于生产环境之前,请先阅读。 JWT 虚拟代理会根据你粘贴到其中的证书验证每个令牌;只有使用匹配的私钥签名的令牌才会被接受。因此,该私钥是一项主凭据:持有它的人可以生成令牌并声明代理会映射的任何身份,这与任何 SAML/OIDC 身份提供商如出一辙。这是 JWT SSO 固有的特性,并非此服务额外引入的——qseow-mcp 只是一个用于出示令牌的客户端;对于它不持有私钥的代理,它无法冒充任何身份。出于同样的原因,上面的代码片段可以安全公开:它只能针对你已经控制的代理进行签名。因此,安全性取决于以下四点,按重要性排序:(1)像保护至关重要的资产一样保护签名密钥——存放在机密存储或 HSM 中,绝不放进代码仓库;一旦怀疑密钥泄露,就立即轮换;(2)身份验证不等于授权——生成令牌的身份仍受该用户的安全规则、流访问权限和分段访问权限约束,因此应通过限制 Qlik 用户的权限来限制 Agent 的权限(这也是优先选择 JWT 而非证书模式的原因;证书模式以绕过安全规则的内部身份运行);(3)该身份需要许可证分配才能执行任何操作;(4)令牌应保持短有效期(示例中的令牌一小时后过期),这样令牌泄露后会自行失效,而密钥泄露则不会。此服务默认是只读的,因此即使身份有效,除非你启用写入,否则也无法修改数据。
面向生产环境规划 JWT
接下来很自然会问:“那么,真正的用户如何以自己的身份(且不会冒充他人)获取令牌?”答案在 Qlik 之外。JWT 代理不会验证任何人的身份;它信任持有签名密钥的一方已经完成了身份验证。因此,身份保证由令牌签发方来落实:(a) 使用真实凭据验证用户身份——例如企业 IdP、MFA,或你已在使用的其他方式;(b) 确保只将该已验证用户的身份写入声明。用户向签发方进行身份验证;只有签发方持有密钥,用户永远不会看到密钥。请选择适合的方案:
- 交互式用户 → 完全不要使用 JWT。 将用户引导至 OIDC 或 SAML 虚拟代理,让现有 IdP(Entra ID / Okta / Google / ADFS)使用各自的登录方式和 MFA 对其进行身份验证。此后,添加用户只需在 IdP 中操作并分配 Qlik 许可证,无需签发令牌或处理密钥。这是面向用户的默认正确方案。
- 服务或 Agent → 专用 Qlik 身份。 配置一个受治理的服务用户(例如
svc_support_agent),使用安全规则限定其权限,并为该身份签发令牌。Agent 以自身身份运行,而不是以某个人的身份运行。这是始终在线的 Agent 最简洁的方案。 - Agent 代表特定用户执行操作 → 可信中间层。 一个小型服务通过你的 IdP 验证用户身份,然后签发短期、按用户区分的 JWT,使 Agent 精确继承该用户的区段访问权限。只有在确实需要通过 Agent 实现按用户限定数据访问时,才应采用此方案。
首次就正确搭建签发方、配置 IdP 连接并设置访问范围,才是值得认真做好的部分——Terenzi LLC 在支持 Agent 部署中正是负责这些工作。
从源代码运行
用于开发,或自行构建 Claude Desktop 安装包
(node mcpb/build.mjs → mcpb/qseow-mcp-<version>.mcpb)。
npm install && npm run build
cp .env.example .env # fill in host + auth
node dist/index.js # stdio MCP server
如果存在 ./.env,服务器会自动读取该文件(或读取由 QSEOW_ENV_PATH 指定的文件);环境中已设置的变量始终优先。向 MCP 客户端(Claude Desktop / Claude Code)注册时,可以在客户端的 env 块中传入变量,也可以将 QSEOW_ENV_PATH 设置为绝对路径——客户端会控制工作目录,因此可能找不到相对路径 ./.env。
演示
examples/ 中有三个可运行的演示(仅在 GitHub 仓库中提供,不包含在 npm 包内)。每个演示都有运行手册和带断言的 trace.mjs,因此其中的说明都可验证,而非仅作示意:
| 演示 | 展示内容 | 工具耗时 |
|---|---|---|
| finance-close | 找出 5,000 万美元对账差异的根本原因:KPI → 定义 → 血缘 → 脚本 → 修复 → 对账 | 约 5 秒 |
| ops | 夜间重新加载为何失败;引擎是否健康;安全规则基线是否发生偏移 | 约 3 秒 |
| builder | 根据需求构建工作表、拒绝无意义内容、发现静默错误的度量,并验证能否渲染 | 约 20 秒 |
使用 cd examples/<demo> && node trace.mjs 运行任一演示——退出代码非零表示断言失败。
针对运行中站点的集成冒烟测试(会创建一个小型演示应用,需要设置 QSEOW_ALLOW_MUTATIONS=true):
npm run smoke
备注
- 引擎会话按服务器进程缓存,并在空闲 5 分钟后清除,因此在同一对话的多次工具调用之间会保留选择状态。
- 每次 QRS 调用都会生成一个新的
xrfkey。 QSEOW_TLS_VERIFY=false可用于使用自签名证书的实验环境;在生产环境中请保持启用。
商业支持
qseow-mcp 免费且开源,并将始终如此。如果你希望部署并验证一套针对自有环境运行的 Qlik 故障排查与支持 Agent——包括服务、Agent 配置、操作手册和团队培训——Terenzi LLC 可提供这项服务。你可以先进行固定费用的只读评估。
Terenzi LLC 是 Qlik 合作伙伴;本项目独立于 Qlik,并非 Qlik 产品(请参阅上文的商标说明)。
许可证
Apache-2.0 — Copyright 2026 Terenzi LLC。请参阅 LICENSE 和 NOTICE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。