mcpField
C
ConnectWise PSA

ConnectWise PSA

本地服务
github.com商业与营销63 周前更新

关于 ConnectWise PSA

ConnectWise PSA 是面向服务提供商技术人员、调度员和财务人员的 MCP 服务,用于操作 ConnectWise Manage。它按角色组织工具集,也提供精选工具之外的 API 访问;本地部署可选只读 SQL 报表功能。

主要功能

  1. 01管理工单、备注和工单工时
  2. 02记录工时并提交工时表
  3. 03搜索公司、联系人和资产
  4. 04安排调度并查看成员空闲情况
  5. 05查看发票、协议和未开票工时
  6. 06可选的只读 SQL 报表

适用场景

  1. 01跟进服务和项目工单
  2. 02记录工作并提交工时表
  3. 03依据成员空闲情况安排调度
  4. 04汇总本地 PSA 数据进行报表分析

MCP 相关

向 MCP 客户端提供 ConnectWise PSA 工具,并按可选工具集和角色预设分组。支持 stdio 和 streamable HTTP;本地部署可启用可选 SQL 工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"selic-mcp-connectwise-psa": {
"command": "npx",
"args": [
"-y",
"mcp-connectwise-psa"
],
"env": {
"CW_SITE": "<CW_SITE>",
"CW_COMPANY_ID": "<CW_COMPANY_ID>",
"CW_CLIENT_ID": "<CW_CLIENT_ID>",
"CW_PUBLIC_KEY": "<CW_PUBLIC_KEY>",
"CW_PRIVATE_KEY": "<CW_PRIVATE_KEY>",
"CW_MEMBER_IDENTIFIER": "<CW_MEMBER_IDENTIFIER>"
}
}
}
}
启动命令npx -y mcp-connectwise-psa
需要配置的环境变量
CW_SITEConnectWise host (e.g. na.myconnectwise.net or an on-prem host; full URLs accepted)
CW_COMPANY_IDConnectWise login company id
CW_CLIENT_IDIntegration clientId from developer.connectwise.com
CW_PUBLIC_KEY密钥API member public key
CW_PRIVATE_KEY密钥API member private key
CW_MEMBER_IDENTIFIERMember identifier the API keys belong to — enables "my tickets"/"my time" tools

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmmcp-connectwise-psa0.4.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

mcp-connectwise-psa

适用于 ConnectWise PSA(Manage)的 MCP(Model Context Protocol)服务 — 精选了涵盖 8 个工具集的工具,面向技术人员、调度员和账单人员;此外还提供用于访问 API 其他功能的备用入口,以及适用于本地部署的只读 SQL 工具集,让 AI 助手能够按照不同角色的工作方式使用 PSA:

  • 工单 — 搜索 / 我的工单 / 完整详情,创建工单,更新状态 / 优先级 / 负责人,添加讨论 / 内部备注,还可发现看板·状态·优先级,并查看每张工单的工时和任务。涵盖服务工单和项目工单 — ConnectWise 将它们保存在不同的资源中,因此读取工具会同时查询两者,而按 ID 查询的工具会检测 ID 所属的类型
  • 工时 — 将工时记录到工单(包含工作角色、工作类型,以及 CW 的休息时间扣除功能),查看自己的工时,查询工作角色和工作类型,以及查看和提交工时表
  • 公司和联系人 — 快速查找、联系人详情(电话 / 邮箱)、公司站点
  • 配置项 — 设备 / 资产的序列号、IP、操作系统和保修信息(只读)
  • 调度 (排程) — 排程条目(列表 / 我的 / 创建 / 重新排程 / 取消),以及成员的时区、工作时间和空闲 / 已预订状态
  • 开票 (财务,只读) — 发票、协议,以及可开票但尚未开票的工时
  • SQL (仅限本地部署) — 直接对 cwwebapp_* Manage 数据库执行只读 T-SQL,以完成 REST 无法表达的跨表报告;附带可搜索的架构目录和已保存查询库,助手可以不断扩充。通过配置 CW_DB_* 启用;启用后,未缩小工具集范围的每个会话都会包含此工具集
  • 工具集和角色预设 — 通过 x-cw-toolsets 标头(或 CW_TOOLSETS)仅启用会话所需的工具;预设包括 tech / dispatch / invoicing / all。默认为 all — 如需更小的工具范围,可按会话缩小范围。每个工具还会通过 _meta.group 报告其所属工具集,让聚合器(MSPStack 网关)能够按能力分组和切换工具
  • 每位成员的 API 密钥(BYOK) — 每位用户提供自己的 ConnectWise 成员密钥;ConnectWise 会强制执行该成员的安全角色,且每次写入都会归属到实际操作人员
  • 传输方式 — 本地使用 stdio,共享部署使用 streamable HTTP;包含 Docker 镜像

