Skip to main content
Glama
mspstack

mcp-connectwise-psa

by mspstack

mcp-connectwise-psa

Un servidor MCP (Model Context Protocol) para ConnectWise PSA (Manage): herramientas seleccionadas en 8 conjuntos de herramientas que cubren a técnicos, despachadores y facturación, además de una vía de escape para el resto de la API y un conjunto de herramientas SQL de solo lectura para implementaciones locales, de modo que un asistente de IA trabaje con PSA como lo haría cada rol:

  • Tickets — búsqueda / mis tickets / detalle completo con notas, crear, actualizar estado/prioridad/propietario, añadir notas de discusión/internas, además de descubrimiento de tableros·estados·prioridades y tiempo y tareas por ticket

  • Tiempo — registrar tiempo en tickets, revisar tu propio tiempo, consulta de roles de trabajo, y listar y enviar tus hojas de horas

  • Empresas y contactos — búsqueda rápida, detalle de contacto (teléfonos/correos), sedes de empresa

  • Configuraciones — dispositivos/activos con números de serie, IP, SO, garantía (solo lectura)

  • Despacho (horario) — entradas de horario (listar/mías/crear/reprogramar/cancelar), y miembros con su zona horaria, horario laboral y disponibilidad libre frente a reservada

  • Facturación (finanzas, solo lectura) — facturas, acuerdos y tiempo facturable no facturado listo para facturar

  • SQL (solo local) — T-SQL de solo lectura directamente contra la base de datos de Manage cwwebapp_* para los informes entre tablas que REST no puede expresar, con un catálogo de esquema buscable y una biblioteca de consultas guardadas que el asistente puede ampliar. Se habilita configurando CW_DB_*; donde esté, cada sesión que no restrinja sus conjuntos de herramientas lo tendrá

  • Conjuntos de herramientas y perfiles — active solo lo que una sesión necesite mediante la cabecera x-cw-toolsets (o CW_TOOLSETS); ajustes predefinidos tech / dispatch / invoicing / all. El valor predeterminado es all — redúzcalo por sesión cuando se desee una superficie menor. Cada herramienta también informa de su conjunto como _meta.group, de modo que un agregador (la pasarela MSPStack) pueda agrupar y cambiar de herramientas según la capacidad

  • Claves de API por miembro (BYOK) — cada usuario aporta sus propias claves de miembro de ConnectWise; ConnectWise aplica el rol de seguridad de ese miembro, y cada escritura se atribuye a la persona real

  • Transportes — stdio para uso local, HTTP transmisible para implementaciones compartidas; imagen de Docker incluida

