MSIO
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MSIO Look at jobs completed in the last 4 months and tell me which zip codes have the most activity."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 checkThen 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 toolsget_pricing_referenceARead-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_customerADestructiveIdempotent
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_companyARead-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_customerARead-onlyIdempotent
Get a single customer by ID (cus_ prefix).
Inputs: customer_id (required). Returns: data, error, success, metadata
hcp_get_estimateARead-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_jobARead-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_addressesARead-onlyIdempotent
List service addresses for a customer (cus_ prefix).
Inputs: customer_id (required). Returns: data, error, success, metadata
hcp_list_customersARead-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_employeesARead-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_itemsARead-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_estimatesARead-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_eventsARead-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_invoicesARead-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_invoicesARead-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_itemsARead-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_jobsARead-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_leadsARead-onlyIdempotent
List leads. Auto-paginates unless explicit page is set.
Inputs: page, page_size. Returns: data, error, success, metadata
hcp_list_lead_sourcesARead-onlyIdempotent
List lead sources. Auto-paginates unless explicit page is set.
Inputs: page, page_size. Returns: data, error, success, metadata
hcp_list_material_categoriesARead-onlyIdempotent
List material categories from HCP price book. Optionally filter by parent category UUID.
Inputs: parent_uuid. Returns: data, error, success, metadata
hcp_list_tagsARead-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_jobADestructiveIdempotent
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_scheduleADestructiveIdempotent
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_agingARead-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_jobARead-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_intelARead-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_healthARead-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_estimateARead-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_forecastARead-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_performanceARead-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_jobsARead-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
Scored across 36 tools
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.
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.
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.
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
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
One MCP server for the services your AI needs: memory, files, Microsoft 365, kanban and more.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
FlicenseNot gradedqualityFmaintenanceMCP 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-- AlicenseAqualityDmaintenanceMCP server for Housecall Pro, providing 5 tools for AI agents to register customers, schedule jobs, create estimates, log leads, and generate invoices (env-gated).5MIT
- FlicenseNot gradedqualityCmaintenanceAn 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.-
- AlicenseAqualityDmaintenanceMCP server for Kickserv field service management that enables AI agents to read and manage customers, jobs, and invoices through natural language.7MIT