connectwise-manage-mcp
MCP server for ConnectWise Manage (PSA) — tickets, companies, contacts, projects, and time entry tools for AI assistants
Install
docker run -i --rm ghcr.io/wyre-technology/connectwise-manage-mcp:v1.8.6CW_MANAGE_COMPANY_IDrequired — ConnectWise company identifier (the short name used to log in)CW_MANAGE_PUBLIC_KEYrequired · secret — ConnectWise API member public key (Members > API Members)CW_MANAGE_PRIVATE_KEYrequired · secret — ConnectWise API member private keyCW_MANAGE_CLIENT_IDrequired · secret — Client ID from the ConnectWise Developer Portal (developer.connectwise.com)CW_MANAGE_URLoptional — ConnectWise API base URL — region-specific (api-na/eu/au.myconnectwise.net) or self-hostedMCP_TRANSPORToptional — Transport mode for the server. Set to 'stdio' for local CLI use; the image defaults to 'http' for gateway hosting.AUTH_MODEoptional — Credential source: 'env' reads vars locally, 'gateway' expects header injection from the WYRE MCP Gateway.LOG_LEVELoptional — Log verbosity: debug, info, warn, error
ConnectWise Manage MCP Server
Let your AI assistant work directly with ConnectWise Manage. Search tickets, log time, look up companies and contacts, manage projects — through natural conversation instead of clicking through the CWM interface.
This is a Model Context Protocol (MCP) server that gives Claude (or any MCP-compatible AI) 53 tools covering the daily operations ConnectWise Manage shops depend on. Works with both cloud-hosted and self-hosted CWM instances — just point it at your server.
Part of the MSP Claude Plugins ecosystem — a growing suite of AI integrations for the MSP stack including Autotask, Datto RMM, IT Glue, HaloPSA, NinjaOne, Huntress, and more. Built by MSPs, for MSPs.
One-Click Deployment
Note on registry auth: This server depends only on public npm packages, so the Cloudflare and DigitalOcean cloud builders install its dependencies anonymously — no token is required for one-click deploy. (If a future release adds a private
@wyre-ai/*dependency, you would supply a GitHub PAT withread:packagesas a build variable —NODE_AUTH_TOKENfor Cloudflare Workers, a build-timeGITHUB_TOKENsecret for DigitalOcean.)Installing the published package: The released package is published to the GitHub Packages npm registry, which requires authentication on every install (even for public packages). To install it, authenticate npm to
npm.pkg.github.comwith a GitHub PAT that hasread:packages:export NODE_AUTH_TOKEN=$(gh auth token) npm install @wyre-ai/connectwise-manage-mcp
For deploying to Azure Container Apps with Entra ID OAuth 2.1, see AZURE_ACA_DEPLOYMENT.md.
Configuration
Environment Variables
| Variable | Required | Description |
|---|---|---|
CW_MANAGE_COMPANY_ID |
Yes | Your ConnectWise company identifier |
CW_MANAGE_PUBLIC_KEY |
Yes | API member public key |
CW_MANAGE_PRIVATE_KEY |
Yes | API member private key |
CW_MANAGE_CLIENT_ID |
Yes | Client ID from ConnectWise Developer Portal |
CW_MANAGE_URL |
No | API base URL (see below) |
CW_MANAGE_REJECT_UNAUTHORIZED |
No | Set to false for self-signed certs (default: true) |
MCP_TRANSPORT |
No | stdio (default) or http |
MCP_HTTP_PORT |
No | HTTP port (default: 8080) |
AUTH_MODE |
No | env (default) or gateway for header-based auth |
API Base URL (CW_MANAGE_URL)
| Instance Type | URL |
|---|---|
| Cloud (North America) | https://api-na.myconnectwise.net (default) |
| Cloud (Europe) | https://api-eu.myconnectwise.net |
| Cloud (Australia) | https://api-au.myconnectwise.net |
| Self-hosted | https://cwm.yourcompany.com |
For self-hosted instances, set CW_MANAGE_URL to your server's base URL. The server automatically appends /v4_6_release/apis/3.0 unless the URL already contains that path.
If your self-hosted instance uses a self-signed certificate, also set CW_MANAGE_REJECT_UNAUTHORIZED=false.
Getting Your API Keys
- Log in to your ConnectWise Manage instance
- Navigate to System > Members > API Members
- Create a new API member with appropriate permissions
- Generate API keys for the member
- Get your Client ID from the ConnectWise Developer Portal
Available Tools
Interactive Ticket Card (MCP Apps)
cw_get_ticket renders as an interactive card in MCP Apps hosts
(Claude Desktop/web) with an in-card "Add note" round-trip via
cw_add_ticket_note that always posts internal-only (internalAnalysisFlag)
notes; plain-JSON behavior is unchanged in other hosts. The card is neutral by
default and brandable via window.__BRAND__ injection or MCP_BRAND_* env
vars (MCP_BRAND_NAME, MCP_BRAND_LOGO_URL, MCP_BRAND_PRIMARY_COLOR,
MCP_BRAND_ACCENT_COLOR, MCP_BRAND_BG, MCP_BRAND_TEXT) — no rebuild
needed.
Tickets
cw_search_tickets— Search service tickets with conditionscw_get_ticket— Get a ticket by IDcw_create_ticket— Create a new service ticket. OptionalparentTicketId(the same fieldcw_get_ticketreturns) creates the ticket as a child of that parent.cw_update_ticket— Update a ticket (JSON Patch)cw_get_ticket_notes— Get all notes on a ticket (including child ticket notes)cw_add_ticket_note— Add a note to a ticket (discussion, internal, or resolution). OptionalemailContactFlag,emailResourceFlag,emailCcFlag, andemailCccontrol who is emailed. Nothing is emailed unless one of those flags is set (or you setprocessNotifications). Omitting them does not email the contact. The create response reportsinternalFlag/externalFlagfrom the note type that was stored, so an internal note is not also reported as external.
Companies
cw_search_companies— Search companiescw_get_company— Get a company by IDcw_create_company— Create a new companycw_update_company— Update a company (JSON Patch)
Contacts
cw_search_contacts— Search contacts. Filter contact type withtypeName,typeId, orchildConditions(for exampletypes/name = "Primary").types/types/nameinconditionsis invalid and returns 400ApiFindConditionbecause type is a child collection; the tool moves those clauses tochildConditions. Contacts havefirstNameandlastName, notname. String values use double quotes (firstName = "Ada"); single quotes are accepted and rewritten.cw_get_contact— Get a contact by IDcw_create_contact— Create a new contact
Projects
cw_search_projects— Search projectscw_get_project— Get a project by IDcw_create_project— Create a new projectcw_search_project_tickets— Search tickets under a projectcw_get_project_ticket— Get a specific project ticket by IDcw_get_project_ticket_notes— Get all notes on a project ticket (including child ticket notes)cw_add_project_ticket_note— Add a note to a project ticket (discussion, internal, or resolution)
Time Entries
cw_search_time_entries— Search time entriescw_get_time_entry— Get a time entry by IDcw_create_time_entry— Create a new time entrycw_update_time_entry— Correct a time entry (JSON Patch onPATCH /time/entries/{id}). Use this to fixactualHourswhen a metered agreement rounds to 0.25.cw_delete_time_entry— Delete a time entry (DELETE /time/entries/{id}). Manage rejects deletes of entries that are already billed.
Members
cw_search_members— Search members/technicianscw_get_member— Get a member by ID
Configuration Items
cw_search_configurations— Search configuration items (assets)cw_get_configuration— Get a configuration item by ID
Service Reference Data
cw_list_boards— List service boardscw_list_priorities— List ticket prioritiescw_list_statuses— List statuses for a board
Activities
cw_search_activities— Search activitiescw_get_activity— Get an activity by IDcw_create_activity— Create a new activity
Agreements
cw_search_agreements— Search agreementscw_get_agreement— Get an agreement by IDcw_get_agreement_additions— Get additions (line items) on an agreementcw_update_agreement_addition— Update an addition with JSON Patch (quantity, effectiveDate, cancelledDate, billCustomer, etc.); supports adryRunpreview that makes no writecw_create_agreement_addition— Create a new addition on an agreement
Invoices
cw_search_invoices— Search invoicescw_get_invoice— Get an invoice by ID
Opportunities
cw_search_opportunities— Search opportunitiescw_get_opportunity— Get an opportunity by IDcw_search_opportunity_forecasts— Search opportunity forecast linescw_search_opportunity_notes— Search notes on an opportunitycw_search_sales_stages— List sales pipeline stages
Catalog (Products)
cw_search_catalog_items— Search product catalog itemscw_get_catalog_item— Get a catalog item by IDcw_create_catalog_item— Create a new catalog itemcw_update_catalog_item— Update a catalog item (JSON Patch)cw_list_catalog_categories— List catalog categoriescw_list_catalog_subcategories— List catalog subcategoriescw_list_manufacturers— List manufacturers
Health
cw_test_connection— Test connection (hits/system/info)
Usage
With Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"connectwise-manage": {
"command": "npx",
"args": ["@wyre-ai/connectwise-manage-mcp"],
"env": {
"CW_MANAGE_COMPANY_ID": "your-company-id",
"CW_MANAGE_PUBLIC_KEY": "your-public-key",
"CW_MANAGE_PRIVATE_KEY": "your-private-key",
"CW_MANAGE_CLIENT_ID": "your-client-id"
}
}
}
}
For a self-hosted instance:
{
"mcpServers": {
"connectwise-manage": {
"command": "npx",
"args": ["@wyre-ai/connectwise-manage-mcp"],
"env": {
"CW_MANAGE_URL": "https://cwm.yourcompany.com",
"CW_MANAGE_COMPANY_ID": "your-company-id",
"CW_MANAGE_PUBLIC_KEY": "your-public-key",
"CW_MANAGE_PRIVATE_KEY": "your-private-key",
"CW_MANAGE_CLIENT_ID": "your-client-id",
"CW_MANAGE_REJECT_UNAUTHORIZED": "false"
}
}
}
}
With Docker
docker compose up -d
HTTP Transport (Gateway Mode)
Run with HTTP transport for multi-tenant gateway deployments:
MCP_TRANSPORT=http AUTH_MODE=gateway node dist/index.js
Pass credentials per-request via headers: X-CW-Company-Id, X-CW-Public-Key, X-CW-Private-Key, X-CW-Client-Id, and optionally X-CW-URL.
Development
# Install dependencies
npm install
# Build
npm run build
# Run in development
npm run dev
# Type check
npm run typecheck
# Run tests
npm test
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
Apache-2.0
Built by WYRE Technology — part of the MSP Claude Plugins ecosystem