快速开始(本地,stdio)

npm install && npm run build
CW_SITE=na.myconnectwise.net \
CW_COMPANY_ID=yourcompany \
CW_CLIENT_ID=<integration clientId> \
CW_PUBLIC_KEY=xxxx CW_PRIVATE_KEY=yyyy \
CW_MEMBER_IDENTIFIER=jdoe \
node dist/index.js

Claude Desktop / Claude Code 配置:

{
  "mcpServers": {
    "connectwise": {
      "command": "node",
      "args": ["/path/to/mcp-connectwise-psa/dist/index.js"],
      "env": {
        "CW_SITE": "na.myconnectwise.net",
        "CW_COMPANY_ID": "yourcompany",
        "CW_CLIENT_ID": "<clientId>",
        "CW_PUBLIC_KEY": "xxxx",
        "CW_PRIVATE_KEY": "yyyy",
        "CW_MEMBER_IDENTIFIER": "jdoe"
      }
    }
  }
}

ConnectWise API 要求提供 clientId — 请在 developer.connectwise.com 注册一个免费集成。API 成员密钥可在 ConnectWise 的我的账户 → API 密钥(按成员)或系统 → 成员 → API 成员(集成账户)中创建。

HTTP 部署

CW_SITE=… CW_COMPANY_ID=… CW_CLIENT_ID=… \
node dist/index.js --transport http --port 3000

也可使用 Docker:docker build -t mcp-connectwise-psa . && docker run -p 3000:3000 -e CW_SITE -e CW_COMPANY_ID -e CW_CLIENT_ID mcp-connectwise-psa

路由用途
POST/GET/DELETE /mcpMCP streamable-http 端点
GET /health存活探针

会话保存在内存中 — 请运行单个实例(或使用粘性会话)。

访问控制 — 自带密钥(BYOK)

通过 HTTP 时,MCP 层没有角色系统。每个会话都会提供自己的 ConnectWise 成员 API 密钥,访问控制由 ConnectWise 本身负责:成员的安全角色决定哪些操作能够成功,且每条备注和时间记录都会归属到该成员名下。

在初始化请求(以及会话中的每个后续请求)中发送密钥:

x-cw-public-key:  <public key>
x-cw-private-key: <private key>
x-cw-member-id:   <your member identifier>   (optional — enables "my tickets"/"my time")
  • 未提供密钥的请求会被拒绝,并返回 401;两个密钥标头必须同时提供。
  • 密钥不会被记录。会话会绑定到密钥对的 SHA-256 哈希;在同一会话 ID 上提供不同的密钥对 → 403。
  • 在 ConnectWise 的 我的账户 → API 密钥 下创建成员 API 密钥。每位技术人员都应使用自己的密钥。

本地 stdio 是单用户模式,使用环境中的 CW_PUBLIC_KEY/CW_PRIVATE_KEY,而不是标头。

工具集

工具按工具集分组,让会话只看到所需的功能 — 调度员不需要发票工具,精简的工具范围也能让助手保持专注(并节省上下文)。写入操作能否成功,仍由成员的 ConnectWise 安全角色决定。

