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.
Resources
14Install
npx skillscat add brilliantdirectories/brilliant-directories-mcp Install via the SkillsCat registry.
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:
- Remote (no Node.js install): add an MCP server to the AI client's config pointing at
https://brilliantmcp.comwith two headers —X-Api-Key(user's BD API key) andX-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. - Local (runs as a child process on the user's machine, needs Node.js): run the setup wizard:
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.npx brilliant-directories-mcp@latest --setup
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 (e.g.,
https://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:
- If using MCP: list your available tools. Use whatever the client exposes.
- If using HTTP directly: GET the OpenAPI spec (URL above). Enumerate
pathsto see every endpoint. Each operation'soperationIdis the stable name. - To discover writable fields on any resource: many resources expose a
/fieldsendpoint (e.g.,GET /api/v2/user/fields,GET /api/v2/data_posts/fields) that returns field metadata includingrequired,type,choices, andhelpText.
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://mysite.com/api/v2/user/get.
Pagination (cursor-based)
- Request:
limit(default 25, max 100) +page(opaque cursor token from prior response'snext_page) - Response includes:
total,current_page,total_pages,next_page,prev_page - Never assume sequential integer page numbers. The
pageparameter 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=ASCResponse 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:
- Warn the user about the limit before starting
- Add pacing between writes (~600–700ms per call at the default limit)
- Watch for HTTP 429 responses; if hit, back off at least 60 seconds before retrying
- 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:
- Verify — call
verifyApiKey(orGET /api/v2/token/verify) to confirm credentials and site are reachable - Discover — if unsure about field names/types, call the resource's
/fieldsendpoint (e.g.,GET /api/v2/user/fields) - Scope — if the task involves many records, count them first with a narrow list query; confirm count with the user before writing
- Confirm destructive operations — summarize what you're about to change/delete and ask the user to confirm, especially for bulk writes
- Act — execute calls, pacing writes per the rate-limit rules
- 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=1Key rules:
- There is NO
createProfessionorcreateServicetool — those are BD internal names. UsecreateTopCategoryandcreateSubCategory. listTopCategoriesreturns TOP-level only;listSubCategoriesreturns SUB-level (filter byprofession_idto scope to one parent).- Sub-sub-categories are just SubCategories with
master_idset to another SubCategory'sservice_id. - A member can have ONE TopCategory (
profession_id) but MANY SubCategories (servicesCSV or multiplerel_servicesrows).
Things to always do
- 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 oncreateUser,servicesCSV supportsparent=>childsub-sub-category syntax, and more. If the user asks for something you think you can't do, scancreateUser/updateUserdescriptions end-to-end before responding "I can't." 9 times out of 10 the capability exists and is documented. - Treat the OpenAPI spec as the source of truth. If this skill and the spec disagree, trust the spec.
- Verify before bulk ops — call the token-verify endpoint before any job touching >50 records.
- Respect rate limits — warn the user, pace writes, back off on 429.
- Confirm destructive operations — deletes, bulk updates, overwrites — always summarize and require explicit confirmation.
- Use pagination tokens, not page numbers.
- Discover fields at runtime when unsure —
/fieldsendpoint or the spec's schema for the operation. - Acknowledge when an operation doesn't exist rather than inventing one.
- 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.
- 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 (typicallycontent_active=1for pages,post_status=1for posts,active=2for 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. - When supplying external image URLs to
createUserorupdateUser, includeauto_image_import=1by 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. Settingauto_image_import=1makes 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." - Categories can be passed by ID or by NAME on
createUser/updateUser. BD accepts both: passprofession_id(numeric) orprofession_name(string) for top-level, andservicesas a CSV mixing IDs and names. Auto-create rules differ: oncreateUser, unknown names are ALWAYS auto-created (hardcoded). OnupdateUser, unknown names are silently SKIPPED unless you passcreate_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 passprofession_name="Restaurants", services="Sushi"oncreateUser— no need to callcreateTopCategory/createSubCategoryfirst. For deeper sub-sub nesting, fall back tocreateSubCategorywithmaster_id.
Things to never do
- 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. - Never assume sequential page numbers — pagination is cursor-based.
- Never run mass deletes without explicit user confirmation — even if the user sounded confident. Summarize first.
- Never invent field names. If unsure, call
/fieldson the resource or read the OpenAPI schema. - Never retry indefinitely on 429 — back off at least 60s; offer to pace or raise the limit.
- Never hardcode the site URL — it's per-customer; always ask or read from config.
- Never rely on memorized endpoint lists — the API evolves; check the spec.
- Never invent URL prefixes when building a member's public profile link. Every user record has a
filenamefield — 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 resolvesfilenameverbatim. Same rule applies to post URLs (use the post'sfilenameorpost_tokenas 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. UsecreateTopCategory,listTopCategories, etc. Populatesusers_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. UsecreateSubCategorywithprofession_id= parent Top's ID. Members can have many — set viausers_data.servicesCSV or viacreateMemberSubCategoryLink.Sub-Sub Category — LEVEL 3 (optional nesting). Just a SubCategory with
master_idpointing at a parent SubCategory'sservice_id. Created viacreateSubCategorywith non-zeromaster_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). UsecreateMemberSubCategoryLinkwhen metadata matters; otherwise the simplerusers_data.servicesCSV field works.Post Type — a configuration row in
data_categoriesthat defines a category of user-publishable content (Blog, Event, Photo Album, Property, Product, etc.). Managed vialistPostTypes/getPostType/updatePostType/deletePostType. Each post type has adata_typefield (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) ordata_type=20(article, event, blog, job, coupon, discussion) fall here. Managed vialistSingleImagePosts/createSingleImagePost/ etc. Backed bydata_poststable.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 vialistMultiImagePosts/createMultiImagePost/ etc. Backed byusers_portfolio_groupstable. Individual photos within a Multi-Image Post are managed separately viaMultiImagePostPhototools.Multi-Image Post Photo — individual photo within a Multi-Image Post. Added AFTER the parent Multi-Image Post via
createMultiImagePostPhotousing the returnedgroup_id. Backed byusers_portfoliotable.Deciding Single vs. Multi: look up the target post type via
getPostType→ read itsdata_typefield →data_type=4means Multi-Image, any other value in {9,20} means Single-Image. Otherdata_typevalues ({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 acreateSingleImagePostorcreateMultiImagePost, defaultauto_image_import=1so 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 vialistWebPages,getWebPage,createWebPage,updateWebPage,deleteWebPage. Note: several page fields have admin-UI labels that differ from the API field name (e.g.,show_formis actually the "Apply NoIndex, NoFollow" toggle, NOT a contact-form toggle) — seecreateWebPage/updateWebPagetool 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
activeorcontent_activefield where1= visible/live and0= hidden/draft. Members use a 3-state convention (1= not active,2= active,3= canceled, etc.) — always verify via/fieldsfor 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 keyX-BD-Site-URL→ their BD site URL
Advanced (runs locally, needs Node.js): Setup wizard configures their client automatically.
npx brilliant-directories-mcp@latest --setupAfter 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.