mcp-whmcs
by angelorc
README.md
# mcp-whmcs
MCP server for [WHMCS](https://www.whmcs.com/). It lets Claude (or any MCP client) manage clients, services,
orders, invoices, quotes, domains, tickets and system settings through the
[WHMCS External API](https://developers.whmcs.com/api/).
- **128 typed tools** for the common workflows, with validated parameters and WHMCS quirks handled for you:
PHP bracket notation, `base64(serialize())` for custom fields, parallel arrays for `AddOrder`, numbered
invoice lines, and booleans sent as `1`/`0`.
- **`whmcs_call_api`** runs any of the 162 WHMCS actions, and custom actions added by addon modules.
**`whmcs_list_actions`** lists them with their kind and documentation link.
- **Safety:** read-only mode, `confirm: true` required on destructive tools, sensitive actions turned off by
default, and MCP annotations (`readOnlyHint` / `destructiveHint`) on every tool.
- Responses are compact JSON. WHMCS list wrappers (`{"clients":{"client":[…]}}`) are collapsed into arrays, and
very large payloads are truncated with a hint to paginate.
## Install
### API credentials (recommended)
Create them in WHMCS under **Configuration → System Settings → Manage API Credentials**. Assign an API role
that grants only the actions you need.
```bash
claude mcp add whmcs \
-e WHMCS_API_URL=https://your-whmcs.com/includes/api.php \
-e WHMCS_IDENTIFIER=your_identifier \
-e WHMCS_SECRET=your_secret \
-- npx -y mcp-whmcs
```
### Admin username and password (legacy)
The password is MD5-hashed before it is sent, which is what WHMCS expects.
```bash
claude mcp add whmcs \
-e WHMCS_API_URL=https://your-whmcs.com/includes/api.php \
-e WHMCS_USERNAME=your_admin_user \
-e WHMCS_PASSWORD=your_admin_password \
-- npx -y mcp-whmcs
```
`bunx mcp-whmcs` works in place of `npx -y mcp-whmcs`. For a read-only assistant, add
`-e WHMCS_READ_ONLY=true`.
### Allow the API caller's IP
By default WHMCS accepts API calls only from allowed IPs. You can do either of the following:
- Add the IP of the machine that runs the server under **Configuration → System Settings → General Settings →
Security → API IP Access Restriction**.
- Or set `$api_access_key = '...';` in WHMCS `configuration.php` and pass the same value as `WHMCS_ACCESS_KEY`.
### Other MCP clients
```json
{
"mcpServers": {
"whmcs": {
"command": "npx",
"args": ["-y", "mcp-whmcs"],
"env": {
"WHMCS_API_URL": "https://your-whmcs.com/includes/api.php",
"WHMCS_IDENTIFIER": "your_identifier",
"WHMCS_SECRET": "your_secret"
}
}
}
}
```
## Configuration
| Variable | Description |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WHMCS_API_URL` | **Required.** `https://host/includes/api.php`, or the WHMCS base URL (`/includes/api.php` is appended). |
| `WHMCS_IDENTIFIER` / `WHMCS_SECRET` | API credentials (recommended). |
| `WHMCS_USERNAME` / `WHMCS_PASSWORD` | Legacy admin login, used when no API credentials are set. Set `WHMCS_PASSWORD_IS_MD5=true` if the password is already a hash. |
| `WHMCS_ACCESS_KEY` | API access key that bypasses the IP allow list. |
| `WHMCS_READ_ONLY` | `true` registers read tools only. `whmcs_call_api` then refuses non-read actions. |
| `WHMCS_ALLOW_SENSITIVE` | `true` enables secret-revealing or system-level actions: `DecryptPassword`, `GetClientPassword`, `CreateSsoToken`, `SetConfigurationValue`, OAuth credentials, and module activation/configuration. |
| `WHMCS_TOOLSETS` | Comma-separated subset of `clients,services,orders,billing,domains,support,system,projects`. Fewer tools mean a smaller prompt. |
| `WHMCS_TIMEOUT_MS` | Request timeout in milliseconds (default `30000`). |
| `WHMCS_MAX_RESPONSE_CHARS` | Truncate tool output after this many characters (default `100000`). |
## Tools
✎ = write, ⚠ = destructive (requires `confirm: true`), 🔒 = requires `WHMCS_ALLOW_SENSITIVE`. All names have the
`whmcs_` prefix.
| Toolset | Tools |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **clients** | get_clients, get_client_details, add_client ✎, update_client ✎, close_client ⚠, delete_client ⚠, get_client_groups, add_client_note ✎, get_emails, get_cancelled_packages, get_contacts, add_contact ✎, update_contact ✎, delete_contact ⚠, get_users, add_user ✎, update_user ✎, reset_user_password ✎, create_client_invite ✎, get_permissions_list, get_user_permissions, update_user_permissions ✎, delete_user_client ⚠ |
| **services** | get_client_products, get_client_addons, update_client_product ✎, update_client_addon ✎, module_create ✎, module_suspend ✎, module_unsuspend ✎, module_terminate ⚠, module_change_password ✎, module_change_package ✎, module_custom ✎, upgrade_product ✎, add_cancel_request ⚠ |
| **orders** | get_orders, get_order_statuses, add_order ✎, accept_order ✎, pending_order ✎, cancel_order ⚠, fraud_order ⚠, delete_order ⚠, order_fraud_check ✎, get_products, get_promotions, add_product ✎ |
| **billing** | get_invoices, get_invoice, create_invoice ✎, update_invoice ✎, add_invoice_payment ✎, capture_payment ✎, apply_credit ✎, gen_invoices ✎, add_billable_item ✎, get_transactions, add_transaction ✎, get_credits, add_credit ✎, get_pay_methods, delete_pay_method ⚠, get_quotes, create_quote ✎, update_quote ✎, send_quote ✎, accept_quote ✎, delete_quote ⚠ |
| **domains** | get_client_domains, domain_whois, get_tld_pricing, get_registrars, domain_get_whois_info, domain_get_nameservers, domain_update_nameservers ✎, domain_get_locking_status, domain_update_locking_status ✎, domain_request_epp ✎, domain_register ✎, domain_transfer ✎, domain_renew ✎, domain_toggle_id_protect ✎, domain_release ⚠, update_client_domain ✎ |
| **support** | get_tickets, get_ticket, get_ticket_notes, get_ticket_counts, open_ticket ✎, add_ticket_reply ✎, add_ticket_note ✎, update_ticket ✎, merge_ticket ⚠, delete_ticket ⚠, block_ticket_sender ⚠, get_support_departments, get_support_statuses, get_ticket_predefined_cats, get_ticket_predefined_replies, get_announcements, add_announcement ✎ |
| **system** | get_stats, whmcs_details, get_activity_log, log_activity ✎, get_automation_log, get_module_queue, get_admin_users, get_admin_details, get_staff_online, get_currencies, get_payment_methods, get_email_templates, send_email ✎, send_admin_email ✎, get_todo_items, update_todo_item ✎, add_banned_ip ✎, get_servers, get_health_status, get_affiliates, affiliate_activate ✎, create_sso_token ✎🔒 |
| **projects** | get_projects, get_project, create_project ✎, add_project_task ✎, add_project_message ✎ |
| _always_ | list_actions, call_api |
### Example prompts
- "Which clients have overdue invoices, and how much does each one owe?"
- "Open ticket #ABC-123456, summarize it, and draft a reply as admin `mario`."
- "Suspend service 812 for non-payment, then add a client note."
- "Is `example.it` available? If so, how much is a 2-year registration?"
## Development
Requires [Bun](https://bun.sh).
```bash
bun install
```
```bash
bun run check
```
```bash
bun run build
```
`check` runs oxfmt, oxlint (including the vendored
[anti-slop](https://github.com/dmmulroy/anti-slop) plugin in `tools/oxlint/anti-slop`) and `tsc`.
`bun test` runs the live tests in `test/live.test.ts` against the WHMCS instance configured in `.env`. The test
server always runs with `WHMCS_READ_ONLY=true`, so it can't create, change or delete records.
`bun run inspect` opens the server in the MCP Inspector.
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo recent community issues