工具集键工具
ticketscw_search_tickets、cw_my_tickets、cw_get_ticket、cw_create_ticket、cw_update_ticket、cw_add_ticket_note、cw_bundle_tickets、cw_list_boards、cw_get_board、cw_list_priorities、cw_list_ticket_time、cw_list_ticket_tasks
timecw_create_time_entry、cw_update_time_entry、cw_list_my_time、cw_list_work_roles、cw_list_work_types、cw_list_my_timesheets、cw_submit_timesheet
companiescw_search_companies、cw_get_company、cw_search_contacts、cw_get_contact、cw_list_company_sites
configurationscw_list_configurations、cw_get_configuration
schedulecw_list_schedule_entries、cw_my_schedule、cw_schedule_ticket、cw_update_schedule_entry、cw_delete_schedule_entry、cw_member_availability、cw_list_members、cw_get_member
financecw_list_invoices、cw_get_invoice、cw_list_agreements、cw_get_agreement、cw_list_unbilled_time
advancedcw_find_endpoint(搜索整个 CW API — 约 1,150 个端点)、cw_get(对任意路径执行只读 GET)
sql (本地部署,需要 CW_DB_*)cw_db_query(只读 T-SQL)、cw_db_find_table(架构目录)、cw_db_find_query / cw_db_save_query(已保存查询库)

预设会按角色打包工具集键:tech = tickets + time + companies + configurations · dispatch = tickets + schedule + companies + configurations · invoicing = finance + time + companies · all = 所有键。角色预设会刻意排除 sql — 技术人员使用的工具范围并不等同于数据库访问范围。

advanced 工具集是备用通道(包含在 all 中,但不包含在任何角色预设中):cw_find_endpoint 会搜索整个 ConnectWise API 的内置目录,cw_get 可对任意路径执行只读 GET — 因此助手能够访问精选工具未封装的长尾功能(采购、销售、项目、系统……)。若要移除它,请改为指定工具集键或角色预设(x-cw-toolsets: tech)。

使用逗号分隔的列表选择工具集,可混合使用键和预设:

  • HTTP — 使用 x-cw-toolsets 标头,按会话设置:x-cw-toolsets: dispatch 或 x-cw-toolsets: tech,finance。
  • stdio — 使用 CW_TOOLSETS 环境变量或 --toolsets 标志:CW_TOOLSETS=invoicing。

默认值为 all 预设 — 即服务配置的所有功能;需要更精简工具范围的客户端可指定所需的工具集键或角色。CW_TOOLSETS/--toolsets 中的未知键会导致快速失败;x-cw-toolsets 标头中的未知项会被忽略。唯一具有破坏性的工具是 cw_delete_schedule_entry(dispatch);finance 为只读。cw_db_save_query 会写入数据,但写入目标是查询库文件 — 数据库访问本身通过授权仅限 SELECT。

例外:sql 工具集

其他所有工具集都使用调用方自己的 ConnectWise 密钥,因此 ConnectWise 会对返回结果进行筛选。sql 则不同:它通过服务器级只读登录账号读取数据库,因此查询结果不会归属于任何成员,也不会受到该成员的安全角色、服务板限制或记录权限的筛选。

因此,配置 CW_DB_* 才是关键决策。服务器配置好数据库后,sql 就是一个普通的密钥:它包含在 all 中,也包含在默认选择中,而且任何未缩小工具集范围的会话都能读取整个 PSA 数据库。没有配置 CW_DB_* 的服务器会静默移除它,因此不需要它的部署不会受到影响。

如果需要为部分调用方提供数据库访问权限,而不向其他调用方开放,请按会话配置(x-cw-toolsets: tech),或在服务器前面进行配置——聚合网关可以单独对 cw_db_* 工具分级。服务器端限制损害范围的关键是登录账号:请参阅下方的运行手册,并将其权限限制为 db_datareader,同时拒绝访问凭据列。

SQL 工具集(本地部署数据库)

云托管的 ConnectWise 不提供数据库访问权限,因此此工具集仅适用于本地部署。将其指向 Manage 数据库,并使用专为此用途创建的登录账号:

CW_DB_HOST=sqlhost CW_DB_NAME=cwwebapp_acme \
CW_DB_USER=cw_mcp_ro CW_DB_PASSWORD=… \
CW_DB_QUERY_LIBRARY=/data/cw-queries.json \
node dist/index.js

