mcp-connectwise-psa
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 configurandoCW_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(oCW_TOOLSETS); ajustes predefinidostech/dispatch/invoicing/all. El valor predeterminado esall— 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 capacidadClaves 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.jsConfiguració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 3000O 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 |
| Punto de conexión MCP streamable-http |
| 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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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: dispatchox-cw-toolsets: tech,finance.stdio — la variable de entorno
CW_TOOLSETSo 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.jsEso 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-exportLas 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.sqlCrea 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.sqlCada 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_dirtreepara captura NTLM.OPENROWSET/BULK INSERTleen 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 |
| — | Host de ConnectWise (en la nube o local; se aceptan URL completas) |
| — | Identificador de la empresa de inicio de sesión |
| — | clientId de integración |
| — | Claves de miembro de la API: necesarias para stdio; sin usar en HTTP (BYOK) |
| — | Miembro al que pertenecen las claves stdio (my-tickets/my-time) |
|
| Selección de transporte |
|
| Conjuntos de herramientas habilitados (claves/preajustes); HTTP los sobrescribe por sesión mediante |
| — | Host de SQL Server de ConnectWise, o |
| — | Base de datos y su inicio de sesión dedicado de solo lectura (los cuatro son necesarios a la vez) |
|
| Puerto TCP; no es válido junto con una instancia con nombre |
|
| TLS y aceptación del certificado autofirmado habitual en instalaciones locales |
|
| Lectura en READ UNCOMMITTED para que los informes nunca bloqueen a los escritores de producción |
|
| Límite de tiempo y de filas por consulta |
| — | 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/myAccountfalta en algunas versiones locales: proporciona el identificador de miembro explícitamente (CW_MEMBER_IDENTIFIERox-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_queryse detiene enmax_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=falsesi 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
sqles 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
This server cannot be installed
Maintenance
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
- AlicenseNot gradedqualityBmaintenanceAn MCP server for ConnectWise Manage PSA, enabling management of tickets, projects, contacts, billing, and service operations through ConnectWise Manage's API.19Apache 2.0
- AlicenseAqualityAmaintenanceAn MCP server for SuperOps PSA/RMM, enabling MSPs to manage tickets, assets, clients, and field technician operations through SuperOps's API.213Apache 2.0
- AlicenseNot gradedqualityAmaintenanceMCP server for Kaseya BMS PSA — tickets, accounts, time entries, and contracts. Enables AI assistants to manage service desk operations via the Kaseya BMS API.Apache 2.0
- AlicenseAqualityAmaintenanceMCP 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.37933MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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