fub-mcp
v0.2.1
Published
A comprehensive Model Context Protocol (MCP) server wrapping the Follow Up Boss (FUB) real estate CRM API.
Downloads
513
Maintainers
Readme
fub-mcp
A comprehensive Model Context Protocol server for the Follow Up Boss 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
Easiest: guided setup (macOS)
npx -y fub-mcp setupThis pops a native macOS dialog (masked input, like a password field) asking for
your Follow Up Boss API key (FUB → Admin → API). It validates the key against the
live API before saving, stores it in ~/.fub-mcp/.env (permissions restricted to
your user only), and wires the mcpServers entry into Claude Desktop's config for
you — automatically. Your key is never typed into a Claude conversation, never
seen by any LLM, and never written into claude_desktop_config.json — that file
only ends up with a secret-free {"command": "npx", "args": ["-y", "fub-mcp"]}
entry pointing at the server, which loads the key from ~/.fub-mcp/.env at
startup instead.
Windows/Linux support for the guided setup isn't built yet — use the manual method below on those platforms for now.
If you're on Claude Desktop or Claude Code, the claude-setup
skill has Claude tell you to run the one command above rather than trying to collect
your key itself — see that folder's SKILL.md for why (short version: a plain chat
message isn't a safe place for a live CRM credential to sit).
Manual
Add to your MCP client's config (e.g. Claude Desktop's claude_desktop_config.json,
or Claude Code's MCP settings):
{
"mcpServers": {
"fub-mcp": {
"command": "npx",
"args": ["-y", "fub-mcp"],
"env": {
"FUB_API_KEY": "your-fub-api-key"
}
}
}
}Get your API key from Follow Up Boss: Admin → API.
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. |
| 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:
- Server-level opt-in: unless
FUB_MCP_ALLOW_DELETE=1is set in the server's environment, delete tools aren't registered at all — the model never sees them as callable. - Per-call confirmation: even with that flag set, every delete tool requires a
confirm: trueargument, 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 documentGET /notes/{id}, but the pluralGET /notesendpoint works today and supports apersonIdfilter. Confirmed against the live API; treated as best-effort since it's unofficial.update_persontag handling — adding tags should passmergeTags=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: trueset 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
:idinstead of{id}for path params, and the rate-limit endpoints' documented paths double up the/v1prefix that's already in the base URL.
Skills
Three Claude 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/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
npm install
npm run build
npm run inspect # opens the MCP Inspector against the built serversrc/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
