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)
   and **double-click** it. Claude Desktop opens an install screen.
2. **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.
3. **Turn it on.** Installing does not enable it: go to **Settings → Extensions**,
   find **Follow Up Boss**, and switch the toggle **on**.
4. **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 has been tested on macOS, and Windows is supported
by Claude Desktop but not yet tested by the maintainer. 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**.

#### macOS guided setup (alternative to putting the key in a config file)

```bash
npx -y fub-mcp setup
```

Pops a native macOS dialog (masked input) for your key, validates it against the live
API, stores it in `~/.fub-mcp/.env` (permissions restricted to your user), and adds a
secret-free `mcpServers` entry to Claude Desktop's config. If you're using Claude
Desktop, the extension above is simpler and stores the key more securely.

### 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://followupboss.com/2/api). |
| `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