mcp-connectwise-psa
mcp-connectwise-psa
ConnectWise PSA (Manage) 向けの MCP (Model Context Protocol) サーバーです。8つのツールセットにわたる精選されたツールを備え、テクニシャン、ディスパッチャー、請求業務をカバーします。さらに、API の残りのすべてのための逃げ道と、オンプレミス展開向けの読み取り専用 SQL ツールセットも用意されているため、AI アシスタントは各ロールのやり方で PSA を操作できます:
Tickets(チケット) — 検索 / 自分のチケット / メモ付きの完全詳細、作成、ステータス・優先度・担当者の更新、ディスカッション・内部メモの追加、さらにボード・ステータス・優先度の探索と、チケットごとの時間・タスク
Time(時間) — チケットに対する時間の記録、自分の時間の確認、作業ロールの参照、タイムシートの一覧と提出
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 がそのメンバーのセキュリティロールを強制し、すべての書き込みは実際の人物に帰属します
トランスポート — ローカル利用には 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.jsClaude 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 の My Account → API Keys(メンバーごと)または System → Members → API Members(統合アカウント)で作成します。
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
Route | 目的 |
| MCP streamable-http エンドポイント |
| 生存確認プローブ |
セッションはメモリ内に保持されます — 単一インスタンス(またはスティッキーセッション)で実行してください。
アクセス制御 — キー持ち込み (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 の My Account → API Keys でメンバー API キーを作成します。各テクニシャンは自分のものを使います。
ローカル stdio はシングルユーザーで、ヘッダーの代わりに環境変数の CW_PUBLIC_KEY/CW_PRIVATE_KEY を使用します。
ツールセット
ツールはツールセットにグループ化されており、セッションは必要な機能だけを表示できます。ディスパッチャーに請求ツールは不要であり、ツール面を小さく保つことでアシスタントの焦点が定まり(コンテキストも安価に保てます)。書き込みが実際に成功するかどうかは、依然としてメンバーの ConnectWise セキュリティロールによって決まります。
ツールセットキー | ツール |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
プリセットはペルソナごとにキーをまとめます: 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 クエリ1つで取得でき、お使いのバージョンに常に正しいため、キー列のみを保持します。
保存済みクエリライブラリは、コミットされたコアに加えて、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 に送信するため、ログインに許可されていることだけが発生し得ることです。2つのスクリプトがそれを設定し、証明します。
作成する — 先頭の4つの変数を編集し、sysadmin として実行します。@WhatIf はデフォルトで 1 なので、最初の実行はプランのみを表示します:
sqlcmd -S SQLHOST\CWPROD -d master -i scripts/create-readonly-login.sqlサーバーロールに属さないログインを作成し、1つのデータベースの 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 が 1 つでもあれば、ツールセットはまだ有効にしないでください。
事前に知っておくべき結果が 2 つあります:
SELECT *は失敗します。拒否された列があるテーブルでは、他の列を返す代わりに失敗します。それが意図です。ツールのエラーが、モデルに列名を指定するよう指示します。重要となる権限は EXECUTE です。 EXECUTE があれば、「読み取り専用 SQL」は SQL Server サービス アカウントとしてのリモート コード実行になります —
xp_cmdshell、sp_OACreate、sp_send_dbmail、NTLM キャプチャ用のxp_dirtree。OPENROWSET/BULK INSERTは EXECUTE がまったくなくてもファイルを読み取るため、Ad Hoc Distributed Queries もオフにしておく必要があります。
運用面: 本番プライマリより、読み取り可能な AG セカンダリまたは復元済みのレポート用コピーを優先し、SQL ポートへのアクセスが MCP ホストに限定されるようにファイアウォールを設定し、このログインを対象とした SQL Audit または Extended Events セッションを維持してください。
設定リファレンス
変数 | デフォルト | 目的 |
| — | ConnectWise ホスト(クラウドまたはオンプレミス。完全な URL も受け付けます) |
| — | ログインの会社 ID |
| — | インテグレーションの clientId |
| — | API メンバー キー — stdio では必須。HTTP では未使用(BYOK) |
| — | stdio キーが属するメンバー(my-tickets/my-time) |
|
| トランスポートの選択 |
|
| 有効なツールセット(キー/プリセット)。HTTP では |
| — | ConnectWise SQL Server ホスト、または |
| — | データベースと、その専用の読み取り専用ログイン(4 つすべてをまとめて指定必須) |
|
| TCP ポート。名前付きインスタンスとは併用不可 |
|
| TLS、および一般的なオンプレミスの自己署名証明書の受け入れ |
|
| READ UNCOMMITTED で読み取るため、レポートが本番の書き込みをブロックすることはありません |
|
| クエリごとの制限時間と行数の上限 |
| — | 書き込み可能な保存クエリ ファイルへのパス。未設定 ⇒ 組み込みクエリのみ、保存ツールなし |
注記と制限
チケット検索はデフォルトでオープン チケットを対象とします。ステータス名/ボード名は完全一致、テキスト フィルターは部分一致です。
タイムスタンプは整数秒である必要があります — サーバーが正規化します(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/ライセンス
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for GLPI: tickets, ITIL, assets, knowledge base. GLPI 10/11. Not affiliated with Teclib'.
Hosted MCP servers for MSP tools: ConnectWise, NinjaOne, Microsoft 365, SentinelOne, Pax8 and more.
MCP Server for agents to onboard, pay, and provision services autonomously with InFlow
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceAn MCP server for ConnectWise Manage PSA, enabling management of tickets, projects, contacts, billing, and service operations through ConnectWise Manage's API.27Apache 2.0
- AlicenseAqualityAmaintenanceAn MCP server for SuperOps PSA/RMM, enabling MSPs to manage tickets, assets, clients, and field technician operations through SuperOps's API.223Apache 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.37557 npm4MIT