Three fixes discovered during initial deployment against interakt.halopsa.com: - halo-client: include scope=all in the client_credentials token request. Without it Halo issues a token with no read scopes — every /api/* call fails authorization despite a successful exchange. Manifested as the original "permissions issue". - tools: add pageinate=true to every list_* call. Halo ignores page_size unless pagination is explicitly enabled, so requesting page_size=5 was returning the server-side default of 50. - tools: project list_clients to a summary shape (id, name, top-level, status, customer_relationship names). Full Halo client records are ~18 KB each; a 5-row page was 89 KB, exceeding tool-result budgets. Pass full=true for the original payload; get_client still returns full detail. Also: switch list_clients filter from inactive=false to the canonical includeinactive=false, and ship start.sh (the wrapper documented in CLAUDE.md Step 4) so downstream setups don't have to author it. Verified end-to-end against the live instance: GET /Client with pageinate=true&page_size=3 now returns exactly 3 records and record_count=122 (total active clients). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| src | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.md | ||
| Dockerfile | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| start.sh | ||
| tsconfig.json | ||
Halo PSA MCP Server
An MCP (Model Context Protocol) server that connects AI assistants to your Halo PSA instance, giving you natural-language access to tickets, clients, contracts, invoices, projects, assets, and revenue analytics.
Key Features
- Tickets & Actions — Search, filter, and inspect tickets; view time entries and SLA status
- Clients & Sites — Browse customers, their sites, and contacts
- Contracts — View active contracts representing recurring managed services
- Invoices (Recurring vs One-off) — Separately query recurring invoices (MRR) and ad-hoc invoices
- Revenue Breakdown — Composite tool that categorises recurring vs non-recurring revenue per client
- Projects — View project status, budgets, and associated work
- Assets — Browse configuration items and their associations
- Agents & Teams — See who's working on what
Prerequisites
- A Halo PSA instance with API access enabled
- An API application configured with Client ID and Secret (Services) auth method
- Docker (for container deployment) or Node.js 20+ (for local dev)
Setup: Creating API Credentials in Halo
- Log into your Halo PSA instance as an admin
- Navigate to Configuration > Integrations > Halo PSA API
- Click View Applications > New
- Set the authentication method to Client ID and Secret (Services)
- Under Permissions, grant read access to the scopes you need:
read:tickets— Tickets and actionsread:customers— Clients and sitesread:contracts— Contractsread:invoices— Invoices (recurring and one-off)read:projects— Projectsread:assets— Assetsread:crm— CRM / reporting data
- Save and note down the Client ID and Client Secret
- Note your instance URL (e.g.
https://yourcompany.halopsa.com)
Quick Start with Docker
Build the image
docker build -t halo-psa-mcp .
Run interactively (for testing)
docker run -it --rm
-e HALO_INSTANCE_URL=https://yourcompany.halopsa.com
-e HALO_CLIENT_ID=your-client-id
-e HALO_CLIENT_SECRET=your-client-secret
halo-psa-mcp
Connecting to Claude Desktop
Add this to your claude_desktop_config.json:
{ "mcpServers": { "halo-psa": { "command": "docker", "args": [ "run", "-i", "--rm", "-e", "HALO_INSTANCE_URL=https://yourcompany.halopsa.com", "-e", "HALO_CLIENT_ID=your-client-id", "-e", "HALO_CLIENT_SECRET=your-client-secret", "halo-psa-mcp" ] } } }
Connecting to Claude Code
claude mcp add halo-psa
-- docker run -i --rm
-e HALO_INSTANCE_URL=https://yourcompany.halopsa.com
-e HALO_CLIENT_ID=your-client-id
-e HALO_CLIENT_SECRET=your-client-secret
halo-psa-mcp
Available Tools
| Tool | Description |
|---|---|
list_tickets |
Search/filter tickets by client, agent, status, type, team, priority |
get_ticket |
Full ticket details with actions/notes |
list_clients |
Browse customers with search |
get_client |
Client details with sites |
list_contracts |
Active contracts (recurring services) |
get_contract |
Contract details with billing lines |
list_invoices |
One-off/ad-hoc invoices (non-recurring charges) |
get_invoice |
Invoice line item details |
list_recurring_invoices |
Recurring invoices (MRR/recurring revenue) |
get_recurring_invoice |
Recurring invoice schedule and lines |
list_projects |
Projects with status/budget |
get_project |
Full project details |
list_actions |
Time entries, notes, billable work |
list_assets |
Configuration items / assets |
get_asset |
Asset details and associations |
revenue_breakdown |
Recurring vs non-recurring revenue analysis per client |
list_agents |
Technicians and team members |
list_reports |
Available Halo reports |
Recurring vs Non-Recurring Revenue
The revenue_breakdown tool is specifically designed to answer the question: "What is recurring vs non-recurring for this customer?"
It combines:
- Recurring Invoices — scheduled auto-billing (monthly/quarterly/annual managed services)
- Contracts — recurring service agreements with billing terms
- Standard Invoices — one-off project work, ad-hoc charges, break-fix billing
License
MIT