mcp-connectwise-psa
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-connectwise-psashow my open tickets"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-connectwise-psa
An MCP (Model Context Protocol) server for ConnectWise PSA (Manage), focused on what technicians do all day:
Tickets — my tickets, search, full detail with notes, create, update status/priority/owner, add discussion/internal notes
Time entries — log time against tickets, review your own time
Companies & contacts — fast lookup (read-only)
Configurations — devices/assets with serials, IPs, OS, warranty (read-only)
Role-based access control — viewer / editor bearer tokens decide which tools a session sees
Per-tech API keys (BYOK) — techs supply their own ConnectWise member keys, so notes and time entries are attributed to the actual person in ConnectWise
Transports — stdio for local use, streamable HTTP for shared deployments; Docker image included
Quick start (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=JSmith \
node dist/index.jsClaude Desktop / Claude Code config:
{
"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": "JSmith"
}
}
}
}A clientId is required by the ConnectWise API — register a (free) integration at developer.connectwise.com. API member keys are created in ConnectWise under My Account → API Keys (per member) or System → Members → API Members (integration accounts).
Related MCP server: superops-mcp
HTTP deployment
CW_SITE=… CW_COMPANY_ID=… CW_CLIENT_ID=… \
MCP_TOKENS_VIEWER="alice:$(openssl rand -hex 32)" \
MCP_TOKENS_EDITOR="bot:$(openssl rand -hex 32)" \
node dist/index.js --transport http --port 3000Or with Docker: docker build -t mcp-connectwise-psa . && docker run -p 3000:3000 -e CW_SITE -e CW_COMPANY_ID -e CW_CLIENT_ID -e MCP_TOKENS_VIEWER -e MCP_TOKENS_EDITOR mcp-connectwise-psa
Route | Purpose |
| MCP streamable-http endpoint |
| Liveness probe |
Sessions are held in memory — run a single instance (or sticky sessions).
Access control
Role tokens
MCP_TOKENS_VIEWER="alice:tokA,bob:tokB" # read-only tools
MCP_TOKENS_EDITOR="helpdesk-bot:tokC" # + create/update tickets, notes, time entries
MCP_TOKENS_ADMIN="ops:tokD" # reserved for future destructive toolsClients send Authorization: Bearer <token>. Tools outside the role are not even registered for the session, a runtime guard re-checks every call, and session ids never carry privilege (each request re-authenticates; principal mismatch → 403). Labels appear in the audit log and allow per-person revocation. With no tokens configured the server runs in dev mode (full access + loud warning).
Bring your own keys (BYOK) — recommended for techs
Send your own ConnectWise member API keys on the initialize request:
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")The session then acts as you in ConnectWise: your security role limits what succeeds, and every note and time entry is attributed to you. CLIENT_CW_KEYS controls the policy: with-token (default — a bearer token is still required), open, or disabled. Keys are never logged; sessions are bound to a SHA-256 hash of the pair.
Token-only sessions use the server-wide CW_PUBLIC_KEY/CW_PRIVATE_KEY (use an integration API member with a conservative security role — its writes are attributed to that integration member).
Tools
Tool | Tier |
| read |
| read |
| read |
| read |
| write |
| write |
Viewer = read. Editor/Admin = read + write. No destructive (delete) tools in v1.
Configuration reference
Variable | Default | Purpose |
| — | ConnectWise host (cloud or on-prem; full URLs accepted) |
| — | Login company id |
| — | Integration clientId |
| — | Server-wide API member keys (optional when BYOK is enabled) |
| — | Member the server-wide keys belong to |
|
| Transport selection |
|
| BYOK policy: |
| — |
|
Notes & limits
Ticket searches default to open tickets; status/board names are exact, text filters are substrings.
Timestamps must have whole seconds — the server normalizes (ConnectWise rejects fractional seconds).
Time entries require an open time report period in ConnectWise for the entry date; the API's message is passed through when none exists.
/system/myAccountis missing on some on-prem versions — provide the member identifier explicitly (CW_MEMBER_IDENTIFIERorx-cw-member-id) for "my tickets"/"my time".Discussion notes are customer-visible; internal notes are not — the tool makes this explicit.
Development
npm install
npm run dev # stdio via tsx
npm run dev:http # http via tsx
npm test # vitest
npm run build # tsc → dist/License
This server cannot be installed
Maintenance
Latest Blog Posts
- 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/selic/mcp-connectwise-psa'
If you have feedback or need assistance with the MCP directory API, please join our Discord server