# AgreeKeep MCP — HVAC membership ops for agents

> Org-scoped HTTPS tools for overdue agreements, season completion, batch PM scheduling, ACCA-guided checklists, and renewal invoice drafts — API keys or OAuth. Writes are included in Pro ($29/mo).

## What it does (buyer language)

- **Overdue inbox** — `list_overdue_agreements` returns agreements with PM visits past their seasonal window (spring/fall/current).
- **Season board** — `get_season_completion` for completion % and counts; `list_agreements` / `get_agreement` for roster detail.
- **Batch schedule** — `schedule_pm_visits` is confirm-gated (dry-run + `confirm_token`) before creating visits.
- **Checklists** — `generate_pm_checklist` builds tier-aware PM checklists (Guidance for shop SOPs—not ACCA certification, not legal advice, not a substitute for licensed tech judgment.).
- **Renewals** — `list_renewals_due` and confirm-gated `invoice_membership_renewals` (draft/send; no processor lock-in claims).

We do **not** expose live carrier warranties, manufacturer claim status, or refrigerant compliance certifications. `sync_from_jobber` is an MVP stub — preview candidates only; no destructive Jobber writes without human confirm in the UI.

## Auth

- **API keys (primary):** org keys from app settings, prefix `ak_`. Header `Authorization: Bearer <key>`.
- **OAuth 2.1:** authorization code + PKCE S256. Register at `https://agreekeep.com/api/oauth/register`, authorize at `https://agreekeep.com/api/oauth/authorize` (shop login + consent), token at `https://agreekeep.com/api/oauth/token`. Access tokens use prefix `akat_`.
- Scopes include `agreements:read`, `schedule:write`, `billing:write`. Missing scope returns `forbidden_scope`.
- Missing/invalid credential → **401** with `WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource/api/mcp"` (RFC 9728).
- **Demo read path:** `ak_demo_agreekeep_mvp_key` on seeded Demo HVAC (Pro preview, not a Free shop). Read-only tools, 40 calls per UTC day. Writes return `upgrade_required` and `https://agreekeep.com/billing?plan=pro`.

## Pricing

MCP is **included in Pro ($29/mo)** on the existing Stripe price (`STRIPE_PRICE_ID`). No second Stripe account and no metered overage price.

| Plan | MCP |
|------|-----|
| Free / demo | Read-only: list/get agreements, overdue, season completion, renewals due. Hard cap 40/UTC day. |
| Pro | Read + write/automation. Soft warning at 2000/UTC day. Hard stop 3000 (HTTP 429, JSON-RPC -32029). |
| Shop+ | Same MCP access as Pro. Multi-location sales stays on Shop+ only — not a gate for MCP. |

## Endpoint status

Streamable HTTP (stateless POST):

- **URL:** `https://agreekeep.com/api/mcp`
- **POST** — JSON-RPC `initialize` / `tools/list` / `tools/call`, plus legacy `{ "method": "tools/list" }`. Prefer `Accept: application/json`. If the client accepts only `text/event-stream`, the server writes one SSE event and closes.
- **GET** — discovery JSON. `Accept: text/event-stream` without JSON returns **405 immediately** (no held SSE session).
- **DELETE** — 405, no session to terminate.
- **PRM:** `https://agreekeep.com/.well-known/oauth-protected-resource/api/mcp` (root and `/mcp` aliases exist)
- **AS metadata:** `https://agreekeep.com/.well-known/oauth-authorization-server`
- **Registry manifest:** `https://agreekeep.com/server.json` (hosted here; official MCP Registry listing is not published yet)
- **Smithery card:** `https://agreekeep.com/.well-known/mcp/server-card.json`
- **Alias:** `https://agreekeep.com/.well-known/mcp.json`

Retries: send `Idempotency-Key` on mutating tools. Calls time out at 20s. For stdio-only clients, use `@agreekeep/mcp-bridge` (source in `packages/agreekeep-mcp-bridge`; the npm package is not published yet).

## Tool catalog

