Skip to main content
Glama
MSIO
by brystal00

MSIO — HCP Tools for AI Agents

Madam Secretary Intelligent Operations (MSIO) is an MCP server built to assist plumbing company operators who use Housecall Pro (HCP) daily. Running it as an MCP server means operators work through the AI chat interface they are already familiar with, leveraging the power of a cloud-based subscription AI they already pay for. The purpose of MSIO is to give AI agents useful tools to do useful work by enabling them to interact with HCP. It is in daily production use at a working plumbing company.

What it can do

MSIO gives your AI agent the ability to do the tasks that make management, evaluation, and projections easier. Most AI agents are innately good at pattern recognition, but they lack the tools to interact properly with HCP — and they lack context. MSIO provides the functions to search job history and parse information so the AI agent can read it and find the patterns. For instance, you could give it a job like:

"Look through the jobs completed over the last 4 months. Find out which zip codes have the most activity, what types of jobs we've done, and which tech has been the most efficient with their time."

The server exposes 36 tools: reading HCP data (jobs, customers, estimates, invoices, employees, tags, leads), spotting problems (stale estimates, uninvoiced jobs, overdue receivables), business intelligence (customer history and risk signals, tech performance, revenue forecasting, job classification), estimate generation, and a small set of validated write operations (tags, notes, line items, scheduling).

Related MCP server: housecallpro-mcp

Architecture

When the MCP server connects to the user's agent, it provides the agent with descriptions of its tools for selection when needed. A user request triggers the agent to select a tool based on reasoning. The agent forms the client request for the appropriate tool, structured as MCP over stdio. app.py routes the request to that tool's handler, which validates the inputs and then calls HCP's REST API through hcp_client.py. Structured JSON is returned from HCP, parsed into a consistent response envelope (success / data / error / metadata, with credentials redacted), and given back to the agent. The agent then reads the information and forms the response that is given to the user.

Reasoning happens at the two ends of that chain — tool selection and the final answer — and everything in the middle is deterministic Python. The server makes no LLM calls of its own: it either works or returns a structured error, and it cannot hallucinate.

Much of the deterministic layer exists because HCP's API behaves in ways the docs don't advertise. Every monetary amount arrives in cents. Estimates are write-once — no update, no delete. And POST /jobs returns a 201 success while silently dropping the job's description field; the server works around it by creating the job, then attaching the description as a note in a second call. Each gotcha like this is encoded once in the execution layer so no user — human or AI — ever hits it again.

Install and configuration

MSIO's intended use is with Claude Desktop, and the directions below reflect that — it's what the server was built and tested against. Because it's built on the open MCP standard, any MCP-compatible agent is viable, including private/self-hosted agents; installation and configuration guides for those will be added in future updates.

Requires Python 3.11+ and uv. An HCP API key is only available on plan tiers that include API access (e.g. MAX) — find it in your HCP settings, where you will have HCP generate a key.

git clone https://github.com/brystal00/msio-server
cd msio-server
uv venv .venv --python 3.13
uv pip install -e ".[dev]"
make check

Then register the server in your Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "madam-secretary": {
      "command": "/path/to/msio-server/.venv/bin/python",
      "args": ["/path/to/msio-server/server.py"],
      "env": { "HCP_API_KEY": "your_key_here" }
    }
  }
}

Restart Claude Desktop, approve the MCP connection, and Claude will have access to the tools. (A double-click install bundle for non-technical users is planned.)

Status and scope

This application is completely local stdio. This is deliberate: it keeps access to your HCP account and your data centralized to your computer — there is no hosted service, no third-party server, and nothing to sign up for. It is important to note that if you use a cloud-model AI agent, your data will flow through their cloud servers accordingly.

License

Licensed under the MIT License. Built on Anthropic's open Model Context Protocol standard.

Available Tools

36 tools
get_pricing_referenceA
Read-onlyIdempotent

Look up historical pricing from the south Alabama contractor line item corpus.

USE WHEN: Generating estimates, validating pricing, comparing job costs, "what do we charge for X?". DO NOT USE WHEN: Looking up a specific job's line items (use hcp_list_job_line_items). GOTCHAS: Prices are south Alabama contractor historical (south Alabama market). Adjust for other regions.

Inputs: service_category (required), kind, unit_type. Returns: data, error, success, metadata

hcp_add_job_line_itemA

