# MCP server for AI assistants

> Calculators for HVAC, plumbing, and electrical business owners that an AI assistant can run for you: plan a labor rate, check a job’s profit, model missed-lead recovery, price a maintenance plan, and find the break-even for a new hire or truck. No Couplr account is needed, and the tools cannot access or change Couplr account data.

- Canonical URL: https://couplrfsm.com/developers/mcp
- Markdown: https://couplrfsm.com/developers/mcp.md
- API version: v1 (base URL https://couplrfsm.com/api/v1)
- OpenAPI specification: https://couplrfsm.com/developers/openapi.yaml
- All documentation pages: https://couplrfsm.com/llms.txt

## What this is

> **Flip:** Hi, I’m Flip, Couplr’s assistant. I’ll walk you through connecting these calculators to the AI assistant you already use. There’s no account to create and nothing to install.

Couplr Business Tools is a small MCP server with calculators for HVAC, plumbing, and electrical business owners. You give it your own numbers; it works out a labor rate, checks a job’s profit, models what booking more of your leads would be worth, prices a maintenance plan, or finds the break-even for a new hire or truck.

MCP (Model Context Protocol) is a standard way for an AI assistant, such as ChatGPT or Claude, to use outside tools. Once you connect this server, your assistant can run these calculators for you during a conversation and explain the results.

- **No Couplr account is needed.** There is no sign-in, API key, or signup.
- **It only calculates.** It cannot read or change anything in a Couplr account.
- **It uses only the numbers you provide.** It does not supply market prices, wage benchmarks, or promised results.

## What it can and cannot do

| Capability | Status |
| --- | --- |
| Plan an hourly labor rate (`plan_labor_rate`) | Available |
| Check a job’s profitability (`analyze_job_profit`) | Available |
| Model missed-lead recovery (`plan_lead_recovery`) | Available |
| Price a maintenance plan (`price_maintenance_plan`) | Not live yet: built in server version 1.1.0, which is not deployed to the endpoint |
| Find the break-even for a new hire or truck (`plan_hire_break_even`) | Not live yet: built in server version 1.1.0, which is not deployed to the endpoint |
| Interactive result card with editable inputs | Available in hosts that support MCP Apps; other hosts get the full result as text and data |
| Access to a Couplr account (customers, jobs, schedule, estimates, invoices) | Not available |
| Sending invoices or messages, taking payments, or changing any record | Not available |
| Sign-in, OAuth, or API keys | Not available and not needed |
| Currency conversion | Not available: the currency is a label for your inputs and results |

> **Flip:** I’d rather tell you now than have you find out halfway through: these tools can’t see or change anything in a Couplr account. They do the math with the numbers you give them, and that’s all.
>
> This server is separate from the Couplr app. Connecting it does not connect your Couplr account, and no MCP server for Couplr account data is available today.

## Before you connect

- An AI assistant or other MCP client that can connect to a remote MCP server by URL without authentication. See “Connect a client”.
- Your own business numbers. Each calculator lists exactly what it needs in the “Tool reference”. If you leave something out, the assistant should ask you for it rather than guess.

Do not enter customer names, addresses, contact details, passwords, or payment details. The calculators accept only the numeric fields, trade, and currency listed in the tool reference.

## Quickstart

1. Open your MCP client’s settings for adding a custom or remote MCP server. Steps for specific clients are in “Connect a client”.
2. Add this server URL: `https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp`. Choose no authentication.
3. Start a new conversation and make sure the Couplr tools are enabled for it.
4. Ask a question using your own numbers. For example: “My HVAC shop has 2 techs at $30/hour plus 25% burden, 40 paid hours a week for 50 weeks, 50% billable utilization, and $50,000 annual overhead. What hourly labor rate gives a 20% operating margin? Use USD.”
5. Review the answer and the assumptions listed with it. Change any input and ask again to compare scenarios.

> **Flip:** Use your real numbers, not round guesses. If you leave one out, your assistant should ask you for it. If it makes one up instead, tell it to stop and ask.

For that example the tool returns a break-even rate of 100 USD and a target rate of 125 USD per billable hour. These figures are an example computed from the sample inputs, not a recommendation.

## Connect a client

| Setting | Value |
| --- | --- |
| Server URL | `https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp` |
| Transport | Streamable HTTP. Requests are HTTP `POST`; responses are JSON. |
| Authentication | None. Do not send credentials. |
| Sessions | None. Each request stands alone. |
| Request size | Up to 16 KiB per request body. |

The server does not offer the older HTTP+SSE transport or a `GET` event stream: `GET` and `DELETE` on the URL return `405`. It is meant to be called by an MCP client, not from a web page: requests that carry a browser `Origin` header are refused with `403`.

The steps below follow each vendor’s own documentation as checked on 2026-11-14. Menu names can change; the linked vendor pages are the authority.

### ChatGPT

Use ChatGPT on the web. Whether you can add a custom MCP server depends on your plan and, in a workspace, on your administrator’s settings.

1. Go to ChatGPT Plugins at [chatgpt.com/plugins](https://chatgpt.com/plugins).
2. Select the plus button, then **Add custom MCP server**.
3. Enter a name, for example “Couplr Business Tools”, and optionally a description.
4. Under **Connection**, enter the **Server URL**: `https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp`.
5. For authentication, choose **No authentication**.
6. Review the risk warning and select **I understand and want to continue**.
7. Select **Create as a plugin**, then review the tools ChatGPT discovered.
8. Install the plugin you just created.
9. Start a new conversation, type `@` in the prompt box, select the plugin, and ask your question.

ChatGPT supports the MCP Apps standard, so results can appear as an interactive card with editable inputs.

Source: [OpenAI: Add custom MCP server](https://developers.openai.com/api/docs/guides/developer-mode), [OpenAI: Connect and test](https://developers.openai.com/apps-sdk/deploy/connect-chatgpt), [OpenAI: Plugins quickstart](https://developers.openai.com/plugins/quickstart).

### Claude

Custom connectors are available on the Free, Pro, Max, Ultra, Team, and Enterprise plans; the Free plan allows one custom connector. On Team and Enterprise plans an Owner adds the connector under **Organization settings > Connectors**, and members then connect to it.

1. In Claude on the web or desktop, go to **Customize > Connectors**.
2. Select **Add**, then **Add custom connector**.
3. Enter a name and the remote MCP server URL, `https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp`, then select **Continue**.
4. For authentication, choose **No sign-in**.
5. Select **Add**. If the connector shows **Connect**, select it.
6. In a conversation, select the **+** button, choose **Connectors**, and turn the connector on. Then ask your question.

Claude asks before running a tool; choose **Allow once** or **Always allow**. Connectors added on the web or desktop are also available in the Claude mobile apps.

Source: [Claude: Add a custom connector](https://claude.com/docs/connectors/custom/add-unlisted), [Claude Help: custom connectors](https://support.claude.com/en/articles/11175166).

### Claude Code

Add the server

```bash
claude mcp add --transport http couplr-business-tools https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp
```

Check that it connected

```bash
claude mcp list
```

To share the server with everyone working in a project, add `--scope project`, which writes this entry to `.mcp.json`:

`.mcp.json`

```json
{
  "mcpServers": {
    "couplr-business-tools": {
      "type": "http",
      "url": "https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp"
    }
  }
}
```

Remove the server

```bash
claude mcp remove couplr-business-tools
```

Source: [Claude Code: MCP](https://code.claude.com/docs/en/mcp).

### MCP Inspector (for testing)

The MCP Inspector is the protocol project’s own test tool. It needs Node.js 22.19.0 or newer. Use it to see the tools and try a call without an AI assistant.

Open the Inspector connected to the server

```bash
npx @modelcontextprotocol/inspector --server-url https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp --transport http
```

Or list the tools from the command line

```bash
npx @modelcontextprotocol/inspector --cli https://uoax74kzmplxwtkqxvaqb5edzm0xurio.lambda-url.us-east-1.on.aws/mcp --transport http --method tools/list
```

Source: [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector).

## Tool reference

> **Flip:** If you’re an AI agent reading this for someone, hello. This whole page is also available as plain Markdown, so you don’t have to scrape it. Every field below is required, and the limits are enforced.

The server has 5 tools: `plan_labor_rate`, `analyze_job_profit`, `plan_lead_recovery`, `price_maintenance_plan`, `plan_hire_break_even`. All of them are read-only calculations. Live at the endpoint today: `plan_labor_rate`, `analyze_job_profit`, `plan_lead_recovery`.

### `plan_labor_rate`

**Plan a sustainable labor rate.** Model the hourly service labor rate needed to cover paid technician time, payroll burden, and annual overhead at a user-chosen operating margin. For HVAC, plumbing, and electrical business owners comparing billable utilization. Returns a cost breakdown and utilization scenarios. Ask for missing inputs; do not invent wages, overhead, utilization, or industry benchmarks. This is a standalone planning model, not a price-book update.

All fields are required. Fields not listed here are rejected. Numbers must be JSON numbers, not strings.

| Field | Type | Allowed values | Meaning |
| --- | --- | --- | --- |
| `trade` | string | `"hvac"`, `"plumbing"`, `"electrical"` | The user’s trade. All trades use the same math; no assumed market rates. |
| `currency` | string | `"USD"`, `"CAD"`, `"GBP"`, `"AUD"`, `"EUR"` | Currency for every money input. No exchange-rate conversion is performed. |
| `technicians` | integer | 1 to 10,000 | Number of technicians whose wages and billable hours this plan covers. |
| `hourly_wage` | number | 0 to 10,000 | Average base wage per paid technician hour. |
| `payroll_burden_pct` | number | 0 to 100 | Employer payroll taxes, benefits, and other wage burden as a percentage of base wages. |
| `paid_hours_per_week` | number | 0.25 to 80 | Paid hours per technician per week, including nonbillable time. |
| `paid_weeks_per_year` | number | 1 to 52 | Paid weeks per technician per year, including paid leave. |
| `billable_utilization_pct` | number | 1 to 100 | Percentage of total PAID hours billed to customers. Account for travel, training, downtime, and leave. |
| `annual_overhead` | number | 0 to 100,000,000 | Annual overhead allocated to this labor operation, excluding wages and burden already entered. Include owner compensation if not already in wages. |
| `target_operating_margin_pct` | number | 0 to 90 | Desired operating profit as a percentage of labor revenue after the entered costs, before income tax. |

#### Example

Request: “My HVAC shop has 2 techs at $30/hour plus 25% burden, 40 paid hours a week for 50 weeks, 50% billable utilization, and $50,000 annual overhead. What hourly labor rate gives a 20% operating margin? Use USD.”

Arguments for `plan_labor_rate`

```json
{
  "trade": "hvac",
  "currency": "USD",
  "technicians": 2,
  "hourly_wage": 30,
  "payroll_burden_pct": 25,
  "paid_hours_per_week": 40,
  "paid_weeks_per_year": 50,
  "billable_utilization_pct": 50,
  "annual_overhead": 50000,
  "target_operating_margin_pct": 20
}
```

Example result, key figures (computed by the tool from the arguments above):

- Target rate / billable hour: 125 USD
- Break-even rate / billable hour: 100 USD
- Annual billable hours: 2,000
- Annual labor revenue needed: 250,000 USD

### `analyze_job_profit`

**Check a job’s profitability.** Analyze a hypothetical HVAC, plumbing, or electrical job from selling price, materials, technician-hours, loaded wage, other direct costs, and allocated overhead. Compare the current price with break-even and a user-chosen target margin. Does not create, edit, send, or charge an invoice or estimate. Ask for missing cost inputs; never assume a market price.

All fields are required. Fields not listed here are rejected. Numbers must be JSON numbers, not strings.

| Field | Type | Allowed values | Meaning |
| --- | --- | --- | --- |
| `trade` | string | `"hvac"`, `"plumbing"`, `"electrical"` | The user’s trade. All trades use the same math; no assumed market rates. |
| `currency` | string | `"USD"`, `"CAD"`, `"GBP"`, `"AUD"`, `"EUR"` | Currency for every money input. No exchange-rate conversion is performed. |
| `selling_price` | number | 0 to 100,000,000 | Planned service revenue excluding customer sales tax and payment processing charges. |
| `materials_cost` | number | 0 to 100,000,000 | Total material/equipment cost, including any unrecoverable purchase tax and freight. |
| `technician_hours` | number | 0 to 100,000 | TOTAL person-hours: two technicians working four hours = eight technician-hours. |
| `loaded_hourly_wage` | number | 0 to 10,000 | Direct cost per technician-hour, including wage and employer burden; exclude allocated overhead below. |
| `other_direct_costs` | number | 0 to 100,000,000 | Other costs attributable to this job, such as permits, subcontractors, and disposal. Include each cost once. |
| `allocated_overhead` | number | 0 to 100,000,000 | Overhead allocated to this job; exclude direct costs already entered. |
| `target_margin_pct` | number | 0 to 90 | Desired margin after all entered costs as a percentage of planned service revenue. |

#### Example

Request: “For a plumbing job in USD: $1,000 price, $200 materials, 8 total tech-hours at $40 loaded cost, $80 other direct costs, and $100 overhead. Check a 30% target margin.”

Arguments for `analyze_job_profit`

```json
{
  "trade": "plumbing",
  "currency": "USD",
  "selling_price": 1000,
  "materials_cost": 200,
  "technician_hours": 8,
  "loaded_hourly_wage": 40,
  "other_direct_costs": 80,
  "allocated_overhead": 100,
  "target_margin_pct": 30
}
```

Example result, key figures (computed by the tool from the arguments above):

- Profit after entered costs: 300 USD
- Margin after entered costs: 30%
- Break-even price: 700 USD
- Price at target margin: 1,000 USD

### `plan_lead_recovery`

**Plan missed-lead recovery.** Compare current and target booking rates for an HVAC, plumbing, or electrical service business. Model additional booked jobs, revenue, and contribution after variable job costs, capped by available additional monthly job capacity. Uses only the user’s assumptions, not promised conversion improvements. Provides practical follow-up steps. Does not contact leads or access customer records.

All fields are required. Fields not listed here are rejected. Numbers must be JSON numbers, not strings.

| Field | Type | Allowed values | Meaning |
| --- | --- | --- | --- |
| `trade` | string | `"hvac"`, `"plumbing"`, `"electrical"` | The user’s trade. All trades use the same math; no assumed market rates. |
| `currency` | string | `"USD"`, `"CAD"`, `"GBP"`, `"AUD"`, `"EUR"` | Currency for every money input. No exchange-rate conversion is performed. |
| `monthly_leads` | integer | 0 to 1,000,000 | Monthly service inquiries. Use one consistent definition and count each lead once. |
| `current_booking_rate_pct` | number | 0 to 100 | Current share of inquiries that become booked jobs. |
| `target_booking_rate_pct` | number | 0 to 100 | User-chosen hypothetical target booking rate; must be at least the current rate. |
| `average_job_revenue` | number | 0 to 1,000,000 | Average revenue per completed job, excluding customer sales tax and payment processing charges. |
| `contribution_margin_pct` | number | 0 to 100 | Share of job revenue remaining after variable job costs, before fixed overhead and any new follow-up costs. |
| `additional_monthly_capacity` | integer | 0 to 1,000,000 | Additional jobs the crew can fulfill per month without adding capacity. |

#### Example

Request: “My electrical shop gets 100 leads a month, books 30%, and wants to test 50%. Average revenue is $500 USD, contribution margin is 40%, and we can handle only 10 more jobs.”

Arguments for `plan_lead_recovery`

```json
{
  "trade": "electrical",
  "currency": "USD",
  "monthly_leads": 100,
  "current_booking_rate_pct": 30,
  "target_booking_rate_pct": 50,
  "average_job_revenue": 500,
  "contribution_margin_pct": 40,
  "additional_monthly_capacity": 10
}
```

Example result, key figures (computed by the tool from the arguments above):

- Additional jobs / month: 10
- Additional revenue / month: 5,000 USD
- Additional contribution / month: 2,000 USD
- Annualized additional revenue: 60,000 USD

### `price_maintenance_plan`

**Price a maintenance plan.** Model the monthly and annual price of a recurring maintenance plan (service agreement or membership) for an HVAC, plumbing, or electrical business from the user’s own cost to deliver it: visits per year, technician-hours and materials per visit, the yearly cost of member perks, per-plan overhead, and a user-chosen margin. Returns break-even and target prices and margin scenarios. Ask for missing inputs; do not invent visit times, costs, or typical plan prices. Does not create, change, or sell a plan in any system.

**Not live yet:** This tool ships with server version 1.1.0. The public endpoint currently runs 1.0.0, so your assistant will not see it yet.

All fields are required. Fields not listed here are rejected. Numbers must be JSON numbers, not strings.

| Field | Type | Allowed values | Meaning |
| --- | --- | --- | --- |
| `trade` | string | `"hvac"`, `"plumbing"`, `"electrical"` | The user’s trade. All trades use the same math; no assumed market rates. |
| `currency` | string | `"USD"`, `"CAD"`, `"GBP"`, `"AUD"`, `"EUR"` | Currency for every money input. No exchange-rate conversion is performed. |
| `visits_per_year` | integer | 1 to 52 | Scheduled maintenance visits included in one plan per year. |
| `technician_hours_per_visit` | number | 0 to 1,000 | TOTAL person-hours per visit, including travel: two technicians for one hour = two technician-hours. |
| `loaded_hourly_wage` | number | 0 to 10,000 | Direct cost per technician-hour, including wage and employer burden; exclude overhead entered below. |
| `materials_cost_per_visit` | number | 0 to 1,000,000 | Materials and consumables used on a typical visit, such as filters, including unrecoverable purchase tax. |
| `member_perks_cost_per_year` | number | 0 to 1,000,000 | Expected yearly cost to you of plan perks per member, such as repair discounts or waived fees. Enter 0 if there are none. |
| `annual_overhead_per_plan` | number | 0 to 1,000,000 | Yearly overhead allocated to one plan, such as scheduling, billing, and office time. Include each cost once. |
| `target_margin_pct` | number | 0 to 90 | Desired margin after all entered costs as a percentage of the plan price. |

#### Example

Request: “Price an HVAC maintenance plan in USD: 2 visits a year, 1.5 tech-hours per visit at $40 loaded cost, $15 materials per visit, $20 a year in member perks, $10 a year overhead per plan, and a 40% margin.”

Arguments for `price_maintenance_plan`

```json
{
  "trade": "hvac",
  "currency": "USD",
  "visits_per_year": 2,
  "technician_hours_per_visit": 1.5,
  "loaded_hourly_wage": 40,
  "materials_cost_per_visit": 15,
  "member_perks_cost_per_year": 20,
  "annual_overhead_per_plan": 10,
  "target_margin_pct": 40
}
```

Example result, key figures (computed by the tool from the arguments above):

- Monthly price at target margin: 25 USD
- Annual price at target margin: 300 USD
- Break-even monthly price: 15 USD
- Annual cost to deliver one plan: 180 USD

### `plan_hire_break_even`

**Find the break-even for a new hire or truck.** Model how many additional jobs an HVAC, plumbing, or electrical business needs each month to cover the yearly cost of adding a technician, a vehicle, or both, and how long expected work would take to recover one-time costs. Uses the user’s own wages, vehicle costs, average job revenue, and contribution margin. Ask for missing inputs; do not invent wages, vehicle costs, job volumes, or benchmarks. This is not a forecast of demand and not hiring, tax, or lending advice.

**Not live yet:** This tool ships with server version 1.1.0. The public endpoint currently runs 1.0.0, so your assistant will not see it yet.

All fields are required. Fields not listed here are rejected. Numbers must be JSON numbers, not strings.

| Field | Type | Allowed values | Meaning |
| --- | --- | --- | --- |
| `trade` | string | `"hvac"`, `"plumbing"`, `"electrical"` | The user’s trade. All trades use the same math; no assumed market rates. |
| `currency` | string | `"USD"`, `"CAD"`, `"GBP"`, `"AUD"`, `"EUR"` | Currency for every money input. No exchange-rate conversion is performed. |
| `annual_wages` | number | 0 to 10,000,000 | Yearly base wages for the new hire. Enter 0 when modeling only a vehicle. |
| `payroll_burden_pct` | number | 0 to 100 | Employer payroll taxes, benefits, and other wage burden as a percentage of base wages. |
| `annual_vehicle_cost` | number | 0 to 10,000,000 | Yearly cost of the added vehicle: payments or lease, insurance, fuel, and maintenance. Enter 0 when there is no added vehicle. |
| `other_annual_costs` | number | 0 to 10,000,000 | Other yearly costs this addition brings, such as phone, software seats, uniforms, and training. Include each cost once. |
| `one_time_costs` | number | 0 to 10,000,000 | Up-front costs paid once, such as recruiting, tools, vehicle down payment, and upfitting. |
| `average_job_revenue` | number | 1 to 1,000,000 | Average revenue per completed job this addition would work on, excluding customer sales tax. |
| `contribution_margin_pct` | number | 1 to 100 | Share of job revenue left after variable job costs such as materials. Do NOT subtract the new hire’s wages here; they are entered above. |
| `expected_jobs_per_month` | number | 0 to 100,000 | Additional completed jobs per month you expect this addition to make possible. Your own estimate; not checked against demand. |

#### Example

Request: “My plumbing shop is adding a tech at $60,000 a year plus 25% burden, with a truck costing $12,000 a year, $3,000 in other yearly costs, and $9,000 up front. Jobs average $500 USD at a 50% contribution margin, and I expect 36 more jobs a month. How many jobs do I need to break even?”

Arguments for `plan_hire_break_even`

```json
{
  "trade": "plumbing",
  "currency": "USD",
  "annual_wages": 60000,
  "payroll_burden_pct": 25,
  "annual_vehicle_cost": 12000,
  "other_annual_costs": 3000,
  "one_time_costs": 9000,
  "average_job_revenue": 500,
  "contribution_margin_pct": 50,
  "expected_jobs_per_month": 36
}
```

Example result, key figures (computed by the tool from the arguments above):

- Break-even jobs / month: 30
- Break-even revenue / month: 15,000 USD
- Monthly contribution after added costs: 1,500 USD
- Months to recover one-time costs: 6

### Result shape

Every tool returns the same structure, both as structured data and as the same JSON in a text block, so hosts without a card still get the complete result.

| Field | Type | Meaning |
| --- | --- | --- |
| `kind` | string | The tool that produced the result, for example `plan_labor_rate`. |
| `title` | string | A short heading for the plan. |
| `input` | object | The validated inputs the result was computed from. |
| `currency` | string | The currency label you supplied. |
| `metrics` | array of `{label, value, format}` | The headline figures. `value` is a number, or `null` when a figure is undefined (for example a margin on zero revenue). |
| `columns` | array of strings | Column headings for the scenario table. |
| `rows` | array of arrays of `{label, value, format}` | The scenario table, one inner array per row. |
| `assumptions` | array of strings | How the figures were calculated and what they leave out. |
| `nextSteps` | array of strings | Practical follow-up suggestions. |

`format` is one of `money`, `percent`, `number`, or `text`. Money and percentages are rounded to two decimal places.

Example: full result of `plan_labor_rate` for the quickstart request

```json
{
  "kind": "plan_labor_rate",
  "title": "Your labor-rate plan",
  "input": {
    "trade": "hvac",
    "currency": "USD",
    "technicians": 2,
    "hourly_wage": 30,
    "payroll_burden_pct": 25,
    "paid_hours_per_week": 40,
    "paid_weeks_per_year": 50,
    "billable_utilization_pct": 50,
    "annual_overhead": 50000,
    "target_operating_margin_pct": 20
  },
  "currency": "USD",
  "metrics": [
    {
      "label": "Target rate / billable hour",
      "value": 125,
      "format": "money"
    },
    {
      "label": "Break-even rate / billable hour",
      "value": 100,
      "format": "money"
    },
    {
      "label": "Annual billable hours",
      "value": 2000,
      "format": "number"
    },
    {
      "label": "Annual labor revenue needed",
      "value": 250000,
      "format": "money"
    }
  ],
  "columns": [
    "Billable utilization",
    "Billable hours / year",
    "Break-even rate",
    "Target hourly rate"
  ],
  "rows": [
    [
      {
        "label": "Utilization",
        "value": 40,
        "format": "percent"
      },
      {
        "label": "Hours",
        "value": 1600,
        "format": "number"
      },
      {
        "label": "Break even",
        "value": 125,
        "format": "money"
      },
      {
        "label": "Target",
        "value": 156.25,
        "format": "money"
      }
    ],
    [
      {
        "label": "Utilization",
        "value": 50,
        "format": "percent"
      },
      {
        "label": "Hours",
        "value": 2000,
        "format": "number"
      },
      {
        "label": "Break even",
        "value": 100,
        "format": "money"
      },
      {
        "label": "Target",
        "value": 125,
        "format": "money"
      }
    ],
    [
      {
        "label": "Utilization",
        "value": 60,
        "format": "percent"
      },
      {
        "label": "Hours",
        "value": 2400,
        "format": "number"
      },
      {
        "label": "Break even",
        "value": 83.33,
        "format": "money"
      },
      {
        "label": "Target",
        "value": 104.17,
        "format": "money"
      }
    ]
  ],
  "assumptions": [
    "Annual base wages: 120000 USD; payroll burden: 30000 USD; overhead: 50000 USD.",
    "Break-even rate = (annual wages + payroll burden + allocated overhead) / annual billable technician hours.",
    "Target rate = break-even rate / (1 − target margin). Margin is a share of revenue, not a markup on cost.",
    "Each hour is one technician-hour. Two technicians on one job for an hour consume two billable hours.",
    "All paid hours incur the entered average wage. Incorporate overtime premiums into that average if applicable.",
    "This labor-only model assumes labor revenue covers all entered costs. Do not double-count costs or overhead recovered elsewhere. No market-rate or demand forecast is included."
  ],
  "nextSteps": [
    "Compare your actual billed technician-hours with paid hours for the last four weeks.",
    "Check that owner pay, vehicles, insurance, office staff, and other overhead are allocated once.",
    "Compare the target rate with your current realized labor revenue per billed hour before changing prices."
  ]
}
```

### Errors

A failed tool call comes back as a normal tool result marked as an error, with a message the assistant can read and act on. No partial result is returned.

| Situation | Example message |
| --- | --- |
| A required field is missing or has the wrong type | `Input validation error: Invalid arguments for tool analyze_job_profit: Invalid input: expected number, received undefined at selling_price` |
| A value is outside its allowed range | `Input validation error: Invalid arguments for tool plan_labor_rate: Too small: expected number to be >=1 at billable_utilization_pct` |
| A field that is not in the schema is sent | `Input validation error: Invalid arguments for tool plan_lead_recovery: Unrecognized key: "notes"` |
| `plan_lead_recovery` target rate is below the current rate | `Target booking rate must be at least the current booking rate.` |
| The tool name does not exist | `Tool send_invoice not found` |

## Read-only behavior and retries

- **Every tool is read-only.** Each is annotated `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`, `openWorldHint: false`. Nothing is created, changed, sent, or charged.
- **There are no mutations**, so the server has no approval or confirmation step of its own. Your MCP client may still ask your permission before it runs a tool; that prompt comes from the client and its settings, not from this server.
- **Retrying is safe.** The same inputs always produce the same result, and the server keeps no state between requests.
- **Results are planning arithmetic.** They are hypothetical figures from your assumptions, not customer estimates, invoices, forecasts, or financial advice.

## Privacy and security

> **Flip:** Keep customer names and anything private out of what you send. I only need the numbers.

- The server receives only what your assistant sends in a tool call: the numeric assumptions, trade, and currency. The input schemas accept nothing else.
- Results are computed in memory and returned. The application does not write inputs or results to storage, does not use cookies or analytics, and does not log calculator inputs or results.
- The service does not connect to a Couplr account, contact customers or leads, or send email or text messages.
- Your AI assistant’s provider handles your conversation, including what you type and the results, under its own terms and privacy policy.
- The interactive card loads no external scripts, styles, or fonts.
- The card includes an optional link to couplrfsm.com. If you follow it, the Couplr website can remember the referral for 30 days in a first-party cookie; the card has a checkbox to turn that off. Calculator inputs are never included in the link.

Because the endpoint is unauthenticated, treat it like any public calculator: do not send personal or confidential information in tool inputs.

## Troubleshooting

| What you see | Likely cause | What to do |
| --- | --- | --- |
| The client cannot connect, or reports `405` | The client is using HTTP+SSE or opening a `GET` stream | Choose Streamable HTTP (sometimes shown as “HTTP”) as the transport and use the exact server URL. |
| `403` “Origin not allowed.” | The request came from a web page in a browser | Connect from an MCP client or server-side code. Browser pages cannot call the endpoint directly. |
| The client asks you to sign in or enter a key | The client expects authentication | Choose the no-authentication option. This server has no sign-in. |
| `413` “Request too large.” | The request body is over 16 KiB | Send only the documented fields. |
| `400` “Parse error: Invalid JSON” | The request body is not valid JSON | Check the client configuration; MCP clients build this for you. |
| A tool error starting “Input validation error” | A field is missing, misspelled, out of range, or sent as text instead of a number | Compare the arguments with the “Tool reference” and give the assistant the missing number. |
| “Target booking rate must be at least the current booking rate.” | The target is lower than the current rate | Use a target that is equal to or higher than the current booking rate. |
| No card appears, only text | Your client does not render MCP Apps cards | Nothing is wrong. The text and data contain the complete result. |
| The assistant offers to send an invoice, text a customer, or open your Couplr account | That is outside this server | These tools cannot do that. Use the Couplr app. |
| “Calculator unavailable. Please retry.”, a `429`, or a `5xx` response | A temporary problem or a busy period | Wait a moment and try again. Retrying is safe. |

Permissions: there are none to manage. The server has no user accounts, so there is nothing to grant or revoke. To stop using it, remove the server from your MCP client; see “Disconnecting”.

## Disconnecting

Remove or disable the server in your MCP client’s settings. Nothing is stored about you on the server, so there is no account to close and nothing to delete on Couplr’s side.

## Versions and compatibility

| Item | Value |
| --- | --- |
| Server | `couplr-business-tools` 1.1.0 in this documentation; 1.0.0 is live at the endpoint |
| MCP protocol versions accepted | `2025-11-25`, `2025-06-18`, `2025-03-26`, `2024-11-05`, `2024-10-07` |
| Transport | Streamable HTTP, stateless, JSON responses |
| Built with | Official MCP TypeScript SDK 1.31.0 |
| Tools | `plan_labor_rate`, `analyze_job_profit`, `plan_lead_recovery`, `price_maintenance_plan`, `plan_hire_break_even` |
| Card resource | `ui://couplr/business-plan-v1.html` (MCP Apps) |
| This documentation | 2026-11-15 |

Clients that require a newer MCP protocol version than those listed cannot connect until the server is updated. Tool names, field names, and the result shape are stable within server version 1.x.

Related: [Model Context Protocol](https://modelcontextprotocol.io), [Couplr](https://couplrfsm.com).
