From superops
Manages SuperOps.ai PSA client accounts: create, update, search, and manage client fields, sites, contacts, custom fields, and lifecycle stages.
How this skill is triggered — by the user, by Claude, or both
Slash command
/superops:clientsWhen to use
When creating, updating, searching, and managing client accounts. Use when: superops client, client management, create client superops, update client, client site, client contact, account management, client custom fields, delete client, or client lifecycle.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Clients (also called Accounts) are the foundation of SuperOps.ai's PSA. Every ticket, asset, and service is associated with a client. This skill covers client CRUD operations, site management, contact handling, and custom field configuration.
Clients (also called Accounts) are the foundation of SuperOps.ai's PSA. Every ticket, asset, and service is associated with a client. This skill covers client CRUD operations, site management, contact handling, and custom field configuration.
| Stage | Description |
|---|---|
| Lead | Prospective client |
| Prospect | Qualified lead |
| Customer | Active paying client |
| Churned | Former client |
| Status | Description |
|---|---|
| Active | Current client |
| Inactive | Temporarily suspended |
| Archived | No longer serviced |
| Field | Type | Required | Description |
|---|---|---|---|
accountId | ID | System | Unique identifier |
name | String | Yes | Client/company name |
stage | Enum | No | Lead, Prospect, Customer, Churned |
status | Enum | No | Active, Inactive, Archived |
emailDomains | [String] | No | Associated email domains |
website | String | No | Company website |
phone | String | No | Primary phone number |
| Field | Type | Description |
|---|---|---|
industry | String | Industry type |
employeeCount | Int | Number of employees |
annualRevenue | Decimal | Annual revenue |
accountManager | Technician | Assigned account manager |
primaryContact | Contact | Main point of contact |
| Field | Type | Description |
|---|---|---|
address | String | Street address |
city | String | City |
state | String | State/province |
country | String | Country |
postalCode | String | ZIP/postal code |
mutation createClientV2($input: CreateClientInputV2!) {
createClientV2(input: $input) {
accountId
name
stage
status
emailDomains
createdTime
}
}
Variables:
{
"input": {
"name": "Acme Corporation",
"stage": "Customer",
"status": "Active",
"emailDomains": ["acme.com", "acmecorp.com"],
"website": "https://www.acme.com",
"phone": "+1-555-123-4567",
"industry": "Technology",
"employeeCount": 150,
"address": {
"street": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"country": "USA",
"postalCode": "94102"
},
"accountManager": {
"email": "[email protected]"
}
}
}
query getClientList($input: ListInfoInput!) {
getClientList(input: $input) {
clients {
accountId
name
stage
status
emailDomains
phone
website
industry
employeeCount
accountManager {
id
name
email
}
primaryContact {
id
name
email
}
createdTime
lastUpdatedTime
}
listInfo {
totalCount
hasNextPage
endCursor
}
}
}
Variables - Active Customers:
{
"input": {
"first": 50,
"filter": {
"stage": "Customer",
"status": "Active"
},
"orderBy": {
"field": "name",
"direction": "ASC"
}
}
}
Variables - Search by Name:
{
"input": {
"first": 20,
"filter": {
"name": {
"contains": "Acme"
}
}
}
}
query getClient($input: ClientIdentifierInput!) {
getClient(input: $input) {
accountId
name
stage
status
emailDomains
website
phone
industry
employeeCount
annualRevenue
address {
street
city
state
country
postalCode
}
accountManager {
id
name
email
phone
}
primaryContact {
id
name
email
phone
}
sites {
id
name
address
isDefault
}
customFields {
name
value
}
createdTime
lastUpdatedTime
}
}
Variables:
{
"input": {
"accountId": "client-uuid-here"
}
}
mutation updateClient($input: UpdateClientInput!) {
updateClient(input: $input) {
accountId
name
stage
status
lastUpdatedTime
}
}
Variables:
{
"input": {
"accountId": "client-uuid",
"stage": "Customer",
"status": "Active",
"accountManager": {
"id": "tech-uuid"
},
"customFields": [
{
"name": "Contract Type",
"value": "Managed Services"
},
{
"name": "Monthly Retainer",
"value": "5000"
}
]
}
}
Soft Delete (Recoverable):
mutation softDeleteClients($input: DeleteClientsInput!) {
softDeleteClients(input: $input)
}
Hard Delete (Permanent):
mutation hardDeleteClients($input: DeleteClientsInput!) {
hardDeleteClients(input: $input)
}
Restore Deleted Clients:
mutation restoreClients($input: RestoreClientsInput!) {
restoreClients(input: $input)
}
Variables:
{
"input": {
"accountIds": ["client-uuid-1", "client-uuid-2"]
}
}
mutation createSite($input: CreateSiteInput!) {
createSite(input: $input) {
id
name
address {
street
city
state
country
postalCode
}
isDefault
client {
accountId
name
}
}
}
Variables:
{
"input": {
"clientId": "client-uuid",
"name": "San Francisco Office",
"address": {
"street": "456 Market Street",
"city": "San Francisco",
"state": "CA",
"country": "USA",
"postalCode": "94103"
},
"isDefault": false,
"phone": "+1-555-234-5678",
"timezone": "America/Los_Angeles"
}
}
query getClientSites($input: ClientSitesInput!) {
getClientSites(input: $input) {
sites {
id
name
address {
street
city
state
country
postalCode
}
phone
timezone
isDefault
assetCount
contactCount
}
listInfo {
totalCount
}
}
}
mutation updateSite($input: UpdateSiteInput!) {
updateSite(input: $input) {
id
name
isDefault
lastUpdatedTime
}
}
mutation createRequester($input: CreateRequesterInput!) {
createRequester(input: $input) {
id
firstName
lastName
email
phone
title
client {
accountId
name
}
site {
id
name
}
}
}
Variables:
{
"input": {
"clientId": "client-uuid",
"firstName": "John",
"lastName": "Smith",
"email": "[email protected]",
"phone": "+1-555-345-6789",
"title": "IT Manager",
"siteId": "site-uuid",
"isPrimaryContact": true
}
}
query getClientRequesters($input: ClientRequestersInput!) {
getClientRequesters(input: $input) {
requesters {
id
firstName
lastName
email
phone
title
site {
id
name
}
isPrimaryContact
isVIP
}
listInfo {
totalCount
hasNextPage
}
}
}
mutation updateRequester($input: UpdateRequesterInput!) {
updateRequester(input: $input) {
id
firstName
lastName
email
phone
lastUpdatedTime
}
}
mutation onboardClient($client: CreateClientInputV2!, $site: CreateSiteInput!, $contact: CreateRequesterInput!) {
createClientV2(input: $client) {
accountId
name
}
}
Then create site and primary contact.
query searchClients($input: ListInfoInput!) {
getClientList(input: $input) {
clients {
accountId
name
emailDomains
status
}
}
}
Variables for fuzzy search:
{
"input": {
"filter": {
"or": [
{ "name": { "contains": "acme" } },
{ "emailDomains": { "contains": "acme.com" } }
]
},
"first": 10
}
}
query getClientHealth($clientId: ID!) {
getClient(input: { accountId: $clientId }) {
name
status
}
getClientAssets: getAssetList(input: {
filter: { client: { accountId: $clientId } }
}) {
listInfo { totalCount }
}
getClientTickets: getTicketList(input: {
filter: {
client: { accountId: $clientId },
status: ["Open", "In Progress"]
}
}) {
listInfo { totalCount }
}
getClientAlerts: getAlertList(input: {
filter: {
client: { accountId: $clientId },
status: "Active"
}
}) {
listInfo { totalCount }
}
}
| Error | Cause | Resolution |
|---|---|---|
| Client not found | Invalid account ID | Verify client exists |
| Duplicate name | Client name exists | Use unique name |
| Invalid email domain | Malformed domain | Check domain format |
| Permission denied | Insufficient access | Check user permissions |
| Rate limit exceeded | Over 800 req/min | Implement backoff |
// Validate client input
function validateClientInput(input) {
const errors = [];
if (!input.name || input.name.trim().length < 2) {
errors.push('Client name must be at least 2 characters');
}
if (input.emailDomains) {
const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}$/;
input.emailDomains.forEach(domain => {
if (!domainRegex.test(domain)) {
errors.push(`Invalid email domain: ${domain}`);
}
});
}
if (input.website && !input.website.startsWith('http')) {
errors.push('Website must be a valid URL');
}
return errors;
}
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin superopsManages HaloPSA client records including creation, updates, search, sites, contacts, and onboarding workflows. Useful for MSP account managers handling CRM in HaloPSA.
Manages ConnectWise Automate client organizations: CRUD operations, locations, settings, groups, extra data fields (EDFs), and hierarchy.
Manages Syncro MSP customer records - create, update, search, and manage contacts, sites, and locations. Essential for MSP client onboarding and operations.