Skip to main content
Glama
gray-wilbee

fub-mcp

by gray-wilbee
README.md
# fub-mcp

A comprehensive [Model Context Protocol](https://modelcontextprotocol.io) server for
the [Follow Up Boss](https://www.followupboss.com/) real estate CRM API. Not
affiliated with or endorsed by Follow Up Boss.

Generates one MCP tool per FUB API operation (~130+ tools) directly from FUB's
published OpenAPI spec, plus a small set of hand-written extras for behavior that's
real but undocumented. Runs entirely on your machine — your API key never leaves it.

## Install

### Claude Desktop (recommended — no Terminal, no Node.js)

1. **Download** [`fub-mcp.mcpb`](https://github.com/gray-wilbee/fub-mcp/releases/latest/download/fub-mcp.mcpb)
   (it lands in your Downloads folder).
2. **Install it from inside Claude Desktop:** open **Settings → Extensions →
   Advanced settings → Install Extension…** and choose the downloaded file. (Dragging
   the file onto the Claude Desktop window also works. On macOS, double-clicking works
   too, but **on Windows double-clicking does not** — Claude Desktop doesn't register
   the file type, so Windows offers Notepad instead. Cancel that prompt and use the
   in-app route.)
3. **Paste your Follow Up Boss API key** into the masked field (FUB → Admin → API),
   then click **Install**. Claude Desktop stores the key in your system keychain
   (macOS Keychain / Windows Credential Manager); it is never typed into a chat and
   never sent anywhere except directly to Follow Up Boss.
4. **Turn it on.** Installing does not enable it: go to **Settings → Extensions**,
   find **Follow Up Boss**, and switch the toggle **on**.
5. **Start a new chat** and try *"List my 3 most recently added contacts."*

Claude Desktop ships its own Node.js runtime, so nothing else needs installing. Notes:
the bundle isn't code-signed yet, so Claude Desktop may show an unverified-developer
caution. It is pure JavaScript (no native binaries) and has been tested end to end on
both macOS and Windows. To update, download the newest `.mcpb` and install it over
the old one.

### Claude Code, other MCP clients, or Terminal users

```bash
claude mcp add fub-mcp --env FUB_API_KEY=your-key -- npx -y fub-mcp
```

or add this to your MCP client's config (e.g. `claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "fub-mcp": {
      "command": "npx",
      "args": ["-y", "fub-mcp"],
      "env": {
        "FUB_API_KEY": "your-fub-api-key"
      }
    }
  }
}
```

Requires Node.js 18+. Get your API key from Follow Up Boss: **Admin → API**.

#### Optional: macOS-only key-entry popup

If you'd rather not put your key in a config file, macOS users can run
`npx -y fub-mcp setup`: a native masked dialog collects the key, validates it against
the live API, saves it to `~/.fub-mcp/.env` (readable only by your user), and adds a
secret-free entry to Claude Desktop's config. Claude Desktop users should prefer the
extension above, which needs no Terminal and stores the key in the OS keychain. This
popup is not available on Windows or Linux (use the extension, or the commands above).

### Recommended for heavy use: register your own FUB system

Follow Up Boss asks API users to register their system, and registered systems get a
higher request rate (FUB's API states this in its responses). By default this tool
identifies itself as an unregistered `fub-mcp`. FUB's terms also say a system key is
private and must not be shared, so a shared one can't ship with this project: each
customer registers their own.

1. Register at <https://apps.followupboss.com/system-registration> (system name, a
   "System ID Header" of your choosing such as `acme-realty-claude`, your name, email,
   and organization). Read the terms linked on that page.
2. FUB provides your **X-System-Key** after you register.
3. In Claude Desktop, open **Settings → Extensions → Follow Up Boss** and fill in the
   two optional fields: **your registered system ID** (the System ID Header) and
   **your system key**. Restart Claude Desktop. (Other clients: set
   `FUB_MCP_SYSTEM_NAME` and `FUB_MCP_SYSTEM_KEY`.)

**Keep the system key private, like your API key.** Paste it only into that masked
field. Never put it in a chat, email, screenshot, or plain-text file; if you need a
copy, use a password manager. The setup instructions tell Claude never to ask for it.
If a key ever lands somewhere it shouldn't, email api@followupboss.com and ask for a
replacement.

### Optional environment variables

| Variable | Default | Purpose |
|---|---|---|
| `FUB_MCP_SYSTEM_NAME` | `fub-mcp` | Sent as `X-System` so FUB attributes actions to this tool and grants the better registered-system rate limit. |
| `FUB_MCP_SYSTEM_KEY` | unset | Only needed if you've separately [registered your own system](https://apps.followupboss.com/system-registration). |
| `FUB_MCP_ALLOW_DELETE` | `0` | Set to `1` to enable DELETE-verb tools at all. See **Delete safety** below. |

## Delete safety

Follow Up Boss DELETE calls are permanent. This server treats them as opt-in at two
layers:

1. **Server-level opt-in**: unless `FUB_MCP_ALLOW_DELETE=1` is set in the server's
   environment, delete tools aren't registered at all — the model never sees them as
   callable.
2. **Per-call confirmation**: even with that flag set, every delete tool requires a
   `confirm: true` argument, and its description instructs the model to get explicit,
   specific confirmation from the user before calling it — not to infer consent from
   general intent.

Neither layer trusts the model alone; both must be satisfied.

## What's generated vs. hand-written

Most tools (`list_people`, `create_note`, `update_deal`, ...) are generated at build
time straight from FUB's OpenAPI spec (vendored in `src/openapi/fub-openapi.json` —
refresh it from https://docs.followupboss.com/openapi to pick up FUB API changes).

A few things needed hand-written overrides in `src/overrides/`:

- **`list_notes`** — FUB's docs only document `GET /notes/{id}`, but the plural
  `GET /notes` endpoint works today and supports a `personId` filter. Confirmed
  against the live API; treated as best-effort since it's unofficial.
- **`update_person` tag handling** — adding tags should pass `mergeTags=true`
  (defaulted for you); removing a tag has no dedicated endpoint and requires a
  fetch → filter → PUT-the-whole-array-back pattern (documented in the tool
  description).
- **Notes vs. templates HTML handling** — notes need `isHtml: true` set explicitly
  for HTML bodies; email templates take raw HTML directly with no such flag. These
  are easy to mix up, so both tools' descriptions call it out.
- Two spec quirks fixed transparently by the generator: a couple of endpoints use
  `:id` instead of `{id}` for path params, and the rate-limit endpoints' documented
  paths double up the `/v1` prefix that's already in the base URL.

## Skills

Three [Claude Skills](./skills) ship alongside the server for common multi-step
workflows the tools alone don't capture:

- **`query-smart-list`** — resolve a Smart List by name (not just ID) before filtering
  people by it.
- **`create-html-email-template`** — build and upload an HTML email template
  correctly (see the HTML-handling gotcha above), including FUB's `%merge_field%`
  syntax.
- **`create-text-template`** — build an SMS template with the same merge fields, plus
  FUB's own texting-compliance guidance (opt-out language, carrier-filtering
  avoidance).

## Using this outside Claude

- **ChatGPT Custom GPT**: see [`gpt/`](./gpt) for a trimmed, ≤30-operation OpenAPI
  schema and setup instructions — each person builds their own GPT with their own
  API key, no shared/hosted backend involved.
- **Claude web or mobile without the desktop app**: not currently supported.
  Claude.ai's custom-connector UI only supports OAuth (or an org-admin-only static
  header beta) for remote connectors, so there's no individual, bring-your-own-key
  path there today the way there is for a Custom GPT. Reaching pure web/mobile users
  would require a hosted, multi-tenant OAuth backend — out of scope for this repo for
  now.

## Development

```bash
npm install
npm run build
npm run inspect   # opens the MCP Inspector against the built server
```

`src/openapi/generate-tools.ts` does the spec → tool-schema conversion;
`src/overrides/index.ts` is where undocumented endpoints, description corrections,
and default overrides live. `src/tools.ts` merges the two and applies delete-gating.

## License

MIT

TDQS

C2.7/5.0

Scored across 133 tools

Disambiguation3/5

Most tools map cleanly to a resource+action, but the sheer number (133) and similar names create real ambiguity: create_event vs. create_person, list_events vs. list_em_events, and the people/claim/ignore_unclaimed cluster are easy to confuse. Descriptions help, but the boundaries are not immediately evident from the names alone.

Naming Consistency2/5

The dominant list_/get_/create_/update_ pattern is undermined by several post_/put_ prefixed tools (post_people_claim, put_inbox_apps_message) and inconsistent singular/plural forms (create_automations_person vs. list_automations_people). This mixes verb styles and noun forms within the same resource families, making the naming pattern unreliable.

Tool Count1/5

133 tools is an extreme count for any MCP server; it far exceeds the 50+ threshold for a severe mismatch. While a full CRM API is inherently large, exposing every endpoint as a separate tool creates a heavy, unwieldy surface that is hard for agents to navigate.

Completeness3/5

The surface is remarkably broad, covering people, deals, pipelines, stages, notes, calls, tasks, appointments, templates, webhooks, teams, automations, and custom fields. However, there are notable gaps: no delete operation exists for any resource, events lack update, and there is no actual send capability for emails/texts (only template merge/render utilities).

Maintenance

ActivityMaintained
ResponsivenessNo issues