WYRE-AI/msp-claude-plugins/msp-claude-plugins/connectwise/automate/skills/clients/SKILL.md
ConnectWise Automate Clients
ConnectWise Automate client management: client CRUD, client identifiers, locations, client hierarchy, groups, extra data fields (EDFs), and client-level settings.
- Source repository stars
- 42
- Declared platforms
- 0
- Static risk flags
- 0
- Last source update
- 2026-08-28
- Source checked
- 2026-08-28
Decision brief
What it does: where it fits
ConnectWise Automate client management: client CRUD, client identifiers, locations, client hierarchy, groups, extra data fields (EDFs), and client-level settings.
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/connectwise/automate/skills/clients"Inspect the Agent Skill "ConnectWise Automate Clients" from https://github.com/WYRE-AI/msp-claude-plugins/blob/5005f73ba2f52cd299f58aa6bb79f4e70ae87103/msp-claude-plugins/connectwise/automate/skills/clients/SKILL.md at commit 5005f73ba2f52cd299f58aa6bb79f4e70ae87103. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Client Onboarding Workflow
Review the “Client Onboarding Workflow” section in the pinned source before continuing.
Review and apply the “Client Onboarding Workflow” source section. - 02
Anti-triggers
The PSA account record — the same customer exists in ConnectWise
The PSA account record — the same customer exists in ConnectWiseThe machines inside a client — clients and locations are containers;- The PSA account record — the same customer exists in ConnectWise PSA as a company, with a separate ID space; agreements, invoicing and ticket routing hang off that record, not this one. Use connectwise-psa-companies.… - 03
Key Concepts
Review the “Key Concepts” section in the pinned source before continuing.
Review and apply the “Key Concepts” source section. - 04
Client Hierarchy
Review the “Client Hierarchy” section in the pinned source before continuing.
Review and apply the “Client Hierarchy” source section. - 05
Client Identifiers
Review the “Client Identifiers” section in the pinned source before continuing.
Review and apply the “Client Identifiers” source section.
Permission review
Static risk signals and limitations
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 91/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 42 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- WYRE-AI/msp-claude-plugins
- Skill path
- msp-claude-plugins/connectwise/automate/skills/clients/SKILL.md
- Commit
- 5005f73ba2f52cd299f58aa6bb79f4e70ae87103
- License
- Apache-2.0
- Collected
- 2026-08-28
- Default branch
- main
View the original SKILL.md
ConnectWise Automate Client Management
Overview
Clients in ConnectWise Automate represent customer organizations. Each client can have multiple locations (physical sites), and computers belong to specific locations within clients. This skill covers client CRUD operations, location management, client-level settings, and group configurations.
Anti-triggers
- The PSA account record — the same customer exists in ConnectWise
PSA as a
company, with a separate ID space; agreements, invoicing and ticket routing hang off that record, not this one. Useconnectwise-psa-companies. - The machines inside a client — clients and locations are containers;
endpoint status, inventory and patching are
connectwise-automate-computers.
Key Concepts
Client Hierarchy
Client (Organization)
├── Location 1 (Physical Site)
│ ├── Computer A
│ └── Computer B
├── Location 2
│ └── Computer C
└── Client Settings
├── EDFs (Custom Fields)
├── Groups
└── Policies
Client Identifiers
| Identifier | Type | Description | Example |
|---|---|---|---|
ClientID | integer | Primary key, auto-incrementing | 100 |
Name | string | Client display name | Acme Corporation |
ExternalID | string | External system reference | CW-12345 |
City | string | Primary city | Chicago |
Location Identifiers
| Identifier | Type | Description | Example |
|---|---|---|---|
LocationID | integer | Primary key | 1 |
Name | string | Location name | Main Office |
ClientID | integer | Parent client | 100 |
Address | string | Street address | 123 Main St |
Field Reference
See references/fields.md for the complete Client, Location, and Group field reference (TypeScript interfaces).
API Patterns
See references/api.md for the complete endpoint catalog: client CRUD, location CRUD, client computers/groups, and EDF get/update — with full request/response JSON examples.
Workflows
Client Lookup by Name
async function findClientByName(client, name) {
const clients = await client.request(
`/Clients?condition=Name contains '${name}'`
);
if (clients.length === 0) {
return { found: false, suggestions: [] };
}
if (clients.length === 1) {
return { found: true, client: clients[0] };
}
return {
found: false,
ambiguous: true,
suggestions: clients.map(c => ({
name: c.Name,
id: c.ClientID,
city: c.City,
computerCount: c.ComputerCount
}))
};
}
Create Client with Default Location
async function createClientWithLocation(apiClient, clientData, locationName = 'Main Office') {
// Create the client
const newClient = await apiClient.request('/Clients', {
method: 'POST',
body: JSON.stringify(clientData)
});
// Create default location
const location = await apiClient.request(
`/Clients/${newClient.ClientID}/Locations`,
{
method: 'POST',
body: JSON.stringify({
Name: locationName,
Address1: clientData.Address1,
City: clientData.City,
State: clientData.State,
Zip: clientData.Zip
})
}
);
return {
client: newClient,
location: location
};
}
Bulk Client Report
async function generateClientReport(apiClient) {
const clients = await apiClient.request('/Clients?pageSize=500');
const report = [];
for (const client of clients) {
const locations = await apiClient.request(
`/Clients/${client.ClientID}/Locations`
);
report.push({
name: client.Name,
id: client.ClientID,
contact: client.ContactName,
email: client.ContactEmail,
computers: client.ComputerCount,
locations: locations.map(l => l.Name)
});
// Respect rate limits
await sleep(100);
}
return report;
}
Client Health Dashboard
async function getClientHealth(apiClient, clientId) {
const client = await apiClient.request(`/Clients/${clientId}`);
const computers = await apiClient.request(
`/Clients/${clientId}/Computers?pageSize=500`
);
const online = computers.filter(c => c.Status === 'Online').length;
const offline = computers.filter(c => c.Status === 'Offline').length;
return {
client: client.Name,
totalComputers: computers.length,
online,
offline,
healthPercentage: Math.round((online / computers.length) * 100),
offlineComputers: computers
.filter(c => c.Status === 'Offline')
.map(c => ({
name: c.Name,
lastContact: c.LastContact
}))
};
}
Update Client EDFs
async function updateClientEDFs(apiClient, clientId, edfUpdates) {
const results = [];
// Get existing EDFs
const edfs = await apiClient.request(
`/Clients/${clientId}/ExtraDataFields`
);
for (const [name, value] of Object.entries(edfUpdates)) {
const edf = edfs.find(e => e.Name === name);
if (edf) {
await apiClient.request(
`/Clients/${clientId}/ExtraDataFields/${edf.EDFID}`,
{
method: 'PUT',
body: JSON.stringify({ Value: value })
}
);
results.push({ name, status: 'updated', value });
} else {
results.push({ name, status: 'not_found' });
}
}
return results;
}
Error Handling
Common Client API Errors
| Error | Status | Cause | Resolution |
|---|---|---|---|
| Client not found | 404 | Invalid ClientID | Verify client exists |
| Duplicate name | 400 | Client name exists | Use unique name |
| Invalid EDF | 400 | EDF doesn't exist | Check EDF configuration |
| Permission denied | 403 | Insufficient rights | Check user permissions |
| Has computers | 400 | Client has assigned computers | Remove computers first |
Error Response Example
{
"error": {
"code": "BadRequest",
"message": "Cannot delete client with assigned computers"
}
}
See references/examples.md for a "Safe Client Deletion" helper that checks for assigned computers, optionally reassigns them, then deletes the client.
Best Practices
- Use ExternalID for integrations - Link to PSA/CRM systems
- Standardize naming conventions - Consistent client names
- Create locations for each site - Better organization
- Use EDFs for business data - Contract type, SLA level, etc.
- Maintain contact information - Keep primary contacts updated
- Group by client type - MSP vs internal, etc.
- Regular client audits - Review inactive clients
- Document client-specific settings - Notes in Comment field
- Use groups for policies - Apply settings at group level
- Plan location structure - Consider VPN, network segments
Client Onboarding Workflow
async function onboardNewClient(apiClient, clientInfo) {
const results = {
steps: [],
success: true
};
try {
// Step 1: Create client
const client = await apiClient.request('/Clients', {
method: 'POST',
body: JSON.stringify({
Name: clientInfo.name,
Address1: clientInfo.address,
City: clientInfo.city,
State: clientInfo.state,
Zip: clientInfo.zip,
Phone: clientInfo.phone,
ContactName: clientInfo.contactName,
ContactEmail: clientInfo.contactEmail,
ExternalID: clientInfo.externalId
})
});
results.steps.push({ step: 'Create Client', status: 'success', id: client.ClientID });
// Step 2: Create primary location
const location = await apiClient.request(
`/Clients/${client.ClientID}/Locations`,
{
method: 'POST',
body: JSON.stringify({
Name: 'Main Office',
Address1: clientInfo.address,
City: clientInfo.city,
State: clientInfo.state,
Zip: clientInfo.zip
})
}
);
results.steps.push({ step: 'Create Location', status: 'success', id: location.LocationID });
// Step 3: Set EDFs
if (clientInfo.edfs) {
await updateClientEDFs(apiClient, client.ClientID, clientInfo.edfs);
results.steps.push({ step: 'Set EDFs', status: 'success' });
}
// Step 4: Add to groups (if specified)
if (clientInfo.groups) {
for (const groupId of clientInfo.groups) {
await apiClient.request(`/Groups/${groupId}/Clients`, {
method: 'POST',
body: JSON.stringify({ ClientID: client.ClientID })
});
}
results.steps.push({ step: 'Add to Groups', status: 'success' });
}
results.clientId = client.ClientID;
results.locationId = location.LocationID;
} catch (error) {
results.success = false;
results.error = error.message;
}
return results;
}
Related Skills
- ConnectWise Automate Computers - Computers within clients
- ConnectWise Automate Scripts - Client-scoped scripts
- ConnectWise Automate Monitors - Client monitoring
- ConnectWise Automate Alerts - Client alerts
- ConnectWise Automate API Patterns - Authentication and pagination
Frequently asked questions
What to verify before installation and use
What does the ConnectWise Automate Clients source document cover?
ConnectWise Automate client management: client CRUD, client identifiers, locations, client hierarchy, groups, extra data fields (EDFs), and client-level settings.
How do I install ConnectWise Automate Clients?
The source record exposes this install command: npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/connectwise/automate/skills/clients". Inspect the command and pinned source before running it.
Alternatives
Compare before choosing
alirezarezvani/claude-skills
app-store-optimization
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
brucesongs/kali-claw
insecure-design
Insecure Design (OWASP A06:2025) focuses on security flaws in system architecture and design phases, rather than code implementation-level bugs.
NintendaDev/unikit-ai
unikit-docs
Generate and maintain the project's TECHNICAL documentation from its codebase — scans the project structure, tech stack, and module boundaries, then writes a lean README landing page plus detailed topic pages (architecture, modules, setup, build, APIs), only the docs that are relevant. Use whenever the user wants to create, update, or validate documentation of the CODE or the project itself, e.g. "generate documentation", "create docs", "write the README", "update the project docs", "document th
K-Dense-AI/scientific-agent-skills
dask
Distributed computing for larger-than-RAM pandas/NumPy workflows. Use when you need to scale existing pandas/NumPy code beyond memory or across clusters. Best for parallel file processing, distributed ML, integration with existing pandas code. For out-of-core analytics on single machine use vaex; for in-memory speed use polars.