Add a line item to a job. Price is in CENTS (e.g., 1500 = $15.00). Response prices converted from cents to dollars.

Inputs: name (required), price (required), job_id (required), quantity (required), +2 more. Returns: data, error, success, metadata

hcp_add_job_noteA

Add a note to a job. note_type: 'internal' (staff only) or 'customer' (visible to customer).

Inputs: note (required), job_id (required), note_type. Returns: data, error, success, metadata

hcp_apply_tag_to_customerA
DestructiveIdempotent

Add tags to a customer. Merges with existing tags via GET+PATCH to prevent data loss (HCP PATCH replaces the entire tags array). Tags are arbitrary strings, not tag_ IDs. Deduplicates before writing.

Inputs: tags (required), customer_id (required). Returns: data, error, success, metadata

hcp_apply_tag_to_jobA

Apply a tag to a job. Idempotent — re-applying an existing tag is safe. Returns the full list of tags on the job after applying. Tag removal is available via hcp_remove_tag_from_job.

Inputs: job_id (required), tag_id (required). Returns: data, error, success, metadata

hcp_create_jobA

Create a new job. Requires customer_id (cus_ prefix). Prices converted from cents to dollars. Note: HCP API silently drops 'description' on POST /jobs. If description is provided, it is added as an internal note on the job after creation.

Inputs: customer_id (required), tags, description, lead_source, +5 more. Returns: data, error, success, metadata

hcp_create_leadA

Create a new lead. customer_name is the only required field. HCP expects nested customer and address objects.

Inputs: customer_name (required), notes, source, priority, +9 more. Returns: data, error, success, metadata

hcp_create_tagA

Create a new tag. Returns 422 if tag name already exists. Tag names are case-sensitive.

Inputs: name (required). Returns: data, error, success, metadata

hcp_get_companyA
Read-onlyIdempotent

Get company profile for the authenticated API key. Returns company name, timezone, address, and settings. No parameters needed.

Inputs: no named parameters. Returns: data, error, success, metadata

hcp_get_customerA
Read-onlyIdempotent

Get a single customer by ID (cus_ prefix).

Inputs: customer_id (required). Returns: data, error, success, metadata

hcp_get_estimateA
Read-onlyIdempotent

Get a single estimate by ID (csr_ prefix). Prices converted from cents to dollars.

Inputs: estimate_id (required). Returns: data, error, success, metadata

hcp_get_jobA
Read-onlyIdempotent

Get a single job by ID. Prices converted from cents to dollars.

Inputs: job_id (required). Returns: data, error, success, metadata

hcp_list_customer_addressesA
Read-onlyIdempotent

List service addresses for a customer (cus_ prefix).

Inputs: customer_id (required). Returns: data, error, success, metadata

hcp_list_customersA
Read-onlyIdempotent

List customers with optional search. Auto-paginates unless explicit page is set.

Inputs: q, page, page_size. Returns: data, error, success, metadata

hcp_list_employeesA
Read-onlyIdempotent

List employees/technicians. Auto-paginates unless explicit page is set. Employee IDs use pro_ prefix.

Inputs: page, page_size. Returns: data, error, success, metadata

hcp_list_estimate_line_itemsA
Read-onlyIdempotent

List line items for a specific estimate option. Prices converted from cents to dollars.

Inputs: option_id (required), estimate_id (required). Returns: data, error, success, metadata

hcp_list_estimatesA
Read-onlyIdempotent

List estimates with optional filters. Auto-paginates unless explicit page is set. Prices converted from cents to dollars.

Inputs: page, page_size, customer_id, work_status, +2 more. Returns: data, error, success, metadata

hcp_list_eventsA
Read-onlyIdempotent

List events with incremental polling. Auto-paginates unless explicit page is set. Max page_size is 50 (HCP limit). Use last_polled_at (ISO 8601) for incremental consumption.

Inputs: page, page_size, last_polled_at. Returns: data, error, success, metadata

hcp_list_invoicesA
Read-onlyIdempotent

List invoices. No server-side filtering available. For job-specific invoices, use hcp_list_job_invoices(job_id) instead. Invoice items are inline (no nested call needed). Prices converted from cents to dollars.

Inputs: page, page_size. Returns: data, error, success, metadata

hcp_list_job_invoicesA
Read-onlyIdempotent

