Manage a Brilliant Directories (BD) membership or directory website via its REST API. Use when the user mentions their BD site, their directory, their members/leads/posts, managing site content, or automating anything on their Brilliant Directories platform.
Scanned 5/27/2026
Install via CLI
openskills install brilliantdirectories/brilliant-directories-mcp---
name: brilliant-directories
description: Manage a Brilliant Directories (BD) membership or directory website via its REST API. Use when the user mentions their BD site, their directory, their members/leads/posts, managing site content, or automating anything on their Brilliant Directories platform.
license: MIT
metadata:
author: Brilliant Directories
homepage: https://github.com/brilliantdirectories/brilliant-directories-mcp
npm: https://www.npmjs.com/package/brilliant-directories-mcp
openapi: https://raw.githubusercontent.com/brilliantdirectories/brilliant-directories-mcp/main/mcp/openapi/bd-api.json
---
# Brilliant Directories
Brilliant Directories (BD) is the SaaS platform behind 50,000+ membership and directory websites. This skill gives you programmatic control over a BD-powered site via its REST API.
## What having this skill active means for your user
You can do, without them opening the BD admin UI:
- **Member ops** — create, bulk import, update, search, delete members; auto-fetch profile photos/logos/cover images from external URLs (web-scrapes, CSVs, cross-site migrations); manage categories, credits, and tags
- **Content ops** — write blog articles, events, job listings, coupons, video posts, photo albums, property/product listings; edit the homepage, landing pages, about/contact, SEO meta tags, social Open Graph tags
- **Taxonomy ops** — build out the site's 3-tier category hierarchy (Top Category → Sub Category → Sub-Sub Category) from scratch or inline while creating members
- **Inbox & engagement** — read lead inbox, moderate reviews, trigger lead matching to send notification emails to eligible members
- **Site config** — edit navigation menus, form fields, email templates, widgets, smart lists, 301 redirects, membership plans
- **Billing introspection** — pull a member's invoice history and subscription status (read-only)
Typical outcome unlocks: "scrape 50 local businesses → create members with logos locally stored → write a blog post showcasing them → add redirects preserving SEO" — one agent run, zero admin clicks.
## Ground truth
**The authoritative source for every available operation is the OpenAPI spec:**
`https://raw.githubusercontent.com/brilliantdirectories/brilliant-directories-mcp/main/mcp/openapi/bd-api.json`
If this skill and the spec disagree, **the spec wins.** Scan the relevant tool description end-to-end before claiming a limit — BD exposes BD-specific capabilities (auto-image-import, auto-category-create, `parent=>child` sub-sub syntax, filename-is-full-path) that don't match typical REST API assumptions.
## When to activate
Activate this skill when the user:
- Mentions "my BD site," "my directory," "my directoryup site," "brilliant directories," or "my members"
- Asks to manage, import, update, export, search, or bulk-modify members/leads/posts/pages
- Wants to update the homepage, create a landing page, edit site content, or change SEO
- Wants to send emails, manage templates, configure forms, categories, tags, menus, or membership plans
- Mentions automating tasks across their directory/membership platform
- Asks something that sounds like an admin-panel task on a BD-powered site
## Two ways to reach the API (agent-agnostic)
This skill works with any AI agent. Two integration paths — use whichever the agent supports:
### Path A — MCP (preferred for Claude Desktop / Cursor / Windsurf / Cline / Claude Code)
The user installs the MCP server once; it exposes every BD operation as a tool. To check if it's active, look at your available tools for names like `verifyApiKey`, `listUsers`, `createUser`, `listWebPages`, etc.
**Two install options** — both give the full tool surface + same agent directives:
1. **Remote (no Node.js install):** add an MCP server to the AI client's config pointing at `https://brilliantmcp.com` with two headers — `X-Api-Key` (user's BD API key) and `X-BD-Site-URL` (user's BD site URL). This hits our hosted Cloudflare Worker; the user does nothing on their machine beyond editing the config file.
2. **Local (runs as a child process on the user's machine, needs Node.js):** run the setup wizard:
```bash
npx --prefer-online brilliant-directories-mcp@latest --setup
```
The wizard asks for their BD site URL and API key, then configures their AI client automatically. After a client restart, the tools become available.
Both paths are documented in detail in the README's "Setup by Platform" section. Remote is the faster recommendation for non-technical users; Local is useful when the user wants the MCP on their own infrastructure.
**Getting an API key:** BD Admin > Developer Hub > Generate API Key (full walkthrough: https://support.brilliantdirectories.com/support/solutions/articles/12000088768).
### Path B — Direct HTTPS using the OpenAPI spec (for ChatGPT Actions, n8n, Make, Zapier, LangChain, custom agents)
If MCP isn't available but the agent can make authenticated HTTP requests:
- Base URL: the user's BD site, full canonical URL with `www.` if applicable (e.g., `https://www.mysite.com`) — never hardcode, always ask
- Auth: HTTP header `X-Api-Key: {user's API key}`
- All endpoints and schemas: the OpenAPI spec URL above. Read it to discover operations, required fields, response shapes.
Both paths hit the same underlying REST API and behave identically.
## Tool / operation discovery (future-proof rule)
**Never assume a tool exists based on this document.** BD's API grows over time and this skill can't be updated for every new resource. The correct pattern:
1. If using MCP: list your available tools. Use whatever the client exposes.
2. If using HTTP directly: GET the OpenAPI spec (URL above). Enumerate `paths` to see every endpoint. Each operation's `operationId` is the stable name.
3. To discover writable fields on any resource: many resources expose a `/fields` endpoint (e.g., `GET /api/v2/user/fields`, `GET /api/v2/data_posts/fields`) that returns field metadata including `required`, `type`, `choices`, and `helpText`.
If a user asks for something and no matching operation appears in the spec, say so honestly: "The BD API doesn't currently expose that operation — you'll need to do it in the BD admin panel."
## Core conventions (stable across all resources)
### Authentication
Every API call uses `X-Api-Key` as an HTTP header. Via MCP, the server handles this automatically. Never ask the user to paste their API key into chat.
### Base URL pattern
All endpoints live under `{site_url}/api/v2/{resource}/{action}` — e.g., `https://www.mysite.com/api/v2/user/get`.
### Pagination (cursor-based)
- Request: `limit` (default 25, max 100) + `page` (opaque cursor token from prior response's `next_page`)
- Response includes: `total`, `current_page`, `total_pages`, `next_page`, `prev_page`
- **Never assume sequential integer page numbers.** The `page` parameter is an opaque token.
### Filtering
All list endpoints support property-based filtering:
```
?property=city&property_value=Los Angeles&property_operator==
```
Operators: `=`, `LIKE`, `>`, `<`, `>=`, `<=`. Multiple filters via `property[]=...&property_value[]=...`.
### Sorting
```
?order_column=last_name&order_type=ASC
```
### Response shape
Success: `{ "status": "success", "message": [...records...] or {record}, ...pagination fields... }`.
Error: `{ "status": "error", "message": "human-readable reason" }` with standard HTTP status codes.
### Rate limits
**Default 100 requests per 60 seconds per API key.** Customers can request a raise to anywhere between 100 and 1,000/min by contacting Brilliant Directories support — this is NOT a self-service admin setting.
For bulk operations:
1. Warn the user about the limit before starting
2. Add pacing between writes (~600–700ms per call at the default limit)
3. Watch for HTTP 429 responses; if hit, back off at least 60 seconds before retrying
4. For known-large jobs (>500 records), suggest the user contact BD support to raise the limit first
### Template tokens in text fields
Many text fields (titles, meta tags, email subjects, page content) support BD template tokens:
- `%%%website_name%%%` — the site's configured name
- `%%Profession%%` — the user's profession/category
- Widget embeds: `[widget=Widget Name]`
Preserve these exactly as the user provides — do not "clean them up" or escape them.
## Canonical multi-step pattern
For any non-trivial task, follow this sequence:
1. **Verify** — call `verifyApiKey` (or `GET /api/v2/token/verify`) to confirm credentials and site are reachable
2. **Discover** — if unsure about field names/types, call the resource's `/fields` endpoint (e.g., `GET /api/v2/user/fields`)
3. **Scope** — if the task involves many records, count them first with a narrow list query; confirm count with the user before writing
4. **Confirm destructive operations** — summarize what you're about to change/delete and ask the user to confirm, especially for bulk writes
5. **Act** — execute calls, pacing writes per the rate-limit rules
6. **Report** — summarize what happened: X succeeded, Y failed with specific reasons, Z skipped
### Worked example: "Import 300 members from this CSV"
```
1. Call verifyApiKey → confirm credentials work
2. Call GET /api/v2/user/fields → confirm required fields: email, password, subscription_id
3. Parse the CSV, show the user "I found 300 records, first row looks like: {...}. Proceed?"
4. If >100, warn: "BD's default rate limit is 100/min — this will take ~3 minutes. Want to have BD support raise it first?"
5. For each row: call createUser with ~700ms delay. Track failures with reasons.
6. Report: "Created 287/300. 13 failed: 9 because email already exists, 4 invalid subscription_id."
```
### Worked example: "Set up a Restaurants category with Sushi sub-category and assign a member"
BD classifies members via a 3-tier hierarchy. Each tier is a different API resource with explicit TopCategory / SubCategory / MemberSubCategoryLink naming:
```
1. createTopCategory (backed by /api/v2/list_professions/create)
with name="Restaurants", filename="restaurants"
→ returns profession_id (e.g. 42). Populates users_data.profession_id.
2. createSubCategory (backed by /api/v2/list_services/create)
with name="Sushi", profession_id=42, filename="sushi"
→ returns service_id (e.g. 17)
— Optional: pass master_id=<parent service_id> to make this a sub-sub-category
nested under another SubCategory. master_id=0 (default) means directly under the TopCategory.
3. Assign a member — two options depending on whether you need per-link metadata:
a) Simple (just tag them):
updateUser with user_id=<Alice>, profession_id=42, services="17"
b) With per-link metadata (price, specialty, completion count):
createMemberSubCategoryLink with user_id=<Alice>, service_id=17, avg_price=29.99, specialty=1
```
Key rules:
- There is NO `createProfession` or `createService` tool — those are BD internal names. Use `createTopCategory` and `createSubCategory`.
- `listTopCategories` returns TOP-level only; `listSubCategories` returns SUB-level (filter by `profession_id` to scope to one parent).
- Sub-sub-categories are just SubCategories with `master_id` set to another SubCategory's `service_id`.
- A member can have ONE TopCategory (`profession_id`) but MANY SubCategories (`services` CSV or multiple `rel_services` rows).
## Things to always do
0. **Before claiming a limitation ("I can't do X", "the API doesn't support Y", "you'll need to manually..."), READ the relevant tool description first.** Don't assume limits based on typical REST APIs. This skill documents BD-specific capabilities that are NOT obvious from tool names alone — notably: external image URLs are auto-fetched (via `auto_image_import=1`), categories auto-create by name on `createUser`, `services` CSV supports `parent=>child` sub-sub-category syntax, and more. If the user asks for something you think you can't do, scan `createUser` / `updateUser` descriptions end-to-end before responding "I can't." 9 times out of 10 the capability exists and is documented.
1. **Treat the OpenAPI spec as the source of truth.** If this skill and the spec disagree, trust the spec.
2. **Verify before bulk ops** — call the token-verify endpoint before any job touching >50 records.
3. **Respect rate limits** — warn the user, pace writes, back off on 429.
4. **Confirm destructive operations** — deletes, bulk updates, overwrites — always summarize and require explicit confirmation.
5. **Use pagination tokens, not page numbers.**
6. **Discover fields at runtime** when unsure — `/fields` endpoint or the spec's schema for the operation.
7. **Acknowledge when an operation doesn't exist** rather than inventing one.
8. **Consider downstream side-effects** — when an operation changes a URL-facing field (a slug, filename, category path), inbound links to the old URL break. Ask the user if they want a compensating action (e.g., a redirect rule). The same principle applies elsewhere: renaming a required category may leave orphan records; deleting a membership plan affects every member on it. Think one hop ahead and offer the user the safer workflow.
9. **If a new/updated record isn't visible on the public site, check the fundamentals before assuming a cache bug.** BD's API writes take effect immediately when the inputs are correct. If the user reports 404 or "I don't see it," first verify: (a) the required fields were all provided, (b) any enum-typed fields (e.g., `seo_type`, `active`, `post_status`) received valid values, (c) active/status flags are set to the "visible" value (typically `content_active=1` for pages, `post_status=1` for posts, `active=2` for members). Only if those check out and the record is still invisible, suggest the user try re-saving the record in BD admin as a last-resort cache nudge — but this is rare.
10. **When supplying external image URLs to `createUser` or `updateUser`, include `auto_image_import=1` by default.** Fields that accept image URLs (`profile_photo`, `logo`, `cover_photo`) are stored as-is unless this flag is set — meaning the images will break if the source host goes down. Setting `auto_image_import=1` makes BD fetch and store the images locally. This is the right default for any web-scrape, CSV import, or cross-site migration flow. Only skip it when the user explicitly says "keep the external reference."
11. **Categories can be passed by ID or by NAME on `createUser` / `updateUser`.** BD accepts both: pass `profession_id` (numeric) or `profession_name` (string) for top-level, and `services` as a CSV mixing IDs and names. **Auto-create rules differ:** on `createUser`, unknown names are ALWAYS auto-created (hardcoded). On `updateUser`, unknown names are silently SKIPPED unless you pass `create_new_categories=1`. Verified live on the BD test site 2026-04-18. If the user says "create a member in a new Restaurants → Sushi category," just pass `profession_name="Restaurants", services="Sushi"` on `createUser` — no need to call `createTopCategory` / `createSubCategory` first. For deeper sub-sub nesting, fall back to `createSubCategory` with `master_id`.
## Things to never do
1. **Never ask the user to paste their API key into chat.** The key lives in their MCP config or their HTTP client's secret store. If they have to provide it, direct them to `--setup`.
2. **Never assume sequential page numbers** — pagination is cursor-based.
3. **Never run mass deletes without explicit user confirmation** — even if the user sounded confident. Summarize first.
4. **Never invent field names.** If unsure, call `/fields` on the resource or read the OpenAPI schema.
5. **Never retry indefinitely on 429** — back off at least 60s; offer to pace or raise the limit.
6. **Never hardcode the site URL** — it's per-customer; always ask or read from config.
7. **Never rely on memorized endpoint lists** — the API evolves; check the spec.
8. **Never invent URL prefixes when building a member's public profile link.** Every user record has a `filename` field — that IS the full relative path. The public profile URL is simply `<site-domain>/<user.filename>`. Do NOT prepend `/business/`, `/profile/`, `/member/`, `/listing/`, or any other segment. BD's router resolves `filename` verbatim. Same rule applies to post URLs (use the post's `filename` or `post_token` as documented in the post endpoints).
## BD terminology glossary
- **Member / user** — an account on a BD site. Core resource.
- **Subscription / plan / membership plan** — a tier a member belongs to. Referenced as `subscription_id`.
- **Top Category / Profession** — LEVEL 1 of the member taxonomy (e.g., "Restaurants"). Stored in `list_professions`. Use `createTopCategory`, `listTopCategories`, etc. Populates `users_data.profession_id`. A member has exactly one.
- **Sub Category / Service** — LEVEL 2, nested under a Top Category (e.g., "Sushi" under "Restaurants"). Stored in `list_services`. Use `createSubCategory` with `profession_id` = parent Top's ID. Members can have many — set via `users_data.services` CSV or via `createMemberSubCategoryLink`.
- **Sub-Sub Category** — LEVEL 3 (optional nesting). Just a SubCategory with `master_id` pointing at a parent SubCategory's `service_id`. Created via `createSubCategory` with non-zero `master_id`.
- **Member ↔ Sub Category link / rel_services** — join-table row linking a member to a SubCategory with per-link metadata (`avg_price`, `specialty`, `num_completed`). Use `createMemberSubCategoryLink` when metadata matters; otherwise the simpler `users_data.services` CSV field works.
- **Post Type** — a configuration row in `data_categories` that defines a category of user-publishable content (Blog, Event, Photo Album, Property, Product, etc.). Managed via `listPostTypes` / `getPostType` / `updatePostType` / `deletePostType`. Each post type has a `data_type` field (integer) that classifies its family. Post types are read/updated via API, but NOT creatable via the API (too admin-specific — create new post types in BD admin UI). Do NOT create posts via these tools — this is metadata only.
- **Single-Image Post** — a post record in the Single-Image family (one feature image per post). Post types with `data_type=9` (video) or `data_type=20` (article, event, blog, job, coupon, discussion) fall here. Managed via `listSingleImagePosts` / `createSingleImagePost` / etc. Backed by `data_posts` table.
- **Multi-Image Post** — a post record in the Multi-Image family (photo albums, galleries, property listings with multiple photos). Post types with `data_type=4` (Photo Album, Classified, Property, Product) fall here. Managed via `listMultiImagePosts` / `createMultiImagePost` / etc. Backed by `users_portfolio_groups` table. Individual photos within a Multi-Image Post are managed separately via `MultiImagePostPhoto` tools.
- **Multi-Image Post Photo** — individual photo within a Multi-Image Post. Added AFTER the parent Multi-Image Post via `createMultiImagePostPhoto` using the returned `group_id`. Backed by `users_portfolio` table.
**Deciding Single vs. Multi:** look up the target post type via `getPostType` → read its `data_type` field → `data_type=4` means Multi-Image, any other value in {9,20} means Single-Image. Other `data_type` values ({10, 13, 21, 29}) are internal admin types (Member Listings, Reviews, Specialties, Favorites) — use the resource-specific endpoint instead.
**Auto-image-import rule** (same as `createUser`): when any external image URL is supplied on a `createSingleImagePost` or `createMultiImagePost`, default `auto_image_import=1` so BD fetches the image and stores it locally. Skip only when the user explicitly wants external URL references kept.
- **Web Page / SEO page / `list_seo`** — any static-ish page on the site: homepage (`seo_type=home`), about, contact, custom landing pages (`seo_type=content`), profile/search result templates. Managed via `listWebPages`, `getWebPage`, `createWebPage`, `updateWebPage`, `deleteWebPage`. Note: several page fields have admin-UI labels that differ from the API field name (e.g., `show_form` is actually the "Apply NoIndex, NoFollow" toggle, NOT a contact-form toggle) — see `createWebPage`/`updateWebPage` tool descriptions for the full field→UI-label mapping.
- **Widget** — reusable HTML component embeddable in pages/emails via `[widget=Name]` shortcode.
- **Lead** — an inbound contact/inquiry, can be routed/matched to relevant members.
- **Form** — a configurable form that collects inputs (signup, contact, quote request, etc.).
- **Redirect / `redirect_301`** — a 301 permanent redirect rule. Maps an old URL path to a new destination. Used after profile renames, post slug changes, category restructuring, or custom URL migrations to preserve SEO and inbound links.
- **Template token** — placeholder like `%%%website_name%%%` expanded at render time.
- **Active status** — most BD records have an `active` or `content_active` field where `1` = visible/live and `0` = hidden/draft. Members use a 3-state convention (`1` = not active, `2` = active, `3` = canceled, etc.) — always verify via `/fields` for the specific resource.
## Reference URLs
- **OpenAPI spec (live, authoritative):** https://raw.githubusercontent.com/brilliantdirectories/brilliant-directories-mcp/main/mcp/openapi/bd-api.json
- **Full endpoint docs (human-readable):** https://github.com/brilliantdirectories/brilliant-directories-mcp/tree/main/docs
- **npm package (MCP server):** https://www.npmjs.com/package/brilliant-directories-mcp
- **Issues / bug reports:** https://github.com/brilliantdirectories/brilliant-directories-mcp/issues
- **BD's own API documentation:** https://support.brilliantdirectories.com/support/solutions/articles/12000108045
- **Generate an API key:** https://support.brilliantdirectories.com/support/solutions/articles/12000088768
## Installation recap for the user
If the user needs to set up the MCP server, two options — **Easy is the recommended path for non-technical users**:
**Easy (no Node.js install):** Add an MCP server to their AI client's config pointing at `https://brilliantmcp.com` with two headers:
- `X-Api-Key` → their BD API key
- `X-BD-Site-URL` → their BD site URL
**Advanced (runs locally, needs Node.js):** Setup wizard configures their client automatically.
```bash
npx brilliant-directories-mcp@latest --setup
```
After either path, restart their AI client — tools become available.
For non-MCP integrations (ChatGPT Actions, n8n, Make, Zapier, Postman, custom agents): import the OpenAPI spec URL directly and authenticate with the `X-Api-Key` header.
## Bundled growth skills
This plugin ships with growth-automation skills that turn the MCP tools into higher-level workflows. Each skill is invoked via the `/bd:` namespace.
**`/bd:events`** — Researches local events from public web sources and creates SEO-rich event posts on the user's BD site. Walks through site context, hunts events matching the user's vertical and location, applies quality gates (date sanity, source credibility, confidence threshold), manufactures structured post bodies with FAQ + internal/external linking + source attribution, geocodes addresses via OpenStreetMap. Interactive or autonomous mode. Drafts by default in autonomous runs.
More skills are in the backlog (`/bd:jobs`, `/bd:blog`, `/bd:properties`, `/bd:seo`, etc.) — each will follow the same shared methodology under `skills/_shared/`.
### Skills architecture
All BD growth skills share a common protocol layer in `skills/_shared/`:
- `METHODOLOGY.md` — research methodology, quality gates, dedup, mode detection, audit
- `URL-PATTERNS.md` — BD internal URL construction patterns
- `SAFETY-RULES.md` — whitehat scraping, attribution, no-fabrication
- `BD-PROTOCOLS.md` — MCP wrapper specifics (rate limits, force-injections)
- `ANTI-SLOP.md` — writing voice and AI-pattern blacklist (mandatory for any content generation)
Per-skill files in `skills/<name>/SKILL.md` layer on data-type-specific details: post type discovery, field reference, source candidates, EEAT template, dedup keys.
Always read the relevant `_shared/*.md` files before running any `/bd:*` skill.
No comments yet. Be the first to comment!