Inicio rápido (local, 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

Configuración de 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 exige un clientId en la API: registre una integración (gratuita) en developer.connectwise.com. Las claves de miembro de la API se crean en ConnectWise en Mi cuenta → Claves de API (por miembro) o Sistema → Miembros → Miembros de API (cuentas de integración).

Related MCP server: superops-mcp

Implementación HTTP

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

O con 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

Ruta

Propósito

POST/GET/DELETE /mcp

Punto de conexión MCP streamable-http

GET /health

Sonda de actividad

Las sesiones se mantienen en memoria: ejecute una única instancia (o sesiones fijas).

Control de acceso: traiga sus propias claves (BYOK)

Por HTTP no hay ningún sistema de roles a nivel de MCP. Cada sesión presenta sus propias claves de miembro de ConnectWise, y es el propio ConnectWise el que actúa como control de acceso: el rol de seguridad del miembro decide qué se permite, y cada nota y entrada de tiempo se atribuye a ese miembro.

Envíe sus claves en la solicitud de inicialización (y en cada solicitud posterior de la sesión):

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")
  • Una solicitud sin claves se rechaza con 401; ambas cabeceras de clave son obligatorias a la vez.

  • Las claves nunca se registran. Una sesión se vincula a un hash SHA-256 del par de claves; presentar un par distinto en el mismo id de sesión → 403.

  • Cree claves de miembro de la API en ConnectWise en Mi cuenta → Claves de API. Cada técnico usa las suyas.

El stdio local es de un solo usuario y usa CW_PUBLIC_KEY/CW_PRIVATE_KEY del entorno en lugar de cabeceras.

Conjuntos de herramientas

Las herramientas se agrupan en conjuntos de herramientas para que una sesión solo vea las capacidades que necesita: un despachador no necesita las herramientas de facturación, y una superficie de herramientas pequeña mantiene al asistente centrado (y su contexto económico). Que una escritura tenga éxito o no lo sigue rigiendo el rol de seguridad del miembro en ConnectWise.

Clave del conjunto

Herramientas

tickets

cw_search_tickets, cw_my_tickets, cw_get_ticket, cw_create_ticket, cw_update_ticket, cw_add_ticket_note, cw_list_boards, cw_get_board, cw_list_priorities, cw_list_ticket_time, cw_list_ticket_tasks

time

cw_create_time_entry, cw_update_time_entry, cw_list_my_time, cw_list_work_roles, cw_list_my_timesheets, cw_submit_timesheet

companies

cw_search_companies, cw_get_company, cw_search_contacts, cw_get_contact, cw_list_company_sites

configurations

cw_list_configurations, cw_get_configuration

schedule

cw_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

finance

cw_list_invoices, cw_get_invoice, cw_list_agreements, cw_get_agreement, cw_list_unbilled_time

advanced

cw_find_endpoint (busca en toda la API de CW — ~1150 puntos de conexión), cw_get (GET de solo lectura en cualquier ruta)

sql (local, requiere CW_DB_*)

cw_db_query (T-SQL de solo lectura), cw_db_find_table (catálogo de esquema), cw_db_find_query / cw_db_save_query (biblioteca de consultas guardadas)

Ajustes predefinidos agrupan claves por perfil: tech = tickets + time + companies + configurations · dispatch = tickets + schedule + companies + configurations · invoicing = finance + time + companies · all = todas las claves. Los ajustes predefinidos de perfil excluyen deliberadamente sql: una superficie de técnico no es una superficie de base de datos.

El conjunto advanced es la vía de escape (está en all, pero en ningún ajuste predefinido de perfil): cw_find_endpoint busca en un catálogo integrado de toda la API de ConnectWise, y cw_get realiza un GET de solo lectura en cualquier ruta, de modo que el asistente pueda llegar a la larga cola (aprovisionamiento, ventas, proyectos, sistema…) que las herramientas seleccionadas no envuelven. Para eliminarlo, nombre las claves o un ajuste predefinido de perfil en su lugar (x-cw-toolsets: tech).

Seleccione conjuntos de herramientas con una lista separada por comas que mezcle claves y ajustes predefinidos:

  • HTTP — la cabecera x-cw-toolsets, por sesión: x-cw-toolsets: dispatch o x-cw-toolsets: tech,finance.

  • stdio — la variable de entorno CW_TOOLSETS o el indicador --toolsets: CW_TOOLSETS=invoicing.

El valor predeterminado es el ajuste predefinido all — toda la capacidad para la que esté configurado el servidor; un cliente que quiera una superficie menor nombra las claves o el perfil que necesite. Las claves desconocidas en CW_TOOLSETS/--toolsets fallan de inmediato; los tokens desconocidos en la cabecera x-cw-toolsets se ignoran. La única herramienta destructiva es cw_delete_schedule_entry (dispatch); finanzas es de solo lectura. cw_db_save_query escribe, pero en el archivo de la biblioteca de consultas: el acceso a la base de datos en sí es solo SELECT por concesión.

Excepción: el conjunto de herramientas sql

Cualquier otro conjunto de herramientas se ejecuta con las claves de ConnectWise del propio llamante, por lo que ConnectWise filtra lo que se devuelve. sql no: lee la base de datos mediante un inicio de sesión de solo lectura en todo el servidor, por lo que sus resultados no se atribuyen a un miembro ni se filtran por el rol de seguridad, las restricciones de tablero o los permisos de registro de ese miembro.

Por tanto, configurar CW_DB_* es la decisión que importa. Una vez que un servidor tiene una base de datos, sql es una clave normal: está en all, está en la selección predeterminada, y toda sesión que no restrinja sus conjuntos de herramientas puede leer toda la base de datos de PSA. Un servidor sin CW_DB_* la elimina silenciosamente, de modo que nada se rompe para las implementaciones que nunca la quisieron.

Si necesita acceso a la base de datos para algunos llamantes pero no para otros, hágalo por sesión (x-cw-toolsets: tech) o delante del servidor: una pasarela agregadora puede clasificar las herramientas cw_db_* por separado. Lo que limita el daño en el lado del servidor es el inicio de sesión: consulte el runbook a continuación y manténgalo en db_datareader con las columnas de credenciales denegadas.

Conjunto de herramientas SQL (base de datos local)

ConnectWise alojado en la nube no ofrece acceso a la base de datos, por lo que este conjunto de herramientas es solo para implementaciones locales. Apúntelo a la base de datos de Manage con un inicio de sesión creado precisamente para este fin:

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

Eso es todo: con una base de datos configurada, el conjunto de herramientas sql forma parte de la selección predeterminada. Nombrar sql sin CW_DB_* falla al inicio (una selección que solo lo incluya, como all, se elimina en su lugar). Nada se conecta a la base de datos hasta que una sesión usa realmente una herramienta.

Empiece por las vistas de informes. ConnectWise incluye vistas desnormalizadas v_rpt_* que ya unen tablero, estado, empresa y contacto a un registro: v_rpt_service, v_rpt_time, v_rpt_company, v_rpt_invoices, v_rpt_agreementlist. cw_db_find_table las conoce a ellas y a las tablas base que hay detrás; solo incluye columnas clave, porque la lista exacta de columnas está a una consulta INFORMATION_SCHEMA de distancia y siempre es correcta para su versión.

La biblioteca de consultas guardadas es el núcleo confirmado más una superposición de escritura en CW_DB_QUERY_LIBRARY (JSON, { version, queries[] }). Las entradas de la superposición ganan por slug, cw_db_save_query añade a ella, y scripts/import-queries.mjs la rellena desde una exportación existente de BrightGauge:

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

Las consultas importadas permanecen fuera de este repositorio: son sus informes y pueden contener nombres de empresa y tarifas. En un contenedor, apunte CW_DB_QUERY_LIBRARY a un almacenamiento montado o las consultas guardadas morirán con el contenedor.

El inicio de sesión es el límite de seguridad

No hay validación de sentencias: el servidor envía el SQL del modelo a SQL Server tal cual, por lo que lo que el inicio de sesión pueda hacer es exactamente lo que puede ocurrir. Dos scripts lo configuran y lo demuestran.

Créelo — edite las cuatro variables de la parte superior, ejecútelo como administrador del sistema. @WhatIf tiene el valor predeterminado 1, por lo que la primera ejecución solo imprime el plan:

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

Crea el inicio de sesión sin ningún rol de servidor, lo añade a db_datareader en una base de datos, deniega todo lo demás (EXECUTE, todas las escrituras, DDL, BACKUP) y deniega SELECT en cada columna de aspecto de credencial que descubra: los nombres cambian entre versiones de Manage y cada MSP añade los suyos, por lo que se encuentran en lugar de estar codificados. Volver a ejecutarlo es seguro y así es como se vuelven a aplicar las denegaciones después de que una actualización añada tablas. Informa de los ajustes de toda la instancia que deben estar desactivados pero nunca los cambia: deshabilitar xp_cmdshell puede romper otras aplicaciones, por lo que eso sigue siendo una decisión.

Verifíquelo — como el nuevo inicio de sesión, no como administrador:

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

Cada comprobación imprime PASS o FAIL: SELECT funciona, UPDATE/CREATE TABLE se rechazan (dentro de una transacción que siempre revierte, por si falta un DENY), xp_cmdshell/sp_OACreate/OPENROWSET(BULK …) son inalcanzables, una columna de credenciales es ilegible y el inicio de sesión no tiene ningún rol elevado. Un FAIL significa que aún no se debe habilitar el conjunto de herramientas.

Dos consecuencias que conviene saber de antemano:

  • SELECT * falla en cualquier tabla con una columna denegada, en lugar de devolver las demás columnas. Ese es el objetivo; el error de la herramienta le dice al modelo que nombre sus columnas.

  • EXECUTE es el permiso que importa. Con él, el "SQL de solo lectura" se convierte en ejecución remota de código como la cuenta de servicio de SQL Server: xp_cmdshell, sp_OACreate, sp_send_dbmail, xp_dirtree para captura NTLM. OPENROWSET/BULK INSERT leen archivos sin necesidad de EXECUTE, por lo que las consultas distribuidas ad hoc también deben estar desactivadas.

Operativamente: prefiere una secundaria de AG legible o una copia de informes restaurada en lugar de la principal de producción, protege con cortafuegos el puerto SQL hacia el host MCP y mantén una sesión de SQL Audit o Extended Events en este inicio de sesión.

Referencia de configuración

Variable

Default

Propósito

CW_SITE

Host de ConnectWise (en la nube o local; se aceptan URL completas)

CW_COMPANY_ID

Identificador de la empresa de inicio de sesión

CW_CLIENT_ID

clientId de integración

CW_PUBLIC_KEY / CW_PRIVATE_KEY

Claves de miembro de la API: necesarias para stdio; sin usar en HTTP (BYOK)

CW_MEMBER_IDENTIFIER

Miembro al que pertenecen las claves stdio (my-tickets/my-time)

TRANSPORT / PORT

stdio / 3000

Selección de transporte

CW_TOOLSETS

all

Conjuntos de herramientas habilitados (claves/preajustes); HTTP los sobrescribe por sesión mediante x-cw-toolsets

CW_DB_HOST

Host de SQL Server de ConnectWise, o host\INSTANCE: habilita el conjunto de herramientas sql

CW_DB_NAME / CW_DB_USER / CW_DB_PASSWORD

Base de datos y su inicio de sesión dedicado de solo lectura (los cuatro son necesarios a la vez)

CW_DB_PORT

1433

Puerto TCP; no es válido junto con una instancia con nombre

CW_DB_ENCRYPT / CW_DB_TRUST_SERVER_CERT

true / true

TLS y aceptación del certificado autofirmado habitual en instalaciones locales

CW_DB_READ_UNCOMMITTED

true

Lectura en READ UNCOMMITTED para que los informes nunca bloqueen a los escritores de producción

CW_DB_QUERY_TIMEOUT_MS / CW_DB_MAX_ROWS

30000 / 200

Límite de tiempo y de filas por consulta

CW_DB_QUERY_LIBRARY

Ruta al archivo de consultas guardadas editable; sin definir ⇒ solo consultas integradas, sin herramienta de guardado

Notas y límites

  • Las búsquedas de tickets usan por defecto los tickets abiertos; los nombres de estado/tablero son exactos, los filtros de texto son subcadenas.

  • Las marcas de tiempo deben tener segundos completos: el servidor normaliza (ConnectWise rechaza los segundos fraccionarios).

  • Las entradas de tiempo requieren un período de informe de tiempo abierto en ConnectWise para la fecha de la entrada; si no existe, se transmite el mensaje de la API.

  • /system/myAccount falta en algunas versiones locales: proporciona el identificador de miembro explícitamente (CW_MEMBER_IDENTIFIER o x-cw-member-id) para "my tickets"/"my time".

  • Las notas de discusión son visibles para el cliente; las notas internas no lo son: la herramienta lo hace explícito.

  • cw_db_query se detiene en max_rows (200 por defecto) o en un presupuesto de ~20 000 caracteres y cancela la consulta en el servidor; la respuesta indica qué límite se alcanzó. El plazo por consulta es de 30 s por defecto, 120 s como máximo.

  • La conexión a la base de datos lee en READ UNCOMMITTED para que un escaneo de informes no pueda bloquear a un técnico que guarda un ticket. El coste son lecturas sucias: los recuentos son aproximados bajo escrituras concurrentes. Establece CW_DB_READ_UNCOMMITTED=false si un informe debe ser exacto.

  • SELECT * falla en cualquier tabla con una columna con DENY: nombra las columnas que necesites.

  • Las instancias de ConnectWise alojadas en la nube no tienen acceso a la base de datos; el conjunto de herramientas sql es solo local.

Desarrollo

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

Licencia

MIT

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
4dRelease cycle
11Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    MCP server for SolarWinds Service Desk (SWSD/Samanage) enabling reading and modifying tickets, comments, knowledge-base articles, and more via each user's own API token.
    37
    93
    3
    MIT

View all related MCP servers

Related MCP Connectors

  • MCP Server for agents to onboard, pay, and provision services autonomously with InFlow

  • A paid remote MCP for ClawManager, built to return verdicts, receipts, usage logs, and audit-ready J

  • MCP server for Appcircle mobile CI/CD platform.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mspstack/mcp-connectwise-psa'

If you have feedback or need assistance with the MCP directory API, please join our Discord server