List all invoices for a specific job. Eliminates need to paginate full invoice list (29K+) and filter client-side. Prices converted from cents to dollars.

Inputs: job_id (required). Returns: data, error, success, metadata

hcp_list_job_line_itemsA
Read-onlyIdempotent

List line items for a job. Prices converted from cents to dollars. Note: HCP returns job line items in {object: 'list', data: [...]} format, normalized here to standard shape.

Inputs: job_id (required). Returns: data, error, success, metadata

hcp_list_jobsA
Read-onlyIdempotent

List jobs with optional filters. Auto-paginates unless explicit page is set. Prices converted from cents to dollars.

Inputs: page, page_size, customer_id, work_status, +4 more. Returns: data, error, success, metadata

hcp_list_leadsA
Read-onlyIdempotent

List leads. Auto-paginates unless explicit page is set.

Inputs: page, page_size. Returns: data, error, success, metadata

hcp_list_lead_sourcesA
Read-onlyIdempotent

List lead sources. Auto-paginates unless explicit page is set.

Inputs: page, page_size. Returns: data, error, success, metadata

hcp_list_material_categoriesA
Read-onlyIdempotent

List material categories from HCP price book. Optionally filter by parent category UUID.

Inputs: parent_uuid. Returns: data, error, success, metadata

hcp_list_tagsA
Read-onlyIdempotent

List all tags. Auto-paginates unless explicit page is set. Tag IDs use tag_ prefix.

Inputs: page, page_size. Returns: data, error, success, metadata

hcp_remove_tag_from_jobA
DestructiveIdempotent

Remove a tag from a job. Returns the remaining tags on the job after removal.

Inputs: job_id (required), tag_id (required). Returns: data, error, success, metadata

hcp_update_job_scheduleA
DestructiveIdempotent

Update a job's schedule. Overwrites existing schedule — previous values are lost. Times must be ISO 8601 format.

Inputs: job_id (required), scheduled_end (required), scheduled_start (required), employee_ids. Returns: data, error, success, metadata

msio_ar_agingA
Read-onlyIdempotent

Bucket overdue invoices by age for accounts receivable analysis.

USE WHEN: "How much money is owed?", AR review, collection priority, cash flow analysis. DO NOT USE WHEN: Looking for specific invoice (use hcp_list_invoices). GOTCHAS: Invoice endpoint has no server-side filters. For large accounts (29K+ invoices), results are capped at max_invoices. Check metadata.coverage_pct.

Inputs: customer_id, max_invoices, payment_terms_days, include_zero_amount, +1 more. Returns: data, error, success, metadata

msio_classify_jobA
Read-onlyIdempotent

Classify a job into one of 13 plumbing service categories using tags, line items, description, and notes. Returns category, confidence level, all detected signals, and a suggested tag. USE WHEN need to categorize a job, auto-tag jobs, understand job mix, classify for reporting. DO NOT USE WHEN looking for job details (use hcp_get_job) or listing jobs (use hcp_list_jobs). GOTCHAS: regex-based, not AI; ~38.8% of jobs fall into general catch-all.

Inputs: job_id (required). Returns: data, error, success, metadata

msio_customer_intelA
Read-onlyIdempotent

Comprehensive customer intelligence — 9 binary pattern flags for churn risk, payment health, value assessment, and service patterns. Returns all patterns that fire with human-readable explanations.

USE WHEN: "Tell me about this customer", customer history review, churn risk assessment, before sending an estimate, account health check. DO NOT USE WHEN: Looking up customer contact info only (use hcp_get_customer), listing all customers (use hcp_list_customers). GOTCHAS: Requires customer_id (cus_ prefix). Fetches all customer jobs + invoices — may take a few seconds for high-volume customers.

Inputs: customer_id. Returns: data, error, success, metadata

msio_estimate_healthA
Read-onlyIdempotent

Scan estimates and flag those needing follow-up. Returns stale sent estimates (no customer response after threshold) and approved-but-unscheduled estimates (customer said yes but no job created). USE WHEN contractor asks about pending estimates, revenue at risk, stale quotes, or what needs attention. DO NOT USE WHEN looking for specific estimate details (use hcp_get_estimate).

Inputs: status, customer_id, max_estimates, date_range_end, +2 more. Returns: data, error, success, metadata

msio_generate_estimateA
Read-onlyIdempotent