仅此而已:配置数据库后,sql 工具集就会包含在默认选择中。未配置 CW_DB_* 却指定 sql 会导致启动失败(像 all 这样仅包含它的选择则会将其移除)。只有会话实际使用某个工具时,才会连接数据库。

请从报表视图开始。 ConnectWise 提供了非规范化的 v_rpt_* 视图,其中已将服务板、状态、公司和联系人关联到记录上,例如 v_rpt_service、v_rpt_time、v_rpt_company、v_rpt_invoices、v_rpt_agreementlist。cw_db_find_table 可识别这些视图及其背后的基础表;它只返回关键列,因为只需执行一次 INFORMATION_SCHEMA 查询,就能获取确切的列清单,而且对于你的版本始终准确。

已保存查询库由已提交的核心内容和 CW_DB_QUERY_LIBRARY(JSON 格式,{ version, queries[] })中的可写覆盖项组成。覆盖项按 slug 优先,cw_db_save_query 会向其中追加内容,而 scripts/import-queries.mjs 可从现有的 BrightGauge 导出文件填充该库:

node scripts/import-queries.mjs /path/to/brightgauge-export

导入的查询不会存放在此仓库中——它们属于你的报表,可能包含公司名称和费率。在容器中运行时,请将 CW_DB_QUERY_LIBRARY 指向已挂载的存储,否则容器销毁后,已保存的查询也会一并丢失。

登录账户就是安全边界

服务器不会验证语句:服务器会将模型的 SQL 原样发送给 SQL Server,因此登录账户获准执行的操作,就是实际可能发生的操作。以下两个脚本会完成设置并进行验证。

创建账户——编辑顶部的四个变量,以 sysadmin 身份运行。@WhatIf 默认为 1,因此首次运行只会打印计划:

sqlcmd -S SQLHOST\CWPROD -d master -i scripts/create-readonly-login.sql

此脚本创建的登录账户不属于任何服务器角色,并将其添加到一个数据库的 db_datareader 角色中;对其他所有操作(EXECUTE、所有写入、DDL、BACKUP)执行 DENY,并对其发现的所有类似凭据的列执行 SELECT 的 DENY——这些列名会随 Manage 版本变化,而且每个 MSP 都会添加自己的列,因此脚本会查找它们,而不是硬编码。重复运行是安全的;升级添加表后,可用此脚本重新应用 DENY。脚本会报告必须关闭的实例级设置,但绝不会更改它们:禁用 xp_cmdshell 可能会破坏其他应用程序,因此是否禁用由你决定。

验证账户——使用新登录账户而非管理员身份运行:

sqlcmd -S SQLHOST\CWPROD -d cwwebapp_acme -U cw_mcp_ro -P '<password>' -i scripts/verify-readonly-login.sql

每项检查都会输出 PASS 或 FAIL:SELECT 可用;UPDATE/CREATE TABLE 会被拒绝(在始终回滚的事务中执行,以防某项 DENY 缺失);无法访问 xp_cmdshell/sp_OACreate/OPENROWSET(BULK …);无法读取凭据列;且该登录账户不属于任何高权限角色。只要有一项 FAIL,就先不要启用工具集。

有两点需要提前了解:

  • 对含有被拒绝访问列的任何表执行 SELECT * 都会失败,而不是返回其他列。这正是我们想要的效果;工具返回的错误会提示模型明确指定列名。
  • 关键权限是 EXECUTE。 有了这项权限,“只读 SQL”就会变成以 SQL Server 服务账户身份远程执行代码——例如 xp_cmdshell、sp_OACreate、sp_send_dbmail,以及用于捕获 NTLM 凭据的 xp_dirtree。无需 EXECUTE 权限,OPENROWSET/BULK INSERT 也能读取文件,因此还必须关闭 Ad Hoc Distributed Queries。

运维建议:优先使用可读的 AG 辅助副本或还原后的报表副本,而非生产主副本;将 SQL 端口的防火墙访问限制为仅允许 MCP 主机;并为此登录账户启用 SQL Audit 或 Extended Events 会话。

