From connectwise-psa
Searches, creates, and updates ConnectWise PSA product catalog items (SKUs), manages categories, subcategories, and manufacturers, and supports common MSP workflows.
How this skill is triggered — by the user, by Claude, or both
Slash command
/connectwise-psa:product-catalogWhen to use
When searching, creating, or updating ConnectWise PSA product catalog items (SKUs), categories, subcategories, or manufacturers. Use when: connectwise product, connectwise catalog, connectwise sku, product catalog connectwise, catalog item connectwise, cw manage product, add product connectwise, create sku, product category connectwise, manufacturer connectwise, procurement catalog, connectwise pricing, bundle product, or managed service sku.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
The ConnectWise Manage product catalog is the master list of everything an MSP sells — hardware SKUs, software licenses, managed service subscriptions, bundles, and service offerings. Catalog items are the building blocks that flow into quotes, opportunities, sales orders, agreement additions, and ticket charges. Getting the catalog right drives accurate quoting, consistent billing, and clean C...
The ConnectWise Manage product catalog is the master list of everything an MSP sells — hardware SKUs, software licenses, managed service subscriptions, bundles, and service offerings. Catalog items are the building blocks that flow into quotes, opportunities, sales orders, agreement additions, and ticket charges. Getting the catalog right drives accurate quoting, consistent billing, and clean COGS/margin reporting.
This skill covers the full catalog item schema, the supporting lookup entities (categories, subcategories, manufacturers, product types, unit of measure), and the workflows for the most common MSP scenarios.
Base: /procurement/catalog
Categories: /procurement/categories
Subcategories: /procurement/subCategories
Manufacturers: /procurement/manufacturers
Product types: /procurement/productTypes
Unit of measure: /procurement/unitOfMeasures
Product class: /procurement/productClasses
Available MCP tools (connectwise-manage-mcp):
| Tool | Purpose |
|---|---|
cw_search_catalog_items | Search catalog items with CW conditions syntax |
cw_get_catalog_item | Fetch one catalog item by ID |
cw_create_catalog_item | Create a new catalog item (common fields + extraFields passthrough) |
cw_update_catalog_item | JSON Patch update against an existing item |
cw_list_catalog_categories | List categories |
cw_list_catalog_subcategories | List subcategories (filter by category/id=N) |
cw_list_manufacturers | List manufacturers |
productClass is the single most important field because it drives downstream billing, inventory, and agreement behavior.
| Class | Use For | Behavior |
|---|---|---|
NonInventory | Software licenses, pass-through charges, most SaaS | No stock tracking, cost = last-purchased or fixed |
Inventory | Physical hardware you stock | Tracks on-hand, reorder points, cost layers |
Bundle | Parent SKU composed of child SKUs | Expands into components at quote time |
Service | Labor-based services, project service items | Maps to work roles, billable on tickets |
Agreement | Recurring managed-services line items | Drives MRR additions on agreements |
Rule of thumb for MSPs:
AgreementNonInventory (or Agreement if billing monthly)InventoryServiceBundle| Field | Type | Required | Description |
|---|---|---|---|
id | int | System | Auto-generated ID |
identifier | string(60) | Yes | Unique SKU / part number (your internal code) |
description | string(50) | Yes | Internal-facing short description |
customerDescription | string | No | Customer-facing description (shows on quotes/invoices) |
notes | string | No | Internal notes (not customer-visible) |
| Field | Type | Required | Description |
|---|---|---|---|
category | object | No | {id: categoryId} |
subcategory | object | Yes | {id: subcategoryId} — CW requires this |
type | object | Yes | {id: typeId} — product type |
productClass | enum | No | NonInventory / Inventory / Bundle / Service / Agreement |
serializedFlag | boolean | No | Track by serial number (hardware) |
serializedCostFlag | boolean | No | Per-unit cost tracking |
phaseProductFlag | boolean | No | Eligible as a project phase product |
| Field | Type | Required | Description |
|---|---|---|---|
cost | decimal | No | Your cost |
price | decimal | No | Sell price |
priceMethodFlag | string | No | Markup_Flat, Markup_Percent, Gross_Margin, Price_Flat |
costFlag | string | No | Billable, DoNotBill, NoCharge |
taxableFlag | boolean | No | Subject to sales tax |
| Field | Type | Required | Description |
|---|---|---|---|
manufacturer | object | No | {id: manufacturerId} |
manufacturerPartNumber | string | No | MPN (not your SKU — the mfr's part number) |
vendor | object | No | {id: vendorCompanyId} — a company flagged as a vendor |
vendorSku | string | No | Vendor's SKU for reordering |
| Field | Type | Required | Description |
|---|---|---|---|
unitOfMeasure | object | No | {id: uomId} — Each, Box, Hour, Month, License, etc. |
minStockLevel | int | No | Reorder threshold |
ianCode | string | No | Inventory account number (GL) |
upc | string | No | UPC barcode |
| Field | Type | Required | Description |
|---|---|---|---|
inactiveFlag | boolean | No | Retired from active sale |
specialOrderFlag | boolean | No | Not normally stocked |
buyingEveryFlag | boolean | No | Continuous purchase |
extraFieldsThe cw_create_catalog_item tool surfaces ~11 common fields directly as typed Zod params. For any field not in that list (e.g. manufacturerPartNumber, unitOfMeasure, upc, minStockLevel, serializedFlag), use extraFields:
{
"identifier": "DELL-OPTI-7010",
"description": "Dell OptiPlex 7010 Desktop",
"subcategoryId": 12,
"typeId": 3,
"cost": 849.00,
"price": 1199.00,
"categoryId": 5,
"manufacturerId": 17,
"productClass": "Inventory",
"taxableFlag": true,
"customerDescription": "Dell OptiPlex 7010 - i5/16GB/512GB SSD",
"extraFields": {
"manufacturerPartNumber": "OPT7010-i5-16-512",
"unitOfMeasure": { "id": 1 },
"vendor": { "id": 9823 },
"vendorSku": "DELL-7010-BSTOCK",
"minStockLevel": 2,
"serializedFlag": true,
"ianCode": "1400-INV-HW"
}
}
extraFields is merged into the POST body verbatim — anything the CW /procurement/catalog POST endpoint accepts will work.
{
"identifier": "FW-MERAKI-MX67",
"description": "Meraki MX67 Firewall",
"subcategoryId": 8,
"typeId": 2,
"productClass": "Inventory",
"categoryId": 3,
"manufacturerId": 24,
"cost": 495.00,
"price": 795.00,
"taxableFlag": true,
"extraFields": {
"manufacturerPartNumber": "MX67-HW",
"unitOfMeasure": { "id": 1 },
"serializedFlag": true,
"minStockLevel": 1
}
}
{
"identifier": "M365-BP",
"description": "M365 Business Premium",
"subcategoryId": 21,
"typeId": 5,
"productClass": "NonInventory",
"cost": 22.00,
"price": 28.50,
"taxableFlag": false,
"customerDescription": "Microsoft 365 Business Premium - per user/month",
"extraFields": {
"unitOfMeasure": { "id": 7 }
}
}
{
"identifier": "MSP-WKST-MGD",
"description": "Managed Workstation",
"subcategoryId": 30,
"typeId": 9,
"productClass": "Agreement",
"cost": 18.00,
"price": 75.00,
"customerDescription": "Fully Managed Workstation - RMM, EDR, patching, backup",
"extraFields": {
"unitOfMeasure": { "id": 7 },
"ianCode": "4100-REC-MSP"
}
}
{
"identifier": "SVC-PM-HR",
"description": "Project Management - hourly",
"subcategoryId": 45,
"typeId": 11,
"productClass": "Service",
"cost": 85.00,
"price": 195.00,
"extraFields": {
"unitOfMeasure": { "id": 3 },
"phaseProductFlag": true
}
}
Use cw_update_catalog_item with JSON Patch ops. CW Manage is strict about patch syntax — reference fields use /id paths.
Adjust price:
[{ "op": "replace", "path": "price", "value": 29.95 }]
Retire a SKU:
[{ "op": "replace", "path": "inactiveFlag", "value": true }]
Change manufacturer:
[{ "op": "replace", "path": "manufacturer/id", "value": 42 }]
Update customer description + cost atomically:
[
{ "op": "replace", "path": "customerDescription", "value": "M365 Business Premium (annual commit)" },
{ "op": "replace", "path": "cost", "value": 21.00 }
]
Catalog search uses standard CW conditions syntax.
All active hardware from one manufacturer:
conditions=manufacturer/id=17 and inactiveFlag=false and productClass="Inventory"
SKUs with a specific prefix:
conditions=identifier like 'M365-%'
Items missing a manufacturer (data hygiene):
conditions=manufacturer=null and inactiveFlag=false
Price-list export — active NonInventory:
conditions=productClass="NonInventory" and inactiveFlag=false
orderBy=identifier asc
Recently updated:
conditions=_info/lastUpdated>=[2026-01-01T00:00:00Z]
VENDOR-PRODUCT-VARIANT) and stick to it. Catalog bloat from inconsistent SKUs is the #1 reason CW quote selection gets painful.productClass — default CW behavior when it's missing is rarely what MSPs want. Bundles and agreement items especially must be classified correctly or they won't expand / won't roll up MRR.subcategory and type are required — look them up first with cw_list_catalog_subcategories and cache the IDs. Don't hardcode.description from customerDescription — internal SKU naming (short, searchable) vs customer-facing (descriptive, marketing-friendly).inactiveFlag=true instead of deleting. Historical quotes, tickets, and invoices reference the item by ID.ianCode) on agreement items — this is what flows to accounting. Missing ianCode on Agreement class items is a common source of bad financial reports.cost current — margin reporting uses the catalog cost at quote time unless the quote has its own override. Stale cost = lying margin.| Symptom | Cause | Fix |
|---|---|---|
SubCategory is required | Missing subcategory.id | Include subcategoryId on create |
Type is required | Missing type.id | Include typeId on create |
Duplicate identifier | SKU already exists | Search first; or use cw_update_catalog_item |
| Bundle won't expand on quote | Child SKUs missing or productClass wrong on parent | Confirm parent is productClass: "Bundle" and children exist |
| Agreement addition doesn't bill | productClass is NonInventory instead of Agreement | Patch productClass to Agreement |
| Price not applying on quote | priceMethodFlag overrides fixed price | Set priceMethodFlag: "Price_Flat" if you want the catalog price to stick |
| Serial prompt won't appear | serializedFlag=false | Patch to true |
| Cost shows $0 on reports | cost never set, relying on last-PO | Set an explicit cost value |
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin connectwise-psaSearches Autotask products, checks pricing, manages inventory, and navigates product/service/bundle relationships for MSP quoting and procurement.
Searches and browse the SalesBuildr product catalog for pricing and category information when building quotes.
Creates, updates, and manages ConnectWise PSA projects including phases, templates, resource allocation, and project tickets. Useful for MSPs automating project-based service delivery.