Generate a Good/Better/Best three-tier estimate skeleton (language only).

USE WHEN: Contractor needs estimate scaffolding — scope language, line item structure, tier framing for a Good/Better/Best presentation. DO NOT USE WHEN: Creating an estimate record in HCP (no API write here), looking up raw historical pricing. GOTCHAS: v0.1.0 is language-only — every tier returns unit_price=null. The connected AI must NOT invent dollar amounts. To get grounded pricing, aggregate the contractor's own past HCP jobs of the same category at runtime. Per-job-type directive content (when present) goes in directive_guidance.

Inputs: job_description (required), service_category (required), conditions. Returns: data, error, success, metadata

msio_revenue_forecastA
Read-onlyIdempotent

Historical revenue analysis with trend detection and simple projection.

USE WHEN: "How's business?", revenue trends, forecasting, seasonal analysis, "are we growing?", financial planning. DO NOT USE WHEN: Looking for specific job revenue (use hcp_get_job), invoice details (use hcp_list_invoices). GOTCHAS: Projection uses simple moving average -- not ML. Accuracy decreases with fewer months of data. Pipeline shows scheduled jobs only.

Inputs: employee_id, lookback_months, projection_months. Returns: data, error, success, metadata

msio_tech_performanceA
Read-onlyIdempotent

Per-technician performance metrics — revenue, job count, avg value, completion rate.

USE WHEN: "How are my techs doing?", performance review, revenue by tech, comparing technicians, identifying top performers. DO NOT USE WHEN: Looking up employee details (use hcp_list_employees), scheduling (use hcp_update_job_schedule). GOTCHAS: Default is last 30 days. Job type breakdown uses regex classification (v7 taxonomy, 25 categories with multi-label support). Uses first assigned tech per job — doesn't split multi-tech jobs.

Inputs: employee_id, date_range_end, date_range_start, include_job_types. Returns: data, error, success, metadata

msio_uninvoiced_jobsA
Read-onlyIdempotent

Detect completed jobs with no invoice — unbilled revenue.

USE WHEN: End-of-day check, "did we invoice everything?", revenue leakage. DO NOT USE WHEN: Looking for job details (use hcp_get_job) or invoice details (use hcp_list_invoices). GOTCHAS: Default date range is today CT. Uses scheduled date filter (not completion date). $0 jobs still flagged.

Inputs: date_range_end, date_range_start, minimum_job_value, assigned_employee_id. Returns: data, error, success, metadata

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 36 tools

    Disambiguation5/5

    Each tool targets a distinct resource or workflow, and direct overlaps (e.g., hcp_list_invoices vs hcp_list_job_invoices vs msio_ar_aging) are explicitly differentiated with USE WHEN/DO NOT USE WHEN guidance. The hcp_* resource actions and msio_* analytics tools are clearly separated in purpose.

    Naming Consistency3/5

    The hcp_* tools follow a predictable verb_noun pattern, while the msio_* analytics tools mostly use descriptive noun phrases rather than actions. The lone get_pricing_reference tool breaks the prefix convention, making the overall scheme mixed but still readable.

    Tool Count2/5

    36 tools is on the heavy side, especially when many are narrow read/list endpoints plus a separate analytics layer. While each tool is individually justified, the combined surface is larger than an agent can efficiently evaluate in one pass.

    Completeness3/5

    The server covers job creation, scheduling, notes, line items, tags, invoices, and a rich analytics layer, but several lifecycle gaps exist: no customer create/update, no estimate creation or update, no invoice get-by-id, and no update/delete operations for many core objects. These are notable but workable gaps given the read-heavy analytics focus.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      F
      maintenance
      MCP server that lets AI agents execute structured business processes by exposing process steps as tools with a sequenced event bus to prevent skipping steps.
      1
      -
    • A
      license
      A
      quality
      D
      maintenance
      MCP server for Housecall Pro, providing 5 tools for AI agents to register customers, schedule jobs, create estimates, log leads, and generate invoices (env-gated).
      5
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      An MCP server that enables AI agents to execute real-world actions through 10 specialized engines covering authenticated API calls, browser automation, visual QA, shell commands, file operations, job scraping, and parallel task execution.
      -
    • A
      license
      A
      quality
      D
      maintenance
      MCP server for Kickserv field service management that enables AI agents to read and manage customers, jobs, and invoices through natural language.
      7
      MIT