配置参考

变量默认值用途
CW_SITE—ConnectWise 主机(云端或本地部署;接受完整 URL)
CW_COMPANY_ID—登录公司 ID
CW_CLIENT_ID—集成 clientId
CW_PUBLIC_KEY / CW_PRIVATE_KEY—API 成员密钥——stdio 必需;HTTP 不使用(BYOK)
CW_MEMBER_IDENTIFIER—stdio 密钥所属的成员(my-tickets/my-time)
TRANSPORT / PORTstdio / 3000传输方式选择
CW_TOOLSETSall已启用的工具集(键/预设);HTTP 可通过 x-cw-toolsets 按会话覆盖
CW_DB_HOST—ConnectWise SQL Server 主机,或 host\INSTANCE——启用 sql 工具集
CW_DB_NAME / CW_DB_USER / CW_DB_PASSWORD—数据库及其专用只读登录账户(四项必须同时提供)
CW_DB_PORT1433TCP 端口;与命名实例同时使用时无效
CW_DB_ENCRYPT / CW_DB_TRUST_SERVER_CERTtrue / trueTLS,以及是否接受本地部署环境中常见的自签名证书
CW_DB_READ_UNCOMMITTEDtrue以 READ UNCOMMITTED 级别读取,避免报表查询阻塞生产写入
CW_DB_QUERY_TIMEOUT_MS / CW_DB_MAX_ROWS30000 / 200单次查询时限和行数上限
CW_DB_QUERY_LIBRARY—可写的已保存查询文件路径;未设置 ⇒ 仅使用内置查询,不提供保存工具

注意事项与限制

  • 工单搜索默认仅搜索未关闭的工单;状态/看板名称必须完全匹配,文本筛选条件按子字符串匹配。
  • 服务工单和项目工单位于 ConnectWise 的不同资源中。读取工具接受 ticket_type(默认为 both),并会合并结果;按 ID 查询的工具默认为 auto,会检测资源,因此会多进行一次查询——传入 service/project 可跳过检测。cw_create_ticket 仅创建服务工单:项目工单需要指定项目和阶段。
  • 已记录时段中的休息时间应填写在 hours_deduct 中,time_end 保持为实际结束时间。若改为传入缩短后的 hours,ConnectWise 会显示一个实际并未发生的结束时间。
  • 时间戳必须精确到整秒——服务端会进行规范化处理(ConnectWise 不接受小数秒)。
  • 时间条目要求 ConnectWise 中存在覆盖该条目日期的开放时间报告周期;若不存在,API 的消息会直接传回。
  • 某些本地部署版本缺少 /system/myAccount——对于“我的工单”/“我的时间”,请显式提供成员标识符(CW_MEMBER_IDENTIFIER 或 x-cw-member-id)。
  • 讨论备注对客户可见;内部备注则不可见——工具会明确区分。时间条目的备注可以复制到工单的讨论(add_to_detail)、内部分析(add_to_internal)、解决方案(add_to_resolution)中,也可以不复制;结果会说明复制到了哪里。请注意,三项都关闭时,备注仍保留在时间条目中,并不意味着它会变成内部备注。
  • cw_db_query 会在达到 max_rows(默认值为 200)或约 20,000 个字符的上限时停止,并在服务端取消查询;响应会说明触发了哪个限制。每次查询的默认期限为 30 秒,最长为 120 秒。
  • 数据库连接以 READ UNCOMMITTED 模式读取,避免报告扫描阻塞技术人员保存工单。代价是可能出现脏读:有并发写入时,计数只是近似值。如果报告必须精确,请设置 CW_DB_READ_UNCOMMITTED=false。
  • 对含有 DENY 权限列的表执行 SELECT * 会失败——请明确指定所需列。
  • 云托管的 ConnectWise 实例无法访问数据库;sql 工具集仅适用于本地部署。

开发

npm install
npm run dev          # stdio via tsx
npm run dev:http     # http via tsx
npm test             # vitest
npm run build        # tsc → dist/

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。