- **list_overdue_agreements** — Use when you need memberships whose seasonal PM visit is past its spring or fall window. Do not use to schedule, invoice, or mark complete. Optional: season (spring|fall|current), as_of (YYYY-MM-DD), limit (1-100), cursor, include_bumped, min_days_overdue. Returns items and next_cursor. Free/demo keys may call this.
- **schedule_pm_visits** — Use to batch-place PM visits on the calendar for known agreement ids. Do not use to list who is overdue — call list_overdue_agreements first. Requires Pro. Required: agreement_ids, window (spring|fall), preferred_date_range {start, end}. Default is dry-run and returns confirm_token. Pass that token with dry_run false to apply. Send Idempotency-Key when retrying the apply. Does not dispatch a technician in Jobber or ServiceTitan.
- **generate_pm_checklist** — Use when a tech needs an ACCA 4 QM–guided checklist instance for one visit. Do not use as a certification or refrigerant-compliance record. Requires Pro. Required: agreement_id or visit_id. Creates a new instance; send Idempotency-Key so a retry does not duplicate it.
- **invoice_membership_renewals** — Use to draft renewal invoices for agreements due soon. Do not use to charge a card or to list the queue — call list_renewals_due first. Requires Pro. Optional: agreement_ids, due_within_days (default 30), send (draft vs sent flag). Default dry-run returns confirm_token. Nothing is charged. Send Idempotency-Key when applying.
- **list_agreements** — Use for a paginated membership roster. Do not use when you already have an agreement_id — call get_agreement. Optional: status, tier_id, query (customer name), limit (1-100), cursor. Returns items and next_cursor. Free/demo keys may call this.
- **get_agreement** — Use for one membership: customer, equipment, visits, tier. Do not use to scan the shop — call list_agreements. Required: agreement_id. Free/demo keys may call this.
- **create_agreement** — Use to add a membership and due-visit placeholders. Do not use to update an existing agreement. Requires Pro. Required: customer {name}, tier_id, term_start (YYYY-MM-DD). dry_run true returns confirm_token and does not write. Send Idempotency-Key on the write so a retry does not create a second agreement.
- **mark_visit_complete** — Use when a PM visit is done. Do not use to cancel or bump — call mark_visit_status. Requires Pro. Required: visit_id. Optional: completed_at, tech_id, findings, prebook_opposite_season (default true). Repeating the same visit stays complete and does not duplicate the opposite-season stub. Send Idempotency-Key on retries.
- **get_season_completion** — Use for season completion percent and due/scheduled/complete/overdue counts. Do not use for the customer-level overdue list. Required: season (spring|fall). Optional: year. Free/demo keys may call this.
- **sync_from_jobber** — Use only to preview Jobber candidates that still need a human confirm in the AgreeKeep UI. Do not use to write back to Jobber or to activate agreements. Requires Pro. MVP stub: no destructive Jobber writes. Default dry-run returns confirm_token. Send Idempotency-Key when confirming.
- **list_renewals_due** — Use for agreements whose term ends soon or whose payment method failed. Do not use to create invoices — call invoice_membership_renewals after you have ids. Optional: within_days (default 30), include_failed_payments, limit, cursor. Free/demo keys may call this.
- **mark_visit_status** — Use to set a visit to missed, forfeited, rescheduled, bumped, snoozed, due, or scheduled. Do not use to mark the work done — call mark_visit_complete. Requires Pro. Required: visit_id, status. Optional: reason, new_date, snooze_until. Bump count increments only the first time a visit becomes bumped. Send Idempotency-Key on retries.

## Install — Cursor (`mcp.json`)

Documented stub (adjust when your Cursor build supports HTTP MCP for this endpoint):

```json
{
  "mcpServers": {
    "agreekeep": {
      "url": "https://agreekeep.com/api/mcp",
      "headers": {
        "Authorization": "Bearer ak_YOUR_ORG_KEY"
      }
    }
  }
}
```

Replace `ak_YOUR_ORG_KEY` with an org API key from **Settings → API keys**. The demo key is read-only. Pro ($29/mo) unlocks write tools.

## Install — Claude Desktop (stdio bridge)

```json
{
  "mcpServers": {
    "agreekeep": {
      "command": "npx",
      "args": ["-y", "@agreekeep/mcp-bridge@0.3.0"],
      "env": {
        "AGREEKEEP_API_KEY": "ak_YOUR_ORG_KEY"
      }
    }
  }
}
```

The npm package is not published yet. Run the bridge from `packages/agreekeep-mcp-bridge` until `@agreekeep/mcp-bridge` is on npm.

## Install — Claude Desktop (HTTP — when supported)

Some builds accept remote HTTP MCP with Bearer headers:

```json
{
  "mcpServers": {
    "agreekeep": {
      "url": "https://agreekeep.com/api/mcp",
      "headers": {
        "Authorization": "Bearer ak_YOUR_ORG_KEY"
      }
    }
  }
}
```

## Install — ChatGPT

Point a remote MCP connector at `https://agreekeep.com/api/mcp` with `Authorization: Bearer ak_YOUR_ORG_KEY`. Same tools, plan gate, and fair-use limits. No extra package.

## Rate limits & legal limits

- Pro: soft 2000/UTC day, hard 3000. Free/demo: hard 40. HTTP 429 includes `Retry-After`.
- Respect confirm gates on schedule, renewals, Jobber sync, and agreement create — never skip `dry_run` in production automations without human review.
- Retry writes with the same `Idempotency-Key`.
- Membership is a service contract/plan with defined included tasks—not a manufacturer warranty or insurance.
- Guidance for shop SOPs—not ACCA certification, not legal advice, not a substitute for licensed tech judgment.
- No legal advice; no E&O; no warranty of HVAC workmanship.

## More

- HTML install page: https://agreekeep.com/mcp
- llms.txt: https://agreekeep.com/llms.txt
- Pricing (MCP included in Pro): https://agreekeep.com/pricing.md
