Skip to main content
Glama
mspstack

mcp-connectwise-psa

by mspstack

mcp-connectwise-psa

ConnectWise PSA(Manage)용 MCP(Model Context Protocol) 서버 — 8개 툴셋에 걸친 선별된 도구로 기술자, 디스패처, 청구 담당자를 아우르며, 나머지 API를 위한 탈출구와 온프레미스 배포용 읽기 전용 SQL 툴셋까지 갖춰 AI 어시스턴트가 각 역할이 PSA를 다루는 방식 그대로 작업할 수 있게 합니다:

  • 티켓(Tickets) — 검색 / 내 티켓 / 메모 포함 전체 상세, 생성, 상태/우선순위/담당자 업데이트, 토론·내부 메모 추가, 보드·상태·우선순위 탐색 및 티켓별 시간·작업

  • 시간(Time) — 티켓에 시간 기록, 내 시간 조회, 작업 역할(work-role) 조회, 타임시트 목록 및 제출

  • 회사 및 연락처(Companies & contacts) — 빠른 조회, 연락처 상세(전화/이메일), 회사 사이트

  • 구성(Configurations) — 일련번호, IP, OS, 보증 정보가 포함된 장치/자산(읽기 전용)

  • 디스패치(Dispatch) (일정) — 일정 항목(목록/내 일정/생성/재조정/취소), 시간대, 근무 시간, 예약 여부를 포함한 구성원 정보

  • 인보이싱(Invoicing) (재무, 읽기 전용) — 인보이스, 계약, 청구 가능한 미청구 빌링 시간

  • SQL (온프레미스 전용) — REST로는 표현할 수 없는 교차 테이블 보고를 위해 cwwebapp_* Manage 데이터베이스에 직접 실행하는 읽기 전용 T-SQL. 검색 가능한 스키마 카탈로그와 어시스턴트가 확장할 수 있는 저장 쿼리 라이브러리 포함. CW_DB_* 설정으로 활성화되며, 설정된 경우 툴셋을 좁히지 않는 모든 세션에서 사용 가능

  • 툴셋 및 페르소나(Toolsets & personas) — x-cw-toolsets 헤더(또는 CW_TOOLSETS)로 세션이 필요한 기능만 활성화. 프리셋: tech / dispatch / invoicing / all. 기본값은 all — 더 작은 표면이 필요할 때 세션별로 좁힐 수 있습니다. 각 도구는 또한 자체 툴셋을 _meta.group으로 보고하므로, 집계자(MSPStack 게이트웨이)가 기능별로 도구를 그룹화하고 전환할 수 있습니다

  • 구성원별 API 키(BYOK) — 각 사용자가 자신의 ConnectWise 구성원 키를 제공합니다. ConnectWise가 해당 구성원의 보안 역할을 적용하며, 모든 쓰기 작업은 실제 사용자에게 귀속됩니다

  • 전송(Transports) — 로컬 사용용 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 구성원(통합 계정)에서 생성합니다.

Related MCP server: superops-mcp

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 /mcp

MCP streamable-http 엔드포인트

GET /health

활성 상태 프로브

세션은 메모리에 보관됩니다 — 단일 인스턴스(또는 고정 세션)로 실행하세요.

접근 제어 — 키 직접 제공(BYOK)

HTTP에서는 MCP 수준의 역할 시스템이 없습니다. 각 세션이 자체 ConnectWise 구성원 API 키를 제시하며, ConnectWise 자체가 접근 제어 역할을 합니다: 구성원의 보안 역할이 무엇이 성공하는지 결정하고, 모든 메모와 시간 항목은 해당 구성원에게 귀속됩니다.

initialize 요청(및 세션의 모든 후속 요청)에 키를 보내세요:

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 보안 역할에 따라 결정됩니다.

툴셋 키

도구

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(전체 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(디스패치)입니다. 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[] })로 구성됩니다. 오버레이 항목은 슬러그로 우선하며, 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. OPENROWSET/BULK INSERT는 EXECUTE 없이도 파일을 읽을 수 있으므로, Ad Hoc Distributed Queries도 반드시 꺼야 합니다.

