halo-psa-mcp/CLAUDE.md
Piers Macrae Cockram 57c191ee1f feat: initial Halo PSA MCP server scaffold
TypeScript MCP server exposing 18 tools for querying a Halo PSA
instance via OAuth 2.0 Client Credentials:

- Tickets / actions (list, get, time entries)
- Clients / sites (list, get)
- Contracts (list, get — recurring service agreements)
- Invoices — both one-off (list, get) and recurring (list, get)
- Projects (list, get)
- Assets / configuration items (list, get)
- Agents, reports (list)
- revenue_breakdown — composite tool that cross-references contracts,
  recurring invoices, and one-off invoices to separate recurring
  (MRR) from non-recurring revenue per client

Build artefacts verified: npm install clean (0 vulnerabilities, 107
pkgs), npm run build produces dist/*.js with no TS errors, server
boots and announces 'Halo PSA MCP server running on stdio'.

Shipping with Dockerfile (multi-stage, alpine), .env.example,
README.md (user-facing), and CLAUDE.md (deployment briefing for
downstream Claude Code setup on customer machines).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:36:37 +10:00

2.4 KiB

Halo PSA MCP Server — Deployment Briefing

You are setting up the Halo PSA MCP server on this machine. This MCP server connects you (Claude Code) to the customer's live Halo PSA instance so you can query their tickets, clients, contracts, invoices, projects, assets, and revenue data via natural language.

What this project is

An MCP server built in TypeScript that authenticates against the Halo PSA REST API using OAuth 2.0 Client Credentials and exposes 18 tools for querying business data. The key differentiator is the revenue_breakdown tool which cross-references contracts, recurring invoices, and one-off invoices to distinguish recurring from non-recurring revenue per customer.

Autonomous Setup Instructions

Follow these steps in order. Do NOT skip any step.

Step 1 — Clone and build

cd ~ git clone https://git.mineracks.com/mineracks/halo-psa-mcp.git cd halo-psa-mcp npm install npm run build

Verify the build succeeded (no TypeScript errors, dist/index.js exists).

Step 2 — Collect credentials

Ask the user for these three values. Do NOT proceed without them:

  1. HALO_INSTANCE_URL — Their Halo PSA URL (e.g. https://companyname.halopsa.com)
  2. HALO_CLIENT_ID — OAuth Client ID (GUID format)
  3. HALO_CLIENT_SECRET — OAuth Client Secret

Optional: 4. HALO_TENANT — Only needed for multi-tenant Halo instances

If the user hasn't created API credentials yet, walk them through it:

  • Log into Halo PSA as admin
  • Configuration > Integrations > Halo PSA API > View Applications > New
  • Auth method: Client ID and Secret (Services)
  • Grant read permissions: read:tickets, read:customers, read:contracts, read:invoices, read:projects, read:assets, read:crm
  • Save, copy the Client ID and Secret

Step 3 — Create the .env file

Write a .env file in the project root with the credentials from Step 2.

Step 4 — Create a shell wrapper and register the MCP

Create ~/halo-psa-mcp/start.sh that sources the .env and execs node dist/index.js. chmod +x it, then run: claude mcp add halo-psa -- ~/halo-psa-mcp/start.sh

Step 5 — Verify

Restart Claude Code, then test with list_clients (page_size: 5) and list_tickets (page_size: 5, open_only: true).

Key Concept: Recurring vs Non-Recurring

  • RECURRING = Contracts + Recurring Invoices (managed services, monthly/quarterly/annual billing)
  • NON-RECURRING = Standard Invoices + Project charges (break-fix, ad-hoc, project work)

The revenue_breakdown tool automates this analysis.