Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Open a change request in HaloPSA / HaloITSM through a discover-preview-confirm-submit workflow, with the confirmed change ticket type cached in Memory. Use when raising a Halo change, opening a CR in Halo, submitting a change ticket, or asking NetClaw to file a change in HaloPSA.
.claude/skills/automateyournetwork-halo-change-request/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-22 | ✗→✓ | ▲ Improved | 328% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 222% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 192% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 173% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 305% | 0% |
Open a change request in Halo through a strict discover -> preview -> confirm -> submit flow. Halo is HaloPSA / HaloITSM (the same product and the same REST API — HaloPSA is the MSP edition, HaloITSM the internal-IT edition). A "change request" in Halo is not a fixed object type: it is simply a ticket type ("Request Type") whose numeric id and custom fields are configured per organization — and an org often defines several change types (for example a customer-facing change and an internal change). This skill figures out which change is being raised, discovers the matching type, confirms it with a human, remembers it per category, learns its fields, and gates the single write behind explicit approval.
halo-mcp (NetClaw-authored, mcp-servers/halo-mcp/)python3 -u mcp-servers/halo-mcp/halo_mcp_server.py (stdio transport)HALO_CLIENT_ID / HALO_CLIENT_SECRET against HALO_BASE_URL (token from <base>/auth/token, resource API at <base>/api)fastmcp, httpx, python-dotenvhalo_create_change_request is the ONLY tool in the entire server that can mutate Halo, and it previews (no write) unless submit=true.This skill also uses the Memory MCP server (memory-mcp) to cache the confirmed change ticket type per Halo tenant.
| Tool | Parameters | What It Does | |------|------------|--------------| | halo_list_ticket_types | can_create_only?, customer?, showcounts? | Discover ticket types ("Request Types"). Use can_create_only=true to find the org's CHANGE type | | halo_get_ticket_type | ticket_type | Authoritative field schema for a type — required/optional/visible field definitions | | halo_list_fields | custom_only? | Master FieldInfo catalog (ids <-> names <-> dropdown option values) | | halo_get_field | field | One field definition by numeric id, with its lookup values | | halo_list_tickets | ticket_type?, customer?, asset_id?, status?, open_only?, search? | Find a sample existing change to copy field patterns from | | halo_get_ticket | ticket (numeric id) | Read one populated ticket as a concrete example | | halo_create_change_request | summary, details, ticket_type, customer?, site?, user?, asset?, custom_fields?, submit=false | THE ONLY WRITE. Previews the exact POST body unless submit=true | | halo_list_clients | search? | Resolve a Halo Client name to its id (the customer param) | | halo_list_sites | customer?, search? | Resolve a site within a client | | halo_list_users | customer?, site_id?, search? | Resolve the requesting contact/user | | memory_get_facts | entity, key? | Recall the tenant's change-type catalog (key="change_ticket_types") | | memory_record_fact | entity, key, value, metadata? | Merge a confirmed change type ({id, name, category}) into the catalog | | memory_record_decision | context, decision, rationale, ... | Log the human's ticket-type confirmation | | memory_invalidate | fact_id, reason | Retire a cached ticket type that no longer resolves |
customer param (a client name or numeric id), which the server resolves to a client_id. When someone says "the client," they mean this.halo_create_change_request with submit=false performs NO HTTP write; it returns the exact array body that would be POSTed to /api/Tickets. The real POST happens only on a second call with submit=true.The full change-request flow, step by step. Do not skip steps (a) or (c).
An organization usually has more than one change type — most commonly a customer change (raised against a client) and an internal change (internal IT / infrastructure), and sometimes standard / normal / emergency splits. So first decide which change this is, then resolve the matching type. Never assume there is only one.
customer/client is a customer change; a change with no client (internal infra, your own systems) is an internal change. If it is at all ambiguous, ASK the operator — e.g. "Is this a customer change or an internal change?" Use a short lowercase label for the category (customer, internal, emergency, ...).
memory_get_facts(entity="halo-<tenant>", key="change_ticket_types") The value is a list of {"id":..., "name":..., "category":...} — the change types already confirmed for this instance. <tenant> is from HALO_TENANT, or the host of HALO_BASE_URL (e.g. halo-acme for acme.halopsa.com).
with halo_get_ticket_type(ticket_type=<id>):
(below), and memory_invalidate the stale fact when you rewrite the catalog.
halo_list_ticket_types(can_create_only=true) This commonly returns several change-shaped types (e.g. "Change Request", "Internal Change", "Emergency Change"). Present the candidates and ask the operator which one is the <category> change — do NOT auto-pick when more than one looks like a change, and do NOT collapse them into a single "the change type".
others — do not overwrite the whole list with a single entry): memory_record_fact(entity="halo-<tenant>", key="change_ticket_types", value=<updated JSON list including {"id":<id>,"name":"<name>","category":"<category>"}>) memory_record_decision(context="Halo change type for <tenant> / <category>", decision="Use ticket type <id> (<name>) for <category> changes", rationale="Operator-confirmed from halo_list_ticket_types(can_create_only=true)")
Carry the selected <id> into (b) and (c). If a single request genuinely spans both a customer and an internal change, that is two change tickets — run the flow once per category, confirming each.
halo_get_ticket_type(ticket_type=<id>) Use halo_list_fields / halo_get_field to resolve any custom FieldInfo ids <-> names <-> option values you need.
halo_list_tickets(ticket_type=<id>) # find a recent one halo_get_ticket(ticket=<sample id>) # inspect its summary/details/customfields
metadata={...}) if it helps future runs — but only the metadata, never any ticket's contents.halo_list_clients, halo_list_sites, halo_list_users). halo_create_change_request( summary="...", details="...", ticket_type="<id>", customer="<client name or id>", site="...", user=<id>, asset="...", custom_fields={<id-or-name>: <value>, ...}, submit=false)
body to the operator verbatim. It is the exact /api/Tickets payload.submit=true to perform the one real write.Log the decision and the created ticket id to the GAIT audit trail (see gait-session-tracking): the confirmed ticket type, the previewed body, the approval, and the resulting Halo ticket id.
| Skill | Integration | |-------|-------------| | gait-session-tracking | Mandatory. Record the ticket-type decision, the preview, the human approval, and the created ticket id in the GAIT audit trail | | memory | Caches the per-category change-type catalog per tenant (entity="halo-<tenant>", key="change_ticket_types"); no credentials or ticket contents | | halo-ticket-context | Read the created change and its action history afterward for follow-up | | halo-asset-context | Review the affected asset and its open tickets before proposing the change | | servicenow-change-workflow | Sibling gated-change pattern (STOP-until-confirmed) if the org also runs ServiceNow |
| Variable | Required | Description | |----------|----------|-------------| | HALO_BASE_URL | Yes | Halo host, e.g. https://<tenant>.halopsa.com | | HALO_CLIENT_ID | Yes | OAuth2 client-credentials application id (Configuration > Integrations > Halo API) | | HALO_CLIENT_SECRET | Yes | OAuth2 client secret | | HALO_TENANT | Optional | Tenant identifier (also used to key Memory as halo-<tenant>) | | HALO_SCOPE | Optional | OAuth2 scope (default all) | | HALO_AUTH_URL | Optional | Override the auth-server URL for self-hosted layouts | | HALO_VERIFY_SSL | Optional | true/false TLS verification (default true) | | HALO_TIMEOUT | Optional | Per-request timeout in seconds (default 30) | | HALO_PAGE_SIZE / HALO_MAX_PAGES | Optional | Pagination tuning (defaults 50 / 20) | | HALO_RATE_LIMIT | Optional | Requests/minute cap (0 = disabled) |
halo_create_change_request. Every other Halo tool is read-only. Never attempt any other mutation through this server.submit=false), present the exact body, STOP, and only re-call with submit=true after the operator approves that preview (Constitution XIV).halo-<tenant>.halo_get_ticket_type, memory_invalidate it and re-discover.Other measured skills in the registry, with their headline benchmark lift.