운영 관점에서: 프로덕션 기본 복제본 대신 읽기 가능한 AG 보조 복제본이나 복원된 보고용 복사본을 사용하고, MCP 호스트에 SQL 포트를 방화벽으로 차단하며, 이 로그인에 대해 SQL Audit 또는 Extended Events 세션을 유지하십시오.

구성 참조

변수

기본값

용도

CW_SITE

—

ConnectWise 호스트(클라우드 또는 온프레미스; 전체 URL 허용)

CW_COMPANY_ID

—

로그인 회사 ID

CW_CLIENT_ID

—

통합 클라이언트 ID

CW_PUBLIC_KEY / CW_PRIVATE_KEY

—

API 멤버 키 — stdio에서 필수; HTTP에서는 미사용 (BYOK)

CW_MEMBER_IDENTIFIER

—

키가 속한 멤버 (my-tickets/my-time)

TRANSPORT / PORT

stdio / 3000

전송 선택

CW_TOOLSETS

all

활성화된 툴셋 (키/프리셋); HTTP에서는 x-cw-toolsets로 세션별 재정의

CW_DB_HOST

—

ConnectWise SQL Server 호스트, 또는 host\INSTANCE — sql 툴셋 활성화

CW_DB_NAME / CW_DB_USER / CW_DB_PASSWORD

—

데이터베이스 및 전용 읽기 전용 로그인 (네 개 모두 함께 필요)

CW_DB_PORT

1433

TCP 포트; 명명된 인스턴스와 함께 사용하면 유효하지 않음

CW_DB_ENCRYPT / CW_DB_TRUST_SERVER_CERT

true / true

TLS 및 일반적인 자체 서명 온프레미스 인증서 허용

CW_DB_READ_UNCOMMITTED

true

READ UNCOMMITTED로 읽어 보고가 프로덕션 쓰기를 차단하지 않도록 함

CW_DB_QUERY_TIMEOUT_MS / CW_DB_MAX_ROWS

30000 / 200

쿼리당 시간 제한 및 행 상한

CW_DB_QUERY_LIBRARY

—

저장된 쿼리 파일 경로; 설정하지 않으면 기본 제공 쿼리만 사용, 저장 도구 없음

참고 사항 및 제한 사항

  • 티켓 검색은 기본적으로 열린 티켓으로 제한됩니다; 상태/보드 이름은 정확히 일치해야 하고, 텍스트 필터는 부분 일치입니다.

  • 타임스탬프는 초 단위여야 합니다 — 서버가 정규화합니다 (ConnectWise는 소수 초를 거부합니다).

  • 시간 항목은 해당 날짜에 ConnectWise에 열린 시간 보고 기간이 있어야 합니다; 기간이 없으면 API의 메시지가 그대로 전달됩니다.

  • /system/myAccount는 일부 온프레미스 버전에 없습니다 — "my tickets"/"my time"에 대해 멤버 식별자를 명시적으로 제공하십시오 (CW_MEMBER_IDENTIFIER 또는 x-cw-member-id).

  • cw_db_query는 max_rows(기본값 200) 또는 약 20,000자 예산에서 중단되고 쿼리를 서버 측에서 취소합니다; 응답은 어떤 제한에 도달했는지 알려줍니다. 쿼리당 시간 제한은 기본 30초, 최대 120초입니다.

  • 데이터베이스 연결은 READ UNCOMMITTED로 읽으므로 보고 스캔이 기술자가 티켓을 저장하는 것을 차단하지 않습니다. 대가는 더티 리드입니다: 동시 쓰기가 있는 경우 개수는 근사치입니다. 보고서가 정확해야 하면 CW_DB_READ_UNCOMMITTED=false로 설정하십시오.

  • SELECT *는 DENY된 열이 있는 테이블에서 실패합니다 — 필요한 열 이름을 지정하십시오.

  • 클라우드 호스팅 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

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    An MCP server for SuperOps PSA/RMM, enabling MSPs to manage tickets, assets, clients, and field technician operations through SuperOps's API.
    22
    3
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP 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
  • 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
    557 npm
    4
    MIT