brilliant-directories-mcp
OfficialThe Brilliant Directories MCP server gives AI agents comprehensive API access to manage a Brilliant Directories site across nearly every resource:
Member/User Management
Create, read, update, delete, search, and list members
Validate login credentials, fetch transactions and subscriptions
Dynamically discover available user fields
Content & Posts
Full CRUD + search for single-image posts and multi-image album groups (portfolios)
Manage individual album photos; discover post field definitions for custom post types
Reviews
Full CRUD + search with moderation status control (Pending, Accepted, Declined, Waiting for Admin)
Leads & Lead Matching
Create, read, update, delete leads with auto-matching to members
Full CRUD for lead match records
Categories
List top-level categories (professions), manage sub-categories and member↔sub-category relationships
Post Types
Full CRUD for post types; retrieve their custom field definitions
Forms & Form Fields
Full CRUD for forms and individual fields, supporting extensive field types (textbox, dropdown, checkbox, rich text, CAPTCHA, file upload, etc.)
Membership Plans
Full CRUD for subscription/membership plans with pricing and profile type configuration
Email Templates
Full CRUD with merge tag and trigger support
Widgets
Full CRUD plus render widgets to HTML
Menus & Menu Items
Full CRUD for site navigation menus and their individual items
Clicks Tracking
Full CRUD for click records (phone, email, link interactions)
Unsubscribe List
Add, view, update, and remove emails
Utilities
Verify API key / check rate limit status
Manage 301 redirects, web pages, website settings cache, smart lists, and tags
All list endpoints support pagination, filtering (multiple operators), and sorting
Enables direct HTTP API access to Brilliant Directories resources using curl commands with X-Api-Key authentication for member management, content operations, and site administration.
Integrates with Make automation platform through custom app creation using OpenAPI spec or HTTP modules, allowing workflow automation for Brilliant Directories member management and content operations.
Provides integration through OpenAPI spec import or HTTP Request nodes, enabling workflow automation for managing Brilliant Directories members, content, forms, and site resources.
Enables automation through existing Brilliant Directories Zapier app or Webhooks by Zapier with X-Api-Key header, allowing integration with other apps for member management and content operations.
Official Brilliant Directories MCP Server — Setup Guide
Universal AI integration for your BD site. Give any AI agent full access to your Brilliant Directories site with one API key.
Manage members, posts (single-image and multi-image), leads, reviews, top and sub categories, email templates, pages (homepage, landing pages), 301 redirects, smart lists, widgets, menus, forms, tags, membership plans, and more — across every resource BD exposes via its REST API.
This guide walks you through connecting your AI of choice (Claude, Cursor, etc.) to your BD site. Pick your AI app below, paste two things, restart. Most setups take under 5 minutes.
⚠️ REQUIREMENTS — Before you start
Your BD site URL. Use the full canonical URL exactly as it loads in a browser — include
https://(orhttp://if your site has no SSL), includewww.if your site uses it, no trailing slash.✅
https://www.mysite.com(most BD sites)✅
https://mysite.com(only if your site has nowww.)✅
http://mysite.com(HTTP-only sites — protocol respected)❌
mysite.com(missing protocol)❌
https://mysite.com/(trailing slash)❌
https://mysite.comif the site actually serves atwww.mysite.com— use the form your site canonically responds at
Your BD API key.
BD Admin → Developer Hub → Generate API Key → copy it.
Full walkthrough: How to Create an API Key.
Node.js — only for the Advanced path (see below). Not needed for the Easy path. If you need it, one-time install from nodejs.org (click
Get Node.js®to download, then clickWindows Installer (.msi)— Mac:macOS Installer— double-click the downloaded file to install, Next through the prompts).
🚨 API PERMISSIONS — DO NOT SKIP THIS
New BD API keys ship locked down — only member read/write is enabled by default.
Every other resource (web pages, forms, menus, tags, email templates, reviews, leads, categories, post types, widgets, etc.) lives behind an "Advanced Endpoints" toggle and returns 403 API Key does not have permission to access this endpoint until you flip it on.
This catches almost every first-time user. If your AI can list members but can't create a page or update a form, stop debugging — it's this.
Turn on Advanced Endpoints:
BD Admin → Developer Hub
Find your API key in the list → Actions dropdown → Permissions
Click the Advanced Endpoints tab
Toggle everything ON (or cherry-pick only the resources you'll use — but ALL ON is the fastest way to stop tripping over this)
Click Save Permissions
The change is immediate — no key rotation, no AI restart needed. Re-run the failed request and it'll succeed.
Want to stop the AI from deleting anything? Uncheck every
deleteaction under Advanced Endpoints. The AI will still be able to read, create, and update — but anydelete*tool call will return 403 instead of wiping data. Good baseline for production sites where the AI shouldn't be trusted with destructive operations.
Why BD locks it down by default: least-privilege. A leaked key with baseline-only permissions can only read/write members on your site, not rewrite your whole directory. Once you've decided which endpoints your agent actually needs, you can pare the permissions back down to just those.
Related MCP server: Google Drive server
Table of Contents
Setup by Platform
Each platform has two options:
🚀 Easy config block — points at our hosted MCP at
https://brilliantmcp.com. No Node.js, no install, no terminal. Starts working the moment you save and restart your AI app.🛠️ Advanced config block — spawns the MCP as a
npxchild process on your machine. Use when you want the MCP on your own hardware.Needs Node.js installed first — get it from nodejs.org (click
Get Node.js®to download, then clickWindows Installer (.msi)— Mac:macOS Installer— and DOUBLE-CLICK the downloaded file to install it).
Both give the full BD tool surface, same instructions, same lean shapers, same safety guards.
🚀 Easy config block (recommended — 30-second install)
In your AI client's MCP config (Cursor, Windsurf, Cline, Codex, n8n, etc.), add this entry:
{
"mcpServers": {
"brilliant-directories": {
"url": "https://brilliantmcp.com",
"headers": {
"X-Api-Key": "ENTER_API_KEY",
"X-BD-Site-URL": "https://www.your-site.com"
}
}
}
}Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL (full canonical form — https://, exact host, no trailing slash, see Requirements).
⚠️ Claude Desktop doesn't accept the Easy block — use the Advanced block in the Claude Desktop section.
Save, then fully quit and reopen the AI app. Saving alone is not enough — every AI client loads MCP servers only at fresh launch, not on hot-reload. Done. Working? Skip to "What you can ask the AI".
Need a client-specific walkthrough? Jump to your platform's section below.
🛠️ Advanced config block (requires Node.js install)
⚠️ STEP 1 — Install Node.js FIRST (the Advanced path runs an
npxcommand on your machine):
Go to nodejs.org → click Get Node.js®
Download: Windows Installer (.msi) or macOS Installer
Double-click the file → click Next through every prompt to fully install Node.js
Skip this and you'll see "no MCP servers" with
spawn npx ENOENTin the log.
Why
--prefer-online+@latest? Forces npm to revalidate against the registry on every launch so you always pull the newest version. Prevents theETARGET No matching version founderror that hits when your local npm cache is stale.
STEP 2 — Paste this config:
{
"mcpServers": {
"brilliant-directories": {
"command": "npx",
"args": [
"-y",
"--prefer-online",
"brilliant-directories-mcp@latest",
"--api-key", "ENTER_API_KEY",
"--url", "https://www.your-site.com"
]
}
}
}STEP 3 — Fully quit the AI app, then reopen. Closing the window is NOT enough — the AI loads MCP servers only at a true relaunch:
Windows: right-click the app's icon in the system tray (bottom-right, may be hidden under
^) → Quit, then reopenMac:
Cmd+Qor menu bar → → Quit , then reopen
Claude Desktop
⚠️ Claude Desktop requires Node.js + the Advanced (npm) config. It doesn't accept the Easy
url-shaped block — only stdio (command+args).
⚠️ Windows users: install Claude Desktop from claude.ai/download, NOT the Microsoft Store (the Store version sandboxes the config file).
Banner saying "Tool result could not be submitted… connection interrupted"? Cosmetic UI bug across every MCP connector (anthropics/claude-code #51874) — your tools still work. Safe to ignore.
⚠️ STEP 1 — Install Node.js FIRST (before pasting the config below):
Go to nodejs.org → click Get Node.js®
Download: Windows Installer (.msi) or macOS Installer
Double-click the file → click Next through every prompt to fully install Node.js
Skip this and you'll see "no MCP servers" with
spawn npx ENOENTin the log.
Steps (no terminal):
Open Claude Desktop.
Menu bar → Settings.
Developer tab → Edit Config.
This opens
claude_desktop_config.jsonin TextEdit (Mac) or Notepad (Windows).Pick your scenario:
Scenario A — file is empty {} or has no mcpServers entry
Select all (Cmd+A / Ctrl+A) and delete. Paste this:
{
"mcpServers": {
"brilliant-directories": {
"command": "npx",
"args": [
"-y",
"--prefer-online",
"brilliant-directories-mcp@latest",
"--api-key", "ENTER_API_KEY",
"--url", "https://www.your-site.com"
]
}
}
}Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL. Save, then fully quit and reopen Claude Desktop. Saving alone is not enough — Claude loads MCP servers only at fresh launch.
Scenario B — file already has content (preferences, Google connectors, other MCP servers)
Merge — don't overwrite. Two rules:
Comma between top-level entries.
Final
}at the bottom stays one brace.
Before:
{
"preferences": {
"menuBarEnabled": false,
"legacyQuickEntryEnabled": false
}
}After:
{
"preferences": {
"menuBarEnabled": false,
"legacyQuickEntryEnabled": false
},
"mcpServers": {
"brilliant-directories": {
"command": "npx",
"args": [
"-y",
"--prefer-online",
"brilliant-directories-mcp@latest",
"--api-key", "ENTER_API_KEY",
"--url", "https://www.your-site.com"
]
}
}
}Two changes: , added after the preferences closing }, and the mcpServers block added before the final }. Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL. Save, then fully quit and reopen Claude Desktop.
Paste your final file into jsonlint.com before restarting to ensure correct formatting.
Missing commas silently break the MCP — a validator flags them instantly.
Fully quit and reopen Claude Desktop. Start a new chat.
"Fully quit" means more than closing the window — Claude loads MCP servers only at a true relaunch:
Windows: right-click the Claude icon in the system tray (bottom-right, may be hidden under
^) → Quit, then reopenMac:
Cmd+Qor menu bar → Claude → Quit Claude, then reopen
Verify the BD MCP loaded. The exact UI varies by Claude Desktop version:
In any chat, ask "what tools do you have?" — you should see
brilliant-directoriestools listed.OR check Settings → Developer → MCP servers —
brilliant-directoriesshould show as connected (no error status).Older builds also show a 🔨 hammer icon with a tool count near the chat input — click it to see the tools.
Not connected? Check Settings → Developer → MCP servers for the error. Common causes:
JSON typo — paste your file into jsonlint.com
Wrong API key, or URL missing
https:/// has trailing slashNode.js not installed (Claude Desktop spawns
npx)Saw "not valid MCP server configurations"? You pasted a
url-shaped block — Claude Desktop only accepts the stdio (command+args) shape shown above.
Direct config file path (if you skip Settings):
Mac:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Claude Code
Claude Code has no MCP GUI — install via terminal. Works in Terminal.app (Mac), PowerShell (Windows), or Cursor / VS Code's built-in terminal (open with Ctrl+` / Cmd+` or View → Terminal).
Prerequisites — one-time install:
Node.js — from nodejs.org (click
Get Node.js®→Windows Installer (.msi)ormacOS Installer→ double-click to install, click Next through the prompts).The
claudeCLI — in any terminal, run:npm install -g @anthropic-ai/claude-codeClose and reopen the terminal. Verify with
claude --version.
Three options below — pick whichever fits.
⚡ Plugin (one-line install, recommended if your Claude Code supports it)
Inside an active claude session, run these two slash commands:
/plugin marketplace add brilliantdirectories/brilliant-directories-mcp
/plugin install brilliant-directories@brilliant-directories-mcpClaude Code fetches the plugin manifest, registers the BD MCP server, and tools become available immediately. You'll be prompted for BD_API_KEY and BD_SITE_URL on first use, or set them as environment variables before launching claude. (The Easy and Advanced paths below take credentials inline in the claude mcp add command instead — different paths, same end result.)
Don't see
/plugincommands? Plugin support requires a recent build. Runnpm install -g @anthropic-ai/claude-code@latestand restart the terminal. If still missing, use the Easy or Advanced path below.
🚀 Easy (hosted Worker — no local BD MCP subprocess)
claude mcp add brilliant-directories --transport http https://brilliantmcp.com \
--header "X-Api-Key: ENTER_API_KEY" \
--header "X-BD-Site-URL: https://www.your-site.com"Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL. Verify with claude mcp list — brilliant-directories should show ✓ Connected. Close and reopen Claude Code.
🛠️ Advanced (BD MCP runs locally via npx)
claude mcp add brilliant-directories -- npx -y --prefer-online brilliant-directories-mcp@latest --api-key ENTER_API_KEY --url https://www.your-site.comSame shape, but runs the MCP server as an npx child process on your machine. Replace the placeholders. Verify with claude mcp list. Close and reopen Claude Code. The -y flag auto-accepts the first-time npx install prompt so the spawn doesn't hang.
Credentials live inside the
claude mcp addcommand. They're written into your user-level Claude config file and passed to BD automatically on every tool call. To rotate:claude mcp remove brilliant-directories, then re-runclaude mcp addwith new values.
Claude extension inside Cursor
If you chat with Claude inside Cursor (the Anthropic "Claude" extension installed from the Cursor extension marketplace), that extension has its OWN MCP config — separate from Cursor's native agent. Installing in one doesn't install in the other.
Note: the Claude extension and the Claude Code CLI both read the SAME file —
~/.claude.json(Windows:C:\Users\<you>\.claude.json). If you've already set up Claude Code per the section above, the BD MCP is already loaded for the Claude extension too. This section covers customers who only use the Claude extension and don't have the CLI installed.
Two different MCP configs. Two different places the tools show up.
1. Claude extension (inside Cursor or Claude Code CLI)
Config file (Windows):
C:\Users\<you>\.claude.jsonConfig file (Mac / Linux):
~/.claude.jsonTools appear: when you chat with Claude — ask "what tools do you have" or type
/mcp
2. Cursor's native agent
Config file (Windows):
C:\Users\<you>\.cursor\mcp.jsonConfig file (Mac / Linux):
~/.cursor/mcp.jsonTools appear: Cursor Settings → Tools & MCP
Easiest setup — edit the JSON file in Notepad (NO terminal, NO claude CLI needed):
⚠️ STEP 1 — Install Node.js FIRST (before editing the config below):
Go to nodejs.org → click Get Node.js®
Download: Windows Installer (.msi) or macOS Installer
Double-click the file → click Next through every prompt to fully install Node.js
Skip this and you'll see "no MCP servers" with
spawn npx ENOENTin the log.
Open the file. Paste the path into File Explorer's address bar (Windows) or Finder's Go → Go to Folder (Mac). If it doesn't exist yet, create a new empty text file at that path named exactly
.claude.json.Paste this inside. If the file already has content with an
mcpServerskey, merge the"brilliant-directories": {...}entry into the existingmcpServersobject — don't overwrite other entries.{ "mcpServers": { "brilliant-directories": { "command": "npx", "args": [ "-y", "--prefer-online", "brilliant-directories-mcp@latest", "--api-key", "ENTER_API_KEY", "--url", "https://www.your-site.com" ] } } }Replace
ENTER_API_KEYwith your BD API key andhttps://www.your-site.comwith your BD site URL (includehttps://, no trailing slash).Save the file, then fully quit and reopen Cursor so the Claude extension picks up the new config. Saving alone is not enough.
Chat with Claude and ask "what tools do you have?" — you should see
brilliant-directoriestools listed.
Cursor's Tools & MCP panel will stay empty — that's expected. Claude's extension reads
~/.claude.json; Cursor's panel only reflects~/.cursor/mcp.json. If you want BD tools in BOTH surfaces, also do the Cursor section install.
Alternative — if you have the claude CLI installed (most users don't — skip if you don't know what it is): run this in any terminal:
claude mcp add brilliant-directories -- npx -y --prefer-online brilliant-directories-mcp@latest --api-key ENTER_API_KEY --url https://www.your-site.comThe CLI writes the same JSON to ~/.claude.json for you — same end result as editing by hand.
OpenAI (Codex Desktop)
OpenAI surface | Supported? |
Codex Desktop (the desktop app) | ✅ Yes — full MCP, both transports |
ChatGPT web / desktop / mobile | ❌ No — no MCP connector support in consumer ChatGPT |
For BD automation in the OpenAI ecosystem, use Codex Desktop. ChatGPT itself can't speak MCP yet; for GUI alternatives if you don't want Codex, use Claude Desktop / Cursor / Windsurf / Cline.
Codex Desktop setup
1. Download Codex Desktop from chatgpt.com/codex/get-started and install it.
2. Open Codex Desktop → File → Settings → MCP Servers → + Add Server.
A "Connect to a custom MCP" form opens with two tabs: STDIO (Advanced — runs locally, needs Node.js) and Streamable HTTP (Easy — hosted Worker, no Node.js). Either works — pick one.
🚀 Easy (Streamable HTTP — recommended, no Node.js install required):
Click the Streamable HTTP tab. Fill the form top-to-bottom:
Field (as shown in Codex) | Value |
Name |
|
URL |
|
Bearer token env var | leave empty — don't touch |
Headers — Key |
|
Headers — Value | your BD API key |
Click + Add header to add the second row | |
Headers — Key (row 2) |
|
Headers — Value (row 2) |
|
Headers from environment variables | leave empty — don't touch |
Click Save, then fully quit and reopen Codex. Saving alone is not enough — Codex loads MCP servers only at fresh launch.
🛠️ Advanced (STDIO — runs on your machine, needs Node.js):
⚠️ STEP 1 — Install Node.js FIRST (before pasting the config below):
Go to nodejs.org → click Get Node.js®
Download: Windows Installer (.msi) or macOS Installer
Double-click the file → click Next through every prompt to fully install Node.js
Skip this and you'll see "no MCP servers" with
spawn npx ENOENTin the log.
Click the STDIO tab. Fill the form top-to-bottom:
Field (as shown in Codex) | Value |
Name |
|
Command to launch |
|
Arguments — Row 1 |
|
Click + Add argument between each row below | |
Arguments — Row 2 |
|
Arguments — Row 3 |
|
Arguments — Row 4 | your BD API key |
Arguments — Row 5 |
|
Arguments — Row 6 |
|
Environment variables | leave empty — don't touch |
Environment variable passthrough | leave empty — don't touch |
Working directory | leave empty — don't touch |
Click Save, then fully quit and reopen Codex. Saving alone is not enough — Codex loads MCP servers only at fresh launch.
"Fully quit" means more than closing the window — Codex loads MCP servers only at a true relaunch:
Windows: right-click the Codex icon in the system tray (bottom-right, may be hidden under
^) → Quit, then reopenMac:
Cmd+Qor menu bar → Codex → Quit Codex, then reopen
4. Test the connection: in a new Codex chat, ask "list my first 5 members on my BD site". Tools invoke, data comes back.
Pro tip — multi-site management: repeat this setup with a different Name + credentials per BD site (e.g.
brilliant-directories-main/brilliant-directories-staging). Then tell Codex "on brilliant-directories-main, list the top categories" or "copy these email templates from -main to -staging". Useful for agencies and multi-brand operators.
Windsurf
Windsurf's AI pane is called Cascade. MCP servers plug into Cascade.
⚠️ Windsurf uses
serverUrl(noturl) for remote MCP servers. The Easy config block below reflects that.
Open Windsurf.
Open settings: click Windsurf - Settings at the bottom-right of the window, OR Command Palette (
Cmd/Ctrl+Shift+P) → typeOpen Windsurf Settings.In settings, find the Cascade section → Model Context Protocol (MCP) → enable it.
In the Cascade panel on the right of your window, click the MCPs icon (top-right of the panel) → Configure. This opens the MCP config file.
Paste one of these (Easy is recommended):
🚀 Easy (recommended — no Node.js install required):
{
"mcpServers": {
"brilliant-directories": {
"serverUrl": "https://brilliantmcp.com",
"headers": {
"X-Api-Key": "ENTER_API_KEY",
"X-BD-Site-URL": "https://www.your-site.com"
}
}
}
}🛠️ Advanced (runs on your machine, needs Node.js):
⚠️ STEP 1 — Install Node.js FIRST (before pasting the config below):
Go to nodejs.org → click Get Node.js®
Download: Windows Installer (.msi) or macOS Installer
Double-click the file → click Next through every prompt to fully install Node.js
Skip this and you'll see "no MCP servers" with
spawn npx ENOENTin the log.
{
"mcpServers": {
"brilliant-directories": {
"command": "npx",
"args": [
"-y",
"--prefer-online",
"brilliant-directories-mcp@latest",
"--api-key", "ENTER_API_KEY",
"--url", "https://www.your-site.com"
]
}
}
}Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL. Save, then fully quit and reopen Windsurf. Saving alone is not enough — Windsurf loads MCP servers only at fresh launch.
"Fully quit" means more than closing the window — Windsurf loads MCP servers only at a true relaunch:
Windows: right-click the Windsurf icon in the system tray (bottom-right, may be hidden under
^) → Quit, then reopenMac:
Cmd+Qor menu bar → Windsurf → Quit Windsurf, then reopen
Cline (VS Code extension)
Open VS Code with the Cline extension installed.
Click the Cline icon in the VS Code sidebar to open the Cline panel.
In Cline's top nav, click the MCP Servers icon.
Click Configure MCP Servers — opens the Cline MCP config file in VS Code.
Paste one of these (Easy is recommended):
🚀 Easy (recommended — no Node.js install required):
{
"mcpServers": {
"brilliant-directories": {
"url": "https://brilliantmcp.com",
"headers": {
"X-Api-Key": "ENTER_API_KEY",
"X-BD-Site-URL": "https://www.your-site.com"
}
}
}
}🛠️ Advanced (runs on your machine, needs Node.js):
⚠️ STEP 1 — Install Node.js FIRST (before pasting the config below):
Go to nodejs.org → click Get Node.js®
Download: Windows Installer (.msi) or macOS Installer
Double-click the file → click Next through every prompt to fully install Node.js
Skip this and you'll see "no MCP servers" with
spawn npx ENOENTin the log.
{
"mcpServers": {
"brilliant-directories": {
"command": "npx",
"args": [
"-y",
"--prefer-online",
"brilliant-directories-mcp@latest",
"--api-key", "ENTER_API_KEY",
"--url", "https://www.your-site.com"
]
}
}
}Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL. Save, then fully quit and reopen VS Code. Saving alone is not enough — Cline loads MCP servers only at fresh launch, not on panel reload or toggle.
Back in the MCP Servers panel, confirm
brilliant-directoriesappears — toggle it on if not already."Fully quit" means more than closing the window — Cline loads MCP servers only at a true VS Code relaunch:
Windows: right-click the VS Code icon in the system tray (bottom-right, may be hidden under
^) → Quit, then reopenMac:
Cmd+Qor menu bar → Code → Quit Visual Studio Code, then reopen
Cursor
Fastest path (no install, 30 seconds): open Cursor Settings → MCP (or Model Context Protocol) → Add new MCP server → paste the Easy config block with your API key + site URL. Fully quit + reopen. Tools appear in the chat.
Or edit
~/.cursor/mcp.jsondirectly and paste the block. Either way works.Prefer the local install? Keep reading — the Cursor Directory installer below sets up the Advanced path (runs as an npx child process).
Cursor Directory one-click install for the Advanced path (no terminal, no file editing):
⚠️ STEP 1 — Install Node.js FIRST (the Cursor Directory installer wires up an
npxchild process):
Go to nodejs.org → click Get Node.js®
Download: Windows Installer (.msi) or macOS Installer
Double-click the file → click Next through every prompt to fully install Node.js
Skip this and Cursor will show "no MCP servers" with
spawn npx ENOENTin the log.
Open → cursor.directory/plugins/brilliant-directories
Click Install / Add to Cursor → allow browser to open Cursor.
Cursor shows an "Install MCP Server?" prompt with most fields pre-filled. Two things you need to change:
Rename the Name field (don't leave it as
server— too generic):brilliant-directories-60031— site-ID-based (recommended pattern)brilliant-directories-mysite— site-name-basedbrilliant-directories-main/brilliant-directories-staging/brilliant-directories-client-acme— nicknameWhy: Cursor lists every MCP by this Name; if you later add a second BD site, you'll need to tell them apart.
Fill Environment Variables — RIGHT side only:
Left (do NOT touch)
Right (paste your values)
BD_API_KEYyour BD API key
BD_SITE_URLhttps://www.your-site.com— includehttps://, no trailing slashAPI key → BD Admin → Developer Hub → Generate API Key (BD shows it once; if lost, generate a new one).
Advanced endpoint permissions must be enabled on the key or most writes 403. See Before you start.
Click Install.
Fully quit and reopen Cursor.
"Fully quit" means more than closing the window — Cursor loads MCP servers only at a true relaunch:
Windows: right-click the Cursor icon in the system tray (bottom-right, may be hidden under
^) → Quit, then reopenMac:
Cmd+Qor menu bar → Cursor → Quit Cursor, then reopen
Tools appear in Settings → Tools & MCP.
Pro tip — multi-site management: install the BD MCP multiple times with different API keys + URLs, each with a unique Name (e.g.
brilliant-directories-60031,brilliant-directories-marketing). Then tell Cursor "on brilliant-directories-60031, list the top categories" or "compare member counts between the two sites". Same pattern works in Claude Desktop and Claude Code. Useful for agencies and multi-brand operators.
Alternative A — Cursor Settings GUI (manual, no terminal)
Open Cursor.
Open settings:
Mac: menu bar → Cursor → Settings → Cursor Settings
Windows / Linux: File → Preferences → Cursor Settings
Or: Command Palette (
Cmd/Ctrl+Shift+P) → typeOpen MCP Settings
In the sidebar, click Tools & MCP.
Click New MCP Server.
Paste the config block. Replace
ENTER_API_KEYwith your BD API key andhttps://www.your-site.comwith your BD site URL.Click Save, then fully quit and reopen Cursor. Saving alone is not enough — Cursor loads MCP servers only at fresh launch.
Alternative B — Edit the config file directly
Use this if the GUI doesn't show "Tools & MCP" or the "New MCP Server" button silently fails. Same result as the GUI method.
Cursor reads from mcp.json in a hidden .cursor folder in your home directory.
Mac / Linux
Open Finder (Mac) or your file manager (Linux).
Cmd+Shift+G(Mac) orCtrl+L(Linux) to open a "Go to Folder" input.Type
~/.cursor→ Enter.If "Folder doesn't exist": navigate to
~/and create a new folder named exactly.cursor(leading dot). Retry.
Inside
.cursor, openmcp.jsonin TextEdit / any text editor. If missing: create it. TextEdit users: File → New → Format menu → Make Plain Text first, then save asmcp.json(notmcp.json.txt).Paste the config block. Replace
ENTER_API_KEYwith your BD API key andhttps://www.your-site.comwith your BD site URL. Save, then fully quit and reopen Cursor.
Windows
Windows key → type
File Explorer→ Enter.Click the address bar at the top. Type
%USERPROFILE%\.cursor→ Enter.If "Windows can't find": go to
%USERPROFILE%, right-click → New → Folder → name it exactly.cursor(leading dot). Retry.
Inside
.cursor, openmcp.jsonin Notepad. If missing: right-click empty area → New → Text Document → rename tomcp.json(click Yes to the extension warning).Can't see
.txt/.jsonextensions? File Explorer → View menu → check File name extensions.
Paste the config block. Replace
ENTER_API_KEYwith your BD API key andhttps://www.your-site.comwith your BD site URL. Save, then fully quit and reopen Cursor.
n8n
✅ MCP Client Tool works — use the SSE transport + our dedicated URL.
n8n's built-in MCP Client Tool node connects to our server and loads every BD tool. Configure like this:
Field | Value |
Server Transport |
|
MCP Endpoint URL |
|
Authentication |
|
Header 1 | Name: |
Header 2 | Name: |
Save the node. Click the Tool dropdown — should populate with every BD tool. Pick any tool, click Execute.
Why "SSE (Deprecated)" and not "HTTP Streamable"?
The MCP spec deprecated SSE in favor of HTTP Streamable
n8n's SSE client works today against our server
n8n's HTTP Streamable client has known upstream bugs we filed
Our server supports BOTH transports — when n8n fixes their HTTP Streamable client, you can switch to
https://brilliantmcp.com(no/ssepath) with Transport =HTTP Streamable. No server changes needed.
Why
https://brilliantmcp.com/sse? The mainbrilliantdirectories.comdomain has zone-level security rules (bot challenges, geo blocks) that protect our marketing site but silently blocked n8n's SSE handshake.brilliantmcp.comis a dedicated zone with no inherited security posture — n8n connects cleanly. It's the single canonical URL for the hosted MCP endpoint.
Don't want MCP? Alternative paths for n8n:
✅ HTTP Request node + OpenAPI import — n8n has native OpenAPI support. Import this spec URL as a custom API:
https://raw.githubusercontent.com/brilliantdirectories/brilliant-directories-mcp/main/mcp/openapi/bd-api.jsonn8n generates a node for every BD operation automatically. Prompts for your BD site URL and API key on import. Every BD operation available, zero MCP protocol involved.
✅ Plain HTTP Request node — point a single HTTP Request node at https://www.your-site.com/api/v2/user/get with header X-Api-Key: ENTER_API_KEY. Chain multiple nodes for workflows touching several BD endpoints. Simplest possible setup.
Want to verify the server is healthy yourself? Install the official MCP Inspector (npx @modelcontextprotocol/inspector) and point it at https://brilliantmcp.com/sse. Inspector is the reference implementation of MCP's client spec.
Make.com
Make.com ships an MCP Client app (currently Open Beta) that connects to remote MCP servers — see Make's MCP Client docs. To connect it to our Worker:
Add the MCP Client module to your scenario, click Create a connection.
Click + New MCP Server (we're not yet on Make's verified-servers list).
URL:
https://brilliantmcp.comAPI Key / Access token: your 32-char BD API key.
Save, then refresh the scenario so Make picks up the new connection.
⚠️ Known limitation as of Make's beta release: the MCP Client UI exposes a single token field. Our Worker requires two custom headers (X-Api-Key AND X-BD-Site-URL). If Make sends only the API key, the Worker will reject with Missing X-BD-Site-URL header. Test the connection before building production scenarios — if it fails, fall back to the HTTP path below.
Fallback path (works today, every BD operation): use Make's standard HTTP module against https://www.your-site.com/api/v2/* with these headers:
X-Api-Key: <your 32-char BD API key>
X-BD-Site-URL: https://www.your-site.comThis hits BD's REST API directly. Skips MCP entirely; every endpoint reachable.
You can also build a custom Make app from our OpenAPI spec for a more polished UX.
Zapier
The "MCP Client by Zapier" app only supports OAuth / Bearer Token — no custom-headers field, so it cannot authenticate against our Worker (same single-token limitation as Make).
Use one of these paths instead:
BD's existing Zapier app (if it covers what you need) — same underlying API, same API key.
Webhooks by Zapier against
https://www.your-site.com/api/v2/*, with Custom HeadersX-Api-Key: <your key>andX-BD-Site-URL: https://www.your-site.com. This hits BD's REST API directly and skips MCP entirely — every BD operation reachable.
Abacus.AI (ChatLLM Agent)
Abacus AI Agent supports MCP servers — both stdio (npm) and remote (URL) — via its Configure MCP page (Agent Settings → MCP Server Config). See Abacus's MCP docs.
✅ Recommended (stdio / npm — passes both credentials reliably): paste this into the MCP Server Config JSON. It runs the package in Abacus's hosted environment and passes your API key + site URL as args, so no custom-headers support is needed.
{
"brilliant-directories": {
"command": "npx",
"args": [
"-y",
"--prefer-online",
"brilliant-directories-mcp@latest",
"--api-key", "ENTER_API_KEY",
"--url", "https://www.your-site.com"
]
}
}Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL. Abacus will query the server and list every BD tool.
🚀 Remote URL (only if your Abacus MCP config accepts custom headers): our Worker needs two headers (X-Api-Key AND X-BD-Site-URL). Abacus's documented remote-server example shows only a url field — if your config also accepts a headers/env block, use:
{
"brilliant-directories": {
"url": "https://brilliantmcp.com",
"headers": {
"X-Api-Key": "ENTER_API_KEY",
"X-BD-Site-URL": "https://www.your-site.com"
}
}
}If Abacus sends only a single token (no second header), the Worker rejects with Missing X-BD-Site-URL header — use the stdio config above instead.
Paste only the server-config JSON, not a
{ "mcpServers": { ... } }wrapper — Abacus expects the inner object. Abacus allows up to 5 servers / 50 active tools; the BD server alone exposes more than 50, so keep other servers light or scope which tools you enable.
curl / Any HTTP Client
Paste these in a terminal (Mac: Terminal.app · Windows: PowerShell). Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL.
Why these examples only need
X-Api-Key(and notX-BD-Site-URL): these calls go DIRECTLY to your BD site (your-site.com/api/v2/...), bypassing the MCP Worker. TheX-BD-Site-URLheader is only needed when calling the hosted Worker athttps://brilliantmcp.com— the Worker uses it to route to the right BD site. When you call your BD site directly, the URL itself IS the routing.
# Verify your API key
curl -H "X-Api-Key: ENTER_API_KEY" https://www.your-site.com/api/v2/token/verify
# List members
curl -H "X-Api-Key: ENTER_API_KEY" https://www.your-site.com/api/v2/user/get?limit=10
# Create a member
curl -X POST -H "X-Api-Key: ENTER_API_KEY" \
-d "email=new@example.com&password=secret123&subscription_id=1&first_name=Jane&last_name=Doe" \
https://www.your-site.com/api/v2/user/create
# Search members (spaces in values need URL-encoding as + or %20)
curl -X POST -H "X-Api-Key: ENTER_API_KEY" \
-d "q=dentist&address=Los+Angeles&limit=10" \
https://www.your-site.com/api/v2/user/search
# Update a member
curl -X PUT -H "X-Api-Key: ENTER_API_KEY" \
-d "user_id=42&company=New Company Name" \
https://www.your-site.com/api/v2/user/updateWhat you can ask the AI
Once connected, your AI can read AND write to your BD site. Example prompts:
"List all members who signed up this month"
"Create a new member named Jane Doe with email jane@example.com"
"Add a blog post by member 42 titled 'Welcome to our directory'"
"Show me unpaid invoices"
"Add Jane to the VIP tag"
"Set up a new landing page at /promo with a hero section"
Comprehensive coverage across members, posts, leads, reviews, pages, forms, menus, widgets, email templates, tags, redirects, smart lists, categories, membership plans, and more.
What success looks like: the AI returns the data you asked for, or confirms the action with a new ID. What failure looks like: the AI says "I don't have access to that," "no tools available," or "unknown function." → jump to Troubleshooting.
⚠️ The AI can also DELETE and MODIFY live data. Writes go directly to your live site — no undo. Before running bulk or destructive operations, test on ONE record first. Consider a backup. If unsure, ask the AI to preview (list/show) before it acts.
Growth-automation skill (bd-skill-content)
This repo ships a companion Claude Skill that uses the BD MCP to do high-leverage content workflows for you: researching public sources, manufacturing SEO-rich posts, deduplicating, and posting to your BD site.
Download
Get the latest skill zip from the GitHub Releases page: bd-skill-content.zip.
Install
Open claude.ai → Settings → Customize → Skills → Upload Skill.
Upload the
bd-skill-content.zipfile you downloaded.Ensure your BD MCP is connected (either the hosted
https://brilliantmcp.comor the npm-installed local server).Start a chat and tell Claude what you want: "create event posts for upcoming fitness events in Austin."
Content types in v0.1
Events — researches local events from public web sources (chamber sites, tourism boards, civic calendars, public Eventbrite pages, etc.), creates structured event posts with FAQ, internal links to related events, source attribution, and Nominatim-geocoded coordinates.
More content types (jobs, properties, blog, SEO landing pages) coming in future releases. They will share the same shared methodology and ship in the same zip.
Defaults
Drafts by default in autonomous runs (you review before publishing)
Free to run (no API keys, no paid services)
Whitehat scraping (facts only, public pages only, attribution always)
Realistic run time: 30-60 minutes for 10-20 posts
Build from source
The skill source lives in bd-skill-content/. Rebuild the zip yourself:
node scripts/build-skill-zip.js
# Output: bd-skill-content/bd-skill-content.zipAll built on the same foundation: shared research methodology, quality gates, dedup, anti-slop writing voice, whitehat sourcing.
Updates are automatic
Once set up, you get new MCP versions automatically the next time you fully quit and reopen your AI app.
Troubleshooting
Verify your setup with one command. Paste in a terminal (Mac: Terminal.app · Windows: PowerShell). Replace ENTER_API_KEY with your BD API key and https://www.your-site.com with your BD site URL:
npx --prefer-online brilliant-directories-mcp@latest --verify --api-key ENTER_API_KEY --url https://www.your-site.comPrints OK if credentials work, FAIL with the error otherwise. Good first step for any connectivity issue.
Debug mode — see exactly what's happening:
npx --prefer-online brilliant-directories-mcp@latest --debug --verify --api-key ENTER_API_KEY --url https://www.your-site.comLogs every API request and response to stderr (your API key is automatically redacted), then exits. Useful when something isn't working and you want to share output with BD support.
Drop
--verifyto start the full MCP stdio server with debug logging — it will appear to hang in a regular terminal because MCP servers run forever over stdio, waiting for an AI client to connect. Use--debug --verifyfor one-shot debugging from a shell.
Common issues:
AI says "no tools" or "I don't have access" — you didn't fully quit and reopen your AI app after setup. Fully quit (Mac
Cmd+Q; Windows right-click taskbar → Quit), then reopen.401 Unauthorized— API key is wrong, revoked, or lacks permission for the endpoint. Regenerate in BD Admin → Developer Hub.403 API Key does not have permission to access this endpoint— this specific endpoint isn't granted on your key. Edit the key in BD Admin → Developer Hub and enable the missing endpoint (the error names it).404 Not Found— your site URL is wrong. Must includehttps://and NO trailing slash, and match the canonical form your site responds at (includewww.if your site uses it). Correct:https://www.mysite.com. Wrong:mysite.com,https://mysite.com/, orhttps://mysite.comwhen the site actually serves atwww.mysite.com.429 Too Many Requests— rate limit hit (100 req/60s default). Wait 60 seconds, or email BD support to raise your site's limit up to 1,000/min.Unknown tool(from Claude) — the MCP server didn't load. Fully quit + reopen the AI app first. If still broken, the npx cache has a stale install:Windows PowerShell:
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\npm-cache\_npx"Mac/Linux Terminal:
rm -rf ~/.npm/_npxThen fully quit + reopen. The
-yin your config makesnpxre-download automatically — you do NOT neednpm install -g brilliant-directories-mcp.
npx: command not foundorspawn npx ENOENT— Node.js isn't installed (or your AI app started before Node was installed). Install from nodejs.org, then fully quit and reopen your AI app. Still seeing it? Reboot your computer (rare, but fixes a WindowsPATH-cache issue that occasionally lingers after install).ETARGET No matching version found— your local npm cache is stale. Adding--prefer-onlineto your config args (per the snippets above) prevents this; if your config doesn't have it yet, runnpm cache clean --forceand restart your AI app."not valid MCP server configurations" (Claude Desktop) —
claude_desktop_config.jsondoesn't accepturl-shaped blocks. Use the Advanced (npm/stdio) config from the Claude Desktop section. Windows users on the Microsoft Store version of Claude Desktop should also uninstall and reinstall from claude.ai/download (the Store version sandboxes the config in ways that can break MCP loading silently).
Authentication
Two credentials, sent as HTTP headers on every request. No OAuth, no Bearer tokens, no signing.
Header | Value | Required | Notes |
| your BD API key | Yes | Authenticates the request. Admin → Developer Hub → Generate API Key. |
|
| Yes | Pairs the API key with its BD site. Full canonical URL ( |
Universal MCP Client Reference
Any generic MCP client (LibreChat, custom agents, etc.) asks the same four questions. Use this table to fill any of them in.
Field the client asks for | What to enter |
MCP Server URL / Endpoint URL / Remote Server URL |
|
Transport |
|
Custom / Multiple Headers | Two entries: |
OAuth | Off / No / disabled — we don't use OAuth |
Bearer Token | Leave empty — we don't use Bearer auth |
n8n is the exception. n8n's Streamable HTTP client has upstream bugs, so n8n users must use Transport =
Server Sent Events (Deprecated)+ URLhttps://brilliantmcp.com/sse(with the/ssepath). See the n8n section for the exact field values. Our server supports both transports — n8n just happens to need the legacy one today.
How to tell if any other MCP client will work: the blocker is always "can this client send custom HTTP headers?" If the UI shows a Custom Headers / Multiple Headers / HTTP Headers field, you're good — plug in our two headers. If the UI only offers OAuth or Bearer Token, that client cannot reach our Worker today.
Rate Limits
Default: 100 requests per 60 seconds per API key. On request: up to 1,000 requests per minute — contact the Brilliant Directories support team to have your site's limit raised (any value between 100 and 1,000/min).
The limit is set server-side by BD, not a self-service setting in your admin. If you expect heavy API usage, email BD support before bulk operations and ask for a temporary or permanent increase.
When exceeded, the API returns HTTP 429 Too Many Requests. The MCP server surfaces this as an actionable error for your AI agent — it will know to back off or recommend requesting a higher limit.
Plan bulk operations: if you're asking your agent to import/update hundreds of records, either (a) request a higher limit from BD support first, or (b) tell the agent to pace itself (e.g., "import these 500 members, pausing to respect the 100/min rate limit").
Pagination
All list endpoints support pagination:
Parameter | Description |
| Records per page (default 25, max 100) |
| Cursor token from |
Response includes: total, current_page, total_pages, next_page, prev_page
Filtering
All list endpoints support filtering. Your AI handles the syntax — just ask naturally ("members in Los Angeles added this month", "pages with sale in the title", etc.). If you need to filter via direct HTTP (curl, Postman, Zapier webhooks, etc.), the filter params are property, property_value, and property_operator, repeatable as property[] arrays for multi-condition queries. Full operator reference lives in the MCP tool descriptions + SKILL.md.
Sorting
GET /api/v2/user/get?order_column=last_name&order_type=ASCAvailable Resources
About the
Operationscolumn: short verbs likelist, get, create, update, deletemap to MCP tool names by prefixing the verb to the resource (e.g. Reviews →listReviews,getReview,createReview...). Where the same verb covers multiple resource sub-types (e.g. single-image posts vs multi-image posts share/api/v2/data_posts/and/api/v2/users_portfolio_groups/paths but are distinct tools), the full tool names are spelled out in this table so there's no ambiguity.
Resource | Base Path | Operations |
Brand Kit |
| getBrandKit |
Clicks (Profile Analytics) |
| list, get, create, update, delete |
Data Types |
| list, get, create, update, delete |
Email Templates |
| list, get, create, update, delete |
Form Fields |
| list, get, create, update, delete |
Forms |
| list, get, create, update, delete |
Forms Inbox |
| listFormInquiries, getFormInquiry |
Lead Matches |
| list, get, create, update, delete |
Leads |
| list, get, create, match, update, delete |
Member ↔ Sub Category Links |
| listMemberSubCategoryLinks, getMemberSubCategoryLink, createMemberSubCategoryLink, updateMemberSubCategoryLink, deleteMemberSubCategoryLink |
Membership Plans |
| list, get |
Menu Items |
| list, get, create, update, delete |
Menus |
| list, get, create, update, delete |
Multi-Image Post Photos |
| listMultiImagePostPhotos, getMultiImagePostPhoto, createMultiImagePostPhoto, updateMultiImagePostPhoto, deleteMultiImagePostPhoto |
Multi-Image Posts |
| listMultiImagePosts, getMultiImagePost, createMultiImagePost, updateMultiImagePost, deleteMultiImagePost, getMultiImagePostFields |
Post Types |
| list, get, update, delete, custom_fields |
Redirects (301) |
| list, get, create, update, delete |
Reviews |
| list, get, create, update, delete |
Single-Image Posts |
| listSingleImagePosts, getSingleImagePost, createSingleImagePost, updateSingleImagePost, deleteSingleImagePost, getSingleImagePostFields |
Site Info |
| getSiteInfo |
Smart Lists |
| list, get, create, update, delete |
Sub Categories |
| listSubCategories, getSubCategory, createSubCategory, updateSubCategory, deleteSubCategory |
Tag Groups |
| list, get, create, update, delete |
Tag Relationships |
| list, get, create, update, delete |
Tag Types |
| list, get |
Tags |
| list, get, create, update, delete |
Top Categories |
| listTopCategories, getTopCategory, createTopCategory, updateTopCategory, deleteTopCategory |
Unsubscribe |
| list, get, create, update, delete |
User Metadata |
| list, get, update, delete |
User Photos |
| list, get, create, update, delete |
Users/Members |
| list, get, create, update, delete, search, login, transactions, subscriptions, fields |
Web Pages (SEO/static) |
| listWebPages, getWebPage, createWebPage, updateWebPage, deleteWebPage |
Website Settings |
| refreshSiteCache |
Widgets |
| list, get, create, update, delete, render |
Field Discovery
Some endpoints support dynamic field discovery:
# Get all available user fields
curl -H "X-Api-Key: ENTER_API_KEY" https://www.your-site.com/api/v2/user/fields
# Get custom fields for a specific post type
curl -H "X-Api-Key: ENTER_API_KEY" https://www.your-site.com/api/v2/data_posts/fields?form_name=my-formStable asset URLs
For tools that import specs by URL (ChatGPT Actions, n8n, Postman):
https://raw.githubusercontent.com/brilliantdirectories/brilliant-directories-mcp/main/mcp/openapi/bd-api.jsonSecurity
API keys are never embedded in the package
All requests go directly from the user's machine to their BD site
No data passes through third-party servers
API key permissions control which endpoints are accessible
Treat your API key like a password
FAQ
Does this cost anything? The MCP server is free (MIT license, open source). Your AI agent's subscription (Claude, Cursor, etc.) is separate. API calls to your BD site count against your site's rate limit but don't cost extra.
Is my data sent to Anthropic / OpenAI / third parties? Your BD site data passes from your BD site directly to the AI client on your machine, then to the AI provider you use (Anthropic, OpenAI, etc.) as part of your conversation with the AI. The MCP server itself doesn't relay data anywhere else — no telemetry, no third-party servers in between.
Can I connect more than one BD site?
Yes. Add multiple entries under mcpServers with different names (e.g. bd-site-a, bd-site-b), each with its own API key and URL. Your AI will see tools from both.
Can my team share one key, or should everyone have their own? Each person should generate their own API key (BD Admin → Developer Hub). Keys are per-user so revoking one doesn't break anyone else.
How do I disconnect / remove the MCP?
Claude Code:
claude mcp remove brilliant-directoriesCursor / Windsurf / Cline: delete the
brilliant-directoriesentry from the MCP config JSON file, save, fully quit and reopen the app.
How do I undo something the AI did?
BD's API doesn't have a universal undo. For members, prefer updateUser active=3 (Canceled) over deleteUser — it's reversible. For destructive operations, back up first or test on one record.
Can I try this safely on a test site before production? Yes. Generate a separate API key on a BD staging/dev site, set that URL + key in your MCP config. Once you trust the workflow, switch to production.
How do I know which endpoints my API key has permission for?
Check your key in BD Admin → Developer Hub. When you hit 403 API Key does not have permission to access this endpoint, the error names the denied endpoint — enable it on the key, save, retry.
Support
Bug reports / feature requests: https://github.com/brilliantdirectories/brilliant-directories-mcp/issues
BD Support: https://support.brilliantdirectories.com
API Docs: https://support.brilliantdirectories.com/support/solutions/articles/12000108045
Available Tools
171 toolscreateCategoryTreeA
Create a full category taxonomy (tops + subs + sub-subs) in one call. - Wrapper-native synthetic tool. Creates member categories — top categories, their sub-categories, and third-tier sub-sub-categories — in one call.
Use when: creating a category at any level, including adding to a structure that already exists. Use createTopCategory or createSubCategory only for a single category that needs desc, keywords, icon, sort_order, lead_price, image, master_id, or a filename other than the default slug set at create time. For every other category create, use createCategoryTree.
Required: groups — an array of { top_category, sub_categories }, 25 entries maximum per call.
Send the whole taxonomy in one call. A top category named again is matched by name and reused, so a later call adds to it. Never issue two calls concurrently: a top category named in both is created twice, because BD's category list does not reflect a row written by a call still in flight. A second call is safe once the first call's response has returned.
The three shapes, all the same input:
New top plus its subs:
{ top_category: "Surf Shops", sub_categories: ["Surfboards", "Wetsuits"] }Subs under a top that already exists: the same shape, naming that top. It is reused; only the listed subs are added, and existing subs are left alone.
Top only: omit
sub_categoriesor pass[].
Third tier — Parent=>Child: a sub_categories entry containing => creates Child under Parent, and Parent under the group's top_category. An existing Parent is reused. Exactly one => per entry: "Surf Camps=>Kids Camps". A=>B=>C is rejected — send A=>B in this call, then "B=>C" in a second call naming the same top_category once this call's response has returned.
Sub-category names must not contain commas — this tool writes them through BD's comma-separated services field, which would split one name into several. Replace the comma with a hyphen. To create the parts as separate categories instead, send each as its own sub_categories entry. One comma anywhere in sub_categories rejects the call. Top category names may contain commas.
Nothing is written until every name validates. Writing itself is not atomic: a failure part-way leaves earlier groups created. groups_completed and each group's top_status / sub_status name exactly what landed — read them before retrying. Re-send a group only when its top_status is error, or its sub_status is error or not attempted; created, existing, and none requested all mean that part landed.
Building sub-categories requires a temporary member, which this tool creates and deletes for you. temp_member reports what happened to it; the categories are unaffected either way.
See also: createTopCategory, createSubCategory, listTopCategories, listSubCategories.
Returns: { status, message: { groups_requested, groups_completed, sub_categories_created, temp_member, groups: [{ top_category, profession_id, top_status, sub_categories, sub_status }] } }. top_status is created, existing, or error. sub_status is created, error, none requested, or not attempted. sub_categories_created is the total across all groups — report it rather than counting names. temp_member is one of: temporary member deleted — cleanup succeeded; not needed (no sub-categories requested); no temporary member was created — no sub-category was written and every sub_status is error; or a user_id — sub-categories were written but cleanup failed, so pass that id to deleteUser. Each group carries the resolved profession_id, ready for updateUser.profession_id. Sub-category ids are not returned — read them with listSubCategories filtered on that profession_id before assigning members via updateUser.services or createMemberSubCategoryLink.
| Name | Required | Description | Default |
|---|---|---|---|
| groups | Yes | Category groups. Each item: `{ "top_category": "Surf Shops", "sub_categories": ["Surfboards", "Surf Camps=>Kids Camps"] }`. Name an existing top category to add to it. `sub_categories` is optional — omit for a top category alone. Maximum 25 entries per call; send further groups in a later call, where existing top categories are matched by name and reused. | |
| subscription_id | No | Membership plan id for the internal temporary member. Optional — the wrapper resolves the site's first plan when omitted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by explaining non-atomic behavior, validation before writes, the temporary member lifecycle, concurrency hazards, comma restrictions, and detailed status reporting. The annotations already indicate this is a non-read-only, non-idempotent operation, and the description expands on those traits extensively without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but densely packed with behavior the agent must know to call the tool safely and correctly. It is front-loaded with the core purpose and 'Use when' guidance, then progresses to examples, validation rules, failure semantics, and return values, with each section earning its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and absence of an output schema, the description fully compensates by documenting the return structure, all status values, temp_member outcomes, retry guidance, and how to read sub-category ids afterward. It also cross-references the relevant sibling tools, making the definition complete for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already covers 100% of the parameters, the description adds substantial operational meaning: the Parent=>Child syntax, the 25-entry maximum, the reuse semantics for existing top categories, the no-comma rule, and concrete input shapes. This goes far beyond the schema's field-level documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: creating a full category taxonomy (top, sub, and sub-sub categories) in one call. It distinguishes itself from the sibling tools createTopCategory and createSubCategory by explaining that those are only for single categories with specific fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit 'Use when' guidance and explicitly names the alternatives (createTopCategory, createSubCategory) and the conditions under which to use them instead. It also covers operational usage constraints like avoiding concurrent calls and sending the whole taxonomy in one call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createClickA
Create a click record - Create a new click record. Writes live data.
Use when: replicating a click event from an external source (e.g., tracking clicks on a mirrored profile page on another domain). Usually not needed - BD auto-records clicks on its own surfaces.
Required: user_id, click_type, click_name, click_from, click_url.
Parameter interactions:
user_id- the member profile being trackedclick_type-link(external),phone(reveal), oremail(reveal)click_from- source surface:profile_pageorsearch_resultsclick_url- the URL that was clicked
See also: updateClick (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | ||
| click_url | Yes | ||
| click_from | Yes | Full URL of the page where the click originated (HTTP referer). Free-form URL string; empty allowed when no referer header is present (e.g. direct hits, bot traffic). NOT an enum. | |
| click_name | Yes | ||
| click_type | Yes | Free-form label for the click target. NOT an enum — BD doesn't normalize and site owners create custom labels via click-tracking widgets. Common BD-canonical values (mixed casing intentional, BD does NOT normalize): `View Post`, `Profile`, `Phone Number`, `website`, `Facebook`, `Contact Form`, `Search Results`, `booking_link`, `Instagram`, `Post Link`, `LinkedIn`, `YouTube`, `Blog`, `Twitter`, `Google`, `Pinterest`. Reuse the exact casing of the value you're tracking against — `Profile` and `profile` produce two distinct rows in analytics. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context (writes live data, external replication use case) beyond annotations. However, it contradicts the schema by suggesting click_type has limited values (link/phone/email) while schema says free-form, reducing accuracy.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections, front-loaded purpose, and no wasted sentences. It efficiently conveys usage, requirements, and parameter details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 required params and no output schema, the description covers the use case, parameter interactions, and alternates. Missing details on response or side effects, but adequate for a creation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 40% schema description coverage, the description attempts to add meaning for all 5 parameters, but for click_type and click_from it provides restrictive interpretations that conflict with the schema's free-form nature. It adds some value but with inaccuracies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool creates a click record and writes live data. It distinguishes from the sibling 'updateClick' by mentioning it in the 'See also' section, providing differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use (replicating external click events) and when not to (BD auto-records). It also lists required parameters and references an alternative tool (updateClick).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createDataTypeA
Create a data type - Define a new content-type template. Only do this when the user explicitly wants a new post type - most sites come pre-configured with the types they need.
Use when: adding a new data-type classifier. Rare - usually preconfigured.
Required: category_name, category_active.
Pre-check before create: BD does NOT enforce uniqueness on category_name or the derived system_name. Duplicate data types corrupt the post-type admin UI, break post-listing widgets that bind by name, and risk posts landing under the wrong type. Do a server-side filter-find: listDataTypes property=category_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 row = taken. Do NOT paginate unfiltered lists - filtered lookup is one tiny response. If taken: reuse via updateDataType, OR ask the user, OR pick an alternate category_name and re-check. Never silently create a duplicate.
Enums: category_active: 1=active and available for members to use, 0=inactive; limit_available: 0, 1.
See also: updateDataType (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| category_name | Yes | Display name for this content type (e.g. "Single Photo Post", "Multi-Photo Post", "Video Post") | |
| category_active | Yes | 1 = active and available for members to use; 0 = inactive | |
| limit_available | No | 1 = membership-plan posting limits apply to this data type; 0 = no per-plan limits |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals that the system does NOT enforce uniqueness on category_name, leading to potential corruption. It details the required pre-check and consequences of duplicates. This adds significant behavioral context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (Use when, Required, Pre-check, Enums, See also). It is slightly verbose but every sentence provides value. Front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully covers input parameters, behavioral requirements (duplicate checking), and edge cases (reuse, ask, alternate name). References sibling tool updateDataType. Complete for agent decision-making.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning: it lists required parameters, explains enum values for category_active and limit_available, and provides pre-check context that enhances parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Create a data type - Define a new content-type template.' It specifies that this is for new post types and that most sites are pre-configured, distinguishing it from related tools like updateDataType.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Only do this when the user explicitly wants a new post type.' Provides a pre-check to avoid duplicates, with clear steps and alternatives (reuse via updateDataType, ask user, pick alternate name). Includes when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createEmailTemplateA
Create an email template - Create a new emailtemplate record. Writes live data.
Use when: adding a new transactional/marketing template. Rare - most BD email templates are built into the admin UI.
Required: email_name.
Pre-check before create: BD does NOT enforce uniqueness on email_name. Duplicates cause the wrong template to fire on transactional triggers. Do a server-side filter-find: listEmailTemplates property=email_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 row = taken. Do NOT paginate unfiltered lists looking for the name - on sites with many templates that burns rate limit for nothing. If taken: reuse via updateEmailTemplate, OR ask the user, OR pick an alternate email_name and re-check. Never silently create a duplicate.
Enums: signature: 0/1; notemplate: default 2 (template + logo center); other values 0 (logo left), 3 (logo right), 4 (template, no logo), 1 (plaintext-only, no wrapper); category_id: default 0 (My Saved Templates) — 1/3/4/15/16 are system-populated, do NOT create under them; unsubscribe_link: 0/1.
Parameter interactions:
email_subjectandemail_bodycan use template tokens (e.g.%%%website_name%%%, recipient field tokens)email_bodysupports HTML
See also: updateEmailTemplate (modify existing).
On create: email_name is the only required field. Subject and body are optional at create time - you can create a template stub and fill in email_subject / email_body via updateEmailTemplate later. This lets you programmatically scaffold templates before customizing them via the admin UI.
| Name | Required | Description | Default |
|---|---|---|---|
| website | No | 0=platform-wide | |
| priority | No | ||
| triggers | No | Comma-separated events | |
| signature | No | Append the site's default email signature to this template. Default `0`. Set to `1` only when the user explicitly asks to include the site signature; BD appends it automatically at send time. | |
| email_body | No | Content-only HTML — BD wraps it in the document scaffold. Open with any content tag (`<p>`, `<table>`, `<div>`, `<h1>`/`<h2>`, `<img>`, etc.). Inline `style=""` only — no `<style>` blocks (Outlook strips them) and no `class=""` (emails have no site stylesheet). Gradients need a fallback `background-color:` first. Verify image URLs return 200 before embedding when possible. Supports `%%%merge_tag%%%` tokens and `[widget=Name]` shortcodes. See **Rule: Email template recipe**. | |
| email_from | No | ||
| email_name | Yes | Internal name for this email template (used by `[email-template name=...]` references and admin lookups). **Lowercase, hyphens, no spaces** (e.g. `welcome-email`, `password-reset`, `lead-notification-admin`) — see **Rule: Email template recipe**. | |
| email_type | No | ||
| notemplate | No | Template + logo wrapper mode. `0` = template + logo left; `2` = template + logo center (default — use unless user specifies otherwise or it's a plaintext email); `3` = template + logo right; `4` = template, no logo; `1` = no template or logo (plaintext-only). When this is anything other than `1`, BD's global template already wraps `email_body` in a 600px-wide constraining table — do NOT add your own outer max-width wrapper in that case. | |
| category_id | No | Template category. On `create`: default to `0` (My Saved Templates); other values (`1`/`3`/`4`/`15`/`16`) are system-populated — do NOT create under them. `update` is unrestricted in any category. | |
| content_type | No | ||
| email_subject | No | Supports merge tags | |
| unsubscribe_link | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Warns that BD does not enforce uniqueness on email_name, describes enum side-effects, optional fields at create, and HTML wrapping behavior. No contradiction with annotations (readOnlyHint=false). Adds substantial behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections (use when, pre-check, enums, interactions, see also). Slightly verbose but justified by complexity (13 params). Front-loaded with purpose and usage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers most aspects: required params, enums, pre-flight check. Missing return value description and error conditions. With no output schema, some information gap, but still comprehensive overall.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond schema: explains enum values (e.g., notemplate modes, category_id restrictions), parameter interactions (tokens in subject/body, HTML support), and naming rules for email_name. Schema coverage 62%, description compensates richly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States verb+resource: 'Create an email template - Create a new emailtemplate record.' Distinguishes from siblings by noting rarity and referencing updateEmailTemplate as alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: adding a new transactional/marketing template.' Provides a detailed pre-check procedure to avoid duplicates, recommends updateEmailTemplate if name is taken, and includes 'See also: updateEmailTemplate' for modification.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createFormA
Create a form - Create a new form record. Writes live data. Add fields afterward via createFormField.
Required: form_name, form_title, form_action, form_layout, form_table, form_url, form_class, table_index, form_action_div, form_email_on, form_success_message.
Class selection — see Rule: Forms § Form classes before picking form_table. Follow § Form-level recipe for the canonical creation recipe.
Mandatory form_name pre-check per Rule: Pre-check natural keys — BD does NOT enforce uniqueness; duplicate form_name produces ambiguous [form=…] shortcode resolution.
Wrapper-enforced refusal: form_action_type=redirect AND empty form_target → call refused (see Rule: Forms § Wrapper-enforced invariants).
See also: updateForm, createFormField, listFormFields.
Returns: { status: "success", message: {...createdRecord}, _admin_edit_url: "..." }. _admin_edit_url is a centralized-admin deep-link to the Form Builder editor for this form_name — surface it to the user so they can jump straight to the admin edit screen for the form just created.
| Name | Required | Description | Default |
|---|---|---|---|
| form_url | Yes | Save Action URL - overrides default `action=` on the rendered form. **Required exact value for every form an agent creates:** `/api/widget/json/post/Bootstrap%20Theme%20-%20Function%20-%20Save%20Form`. This is the BD Save Form widget endpoint; without it, submit wiring breaks. Do NOT decode the `%20` - BD needs the URL-encoded form verbatim. | /api/widget/json/post/Bootstrap%20Theme%20-%20Function%20-%20Save%20Form |
| form_name | Yes | System slug (lowercase alphanumerics + hyphens + underscores; NO spaces). Hyphens and underscores are NOT interchangeable — the stored value is the lookup key, byte-exact, in `[form=<form_name>]` shortcodes and on `createFormField` parent references. Immutable post-create. Must be unique per site. For the human-readable nickname use `form_title`. Example: `form_name=strength_blueprint_ebook`. | |
| form_class | Yes | CSS class applied to every field — UI consistency insurance. Canonical: `form-control`. Per-field `input_class` layers extra CSS on top. | form-control |
| form_table | Yes | Database table the form submissions post into. `website_contacts` = Standard public class (default for ALL public capture; free-create with this tool). `leads` = Lead-saving class (BD's Get-Matched member-routing ONLY) — never free-create from scratch; clone `bootstrap_get_match` per **Rule: Forms** § Lead-match special case. `users_data` = Member-dashboard class — never free-create from scratch; clone-and-assign one of the 3 canonical dashboard forms per § Member-dashboard special case. See § Form classes for the picking rule. Once set on create, treat as immutable. | website_contacts |
| form_title | Yes | Human-friendly nickname (free text — spaces and any characters allowed). Surfaced in admin UI and form-listing screens. Example: `form_title="Strength Blueprint Ebook"`. NOT the same as `form_name` (the system slug). | |
| form_action | Yes | **post** = form submits via POST body (default, most forms). **get** = form submits as URL query string (use for bookmarkable search/filter forms). | post |
| form_layout | Yes | **bootstrapvertical** = Labels Above Inputs (canonical default). **bootstrap** = Labels Left of Inputs (canonical default for Member-dashboard class — `form_action_type=default`). User override wins in either case. | bootstrapvertical |
| form_target | No | Destination URL. **Required when `form_action_type=redirect`** — wrapper refuses the call without it. Full URL with `https://`, e.g. `https://mysite.com/thanks`. | |
| table_index | Yes | Primary key column matching `form_table`: `website_contacts` → `ID`, `leads` → `lead_id`, `users_data` → `user_id`. Required exact match — BD uses this to look up individual submissions. | ID |
| form_email_on | Yes | Send admin notification email on each submission. `0` = OFF (default when an agent creates a form - safer: spammy forms won't flood the admin inbox). `1` = ON. Admin UI defaults this to ON; agents default it to OFF unless user explicitly requests notifications. | |
| form_action_div | Yes | Target element ID (CSS selector including `#`) swapped in the DOM on form submit by the `widget` (Success Pop-Up) action type; harmlessly ignored on `notification` / `redirect`. **Always send `#main-content`** unless the user explicitly names a different target — it's the canonical default for every `form_action_type`. Must include leading `#`. | #main-content |
| form_action_type | No | Post-submit behavior: - `widget` = Success Pop-Up (agent default). - `notification` = Inline Success Alert Banner. - `redirect` = Redirect to URL (wrapper-enforced: `form_target` required, see `form_target` field). - `default` = Member-dashboard class (admin-clone-only; do not create from scratch). - `""` (empty) = no post-submit behavior (valid only for internal/programmatic forms, NOT public-facing). For public-facing values (`widget` / `notification` / `redirect`), Button-last is the agent-side tail-pattern responsibility (NOT wrapper-enforced). See **Rule: Forms** § Form-level recipe. | widget |
| form_email_recipient | No | Comma-separated email list to receive submission notifications. Used only when `form_email_on=1`. Empty = site default admin recipient. | |
| form_success_message | Yes | Post-submit success copy. Canonical default for Standard public AND Lead-saving classes: `Your Message has been Received`. Override only on explicit user request. Applies to `form_action_type` ∈ {`widget`, `notification`, `redirect`}; not used by `default` (member-dashboard) class. | Your Message has been Received |
| label_to_placeholder | No | Form-level toggle. When `"1"`, BD collapses each field's `field_text` (label) into placeholder text inside the input — saves vertical space, removes the explicit `<label>` element above each field. Per-field `field_placeholder` is overridden when this is on. Default `"0"`. | 0 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnly=false, openWorld=true), the description discloses that the tool 'Writes live data', flags BD's lack of uniqueness enforcement on form_name causing ambiguous shortcodes, and reveals a wrapper-enforced refusal when form_action_type=redirect with empty form_target. These are actionable behavioral constraints not present in structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured, using bolded required fields, rule references, and a clear return contract. Each section contributes to parameter constraints or usage context, though the heavy reliance on external 'Rule: Forms' references and the sheer length prevent a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 15 parameters and no output schema, the description fully compensates by defining the return shape ({status, message, _admin_edit_url}) and instructing the agent to surface _admin_edit_url to the user. It also covers prerequisites, exclusions, and wrapper enforcement, making the tool's behavior predictable in context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 15 parameters. The description adds extra semantic value by highlighting form_name uniqueness pre-checks, form_target's conditional requirement based on wrapper rules, and form_table's clone-vs-create guidance. This exceeds the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Create a form - Create a new form record') and immediately distinguishes itself from the later step 'Add fields afterward via createFormField'. It also lists sibling tools (updateForm, createFormField, listFormFields) in a 'See also' section, making differentiation clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use and when-not-to-use guidance: it instructs agents to add fields via createFormField, warns against free-creating leads and users_data forms ('never free-create from scratch'), and directs consultation of 'Rule: Forms § Form classes before picking form_table'. It also names alternatives via 'See also'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createFormFieldA
Create a form field - Create a new formfield record. Writes live data.
Required: form_name, field_name, field_text, field_type, field_order.
Canonical field_name for form_table=website_contacts: yourname / inquiry_email / phone / comments (NOT name / email / message — those persist but don't surface in the admin inbox columns). Anything else = custom field_name. Full table at Rule: Forms § Form classes.
See Rule: Forms § Field anatomy for field shape, view-flag defaults, validators, and the canonical json_meta skeleton. § Form-level recipe covers the tail pattern. § Lead-match / § Member-dashboard cover special-case forms.
Wrapper-enforced refusals: (1) field_required=1 with field_type ∈ {HoneyPot, HTML, Tip, Button} — Hidden is allowed. (2) field_type not in the canonical enum (strict case match; textarea is the lone lowercase value). (3) field_type=Hidden with empty field_name or empty field_text. (4) Non-binary value on any of field_required / field_input_view / field_display_view / field_email_view / field_search_view / field_grid_view / field_input_view_admin_only (empty / omitted accepted — BD applies per-field defaults).
Agent pre-checks (NOT wrapper-enforced): field_name uniqueness within form, single submit element per form. See Rule: Forms § Wrapper-enforced invariants → Agent-side responsibilities.
See also: updateFormField, listFormFields.
| Name | Required | Description | Default |
|---|---|---|---|
| form_name | Yes | Parent form slug | |
| json_meta | No | JSON-stringified per-field metadata blob (UI rendering + validator config). See **Rule: Forms** § Field anatomy → `json_meta` for the canonical skeleton. Pass the full skeleton even when unused; BD's admin form-builder writes all keys. Validators in `field_validate.validators` only fire when `field_validator_enabled` is `"1"`. | |
| field_name | Yes | Internal system key for this field. **Underscores only, no spaces** - e.g. `first_name`, `company_email`. Used as the HTML `name` attribute. | |
| field_text | Yes | Public-facing display label shown to the user. Free-form text - e.g. "First Name", "Your Email Address". | |
| field_type | Yes | Form field type. Copy spelling exactly — most are TitleCase but `textarea` is lowercase. Grouping + use cases at **Rule: Forms** § Field anatomy → Valid field_type values. | |
| field_ldesc | No | Helper text rendered under the input field. Use for instructions / format hints (e.g. "Use international format"). | |
| field_order | Yes | Display position (lower = earlier). New forms: multiples of 10 (10, 20, 30…), security tail included. Adding to an existing form: continue its pattern — don't renumber unrelated fields. | |
| input_class | No | HTML `class=` attribute on the rendered input. **Required for `field_type=Button`** - without it, submit button renders unstyled. Canonical Button pattern: `btn btn-lg btn-block <variant>` where `<variant>` is a Bootstrap button class (`btn-primary`/`btn-secondary`/`btn-danger`/`btn-success`/`btn-warning`/`btn-info`/`btn-dark`) or a custom site class. Example: `btn btn-lg btn-block btn-secondary`. Optional on non-Button fields. | |
| default_value | No | Prefilled value the field loads with on render. Accepts a static value OR PHP (e.g. `<?php echo date('Y-m-d'); ?>`) — BD evaluates at render time on any field_type. | |
| field_options | No | For `field_type` ∈ {`Radio`, `Checkbox`, `Select`}: `system_name=>label,system_name=>label,...`. LHS submitted value, RHS displayed text. Comma and `=>` are reserved separators. `%%%token%%%` translations supported. Silently ignored on other field types. | |
| field_required | No | `0` or `1`. Forbidden when `field_type` ∈ {`HoneyPot`, `HTML`, `Tip`, `Button`} — wrapper refuses these combinations because the requirement can't be satisfied at submit. `Hidden` is allowed (its value comes from `field_text`). | |
| field_grid_view | No | Table View flag — value renders in admin-dashboard / front-end data tables. Schema default `1`; send `0` to hide. | |
| field_email_view | No | Include value in notification emails. Binary `0`/`1`. | |
| field_input_view | No | Binary `0`/`1`. For readonly behavior, add the `readonly` CSS class to `input_class` (e.g. `form-control readonly`); do NOT use `field_input_view=2`. | |
| field_placeholder | No | ||
| field_search_view | No | Lead Previews flag — value visible in lead-preview cards before purchase. Applies to forms with `form_table=leads`. Schema default empty (treat as `0`); send explicitly when overriding. | |
| field_display_view | No | Show submitted value on front-end record-detail pages. Binary `0`/`1`. | |
| field_input_view_admin_only | No | Admin-only render flag. When `1`, field renders only when an admin is logged-in on the front end with admin-view enabled; members never see it. Use on `form_action_type=default` member-account forms. Default `0`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations (readOnlyHint=false, etc.), the description adds extensive behavioral context: 'Writes live data', detailed 'Wrapper-enforced refusals', and 'Agent pre-checks'. This goes well beyond annotations to fully disclose validation rules and side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed and well-organized with sections, but it is lengthy due to extensive references and examples. While structured, it could be more concise for efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 18 parameters, no output schema, and complex enums, the description is highly complete. It covers required fields, validation rules, real-world examples, and references to rules. Agent pre-checks and wrapper-enforced refusals ensure agents have full context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 94% schema description coverage, the baseline is high. The description adds value by clarifying canonical field names, input_class requirements, and refusals. It provides examples and rule references, enhancing understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Create a form field - Create a new formfield record. Writes live data.' It clearly identifies the resource and action. Mentioning sibling tools (updateFormField, listFormFields) further distinguishes its specific purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description lists required parameters and provides canonical examples. It references rules and sibling tools, offering context on when to use. However, it lacks explicit 'when not to use' or alternative conditions, so it's slightly below a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createLeadA
Create a lead - Create a new lead record. Writes live data.
Use when: importing leads from an external form, CSV, or web-scrape. Default is SILENT - no notification emails fire unless you pass send_lead_email_notification=1, and no member routing happens unless you pass auto_match=1 (inline) or call matchLead afterward. top_id (category) is required - look it up via listTopCategories.
Required: lead_name, lead_email, lead_phone, lead_message, lead_location, top_id.
Parameter interactions:
top_id- category ID; discover vialistTopCategoriesAll 6 required fields (
lead_name,lead_email,lead_phone,lead_message,lead_location,top_id) must be supplied togetherResponse includes
lead_idANDtoken- token may be needed for customer-facing URLsAfter creating, call
matchLeadto trigger member notifications
See also: updateLead (modify existing).
Operational rules (from BD support article 12000091106):
send_lead_email_notification=1- activates lead email notifications to the site admin and/or matched members. Default is off: leads created via API are silent unless this flag is set. For the full auto-matching flow (finds members by category/location and emails them), callmatchLeadseparately after creating the lead (or passauto_match=1on this call to run inline).
Targeting specific members (override auto-match): set users_to_match to a comma-separated list of member IDs or emails (e.g. 6099,6100 or user1@example.com,user2@example.com, mixed OK). This BYPASSES the normal category/location/service-area matching and routes the lead to ONLY those members. Typically paired with auto_match=1 (to run the match step inline) and send_lead_email_notification=1 (to fire the matched-member email). Common pattern when an external system already knows who should receive the lead.
| Name | Required | Description | Default |
|---|---|---|---|
| top_id | Yes | Top category ID. Discover via `listTopCategories`. | |
| lead_name | Yes | Submitter's full name. | |
| auto_match | No | Set to `1` to run the match step inline during create (equivalent to calling `matchLead` immediately after). Default `0` = no match step fires. When combined with `users_to_match`, the match step still fires but the category/location/service-area matching ALGORITHM is bypassed — the lead routes ONLY to the specified members. | |
| lead_email | Yes | Submitter email address. | |
| lead_phone | Yes | Submitter phone number. | |
| lead_message | Yes | Submitter's detailed request — what they typed describing their needs. | |
| lead_location | Yes | Geocoded location string. BD computes the derived geocode columns (`lat`/`lng`/bounding box/`country_sn`/`adm_lvl_1_sn`/`location_type`) from this. | |
| users_to_match | No | **ADVANCED - OVERRIDES auto-match.** Comma-separated list of `user_id` values OR member email addresses (mixable) to route this lead to directly. When set, BD skips normal category/location/service-area auto-matching and routes ONLY to these members. Examples: `239` | `6099,6100` | `user1@example.com,user2@example.com` | `239,user1@example.com`. Typically paired with `auto_match=1` (triggers match inline) AND `send_lead_email_notification=1` (fires matched-member email - without the flag, matches record but no email sends). | |
| send_lead_email_notification | No | Set `1` to fire lead notification emails on create. Default `0` - API-created leads are silent. - With `auto_match=1` or `users_to_match` populated -> matched-member notification fires (if this flag = `1`) - Without a match step -> only admin notification fires (if configured) **For matched-member notifications:** combine this flag with a matching trigger (`auto_match=1` and/or `users_to_match`) - neither alone is sufficient. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are readOnlyHint=false (write operation) and destructiveHint=false (not destructive). The description adds: 'Writes live data', default silent behavior (no notifications unless flags), no automatic member routing without auto_match or matchLead, response includes lead_id and token, and operational rules from support article. This goes well beyond annotations, providing essential behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is long but well-structured with headings, bullet points, and clear sections. It front-loads the core purpose and usage, then dives into details. Every sentence adds value—no fluff. The structure aids readability for an AI agent parsing instructions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 9 parameters, 2 enums, no output schema, and complex workflow (notifications, matching, member overrides), the description is remarkably complete. It covers operational rules, parameter interactions, response fields (lead_id, token), recommends sibling tools (listTopCategories, updateLead, matchLead), and even references a support article. No gaps identified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, yet description adds substantial meaning: explains default values (0 for flags), parameter interactions (auto_match and users_to_match combinations), and patterns (e.g., 'Typically paired with auto_match=1 AND send_lead_email_notification=1'). It clarifies that required fields must be supplied together. Description compensates fully despite schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description starts with 'Create a lead - Create a new lead record. Writes live data.' which clearly states the verb (create) and resource (lead). It distinguishes from siblings like updateLead and createLeadMatch by explaining the default silent behavior and the optional matching workflow. The purpose is specific and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description explicitly states when to use: 'importing leads from an external form, CSV, or web-scrape.' It explains default silent mode, when to pass flags (send_lead_email_notification, auto_match), and references sibling tool matchLead. It does not explicitly say when NOT to use, but context is clear enough. A slight improvement would be an explicit contraindication.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createLeadMatchA
Create a lead match - Create a new leadmatch record. Writes live data.
Use when: manually creating a lead↔member match BYPASSING BD's auto-matching. Rarely needed - usually matchLead handles this automatically. Use for data migrations, manual override scenarios, or replaying matches from another system.
Required: lead_id, user_id, lead_status, match_price, lead_token, lead_matched_by.
Pre-check before create (PAIR uniqueness): BD does NOT enforce uniqueness on the (lead_id, user_id) pair. Matching the same lead to the same member twice creates two match rows - the member gets double-billed (if the match charges credits), both rows appear in the member's inbox, and reporting double-counts the match. Filter-find pattern (single-field server filter + client-side intersect): call listLeadMatches property=lead_id property_value=<proposed lead_id> property_operator== to narrow to all matches for that lead, then CLIENT-SIDE filter the returned rows to those where user_id=<proposed user_id>. Zero results after the client-side step = pair free; >=1 = already matched. If the pair already exists: reuse via updateLeadMatch (e.g. to bump lead_status), OR confirm with the user before creating the duplicate match. Never silently double-match.
Parameter interactions:
Usually created automatically by
matchLead; manual creation bypasses BD's matching logiclead_idanduser_idmust both exist (usegetLead/getUserto verify)lead_status- match lifecycle state (see Enums)match_price,lead_points,lead_rating,lead_distance- scoring fields used in ranking and billing
See also: updateLeadMatch (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| lead_id | Yes | ||
| user_id | Yes | ||
| lead_type | No | ||
| lead_token | Yes | ||
| lead_chosen | No | ||
| lead_points | No | ||
| lead_rating | No | ||
| lead_status | Yes | Lead status (integer). NON-SEQUENTIAL enum - `3` does NOT exist; do not assume gaps are fillable: - `1` = Pending (received, awaiting action) - `2` = Matched (assigned to members) - `4` = Follow-Up (in progress) - `5` = Sold Out (no capacity) - `6` = Closed (resolved - converted or won't convert) - `7` = Bad Leads (spam/invalid) - `8` = Delete (soft-delete - hides from views) "Sold" / "won" -> `6` (Closed). Spam -> `7`. BD does NOT validate this enum - out-of-set integers are accepted and stored with undefined render behavior. Always use documented values. | |
| lead_viewed | No | ||
| match_price | Yes | ||
| lead_accepted | No | ||
| lead_distance | No | ||
| lead_response | No | ||
| lead_matched_by | Yes | ||
| lead_match_notes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description states 'Writes live data' (non-read-only) and warns about duplicate creation leading to double-billing and reporting issues. Annotations show readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false; description adds context about non-enforced uniqueness and client-side pre-check pattern.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bold headings, bullet points, and sections. Front-loads purpose and usage. Every sentence adds value, though the caution about double-billing could be slightly condensed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers key behavioral aspects: creation as manual bypass, uniqueness pre-check with client-side filtering, parameter interactions, and reference to update alternative. Does not describe return values or error conditions, but output schema is absent and annotations are present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 7% schema description coverage, the description compensates by listing required fields, explaining lead_status enum and non-validation, and describing scoring fields. However, not all 15 parameters are individually explained, leaving some gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Create a lead match - Create a new leadmatch record' with a specific verb and resource. It distinguishes from sibling 'matchLead' by noting it bypasses auto-matching for manual scenarios.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' section lists specific manual override scenarios (data migrations, manual overrides, replaying matches) and contrasts with automatic handling via 'matchLead'. Provides pre-check uniqueness pattern and alternative 'updateLeadMatch' for duplicates.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createMemberSubCategoryLinkA
Link a service to a user - Create a new Member ↔ Sub Category link with optional metadata. Writes live data.
Links an existing member (user_id) to an existing Sub Category (service_id) with per-link metadata (pricing, specialty). This is the richer alternative to setting users_data.services CSV via updateUser - use this when you need per-link data.
Use when: the simpler users_data.services CSV isn't rich enough - you need per-link avg_price, specialty=1, or num_completed. For plain "tag this member with this sub-cat" use updateUser with services=<service_id> instead.
Required: user_id, service_id.
Pre-check before create (PAIR uniqueness): BD does NOT enforce uniqueness on the (user_id, service_id) pair in rel_services. Linking the same member to the same Sub Category twice produces two rel_services rows, double-counts the member in that Sub Category's listing widgets, and leaves per-link metadata (specialty/avg_price) ambiguous - which row wins? Filter-find pattern (single-field server filter + client-side intersect): call listMemberSubCategoryLinks property=user_id property_value=<proposed user_id> property_operator== to narrow to all rel_services rows for that member, then CLIENT-SIDE filter to rows where service_id=<proposed service_id>. Zero results after client-side step = link free; >=1 = already linked. If the link already exists: update it via updateMemberSubCategoryLink (e.g. to set specialty=1 or avg_price), OR skip the create (idempotent). Never silently double-link the same member to the same Sub Category.
Parameter guidance:
user_id- member (fromlistUsers/searchUsers)service_id- Sub Category (fromlistSubCategories)avg_price- decimal, the member's price for this servicespecialty-0or1flags this Sub Category as a specialty offering on the member's profilenum_completed- counter of jobs/projects completed in this Sub Categorydate- YYYYMMDDHHmmss timestamp
See also: updateUser with services="<csv>" (simpler, no per-link metadata), listSubCategories, getMemberSubCategoryLink.
Writes live data: appears on the member's public profile immediately.
Returns: { status: "success", message: {...createdRecord} } with rel_id.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. Optional — omit unless backfilling historical data. | |
| user_id | Yes | ||
| avg_price | No | ||
| specialty | No | ||
| service_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool writes live data (matching annotations), warns about duplicate links not being enforced, and explains the impact on the public profile. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with sections (summary, usage, pre-check, parameters, see also). It is front-loaded with purpose, though some tangential context at the end could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers when to use, duplicate handling, parameter details, side effects, related tools, and even the broader classification system. No output schema exists, but return format is mentioned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite low schema coverage (20%), the description explains each parameter's purpose, meaning, and source (e.g., user_id from listUsers), fully compensating for the schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool creates a link between a member and a subcategory with optional metadata. It contrasts with the simpler updateUser approach, making its purpose distinct among sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states when to use this tool (when per-link metadata needed) versus updateUser (plain tagging). It provides a pre-check pattern and alternative actions if a duplicate exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createMenuA
Create a menu - Create a new menu record. Writes live data.
Use when: adding a new navigation container. After creating the container, add entries via createMenuItem using the returned menu_id.
Required: menu_name, menu_title.
Pre-check before create: BD does NOT enforce uniqueness on menu_name. Duplicates cause the wrong menu to render wherever the menu is referenced. Do a server-side filter-find: listMenus property=menu_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 row = taken. Do NOT paginate unfiltered lists - filtered lookup is one tiny response. If taken: reuse via updateMenu, OR ask the user, OR pick an alternate menu_name and re-check. Never silently create a duplicate.
Parameter interactions:
menu_name(max 35 chars) - the internal identifiermenu_title- the visible headingmenu_active:0=Inactive,1=Active
See also: updateMenu (modify existing).
Returns: { status: "success", message: {...createdRecord}, _admin_edit_url: "..." }. _admin_edit_url is a centralized-admin deep-link to the Menu Builder editor for this menu_id — surface it to the user so they can jump straight to the admin edit screen for the menu just created.
| Name | Required | Description | Default |
|---|---|---|---|
| menu_name | Yes | ||
| menu_title | Yes | ||
| menu_active | No | ||
| menu_div_id | No | ||
| menu_div_css | No | ||
| menu_effects | No | ||
| menu_div_code | No | ||
| menu_location | No | ||
| menu_div_class | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a non-read-only, non-idempotent write operation, but the description adds crucial behavioral context: BD does NOT enforce uniqueness on `menu_name`, duplicates cause wrong menu rendering, and a server-side pre-check is required before creation. It also discloses the return value shape and the `_admin_edit_url` deep-link, going well beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is relatively long but well-structured with bolded labels (Use when, Required, Pre-check, Parameter interactions, See also, Returns). Each section serves a purpose, and there is no filler. The length is justified by the operational warnings and return details, though it could be slightly tightened without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 9 parameters and no output schema, the description covers the core workflow, required parameters, critical duplicate-prevention steps, parameter interactions for key fields, and the exact return object including `_admin_edit_url`. It omits explanations for optional layout-related fields, but these are likely less critical; overall it gives an agent enough to use the tool safely and effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden. It adds meaningful semantics for three of nine parameters: `menu_name` as internal identifier (max 35), `menu_title` as visible heading, and `menu_active` with 0/1 mapping. However, six other parameters (`menu_div_id`, `menu_div_css`, `menu_effects`, etc.) are left unexplained, so the description only partially compensates for the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Create a menu - Create a new menu record. Writes live data.' which clearly identifies the action (create), the resource (menu record), and the live-write nature. It differentiates from siblings by explicitly referencing 'createMenuItem' for adding entries and 'updateMenu' for modifying existing menus, making its purpose distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The '**Use when:** adding a new navigation container' gives a clear condition for use. It also provides explicit alternatives: 'After creating the container, add entries via `createMenuItem`' and 'If taken: reuse via `updateMenu`, OR ask the user, OR pick an alternate `menu_name`'. This tells the agent exactly when to use this tool and when to turn to others.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createMenuItemA
Create a menu item - Create a new menuitem record. Writes live data.
Use when: adding a nav link to an existing menu. Parent menu_id must exist. For nested items pass master_id=<parent menu_item_id>; for top-level pass 0. menu_order determines display position (lower = earlier).
Required: menu_id, menu_name, menu_link, master_id, menu_order.
Enums: menu_active: 0=Inactive, 1=Active.
Parameter interactions:
menu_id- parent menu container (fromcreateMenuorlistMenus)master_id-0for top-level items; for nested items, the ID of the parent menu itemmenu_order- display position within the parent menu (integer, lower = earlier)menu_target:_blank(new tab) or_self(same window)
See also: updateMenuItem (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| menu_id | Yes | Parent menu ID | |
| master_id | Yes | 0 for top-level, parent item ID for sub-items | |
| menu_icon | No | ||
| menu_link | Yes | URL or path | |
| menu_name | Yes | Display text — the visible menu link label. Supports `[widget=Name]` shortcodes. | |
| menu_class | No | ||
| menu_order | Yes | ||
| menu_active | No | ||
| menu_target | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations show readOnlyHint=false, destructiveHint=false, idempotentHint=false, openWorldHint=true. The description confirms writes ('Writes live data') but does not disclose authorization needs, side effects, or return value. With annotations providing some safety profile, the description provides moderate additional context but lacks completeness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is about 10 lines, front-loaded with purpose, then covers usage, required fields, enums, parameter interactions, and see-also. Every sentence is necessary and contributes to understanding, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (9 params, 5 required, no output schema), the description covers usage conditions, parameter interactions, enums, and provides a sibling reference. However, it omits return value and error conditions, which would enhance completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 44% (4/9 params have descriptions). The description adds valuable semantics for key parameters: explains `menu_id` as parent menu container, `master_id` as 0 for top-level, `menu_order` as position, and `menu_target` enums. It compensates significantly for the schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Create a menu item - Create a new menuitem record. Writes live data.' It clearly identifies the verb (create) and resource (menu item), and distinguishes from siblings like 'createMenu' and 'updateMenuItem'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use: 'adding a nav link to an existing menu. Parent `menu_id` must exist. For nested items pass `master_id=<parent menu_item_id>`; for top-level pass `0`.' It also references 'updateMenuItem' for modifications, offering clear context and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createMultiImagePostA
Create an album group - Create a new portfoliogroup record. Writes live data.
Use when: creating a photo album, gallery, product listing with multiple photos, or any post type with data_type=4. Confirm the target post type's data_type via listPostTypes first - data_type=4 belongs here; 9/20 belongs in createSingleImagePost. For external image URLs, always use the bulk post_image CSV + auto_image_import=1 here - this is the only path that imports externals into site storage. createMultiImagePostPhoto does NOT import and is only suitable for already-hosted-on-site URLs.
Required: user_id, data_id, data_type.
Pre-check before create: BD does NOT enforce uniqueness on group_name, and the public URL slug is derived from it — duplicate names produce a URL collision (unpredictable which resolves). Do a server-side filter-find: listMultiImagePosts property=group_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 = taken. If taken: compare records, not strings - the same real-world record -> do NOT create (reuse via updateMultiImagePost); a different record sharing the name -> retitle to distinguish and re-check. Never create a duplicate under a new name.
Parameter interactions:
data_id+data_type- specify the post type this album belongs to (fromlistPostTypes;data_typemust be4)group_status:0=Hidden,1=Publishedpost_image- comma-separated image URLs imported as child photos at create timeauto_image_import=1- fetches thepost_imageURLs into site storage (required for external sources to survive)
Post-create verification (critical): HTTP 200 does NOT mean every photo imported. After create, call listMultiImagePostPhotos property=group_id&property_value=<new_group_id>&property_operator==; row count must equal CSV count and every row needs non-empty file + image_imported=2 (success; 0 = silent-failure row). Fix failed row: deleteMultiImagePostPhoto, then updateMultiImagePost group_id=<same>&post_image=<replacement>&auto_image_import=1 (appends). Do NOT delete and recreate the album.
See also: updateMultiImagePost (modify existing), createMultiImagePostPhoto (already-hosted URLs only).
Returns: { status: "success", message: {...createdRecord} } - includes the server-assigned group_id.
Which endpoint to use - data_type family decides:
Every post type in data_categories has a data_type field that classifies its family. Call listPostTypes or getPostType to see the data_type of your target post type, then choose:
| Family | Use endpoint |
| Multi-image (albums, galleries, photo-heavy listings - e.g. Classified, Photo Album, Property, Product) |
|
| Single-image video |
|
| Single-image article / event / blog / job / coupon |
|
| Internal admin types (Member Listings, Reviews, Sub Accounts, Specialties, Favorites) - NOT posts | Use the resource-specific endpoint (e.g. |
If you call the wrong create endpoint for a given post type, BD may accept the row but it won't render on the public site correctly.
Category for multi-image posts: multi-image posts do NOT expose post_category like single-image posts do. Album-level categorization is configured differently in BD admin and is not cleanly writable via the create payload. If categorization is needed, add it via a follow-up updateMultiImagePost or BD admin.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | Yes | ||
| user_id | Yes | ||
| data_type | Yes | Classification family - for this endpoint, must be `4` (multi-image). Read from the target post type's `data_type` column via `listPostTypes` / `getPostType`. If the post type's `data_type` is `9` or `20`, use `createSingleImagePost` instead. Do NOT call `listDataTypes` - `data_type` is a classification, not a per-site FK. | |
| post_tags | No | Comma-separated keywords for the album. Free-form strings - not related to the `Tags` resource. | |
| group_desc | No | Album description HTML. Froala body field — see **Rule: Post-body formatting** (structure, `fr-dib fr-fil`/`fr-fir` float + inline `width: 350px`, landscape Pexels images). | |
| group_name | No | ||
| post_image | No | Comma-separated list of image URLs to import as the album's photos (created at upload time as child `MultiImagePostPhoto` records). **LANDSCAPE only — verify each candidate's orientation via `getImageDimensions` per **Rule: Image dimensions** before commit; bare URLs, no `?query`, each must end in `.jpg`/`.jpeg`/`.png` (WebP/GIF/AVIF skipped pre-tool per the same rule) — see **Rule: Image URLs**.** Query strings (`?w=1600`, `?auto=compress`) get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. After create, verify every URL landed via `listMultiImagePostPhotos`. `createMultiImagePostPhoto` does NOT import externals and cannot patch a failed row. | |
| auto_geocode | No | Set to `1` to geocode the album's location. Requires the "Pretty URLs with Google Maps" site feature. | |
| group_status | No | 0=Not Published, 1=Published, 3=Pending Approval (rare — set when site admin requires manual moderation before albums go live). | |
| auto_image_import | No | **Auto-import images to site storage.** Set `1` when any external image URL field on this multi-image post holds a URL - BD fetches and saves each image locally. Without the flag, BD stores URLs as-is; images break if source hosts go down. **Recommended default when supplying external image URLs**; omit or set `0` only if user explicitly wants external URL references. Supports JPG/PNG/GIF/WebP/SVG. Processing delay: several minutes per image. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations by disclosing critical behaviors: 'Writes live data,' 'HTTP 200 does NOT mean every photo imported,' duplicate group_name causes URL collisions, and auto_image_import fetches externals into site storage. It also describes post-create verification steps, silent-failure rows, and the instruction 'Do NOT delete and recreate the album.' No contradiction with annotations (readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with bold section headers (Use when, Required, Pre-check, Parameter interactions, Post-create verification, etc.) and a clear data_type mapping table. It is front-loaded with the core purpose and use-when guidance; while lengthy, the detail is necessary for a complex creation tool with many failure modes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers return format ('{ status: "success", message: {...createdRecord} }'), post-create verification via listMultiImagePostPhotos, the consequence of choosing the wrong endpoint, and the lack of post_category for multi-image posts. Despite no output schema, the description fully prepares the agent for the create flow, verification, and failure recovery.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds substantial meaning beyond the schema: group_name uniqueness and collision risk, post_image must be landscape and end in .jpg/.jpeg/.png with no query strings, data_type must be 4 and read from listPostTypes/getPostType, auto_image_import=1 needed for external URLs, and group_status meanings including 3=Pending Approval. These details are essential for correct parameter usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Create an album group - Create a new portfoliogroup record. Writes live data,' giving a specific verb and resource. It further distinguishes from siblings by explicitly stating 'data_type=4 belongs here; 9/20 belongs in createSingleImagePost,' and explains the tool's role for multi-image post types like albums and galleries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when:' conditions (photo album, gallery, product listing, or any post type with data_type=4), and names alternatives: 'createSingleImagePost' for data_type 9/20, and 'createMultiImagePostPhoto' for already-hosted URLs only. It also gives a full data_type-to-endpoint mapping table and warns against using the wrong endpoint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createMultiImagePostPhotoA
Create an album photo - Create a new portfoliophoto record. Writes live data.
Use when: adding ONE image to an existing album where the image is already hosted on the BD site (or hotlinking is acceptable). The parent album must exist (call createMultiImagePost first to get group_id).
Does NOT import external URLs. This endpoint has no auto_image_import field — the URL is recorded as-is. The parent album's auto_image_import=1 applies only to photos passed via the parent's bulk post_image CSV at create time; it does NOT cascade to subsequent createMultiImagePostPhoto calls. For external URLs that must survive source outages (e.g. Pexels, stock sites), do NOT use this endpoint — create a NEW album via createMultiImagePost with a bulk CSV post_image + auto_image_import=1, and delete the old album.
Required: user_id, group_id.
Parameter interactions:
group_id- parent album group (fromcreateMultiImagePostorlistMultiImagePosts)original_image_url- full URL of the image; must already be publicly accessible; stored verbatim (no fetch)
See also: createMultiImagePost (the correct path for external URLs), updateMultiImagePostPhoto (modify title/order only — cannot re-import).
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| user_id | Yes | ||
| group_id | Yes | ||
| original_image_url | No | Image URL for this photo row. **LANDSCAPE only — verify orientation via `getImageDimensions` per **Rule: Image dimensions** before commit; bare URL, no `?query`, must end in `.jpg`/`.jpeg`/`.png` (WebP/GIF/AVIF skipped pre-tool per the same rule) — see **Rule: Image URLs**.** Note: `createMultiImagePostPhoto` does NOT import externals — records the URL as-is. For external URLs that must survive source outages, use `createMultiImagePost`'s bulk `post_image` CSV with `auto_image_import=1` instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate non-read-only, non-destructive, non-idempotent, open world. Description adds that it writes live data, does not import external URLs, and parent album's auto_image_import does not cascade. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is verbose with nested formatting and bullet points. Front-loaded with purpose but contains lengthy explanations that could be more concise. Still structured and readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage, parameters, limitations, and alternatives. No output schema, so return value is not expected. Provides sufficient context for correct tool selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (25%), but description explains user_id and group_id as required, group_id source, and original_image_url constraints (public, verbatim). Title not explicitly described but inferable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it creates an album photo record, specifying 'album photo' and 'portfoliophoto record'. It distinguishes from sibling createMultiImagePost by clarifying it adds one photo to an existing album.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' condition, prerequisite of parent album existence, and explicit 'Do NOT use' scenario for external URLs. Provides alternatives: createMultiImagePost for bulk import with auto_image_import, updateMultiImagePostPhoto for modifications.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createRedirectA
Create a redirect - Create a new 301 redirect rule.
Use when: preserving SEO after any URL change - slug rename on a member profile, post, page, or category. BD auto-creates some redirects on its own (admin-triggered renames), but you must create them manually for API-triggered changes. Avoid duplicate old_filename values.
Required: old_filename, new_filename.
type is wrapper-managed: the wrapper hardcodes type=custom on every create. The other BD type values (profile, post, category) are reserved for BD's own auto-redirect logic on admin-triggered renames and are not exposed here.
Pre-check before create - TWO checks (redirects are uniquely dangerous: wrong rules cause infinite loops and SEO damage):
Check 1 - exact-pair skip (idempotent): Do a server-side filter-find: listRedirects property=old_filename property_value=<proposed old> property_operator==. If a row exists where new_filename also matches the proposed new, skip the create - the rule is already there; creating a duplicate just bloats the redirect table. If a row exists with the same old_filename but a DIFFERENT new_filename, that's a conflict: reuse via updateRedirect with the new target, OR ask the user which destination wins. Never silently create a duplicate or conflicting old_filename.
Check 2 - reverse-rule loop prevention (CRITICAL): Do a second filter-find: listRedirects property=old_filename property_value=<proposed NEW> property_operator==. If a row exists where new_filename equals your proposed old_filename, creating this rule would produce an infinite redirect loop (A->B and B->A). STOP. Flag to the user, explain the reverse rule in place, and ask whether to delete the existing reverse rule first or abandon the create.
Do NOT paginate unfiltered redirect lists - filtered lookups are two tiny responses. On any site with a large redirect history, dumping the full table wastes rate limit and context.
Parameter interactions:
old_filename/new_filename- URL paths relative to the domain root (not full URLs)db_id- database record ID of the source content if the redirect ties to one; otherwise 0
See also: updateRedirect (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Legacy secondary identifier; typically 0 for system-generated redirects | |
| db_id | No | Database record ID of the source content object this redirect was generated from (0 if not tied to a record) | |
| new_filename | Yes | The new destination URL path | |
| old_filename | Yes | The old URL path being redirected from, relative to the domain root (e.g. old-slug, not the full URL) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses critical behaviors: non-idempotent nature, potential for infinite loops, and required pre-checks. Adds context beyond annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false, openWorldHint=true) by explaining why these checks are necessary and what happens if not done.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Long but well-structured with sections, bold headers, and numbered steps. Front-loaded with purpose and key usage. Every sentence adds value, though could be slightly more concise. The pre-check detail is justified by the tool's risk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (dangerous redirects, no output schema, many siblings), the description covers purpose, usage, pre-checks, parameter details, and alternatives. It is fully complete for an AI agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. Description adds meaning by clarifying that old_filename and new_filename are relative paths, explaining db_id's purpose, and noting that id is legacy. Also explains that type is wrapper-managed, which is not in schema but relevant. Adds significant value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Create a new 301 redirect rule' and specifies it's for preserving SEO after URL changes like slug renames. Distinguishes from siblings by naming updateRedirect and listRedirects, and explains when to use each.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use (API-triggered changes, not admin-triggered), what to avoid (duplicate old_filename), and detailed pre-check steps (idempotent skip, conflict detection, loop prevention). Also mentions see also updateRedirect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createReviewA
Create a review - Create a new review record. Writes live data.
Use when: importing legacy reviews from another platform, adding placeholder reviews for test data, or scripting review submissions from an external integration. Real member-submitted reviews come through the BD review form - only use this API when bypassing that form.
Required: user_id, review_email.
Parameter interactions:
user_id- the member being reviewedrating_overall: integer 1-5 (higher = better)recommend:0=No,1=Yes (shown as a thumbs-up recommendation flag)review_statuscontrols initial visibility - default flow is0Pending -> admin review
See also: updateReview (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | ||
| recommend | No | ||
| review_name | No | Reviewer's display name. Strongly recommended - most BD themes render this on the profile next to the review. | |
| review_email | Yes | REQUIRED (server rejects with `The review email is required` when omitted, despite earlier docs that listed only `user_id` as required). Reviewer's email. Used for notification threading and duplicate-review detection. | |
| review_title | No | ||
| review_status | No | Review status (integer). Authoritative values from BD admin: 0 = Pending (newly submitted, awaiting moderation - default for new reviews) 2 = Accepted (approved and visible on the member profile) 3 = Declined (rejected by admin - not publicly visible) 4 = Waiting for Admin (member pre-accepted, admin sign-off required) Value 1 is NOT a documented status - **but BD does NOT reject it. Passing `1` stores `"1"` verbatim with undefined render behavior.** Stick to the documented set. On create, default flow starts at 0. | |
| rating_overall | No | ||
| rating_results | No | Omitted on create -> BD stores 5 (server default), not null - send every category score you have. | |
| rating_service | No | Omitted on create -> BD stores 5 (server default), not null - send every category score you have. | |
| rating_language | No | Omitted on create -> BD stores 5 (server default), not null - send every category score you have. | |
| rating_response | No | Omitted on create -> BD stores 5 (server default), not null - send every category score you have. | |
| rating_expertise | No | Omitted on create -> BD stores 5 (server default), not null - send every category score you have. | |
| review_description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this is a write operation (readOnlyHint: false, idempotentHint: false). The description adds meaningful context: 'Writes live data,' explains the default review_status flow ('0 Pending -> admin review'), and warns about omitted rating fields defaulting to 5. It does not detail all side effects, hence not 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: purpose first, then usage guidance, required fields, parameter interactions, and a cross-reference. Every sentence provides distinct value; no fluff or repetition. It is compact despite covering many critical details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter create tool with no output schema, the description plus schema form a complete picture. It covers use cases, required fields, key parameter interactions, default behaviors, and sibling relationships. The absence of an output schema is acceptable for a create operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 62%, so the schema does substantial work. The description adds value by clarifying user_id ('the member being reviewed'), recommend ('0=No, 1=Yes'), and review_status semantics ('controls initial visibility'). It also highlights required parameters. This compensates for undocumented fields like review_title and review_description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Create a review - Create a new review record. Writes live data.', which clearly states the action (create) and resource (review record). It distinguishes from siblings by explicitly contrasting with updateReview ('See also: updateReview (modify existing)') and by clarifying that real member-submitted reviews go through the BD form, not this API.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Use when:' section explicitly lists three appropriate scenarios (importing legacy reviews, placeholder/test data, external integration) and an exclusion: 'only use this API when bypassing that form.' It also points to updateReview for modifications. This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createSingleImagePostA
Create a post - Create a new post record. Writes live data.
Use when: creating a blog article, event, job listing, coupon, or any other single-image post type. Look up data_id + data_type via listPostTypes first - the post type's data_type field determines which create endpoint is correct. If data_type=4 on the post type, use createMultiImagePost instead. For posts with scraped external image URLs, include auto_image_import=1 to fetch and store them locally.
Required: user_id, data_id, data_type.
Pre-check before create: BD does NOT enforce uniqueness on post_title, and BD auto-generates filename (the URL slug) from the title - so a duplicate title produces a URL collision (two posts fighting for the same public URL, unpredictable which one resolves). Do a server-side filter-find: listSingleImagePosts property=post_title property_value=<proposed> property_operator==. Zero rows = title free; >=1 row = taken. If post_title contains a comma (the = operator trips the CSV validator on commas only - colons and other characters are safe), switch to property_operator=like property_value=<distinctive-prefix>% using a 3-4-word prefix unique to this event. Do NOT paginate unfiltered lists - sites in the wild have thousands of posts; filtered lookup is one tiny response. If taken: compare records, not strings - the same real-world record -> do NOT create (reuse via updateSingleImagePost or skip); a different record that happens to share the name -> retitle to distinguish and re-check. A free title is NOT proof of a new record: retitled duplicates share dates, venues, and employers - for dated or venued post types also probe post_start_date (8-digit day, contains) or post_venue (contains), paired with data_id, before creating. Never create a duplicate under a new name.
Parameter interactions:
user_id- owner; must be an existing member (discover vialistUsersorsearchUsers)data_id- post type category ID; get vialistPostTypesdata_type- data type classification; usually matches the post type's data typepost_status:0=Draft (not visible),1=Published (public)Response includes both
post_idandpost_token- the token is used for sharable URLs
See also: updateSingleImagePost (modify existing).
Which endpoint to use - data_type family decides:
Every post type in data_categories has a data_type field that classifies its family. Call listPostTypes or getPostType to see the data_type of your target post type, then choose:
| Family | Use endpoint |
| Multi-image (albums, galleries, photo-heavy listings - e.g. Classified, Photo Album, Property, Product) |
|
| Single-image video |
|
| Single-image article / event / blog / job / coupon |
|
| Internal admin types (Member Listings, Reviews, Sub Accounts, Specialties, Favorites) - NOT posts | Use the resource-specific endpoint (e.g. |
If you call the wrong create endpoint for a given post type, BD may accept the row but it won't render on the public site correctly.
For "make a blog post" intent: look up data_categories for data_name matching "blog" (commonly data_id=14 with data_type=20) -> createSingleImagePost with that data_id + data_type.
For "make a photo album" / "gallery" intent: look up the album post type (often data_id=10, data_type=4) -> createMultiImagePost with that data_id + data_type. Photos are added separately via createMultiImagePostPhoto using the returned group_id.
Picking post_category (and other per-type dropdowns): post_category values are configured PER POST TYPE by the site admin in the post type's feature_categories CSV. Read the CSV from your listPostTypes/getPostType result (or getPostTypeCustomFields.post_category.choices where your workflow routes through it) and pass ONE value from it VERBATIM - never from getSingleImagePostFields.post_category.choices, which BD fills from platform master defaults on some forms - BD does not trim whitespace when splitting feature_categories, so options after the first may have a leading space (e.g. " Category 2"). If the user names a category that isn't in the list: ask whether to pick the closest existing option or have them add the new option in BD admin first - do NOT invent a new value. WARNING: if form_name does not match a real post type form, getSingleImagePostFields silently returns a generic SUPER-UNION field list (HTTP 200, no error) - verify form_name exists in listPostTypes first.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude for the post's location (geo-enabled post types). Decimal degrees as string. | |
| lon | No | Longitude for the post's location (geo-enabled post types). Decimal degrees as string. | |
| data_id | Yes | Parent post-type ID (data_categories.data_id, from listPostTypes). | |
| user_id | Yes | ||
| post_job | No | Employment type - used by Job post types only. Other post types ignore this field. | |
| post_url | No | Explicit CTA button link rendered under the feature image on the post-detail page. Use when the owner wants a prominent button. Full `http(s)://` URL. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_url`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post. | |
| state_sn | No | 2-letter state/region code for the post's location (e.g. `CA`). | |
| data_type | Yes | Classification family, read from target post type's `data_type` column (via `listPostTypes`/`getPostType`). Values: - `4` = multi-image - use `createMultiImagePost` instead - `9` = single-image video - `20` = single-image article/event/job/coupon Internal-only values (`10`, `13`, `21`, `28`, `29`) are NOT post-creatable via this endpoint - use the resource-specific creator (e.g. `createReview` for `13`). Do NOT call `listDataTypes` - `data_type` is a classification, not a per-site FK. | |
| post_tags | No | Comma-separated keywords for the post. Free-form strings - not related to the `Tags` resource. | |
| country_sn | No | 2-letter country code for the post's location (e.g. `US`). | |
| post_image | No | Feature image URL. **LANDSCAPE only — verify orientation via `getImageDimensions` per **Rule: Image dimensions** before commit; bare URL, no `?query`, must end in `.jpg`/`.jpeg`/`.png` (WebP/GIF/AVIF skipped pre-tool per the same rule) — see **Rule: Image URLs**.** Query strings (`?w=1600`, `?auto=compress`) get baked into the imported filename and 404. Default: Pexels landscape URL + `auto_image_import=1` (skip only on explicit no-image request). | |
| post_price | No | ||
| post_promo | No | Twin of post_price (job pay, event ticket price, coupon price — live-verified on jobs and events). BD requires post_promo to populate post_price — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null. | |
| post_title | No | ||
| post_venue | No | Event/post venue name/landmark where the event is held (e.g. `Staples Center`) - distinct from `post_location` (the street address). Free text. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_venue`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post. | |
| post_video | No | Full URL of a YouTube or Vimeo video. Only used by Video post types (`data_type=9`). | |
| post_status | No | 0=Not Published, 1=Published, 3=Pending Approval (rare — set when site admin requires manual moderation before posts go live). | |
| auto_geocode | No | Set to `1` to geocode the post's location via Google Maps (uses `post_location`/lat/lon/state_sn/country_sn if supplied). Requires the "Pretty URLs with Google Maps" site feature. | |
| post_caption | No | Deprecated. Leave unset unless user explicitly references it. | |
| post_content | No | Main HTML body of the post. Froala body field — see **Rule: Post-body formatting** (structure, `fr-dib fr-fil`/`fr-fir` float + inline `width: 350px`, landscape Pexels images). HTML allowed; supports `[widget=Name]` shortcodes and `%%%template_tokens%%%`. | |
| post_category | No | Per-post-type dropdown value, configured in BD admin on the post type's `feature_categories` field. Discover allowed values from `feature_categories` on your `listPostTypes`/`getPostType` result, or `getPostTypeCustomFields.post_category.choices` where your workflow routes through it - NOT from `getSingleImagePostFields.post_category.choices` (BD fills that from platform master defaults on some forms). Pass VERBATIM - BD does not trim whitespace, so leading spaces after commas in `feature_categories` persist in the stored option values. | |
| post_location | No | Full or partial street address for the post (Event, Coupon, Job, or any geo-enabled post type). Pair with `auto_geocode=1` to resolve to lat/lon automatically, or set `lat`/`lon`/`state_sn`/`country_sn` explicitly. | |
| post_live_date | No | Creation date stored on the post. Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. Usually auto-set on create; override only for import/migration. | |
| post_meta_title | No | SEO `<title>` override for the post's public page. | |
| post_start_date | No | Scheduled publish date — when the post becomes visible on the public site. Set a future timestamp to schedule (like WordPress's future-publish); set a past timestamp for immediate visibility. REQUIRED on Event post types (marks when the event begins); optional but commonly used on blog/article/news post types for scheduled publishing. Format: `YYYYMMDDHHmmss`. **Event post types: event-local wall-clock** — the time as a visitor in the event's city would read it; do NOT convert to the site's own timezone (a 7 PM Brooklyn event on a Los Angeles-timezoned site stores as `20260616190000`). **Scheduled-publish on blog/article/news types: site timezone.** BD silently truncates other formats, corrupting the value. The wrapper auto-derives `start_time` (`"H:MM AM/PM"`) from this value on `createSingleImagePost` / `updateSingleImagePost` so BD's form-edit time-of-day dropdown stays populated — agent never passes `start_time` directly. | |
| post_expire_date | No | End/expiration date. Coupon post types use this for expiration; Event post types use it for end time. Format: `YYYYMMDDHHmmss`. **Event post types: event-local wall-clock** (match `post_start_date`). **Coupons and other post types: site timezone.** BD silently truncates other formats, corrupting the value. The wrapper auto-derives `end_time` (`"H:MM AM/PM"`) from this value on `createSingleImagePost` / `updateSingleImagePost` — agent never passes `end_time` directly. | |
| auto_image_import | No | **Auto-import images to site storage.** Set `1` when any external image URL field on this single-image post (e.g. `post_image`) holds a URL - BD fetches the image and saves locally. Without the flag, BD stores the URL as-is; images break if source host goes down. **Recommended default when supplying external image URLs**; omit or set `0` only if user explicitly wants the external URL reference. Supports JPG/PNG/GIF/WebP/SVG. Processing delay: several minutes. | |
| post_meta_keywords | No | SEO meta keywords (comma-separated) for the post's public page. | |
| post_meta_description | No | SEO meta description override for the post's public page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses non-obvious side effects: BD does NOT enforce title uniqueness, auto-generates a filename causing URL collisions, may accept rows from wrong endpoints yet fail to render, and stores certain fields in users_meta rather than data_posts. It also documents the duplicate-prevention pre-check workflow and warns against paginating unfiltered lists. This goes well beyond the minimal annotation set (readOnly=false, openWorld=true, idempotent=false, destructive=false).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long but well-structured with bold headers, tables, and front-loaded purpose/usage. Some redundancy exists (the data_type table repeats schema info), but the density of critical warnings justifies most length. It earns a 4 because it is thorough yet slightly repetitive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, alternatives, failure modes, duplicate prevention, parameter interactions, endpoint selection, category selection, and response contents (post_id/post_token). Even warns about getSingleImagePostFields returning a generic super-union list for invalid form_name. With no output schema and 29 parameters, this is exceptionally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 90% schema coverage, the description adds significant interaction knowledge: post_promo back-fills post_price, post_category values must be passed verbatim because BD doesn't trim whitespace, post_start_date/post_expire_date use event-local wall-clock vs site timezone, and post_url/post_venue are stored in users_meta. It also warns against calling listDataTypes and clarifies data_type is a classification, not a per-site FK.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Create a post - Create a new post record. Writes live data.' and enumerates concrete post types (blog article, event, job listing, coupon). It explicitly contrasts with createMultiImagePost via the data_type family table and points to updateSingleImagePost for modifications, making its scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a dedicated 'Use when' section naming specific post types, and explicitly says 'If data_type=4 on the post type, use createMultiImagePost instead.' It includes a full endpoint-selection table and intent-based routing examples for 'make a blog post' vs 'make a photo album', leaving no doubt about alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createSmartListA
Create a smart list - Create a new smartlist record. Writes live data.
Use when: programmatically saving a filter configuration for later reuse. smart_list_type determines the data source (members, leads, reviews, etc.).
Required: smart_list_name, smart_list_type, smart_list_created_by.
Pre-check before create: BD does NOT enforce uniqueness on smart_list_name. Duplicate list names mean admins and other tools can't tell the lists apart in the Smart Lists manager, and automations that look up a list by name will bind to the wrong record. Do a server-side filter-find: listSmartLists property=smart_list_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 row = taken. Do NOT paginate unfiltered lists - filtered lookup is one tiny response. If taken: reuse via updateSmartList, OR ask the user, OR pick an alternate smart_list_name and re-check. Never silently create a duplicate.
Parameter interactions:
smart_list_type- data source (see Enums)smart_list_created_by- admin user ID creating the listsmart_list_query_params- JSON/string of filter criteria specific to the chosen typeschedule- recurrence if the list should auto-refresh
See also: updateSmartList (modify existing).
smart_list_query_params format depends on smart_list_type:
For
smart_list_type=newsletter: store a URL string (admin view uses it directly as an href link - no filter semantics).For ALL other types (
members,leads,reviews,transaction,forms_inbox): pass a JSON string of filter key-value pairs, e.g.{"subscription_id":"1","active":"1"}. The backend encrypts it internally before storing.If empty / no filters: pass
"NA"(the controller defaults missing values to this).
The API accepts the value as a plain string; BD handles the internal encryption. Don't pre-encrypt client-side - you'll get double-encrypted garbage. Use the JSON-key-value format for filterable types.
| Name | Required | Description | Default |
|---|---|---|---|
| schedule | No | Recurrence frequency | |
| smart_list_name | Yes | ||
| smart_list_type | Yes | ||
| smart_list_created_by | Yes | Admin user ID | |
| smart_list_query_params | No | Filter criteria — format depends on `smart_list_type`: - **newsletter** - pass a URL string (used directly as `href`) - **all other types** (members, leads, reviews, transaction, forms_inbox) - pass a JSON string of key-value filter pairs like `{"subscription_id":"1","active":"1"}` - **no filters** - pass `"NA"` Backend encrypts internally - do NOT pre-encrypt client-side. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (readOnlyHint=false, destructiveHint=false). The description adds significant behavioral context: it writes live data, warns about duplicate name confusion, explains backend encryption behavior ('do NOT pre-encrypt'), and notes that the format of smart_list_query_params depends on smart_list_type. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and flows logically through use case, requirements, pre-check, parameter details, and cross-reference. However, it is verbose—the pre-check block contains multi-sentence instructions that could be condensed without losing value. Slightly over-communicates.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters, no output schema, and lightweight annotations, the description covers everything an agent needs: purpose, required fields, parameter interactions, duplicate handling, and an alternative tool. It is fully self-contained and leaves no obvious gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 3 of 5 parameters (60%) but descriptions are sparse. The description extensively explains the conditional format of smart_list_query_params based on smart_list_type, the 'NA' sentinel for no filters, and the encryption warning. It also identifies smart_list_created_by as an admin user ID. This adds critical meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a clear verb+resource: 'Create a smart list - Create a new smartlist record. Writes live data.' It distinguishes from sibling tools like updateSmartList by explaining the creation context and noting alternative uses. The purpose is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'Use when: programmatically saving a filter configuration for later reuse.' It provides a detailed pre-check for name uniqueness and instructs what to do if a duplicate exists, including rerouting to updateSmartList. This provides clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createSubCategoryA
Create a service - Create a new SUB-level member category under an existing Top Category. Writes live data.
Use createTopCategory or createSubCategory only for a single category that needs desc, keywords, icon, sort_order, lead_price, image, master_id, or a filename other than the default slug set at create time. For every other category create, use createCategoryTree.
A Sub Category is level 2 of the 3-tier member classification. It MUST have a parent Top Category (via profession_id). It may optionally sit under another Sub Category (for sub-sub-category nesting, via master_id). Backed by BD's list_services table.
Use when: adding one sub-category that needs desc, keywords, sort_order, lead_price, image, master_id, or a filename other than the default slug set at create time. To auto-create sub-categories while writing a member, include the names in services on createUser, or pass create_new_categories=1 on updateUser.
Required: name, profession_id.
Pre-check before create: BD does NOT enforce uniqueness on filename (URL slug) or name - but uniqueness IS scoped per-parent (two sub-cats with the same filename under different profession_id is fine; same filename under the SAME profession_id is not). Do a server-side filter-find: listSubCategories property=filename property_value=<proposed> property_operator==, then filter results by the intended profession_id. Zero rows under that parent = slug free; >=1 row = taken (URL collision - wrong sub-cat page resolves). Do NOT paginate unfiltered lists - filtered lookup is one tiny response. If taken: reuse via updateSubCategory, OR ask the user, OR pick an alternate filename and re-check. Wrapper safety net: on a missed pre-check, the wrapper auto-suffixes filename on collision (-1...-20) and surfaces the suffix in the response. Pre-checking still preferred — auto-suffix surprises the caller in URL-sensitive workflows.
Parameter guidance:
name- human-readable (e.g. "Sushi")profession_id- the parent Top Category's ID (fromlistTopCategoriesorcreateTopCategory)master_id- for SUB-SUB-CATEGORY nesting, pass the parent Sub Category's ID; default 0 means "directly under the Top Category"filename- URL-slug form;desc,keywords,sort_order,lead_price,image- all optional. The default slug is the name lower-cased and hyphenated, with any character outside the Latin set percent-encoded.
See also: updateSubCategory (modify), listSubCategories (list), createTopCategory (create parent).
Writes live data: changes are immediately visible on the public site.
Returns: { status: "success", message: {...createdRecord} } including service_id. Use that to assign members via updateUser.services (CSV) or createMemberSubCategoryLink.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createCategoryTree, or createTopCategory / createSubCategory when a single category needs create-time field control (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| desc | No | Short internal taxonomy-row label. **Even if the user says "description" - this is NOT an SEO description.** Not a meta-tag surface, not Google-ranking copy, not the H1/intro on the public category search page. Most BD themes don't render this field. For ANY SEO task on a category or sub-category - "write a description that ranks," "improve SEO," "add meta tags," "write intro copy" - create a WebPage with `seo_type=profile_search_results` and the matching slug instead (see `createWebPage`). Short internal blurb only here. | |
| name | Yes | Sub-category name. One name only — a comma-separated list is stored literally as one category named `A,B,C`. To create several at once use `createCategoryTree`. | |
| filename | No | URL slug. Must be unique across web pages, top categories, sub categories, plan public URLs, and member profile slugs (wrapper auto-rejects collisions; pick a different slug or rename the conflict first). | |
| keywords | No | Fuzzy-search synonyms for on-site category matching - NOT SEO meta-keywords. Comma-separated single words (no spaces): synonyms, abbreviations, slang, common misspellings. Example for `Doctor`: `doc,physician,md,medic,gp,specialist`. ~5-10 max. Skip SEO phrases like `doctor near me` - those aren't fuzzy matchers. Optional. | |
| master_id | No | ||
| lead_price | No | ||
| sort_order | No | ||
| profession_id | Yes | Parent category ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say the tool is not read-only, not idempotent, not destructive, and open-world. The description adds substantial behavioral detail: writes are immediately live on the public site, BD does not enforce uniqueness, the wrapper auto-suffixes filename collisions, and a server-side pre-check is recommended. These are non-obvious behavioral traits an agent needs to invoke the tool safely.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with bolded section headers and front-loaded purpose, use-when, and required fields. Some content, such as the member classification explanation, is broader context rather than strictly necessary to invoke the tool, which keeps it from a perfect conciseness score, but everything is organized and purposeful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 8 parameters, no output schema, and a rich sibling ecosystem, the description covers nearly everything needed: required fields, pre-create uniqueness checks, collision behavior, parameter guidance, return shape with service_id, and integration with related tools. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 63% schema description coverage, the description adds meaningful meaning beyond the schema: master_id semantics for sub-sub-category nesting, profession_id as the parent Top Category ID, filename as the URL slug with a default slug generation rule, and the notion that name must be a single name, not a comma-separated list. lead_price and sort_order remain thin, but they are optional and lower-risk.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Create a new SUB-level member category under an existing Top Category.' It also differentiates itself from createTopCategory and createCategoryTree, so an agent can immediately tell what this tool uniquely does and which sibling should be used instead.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Use when' section explicitly lists the conditions for choosing createSubCategory, and states that createCategoryTree should be used for every other category create. It also names alternatives like createTopCategory, updateSubCategory, listSubCategories, createUser, and updateUser, plus the pre-check workflow, making the decision boundary unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createTagA
Create a tag - Create a new tag record. Writes live data.
Use when: adding a new tag. Group (group_tag_id) must exist - discover via listTagGroups.
Required: tag_name, group_tag_id.
added_by is wrapper-managed: the audit-trail added_by field is hardcoded to 0 by the wrapper on every create. Not exposed as an input.
Duplicate tag_name silent-accept: BD does NOT enforce a uniqueness constraint on tag_name within a group_tag_id. Two createTag calls with the same tag_name + group_tag_id both succeed and produce two rows with different tag_ids. Downstream createTagRelationship calls then become ambiguous (which of the two tags?). Recommended pre-check pattern: call listTags with property=tag_name&property_value=<name>&property_operator== (optionally filtered further by group_tag_id) BEFORE create. If a match exists, reuse that tag_id rather than creating a duplicate.
Parameter interactions:
tag_name- the visible labelgroup_tag_id- tag group fromlistTagGroups
See also: updateTag (modify existing).
Returns: { status: "success", message: {...createdRecord} } - includes the server-assigned ID. Use this ID for follow-up operations.
| Name | Required | Description | Default |
|---|---|---|---|
| tag_name | Yes | ||
| group_tag_id | Yes | Tag group this tag belongs to (from `listTagGroups`). **BD does NOT enforce FK** — passing `0` or a nonexistent group_tag_id is silently accepted and produces an orphan tag (live observed). Verify the group exists before passing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that added_by is wrapper-managed, duplicate tag_name is silently accepted, and group_tag_id FK is not enforced, providing critical behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and front-loaded purpose, but slightly verbose; every sentence is informative, though some redundancy could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers prerequisites, edge cases, duplicate handling, return format, and references to sibling tools, fully compensating for lack of output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even with only 50% schema coverage, the description adds meaning by explaining tag_name as 'visible label' and detailing group_tag_id constraints and interactions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Create' and resource 'tag', distinguishes from siblings like updateTag and listTags, and specifies it writes live data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: adding a new tag', requires group existence from listTagGroups, and recommends a pre-check pattern for duplicate detection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createTagGroupA
Create a tag group - Create a new taggroup record. Writes live data.
Use when: organizing tags into new themes (e.g., "Skill Level", "Service Area"). Rare.
Required: group_tag_name, added_by, updated_by.
Pre-check before create: BD does NOT enforce uniqueness on group_tag_name. Duplicate group names cause tag-manager ambiguity (admins can't tell which group a tag belongs to) and break filters that select by group name. Do a server-side filter-find: listTagGroups property=group_tag_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 row = taken. Do NOT paginate unfiltered lists - filtered lookup is one tiny response. If taken: reuse via updateTagGroup, OR ask the user, OR pick an alternate group_tag_name and re-check. Never silently create a duplicate.
See also: updateTagGroup (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| added_by | Yes | ||
| updated_by | Yes | ||
| group_tag_name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate this is a write operation, and the description adds critical context: no enforced uniqueness, consequences of duplicates, and a server-side filter-find workflow. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections (use when, required, pre-check, see also), but slightly verbose. Every sentence is meaningful, but could be trimmed slightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a create tool with 3 required params and no output schema, the description covers the critical pre-check logic and uniqueness risks, which is sufficient for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but description adds meaning for group_tag_name (uniqueness importance) but does not explain added_by and updated_by (likely user IDs). Partial compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Create' and resource 'tag group', and distinguishes from siblings like updateTagGroup and listTagGroups by focusing on creation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use (organizing tags into new themes, rare) and provides a detailed pre-check procedure, including alternative actions if duplicate exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createTagRelationshipA
Create a tag relationship - Create a new tagrelationship record. Writes live data.
Use when: attaching an existing tag to a record (member, post, etc.). The alternative for members is setting the member_tags field via updateUser with member_tag_action=1.
Required: tag_id, object_id, tag_type_id, added_by.
Pre-check before create (TRIPLE uniqueness): BD does NOT enforce uniqueness on the (tag_id, object_id, tag_type_id) triple. Attaching the same tag to the same object twice produces two rel_tag rows, which inflates tag counts on admin reports and can cause some widgets to render the same tag chip twice on the same record. Filter-find pattern (single-field server filter + client-side intersect): call listTagRelationships property=tag_id property_value=<proposed tag_id> property_operator== to narrow to all rows for that tag, then CLIENT-SIDE filter to rows where object_id=<proposed object_id> AND tag_type_id=<proposed tag_type_id>. Zero results after client-side intersect = link free; >=1 = already attached. If the link already exists: skip the create (idempotent - the tag is already on the object). Never silently double-link.
Parameter interactions:
Attaches an existing tag to an existing record. Both sides must exist - use
listTagsand the target resource's list to discover IDs
See also: updateTagRelationship (modify existing).
tag_type_id + object_id - how to target the right record (from BD tag_types table):
The tag_type_id determines WHICH resource/table the object_id lives in. Discover mapping via listTagTypes - each tag type row has a table_relation field naming its target table. Example mapping:
tag_type_id | type_name | Target table (table_relation) | What object_id references |
1 | Users |
|
|
(other rows) | (other types) | e.g. | That table's primary key |
Process: call listTagTypes first to see the tag_type_id -> table_relation mapping on your site, then pick the appropriate tag_type_id and supply the matching record's PK as object_id. Widgets, menus, and forms all support tags via the same tag_type_id + object_id lookup pattern.
| Name | Required | Description | Default |
|---|---|---|---|
| tag_id | Yes | Integer PK of the tag (`tags.id`) passed as a string per the underlying `varchar(500)` column. The schema column comment says "name of the tag" — that's legacy and misleading; BD stores the integer ID stringified. Discover via `listTags`. | |
| added_by | Yes | ||
| object_id | Yes | Primary key of the record being tagged. Which table it lives in depends on tag_type_id - look up via listTagTypes. For tag_type_id=1 (Users), object_id is a user_id from users_data. | |
| tag_type_id | Yes | Tag type classifier ID - determines which TABLE the `object_id` references. Call `listTagTypes` first to see the `tag_type_id` -> `table_relation` mapping. Example: `tag_type_id=1` usually means Users (`table_relation=users_data`), so `object_id` would be a `user_id`. Other tag types may target widgets, menus, forms. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that the tool writes live data, warns about lack of uniqueness constraints causing duplicates, details the triple uniqueness check and filter-find pattern, and explains tag_type_id mapping via listTagTypes. This goes beyond annotations, which only provide hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-organized with sections (Use when, Required, Pre-check, Parameter interactions, See also, tag_type_id mapping). Every sentence adds value, and the structure is front-loaded with purpose. No superfluous content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Very thorough in usage, pre-checks, and parameter details, but does not explicitly describe the return value (e.g., created relationship ID or success). Given no output schema, a brief mention of output would enhance completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds significant meaning beyond schema: explains tag_id is a stringified integer, clarifies added_by is required, and provides detailed mapping for object_id and tag_type_id with examples. Schema coverage is high but description enriches understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Create a tag relationship - Create a new tagrelationship record.' and distinguishes from siblings like createTag and updateTagRelationship, explicitly noting when to use this tool versus updateUser for member tags.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: attaching an existing tag to a record' and provides an alternative for members using updateUser. Also recommends pre-check for duplicates and references updateTagRelationship for modifications.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createTopCategoryA
Create a category - Create a new TOP-level member category. Writes live data.
Use createTopCategory or createSubCategory only for a single category that needs desc, keywords, icon, sort_order, lead_price, image, master_id, or a filename other than the default slug set at create time. For every other category create, use createCategoryTree.
A Top Category is the highest level of the 3-tier member classification (e.g., "Restaurants"). It populates the profession_id field on user records. Backed by BD's list_professions table.
Use when: adding one top category that needs desc, keywords, icon, sort_order, lead_price, image, or a filename other than the default slug set at create time. To auto-create a top category while creating a member, pass profession_name to createUser instead.
Required: name, filename.
Pre-check before create: BD does NOT enforce uniqueness on filename. Two top categories with the same slug -> which one resolves at /filename is undefined. Do a server-side filter-find: listTopCategories property=filename property_value=<proposed> property_operator==. Zero rows = slug free; >=1 row = taken. Do NOT paginate unfiltered lists - filtered lookup is one tiny response. If taken: reuse via updateTopCategory, OR ask the user, OR pick an alternate filename and re-check. Wrapper safety net: on a missed pre-check, the wrapper auto-suffixes filename on collision (-1...-20) and surfaces the suffix in the response. Pre-checking still preferred — auto-suffix surprises the caller in URL-sensitive workflows.
Parameter guidance:
name- human-readable (e.g. "Restaurants", "Dentists")filename- URL-slug form (e.g. "restaurants") used in public member profile URLs. The default slug is the name lower-cased and hyphenated, with any character outside the Latin set percent-encoded.desc,keywords,icon,sort_order,lead_price,image- all optional
See also: listTopCategories (list all), getTopCategory (by ID), createSubCategory (add a sub-category under this top).
Writes live data: changes are immediately visible on the public site.
Returns: { status: "success", message: {...createdRecord} } including the new profession_id. Use that value to populate users_data.profession_id on member records.
Common workflow - full 3-tier setup ("create Restaurants -> Sushi -> assign Alice"):
createCategoryTreewithgroups=[{ top_category: "Restaurants", sub_categories: ["Sushi"] }]-> returnsprofession_id(e.g. 42); read the new sub'sservice_id(e.g. 17) fromlistSubCategoriesAssign Alice:
updateUserwithuser_id=<Alice>,profession_id=42,services="17"(simple), ORcreateMemberSubCategoryLinkwithuser_id=<Alice>,service_id=17,avg_price=...,specialty=1(with per-link metadata)
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createCategoryTree, or createTopCategory / createSubCategory when a single category needs create-time field control (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| desc | No | Short internal taxonomy-row label. **Even if the user says "description" - this is NOT an SEO description.** Most BD themes don't render this field. For SEO copy on the Top-Category public search page (H1, intro, meta tags), create a WebPage with `seo_type=profile_search_results` + matching slug (see `createWebPage`). Short internal blurb only here. | |
| icon | No | Icon identifier (e.g. a Font Awesome class or image filename). | |
| name | Yes | Top-level category name (e.g. "Restaurants", "Dentists"). | |
| image | No | Image filename for the category icon/banner. | |
| filename | Yes | URL-slug form of the name (e.g. "restaurants"). Used in public profile URL paths. | |
| keywords | No | Fuzzy-search synonyms for on-site category matching - NOT SEO meta-keywords. Comma-separated single words (no spaces): synonyms, abbreviations, slang, common misspellings. Example for `Doctor`: `doc,physician,md,medic,gp,specialist`. ~5-10 max. Skip SEO phrases like `doctor near me` - those aren't fuzzy matchers. Optional. | |
| lead_price | No | Per-lead price charged for leads matching this category (decimal). | |
| sort_order | No | Display order among top-level categories. Lower = earlier. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate readOnlyHint=false and idempotentHint=false, but the description reveals key behaviors: writes are immediately visible on the public site, filename uniqueness is NOT enforced by BD, duplicate slugs make resolution undefined, and the wrapper auto-suffixes filename on collision (-1...-20). This is exactly the behavioral context an agent needs beyond the annotation flags.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and sectioned, but it is far longer than necessary and contains direct repetition: the 'Use createTopCategory or createSubCategory only for...' sentence is nearly duplicated by the later 'Use when:' section. The multi-step 3-tier workflow, member classification model, and sub-sub-category digression are useful domain context but not essential for invoking this specific tool, making it bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even without an output schema, the description states the exact return shape, required parameters, pre-check procedure with server-side filter-find, collision handling, and integration points like profession_id on user records. It is complete enough for an agent to call the tool safely and correctly in a real workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds substantial meaning: filename defaults to lowercased hyphenated name with percent-encoding, desc is an internal label and NOT an SEO description, keywords are fuzzy-match synonyms not SEO meta keywords with format examples, and each optional field is clarified. This goes well beyond the schema's short property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with explicit 'Create a new TOP-level member category. Writes live data,' naming a specific verb and resource. It also clearly distinguishes createTopCategory from createSubCategory and createCategoryTree by defining the top-level tier of the 3-tier classification.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use and when-not-to-use guidance: only for a single category needing create-time field control or a custom filename, otherwise use createCategoryTree. Also names the alternative of passing profession_name to createUser for auto-creation, and lists related list/get tools. This is model routing guidance, not just a vague hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createUnsubscribeA
Add email to unsubscribe list - Create a new unsubscribe record. Writes live data.
Use when: programmatically opting a member out of emails (e.g., from an external unsubscribe form or CRM sync). BD adds entries itself when members click email unsubscribe links.
Required: email.
Enums: definitive: 0, 1.
See also: updateUnsubscribe (modify existing).
email is the only meaningful input. Pass the email address to opt out. BD adds unsubscribe records to its global unsubscribe list - this applies across all email campaigns for the site. There is no "unsubscribe from some lists but not others" granularity via this endpoint; it's all-or-nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Email address to unsubscribe from ALL site emails. BD unsubscribe is SITE-WIDE scope - no way to unsub from some lists but not others via this endpoint. Adds the email to the global unsubscribe table. | ||
| definitive | No | 1=permanent unsubscribe |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that it writes live data, is site-wide and all-or-nothing, and affects global unsubscribe list. Annotations are minimal (readOnlyHint false, destructiveHint false) but the description adds important behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bullet-like sections (Use when, Required, Enums, See also). Around 120 words, no unnecessary fluff, though it repeats 'email is the only meaningful input' twice.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers usage, scope, and alternatives well, but fails to mention what the tool returns (no output schema). For a create tool, the agent might expect info on the created record or confirmation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds extra meaning: emphasizes that email is the only meaningful input, explains the scope of unsubscribe, and clarifies the definitive enum values (0,1). This goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool creates a new unsubscribe record for an email, with specific verb 'create' and resource 'unsubscribe'. Differentiates from sibling tools like updateUnsubscribe and deleteUnsubscribe.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use ('programmatically opting a member out of emails') and provides alternative ('See also: updateUnsubscribe') with clear context that BD also does this automatically on click.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createUserA
Create a new member/user - Create a member. Writes live data. Welcome email silent by default - set send_email_notifications=1 to trigger.
Required: email, password, subscription_id.
Use when: adding members outside BD signup - CSV imports, scraped listings, Zapier automations, admin test accounts.
Enums: active: 1=Not Active, 2=Active, 3=Canceled, 4=On Hold, 5=Past Due, 6=Incomplete. listing_type: Individual, Company. verified/nationwide: 1/0.
Prerequisites: subscription_id MUST reference an existing plan - discover via listMembershipPlans. For category assignment via profession_id / profession_name / services, apply Rule: Category taxonomy (auto-create is ON for createUser).
Parameter interactions:
auto_image_import=1- fetch external image URLs into BD storage (forprofile_photo,logo,cover_photoholding URLs). Without it, BD stores the URL as-is; images break if source host goes down. Supports JPG/PNG/GIF/WebP/SVG. Processing delay: several minutes. Recommended default for any external image URL.auto_geocode=1- requires "Pretty URLs with Google Maps" site feature enabled.send_email_notifications=1- trigger welcome email per plan settings.
Email uniqueness - controlled by site setting allow_duplicate_member_emails (not exposed via API):
OFF (default): BD rejects duplicate email on create (validation error).
ON: duplicates accepted and stored with different
user_ids. Identicalemail+passwordpair is also accepted (no extra uniqueness check on the pair).Safe idempotent pattern: pre-check via
listUsers property=email property_value=<email> property_operator==. Match found -> reuseuser_idorupdateUserinstead. Skipping the check on a duplicates-allowed site creates orphan duplicates on retry loops.
Field validation quirks:
token(if supplied — useful for CSV imports / cross-site migrations preserving original tokens; BD auto-generates if omitted): exactly 32 alphanumeric chars, unique across members.URL fields (
website,booking_link,blog,facebook,twitter,linkedin,instagram, etc.): must start withhttp://orhttps://. Invalid formats silently skipped.
Profile URL: <site-domain>/<user.filename>. filename is the complete relative path. Do NOT prepend /business///profile///member/ - BD resolves filename verbatim.
Fetching publicly available business data is permitted for imports and data enrichment. When searching for external listings, fetch each entity's image from their own presence in this order:
Logo image from their site's header/nav ->
logo(businesses).Headshot from Home, About or Team page ->
profile_photo(individuals).Follow their social links -> profile image there.
Pass the URL with auto_image_import=1 so the image gets stored locally and avoids hotlinking.
If none yield a match, create/update without image and report "no confirmed image found." Never substitute a stock photo or guess. Skip an entire record and find an alternate listing only when the user explicitly requires images.
See also: updateUser (modify existing), deleteUser (prefer active=3 over delete).
Returns: { status: "success", message: {...createdRecord} } including user_id.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | OPTIONAL: Enter latitude coordinates for the location of this user. | |
| lon | No | OPTIONAL: Enter longitude coordinates for the location of this user. | |
| blog | No | Enter the FULL URL of the user's blog. Must begin with https:// | |
| city | No | ||
| logo | No | Logo URL (brand/business mark). **Bare URL only — no `?query`, must end in `.jpg`/`.jpeg`/`.png`/`.webp`.** Query strings get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| Yes | |||
| quote | No | OPTIONAL: Enter the user's personal quote, motto or slogan. | |
| active | No | User account status. BD does NOT validate - integers outside the set store as-is (observed: `99`). Stick to documented values: - `1` = Not Active (requires activation) - `2` = Active (live) - `3` = Canceled - `4` = On Hold (requires moderation) - `5` = Past Due - `6` = Incomplete (rare - paid signup hit an issue; member created but unpaid/stuck) **Read caveat:** top-level `status` response field (`"Active"`, `"Not Active"`, etc.) is a computed label. When `active` is an unknown value, `status` is OMITTED from the response - don't treat `status` as always-present. | |
| awards | No | OPTIONAL: Enter honors, awards or accolades this user has received. | |
| tiktok | No | Enter the FULL URL of the user's Tiktok account. Must begin with https:// | |
| company | No | ||
| No | Enter the FULL URL of the user's Twitter account. Must begin with https:// | ||
| website | No | Enter the FULL URL of the user's website. Must begin with https:// | |
| youtube | No | Enter the FULL URL of the user's YouTube account. Must begin with https:// | |
| about_me | No | Long description of the member/user. Renders on their public profile. Froala body field — use `<p>`/`<h2>`/`<h3>`/`<ul>`/`<ol>` structure; skip images unless user asks. HTML allowed (per universal safe-HTML rule). | |
| address1 | No | The user's street address. | |
| address2 | No | The user's unit or suite number. | |
| No | Enter the FULL URL of the user's Facebook account. Must begin with https:// | ||
| filename | No | Override BD's auto-generated URL slug (e.g. `united-states/los-angeles/doctor/jane-smith`). If omitted, BD derives it from city/category/name. **Usually OMIT** - manual values get regenerated by BD on future updates that change URL-influencing fields, silently overwriting your override. | |
| No | Enter the FULL URL of the user's Linkedin account. Must begin with https:// | ||
| password | Yes | ||
| position | No | OPTIONAL: Enter the user's position, title or role at their company. Example: Account Executive | |
| services | No | Assign this user to sub-level categories. Input a comma-separated list of sub-level IDs or names (NO spaces around commas - `"1823,1824"` not `"1823, 1824"`). | |
| snapchat | No | Enter the FULL URL of the user's Snapchat account. Must begin with https:// | |
| state_ln | No | OPTIONAL: Enter the full name of the state / province for this user. | |
| verified | No | If YES, a verified icon badge will display on the user's listing.\n\nValid values:\n 1 = Yes\n 0 = No | |
| No | Enter the FULL URL of the user's Whatsapp account. Must begin with https:// | ||
| zip_code | No | The user's zip / postal code. | |
| No | Enter the FULL URL of the user's Instagram account. Must begin with https:// | ||
| last_name | No | ||
| No | Enter the FULL URL of the user's Pinterest account. Must begin with https:// | ||
| country_ln | No | OPTIONAL: Enter the full name of the country for this user. | |
| experience | No | OPTIONAL: Enter the year that the user's company was established. Example: 1982 | |
| first_name | No | ||
| last_login | No | Timestamp of user's last login. Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. BD updates on each login — omit unless backfilling historical data during import/migration. | |
| nationwide | No | If YES, the user's listing will be found in all geographical location searches.\n\nValid values:\n 1 = Yes\n 0 = No | |
| state_code | No | ||
| affiliation | No | OPTIONAL: Enter the accepted forms of payment this user accepts. | |
| cover_photo | No | Cover photo URL (user/profile banner). Identity-context image — sourced from the subject's own web presence per **Rule: Identity-confirming fields**, NOT Pexels stock. **Bare URL only — no `?query`, must end in `.jpg`/`.jpeg`/`.png`/`.webp`.** Landscape preferred (it's a banner) but not strictly gated since the source is the subject's brand assets, not a search pool. Query strings get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| member_tags | No | ADDITIONAL: Assign Member Tag ID | |
| rep_matters | No | OPTIONAL: Enter the hours of operation for the member. EG: Monday - Friday, 9am - 5pm | |
| signup_date | No | User signup date. Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. BD auto-fills on create — omit unless backfilling legacy signup dates during import/migration. | |
| auto_geocode | No | OPTIONAL: Allow Google to geocode users. Requires "Pretty URLs with Google Maps". Search BD support to learn more.\n\nValid values:\n 1 = Yes\n 0 = No | |
| booking_link | No | Enter the FULL URL of the user's booking page. Must begin with https:// | |
| country_code | No | ||
| listing_type | No | Listing type classification. Canonical values (EXACT case): `Individual` or `Company`. BD does NOT validate - off-canonical values (`individual`, `INDIVIDUAL`, `Business`) store verbatim and break downstream `listing_type === "Individual"` checks. **Always include explicitly on `createUser`.** BD's server-side default when omitted is `Individual` - if you want `Company` as your default (recommended for scraped business listings, CSV imports), you MUST send it explicitly; do NOT rely on omission. Default to `Company`, override to `Individual` when: (1) user explicitly says so, (2) structured input specifies `listing_type` per-record (normalize case client-side), (3) source clearly describes a person, not a business. | Company |
| phone_number | No | ||
| profession_id | No | Assign this user to a top level category. Input the ID number of the top level category. | |
| profile_photo | No | Profile photo URL (member headshot). **Bare URL only — no `?query`, must end in `.jpg`/`.jpeg`/`.png`/`.webp`.** Query strings get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| profession_name | No | Alternative to `profession_id` - pass the top-level category NAME as a string. BD looks it up in `list_professions`. **Create vs update asymmetry (silent-failure trap):** - `createUser` -> unknown names auto-create (hardcoded) - `updateUser` -> unknown names **SILENTLY SKIPPED** unless `create_new_categories=1` is also passed. The write succeeds and returns success; the category just doesn't change. Always pass `create_new_categories=1` on update when supplying a `profession_name` that might not exist. | |
| subscription_id | Yes | Membership plan ID | |
| auto_image_import | No | If YES, system will import user images and save them to your website. Processing may take several minutes after import.\n\nValid values:\n 1 = Yes\n 0 = No | |
| search_description | No | Short description shown under the user's name on search result pages. **170-char limit.** | |
| send_email_notifications | No | Set to `1` to trigger the welcome email on member creation (based on the membership plan's configured email). Default: off - API creates are silent because they typically aren't self-signups. Only set this when you WANT the member notified. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description details behavioral traits such as writes live data, silent welcome email default, email uniqueness handling, field validation quirks (URL format, token length), and parameter interactions (auto_image_import delay, auto_geocode requirement).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with clear headings (Required, Use when, Enums, Prerequisites, etc.) and front-loaded with the core purpose. Some redundancy exists (e.g., repeated URL format notes), but the structure makes it scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 54 parameters, no output schema, and high complexity, the description covers prerequisites, parameter interactions, edge cases (duplicate emails, silent failures), return format, and even data sourcing guidelines. It is exceptionally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite high schema coverage (83%), the description adds substantial meaning: enum explanations (active states, listing_type default/case sensitivity), format requirements (services comma-separated, bare image URLs, YYYYMMDDHHmmss timestamps), and asymmetries (profession_name create vs update).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Create a new member/user' and provides specific use cases (CSV imports, scraped listings, Zapier automations, admin test accounts), clearly distinguishing this tool from siblings like createLead or createForm.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Use when' section and 'See also' reference (updateUser, deleteUser) provide explicit guidance on when to use this tool versus alternatives, along with prerequisites and idempotent patterns for email duplication.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createUserPhotoA
Create a user photo - Create a new userphoto record. Writes live data.
Use when: attaching a new photo record to a member. The image file must already exist in site storage (upload via admin or auto_image_import).
Required: user_id, file, type.
Parameter interactions:
user_id- the membertype- slot:logo,photo, orcover_photofile- image filename (must already exist in site storage)
See also: updateUserPhoto (modify existing).
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Image filename | |
| type | Yes | ||
| user_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal readOnlyHint=false and destructiveHint=false. Description adds 'Writes live data' but no further behavioral details beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections, front-loaded purpose, and no fluff. Minor redundancy in opening sentence but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage, prerequisites, parameter details, and alternative. Lacks output info but acceptable without output schema. Sufficient for a create tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (33%), but description explains each parameter: user_id as member, type with enum values, and file requirement (must exist in storage), adding significant meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Create'), resource ('user photo'), and distinguishes from siblings by specifying 'Create a new userphoto record' and referencing 'updateUserPhoto' for modifications.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use ('attaching a new photo record to a member'), prerequisite (image must exist in site storage), and replaces 'See also' with alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createWebPageA
Create a page - Create a list_seo page record. Writes live data.
Cache refresh is automatic. Response includes auto_cache_refreshed: true after successful writes; no manual refreshSiteCache call needed. If auto_cache_refreshed: false, check auto_cache_refresh_error and retry refreshSiteCache once.
Required fields: seo_type. filename is required for every seo_type EXCEPT data_category (the WRAPPER generates a 10-char lowercase alphanumeric placeholder slug for that type and auto-creates a 301 redirect to the canonical post-type URL; the public URL routes via the post type's data_filename, not list_seo.filename). When seo_type=data_category, linked_post_type is also required (auto-validated at runtime).
Filename uniqueness — enforced by the wrapper, no exceptions. BD does NOT enforce unique filename server-side, but duplicates break the platform (two pages at the same URL render non-deterministically). The wrapper auto-pre-checks listWebPages for an existing slug before forwarding the create. If a row exists, the create is rejected with the existing seo_id so the agent can updateWebPage instead, or pick a unique slug. There is no agent-facing bypass; for seo_type=data_category the wrapper generates the slug itself (10-char lowercase alphanumeric — statistically unique across 36^10, no pre-check needed).
Thin-content warning: if no title, h1, meta_desc, or content is set on a seo_type=content create, a _thin_content_warning field is attached to the response. The page is still created and is publicly live — Google may index it as thin content. Fix: provide at least one of those fields on the create call, or updateWebPage immediately after, or deleteWebPage if the create was premature.
Asset field routing (mandatory - Froala strips mismatched content silently):
content- body HTML. No<style>/<script>tags. Supports[widget=Name]shortcodes +%%%token%%%.content_css- raw CSS rules. NO<style>wrapper. Scope to a unique page class; never target.container/.froala-table/.image-placeholder(reserved). Do NOT use@import(causes FOUC/CLS - usecontent_head<link>tag instead).content_footer_html- JavaScript, pixels, analytics embeds (<script>tags OK here). IIFE-wrap + scope.content_head- head-only deps (<link>,<meta>, JSON-LD, external stylesheets, fonts).content_footer- MISLEADING NAME. NOT footer HTML. Page-access gate enum:""(public),"members_only","digital_products".Hero banner ->
enable_hero_section+hero_*+h1_*/h2_*fields.
All asset fields accept raw content verbatim. No CDATA, no <parameter>/<invoke>/<function_calls> scaffolding, no entity-escaped HTML — forbidden anywhere in the value, not just as wrappers. Server strips these as a safety net; do not rely on it.
SVG/canvas prohibited in content - Froala strips them. Charts/diagrams go in a custom Widget, embedded via [widget=Name] shortcode.
seo_type values: home (system-seeded; cannot CREATE homepage, only updateWebPage), content (generic static page), profile_search_results (member search override — apply Rule: Member search SEO pages), data_category (post search), custom_widget_page, password_retrieval_page, unsubscribed.
Hero section - when enable_hero_section = 1 or 2, apply Rule: Hero readability bundle (atomic — all listed values must be sent together). Notes:
All color fields RGB ONLY (
rgb(0, 0, 0)) - hex not accepted.Hero
h1_*/h2_*fields style ONLY the hero banner; H1/H2 TEXT comes from the record's top-levelh1/h2fields.Hero image: content-relevant Pexels stock photo (free license, no attribution). See Rule: Image URLs (imported field — bare URL, no query string). Never
picsum.photos/lorempixel/placekitten.Hero gap-fix CSS (
seo_type=contentONLY): add.hero_section_container + div.clearfix-lg {display:none}tocontent_cssto close BD's 40px clearfix gap. Never add this rule on any otherseo_type- onprofile_search_results/data_categorythe clearfix provides needed spacing before live search-results; hiding it causes results to butt-join the hero.Hero is cache-gated — but
createWebPage/updateWebPageauto-refresh handles it; no separate call needed.Homepage hero is BENIGN:
seo_id=1stores hero fields but the homepage template does NOT render them. Skip hero fields on homepage unless user explicitly asks.
profile_search_results SEO pages - thin-content remedy workflow:
Used to override BD's auto-generated dynamic search URLs (e.g. california/beverly-hills/plumbers) with static custom SEO copy. Creating a list_seo row with a matching filename takes over the public URL.
CRITICAL - filename MUST be a real slug BD's dynamic router recognizes. Arbitrary slugs render HTTP 404 publicly even when the record is created successfully. See Rule: Member search SEO pages for the canonical slug hierarchy (country/state/city/top/sub, strict order, any subset valid) and the live-lookup endpoints for each segment. Wrapper validates segments at runtime — country slug is derived from country_name (lowercase + spaces→hyphens). For arbitrary-URL static pages use seo_type=content.
Workflow for "add SEO to [category] in [location]":
Resolve each human name to its slug via the relevant
list*endpoint (exact-match=).For ambiguous inputs (e.g. "Beverly Hills plumbers" - could be
beverly-hills/plumbersorcalifornia/beverly-hills/plumbers), ask user which variant.Pre-check:
listWebPages property=filename property_value=<slug> property_operator==. Exists ->updateWebPage. Missing ->createWebPagewith the required defaults listed in step 4.Required defaults on create and every update (unless user overrides):
seo_type=profile_search_resultscustom_html_placement=4(Below Body Content - safest for boilerplate intro without disrupting live results)form_name="Member Search Result"(sidebar - Master Default; do NOT useMember Profile Page, that's for profile pages)menu_layout=3(Left Slim sidebar position)enable_hero_section=1+ content-relevant Pexelshero_image+ the readability safe-defaults from Rule: Hero readability bundle (atomic — all listed values must be sent together). Most end-users don't know to ask for a hero; thin-SEO pages underperform without one. User can opt out withenable_hero_section=0. (Cache flush is automatic post-write.)
Auto-generate SEO meta for the specific combo - don't leave blank:
title- 50-60 chars ideal, <=70 max. Pattern:"[Category] in [City], [State] | [Site Name]".meta_desc- 150-160 chars ideal, <=170 max. 1-2 sentence pitch with location + CTA.meta_keywords- ~200 chars, comma-separated (no spaces).facebook_title- 55-60 chars, differ fromtitle(more conversational).facebook_desc- 110-125 chars, punchier thanmeta_desc.Do NOT auto-set
facebook_image(needs uploaded asset).
H1/H2 double-render trap: if hero enabled AND
contentcontains<h1>/<h2>, both render. Either seth1/h2fields and omit fromcontent, or put incontentand leave fields blank. Never both.No max-width wrappers in
contentorcontent_cssonprofile_search_resultspages. BD's layout already provides the outer container; addingmax-width: 960px; margin: autodouble-constrains to a narrow strip. Let content flow at natural container width.custom_html_placementis only meaningful onprofile_search_results(anddata_category). Ignored oncontentpages.
SEO content for categories: route to createWebPage seo_type=profile_search_results (NOT updateTopCategory.desc / updateSubCategory.desc - those are internal labels, not rendered).
list_seo EAV fields — auto-routed by the wrapper, no special handling. Pass any field on createWebPage / updateWebPage directly; if it's an EAV-stored field (e.g. hero_*, h1_*, h2_*, linked_post_category, disable_*), the wrapper routes the write through users_meta automatically. Response includes an eav_results array confirming which EAV fields were written. Reads merge automatically via getWebPage/listWebPages. On deleteWebPage: BD does NOT cascade — run orphan cleanup per Rule: users_meta orphans (listUserMeta filtered by database=list_seo+database_id=<deleted seo_id>, then deleteUserMeta each match).
See also: listWebPages, updateWebPage, createRedirect (preserve SEO on slug changes).
Returns: { status: "success", message: {...createdRecord}, auto_cache_refreshed: true|false, auto_cache_refresh_error?: "...", _admin_edit_url: "..." } including seo_id. auto_cache_refreshed reports whether the automatic cache flush succeeded; if false, auto_cache_refresh_error explains why and the agent should retry refreshSiteCache manually once. _admin_edit_url is a centralized-admin deep-link to the WebPage editor for this seo_id — surface it to the user so they can jump straight to the admin edit screen for the page just created.
| Name | Required | Description | Default |
|---|---|---|---|
| h1 | No | **H1 Heading** - Supports template tokens. Rendered as the page's main heading. H1 heading - supports template tokens | |
| h2 | No | **H2 Heading** - Supports template tokens. H2 heading - supports template tokens | |
| title | No | **Page Meta Title** - Supports template tokens: `%%%website_name%%%`, `%industry%`, `%profession%`, etc. ~30-60 chars recommended. HTML title tag - supports template tokens like %%%website_name%%% | |
| content | No | Main page body - Froala rich-text editor. **Shortcodes:** `[form=<form_name>]` embeds a BD form; `[widget=<widget_name>]` embeds a widget; `%%%template_tokens%%%` for site vars. **HTML only** - Froala strips `<style>`, `<script>`, `<form>`, `<input>`, `<select>`, `<textarea>`, `contenteditable=`, AND inline `style="..."` attributes on save. Route all non-body assets to their dedicated fields: CSS -> `content_css` (target classes, not inline styles), JS -> `content_footer_html`, head deps (`<link>`, fonts, `<meta>`, JSON-LD) -> `content_head`. SVG/canvas also stripped; for charts/diagrams use a custom Widget embedded via `[widget=Name]` shortcode. | |
| filename | No | URL slug (e.g. home, about-us). Must be unique across web pages, top categories, sub categories, plan public URLs, and member profile slugs — wrapper auto-rejects collisions. Either pick a unique slug or `updateWebPage` the existing record. **OPTIONAL on `seo_type=data_category`** — the WRAPPER generates a 10-char lowercase alphanumeric placeholder slug if omitted (or rewrites a non-conforming agent-supplied value), and auto-creates a 301 redirect from that slug to the canonical post-type URL. The public URL routes via the post type's `data_filename` + category, not `list_seo.filename`. REQUIRED on every other seo_type. | |
| nickname | No | Human-readable label shown in admin panel | |
| seo_text | No | **Wildcard URL Rewrite.** `1` = any URL within this directory routes to this web page (catch-all behavior). Misnamed field - NOT SEO copy; SEO copy goes in `content` + meta fields. | |
| seo_type | Yes | Page type identifier. User-selectable values: - `content` = Single Web Page (USE for custom/landing/static/about/contact - the default) - `data_category` = Post Search Results - `profile_search_results` = Member Search Results - `custom_widget_page` = Custom Widget as Web Page - `password_retrieval_page` = Password Retrieval Page - `unsubscribed` = Unsubscribed Page For "landing page", "static page", "about page", "contact page", any generic custom page -> always `content`. BD has additional internal values (`home`, `profile`, `payment`, etc.) that are system-seeded - do NOT create via API. | |
| form_name | No | **SIDEBAR name** for this page - BD's field is misnamed; controls sidebar slot, NOT a contact form. NOT for rendering forms on this page — to embed a form in the body, use `[form=<form_name>]` inside `content`. Pass exact sidebar `name` string. `""` = no sidebar. Valid values: a Master Default Sidebar OR a custom sidebar `name` from `listSidebars`. See **Rule: Sidebars** for the canonical Master Default list and selection workflow. `menu_layout` controls position when `form_name` is set. **Default on `profile_search_results` pages:** `Member Search Result` (NOT `Member Profile Page` - that's for profile/detail pages, not search results). | |
| meta_desc | No | **Meta Description** - Supports template tokens. ~150-160 chars recommended for search snippets. Meta description - supports template tokens | |
| show_form | No | **Apply NoIndex,NoFollow.** `1` = adds `<meta name="robots" content="noindex,nofollow">` to the page. Auto-applied to protected pages. **NOT a form-render toggle** despite the field name — BD repurposed this column. To render a form in the body, use `[form=<form_name>]` inside `content`. | |
| breadcrumb | No | **OMIT** — BD auto-generates the breadcrumb trail. Never set this yourself; a manual value overrides BD's generated trail and breaks the page. | |
| hero_image | No | Hero background image. Accepts BD-hosted relative path (`/images/bg202.webp`) OR external URL (`https://cdn.example.com/banner.jpg`) — external URLs render hotlinked on WebPages, no `auto_image_import` needed. **LANDSCAPE only — verify orientation via `getImageDimensions` per **Rule: Image dimensions** before commit; bare URL, no `?query`, must end in `.jpg`/`.jpeg`/`.png` (WebP/GIF/AVIF skipped pre-tool per the same rule) — see **Rule: Image URLs**.** Query strings get truncated/mangled in BD's form-urlencoded parsing and the stored URL becomes invalid. Recommended dimensions: 1800 × 600 px. | |
| content_css | No | Custom CSS for this page. Paste raw CSS rules directly - NO `<style>` wrapper. Renders in page `<head>` at load. Scope every selector to a unique page class/ID (e.g. `.my-about-page h2 { ... }`) - bare `body`/`h1`/`p` affect the whole site. Never target reserved BD classes: `.container`, `.froala-table`, `.image-placeholder`. Never `@import` (FOUC/CLS) - load external stylesheets/fonts via `<link>` tag in `content_head`. **Admin Froala editor gotcha** - editor applies `content_css` but does NOT run `content_footer_html` JS. Hide-by-default CSS (scroll reveals, tab panels, accordion collapsed, modal hidden, slider non-active slides) will permanently hide content in the editor. Gate such rules behind a `.js-ready` class that `content_footer_html` JS adds on load: `.my-page.js-ready .reveal { opacity:0 }` NOT `.my-page .reveal { opacity:0 }`. The paired JS rule lives in the `content_footer_html` field. | |
| hide_footer | No | **Hide Footer** - 1 = hides the site footer on this page. | |
| hide_header | No | **Hide Header** - 1 = hides the full site header on this page. | |
| menu_layout | No | Sidebar position + width (integer). Only effective when the page has a sidebar set via `form_name` - ignored without sidebar. NOT a navigation menu layout despite the field name. - `1` = Left Wide (BD default when unspecified) - `2` = Right Wide - `3` = Left Slim - `4` = Right Slim Ordering is NOT sequential by side - left positions are `1` and `3`, right are `2` and `4`. **Default on `profile_search_results` pages:** `3` (Left Slim). On `content` pages, omit unless user specifies (BD defaults to `1`). | |
| content_head | No | Page-scoped `<head>` dependencies - rendered inside `<head>`. Use for: `<link>` tags (external stylesheets, preconnect hints, canonical overrides, Google Fonts), `<meta>` tags beyond standard SEO fields, verification tags, JSON-LD structured data (`<script type="application/ld+json">`), head-required third-party scripts (rare - prefer `content_footer_html` for most JS). | |
| content_menu | No | Menu section this page belongs to | |
| h1_font_size | No | Main title (H1) font size in pixels. Accepts integer values from `30` to `80`. OMIT to inherit BD's per-`seo_type` default. | |
| h2_font_size | No | Sub-title (H2) font size in pixels. Accepts integer values from `20` to `60`. OMIT to inherit BD's per-`seo_type` default. | |
| org_template | No | **OMIT** — internal layout reference. No public lookup endpoint; setting an arbitrary value can render the page against a nonexistent layout. | |
| content_group | No | Admin-panel grouping label | |
| content_order | No | Sort order within menu/section | |
| facebook_desc | No | **Social Media Description (Open Graph)** - Description shown on social shares. Open Graph description | |
| h1_font_color | No | Main title (H1) font color in the hero. RGB format ONLY - e.g. `rgb(255, 255, 255)`. The H1 text itself comes from the page's `h1` field - these `h1_*` fields control ONLY the hero's H1 styling. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| h2_font_color | No | Sub-title (H2) font color in the hero. RGB format ONLY - e.g. `rgb(255, 255, 255)`. The H2 text itself comes from the page's `h2` field. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_link_url | No | Hero call-to-action (CTA) button link URL. If empty, no CTA button is rendered. For internal links, a relative path is fine (e.g. `/signup`); for external, full URL with `http://` or `https://`. | |
| meta_keywords | No | **Meta Keywords** - Supports template tokens (comma-separated). Meta keywords - supports template tokens | |
| content_footer | No | **MISLEADING NAME - NOT page footer HTML.** Misnamed relic column; BD repurposed as the **page-access gate**: - `""` (default) = Public For Everyone - `"members_only"` = Logged-in members only (non-members hit login/signup wall) - `"digital_products"` = Only buyers of digital-product items Finer rules (which members, which plans) live in other fields. Do NOT put HTML here. Page body -> `content`; scripts -> `content_footer_html`. No dedicated "below-body HTML" field - put below-body markup inside `content` itself. | |
| content_layout | No | **Full Screen Page Width override.** OMIT for normal pages (BD's default container width). Set to `1` for full-bleed pages — individual sections in `content` can then break edge-to-edge (background bands, hero strips, viewport-wide images). **For full-bleed sections, set `content_layout=1` FIRST.** Do NOT fake full-bleed with negative-margin/9999px-padding tricks in `content_css` — breaks horizontal scroll, fights `overflow: hidden` parents, prevents future layout changes. Anti-pattern. Pattern with `content_layout=1`: scoped CSS in `content_css` gives each section its own edge-to-edge background; inner `<div class="container">` (or page-scoped max-width wrapper) keeps readable copy centered. | |
| facebook_image | No | **Social Media Shared Image** - URL/filename of the OG image. BD recommends at least 200×200px. Open Graph image URL | |
| facebook_title | No | **Social Media Title (Open Graph)** - Title shown when the page is shared on Facebook/LinkedIn/etc. Open Graph title for social sharing | |
| h1_font_weight | No | Main title (H1) font weight. `300`=Light, `400`=Normal (default), `600`=Bold, `800`=Extra Bold. | |
| h2_font_weight | No | Sub-title (H2) font weight. `300`=Light, `400`=Normal, `600`=Bold (default), `800`=Extra Bold. | |
| hero_alignment | No | Horizontal alignment of the hero title/subtitle/content text block within its column. Default `center`. | |
| hero_link_size | No | CTA button size. MUST be exactly one of: `""` (empty = Normal), `btn-lg` (Large), `btn-xl` (Extra Large). Any other value (e.g. a font-size number like `16`) is stored verbatim and rendered as a broken class — BD does not validate server-side. | |
| hero_link_text | No | Hero CTA button label. Required (non-empty) for the button to render - `hero_link_url` alone without text will not produce a button. | |
| hide_top_right | No | **Hide Top Header Menu** - 1 = hides the top-right nav cluster (account/login links). | |
| content_sidebar | No | Sidebar configuration or widget shortcode | |
| hero_link_color | No | CTA button color variant — attention level, not literal color. MUST be exactly one of: `primary`, `info`, `success`, `warning`, `danger`, `default`, `secondary`. Any other value (e.g. a hex `#ffffff`) is stored verbatim and rendered as a broken class like `btn-#ffffff` — BD does not validate server-side. Choose by attention level needed: `primary` (main CTA), `danger` (urgent/can't-miss), `warning` (attention), `success` (positive action), `info` (neutral-blue), `secondary` (theme secondary), `default` (low-emphasis gray). Actual rendered color comes from the site's theme palette. | |
| allowed_products | No | Comma-separated plan/product IDs (empty = all plans) | |
| hero_top_padding | No | Top padding inside the hero banner, in pixels. Accepts multiples of 10 from `0` to `200`. BD field default `70` — wrapper auto-fills `100` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| linked_post_type | No | Post type's `data_id` (from `listPostTypes`). REQUIRED when `seo_type=data_category`; ignored on other seo_types. See **Rule: Resource disambiguation** when the user names a post type by description rather than `data_id`. | |
| hero_column_width | No | Hero text-content column width as Bootstrap 12-col span. `3`=25%, `4`=30%, `5`=40%, `6`=50%, `7`=60%, `8`=70%, `9`=75%, `10`=80%, `11`=90%, `12`=100%. Narrower = more side padding around the text block. BD field default `8` — wrapper auto-fills `5` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hide_header_links | No | **Hide Main Menu** - 1 = hides the main navigation menu on this page. | |
| page_render_widget | No | **OMIT** — internal widget reference for `seo_type=custom_widget_page` only. No public widget-ID lookup; setting on other page types breaks rendering. | |
| content_footer_html | No | Page-scoped JavaScript + script embeds - rendered before `</body>`. `<script>` tags accepted here (unlike `content`). jQuery loaded globally. Wrap JS in an IIFE `(function($){ ... })(jQuery);` and scope selectors to a unique page class. Also for third-party script embeds (analytics pixels, chat widgets, schema markup). NOT for extra body HTML - `content` is the body field. **If `content_css` uses a `.js-ready` gate for hide-by-default effects** (scroll reveals, tab panels, accordion collapse, modal hidden, slider non-active), JS MUST add that class to the page wrapper as the FIRST line (before any other init code): `document.querySelector('.my-page')?.classList.add('js-ready');`. The admin Froala editor applies CSS but does NOT run this field's JS, so without the gate, hide-rules make content permanently invisible in the editor. | |
| enable_hero_section | No | Hero banner master switch: - `0` = disabled (all other `hero_*`/`h1_font_*`/`h2_font_*` ignored at render; stored values preserved for later toggle-back) - `1` = enabled all devices - `2` = enabled desktop, hidden mobile **On hero off→on transition (`0`/unset → `1`/`2`), wrapper auto-fills the hero readability bundle** — `hero_top_padding=100`, `hero_bottom_padding=100`, `hero_column_width=5`, `hero_content_overlay_color=rgb(0, 0, 0)`, `hero_content_overlay_opacity=0.5`, `hero_content_font_color=rgb(255, 255, 255)`, `hero_content_font_size=18`, `h1_font_color=rgb(255, 255, 255)`, `h2_font_color=rgb(255, 255, 255)` — for any of those 9 fields you OMITTED. BD's per-field defaults render an unreadable hero (10px content text on a 0.4-opacity overlay, default top/bottom padding 70/60 — visually too cramped for most banner imagery); the bundle is the canonical readable recipe. User-supplied values pass through untouched. Filled fields are echoed in `_hero_bundle_autofilled`. **`hero_image` is required** on transition — wrapper rejects if missing (no safe default; walk the image-sourcing ladder). On no-transition updates (hero already on), no auto-fill fires. **Homepage benign** - `seo_type=home` ignores hero fields entirely regardless of value. BD stores but never renders on homepage; skip all `hero_*` fields on homepage updates. | |
| hero_bottom_padding | No | Bottom padding inside the hero banner, in pixels. Accepts multiples of 10 from `0` to `200`. BD field default `60` — wrapper auto-fills `100` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_hide_banner_ad | No | When `1`, suppresses the site-wide "Below Header Banner Ad" on THIS page only (useful when the hero visually replaces that slot). `0` (default) keeps the banner ad in its normal position. | |
| private_page_select | No | Access control setting | |
| hero_section_content | No | Additional text / HTML / widget shortcode rendered BELOW H1 and H2 in the hero section. Supports `[widget=Name]` shortcodes. EAV-routed by the wrapper — pass on `createWebPage` / `updateWebPage` directly, no manual `updateUserMeta` needed. | |
| linked_post_category | No | Either the literal `post_main_page` (pins to the post type's main search-results page) OR an exact category name from the linked post type's `feature_categories` (e.g. `"Category 1"`, case-sensitive). Optional on `seo_type=data_category` — wrapper auto-defaults to `post_main_page` when omitted on a fresh data_category create or content→data_category switch. Ignored on other seo_types. Wrapper enforces pair-uniqueness on `(linked_post_type, linked_post_category)`. | |
| custom_html_placement | No | Render position of `content` HTML relative to dynamic search results. Only meaningful on `seo_type=profile_search_results` (and `data_category`); ignored on `content` pages. - `0` = Inside Tab (content + members in separate nav tabs) - `1` = Above Member Results (within results container, sidebar-width) - `2` = Below Member Results (within results container) - `3` = Above Body Content (full page width, spans sidebar+results) - `4` = Below Body Content (full page width, below sidebar+results) <- **recommended default for AI-generated SEO pages** For boilerplate SEO intro/FAQ/local copy bolstering thin pages, `4` renders full-width below the live results without disrupting member-facing UX. | |
| hero_content_font_size | No | Font size in pixels for the additional hero content block (`hero_section_content`). Accepts integer values from `10` to `30`. BD field default `10` is too small for hero paragraph copy — wrapper auto-fills `18` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_link_target_blank | No | When `1`, opens the CTA link in a new tab (`target="_blank"`). `0` (default) opens in the same tab. | |
| disable_css_stylesheets | No | Disable BD's site stylesheets on this page (frontend only). `1` = page renders without BD's global CSS (use when embedding a fully self-styled custom page or iframe target). `0` (default) = normal BD styling. EAV-stored — agent passes directly; wrapper handles routing on update. | |
| hero_content_font_color | No | Font color for the additional hero content block rendered below H1/H2 (the `hero_section_content` field). RGB format ONLY - e.g. `rgb(0, 0, 0)`. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_background_image_size | No | Controls how the hero background image scales/crops across devices. `mobile-ready` (recommended) = responsive behavior tuned for mobile, `standard` = fixed-ratio behavior. | |
| hero_content_overlay_color | No | Semi-transparent color layer between hero background image and text, for legibility over busy images. **RGB format ONLY** - `rgb(0, 0, 0)` or `rgb(255, 255, 255)`. Hex (`#000000`) NOT accepted. Combine with `hero_content_overlay_opacity` to control strength. Wrapper auto-fills `rgb(0, 0, 0)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_content_overlay_opacity | No | Opacity of `hero_content_overlay_color` layer, 0.1 increments from `0.0` (transparent) to `1` (opaque). Admin UI labels 0-10. BD field default `0.4` is too transparent — wrapper auto-fills `0.5` on hero off→on transition (part of **Rule: Hero readability bundle**). EAV-routed by the wrapper — pass on `updateWebPage` directly, no manual `updateUserMeta` needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide no behavioral hints (readOnlyHint=false, destructiveHint=false, etc.), so the description carries full burden. It fully discloses: writes live data, automatic cache refresh, thin-content warnings, asset field routing, hidden behaviors (e.g., breadcrumb auto-generation, hero readability autofill). No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
While the description is very long, it is well-structured with sections, bullet points, and bold headings. It front-loads a summary. Given the tool's complexity (62 parameters, many edge cases), the length is justified. However, it could be slightly more concise without losing essential details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: creation workflow, field dependencies, error handling (auto_cache_refreshed), return value structure, and integration with other tools. Even without an output schema, the description fully explains response fields. Addresses edge cases like filename uniqueness, EAV routing, and thin-content warnings. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, but the description adds extensive context beyond the schema. For example, explains the actual meaning of misnamed fields like content_footer and form_name, details hero section parameter interactions, and provides enum value semantics. This extra context is crucial for correct usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Create a page - Create a `list_seo` page record. Writes live data.' The verb 'create' and resource 'list_seo page record' are precise. Distinguishes from siblings like updateWebPage, listWebPages, and deleteWebPage by mentioning them and their use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use and when-not-to-use guidance. For example, when filename exists, recommends updateWebPage instead. Details workflows for profile_search_results pages, when to use createRedirect, and when to omit certain fields. Also explains when to use different seo_types.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createWidgetA
Create a widget - Create a new widget (reusable HTML/CSS/JS component). Writes live data.
Cache refresh is automatic. Response includes auto_cache_refreshed: true after successful writes; no manual refreshSiteCache call needed. If auto_cache_refreshed: false, check auto_cache_refresh_error and retry refreshSiteCache once.
Use when: programmatically adding a new reusable block to embed via [widget=Name] shortcode on pages or email templates. Rare in practice - widgets are usually created via BD admin UI where the editor supports live preview. API creation is useful for bulk imports, cross-site migrations, or scripted widget generation.
Required: widget_name (should be unique per site).
widget_name format: alphanumeric + spaces + hyphens + plus + underscores only ([A-Za-z0-9 -+_]+). Special chars (slashes, dots, ampersands, quotes, brackets, etc.) break [widget=Name] shortcode resolution and are runtime-rejected by the wrapper. Examples: Mortgage Calculator, Service-Card, Email_Validator_v2, C++ Course.
Pre-check before create: BD does NOT enforce uniqueness on widget_name. Duplicates break [widget=Name] shortcode resolution - which widget renders at the shortcode is undefined. Do a server-side filter-find: listWidgets property=widget_name property_value=<proposed> property_operator==. Zero rows = name free; >=1 row = taken. Do NOT paginate unfiltered lists looking for the name - on sites with hundreds of custom widgets that burns rate limit for nothing.
On collision (auto-suffix flow): if the proposed name is taken, append -v2 and re-check. Still taken? Try -v3, -v4, ... up through -v10. First free suffix wins. Only if all 10 are taken, ask the user for a different base name. Never silently create a duplicate.
Route by type BEFORE writing values: decide what each piece of code is, then put it in the matching field — HTML → widget_data, CSS → widget_style, JS → widget_javascript. A self-contained block with all three concatenated into widget_data will save successfully but silently break: widget_data strips backslashes on render, mangling regex literals (\d, \s), string escapes (\n, \t), and unicode escapes (\u0022). The other two fields do not strip backslashes. Split by type from the start.
Common fields on create:
widget_data- the HTML contentwidget_style- CSS (scoped to the widget viawidget_classordiv_id)widget_javascript- JS (runs when widget is rendered on a page)widget_viewport-front(public),admin(admin panel only), orbothbootstrap_enabled=1- ensures Bootstrap framework loaded when this widget is renderedwidget_html_element- wrapper element (defaultdiv)
See also: updateWidget (modify existing), listWidgets (check if name is taken first), getWidget (verify storage after create).
Writes live data: the widget is available immediately but does nothing until referenced by a [widget=Name] shortcode on a page or email template.
Returns: { status: "success", message: {...createdRecord}, auto_cache_refreshed: true|false, auto_cache_refresh_error?: "..." } including the new widget_id.
Post-create verification (recommended, especially when uncertain about routing): call getWidget once to confirm widget_data contains only HTML, widget_style contains your CSS, and widget_javascript contains your JS wrapped in <script>...</script>. If anything landed in the wrong field, call updateWidget to relocate before the user tests the widget. Proactive relocation here is correct and does NOT violate the "don't relocate without user-reported breakage" rule on updateWidget — that rule applies to subsequent edits, not to self-correcting your own just-created record.
For the full field list, see listWidgets.
| Name | Required | Description | Default |
|---|---|---|---|
| widget_data | No | HTML only. No `<style>`, no `<script>` — render strips backslashes here (`\d`→`d`, `\n`→`n`, `\t`→`t`, `\\`→`\`). JS with stripped escapes throws SyntaxError on parse — every handler unbound, widget renders but no clicks/inputs work. Fix: relocate to `widget_javascript`, do not rewrite JS to avoid backslashes. Put CSS in `widget_style`, JS in `widget_javascript`. See **Rule: Widget code fields**. | |
| widget_name | Yes | ||
| widget_style | No | Raw CSS. No `<style>` wrapper — BD wraps at render. Wholly-wrapped value: outer wrapper stripped on storage; concatenated wrappers not stripped. See **Rule: Widget code fields**. | |
| widget_viewport | No | ||
| bootstrap_enabled | No | ||
| widget_javascript | No | JS with `<script>...</script>` wrapper required. BD does not auto-wrap; unwrapped content renders as inert text. No backslash-strip on this field — regex literals (`\d`, `\w`, `\s`) AND string escapes (`\n`, `\t`, `\\`) survive intact. See **Rule: Widget code fields**. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behaviors beyond annotations: automatic cache refresh, no uniqueness enforcement, backslash stripping in widget_data, route-by-type rules, and post-creation verification. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bold headings and bullet points, but is quite lengthy. However, every section serves a purpose, and key info is front-loaded. A slight reduction could improve conciseness, but it's well organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 6 parameters and no output schema, the description provides a complete picture: creation process, uniqueness handling, field routing, return format, cache behavior, and verification steps. References listWidgets for full field list. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 50% schema coverage, the description compensates extensively: explains widget_name format with regex, pre-check uniqueness logic, auto-suffix flow, routing by type (HTML/CSS/JS), common fields, and post-create verification. Adds significant value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Create a widget - Create a new widget (reusable HTML/CSS/JS component). Writes live data.' It identifies the resource (widget) and the action (create), distinguishing it from sibling tools like updateWidget, listWidgets, and getWidget by mentioning them under 'See also'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides when to use: 'Use when: programmatically adding a new reusable block to embed via [widget=Name] shortcode on pages or email templates.' It notes rarity and alternatives (BD admin UI), and references sibling tools for checking uniqueness and verification.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteClickADestructiveIdempotent
Delete a click record - Permanently delete a click record by ID. Destructive - cannot be undone via API.
Use when: removing test or spam click records from analytics. Does NOT affect the member's click counter if the site displays one.
Required: click_id.
See also: updateClick (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| click_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide destructiveHint=true and idempotentHint=true. The description adds that deletion is permanent, unrecoverable, requires user confirmation for bulk use, and does not affect click counter, all beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise and well-structured: action, usage, required param, see also, destructive warning, return format. Every sentence adds value; no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool with no output schema, the description covers purpose, usage, parameter, side effects, and return format. No evident gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description must compensate. It names the required parameter 'click_id' and provides context for its use, but does not elaborate beyond the name. Still adequate for a simple integer ID.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the verb 'Delete' and resource 'click record', and specifies 'by ID'. It distinguishes from siblings like 'updateClick' and other delete tools by focusing on click records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when:' section for removing test/spam clicks, states what it does NOT affect (member click counter), and suggests 'updateClick' as alternative for modification without deletion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteDataTypeADestructiveIdempotent
Delete a data type - Deletes a data type definition. Records (posts, portfolio groups) referencing a deleted data type may become orphaned - confirm with the user before deleting.
Use when: removing an unused data type. Posts/groups referencing it orphan - clean up first.
Required: data_id.
See also: updateDataType (modify without removing).
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | Yes | Data type primary key |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint=true), the description details that records referencing a deleted data type may become orphaned and advises user confirmation. Also specifies the return format for the delete operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured with bullet points. It front-loads the purpose and each sentence adds necessary information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a simple tool with one parameter, no output schema, and annotations covering destructive nature, the description provides sufficient context including side effects and return format. It meets all needs for correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (data_id) with 100% schema description coverage. The description adds minimal extra meaning beyond the schema, simply restating 'Required: data_id'. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool deletes a data type definition, using a specific verb and resource. It distinguishes from sibling tools like updateDataType by mentioning modification without removal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use (removing an unused data type), warnings about orphaned records, and mentions of required data_id. Also references updateDataType as an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteEmailTemplateADestructiveIdempotent
Delete an email template - Permanently delete a emailtemplate record by ID. Destructive - cannot be undone via API.
Use when: removing a deprecated template. BD may fall back to defaults if a required system template is deleted - confirm before purging.
Required: email_id.
See also: updateEmailTemplate (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| email_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true. The description reinforces destruction: 'Permanently delete', 'cannot be undone via API', 'records removed are not recoverable.' It adds context about system template fallback and user confirmation, going beyond annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized into clear segments: purpose, use case, required param, see also, destructive warning, return format. Every sentence adds unique value, with no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple destructive tool with one parameter and no output schema, the description covers all relevant aspects: what it does, when to use, required parameter, destructive behavior, return format, and potential system impact.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description must compensate. It states 'Required: email_id.' but does not elaborate on its meaning (e.g., the ID of the template to delete). Since the parameter name is self-explanatory and only one parameter exists, this is minimally adequate, scoring 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete an email template - Permanently delete a emailtemplate record by ID.' It specifies the verb (delete), resource (email template), and nature (permanent). Among sibling tools, it is distinct because it targets email templates specifically.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance: 'Use when: removing a deprecated template.' It warns about potential fallback to defaults if a required system template is deleted. Also notes 'confirm intent with the user before bulk use' and provides an alternative: 'See also: updateEmailTemplate (modify without removing).'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteFormADestructiveIdempotent
Delete a form - Permanently delete a form record by ID. Destructive - cannot be undone via API.
Use when: removing a form - child fields orphan.
Required: form_id.
See also: updateForm (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| form_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint, idempotentHint), description adds that delete is permanent, cannot be undone via API, no soft-delete, and child fields become orphaned. This gives critical behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise with clear sections (use when, required, see also, destructive, returns). Each sentence adds value. Slightly verbose with return format example but overall well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple delete tool with one parameter, description covers purpose, usage, behavior, return format, and warnings. No output schema needed because return is clearly described. Complete for agent use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has one parameter with 0% coverage, but description explicitly states 'Required: form_id' and 'delete a form record by ID.' However, it does not add further constraints or format details beyond what the schema indicates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete a form - Permanently delete a form record by ID.' The verb 'delete' and resource 'form' are specific. It distinguishes from sibling tool `updateForm` which modifies without removing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when: removing a form - child fields orphan.' and 'See also: updateForm (modify without removing).' Also advises confirming intent with user before bulk use, covering when-not-to-use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteFormFieldADestructiveIdempotent
Delete a form field - Permanently delete a formfield record by ID. Destructive - cannot be undone via API.
Use when: removing a field. Existing submission records may reference the old field name - data persists but becomes orphan metadata.
Required: field_id.
See also: updateFormField (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| field_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond destructiveHint annotation by explaining permanence, unrecoverability, orphan metadata, and return format. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, well-structured with sections. Every sentence adds value: purpose, usage, requirement, caution, alternative, return message.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Comprehensive for a simple destructive tool; covers deletion impact, confirmation guidance, and return format despite no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, description states required field_id and its role in context. Parameter name is self-explanatory; could explicitly state it's the ID of the form field.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool deletes a form field permanently. The description distinguishes it from sibling tools like updateFormField by emphasizing destructive nature.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' condition, warns of orphan metadata, includes 'See also' for alternative, and advises user confirmation for bulk operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteLeadADestructiveIdempotent
Delete a lead - Permanently delete a lead record by ID. Destructive - cannot be undone via API.
Use when: removing a spam or test lead. For preserving the lead but closing it, use updateLead with a status change instead.
Required: lead_id.
See also: updateLead (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| lead_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint=true), description confirms 'Permanently delete', 'cannot be undone', 'No soft-delete', and warns to 'confirm intent before bulk use'. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured: summary line, usage guidance, required field, destructive warning, return info. No fluff. Front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given simple input schema and rich annotations, description covers all needed aspects: purpose, when to use, behavioral warnings, return format. Sufficient for agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Single required parameter lead_id, schema coverage 0%. Description only repeats 'Required: lead_id' without adding meaning (e.g., format, source, or constraints). Fails to compensate for missing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb and resource: 'Delete a lead - Permanently delete a lead record by ID.' Distinguishes from siblings like deleteClick by specifying 'lead'. Mentions alternative updateLead for preservation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use: 'removing a spam or test lead.' Provides alternative: 'use updateLead with a status change instead.' Also references updateLead in 'See also.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteLeadMatchADestructiveIdempotent
Delete a lead match - Permanently delete a leadmatch record by ID. Destructive - cannot be undone via API.
Use when: cleaning up an erroneous match (e.g., test data) or removing a match that was auto-created but shouldn't exist. Does NOT unsend the notification email that may have already fired.
Required: match_id.
See also: updateLeadMatch (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| match_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds context beyond annotations: specifies permanent deletion, no soft-delete, records unrecoverable. Warns about unsent email. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with front-loaded purpose, usage sections, and warnings. Slightly verbose but each sentence adds value. Score 4.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-param tool with no output schema, the description covers purpose, usage, behavioral traits, parameter, and return format. Complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Single parameter match_id is mentioned as required, but no additional details beyond schema. Schema coverage is 0%, so description adds minimal value—baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action (Delete) and resource (lead match), with explicit mention of permanence. Differentiates from siblings like updateLeadMatch.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly describes when to use (cleaning up erroneous matches, removing auto-created matches) and warns about side effects (does not unsend notification email). References alternative updateLeadMatch.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteMemberSubCategoryLinkADestructiveIdempotent
Remove a service from a user - Permanently delete a Member ↔ Sub Category link by rel_id. Destructive - cannot be undone via API.
Removes the member's link to this Sub Category in the rel_services join table. Does NOT remove the member from users_data.services CSV if the service_id is listed there - update that separately via updateUser if needed.
Use when: removing a specific link row. Does NOT update the users_data.services CSV - that's a separate field; update it via updateUser if the service_id is also listed there.
Required: rel_id.
Returns: { status: "success", message: "rel_services record was deleted" }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| rel_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes destructive nature ('cannot be undone via API'), which matches the destructiveHint annotation. Also details what is removed and what is not affected, and provides the return value. Adds significant context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description contains several paragraphs of extra context about database schema and other tools, which dilutes conciseness. The essential information is front-loaded, but the additional details could be moved to a reference document.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter destructive tool, the description covers purpose, usage guidelines, behavioral implications, and return value. It also provides broader context about member classification, which is helpful for understanding the tool's role.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'rel_id' is described as the required identifier, and its role is clear from context. However, the description could specify that it corresponds to the link row ID in the join table, though the purpose is still well-understood.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('permanently delete a Member ↔ Sub Category link'), the resource ('rel_services' join table), and the required identifier ('rel_id'). It distinguishes itself from siblings like createMemberSubCategoryLink and updateMemberSubCategoryLink.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('removing a specific link row') and what it does NOT do ('Does NOT update the users_data.services CSV'), with alternative instructions ('update it via updateUser').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteMenuADestructiveIdempotent
Delete a menu - Permanently delete a menu record by ID. Destructive - cannot be undone via API.
Use when: removing a menu container. Child items (menu_items rows with matching menu_id) become orphaned - delete them first.
Required: menu_id.
See also: updateMenu (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| menu_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint=true), the description adds: permanent deletion, cannot be undone, child items become orphaned, no soft-delete available. Discloses return format. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, well-structured. Uses bullet points and clear sections. Each sentence adds value without redundancy. Approximately 5 sentences covering all necessary aspects.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a simple delete tool. Covers purpose, usage, side effects (orphaned children), prerequisites (delete children first), return value, and alternative. With no output schema, the description adequately specifies the response format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Description states 'Required: menu_id.' While the schema already defines it as required integer, the description clarifies its necessity. Could briefly explain what menu_id is, but context of tool name makes it clear. Schema coverage is 0%, so description compensates partially.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Delete a menu - Permanently delete a menu record by ID.' Uses specific verb and resource. Distinguishes from sibling tools by mentioning 'updateMenu' as alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: removing a menu container.' Provides exclusions: child items become orphaned, delete them first. Also warns about destructive nature and suggests confirming with user. Refers to alternative tool 'updateMenu'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteMenuItemADestructiveIdempotent
Delete a menu item - Permanently delete a menuitem record by ID. Destructive - cannot be undone via API.
Use when: removing a single menu entry.
Required: menu_item_id.
See also: updateMenuItem (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| menu_item_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses permanence, no undo via API, no soft delete, and records not recoverable. Also specifies the return format. Annotations already provide destructiveHint=true and readOnlyHint=false, and the description adds crucial context beyond them. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and bold key points. Every sentence adds value, front-loads the essential action, and avoids fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage context, behavior, and return value. Warns about bulk use. Could mention potential cascading effects on references, but for a simple deletion it is fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has one required integer parameter with 0% description coverage. Description explicitly states 'Required: menu_item_id' and confirms it identifies the record by ID. Adds some meaning but no format, constraints, or examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it deletes a menu item permanently by ID. It distinguishes from sibling updateMenuItem (modify without removing) and deleteMenu (deletes a menu), making the specific verb+resource+scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: removing a single menu entry' and provides a 'See also' reference to updateMenuItem. Warns about destructive nature and to confirm intent before bulk use. Lacks explicit alternatives for bulk or multiple items, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteMultiImagePostADestructiveIdempotent
Delete an album group - Permanently delete a portfoliogroup record by ID. Destructive - cannot be undone via API.
Use when: removing the entire album. Recommended sequence: delete child photos first via deleteMultiImagePostPhoto (enumerate via listMultiImagePostPhotos property=group_id&property_value=<id>&property_operator==), THEN delete the group. BD does not cascade — skipping this leaves orphan users_portfolio rows.
Required: group_id.
See also: updateMultiImagePost (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| group_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true. The description reinforces this with 'Permanently delete', 'cannot be undone', 'confirm intent', and 'no soft-delete'. It also explains the need to delete children first and outlines the return format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections for purpose, usage, required parameter, alternative, warnings, and return format. It is slightly verbose but each sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no output schema, but the description provides the return format. It addresses relationships with sibling tools, irreversibility, and the need to handle child records. With one parameter, it is fully specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only one parameter (group_id) and 0% schema description coverage, the description adds that it is required and implies its role as the ID of the album group. While not elaborate, the meaning is clear from context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Delete', the resource 'album group / portfoliogroup record', and the permanent nature of the action. It distinguishes itself from siblings like deleteMultiImagePostPhoto and updateMultiImagePost.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('removing the entire album'), provides a recommended sequence (delete child photos first), warns about orphan rows, and mentions an alternative (updateMultiImagePost for modifications).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteMultiImagePostPhotoADestructiveIdempotent
Delete an album photo - Permanently delete a portfoliophoto record by ID. Destructive - cannot be undone via API.
Use when: permanently removing one photo from an album. For "hide" use updateMultiImagePostPhoto with status=0.
Required: photo_id.
See also: updateMultiImagePostPhoto (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| photo_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal destructiveHint: true, but the description adds crucial context: records are irrecoverable, no soft-delete, and advises user confirmation before bulk use. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Six terse sentences, front-loaded with purpose, then usage, required param, alternative, warnings, and return format. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite being a simple tool, the description covers purpose, usage guidance, behavioral implications, required parameter, and expected output. Sufficient for an agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description carries full burden. It only repeats 'Required: photo_id' from the schema, adding no meaning about what the ID represents or how to obtain it. The name implies the parameter is the photo ID but does not confirm or describe constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool deletes an album photo permanently by ID. It specifies the resource ('portfoliophoto record') and distinguishes it from sibling update tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides use conditions: 'permanently removing one photo from an album' and contrasts with hiding via updateMultiImagePostPhoto. Also includes a 'See also' reference to the modification sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deletePostTypeADestructiveIdempotent
Delete a post type - Permanently delete a posttype record by ID. Destructive - cannot be undone via API.
Use when: removing a post type entirely. Existing posts of this type become orphaned - consider migrating them to another type first via a bulk updateSingleImagePost/updateMultiImagePost.
Required: data_id.
See also: updatePostType (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true; description adds 'cannot be undone via API', 'no soft-delete', and a user confirmation warning. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections for purpose, usage, required param, see-also, destructive warning, and return format. Every sentence adds value, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low complexity (single param, no output schema), the description fully covers behavior, side effects, prerequisites, and expectations. The return value is explicitly stated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 0% description coverage, but the single required integer parameter `data_id` is self-explanatory in context. Description mentions 'Required: data_id' and 'by ID', sufficient for a simple delete operation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb-resource pair 'Delete a post type' with explicit permanence. Distinguishes from sibling `updatePostType` by stating 'modify without removing'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use ('removing a post type entirely'), warns of consequences (orphaned posts), suggests migration steps, and names an alternative tool (`updatePostType`).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteRedirectADestructiveIdempotent
Delete a redirect - Permanently delete a redirect record by ID. Destructive - cannot be undone via API.
Use when: an old redirect is no longer needed (source content has been offline long enough that the 301 value is gone) or the rule is conflicting with a new page at the same path.
Required: redirect_id.
See also: updateRedirect (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| redirect_id | Yes | Redirect primary key |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint:true and idempotentHint:true. The description adds that deletion is permanent, cannot be undone, with no soft-delete via API, and specifies the return message. This adds useful behavioral context beyond annotations, though it could mention error handling for non-existent IDs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured with clear sections (use when, required, see also, destructive, returns). Every sentence adds value, and the structure makes it easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (single parameter, no output schema), the description is complete. It covers purpose, usage guidance, parameter requirement, behavioral impact, return value, and references a sibling tool. No critical information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with a description for redirect_id. The description merely reiterates that redirect_id is required, without adding new semantic meaning. Baseline of 3 is appropriate given high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool deletes a redirect permanently, specifying the resource (redirect record) and action (delete by ID). It distinguishes itself from siblings like updateRedirect by noting that updateRedirect modifies without removing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use scenarios (old redirect no longer needed, conflicting rule) and points to an alternative tool (updateRedirect). It also advises confirming with the user before bulk use, which is excellent guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteReviewADestructiveIdempotent
Delete a review - Permanently delete a review record by ID. Destructive - cannot be undone via API.
Use when: the review content violates policy and must be purged (spam, abuse, PII). For "hide without removing" use updateReview with review_status=3 (Declined) - preserves the audit trail.
Required: review_id.
See also: updateReview (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| review_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already include destructiveHint=true, but description adds critical context: permanent deletion, no recovery, need for user confirmation before bulk use, and return format. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise, well-structured with clear sections: purpose, use-when, required, see-also, destructive warning, returns. Every sentence serves a purpose without unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity (1 parameter, no output schema), the description fully covers what an agent needs: purpose, usage guidelines, behavioral traits, parameter requirement, and return. Complete for effective invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage and only one parameter (review_id). The description mentions 'Required: review_id' but adds no additional meaning (e.g., type, format, source). Carries the burden but barely adds value beyond the schema's property name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete a review - Permanently delete a review record by ID.' It uses a specific verb and resource, and distinguishes from siblings like updateReview by contrasting destructive deletion with hiding.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use ('when the review content violates policy and must be purged') and when not to use ('For 'hide without removing' use updateReview'). Provides an alternative tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteSingleImagePostADestructiveIdempotent
Delete a post - Permanently delete a post record by ID. Destructive - cannot be undone via API.
Use when: removing a post permanently. For "hide without deleting" use updateSingleImagePost with post_status=0 (Draft). Deleting also removes the post_token, breaking any external links to the share URL.
Required: post_id.
See also: updateSingleImagePost (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals destructive behavior beyond annotations: it cannot be undone via API, removes the post_token, and breaks external links. Annotations already indicate destructiveHint=true, but the description adds specific, actionable side effects. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with headers and sections, but it is slightly verbose. Each sentence serves a purpose, but some phrases (e.g., repeated warnings about destructiveness) could be condensed. Overall, it is efficient and front-loaded with key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers the tool's operation: it explains the return value (status and message), side effects (link breakage), and how it differs from alternatives. For a single-parameter delete tool with no output schema, it provides all necessary context for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only one parameter (post_id) and 0% schema description coverage, the description merely restates that post_id is required. It does not explain the parameter's format, range, or examples of valid values, which would add value. However, given the simplicity of the parameter, the description is minimally adequate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Delete a post - Permanently delete'), identifies the resource by ID, and distinguishes it from the sibling tool updateSingleImagePost for hiding posts. The verb and resource are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('Use when: removing a post permanently') and when not to use it (for hiding, use updateSingleImagePost with post_status=0). It also recommends confirming intent with the user before bulk use, providing clear guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteSmartListADestructiveIdempotent
Delete a smart list - Permanently delete a smartlist record by ID. Destructive - cannot be undone via API.
Use when: removing a saved filter configuration.
Required: smart_list_id.
See also: updateSmartList (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| smart_list_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint=true), description adds critical details: 'cannot be undone via API,' 'records removed are not recoverable,' and return format. This provides full transparency for a destructive action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured with clear sections (main, use when, required, see also, destructive behavior, returns). No extraneous text; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple delete tool with one parameter and no output schema, the description covers all necessary aspects: purpose, usage context, parameter, alternative, destructive implications, and return value. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, description states 'Required: smart_list_id' and implies it is the ID of the smart list to delete. Adds minimal meaning beyond the parameter name; lacks further details like format or source.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Delete a smart list - Permanently delete a smartlist record by ID.' The verb 'delete' and resource 'smart list' are explicit. Differentiates from sibling 'updateSmartList' via 'See also' section.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Use when: removing a saved filter configuration.' Also directs to an alternative tool ('updateSmartList' for modification) and warns about destructive nature for bulk use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteSubCategoryADestructiveIdempotent
Delete a service - Permanently delete a SUB-level member category by service_id. Destructive - cannot be undone via API.
Use when: removing an unused sub-category. Any member with this service_id in their users_data.services CSV or in rel_services rows becomes orphaned - clean those up first.
Required: service_id.
Destructive: confirm intent. Members whose users_data.services CSV contains this ID will have an orphan reference. Any Member ↔ Sub Category links (rel_services) pointing at this service_id also become orphaned.
Bound-page caveat: if this category's filename has a seo_type=profile_search_results web page bound to it, deleting the category orphans that page (it'll render empty — no category to query). The wrapper rejects deletes that would orphan a bound page — delete or repurpose the bound page first.
See also: updateSubCategory (modify without removing).
Returns: { status: "success", message: "list_services record was deleted" }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| service_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint=true), the description details what becomes orphaned (users_data.services CSV, rel_services rows) and the bound-page rejection behavior. This adds significant context over annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy and includes tangential background on member classification and missing create tools. While the key points are front-loaded, the extra information reduces conciseness for this specific tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description covers the return format, destruction semantics, orphan handling, and bound-page caveat. It fully informs an agent of all important side effects and usage conditions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema coverage 0%, the description must explain service_id. It states 'Required: service_id' but does not explicitly define the ID. However, context makes it clear that it is the identifier of the sub-category. Almost sufficient, but could be more explicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete a service - Permanently delete a SUB-level member category by service_id.' This distinguishes it from sibling delete tools like deleteTopCategory, with specific verb (delete) and resource (sub-level category).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: removing an unused sub-category.' and warns about orphaned references. Also suggests updateSubCategory as an alternative and details bound-page caveat, providing clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteTagADestructiveIdempotent
Delete a tag - Permanently delete a tag record by ID. Destructive - cannot be undone via API.
Use when: removing a tag entirely. Tag-relationships (rel_tags) pointing at it may orphan.
Required: id.
See also: updateTag (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint=true), describes orphaning of rel_tags, no soft-delete, non-recoverability, and required user confirmation for bulk use.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and bolded key phrases, but slightly verbose. Every sentence contributes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Comprehensive for a single-parameter tool with annotations. Covers return value, side effects, and usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only parameter 'id' is mentioned as required, but schema already covers type and required. Schema coverage is 0%, so description adds minimal value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete a tag - Permanently delete a tag record by ID,' specifying the action (delete) and resource (tag). It differentiates from siblings like updateTag.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: removing a tag entirely' and 'See also: updateTag (modify without removing).' Also adds caution for destructive operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteTagGroupADestructiveIdempotent
Delete a tag group - Permanently delete a taggroup record by ID. Destructive - cannot be undone via API.
Use when: removing a group - child tags orphan; delete or re-group them first.
Required: id.
See also: updateTagGroup (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond annotations: emphasizes permanence ('cannot be undone via API'), describes impact on child tags (orphaning), and states no soft-delete. Contradicts none of the annotations (destructiveHint, idempotentHint, etc.) and adds crucial behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Efficiently structured with bold headings, each sentence earns its place. Front-loaded with main action, no redundant phrases. Approximately 100 words covering purpose, usage, behavior, parameters, and return format.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Completely covers a simple delete operation: describes action, side effects (orphaned children), irreversibility, required parameter, return format. No output schema needed; description provides sufficient context. Sibling tools are many, but this description uniquely addresses its role.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description carries full burden but only notes that 'id' is required and mentions it in the return format. Does not explain what 'id' represents (e.g., the ID of the tag group to delete). Schema itself is minimal (integer, required), so description adds marginal value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb+resource: 'Delete a tag group' and specifies permanent deletion. Differentiates from siblings like deleteTag and updateTagGroup by explicitly naming the resource and providing a 'See also' link to the update alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use case: 'removing a group - child tags orphan; delete or re-group them first.' Warns about destructive nature and need for user confirmation before bulk use. Suggests updateTagGroup as alternative, fulfilling when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteTagRelationshipADestructiveIdempotent
Delete a tag relationship - Permanently delete a tagrelationship record by ID. Destructive - cannot be undone via API.
Use when: detaching a tag from a record. Note: if the member has member_tags CSV set, update that separately too.
Required: id.
See also: updateTagRelationship (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide destructiveHint and readOnlyHint, but the description adds valuable context: 'Destructive - cannot be undone via API', 'No soft-delete via API - records removed are not recoverable', and the return format. Could mention idempotency implications, but overall strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: overview, use when, required, see also, destructive warning, returns. Each sentence is necessary and adds value. Very concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple delete tool with one parameter and annotations, the description covers all necessary aspects: purpose, usage context, parameter requirement, destructive behavior, return format. It is complete and provides adequate guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter 'id' (integer, required). Schema description coverage is 0%, but the description specifies 'Required: id.' However, it does not clarify what the ID represents (e.g., tagrelationship record ID), though it's implied. Minimal addition beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Delete a tag relationship - Permanently delete a tagrelationship record by ID.' This distinguishes it from siblings like 'updateTagRelationship' (modify without removing) and 'createTagRelationship'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use when: detaching a tag from a record.' Provides a note about CSV member_tags, refers to 'updateTagRelationship' as an alternative, and warns about destructive nature with confirmation advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteTopCategoryADestructiveIdempotent
Delete a category - Permanently delete a TOP-level member category by profession_id. Destructive - cannot be undone via API.
Use when: removing an unused top-level category. Any members with matching profession_id become orphaned - reassign them first. Any Sub Categories (list_services rows) under this top also orphan - delete or re-parent them.
Required: profession_id.
Destructive: confirm intent with the user. Members who referenced this profession_id will have orphan references. Sub Categories under this top (with matching profession_id in list_services) also become orphaned - consider reassigning or deleting them first.
Bound-page caveat: if this category's filename has a seo_type=profile_search_results web page bound to it, deleting the category orphans that page (it'll render empty — no category to query). The wrapper rejects deletes that would orphan a bound page — delete or repurpose the bound page first.
See also: updateTopCategory (modify without removing).
Returns: { status: "success", message: "list_professions record was deleted" }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| profession_id | Yes | The top-level category ID to delete. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description explicitly labels tool as destructive and expands on annotations (destructiveHint=true). Details side effects: orphaned members, subcategories, and bound pages. Explains wrapper behavior that rejects if bound page would be orphaned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Core information is front-loaded, but description includes extensive tangential domain details (member classification, sub-sub-categories, table-name mapping). This extra content could be shortened or moved elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single parameter and no output schema, the description covers all essential aspects: action, parameter, side effects, prerequisites, return format, and edge case with bound pages. Agent has enough info to safely invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes profession_id as 'The top-level category ID to delete.' Description restates 'Required: profession_id' but adds no new meaning beyond schema. Schema coverage is 100% so baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it permanently deletes a top-level member category by profession_id. Distinguished from sibling delete tools (e.g., deleteSubCategory) by specifying 'TOP-level member category'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' section: removing unused top-level category. Prerequisites: reassign orphaned members and handle subcategories. Alternatives: updateTopCategory mentioned. Addresses edge case with bound pages and wrapper rejection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteUnsubscribeADestructiveIdempotent
Remove email from unsubscribe list - Permanently delete a unsubscribe record by ID. Destructive - cannot be undone via API.
Use when: re-subscribing a member (remove their unsubscribe entry). Confirm the member's consent first - don't use to silently re-enable emails.
Required: id.
See also: updateUnsubscribe (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds key behavioral details beyond annotations: 'Permanently delete', 'cannot be undone via API', 'No soft-delete via API - records removed are not recoverable.' Consistent with destructiveHint=true. No contradiction with idempotentHint=true (delete is idempotent).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections: summary, use case, required param, alternatives, destructive warning, return format. Every sentence adds value, and key points are front-loaded. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description covers purpose, usage context, behavioral traits, and return value. Annotations are present, and the description complements them well, addressing consent and bulk use concerns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only parameter is 'id', and schema description coverage is 0%. The description merely repeats 'Required: id.' without explaining what the id represents or any constraints. Given low coverage, additional param context is needed but missing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Remove email from unsubscribe list - Permanently delete a unsubscribe record by ID.' The verb 'delete' matches the tool name, and it specifies the resource (unsubscribe record), distinguishing it from other delete tools like deleteClick or deleteForm.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance: 'Use when: re-subscribing a member (remove their unsubscribe entry).' Warns against misuse: 'Confirm the member's consent first - don't use to silently re-enable emails.' Provides alternative: 'See also: updateUnsubscribe (modify without removing).' Adds caution for bulk use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteUserADestructiveIdempotent
Delete a member/user - Permanently delete a user record by ID. Destructive - cannot be undone via API.
Use when: the member record truly must be purged (GDPR request, test cleanup, confirmed duplicate). For reversible removal prefer updateUser with active=3 (Canceled) - the record stays queryable and can be reactivated. Use delete_images=1 to also purge stored profile/cover/logo images.
Required: user_id.
Parameter interactions:
delete_images=1(optional) - also deletes the member's stored profile/cover/logo images from site storage
See also: updateUser (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | ||
| delete_images | No | Set to 1 to also delete user images |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses destructive nature, irreversibility, no soft-delete via API, and need for intent confirmation. Aligns with annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is detailed but each sentence adds value. Front-loaded with purpose and guidelines. Could be slightly trimmed but overall well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers return values, parameter interactions, and alternatives. Given no output schema, it provides enough context for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning to both parameters: user_id as required, delete_images as optional with explanation of its effect. Schema had 50% coverage (delete_images described), so description compensates and adds value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool permanently deletes a user by ID. Distinguishes from siblings like updateUser for reversible removal, and from other delete tools by specifying it's for user records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly lists when to use (GDPR, cleanup, duplicates) and when not to (prefer updateUser with active=3 for reversible removal). Also mentions optional image deletion and provides alternative tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteUserMetaADestructiveIdempotent
Delete a metadata record - Permanently delete a users_meta record by meta_id. DESTRUCTIVE - cannot be undone via API.
HARD RULE - (database, database_id) is ONE atomic compound identity. Verify BOTH of the row BEFORE deleting. Destructive mistakes on users_meta are unrecoverable. A users_meta row's identity is (database, database_id, key). The same numeric database_id routinely belongs to UNRELATED rows on different parent tables - an integer ID may simultaneously be a WebPage's seo_id, a member's user_id, a post's post_id, and a plan's subscription_id. BEFORE calling this endpoint: (1) call getUserMeta(meta_id) or retain the row's full object from a prior listUserMeta response; (2) confirm the row's database value matches the table you intend to clean up. For batch orphan-cleanup after a parent delete: list by the parent's database_id, then CLIENT-SIDE filter to ONLY rows where database equals the parent table's name BEFORE deleting any meta_id. NEVER loop-delete by database_id alone - you WILL destroy unrelated resource metadata (member data, plan metadata, page settings) that happen to share the same numeric ID on other tables.
Use when: removing a specific metadata row, OR cleaning up orphan meta rows after a parent record is deleted (BD does not cascade-delete users_meta when a parent is removed - it's the agent's job to find and delete the orphan rows surgically).
Required: meta_id, database, database_id. All three - always. The identity pair (database, database_id) is enforced at the schema level to prevent cross-table destruction.
Post-parent-delete cleanup workflow (safe pattern):
listUserMetawith filterdatabase_id=<deleted parent's id>In the returned array, filter CLIENT-SIDE to ONLY rows where
databaseequals the parent table's name (e.g.list_seofor a deleted WebPage)For each filtered
meta_id, calldeleteUserMeta(meta_id, database=<parent table>, database_id=<parent id>)- all three requiredNever skip step 2 - the same
database_idcan belong to unrelated rows on other tables
See also: updateUserMeta (modify without removing), listUserMeta (enumerate with filter).
Returns: { status: "success", message: "users_meta record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| meta_id | Yes | ||
| database | Yes | REQUIRED - parent table name (e.g. `list_seo`, `users_data`). Must match the row's stored `database` field. Prevents accidental cross-table deletion since the same `database_id` can exist in multiple parent tables. | |
| database_id | Yes | REQUIRED - parent record PK. Must match the row's stored `database_id` field. Agents MUST verify both `database` and `database_id` before calling delete to prevent destroying unrelated metadata on other tables with the same ID number. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true, but the description adds critical behavioral context: the compound identity risk, cross-table destruction potential, the fact that BD does not cascade-delete, and the exact return format. This goes well beyond annotations with no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a clear summary, hard rule, use cases, workflow, see also, and return value. It is front-loaded with the purpose. However, it is somewhat verbose; with multiple paragraphs, some sentences could be streamlined without losing essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the lack of output schema, the description explicitly states the return format. It covers purpose, risks, usage pattern, alternatives, and prerequisites. For a destructive tool with cross-table implications, this is comprehensive and complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers 67% of parameters with descriptions, but the description reinforces the compound identity of (database, database_id) and explains why both are required to prevent cross-table destruction. This adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Delete a metadata record - Permanently delete a users_meta record by meta_id.' It specifies the resource (users_meta) and action (delete), and distinguishes from siblings by naming the specific table and emphasizing the compound identity requirement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit use cases are given: 'Use when: removing a specific metadata row, OR cleaning up orphan meta rows after a parent record is deleted.' It warns against loop-deleting by database_id alone and provides a safe cleanup workflow. It also references alternatives: updateUserMeta and listUserMeta.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteUserPhotoADestructiveIdempotent
Delete a user photo - Permanently delete a userphoto record by ID. Destructive - cannot be undone via API.
Use when: removing a photo attachment. For member image management consider updateUser with images_action=remove_all / remove_cover_image / etc. instead - that covers the member-record side of image cleanup.
Required: photo_id.
See also: updateUserPhoto (modify without removing).
Destructive: confirm intent with the user before bulk use. No soft-delete via API - records removed are not recoverable.
Returns: { status: "success", message: "record was deleted" }. No body beyond the confirmation string.
| Name | Required | Description | Default |
|---|---|---|---|
| photo_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant behavioral context beyond annotations: 'Permanently delete... cannot be undone via API', 'No soft-delete via API', and includes return format. It complements the destructiveHint and idempotentHint annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the most critical information (destructive nature, permanent deletion). Every sentence adds value without unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple delete-by-ID tool with no output schema, the description covers all necessary aspects: purpose, usage context, alternatives, behavioral implications, and return value. Annotations handle safety flags, and sibling differentiation is addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description compensates by stating 'Required: photo_id' and implying it is the ID of the photo. While minimal, it adds meaning beyond the bare schema. Baseline for zero params is 4, and this tool has one param, so a 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete a user photo - Permanently delete a userphoto record by ID.' It uses a specific verb and resource and explicitly differentiates from related tools like updateUserPhoto and updateUser with image actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: 'Use when: removing a photo attachment.' It also gives clear alternatives for member image management and advises confirming intent with the user before bulk use due to destructive nature.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteWebPageADestructiveIdempotent
Delete a page - Permanently delete a web page by seo_id. Destructive - cannot be undone via API.
Use when: permanently removing a page.
Required: seo_id.
Destructive: confirm with the user. If inbound links or menus reference the deleted page's URL, consider creating a createRedirect BEFORE deleting so those links don't 404. Menus with items pointing at this page also need cleanup.
seo_type=data_category cascade — automatic. When the deleted page is data_category, the wrapper auto-deletes its placeholder-slug 301 redirect (response includes _data_category_redirect_deleted: <redirect_id>). The agent does not need to call deleteRedirect manually.
ORPHAN CLEANUP REQUIRED - BD does NOT cascade-delete users_meta rows. Each WebPage with a hero or custom layout has up to 18 EAV rows in users_meta (database=list_seo, database_id=<seo_id>). These persist after deleteWebPage unless you clean them up. Safe post-delete workflow:
Call
listUserMetafiltered ondatabase=list_seoANDdatabase_id=<deleted seo_id>.Client-side filter the response - keep only rows whose
databasefield equalslist_seo. The samedatabase_idvalue may exist inusers_metapointing at unrelated parent tables (e.g. a member withuser_id=<seo_id>inusers_data), and those rows must NOT be deleted.For each remaining row, call
deleteUserMetawithmeta_id=<row.meta_id>,database=list_seo,database_id=<seo_id>(all three required).
Never loop-delete by database_id alone - you will silently destroy unrelated records on other tables.
See also: updateWebPage (modify without removing).
Returns: { status: "success", message: "list_seo record was deleted" }.
| Name | Required | Description | Default |
|---|---|---|---|
| seo_id | Yes | Page primary key |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (destructiveHint: true), the description details destructive implications, automatic cascade for data_category, orphan cleanup requirements, and post-deletion workflow. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, bullet points, and code formatting. Front-loaded with core purpose. Although verbose, each sentence serves a purpose given the tool's destructive nature.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Includes return value, side effects, pre/post conditions, references to related tools, and warnings for a complete understanding. No output schema, but description compensates fully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% with a basic description for seo_id. Description adds 'Required: seo_id' and contextual usage throughout, enhancing semantics beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete a page - Permanently delete a web page by seo_id', specifying the action, resource, and key differentiators like destructive nature and irreversibility. It also distinguishes from siblings by referencing updateWebPage and createRedirect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: permanently removing a page.' Provides prerequisites (confirm with user, consider redirect), warns against common mistakes (looping by database_id), and lists alternatives (updateWebPage). Comprehensive guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteWidgetADestructiveIdempotent
Delete a widget - Permanently delete a widget by widget_id. Destructive - cannot be undone via API.
Use when: removing an unused widget. For "disable without deleting" use updateWidget with widget_viewport=admin (hides from public pages) - preserves the source for later use.
Destructive caveat: any page or email using [widget=Name] shortcode referencing the deleted widget will render as empty or broken at that spot. Audit with listWidgets + check page content for shortcodes referencing this widget's widget_name or short_code before deleting.
Required: widget_id.
See also: updateWidget with widget_viewport=admin (reversible hide).
Returns: { status: "success", message: "data_widgets record was deleted" }.
| Name | Required | Description | Default |
|---|---|---|---|
| widget_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Exceeds annotation's destructiveHint by detailing side effects like broken shortcodes and recommends auditing with listWidgets, adding significant value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bold headings, bullet points, and separate sections for usage, caveats, and see also. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Comprehensively covers purpose, destructive nature, prerequisites, side effects, output format, and alternative, leaving no obvious gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only mentions that widget_id is required, which is already in schema. With 0% schema coverage, minimal additional semantic value is provided, but the parameter is self-explanatory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb 'Delete' and resource 'widget', and distinguishes from sibling 'updateWidget' by mentioning an alternative for disabling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides when to use (removing unused widget) and when not to use (disable via updateWidget), along with a practical alternative and an audit suggestion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getBrandKitARead-onlyIdempotent
Get the site's brand kit (colors + fonts) for design decisions - Return a compact, semantically-labeled brand kit for this BD site - colors (body / primary / dark / muted / success / warm / alert accents, card surface) + fonts (body + heading Google Fonts). Call this ONCE at the start of any design-related task (building a widget, WebPage, post template, email, hero banner - anything where colors or fonts are chosen) so the output visually matches the site's brand.
Handler is synthetic - makes 20 parallel internal calls to /api/v2/website_design_settings/get?property=setting_name&property_value=custom_N&property_operator== (one per brand-kit slot), then transforms the raw custom_N values into semantic labels. Uses BD's canonical mapping (same mapping BD's admin AI Companion applies). Parallel calls complete in ~1s wall-clock on typical sites; well under the 100 req/60s rate limit even on repeated invocations.
No args. Read-only. Safe to call anytime.
Response shape:
{
body: { background, text, font },
primary: { color, text_on },
dark: { color, text_on },
muted: { color, text_on },
success_accent: { color, text_on },
warm_accent: { color, text_on },
alert_accent: { color, text_on },
card: { background, border, text, title },
heading_font: "<google font family>",
usage_guidance: { primary, dark, muted, success_accent, warm_accent, alert_accent, tint_rule, font_rule }
}Usage guidance embedded in response - agents should read it every call. Key rules:
Primary = brand color - main CTAs, dominant accents.
Dark = high-contrast sections or strong backgrounds.
Muted = subtle section backgrounds, dividers, badges, pills.
Success / Warm / Alert accents = specific semantic states (confirmations / attention / urgency). Use sparingly.
Tint rule: derive lighter/darker tints from palette colors for hover states, gradients, low-emphasis backgrounds. Do NOT introduce new unrelated hues.
Font rule: the site's
body.fontandheading_fontGoogle Fonts are already globally loaded by BD. Do NOT redefine them incontent_css. To switch to a different font, load it via a<link rel="stylesheet" href="https://fonts.googleapis.com/...">tag incontent_head— never@importinside CSS (Outlook + some BD widget contexts strip or fail on@import).
When a slot is empty on the site, the handler applies BD's documented fallback defaults (same defaults BD's admin AI Companion uses). Response is never missing keys - every field always has a value.
Auth: X-Api-Key header. Rate limit: 100 req/60s. Caches well on the agent side - the brand kit rarely changes within a session; call once, reuse.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=true. Description adds valuable behavioral details: 20 parallel internal calls, rate limit, caching advice, fallback defaults, and response shape with usage guidance. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is lengthy but well-structured, front-loading purpose and usage. Every sentence adds value, though some technical details could be condensed. Still earns a 4 for being informative without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, description provides comprehensive detail on response shape, usage guidance, and edge cases (empty slots, auth, rate limit). Fully equips the agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist (0 params, schema coverage 100%), so baseline score is 4. Description mentions 'No args.' which is sufficient; no further parameter info needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool retrieves the site's brand kit (colors and fonts) for design decisions. It specifies use cases like building widgets, webpages, etc., and distinguishes itself from siblings by its unique purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to call 'ONCE at the start of any design-related task' and notes 'Safe to call anytime.' Provides clear context for when to use the tool, leaving no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCityARead-onlyIdempotent
Get a single city - Fetch one city row. Read-only. Note BD schema typo: PK is locaiton_id (sic), not location_id.
Required: locaiton_id (path).
See also: listCities (enumerate + filter).
Returns: { status: "success", message: [{...record}] }.
| Name | Required | Description | Default |
|---|---|---|---|
| locaiton_id | Yes | City primary key (BD schema typo: `locaiton_id`, NOT `location_id`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. Description adds return format and notes the schema typo, adding value beyond annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four succinct sentences with zero waste, front-loading the core purpose and then providing necessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool with no output schema, description provides return format, sibling reference, and explains the typo, fully contextualizing the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and already includes the typo note. Description restates 'Required: locaiton_id (path)' but adds no new semantic meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single city - Fetch one city row. Read-only.' It specifies the action (get/fetch), the resource (city row), and distinguishes it from sibling tool listCities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly mentions required parameter locaiton_id and points to listCities for enumeration/filtering alternatives, providing clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getClickARead-onlyIdempotent
Get a single click record - Fetch a single click record. Read-only.
Use when: rare - drilling into a specific click record by click_id. Most click-analytics work happens via listClicks with filters.
Required: click_id.
See also: listClicks (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| click_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly and idempotent. The description adds details on return format ('{ status: "success", message: [{...record}] }') and error behavior (empty or 404), providing behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, well-structured with clear sections: one-liner, use-when, required param, see also, returns. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-id tool with one parameter and no output schema, the description covers purpose, usage context, parameter requirement, return format, and error behavior. It is complete for its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% so description must compensate. It mentions click_id is required and implies it identifies the record, but does not explain its meaning further. For a single integer parameter, this is adequate but minimal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single click record' and specifies 'Read-only.' It distinguishes from sibling tool listClicks by indicating that this tool is for drilling into a specific record by click_id.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides usage context: 'Use when: rare - drilling into a specific click record by click_id' and contrasts with listClicks for most work. Also includes 'Required: click_id' and 'See also: listClicks'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCountryARead-onlyIdempotent
Get a single country - Fetch one country row. Read-only.
Required: country_id (path).
Returns: { status: "success", message: [{...record}] }.
| Name | Required | Description | Default |
|---|---|---|---|
| country_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds the return format and parameter requirement, providing additional context beyond annotations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with three sentences, front-loading the purpose. Uses bold for emphasis on requirements, making it scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (one parameter, no output schema), the description covers the essential aspects: purpose, required input, and return format. No missing information for typical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description should compensate. It mentions 'country_id' is required and a path parameter but does not explain what it represents, any constraints, or its format. Minimal added value over schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a single country by ID, using specific verbs ('Get', 'Fetch') and resource ('country row'). It distinguishes from sibling tools like listCountries by indicating it fetches one row.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions the required parameter and read-only nature but does not explicitly state when to use this tool over alternatives like listCountries or updateCountry. Usage context is implied but not formally outlined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getDataTypeARead-onlyIdempotent
Get a single data type - Fetch a single datatype record. Read-only.
Use when: fetching one data type's record by ID.
Required: data_id.
See also: listDataTypes (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | Yes | Data type primary key |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark as read-only. Description adds return format details: 'Returns: { status: "success", message: [{...record}] }' and mentions empty/404 when not found. This enriches behavioral understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise with front-loaded title, uses bullet points for key sections, and every sentence adds value. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 1-parameter read-only tool with no output schema, the description covers purpose, usage, return format, and error case. Complete given context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with parameter description 'Data type primary key'. Description restates requirement for data_id but adds no new semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Get a single data type - Fetch a single datatype record.' It clearly identifies the verb (get) and resource (data type), and distinguishes from sibling listDataTypes by specifying it fetches a single record.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: fetching one data type's record by ID.' and provides 'See also: listDataTypes (enumerate many).' This gives clear context for when to choose this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getEmailTemplateARead-onlyIdempotent
Get a single email template - Fetch a single emailtemplate record. Read-only.
Use when: fetching one template's HTML body and subject for edit.
Required: email_id.
Lean-by-default: email_body is stripped. Set include_body=1 to restore it (always do this when you need to edit the HTML).
See also: listEmailTemplates (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Record omits email_body unless include_body=1. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| email_id | Yes | ||
| include_body | No | Opt in to return the full `email_body` HTML. Default stripped — `email_body` is the heaviest field on the row. Set `include_body=1` when you actually need the HTML to edit it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint, etc.), description reveals that email_body is stripped by default and how to retrieve it, describes the return format as an array within a success object, and mentions HTTP 404 for not found. This adds significant behavioral detail not present in annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, using bold headers and bullet points to organize critical information. Every sentence serves a purpose, and the most important details (read-only, required param, lean default) are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description fully explains the return structure and edge cases (empty/404). Combined with annotations and sibling references, it provides complete context for a simple get-by-id tool. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Description adds meaning beyond schema: it explains that include_body=1 is needed for editing and that email_body is the heaviest field. Though schema already covers include_body, the description reinforces its purpose and adds context about default behavior. email_id is simply noted as required, not adding much beyond schema, but overall useful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single email template - Fetch a single emailtemplate record. Read-only.' It explicitly contrasts with 'listEmailTemplates (enumerate many)', distinguishing the tool from siblings. The verb 'get' and resource 'email template' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Includes 'Use when: fetching one template's HTML body and subject for edit.' and 'Required: email_id.' It also advises when to set include_body=1 and references the alternative listEmailTemplates for enumeration, providing clear usage context and when-not-to-use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getFormARead-onlyIdempotent
Get a single form - Fetch a single form record. Read-only.
Use when: fetching one form's metadata.
Required: form_id.
See also: listForms (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| form_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds valuable behavioral context: the return format (status and message array) and the behavior when not found (empty or HTTP 404). This goes beyond what annotations provide, though it doesn't elaborate on other traits like authentication requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise, using only four short lines. It is front-loaded with the core action and uses clear section headers (Use when, Required, See also, Returns). Every sentence adds value with no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one required parameter, read-only, fixed return structure). The description covers purpose, usage context, required parameter, related sibling, and return format including error scenario. With no output schema, the description compensates fully. It is complete for the given complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It only repeats 'Required: form_id.' without adding meaning about what form_id is, any format constraints, or examples. The schema already defines type and required status, so the description adds negligible value for this parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Get a single form - Fetch a single form record. Read-only.' This clearly identifies the verb (get) and resource (single form), and distinguishes from siblings like listForms by specifying scope. The read-only annotation reinforces the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: 'Use when: fetching one form's metadata.' and references sibling 'listForms (enumerate many).' This tells the agent when to use this tool and when to use an alternative, satisfying the usage guidelines dimension.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getFormFieldARead-onlyIdempotent
Get a single form field - Fetch a single formfield record. Read-only.
Use when: one field by ID.
Required: field_id.
See also: listFormFields (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| field_id | Yes | ||
| include_meta | No | Opt in to return the `json_meta` longtext blob (UI rendering metadata + per-field validator config). Default stripped — use when adding or editing per-field validators (regexp, stringLength, etc.). See **Rule: Forms** § Field anatomy → `json_meta`. | |
| include_view_flags | No | Opt in to return form-field view-flag columns: `field_input_view`, `field_display_view`, `field_search_view`, `field_email_view`, `field_grid_view`, `field_input_view_admin_only`, plus the 5 alt-label override columns. Default stripped — use when actively editing field visibility. See **Rule: Forms** § Field anatomy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description adds return format and not-found behavior ('Empty or HTTP 404') beyond annotations that already declare readOnlyHint=true and idempotentHint=true. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, structured with clear sections (Use when, Required, See also, Returns). No redundant sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations and detailed schema, description completes the picture by specifying return format. Lacks explanation of output schema (none provided) but is adequate for a read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 67% of parameters in detail. Description only reinforces required field_id, adding no new semantic value for the optional parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single form field' and contrasts with sibling 'listFormFields' for enumeration. Verb+resource is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: one field by ID' and lists required parameter. References sibling tool for alternatives. Lacks explicit when-not-to-use scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getFormInquiryARead-onlyIdempotent
Get a single Forms Inbox submission - One Forms Inbox submission by inquiry_id. Read-only.
Use when: you hold an inquiry_id from listFormInquiries.
Required: inquiry_id (path).
Returns: the listFormInquiries per-row shape — inquiry_email, yourname, phone, inquiry_form, form_title, url_origin, date_submitted, fields ({label, value} array; include_raw=1 for raw HTML).
See also: listFormInquiries (enumerate, filter).
| Name | Required | Description | Default |
|---|---|---|---|
| inquiry_id | Yes | ||
| include_raw | No | Return the raw `inquiry_content` HTML blob instead of the parsed `fields`. Default off. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states 'Read-only' and details the return shape, listing specific fields and explaining the effect of the include_raw parameter. Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, and the description adds valuable context without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, using a clear structure with sections for main purpose, usage condition, required parameter, return details, and cross-reference. Every sentence adds value with no redundant content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers all necessary aspects: purpose, when to use, required parameter, return structure, and parameter behavior. Annotations and schema provide complementary info, making the overall context complete for a retrieval tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning beyond the schema by identifying inquiry_id as a path parameter and explaining that include_raw=1 returns raw HTML. Schema coverage is 50% (only include_raw has a description), so the description compensates partially, but could have elaborated on the purpose of each field in return.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'Forms Inbox submission', and specifies it retrieves a single item by inquiry_id. It also distinguishes itself from sibling tools by being a read-only retrieval, contrasting with list or mutation tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when: you hold an inquiry_id from listFormInquiries' and provides a 'See also' reference to the enumeration tool. This guides the agent precisely on when to use this tool and how to obtain the required ID.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getImageDimensionsARead-onlyIdempotent
Probe an image URL and return its dimensions + orientation. - Wrapper-native synthetic tool. Range-GETs the first 64KB of an image URL and parses JPG/PNG header bytes to return width, height, format, aspect_ratio, and orientation (landscape | portrait | square). Does NOT proxy to BD. Used by content-creation skills to verify image orientation before committing to a feature-image field (post_image, cover_photo, hero_image).
Batch mode — preferred for 2+ candidates: pass urls (comma-separated, up to 50) instead of url. All URLs probe in parallel; the response is one envelope { status: "success", count, results: [{ url, status, message }, ...] } in input order. A 404/timeout/parse failure is that URL's own status: "error" entry — it never breaks the batch or the other results.
Caller contract: filter candidate URLs to .jpg / .jpeg / .png BEFORE calling. WebP / GIF / AVIF are unsupported — the parser returns { status: "error", message: "unsupported image format..." } as a defense-in-depth fallback, but callers must not rely on it; skip non-JPG/PNG extensions outright per Rule: Image dimensions. Any error response (404, timeout, parse fail, unsupported format) means drop the candidate and pick another.
See also: Rule: Image dimensions, Rule: Image dedup.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Single bare canonical image URL (e.g. `https://images.pexels.com/photos/<id>/pexels-photo-<id>.jpeg`). Must respond with HTTP 200/206 to a Range request for the first 64KB. Provide `url` OR `urls`. | |
| urls | No | Batch mode: comma-separated bare image URLs, up to 50. Probed in parallel; one response carries per-URL results in input order — a failed URL is its own error entry and never breaks the batch. Preferred whenever vetting 2+ candidates. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=true, openWorldHint=true, idempotentHint=true, destructiveHint=false. Description adds significant context beyond annotations: it is a wrapper-native synthetic tool, Range-GETs first 64KB, parses JPG/PNG headers, does not proxy to BD. Also explains batch mode behavior (parallel probing, per-URL error handling) and unsupported format fallback. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections (main purpose, batch mode, caller contract). Information is front-loaded. While some details could be tightened, the length is justified given the complexity of batch mode and error handling. Slight redundancy in 'Rule: Image dimensions' reference could be shortened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, description thoroughly explains return values (width, height, format, aspect_ratio, orientation) and batch response envelope. Covers error scenarios (404, timeout, parse fail, unsupported format) and how to handle them. Complete for a probing tool with no nested objects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (both parameters described in schema). Description adds substantial meaning: for `url` specifies it must respond to Range request for first 64KB and be a canonical image URL; for `urls` explains batch mode details (comma-separated, up to 50, parallel probes, response envelope format in input order, failure isolation). This exceeds the schema's descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Probe an image URL and return its dimensions + orientation'. Specific verb and resource. Distinguishes from sibling tools by specifying its niche use in content-creation skills, which no other sibling appears to cover.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidelines: when to use (verify image orientation before committing to feature-image fields), batch mode preference for 2+ candidates, caller contract to filter to .jpg/.jpeg/.png, and error handling instructions. Also references related rules ('see also'). Provides clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getLeadARead-onlyIdempotent
Get a single lead - Fetch a single lead record. Read-only.
Use when: handling one lead - viewing its details after a lead-notification email, following up in a CRM integration, or confirming the lead exists before calling matchLead.
Required: lead_id.
See also: listLeads (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| lead_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, destructiveHint, idempotentHint. The description adds return format ('{ status: "success", message: [{...record}] }') and failure behavior (empty or 404), which goes beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structured with clear headings (Use when, Required, See also, Returns), front-loaded with purpose, and every sentence contributes value. No redundant words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, use cases, required parameter, return structure, and failure mode. No output schema needed; description is sufficient for a simple getter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description only states 'Required: lead_id,' which is redundant with the schema. Does not elaborate on the meaning or format of lead_id beyond its self-explanatory name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single lead' and 'Fetch a single lead record. Read-only.' Differentiates from listLeads (enumerate many) and matchLead (confirm before calling).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides 'Use when:' scenarios (viewing details after notification, CRM follow-up, confirming existence before matchLead) and 'See also:' alternative (listLeads for enumeration).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getLeadMatchARead-onlyIdempotent
Get a single lead match - Fetch a single leadmatch record. Read-only.
Use when: you have a specific match_id (from listLeadMatches) and need the full match row - lead points, price, response status, etc.
Required: match_id.
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| match_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly and idempotent. Description adds response format and 404 behavior, providing extra context beyond annotations. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise, front-loaded sections: purpose, usage condition, required param, and return format. No fluff, every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-record retrieval with one param and no output schema, description covers purpose, usage, required input, and return structure (including error case). Could include an example but not necessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only required param is match_id; description states it's required and derived from listLeadMatches but does not describe its meaning beyond that. Schema has 0% description coverage, so description partially compensates but not fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'get' and resource 'lead match record', and distinguishes from sibling listLeadMatches by specifying single record retrieval. Title is null but name itself communicates purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when you have a specific match_id' and references listLeadMatches for context. Implicitly tells when not to use (when no ID). Could explicitly state alternatives but sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMembershipPlanARead-onlyIdempotent
Get a single membership plan - Fetch a single membership-plan record. Read-only.
Use when: fetching one plan's config. Same lean-by-default as listMembershipPlans.
Required: subscription_id.
Lean-by-default keep-list: the core fields — subscription_id, subscription_name, subscription_type, profile_type, monthly_amount, yearly_amount, initial_amount, lead_price, searchable, search_membership_permissions, data_settings. A plan's members have a publicly accessible, searchable profile (BD's UI calls this "Listing Searchable") only when searchable=1 AND search_membership_permissions contains visitor. Opt in to restore:
include_plan_config=1- config bundle (limits, sidebars, forms, email templates, upgrade chain, payment defaults).include_plan_display_flags=1-show_*profile-visibility toggles.include_extras=1- returns the full BD plan row, untouched.
EAV-routed fields not merged: custom_checkout_url (and any future EAV-routed plan fields) are stored in users_meta and NOT returned by this endpoint even with include_plan_config=1. Read via listUserMeta database=subscription_types database_id=<subscription_id> to fetch them.
See also: listMembershipPlans (enumerate).
Returns: { status: "success", message: [{...record}] }.
| Name | Required | Description | Default |
|---|---|---|---|
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| subscription_id | Yes | ||
| include_plan_config | No | Opt in to restore plan config fields (limits, sidebars, forms, email templates, upgrade chain, display/payment settings). Default stripped. | |
| include_plan_display_flags | No | Opt in to restore profile-visibility toggles (`show_about`, `show_experience`, `show_phone`, `seal_link`, `website_link`, `social_link`, etc.). Default stripped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint, etc.), description reinforces read-only, details lean-by-default keep-list, specifies exactly which optional bundles restore which fields, notes EAV-routed fields not merged, and explains return format. Adds substantial behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structured with clear sections, front-loaded purpose. Slightly verbose in the keep-list enumeration but each part serves a purpose. No fluff, efficient overall.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, description fully explains return format, lean-by-default fields, opt-in bundles, and a known limitation (EAV not merged). Complete context for using the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 75% schema coverage, description compensates by explaining the lean-by-default pattern, clarifying the purpose of each include_* flag in context, and emphasizing subscription_id is required. Adds meaning beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Explicitly states 'Get a single membership plan' and 'Fetch a single membership-plan record. Read-only.' Differentiates from sibling `listMembershipPlans` for enumeration, giving a specific verb+resource+scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Use when: fetching one plan's config' and references sibling `listMembershipPlans` for enumeration. Positive guidance is clear and sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMemberSubCategoryLinkARead-onlyIdempotent
Get a single user-service relationship - Fetch a single Member ↔ Sub Category link by rel_id. Read-only.
Use when: you have a rel_id and need the full link row. Rare - most workflows query by user_id or service_id via listMemberSubCategoryLinks.
Required: rel_id.
See also: listMemberSubCategoryLinks (enumerate, filter by user_id or service_id).
Returns: { status: "success", message: [{...record}] }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| rel_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare read-only. The description reinforces this ('Read-only') and adds return format details ('{ status: "success", message: [{...record}] }'). No contradictions; adds value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, but contains extensive tangential background on member classification and sub-sub-categories that is not directly relevant to using this tool. This extra content reduces conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite a simple parameter set and no output schema, the description provides return format, use cases, and related concepts. The extra background adds completeness for understanding context, though not strictly necessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description compensates by naming the required parameter ('rel_id'), noting it is required, and explaining its role ('by rel_id'). Since only one simple parameter, this is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the action ('Get'/'Fetch'), the resource ('Member ↔ Sub Category link'), and the key parameter ('rel_id'). It distinguishes from the sibling 'listMemberSubCategoryLinks' by noting the scope difference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly specifies when to use ('when you have a rel_id'), rarity, and provides an explicit alternative ('listMemberSubCategoryLinks' for enumeration/filtering). Also notes common workflow patterns.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMenuARead-onlyIdempotent
Get a single menu - Fetch a single menu record. Read-only.
Lean-by-default keep-list: same shape as listMenus — returns only menu_id, menu_name, menu_title, revision_timestamp. Restore styling/target/rel/json_meta via include_extras=1.
Use when: fetching one menu's metadata. Child items are fetched separately.
Required: menu_id.
See also: listMenus (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 lean-shaped record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| menu_id | Yes | ||
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the lean-by-default keep-list structure, how to restore extras via include_extras=1, the return format (status, message array containing record), and the read-only nature. Annotations already mark readOnlyHint=true, idempotentHint=true, and the description aligns perfectly with no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (purpose, lean-by-default, use when, required, see also, returns). It is concise yet informative, with each sentence providing distinct value. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description fully explains the return format and the lean-by-default behavior. It also addresses when to use this tool versus listMenus. For a read-only single-record retrieval tool, this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning beyond the input schema by explaining that menu_id is required and that include_extras restores 'styling/target/rel/json_meta'. Since the schema only describes include_extras in detail, the description compensates for the missing menu_id description and clarifies the extras behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Get', 'fetch') and resource (single menu record). It explicitly distinguishes itself from the sibling tool 'listMenus' by saying 'Child items are fetched separately' and 'See also: listMenus (enumerate many).'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance with 'Use when: fetching one menu's metadata' and contrasts with when to use a sibling tool. It also states the required parameter and the lean-by-default vs extras behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMenuItemARead-onlyIdempotent
Get a single menu item - Fetch a single menuitem record. Read-only.
Lean-by-default keep-list: same shape as listMenuItems — returns only menu_item_id, menu_name, menu_link, menu_order, menu_id, master_id. Restore styling/target/rel/json_meta + the rarely-actionable revision_timestamp / menu_title / menu_display / tablesExists via include_extras=1.
Use when: editing one specific menu entry. Single-record fetch does NOT apply the empty-link filter — caller asked for this specific row by ID and gets it back.
Required: menu_item_id.
See also: listMenuItems (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 lean-shaped record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| menu_item_id | Yes | ||
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds context about the return format ('status:success, message containing one lean-shaped record') and behavior on missing (empty or 404). It also explains the lean-by-default keep-list and the effect of include_extras, which goes beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is relatively long but well-structured with clear sections (purpose, use when, see also, returns). It front-loads the core purpose. Some redundancy ('Get a single menu item - Fetch a single menuitem record') could be trimmed, but overall it is informative and not excessively verbose for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of an output schema, the description explains the return format and not-found behavior. It also covers the difference from the list sibling and details the optional parameter. This is sufficient for a simple read tool with clear metadata.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 50% coverage (include_extras described, menu_item_id not). The description states 'Required: menu_item_id' and explains the include_extras parameter in detail, including what fields are restored. This adds meaning beyond the schema, especially for the undocumented menu_item_id parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Get a single menu item - Fetch a single menuitem record.' This is a specific verb+resource combination. It also distinguishes from the sibling tool 'listMenuItems' by noting that this single-record fetch does not apply the empty-link filter, making the purpose very clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when: editing one specific menu entry.' It also provides a 'See also' reference to listMenuItems for enumeration. This gives clear guidance on when to use this tool versus the alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMultiImagePostARead-onlyIdempotent
Get a single album group - Fetch a single portfoliogroup record. Read-only.
Lean-by-default keep-list: same shape as listMultiImagePosts — core identity + routing fields plus total_clicks (only when > 0), total_photos, cover_photo_url, cover_thumbnail_url. Restore via flags: include_content=1 (full group_desc HTML), include_author_full=1 (full user nested — default omits author detail; call getUser(user_id) otherwise), include_clicks=1, include_photos=1 (full users_portfolio photo array), include_extras=1 (everything else — geo, post dates, timestamps, tokens, etc.).
Use when: fetching one multi-image post by group_id. Photos in this post are loaded separately via listMultiImagePostPhotos with group_id filter.
Required: group_id.
See also: listMultiImagePosts (enumerate many; supports keyword filter via property + property_operator=LIKE).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 lean-shaped record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| group_id | Yes | ||
| include_clicks | No | Opt in to return `user_clicks_schema.clicks` array. Default: `total_clicks` count surfaced only when > 0; absent means zero clicks. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_photos | No | Opt in to return `photos_schema` array. Default: `total_photos` count only (`image_main_file` URL always returned). | |
| include_content | No | Opt in to return the full `post_content` HTML body. Default stripped (`post_title` + `post_caption` always returned). | |
| include_author_full | No | Opt in to return the full original `user` nested object (every field BD returns, including `password` hash, session `token`, `cookie`). Default: author detail omitted entirely — call `getUser(user_id)` when needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint, destructiveHint, idempotentHint. Description adds details: lean-by-default keep-list, flags to restore more data, return format (status, message array), and behavior on not found (empty or HTTP 404). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections. Front-loaded purpose, then keep-list, use cases, and return format. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully explains the return shape, lean default behavior, and how to control output via flags. Provides guidance on related tools for photos. Sufficient for agent to correctly invoke.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 83% of parameters with descriptions. Description adds value by explaining the lean keep-list and the purpose of each include flag, especially the extras bundle. It also reiterates group_id is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it fetches a single album group/portfoliogroup record. Distinguishes from sibling tools like listMultiImagePosts (enumerate many) and listMultiImagePostPhotos (load photos separately).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states to use when fetching one multi-image post by group_id and that photos are loaded via listMultiImagePostPhotos. Provides a 'See also' link to listMultiImagePosts. Does not explicitly list when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMultiImagePostFieldsARead-onlyIdempotent
Get album group field definitions - Fetch field definitions for a multi-image post type form. Read-only.
Use when: discovering per-post-type custom fields for multi-image posts - same pattern as getSingleImagePostFields but for the users_portfolio_groups resource.
Required: form_name.
Returns: a BARE ARRAY of field-definition objects (NOT wrapped in {status, message}). Each entry has key, label, required, type, and optionally choices, default, helpText. Multi-image post fields seen: user_id, group_status, group_name, group_desc, post_image (CSV of image URLs), auto_image_import, post_tags, auto_geocode. Categorization for multi-image posts is exposed under an internal widget-controller field name, not a clean post_category - not straightforward to write via API.
Silent-fallback warning: if form_name does NOT match a real post-type form, BD may return a generic field list without error. Verify form_name exists in listPostTypes before trusting the response.
| Name | Required | Description | Default |
|---|---|---|---|
| form_name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds that it is 'Read-only' and provides detailed return format: a bare array (not wrapped in status/message) with specific fields like key, label, required, type, etc. It also includes a 'Silent-fallback warning' about potential misleading responses. This adds context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph but well-structured with clear sections. It front-loads the purpose and then provides usage guidelines, parameter requirement, return format, and warnings. It is slightly verbose but each sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only one parameter and no output schema, the description provides comprehensive context: the purpose, when to use, required parameter, detailed return structure, and a critical warning about silent fallback. It also notes a nuance about categorization. This is sufficient for an AI agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% (no parameter descriptions in schema). The description states 'Required: `form_name`' and clarifies that form_name must match a real post-type form. However, it does not explain what form_name represents (e.g., the form's name or identifier), leaving some ambiguity. It adds minimum value beyond the schema requirement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get album group field definitions - Fetch field definitions for a multi-image post type form. Read-only.' It uses a specific verb (fetch) and resource (field definitions for multi-image post type form) and distinguishes from sibling 'getSingleImagePostFields' by mentioning the 'users_portfolio_groups' resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when: discovering per-post-type custom fields for multi-image posts - same pattern as `getSingleImagePostFields` but for the `users_portfolio_groups` resource.' It also warns that if 'form_name' does not match a real post-type form, the API may return a generic field list without error, and advises verifying the form_name exists in 'listPostTypes' before trusting the response.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMultiImagePostPhotoARead-onlyIdempotent
Get a single album photo - Fetch a single portfoliophoto record. Read-only.
Lean-by-default keep-list: same shape as listMultiImagePostPhotos — photo_id, user_id, group_id, file, original_image_url, title, order, status, image_imported, revision_timestamp. Marketplace fields restore via include_marketplace=1.
Use when: editing or removing one specific photo within an album. You need the photo_id (from listMultiImagePostPhotos).
Required: photo_id.
See also: listMultiImagePostPhotos (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| photo_id | Yes | ||
| include_marketplace | No | Opt in to return the photo's marketplace/shop columns (`price`, `manufacturer`, `availability`, `product_category`, `product_type`, `condition`, `inv_id`, `link`, `additional_fields`). Default stripped — use when the site treats photos as a shop catalog (BD's marketplace feature). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. The description adds value by explicitly stating 'Read-only' and detailing the return format including the structure of the response for found and not found cases, which goes beyond annotation hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured with clear sections: a one-line summary, a lean-by-default keep-list, usage guidelines, required parameter, see also, and return format. Every sentence is purposeful and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (single record fetch by ID), the description fully covers purpose, parameters, return format, error behavior, and relationship to sibling tools. Annotations cover safety, and output schema is not needed due to explicit return format description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning beyond the schema by explaining the default keep-list fields and the purpose of 'include_marketplace' parameter. For 'photo_id', it emphasizes it is required and how to obtain it. The schema provides some description for 'include_marketplace', but the description adds contextual usage guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single album photo - Fetch a single portfoliophoto record.' It distinguishes the tool from the sibling 'listMultiImagePostPhotos' by explicitly mentioning 'single' and comparing to the list counterpart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: 'Use when: editing or removing one specific photo within an album.' It also mentions the required prerequisite 'photo_id (from listMultiImagePostPhotos)' and references the sibling tool 'listMultiImagePostPhotos' for enumeration.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getPostTypeARead-onlyIdempotent
Get a single post type - Fetch a single posttype record. Read-only.
Lean-by-default keep-list: same shape as listPostTypes — returns only the core identity + routing fields: data_id, data_type, system_name, data_name, data_filename, form_name, feature_categories, type_of_feature, is_event_feature, is_digital_product, revision_timestamp. Restore via flags: include_code=1 (the 8 PHP/HTML code-template fields — required when you intend to edit them via updatePostType), include_post_comment_settings=1 (the post_comment_settings JSON), include_review_notifications=1 (the 5 review-notification email fields), include_extras=1 (everything else: h1, h2, icon, category_tab, profile_tab, per_page, profile_per_page, sidebar configs, always_on, distance_search, display_order, caption_length, data_active, and all per-page/per-tab display toggles).
Use when: checking the configuration of one post type (which data_type family, whether active, custom field config, current search-results / profile-page template code). Commonly followed by getPostTypeCustomFields to enumerate per-type fields. Also the canonical read before any updatePostType code-field edit — apply Rule: Post-type code fields.
Required: data_id.
Code-field master-fallback: the up to eight HTML/PHP code fields on every post type record (category_header, search_results_div, category_footer, profile_header, profile_results_layout, profile_footer, search_results_layout, comments_code) begin life backed by the BD-core master template and only persist locally in the site DB when an admin (or API call) saves them. This endpoint returns the MASTER value for any code field that has no local override (when include_code=1) - so the agent always sees the real rendered code, not an empty string. This matters because any edit to one of the grouped code fields (search-results group = header+loop+footer, profile group = header+body+footer) MUST include all fields in that group on the write (see Rule: Post-type code fields). Always pass include_code=1 and read current values here BEFORE calling updatePostType for code-field edits.
Reserved data_types — not reachable here. If the resolved record's data_type is 10 (Member Listings), 13 (Member Ratings), or 21 (Member Categories), this endpoint returns message: [] (empty). To access these records, use listPostTypes property=data_type property_value=<value> (e.g. property_value=10) which returns the same data. Member Listings rows omit data_filename — members live at /<user.filename>, member directory landing is /search_results, never /listing/<id>.
See also: listPostTypes (enumerate many; reserved data_types default-excluded, opt-in via property=data_type, property_value=<value>), updatePostType (write; applies Rule: Post-type code fields and Rule: Member Listings post type), getPostTypeCustomFields (per-type custom field enum).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 lean-shaped record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | Yes | ||
| include_code | No | Opt in to return the PHP/HTML code-template fields on post types: `search_results_div`, `search_results_layout`, `profile_results_layout`, `profile_header`, `profile_footer`, `category_header`, `category_footer`, `comments_code`. Default stripped. Only needed when editing post-type templates. Each field can be 1-30KB. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_review_notifications | No | Opt in to return the 5 review-notification email template fields on post types: `review_admin_notification_email`, `review_member_notification_email`, `review_submitter_notification_email`, `review_approved_submitter_notification_email`, `review_member_pending_notification_email`. | |
| include_post_comment_settings | No | Opt in to return the `post_comment_settings` JSON-string field on post types (comment display / edit / delete settings). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, etc. Description adds extensive behavioral context: lean-by-default keep-list, code-field master-fallback behavior, reserved data_types returning empty message, and related rules. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is long but well-structured with bolded section headings. Front-loaded with purpose. Some repetition of code field names, but overall efficient and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given complexity (5 params, special behaviors, no output schema), description covers all necessary details: usage context, parameters, special cases, related tools, and return format. Highly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 80%, but description adds significant meaning to each parameter: explains include_code's master-fallback and grouped edit requirement, lists fields for include_review_notifications, describes include_extras bundle. Goes well beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single post type - Fetch a single posttype record. Read-only.' It specifies the verb and resource, and distinguishes from siblings like listPostTypes and updatePostType.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: checking the configuration of one post type... Commonly followed by getPostTypeCustomFields... Also the canonical read before any updatePostType code-field edit.' Also notes reserved data_types and alternatives, providing excellent guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getPostTypeCustomFieldsARead-onlyIdempotent
Get custom fields for a post type - Fetch a single posttypecustomfields record. Read-only.
Use when: building a create/update payload for a post type that has custom fields (most do). Returns the exact per-type schema to send.
Required: exactly one of data_id (numeric post-type ID) OR system_name (string, e.g. website_blog_article). When system_name is given the wrapper resolves it to data_id via listPostTypes before calling BD.
Parameter interactions:
data_id- the post type to introspect; get vialistPostTypessystem_name- friendlier alternative; the wrapper does the lookupReturns custom field definitions specific to this post type - use to build create/update payloads for matching posts
Discovering enumerated field values (e.g. post_category): per-post-type dropdowns like post_category are configured by the site admin and live in this schema. There is NO createPostCategory API tool - if the user needs a new dropdown option, that is admin-side work. Call this before a create/update to see the exact allowed values for select/radio/checkbox fields, and pass only those values verbatim.
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | No | Post type primary key. Pass this OR `system_name` (exactly one). | |
| system_name | No | Post type system name (e.g. `website_blog_article`). Wrapper resolves to `data_id` via `listPostTypes`. Pass this OR `data_id` (exactly one). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=true, idempotentHint=true. The description adds that the tool is 'Read-only' and explains the resolution of system_name to data_id via listPostTypes. It also mentions the return format and behavior when not found (empty or 404). No contradictions. Excellent transparency beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections (bold headers) and is informative without being overly verbose. Each sentence adds value. It is slightly longer than necessary but remains focused and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description details the return format: '{ status: "success", message: [{...record}] }' and behavior for not found. It also covers parameter interactions, use case, and even addresses the lack of a create endpoint for dropdown values. This is comprehensive for a read-only tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3. The description adds meaning by explaining the mutual exclusivity requirement: 'exactly one of data_id OR system_name'. It also describes how system_name is resolved and that data_id comes from listPostTypes. This provides context beyond the schema's property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Get custom fields for a post type - Fetch a single posttypecustomfields record.' This clearly states the action and resource, distinguishing it from siblings like createPostType or deletePostType. The purpose is unambiguous and precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'Use when: building a create/update payload for a post type that has custom fields (most do).' This gives a clear use case. However, it does not specify alternatives or when not to use, but the context is sufficient. Score 4 for clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getRedirectARead-onlyIdempotent
Get a single redirect - Fetch a single redirect record. Read-only.
Use when: investigating one specific redirect rule by redirect_id.
Required: redirect_id.
See also: listRedirects (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| redirect_id | Yes | Redirect primary key |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. The description adds value by detailing the return format ('{ status: "success", message: [{...record}] }') and behavior when not found (empty or 404), which goes beyond what annotations offer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bold section headings, and it is concise: four sentences covering purpose, usage, required parameter, see-also, and return information. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low complexity (1 param, no output schema), the description is complete. It explains what the tool does, when to use it, what input is required, and what output to expect. Annotations cover safety and idempotency, so no gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of the single parameter (redirect_id) with a description. The description repeats that redirect_id is required, but adds context by saying 'investigating one specific redirect rule by redirect_id', which provides usage context beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single redirect' and 'Fetch a single redirect record. Read-only.' This is a specific verb and resource, and it distinguishes itself from the sibling listRedirects by focusing on one specific redirect rule.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when: investigating one specific redirect rule by redirect_id.' and provides a see-also for listRedirects, offering clear guidance on when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getReviewARead-onlyIdempotent
Get a single review - Fetch a single review record. Read-only.
Lean by default: review_description is truncated to the first 500 chars + … when longer (tagged review_description_truncated: true). Pass include_full_text=1 to get the complete body. For a single-record inspection this is usually the right call.
Use when: investigating one specific review (usually from a moderation notification or support ticket that includes the review_id). For bulk moderation use listReviews with review_status filter.
Required: review_id.
See also: listReviews (enumerate many; supports keyword filter via property=review_description property_operator=LIKE).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| review_id | Yes | ||
| include_full_text | No | Opt in to return the full `review_description` body. Default is lean: bodies over 500 chars are truncated and tagged `review_description_truncated: true`. Set `1` to get the complete body for this specific review. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, etc. The description adds useful behavior like truncation of review_description and the effect of include_full_text, along with response format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bold headers, front-loaded purpose, and efficient sentences. Slightly verbose on return format but overall concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Completely covers tool usage, parameters, return behavior, and sibling references. No output schema, but description provides enough context for an AI agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers include_full_text with description, but the description explains truncation details and mentions review_id as required. Adds practical context beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single review' and 'Fetch a single review record', specifying the verb and resource. It distinguishes from sibling tools like listReviews (bulk) and mutation tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: investigating one specific review...' and directs to listReviews for bulk moderation, providing clear context and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSidebarARead-onlyIdempotent
Get a single custom sidebar - Fetch a single custom sidebar by sidebar_id. Read-only.
Required: sidebar_id (path).
Only returns custom sidebars. Master defaults are not rows in this table — see Rule: Sidebars for the canonical Master Default list; use those names directly in form_name without looking them up.
Returns: { status: "success", message: [{...record}] }.
| Name | Required | Description | Default |
|---|---|---|---|
| sidebar_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, and non-destructive. The description adds that it only returns custom sidebars, not master defaults, providing behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise and well-structured: purpose, required parameter, behavioral note, and return format. No redundant sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequately covers the key aspects: what it does, required param, behavior, and return format. Could mention error handling but overall complete for a simple getter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no description for sidebar_id (0% coverage), but the description explains it is required and identifies the sidebar, adding necessary meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches a single custom sidebar by ID, distinguishing it from siblings like listSidebars.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly specifies the required parameter and clarifies that only custom sidebars are returned, with a note about master defaults. Does not explicitly exclude alternatives but provides clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSingleImagePostARead-onlyIdempotent
Get a single post - Fetch a single post record. Read-only.
Lean-by-default keep-list: response returns only the core identity + routing + load-bearing fields: post_id, post_title, post_filename, post_status, post_start_date, post_expire_date, post_location, post_venue, post_category, data_id, data_type, system_name, data_name, data_filename, user_id, post_image, original_image_url, revision_timestamp, plus total_clicks (only when > 0) / total_photos rollups. Same shape as listSingleImagePosts. Restore via flags: include_content=1 (full post_content HTML), include_post_seo=1 (meta_title/description/keywords), include_author_full=1 (full user nested — default omits author detail; call getUser(user_id) otherwise), include_clicks=1 (click array), include_photos=1 (photo array on multi-image), include_extras=1 (everything else: lat, lon, country_sn, state_sn, post_org_url, post_date, post_live_date, post_updated, post_token, post_clicks, recurring_type, sticky_post, post_featured, post_tags, post_job, post_video, post_price, image_imported, etc.).
Use when: fetching one post by post_id. For enumeration or keyword search use listSingleImagePosts (with property=post_title property_operator=LIKE for keyword-in-body).
Required: post_id.
See also: listSingleImagePosts (enumerate many; supports keyword filter via property + property_operator=LIKE).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 lean-shaped record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| include_clicks | No | Opt in to return `user_clicks_schema.clicks` array. Default: `total_clicks` count surfaced only when > 0; absent means zero clicks. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_photos | No | Opt in to return `photos_schema` array. Default: `total_photos` count only (`image_main_file` URL always returned). | |
| include_content | No | Opt in to return the full `post_content` HTML body. Default stripped (`post_title` + `post_caption` always returned). | |
| include_post_seo | No | Opt in to return `post_meta_title`, `post_meta_description`, `post_meta_keywords`. Default stripped. | |
| include_author_full | No | Opt in to return the full original `user` nested object (every field BD returns, including `password` hash, session `token`, `cookie`). Default: author detail omitted entirely — call `getUser(user_id)` when needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds important context about the lean-by-default keep-list, the include flags to expand the response, and that it returns 404 when not found. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: purpose, keep-list, flag explanations, usage guidance, required field, see also, return format. It front-loads the main purpose. While it is somewhat lengthy, every sentence adds value and the structure is logical.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description includes the return format and 404 behavior. Parameters are well-explained through both schema and description. The keep-list and flags are thoroughly documented. Sibling tools are referenced. It is complete for a read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 86% (high), so baseline is 3. The description provides high-level context for the include_* flags by explaining the lean-by-default strategy, but the schema already fully describes each parameter. The description does not add significant new meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single post - Fetch a single post record. Read-only.' It specifies the resource (post) and action (fetch/get), and distinguishes from the sibling tool listSingleImagePosts by stating 'For enumeration or keyword search use listSingleImagePosts'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance: 'Use when: fetching one post by post_id. For enumeration or keyword search use listSingleImagePosts'. Also provides a 'See also' reference to the sibling tool. This clearly tells when to use and what alternative to use for other scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSingleImagePostFieldsARead-onlyIdempotent
Get post field definitions - Returns custom fields for a specific post type form.
Use when: discovering the per-post-type custom fields before building a create/update payload. Pass form_name of the target post type (e.g. blog_article_fields, events_fields, etc.).
Required: form_name.
Returns: a BARE ARRAY of field-definition objects (NOT wrapped in {status, message}). Each entry has key, label, required, type, and optionally choices (for dropdown/radio), default, helpText.
Silent-fallback warning: if form_name does NOT match a real post-type form, BD returns HTTP 200 with a generic SUPER-UNION field list (containing every possible post field including post_location, lat, lon, post_live_date, post_video, post_job, internals like post_type/logged_user/form_security_token) - and post_category.choices will be ABSENT. Always verify form_name exists first via listPostTypes (look for the matching row's form_name column). If your response has post_category WITHOUT a choices array, you hit the fallback.
post_category values do NOT come from this endpoint: on some forms BD fills post_category.choices from platform master defaults (Sport, Business, ...) instead of this site's list. Source post_category from the post type's feature_categories (on your listPostTypes/getPostType result) and pass one value from it. BD does NOT trim whitespace when splitting the CSV - options after the first may have a leading space (e.g. " Category 2"). Pass VERBATIM.
| Name | Required | Description | Default |
|---|---|---|---|
| form_name | Yes | Form slug for the post type |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnly, openWorld, idempotent), the description discloses critical behavioral details: the return is a bare array (not wrapped), the silent-fallback behavior when form_name is invalid, the exact shape of fallback responses, and that post_category values do not come from this endpoint. It also highlights a whitespace trimming issue. This adds significant value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with clear sections (Use when, Required, Returns, Silent-fallback warning, post_category note). It is front-loaded with the purpose, and every sentence provides essential information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single parameter and no output schema, the description fully compensates by detailing the return format, edge cases, fallback detection, and cross-references to other tools. An agent has all information needed to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema covers the parameter with 100% description, the tool description adds examples ('blog_article_fields, events_fields') and clarifies the impact of an invalid form_name (fallback). This goes beyond the schema's 'Form slug for the post type'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves custom fields for a specific post type form, with a specific verb 'Get' and resource 'post field definitions'. It distinguishes from siblings by specifying the use case of discovering per-post-type custom fields before building create/update payloads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('discovering the per-post-type custom fields before building a create/update payload'), what is required ('form_name'), and provides a warning about silent-fallback with instructions to verify form_name via listPostTypes. Also gives guidance on handling post_category.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSiteInfoARead-onlyIdempotent
Get site-level identity, locale, currency, and brand-image URLs - Returns the site's own identity and locale context — what kind of directory this is, who it serves, the formatting conventions to respect, and the URLs of branding assets. Read-only, no params. Call this once on the first BD task of a conversation and cache for the session; the values rarely change mid-conversation.
Response shape (wrapper adds current_site_datetime — the site-local datetime at call time, YYYYMMDDHHmmss; use it whenever a date field needs "now" and no more precise clock is available): { status: "success", message: { website_id, website_name, website_phone, full_url, main_directory_url_relative, main_directory_url_absolute, profession, industry, primary_country, language, timezone, date_format, distance_format, website_currency, currency_prefix, currency_suffix, currency_format, currency_decimal_divider, currency_thousand_divider, brand_images_relative: {...}, brand_images_absolute: {...}, default_checkout_url } }.
Field semantics to know:
website_id= the site's tenant ID (integer). Used for centralized-admin URL composition (e.g.&newsite=<website_id>onww2.managemydirectory.com/admin/...links). Cache per session.profession= SITE-LEVEL setting describing the archetype of member this directory lists (e.g."Doctor","Personal Trainer"). NOT related to a member'sprofession_id(that's a foreign key into the per-memberlist_professionstaxonomy).industry= SITE-LEVEL setting describing the market/vertical the site serves (e.g."Healthcare","Fitness"). Site metadata, not a member attribute.full_url= the canonical site URL, no trailing slash — its scheme matches your connection and is the correct scheme for every site link you compose (http-only sites returnhttp://, https siteshttps://). Use this when composing public profile URLs (<full_url>/<user.filename>,<full_url>/<seo_id filename>).main_directory_url_relative/main_directory_url_absolute= the site's main member-search-results page (unfiltered directory landing). The canonical "browse all members" / "see the full directory" internal-link target. Use absolute as-is; relative is path-only with no leading slash (e.g."search") — compose as<full_url>/<relative>.timezone/date_format/distance_format/website_currency+ thecurrency_*formatting bits = locale context for how to present data back to the user (dates, distances, money). Respect these when formatting.brand_images_relativeandbrand_images_absolute= parallel objects with 8 keys each (website_logo,website_mascot,website_background,favicon,default_profile_image,default_logo_image,verified_member_image,watermark). Relative = path-only (e.g./images/logo.webp); absolute = full URL (scheme matches your connection). Use absolute URLs when embedding in emails / external content; relative when embedding on the site itself.default_profile_imageon a member read signals "no real photo" — compareimage_main_fileto this URL to detect placeholder state.
Why agents should call this early: the grounding it provides (site purpose, member archetype, locale) shapes every subsequent decision — what 'add a member' means, what categories are relevant, how to format dates and money, what the profile-placeholder image looks like, which brand assets to use in designs.
Auth: X-Api-Key. Rate limit: standard 100 req/60s. Cache for the session.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, idempotentHint, and destructiveHint=false. The description adds rich behavioral context: it details the response shape, field semantics, and caching recommendation. It also mentions auth method and rate limit. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: purpose, caching advice, response shape, field semantics, and rationale. It is front-loaded with the main purpose. Despite length, every sentence adds value, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description fully explains the response shape and field semantics, covering every relevant field. It also includes caching strategy, auth details, and rate limit. The tool's role is uniquely defined among many siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so schema coverage is 100%. The baseline for 0 params is 4. The description does not need to add parameter semantics but instead thoroughly explains the output fields, which adds value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Get site-level identity, locale, currency, and brand-image URLs.' The verb 'Get' and the resource 'siteInfo' are explicit. The tool is distinct from siblings like getUser or listCities, and the description emphasizes its role in providing foundational site context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises agents to call this once per session and cache the results, noting that values rarely change mid-conversation. It also explains why calling early is beneficial for shaping subsequent decisions, providing clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSmartListARead-onlyIdempotent
Get a single smart list - Fetch a single smartlist record. Read-only.
Use when: fetching one saved filter's config.
Required: smart_list_id.
See also: listSmartLists (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| smart_list_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description declares read-only behavior (matching annotations) and adds return format details: '{ status: "success", message: [{...record}] }' and handling of not-found cases (empty or 404). This supplements the annotations with concrete response behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured, using markdown for readability. Each sentence serves a distinct purpose: what, when, required param, see also, and return format. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple fetch tool with one parameter, the description covers all essential aspects: operation type, usage context, required parameter, related tool, and return behavior (including error cases). No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description mentions that smart_list_id is required, but the schema already marks it required. With 0% schema description coverage, the description adds minimal value; however, the parameter name is self-explanatory given the tool's purpose, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single smart list - Fetch a single smartlist record. Read-only.' This specifies the verb (Get/Fetch) and the resource (smart list), distinguishing it from sibling tools like listSmartLists and other CRUD operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly provides a use case: 'Use when: fetching one saved filter's config.' It also references the sibling tool listSmartLists for enumeration, guiding when to choose this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getStateARead-onlyIdempotent
Get a single state/province - Fetch one state row by location_id. Read-only.
Required: location_id (path). Note: location_states PK is location_id (correctly spelled, unlike location_cities.locaiton_id).
Returns: { status: "success", message: [{...record}] }.
| Name | Required | Description | Default |
|---|---|---|---|
| location_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Explicitly states read-only and provides return format structure ({ status, message }), adding value beyond annotations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very concise: three sentences serving distinct purposes (what, required param, return). Information is front-loaded and no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all essential aspects for a simple get tool: action, input, output format. Lacks error handling or behavior when record not found, but sufficient for typical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, description partially compensates by stating location_id is required and is a path parameter, and noting the primary key spelling. Lacks detailed semantic guidance on valid values or source.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action (get/fetch), resource (state/province), and identifier (by location_id). Distinguishes from sibling tools like listStates (multiple) and getCity/getCountry.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context for fetching a single state row by location_id and specifies the required parameter. Does not explicitly list when not to use, but the purpose is self-explanatory given siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSubCategoryARead-onlyIdempotent
Get a single service - Fetch a single SUB-level member category (service) by service_id. Read-only.
Lean by default: keeps service_id, profession_id, master_id, name, filename. Strips SEO metadata (desc, keywords, image, icon, sort_order, lead_price, revision_timestamp). Pass include_category_schema=1 to restore.
Use when: fetching one sub-category by service_id - usually after discovering it via listSubCategories.
Required: service_id (path).
See also: listSubCategories (enumerate; filter by profession_id for scope), getTopCategory (fetch parent Top by profession_id).
Returns: { status: "success", message: [{...record}] }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| service_id | Yes | ||
| include_category_schema | No | Opt in to restore full category metadata: `desc` (SEO description), `keywords`, `image`, `icon`, `sort_order`, `lead_price`, `revision_timestamp`. Default lean keeps: category ID + `name` + `filename` + hierarchy links (`profession_id` on top/sub, `master_id` on sub for sub-sub parent). Hierarchy is always visible so agents can traverse top -> sub -> sub-sub without opt-in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. Description adds critical info about lean default behavior (strips SEO metadata), how to opt-in (include_category_schema=1), and return format. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Core purpose and usage are front-loaded in first sentences. However, additional paragraphs about member classification and sub-sub-categories, while informative, extend length. Could be trimmed without losing essential guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, parameters, return format, lean behavior, and when to use. Provides relevant domain context about classifications. No output schema but return format is described. Complete for a read tool with good annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (only include_category_schema has description). Description compensates by explaining what each parameter does: service_id is path, include_category_schema restores metadata. Adds meaning beyond schema defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Get a single service - Fetch a single SUB-level member category (service) by service_id.' Specifies verb and resource, and distinguishes from sibling tools like listSubCategories and getTopCategory.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' guidance and 'See also' section naming alternative tools and their purposes. Tells agent to use after discovering via listSubCategories, and contrasts with getTopCategory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getTagARead-onlyIdempotent
Get a single tag - Fetch a single tag record. Read-only.
Use when: fetching one tag by ID.
Required: id.
See also: listTags (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=true, destructive=false, idempotent=true. Description adds return format and not-found handling, enhancing transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very concise, front-loaded, and well-structured with clear sections. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one parameter, the description covers purpose, usage, required param, return format, and error case. Fully adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but description only repeats 'Required: id' from schema. No additional meaning about the parameter beyond its name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Get a single tag' and 'Fetch a single tag record.' Distinguishes from sibling listTags by mentioning it enumerates many tags.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: fetching one tag by ID' and 'Required: id.' Also provides 'See also: listTags' for alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getTagGroupARead-onlyIdempotent
Get a single tag group - Fetch a single taggroup record. Read-only.
Use when: fetching one tag group by ID.
Required: id.
See also: listTagGroups (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds return format and not-found behavior ('Returns: { status: "success", message: [{...record}] } … Empty or HTTP 404 when not found'), enhancing behavioral disclosure beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (Purpose, Use when, Required, See also, Returns) and is concise, with no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple Get-by-ID tool with one parameter and no output schema, the description covers purpose, usage, required parameter, alternative tool, and return format, making it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. However, it only repeats 'Required: id' which is already in the schema. It adds no explanation of what 'id' represents (e.g., the unique identifier of the tag group), providing minimal added meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get a single tag group - Fetch a single taggroup record. Read-only,' using a specific verb and resource. It distinguishes itself from sibling 'listTagGroups' by stating 'See also: listTagGroups (enumerate many).'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly includes 'Use when: fetching one tag group by ID' and 'Required: id,' plus references 'listTagGroups' as an alternative, providing clear guidance on when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getTagRelationshipARead-onlyIdempotent
Get a single tag relationship - Fetch a single tagrelationship record. Read-only.
Use when: one relationship row by ID.
Required: id.
See also: listTagRelationships (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, destructiveHint, etc. Description adds return format and empty/404 behavior, complementing annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, well-structured with headings, covers all necessary information in a few lines without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one parameter, description fully covers purpose, usage, required param, alternative, and return format/behavior. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has no parameter description (0% coverage). Description mentions 'Required: id' but doesn't elaborate beyond what is obvious from context. Adequate but minimal added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it fetches a single tag relationship by ID, distinguishing from listTagRelationships. Among siblings, many get tools, but explicitly says 'single' and 'by ID'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: one relationship row by ID' and 'See also: listTagRelationships (enumerate many)', providing when-to-use and alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getTagTypeARead-onlyIdempotent
Get a single tag type - Fetch a single tagtype record. Read-only.
Use when: one tag type by ID.
Required: id.
See also: listTagTypes (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint true and destructiveHint false, and the description adds return format and behavior on not found, providing operational context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is short (3 sentences plus return format), front-loaded with purpose, and no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-id tool with one parameter and no output schema, the description covers purpose, usage, required param, return format, and not-found case. Annotations provide safety hints.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only parameter 'id' is described as 'Required: id', but no additional meaning given. With 0% schema description coverage, the description should compensate but only restates requirement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and resource 'tag type' or 'tagtype record', and distinguishes from sibling 'listTagTypes' which enumerates many.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: one tag type by ID' and provides 'See also: listTagTypes' for enumeration, but lacks explicit when-not conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getTopCategoryARead-onlyIdempotent
Get a single category - Fetch a single TOP-level member category by profession_id. Read-only.
Lean by default: keeps profession_id, name, filename. Strips SEO metadata. Pass include_category_schema=1 to restore.
A Top Category is the highest level of the 3-tier member classification. Backed by BD's list_professions table.
Use when: you already have a profession_id and need its full record (name, filename, etc.). For enumeration use listTopCategories.
Required: profession_id (path parameter).
See also: listTopCategories (enumerate), listSubCategories (sub-categories under this one; filter by profession_id).
Returns: { status: "success", message: [{...record}] } - array of 1 record with full fields.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| profession_id | Yes | ||
| include_category_schema | No | Opt in to restore full category metadata: `desc` (SEO description), `keywords`, `image`, `icon`, `sort_order`, `lead_price`, `revision_timestamp`. Default lean keeps: category ID + `name` + `filename` + hierarchy links (`profession_id` on top/sub, `master_id` on sub for sub-sub parent). Hierarchy is always visible so agents can traverse top -> sub -> sub-sub without opt-in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Matches annotations (readOnlyHint, idempotentHint) and adds details: default lean output, opt-in for full schema, return format, and even broader classification context. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-organized and front-loaded with essential info, but somewhat long due to extra classification details. Still efficient for the depth provided.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a get tool: describes behavior, parameters, output format, and relationship to other tools. No output schema, but return structure is explained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond schema: profession_id required as path parameter, include_category_schema explained with effect on output. Schema has 50% coverage but description compensates fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it fetches a single TOP-level category by profession_id, read-only. Distinguishes from sibling tools like listTopCategories and listSubCategories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use (have profession_id, need full record), when-not-to (use listTopCategories for enumeration), and lists alternatives with specific use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUnsubscribeARead-onlyIdempotent
Get a single unsubscribe record - Fetch a single unsubscribe record. Read-only.
Use when: checking one unsubscribe record by ID.
Required: id.
See also: listUnsubscribes (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true. The description adds return format '{ status: "success", message: [{...record}] }' and mentions empty/404 on not found, which are helpful behavioral details. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is very concise: a single sentence plus structured sections (Use when, Required, See also, Returns). Every sentence adds value. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one parameter, the description covers purpose, usage, parameter, return format, and error cases. It is complete and leaves no ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter 'id' with no schema description (0% coverage). Description states 'Required: `id`' and 'by ID', adding context that id is the identifier for the unsubscribe record. It could be improved by clarifying what the id refers to, but it's sufficient for a single param.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single unsubscribe record' and specifies read-only. It uses a specific verb and resource, and distinguishes from sibling 'listUnsubscribes' by noting this fetches one record by ID.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: checking one unsubscribe record by ID.' and provides 'See also: listUnsubscribes (enumerate many).' This gives clear guidance on when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUserARead-onlyIdempotent
Get a single member/user - Fetch a single user record. Read-only.
Lean-by-default keep-list: same shape as listUsers — identity + routing + location core (user_id, first_name, last_name, email, company, phone_number, subscription_id, profession_id, active, status, city, state_code, country_code, filename, image_main_file, signup_date, last_login, modtime). Restore extras via flags: include_password=1, include_subscription=1, include_clicks=1, include_photos=1, include_transactions=1, include_profession=1, include_tags=1, include_services=1, include_seo_hidden=1, include_about=1, include_legacy_fields=1, include_extras=1 (billing/analytics rollups revenue/card_info/total_clicks/total_photos, duplicate location fields state_ln/country_ln/full_name/user_location/zip_code/lat/lon, plus social URLs, awards, credentials, position, quote, work_experience, ref_code, booking_link, etc.).
Use when: you already have the user_id (from listUsers, searchUsers, a prior create, or a webhook payload) and need the full member record. Cheaper than listUsers + filter. For lookups by email or other field, use listUsers with property/property_value.
Required: user_id.
See also: listUsers (enumerate many), searchUsers (keyword search).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 lean-shaped record when found. Empty or HTTP 404 when not found.
Payment method on file (under include_extras=1): card_info is false when no card is stored (BD convention), or an object with last4/brand/name when one is. Use card_info && card_info.last4 to safely check. Authoritative signal for "does this member have a payment method" — don't infer from subscription_id alone.
Profile URL: every user record has a filename field. To get the full public profile URL, concatenate: <site-domain>/<user.filename>. The filename is the complete relative path (e.g., united-states/monterey-park/doctor/harrison-hasanuddin-d-o) - DO NOT prepend /business/, /profile/, /member/, or any other segment. BD's router resolves filename verbatim. Note: filename is regenerated by BD when member inputs that influence the slug change (category, city, etc.). The value you see NOW is current-as-of-this-read. If you call updateUser afterward, re-fetch before using the filename in URL-referencing content (blog posts, emails, redirects).
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | ||
| include_tags | No | Opt in to return `tags` array. Default stripped. | |
| include_about | No | Opt in to return the `about_me` HTML bio. Default stripped. | |
| include_clicks | No | Opt in to return `user_clicks_schema.clicks` array. Default: `total_clicks` count surfaced only when > 0; absent means zero clicks. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_photos | No | Opt in to return `photos_schema` array. Default: `total_photos` count only (`image_main_file` URL always returned). | |
| include_password | No | Opt in to return bcrypt `password` hash. Default stripped. | |
| include_services | No | Opt in to return `services_schema` sub-category array. Default stripped. | |
| include_profession | No | Opt in to return `profession_schema` (category metadata). Default: `profession_id` only. | |
| include_seo_hidden | No | Opt in to return SEO meta fields (`seo_page_*_hidden`, `seo_social_*_hidden`, `search_description`). Default stripped. | |
| include_subscription | No | Opt in to return full `subscription_schema` (60+ plan fields). Default: `subscription_id` only. | |
| include_transactions | No | Opt in to return full `transactions` invoice array. Default stripped (`revenue` rollup always returned). | |
| include_legacy_fields | No | Return image-import state on `photos_schema` rows: `original`, `resized`, `error`. Requires `include_photos=1`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, destructiveHint, idempotentHint, openWorldHint. The description adds substantial context beyond annotations, including the lean-by-default keep-list, behavior of include flags, return format, filename regeneration, and payment method detection logic. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bold headings, bullet points, and clear sections (purpose, usage, params, return, notes). While lengthy, every sentence serves a purpose. Some redundancy (e.g., 'Get a single member/user' repeated) could be trimmed, but overall structure is effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 13 parameters and no output schema, the description is extremely thorough: covers return format, success/error behavior (empty array/404), special fields (card_info), filename usage and regeneration caveat, and references to siblings. It leaves no important aspect unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (92%), so baseline 3. The description adds significant value by explaining the lean-by-default keep-list, the purpose of each include flag (e.g., 'include_extras' bundle content), and the semantics of 'card_info'. However, the schema already documents most parameters, so the description supplements rather than replaces.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Get a single member/user - Fetch a single user record', clearly identifying the tool's action and target. It differentiates from siblings like listUsers (enumerate many) and searchUsers (keyword search), providing clear purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Use when: you already have the user_id...' and contrasts with alternatives: 'For lookups by email or other field, use listUsers with property/property_value.' It also includes a caveat about re-fetching filename after updateUser.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUserFieldsARead-onlyIdempotent
Get user field definitions - Returns available fields for user records with labels and required flags. Use this to discover custom fields.
Use when: building dynamic forms or importers - you need to discover which fields exist on the User record on THIS specific site (custom fields vary per BD site config). Also useful for validating import-CSV headers before running a batch.
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld. Description adds that it returns status/message structure, with empty/404 when not found, which is additional useful context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is clear and well-structured with 'Use when' and return format. Slightly verbose (code block), but every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, description explains return format and use case context (site-specific custom fields). Fully covers what an agent needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters; baseline 4 applies. No additional param info needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Describes retrieving user field definitions with labels and required flags. Distinguishes from siblings like getPostTypeCustomFields by specifying 'user records' and noting custom fields vary per site.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: building dynamic forms or importers - you need to discover which fields exist on the User record on THIS specific site' and also mentions validating import-CSV headers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUserMetaARead-onlyIdempotent
Get a single metadata record - Fetch a single usermeta record. Read-only.
Use when: fetching one metadata row by meta_id.
Required: meta_id.
Identity check before downstream writes: Before using this row's meta_id for any subsequent updateUserMeta/deleteUserMeta call, confirm the response's database and database_id fields BOTH match the parent record you intend to modify. The same database_id can exist across unrelated parent tables (users_data, list_seo, subscription_types, data_posts, etc.) - blindly passing a meta_id forward without verifying its (database, database_id) pair can silently corrupt or destroy data on an unrelated table. Optional database and database_id query params are accepted for documentation/intent — the actual verification is agent-side (compare message[0].database / message[0].database_id to what you expected before acting).
See also: listUserMeta (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| meta_id | Yes | ||
| database | No | OPTIONAL — your expected parent table name (e.g. `list_seo`). Accepted for intent documentation; verification is agent-side (compare `message[0].database` in the response). Recommended on any `getUserMeta` preceding a write to the users_meta table. | |
| database_id | No | OPTIONAL — your expected parent record PK. Same intent-documentation convention as `database`. Agent-side verification: compare `message[0].database_id` before acting on the row. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint, etc.), the description discloses critical behavioral traits: the need for agent-side verification of (database, database_id) pairs to prevent silent data corruption. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, front-loaded with purpose. Slightly verbose due to safety warnings, but every sentence is justified; could tighten slightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Fully complete given no output schema: covers purpose, parameters, usage guidelines, safety warnings, and return format. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds significant meaning beyond the input schema: explains the optional params as intent documentation and the agent-side verification procedure, complementing the 67% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches a single metadata record by meta_id, differentiating it from listUserMeta for enumeration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: fetching one metadata row by meta_id' and provides detailed safety verification steps to avoid data corruption. Also references sibling tool listUserMeta.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUserPhotoARead-onlyIdempotent
Get a single user photo - Fetch a single userphoto record. Read-only.
Use when: fetching one photo record by photo_id.
Required: photo_id.
See also: listUserPhotos (enumerate many).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record when found. Empty or HTTP 404 when not found.
| Name | Required | Description | Default |
|---|---|---|---|
| photo_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld. Description adds 'Read-only' and return format including empty/404 behavior. Provides extra context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise and well-structured with clear sections: Use when, Required, See also, Returns. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool, the description covers purpose, usage, alternatives, and return behavior. No gaps given the single parameter and no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, description only mentions required photo_id without additional semantic context (e.g., format, source). Fails to compensate for missing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it fetches a single user photo record by photo_id. Distinguishes from sibling listUserPhotos by specifying 'single' vs 'enumerate many'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use ('fetching one photo record by photo_id') and points to alternative listUserPhotos for enumerating many.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUserSubscriptionsARead-onlyIdempotent
Get member subscriptions (membership plan history) - Fetch the subscription / membership-plan history for a specific member. Read-only. Backed by the WHMCS billing integration.
Required: exactly one of user_id (standard — the BD member ID) OR client_id (power-user — the WHMCS billing record ID stored on the user as users_data.clientid). Default to user_id; reach for client_id only when you already have one in hand and want to bypass the user lookup.
Empty result with misleading error: if the member has no billing record yet (never enrolled in any paid plan), BD returns HTTP 400 + {status:"error", message:"user_id or client_id is required"} even though the identifier WAS sent. The error wording is BD's, not the wrapper's. Treat that exact error message on this endpoint as "no billing data for this member" rather than "missing parameter".
Use when: checking a member's current membership plan, their billing cycle (Monthly/Yearly), next due date, plan upgrade history, whether auto-renewal is on, or past canceled subscriptions.
See also: getUserTransactions (invoice-level billing records - different resource), getUser (member profile - profile-level subscription references subscription_id), listMembershipPlans (all plan definitions on the site).
Returns: { status: "success", message: { total: <count>, subscriptions: [{...subscription records}] } }. Each subscription includes id, userid, packageid (membership plan ID), regdate, nextduedate, billingcycle (e.g. Monthly, Yearly), paymentmethod, amount, domainstatus (Active, Cancelled, etc.), and related fields. NOT a simple list of rows - the message is an object containing subscriptions as the array.
Reference support articles:
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | Member ID (the standard input). Pass this OR `client_id`. | |
| client_id | No | WHMCS billing record ID. Power-user alternative to `user_id`. Pass this OR `user_id`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses a misleading error scenario (HTTP 400 + 'user_id or client_id is required' when member has no billing record) and how to interpret it. Describes return format in detail. No contradiction with annotations (which already indicate read-only, idempotent, non-destructive).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections (Required, Empty result, Use when, See also, Returns). Every sentence adds value, and the length is justified given the complexity (error handling, parameter choice). No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: purpose, parameter constraints, error handling, use cases, related tools, and return structure. Despite no output schema, the description fully explains the response format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds significant meaning beyond schema: exactly one required, default to user_id, client_id for power-users bypassing lookup. Schema already has descriptions, but the usage guidance is invaluable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves member subscription/membership-plan history. It names the resource and distinguishes it from siblings like getUserTransactions (invoice-level) and getUser (profile-level references).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (checking membership plan, billing cycle, etc.) and provides a 'See also' section with alternatives. Includes specific guidance on choosing between user_id and client_id, defaulting to user_id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getUserTransactionsARead-onlyIdempotent
Get member billing transactions (invoices) - Fetch the billing transaction history (invoices) for a specific member. Read-only. Backed by the WHMCS billing integration.
Required: exactly one of user_id (standard — the BD member ID) OR client_id (power-user — the WHMCS billing record ID stored on the user as users_data.clientid). Default to user_id; reach for client_id only when you already have one in hand and want to bypass the user lookup.
Empty result with misleading error: if the member has no billing record yet (never enrolled in any paid plan), BD returns HTTP 400 + {status:"error", message:"user_id or client_id is required"} even though the identifier WAS sent. The error wording is BD's, not the wrapper's. Treat that exact error message on this endpoint as "no billing data for this member" rather than "missing parameter".
Use when: you need to see a member's paid/unpaid invoices, payment methods, billing history, or reconcile billing status. Common reasons: answering a member's "what did I pay for?" question, exporting billing history, auditing revenue per member.
See also: getUserSubscriptions (active/past membership plan signups - different resource from invoices), getUser (member profile).
Returns: { status: "success", message: { total: <count>, invoices: [{...invoice records}] } }. Each invoice includes id, invoicenum (may be empty string), date, duedate, datepaid, subtotal, credit, tax, total, status (Paid, Unpaid, etc.), paymentmethod, notes (admin-facing; may contain internal comments - redact before surfacing to end users), and an items array with per-line description, amount, type. NOT a simple list of rows - the message is an object containing invoices as the array. Unpaid invoices have datepaid: "0000-00-00 00:00:00" (MariaDB zero-date sentinel) - do NOT parse as ISO-8601; check status === 'Unpaid' or datepaid.startsWith('0000') first. subscription_details may be false (literal boolean) when absent.
Reference support articles:
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | Member ID (the standard input). Pass this OR `client_id`. | |
| client_id | No | WHMCS billing record ID. Power-user alternative to `user_id`. Pass this OR `user_id`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate read-only and idempotent, and the description reinforces 'Read-only' and adds behavioral details: returns 400 with misleading error when no billing record, return format including MariaDB zero-date sentinel, and notes that subscription_details may be false. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, front-loaded summary, and all information relevant. Slightly verbose (e.g., long error handling explanation) but every sentence adds value; could be tightened without losing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully details return structure, edge cases (unpaid invoices, zero-date, subscription_details false), and error handling. Covers all needed context for successful invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% but description adds mutual exclusivity rule, explains the difference between user_id (standard BD ID) and client_id (WHMCS record), and provides guidance on default behavior. This adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Get member billing transactions (invoices)' and distinguishes from sibling getUserSubscriptions by specifying invoices vs. subscriptions. The verb 'get' and resource 'transactions/invoices' are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (e.g., see invoices, billing history) and provides parameter selection guidance (prefer user_id, use client_id only when you have it). Also warns about a misleading error and how to interpret it. 'See also' references relevant siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getWebPageARead-onlyIdempotent
Get a single page - Fetch a single web page by seo_id. Read-only.
Use when: fetching one page's metadata (+ optionally its body/CSS/JS) before editing. Common for "let me read the current About page before editing it" workflows.
Required: seo_id (path).
Lean-by-default keep-list: same shape as listWebPages — returns only the core identity + linkage fields: seo_id, seo_type, filename, title, h1, h2, nickname, linked_post_category, linked_post_type, date_updated, revision_timestamp. Restore via flags:
include_content=1- returncontent(body HTML).include_code=1- returncontent_css,content_head,content_footer_html.include_extras=1- return everything else (allhero_*fields,meta_desc,meta_keywords,seo_text,facebook_*,content_layout,content_sidebar,menu_layout, allhide_*toggles,master_id,content_active,database,section,custom_html_placement, etc.).
Before updateWebPage edits to body, CSS, head, or footer HTML/JS, pass the matching flag so you have the current value to modify. Hero edits require include_extras=1 to read the existing hero_* values first.
See also: listWebPages (enumerate), updateWebPage (modify). No seo_id yet (user named the page by title/filename/nickname)? Resolve it via listWebPages first — see Rule: List-first.
Returns: { status: "success", message: [{...record}] } - the message array contains 1 lean-shaped record when found.
| Name | Required | Description | Default |
|---|---|---|---|
| seo_id | Yes | Page primary key | |
| include_code | No | Opt in to return `content_css`, `content_head`, `content_footer_html`. Default stripped. Needed before `updateWebPage` edits to CSS/head/JS. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_content | No | Opt in to return the `content` (body HTML) field. Default stripped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, etc. Description adds value by detailing the lean-by-default behavior, explain which include flags restore which fields, and states return format. Does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured with sections (use when, required, lean-by-default, flags, see also, returns). It's slightly lengthy but every sentence adds value. Front-loaded with purpose. Could be more concise but not excessive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the moderate complexity (4 params, no nested objects, no output schema), the description is complete. It covers purpose, usage, parameters, return format, and relationships with siblings. No gaps for expected agent understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. Description greatly enhances understanding by explaining the lean default and the purpose of each include flag, including how to use them before updateWebPage edits. Goes well beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single page' and 'Fetch a single web page by seo_id. Read-only.' It distinguishes from siblings listWebPages (enumerate) and updateWebPage (modify) by specifying the use case of fetching metadata before editing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: fetching one page's metadata... before editing.' Provides guidance on resolving seo_id via listWebPages, and references sibling tools as alternatives. Includes a clear rule for when seo_id is unknown.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getWidgetARead-onlyIdempotent
Get a single widget - Fetch a single widget record by widget_id. Read-only.
Lean-by-default keep-list: returns only widget_id, widget_name, widget_type, widget_viewport, short_code, date_updated, revision_timestamp, is_default. The code fields (widget_data, widget_style, widget_javascript) are stripped — restore with include_code=1.
Use when: you have a widget_id (from listWidgets or admin) and want the widget's SOURCE code to edit or audit. To preview the rendered widget on the front-end, embed it on a page via [widget=Name] shortcode and view the page.
Required: widget_id (path parameter).
See also: listWidgets (enumerate), updateWidget (modify).
Returns: { status: "success", message: [{...record}] } - the message array contains 1 record with all widget fields (widget_data = HTML, widget_style = CSS, widget_javascript = JS, plus metadata).
For the full field list, see listWidgets.
| Name | Required | Description | Default |
|---|---|---|---|
| widget_id | Yes | ||
| include_code | No | Opt in to return `widget_data`, `widget_style`, `widget_javascript` (the HTML/CSS/JS). Default stripped. Needed before `updateWidget` edits to the code. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses lean-by-default behavior (keep-list stripping code fields), explains include_code parameter to restore them, and notes the return format. Annotations already indicate read-only, idempotent, non-destructive; description adds valuable context on default response and when to use include_code.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections (lean-by-default, use when, required, see also, returns). Every sentence informative, no redundancy. Appropriate length for comprehensive tool description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 2 params, one optional enum, no output schema, the description covers purpose, usage, parameters with semantics, return format, and related tools. Complete and self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond schema: clarifies widget_id is required path parameter, explains include_code as opt-in for code fields and its necessity before updateWidget. Schema coverage is 50%, description compensates fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single widget' and 'Fetch a single widget record by widget_id', with specific verb and resource. It distinguishes from siblings like listWidgets (enumerate) and updateWidget (modify).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: you have a widget_id... and want the widget's SOURCE code to edit or audit.' Provides alternative for preview via shortcode. Lists see-also references for enumeration and modification.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listCitiesARead-onlyIdempotent
List cities (location-based search & SEO slugs) - Paginated enumeration of cities enabled on this site for location-based member/post browsing and SEO page URL generation. Read-only source-of-truth for city slugs used in search-result URLs. Backed by BD's location_cities table.
Use when: resolving a human city name (e.g. "Beverly Hills") to its city_filename slug (e.g. beverly-hills) before constructing a search-result URL for a static SEO page, or discovering which cities this site has seeded.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability. Useful filters: city_ln (full name, exact match), city_filename (slug, exact), state_sn (scope to one state), country_sn (scope to one country).
Returns: { status: "success", message: [...rows] } - each row has:
locaiton_id(integer PK, BD schema typo - it islocaiton_id, NOTlocation_id; pass the typo'd form when looking up a single record)city_ln(full name)city_filename(URL slug)state_sn(2-letter state/province code; referenceslocation_states.state_sn)country_sn(2-letter country code; referenceslist_countries.country_code)
System-critical table - create & delete deliberately omitted from this MCP. Cities are managed by BD automatically (a new city row is added when a member signs up from a new location). Creating cities via API risks slug collisions with auto-created rows, and deleting risks orphaning members whose city references the row. Use updateCity only for corrections (rename, fix typo in filename). For new cities, let the next member signup seed it.
Auth: X-Api-Key header. Rate limit: 100 req/60s (on 429, back off 60s). Errors: { "status": "error", "message": "..." } - empty-result responses return {status: "error", message: "location_cities not found", total: 0} (same ambiguous pattern as other list endpoints).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses important behavioral traits beyond annotations: pagination details (cursor-based), return format including a known typo ('locaiton_id'), error handling through empty results pattern, auth requirements, rate limit (100 req/60s), and system-critical nature with warnings against create/delete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is long but well-structured with clear sections (purpose, usage, pagination, filter/sort, return format, system-critical note). Every sentence adds value, though it could be slightly more concise without losing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, description fully documents return structure, fields, and edge cases. Also covers auth, rate limits, and system-critical constraints, making it self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds substantial meaning: explains pagination parameters (page, limit), filter/sort fields (property, property_value, property_operator, order_column, order_type) with specific examples and references to external rules, and clarifies that filter column keys must match response rows.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'List cities (location-based search & SEO slugs)' and explains its use for resolving city names to slugs and discovering seeded cities. It distinguishes itself from siblings like listStates by focusing on cities for SEO slug generation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance on when to use (resolving city name to slug, discovering cities) and when not to (creating cities should be left to member signups, deleting is omitted). References alternative actions like updateCity for corrections.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listClicksARead-onlyIdempotent
List click records - Paginated enumeration of click records. Read-only.
Use when: pulling click-tracking analytics for reports - profile views, phone reveals, website clicks, email clicks. Filter by user_id to see clicks for one member.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getClick (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, openWorldHint, idempotentHint, destructiveHint=false. Description adds pagination behavior, cursor-based mechanics, filter silent-drop detection, derived-field unfilterability, and return structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections for usage, pagination, filter/sort, see also, returns. Front-loaded with purpose, no wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters and no output schema, description covers pagination, filtering, return format thoroughly. References external rules for deeper detail, sufficient for agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 100% coverage. Description adds context: pagination cursor usage, filter parallel arrays, wrong name silently returns empty. Enhances understanding beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it lists click records with paginated enumeration, read-only. Distinguishes from sibling getClick (single record) and other create/update/delete tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: pulling click-tracking analytics for reports; filter by user_id for single member. References pagination/filter rules but lacks explicit when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listCountriesARead-onlyIdempotent
List countries - Paginated enumeration of countries in the global reference table. Read-only reference.
Use when: resolving a country name to its 2-letter country_code (ISO 3166-1 alpha-2) for cross-referencing in location_states.country_sn / location_cities.country_sn, or deriving a country URL slug.
Country URL slug derivation: BD does NOT store a country_filename field. To construct the country segment of a search-result URL, derive it from country_name by lowercasing and replacing spaces with hyphens. Example: country_name="United States" -> country-slug="united-states".
Pagination + filter/sort: standard. Useful filters: country_code, country_name, active.
Returns: rows with country_id, country_code, country_name, active (1=active, 0=inactive).
System-critical table - create & delete deliberately omitted. Countries are a global reference list. Use updateCountry only for corrections (e.g. toggling active).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint; description adds that it's a paginated enumeration of a global reference table, returns specific fields, and omits create/delete. Provides additional context about URL slug derivation and system-critical nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with headers and front-loaded purpose. Slightly verbose due to URL slug derivation details, but still efficient and organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Provides return structure, pagination/filter/sort details, and system-critical context. Lacks output schema but compensates with explicit return fields. Missing auto-complete use case, but overall complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description highlights useful filters (country_code, country_name, active) and explains the context of country_code for URL slugs. This adds value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists countries with pagination, distinguishes from siblings like getCountry and updateCountry, and explicitly says create/delete are omitted. It gives concrete use cases for resolving country codes and URL slugs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (resolving country codes, URL slugs) and when not to (create/delete), and directs to updateCountry for corrections. Also warns that it's a system-critical table.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listDataTypesARead-onlyIdempotent
List data types - List all data types configured on this BD site. Use the data_id values as data_type parameters when creating posts or portfolio groups.
Use when: discovering the valid data_type values on the site. Used as a prerequisite lookup when creating posts or portfolio groups that need a data_type foreign-key value.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getDataType (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds details about pagination (cursor-based), filtering (including silent-drop on wrong property names), sorting, and response format. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (Use when, Pagination, Filter/sort, See also, Returns). It is detailed but not overly verbose, though slightly lengthy. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers usage context, pagination behavior, filtering operators, and response format. It provides necessary context for a tool with 7 optional parameters and complex filtering, and references external rules for further detail. No output schema, but return format is described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining how parameters relate to the tool's purpose (e.g., 'use the data_id values as data_type parameters'), references external rules for pagination and filtering, and clarifies compound filter semantics. However, it does not add new parameter-level meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'List all data types configured on this BD site' and explains that data_id values are used as data_type parameters for creating posts or portfolio groups. It distinguishes itself from the sibling 'getDataType' which retrieves a single record.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when: discovering the valid data_type values on the site. Used as a prerequisite lookup when creating posts or portfolio groups that need a data_type foreign-key value.' It also suggests 'getDataType' as an alternative for single record lookup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listEmailTemplatesARead-onlyIdempotent
List email templates - Paginated enumeration of emailtemplate records. Read-only.
Use when: enumerating the site's transactional/marketing email templates before editing. Common audit: before bulk updating "from" addresses or footers.
Lean-by-default: email_body (the HTML body, the heaviest field per row) is stripped. All identity/metadata fields (email_id, email_name, email_subject, email_type, category_id, notemplate, etc.) are always kept. Set include_body=1 to restore.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getEmailTemplate (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object minus email_body unless include_body=1.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| include_body | No | Opt in to return the full `email_body` HTML. Default stripped — `email_body` is the heaviest field on the row (~8 KB avg, up to tens of KB) and is rarely needed when enumerating templates. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds behavioral details: 'Lean-by-default: email_body stripped', pagination semantics, filter/sort behavior, and the return format. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections (use when, lean-by-default, pagination, filter/sort, see also, returns). Front-loaded with the main action. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 8 parameters, pagination, filtering, and no output schema, the description thoroughly explains the return format, cursor-based pagination, filter operators, and the lean-by-default behavior. It references rule documents for completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the description adds significant meaning beyond field names: explains why `include_body` defaults to 0 (heaviest field), multi-condition filtering with parallel arrays, operator taxonomy (word vs symbol forms), and references to rules for silent-drop detection.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List email templates - Paginated enumeration of emailtemplate records. Read-only.' using a specific verb and resource, distinguishing it from siblings like `getEmailTemplate` (single record) and `createEmailTemplate`.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'enumerating the site's transactional/marketing email templates before editing. Common audit: before bulk updating.' Also references a sibling tool and includes exclusions like 'See also: getEmailTemplate (single record by ID).'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listFormFieldsARead-onlyIdempotent
List form fields - Paginated enumeration of formfield records. Read-only.
Use when: listing fields on a form. Filter by form_name (text slug — form_fields joins to forms by form_name, not form_id).
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getFormField (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
Site records and platform master defaults are merged in the response — see Rule: Default-merge models to filter to one and to sort.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| include_meta | No | Opt in to return the `json_meta` longtext blob (UI rendering metadata + per-field validator config). Default stripped — use when adding or editing per-field validators (regexp, stringLength, etc.). See **Rule: Forms** § Field anatomy → `json_meta`. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_view_flags | No | Opt in to return form-field view-flag columns: `field_input_view`, `field_display_view`, `field_search_view`, `field_email_view`, `field_grid_view`, `field_input_view_admin_only`, plus the 5 alt-label override columns. Default stripped — use when actively editing field visibility. See **Rule: Forms** § Field anatomy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly labels the tool as 'Read-only' and describes pagination ('cursor-based'), return structure, and merging behavior with site records and platform defaults. It references rules for filter operators and pagination semantics. This adds significant behavioral context beyond the annotations (readOnlyHint, openWorldHint, idempotentHint) without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: 'Use when:', 'Pagination:', 'Filter/sort:', 'See also:', 'Returns:'. It is front-loaded with purpose. While slightly lengthy, it is concise given the complexity of the 9 parameters and the need to cover filtering, pagination, and default merging.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description provides a detailed return structure and explains that records include merged defaults. It covers all 9 parameters with additional context and references rules for detailed filter operators and pagination. This gives a comprehensive understanding of the tool's behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds extra meaning for parameters like property (explains multi-condition AND with parallel arrays), include_meta (use case for editing validators), and include_view_flags (visibility flags). It also references external rules for filters and forms, providing more context than schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List form fields - Paginated enumeration of formfield records. Read-only.' The verb 'list' and resource 'form fields' are specific. It distinguishes from siblings like getFormField (single record) by explicitly mentioning it in 'See also: getFormField'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states 'Use when: listing fields on a form.' and provides specific filtering guidance (filter by form_name, joins by text slug not ID). It also mentions 'See also: getFormField' as an alternative for single records, helping the agent decide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listFormInquiriesARead-onlyIdempotent
List Forms Inbox submissions - Paginated Forms Inbox submissions. Read-only.
Use when: reading contact-form and lead submissions.
Per-row fields: inquiry_id, inquiry_email, inquiry_ip, yourname, phone, inquiry_user_id, inquiry_form, form_title, url_origin, date_submitted, fields. inquiry_form is the form system name and the filter key; form_title is its display name (e.g. Trainer Ebook Lead); url_origin is the page URL the form was submitted on — filter it with contains/starts_with/ends_with (e.g. submissions from one page: property=url_origin property_value=about/contact property_operator=contains; omit the leading /, which the WAF strips); inquiry_user_id appears only for member submissions; inquiry_email/yourname/phone appear only when the form captured them, so read fields (the submission parsed to a {label, value} array, custom fields included) as the source of truth. include_raw=1 returns the raw inquiry_content HTML in place of fields.
Search — one form, last 30 days, newest first: property=inquiry_form property_value=contact_form property_operator==, property=date_submitted property_operator=since_days property_value=30, order_column=date_submitted order_type=desc.
Dates on date_submitted: a calendar month = month_eq=<n> + year_eq=<yyyy> (two conditions); a relative window = since_days (older bound) with until_days (newer bound). Filters match the UTC-stored value while the response shows a localized string, so a near-midnight row can bucket into the next day/month; between/gt/lt need a 14-digit value (not ISO); starts_with matches the display string, so it returns wrong rows on dates. See Rule: Filter operators for the full date-operator behavior.
Pretty name to inquiry_form: for a form named by form_title, call getForm with property=form_title property_value=<title> property_operator== and read form_name — that value is the inquiry_form to filter by. On no match (shorthand or typo), listForms and pick the title.
Filter/sort: property+property_value+property_operator; order_column (date_submitted, inquiry_id, inquiry_email, yourname, inquiry_form)+order_type. See Rule: Filter operators.
Pagination: limit (max 100)+page. See Rule: Pagination.
See also: getFormInquiry (one submission by id).
Returns: { status, message: [...rows], total, current_page, total_pages, next_page }.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| include_raw | No | Return the raw `inquiry_content` HTML blob instead of the parsed `fields`. Default off. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint. The description goes far beyond by detailing pagination, filter/sort behavior, date handling, raw vs parsed output, and WAF considerations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with bold headers and bullet points. Given the tool's complexity, the verbosity is partly justified, but could be more concise by trimming some examples and merging repetitive notes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all aspects: input parameters, filtering, sorting, pagination, date quirks, relation to `getForm`, return format, and WAF notes. For a tool with 8 parameters and no output schema, this is exceptionally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description adds significant meaning: explains `page` as cursor from previous response, `include_raw` transforms output, filter patterns, date operators, and compound filters. Provides concrete examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List Forms Inbox submissions' and 'Read-only', establishing a specific verb and resource. It distinguishes from sibling tools like `getFormInquiry` (single submission) and `listForms` (list forms) via the 'See also' section.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'Use when: reading contact-form and lead submissions' and provides a detailed search example. It lacks explicit when-not-to-use but the read-only nature and sibling references imply alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listFormsARead-onlyIdempotent
List forms - Paginated enumeration of form records. Read-only.
Use when: enumerating the site's forms (signup, contact, quote request, custom forms). Child fields are fetched separately via listFormFields.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getForm (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
Site records and platform master defaults are merged in the response — see Rule: Default-merge models to filter to one and to sort.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description details pagination, filter/sort semantics, return structure, and default-merge behavior, adding significant context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-organized with headings and bold terms, front-loaded purpose, each sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, it provides the return shape and default-merge note, making the tool fully understandable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the description still adds meaning by explaining defaults, array usage, operator types, and silent-drop detection, beyond schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists forms with paginated enumeration, specifies it is read-only, and distinguishes from sibling tools like getForm and listFormFields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use (enumerating forms), mentions child fields are fetched separately via listFormFields, and points to getForm for single record retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listLeadMatchesARead-onlyIdempotent
List lead matches - Paginated enumeration of lead_matches records. Read-only.
Use when: auditing who got notified about which lead - useful for billing reports (paid-per-lead sites) or explaining to a member why they did/didn't receive a lead notification. Filter by lead_id to see all matches for one lead, or by user_id to see all leads a member received.
Empty-state quirk: BD returns { status: "error", message: "lead_matches not found", total: 0 } on zero rows (NOT the standard success-shape). The wrapper normalizes this to { status: "success", total: 0, message: [] } before responding — but if a raw BD response leaks through, treat the exact message "lead_matches not found" as an empty result, not as an endpoint failure.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds critical behavioral details beyond annotations: empty-state quirk with non-standard error response and normalization, pagination (cursor-based), filter/sort behavior with silent drops, return shape. Annotations already declare safe read-only operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections for use-case, empty-state, pagination, filter/sort, and returns. Slightly long but every sentence adds value; front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a list tool with 7 parameters and no output schema. Covers pagination, filtering, empty state, return format, and references external rules. No gaps identified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so baseline is 3. Description adds context about silent drops for wrong property names, compound filter arrays, and rule references, improving usability beyond schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it lists lead matches with pagination, and specifies it is read-only. Distinct from sibling tools like getLeadMatch or listLeads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly describes when to use (auditing, billing reports, explaining notifications). Does not directly mention when not to use or compare to sibling list tools, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listLeadsARead-onlyIdempotent
List leads - Paginated enumeration of lead records. Read-only.
Use when: pulling the admin's lead inbox, generating lead reports, or iterating all leads to push into a CRM. For fetching one lead by ID use getLead.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getLead (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=true. The description adds valuable behavioral context beyond annotations: cursor-based pagination (limit, page), filter/sort mechanics, silent-drop detection, derived-field unfilterability, and the exact return structure. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly structured with headings, bullet points, and clear sections. Every sentence adds value, and it is appropriately sized for the tool's complexity. It front-loads the core purpose and uses references to external rules to avoid redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, pagination, filters, and no output schema), the description covers all essential aspects: when to use, pagination behavior, filter/sort details, return format, and key rules. It references relevant rules for full depth, making it complete for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with detailed parameter descriptions. The description does not add significant meaning beyond the schema; it references external rules (Rule: Pagination, Rule: Filter operators) and mentions compound filter behavior, but the schema already explains that. Baseline 3 is appropriate since the schema carries the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List leads - Paginated enumeration of lead records. Read-only.' It specifies the verb (list), resource (leads), and key characteristic (paginated, read-only). It distinguishes from sibling tools like getLead by stating 'For fetching one lead by ID use getLead.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases: 'pulling the admin's lead inbox, generating lead reports, or iterating all leads to push into a CRM.' It also explicitly tells when not to use it and suggests an alternative: 'For fetching one lead by ID use getLead.' This gives clear guidance on when to use vs. alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listMembershipPlansARead-onlyIdempotent
List membership plans - Paginated enumeration of membership-plan records. Read-only.
Use when: discovering subscription_id values to use when creating members. Essential prerequisite for createUser - every member needs a valid subscription_id.
Lean-by-default keep-list: rows return only the core fields: subscription_id, subscription_name, subscription_type, profile_type, monthly_amount, yearly_amount, initial_amount, lead_price, searchable, search_membership_permissions, data_settings. data_settings is the comma-separated list of post-type IDs this plan can publish — kept by default to support author-resolution flows (find plans whose members can publish a given post type). A plan's members have a publicly accessible, searchable profile (BD's UI calls this "Listing Searchable") only when searchable=1 AND search_membership_permissions contains visitor. Everything else stripped — restore via flags:
include_plan_config=1- restores config bundle (active/searchable toggles, limits, forms, sidebars, email templates, upgrade chain, payment defaults, etc.).include_plan_display_flags=1- restoresshow_*profile-visibility toggles.include_extras=1- returns the full BD plan row, untouched (every column).
Pagination: cursor-based (limit, page). See Rule: Pagination.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators.
See also: getMembershipPlan (single by ID).
Returns: { status: "success", total, ..., message: [...records] }.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_plan_config | No | Opt in to restore plan config fields: `sub_active`, `search_priority`, `auto_activate`, `status_after_upgrade`, `upgradable_membership`, `photo_limit`, `style_limit`, `service_limit`, `location_limit`, all form/sidebar/email-template fields, `profile_layout`, `menu_name`, `data_settings_read`, `location_settings`, `payment_default`, `hide_specialties`, `email_member`, `login_redirect`, `page_header`, `page_footer`, `display_ads`, `receive_messages`, `index_rule`, `nofollow_links`. Default stripped. (Note: `data_settings` is now in the lean-by-default keep-list — no opt-in needed.) | |
| include_plan_display_flags | No | Opt in to restore profile-visibility toggles: `show_about`, `show_experience`, `show_education`, `show_background`, `show_affiliations`, `show_publications`, `show_awards`, `show_slogan`, `show_sofware`, `show_phone`, `seal_link`, `website_link`, `social_link`. Default stripped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, etc. Description adds lean-by-default keep-list, flag behavior, pagination details, return format. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Slightly long but well-structured with sections. Front-loaded with purpose. Could be trimmed slightly, but each section adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: purpose, usage, parameters with flags, pagination, filters, return format. References external rules for deeper detail. No output schema, but return shape is described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and description adds context: purpose of include_* flags, lists specific fields restored, explains filter/sort parameters referencing external rules.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb 'list', resource 'membership plans', and scope 'paginated enumeration'. Distinguishes from sibling getMembershipPlan. Read-only is stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: discovering subscription_id for createUser, essential prerequisite. Also mentions pagination and filtering guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listMemberSubCategoryLinksARead-onlyIdempotent
List user-service relationships - Paginated enumeration of MEMBER ↔ SUB CATEGORY links. Read-only.
Each record links a member (user_id) to a Sub Category (service_id) with per-link metadata: avg_price, specialty, num_completed, date. This is level 3 of the member-taxonomy relationship. Backed by BD's rel_services table.
Use when: auditing per-service-link metadata (prices, specialty flags, completion counts) across members. Filter by user_id to see one member's links, service_id to see everyone offering that service. For simpler "is this member tagged with this sub-cat" checks, the users_data.services CSV on the member record is cheaper.
When to use this vs. the simpler users_data.services CSV field: use this resource when you need PER-LINK metadata (pricing tier, specialty flag, completion counter). If you just want "this member is tagged with these Sub Categories" with no extra data, set updateUser.services (CSV of service IDs) instead.
Pagination + filter/sort: standard.
See also: getMemberSubCategoryLink, createMemberSubCategoryLink, listSubCategories (available Sub Categories), updateUser (sets the services CSV for simpler cases).
Returns: { status: "success", ..., message: [...records] }. Each has rel_id, user_id, service_id, date, avg_price, num_completed, specialty.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, openWorldHint, idempotentHint, destructiveHint. The description adds context by stating 'Read-only', explaining pagination and filter/sort behavior as 'standard', and detailing the return format with fields like rel_id, user_id, service_id, etc. It also describes the underlying table (rel_services) and how it fits into the broader classification system, which helps the agent understand implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with clear sections: purpose, use-cases, pagination, return format, business context. Every sentence adds value, though some tangential details about sub-sub-categories and table mapping could be streamlined. It is front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (7 parameters, no output schema), the description provides a complete picture: it explains the return format with all fields, pagination, filtering options, and the business context of how member classification works (profession_id, services CSV, rel_services). It also clarifies relationships with sibling tools and internal table mappings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by giving example use cases for filtering: 'Filter by user_id to see one member's links, service_id to see everyone offering that service.' It also warns about wrong property names silently returning empty, which is beyond the schema. This justifies a score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List user-service relationships - Paginated enumeration of MEMBER ↔ SUB CATEGORY links. Read-only.' It specifies the verb (list), resource (membership links), and scope (paginated, read-only). It distinguishes from sibling tools like getMemberSubCategoryLink (single item) by indicating this is a list endpoint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly provides when-to-use scenarios: 'Use when: auditing per-service-link metadata... For simpler checks, the users_data.services CSV is cheaper.' It also contrasts with updateUser for simpler cases and references sibling tools like getMemberSubCategoryLink, createMemberSubCategoryLink, listSubCategories. This gives clear guidance on alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listMenuItemsARead-onlyIdempotent
List menu items - Paginated enumeration of menuitem records. Read-only.
Lean-by-default keep-list: rows return only menu_item_id, menu_name, menu_link, menu_order, menu_id, master_id. Styling/target/rel/json_meta, plus revision_timestamp / menu_title / menu_display / tablesExists (rarely actionable on read), are stripped — restore via include_extras=1.
Default empty-link filter: rows where menu_link is empty/null (infrastructure nodes — section headers, placeholders) are excluded by default. They can't be link targets. Opt in with include_empty_links=1 only when auditing the full menu structure.
Use when: enumerating items in a menu - always filter by menu_id. Use master_id filter for sub-menu items.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getMenuItem (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is lean-shaped per the keep-list above. total reflects post-filter count when include_empty_links=0. Site records and platform master defaults are merged in the response — see Rule: Default-merge models to filter to one and to sort.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_empty_links | No | Opt in to return MenuItem rows where `menu_link` is empty/null (infrastructure nodes — section headers, placeholders). Default excluded since they can't be link targets. Set to `1` only when auditing menu structure including non-link nodes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the lean-by-default keep-list, default empty-link filter, pagination behavior, filter operator details, and the merging of site records and platform master defaults. This adds significant context beyond the annotations (readOnlyHint, idempotentHint). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is quite long with multiple paragraphs and references to external rules. However, it is well-structured with bold headings, bullet points, and clear sections, making it easy to scan. It could be more concise without losing key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description thoroughly covers the return format, pagination, filtering, default behaviors, and data merging. For a list tool with 9 parameters and complex defaults, this is highly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining the default behaviors of include_empty_links and include_extras, and the filter operator semantics, which go beyond the schema descriptions. However, the schema already provides good descriptions, so the increment is modest.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'List menu items - Paginated enumeration of menuitem records. Read-only.' This clearly states the verb (list) and resource (menu items), and distinguishes it from siblings like getMenuItem by mentioning 'See also: getMenuItem (single record by ID)'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when: enumerating items in a menu - always filter by menu_id. Use master_id filter for sub-menu items.' It also provides guidance on when to opt in to include_empty_links and include_extras, and references rules for filters and pagination.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listMenusARead-onlyIdempotent
List menus - Paginated enumeration of menu records. Read-only.
Lean-by-default keep-list: rows return only menu_id, menu_name, menu_title, revision_timestamp. Styling/target/rel/json_meta fields stripped — restore via include_extras=1 when editing menu appearance.
Use when: enumerating navigation menus on the site (main menu, footer menu, sidebar, etc.). For items within a menu use listMenuItems with menu_id filter.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getMenu (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is lean-shaped per the keep-list above. Site records and platform master defaults are merged in the response — see Rule: Default-merge models to filter to one and to sort.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint and destructiveHint false. The description adds significant context: 'Lean-by-default keep-list,' behavior of include_extras, default-merge models, silent-drop detection, and pagination semantics. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: purpose, keep-list, use-when, pagination, filter/sort, see-also, returns. Each sentence adds value, and the most critical information is front-loaded. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 8 parameters and no output schema, the description provides complete return structure, explains merge behavior, and references rules for pagination and filters. It covers all aspects needed for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value beyond schema by explaining the keep-list, how include_extras works, and filter operator behavior (e.g., silent drop, compound filters). This provides meaningful guidance beyond parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List menus - Paginated enumeration of menu records. Read-only.' It specifies the verb (List), resource (menus), and includes pagination. It distinguishes from siblings like 'listMenuItems' and 'getMenu' by contrasting use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when: enumerating navigation menus on the site' and 'For items within a menu use listMenuItems with menu_id filter.' It provides clear context on when and when not to use this tool, with an alternative tool named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listMultiImagePostPhotosARead-onlyIdempotent
List album photos - Paginated enumeration of portfoliophoto records. Read-only.
Lean-by-default keep-list: rows return photo_id, user_id, group_id, file, original_image_url, title, order, status, image_imported, revision_timestamp. Marketplace fields (price, manufacturer, availability, product_category, product_type, condition, inv_id, link, additional_fields) restore via include_marketplace=1.
Use when: fetching all photos within a multi-image post - always pass group_id to filter. For a single photo by ID use getMultiImagePostPhoto. For image-dedup: property=original_image_url property_operator=in property_value=<URL1,URL2,URL3> returns matched rows with original_image_url in the lean response.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getMultiImagePostPhoto (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is lean-shaped per the keep-list above.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_marketplace | No | Opt in to return the photo's marketplace/shop columns (`price`, `manufacturer`, `availability`, `product_category`, `product_type`, `condition`, `inv_id`, `link`, `additional_fields`). Default stripped — use when the site treats photos as a shop catalog (BD's marketplace feature). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=true, openWorldHint=true, idempotentHint=true, destructiveHint=false. The description adds behavioral details: lean-by-default keep-list, marketplace fields restoration via include_marketplace, cursor-based pagination, filter operators, silent-drop detection, and derived-field unfilterability. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections, bold keywords, and bullet points. It front-loads the main purpose. While somewhat long, every sentence provides useful information for a complex tool. Minor verbosity but overall effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 8 parameters, pagination, filters, and no output schema, the description compensates by detailing the return shape (status, total, current_page, etc.), lean response, filtering options, and references to rules. It is highly complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds value by explaining the keep-list columns, the effect of include_marketplace, pagination details, and filter operators (including compound filters). This goes beyond the schema's property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'List album photos - Paginated enumeration of portfoliophoto records. Read-only.' This clearly specifies the action (list), resource (album photos/portfolio photo records), and pagination. It also distinguishes from sibling tools like getMultiImagePostPhoto and other list tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: fetching all photos within a multi-image post - always pass group_id to filter.' and provides alternatives: 'For a single photo by ID use getMultiImagePostPhoto. For image-dedup: property=original_image_url...' It also includes a 'See also' section.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listMultiImagePostsARead-onlyIdempotent
List album groups - Paginated enumeration of portfoliogroup records. Read-only.
Lean-by-default keep-list: rows return only the core identity + routing fields: group_id, group_name, group_filename, group_status, data_id, data_type, system_name, data_name, data_filename, user_id, revision_timestamp, plus total_clicks (only when > 0), total_photos, cover_photo_url, cover_thumbnail_url rollups. Same keep-list as listSingleImagePosts (single-image fields like post_start_date simply won't appear on multi-image rows). Restore via flags: include_content=1 (full group_desc HTML), include_author_full=1 (full user nested — default omits author detail; call getUser(user_id) otherwise), include_clicks=1 (click array), include_photos=1 (full users_portfolio photo array shaped to PHOTO_LEAN_ALWAYS_KEEP), include_extras=1 (everything else: lat, lon, country_sn, state_sn, post_date, post_live_date, post_updated, post_token, etc.).
Use when: enumerating photo-album / gallery-style posts (Photo Album, Classified, Property, Product - any post type with data_type=4). For single-image post types use listSingleImagePosts.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getMultiImagePost (single record by ID). For keyword-in-body matching, use this tool with property=group_name property_operator=LIKE (or group_desc).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is lean-shaped per the keep-list above.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_clicks | No | Opt in to return `user_clicks_schema.clicks` array. Default: `total_clicks` count surfaced only when > 0; absent means zero clicks. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_photos | No | Opt in to return `photos_schema` array. Default: `total_photos` count only (`image_main_file` URL always returned). | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| include_content | No | Opt in to return the full `post_content` HTML body. Default stripped (`post_title` + `post_caption` always returned). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_author_full | No | Opt in to return the full original `user` nested object (every field BD returns, including `password` hash, session `token`, `cookie`). Default: author detail omitted entirely — call `getUser(user_id)` when needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, openWorldHint, idempotentHint, destructiveHint false. The description adds significant behavioral context: lean-by-default keep-list behavior, pagination semantics, filter/sort details, silent-drop detection, and the effect of include_* flags. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections for use, pagination, filter/sort, and see also. It is front-loaded with purpose and read-only status. Though lengthy, every sentence adds value; minor redundancy (e.g., 'Same keep-list as listSingleImagePosts') is acceptable for cross-reference.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 12 parameters and no output schema, the description thoroughly explains the return shape (status, pagination fields, lean records), pagination behavior, filter operators reference, and hints to rules. It provides nearly everything an agent needs to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, but the description adds extra meaning: it explains the lean keep-list, that include_content returns HTML, include_author_full returns sensitive fields, and how filters interact with the keep-list. This goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List album groups - Paginated enumeration of portfoliogroup records. Read-only.' It distinguishes from sibling listSingleImagePosts by specifying use for multi-image post types. The purpose is specific and well-differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly provides usage context: 'Use when: enumerating photo-album / gallery-style posts... For single-image post types use listSingleImagePosts.' It also references getMultiImagePost for single record retrieval, offering clear guidance on when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listPostTypesARead-onlyIdempotent
List post types - Paginated enumeration of posttype records. Read-only.
Lean-by-default keep-list: rows return only the core identity + routing fields: data_id, data_type, system_name, data_name, data_filename, form_name, feature_categories, type_of_feature, is_event_feature, is_digital_product, revision_timestamp. Everything else stripped — restore via flags:
type_of_feature enum: 1 = events, 2 = real-estate properties, 0 = digital products, null = all other post types. Filter non-event/property/digital-product types by system_name / form_name / data_name — NOT by type_of_feature.
include_code=1- return the 8 PHP/HTML code-template fields (search_results_div,search_results_layout,profile_results_layout,profile_header,profile_footer,category_header,category_footer,comments_code). Use this when editing post-type templates.include_post_comment_settings=1- return thepost_comment_settingsJSON-string field.include_review_notifications=1- return the 5 review-notification email template fields.include_extras=1- return everything else (h1,h2,icon,category_tab,profile_tab,per_page,profile_per_page, sidebar configs,always_on,distance_search,display_order,caption_length,data_active, and all per-page/per-tab display toggles).
Use when: discovering which post types exist on this site AND their data_type families. The data_type value on each row tells you whether a post type belongs to createSingleImagePost (9/20) or createMultiImagePost (4). Use this BEFORE calling either create endpoint to pick the correct tool.
Reserved data_types — default-excluded. 10 (Member Listings — use listUsers / searchUsers; opt-in rows omit data_filename — members live at /<user.filename>, member directory landing is /search_results, never /listing/<id>), 13 (Member Ratings), 21 (Member Categories — use listTopCategories / listSubCategories). To include reserved records, opt in via the property / property_value filter: property=data_type, property_value=10, property_operator== for a single value; property=data_type, property_value=10,4,9, property_operator=in for a comma-list mix of reserved and standard.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getPostType (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is lean-shaped per the keep-list above.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| include_code | No | Opt in to return the PHP/HTML code-template fields on post types: `search_results_div`, `search_results_layout`, `profile_results_layout`, `profile_header`, `profile_footer`, `category_header`, `category_footer`, `comments_code`. Default stripped. Only needed when editing post-type templates. Each field can be 1-30KB. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_review_notifications | No | Opt in to return the 5 review-notification email template fields on post types: `review_admin_notification_email`, `review_member_notification_email`, `review_submitter_notification_email`, `review_approved_submitter_notification_email`, `review_member_pending_notification_email`. | |
| include_post_comment_settings | No | Opt in to return the `post_comment_settings` JSON-string field on post types (comment display / edit / delete settings). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description aligns with annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) and adds details: lean-by-default keep-list, include flags behavior, type_of_feature enum, reserved data_types special behavior. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is lengthy but well-structured with bold section headers, bullet points, and clear front-loading of purpose. Slightly verbose due to extensive details, but every sentence adds value and is organized logically.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema but description thoroughly covers return format, pagination, filtering, lean-by-default, include flags, special data_types, and references to related rules. Complete for a complex list endpoint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage 100%, but description adds significant context beyond schema: explains lean-by-default keep-list, when to use include_code (editing templates), type_of_feature enum meaning, reserved data_types filtering. Each parameter's purpose is enriched.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List post types - Paginated enumeration of posttype records. Read-only.' It uses a specific verb 'list' and resource 'posttypes', and distinguishes from siblings like 'getPostType' (single record) and create/update/delete tools by name and read-only hint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance: 'Use when: discovering which post types exist on this site AND their data_type families... Use this BEFORE calling either create endpoint to pick the correct tool.' Also mentions reserved data_types and alternatives like 'listUsers', providing clear when-to and when-not-to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listRedirectsARead-onlyIdempotent
List redirects (301) - Paginated list of all 301 redirect rules on the site.
Use when: auditing existing 301 rules - useful before bulk URL changes to avoid duplicate rules, or when debugging why a URL unexpectedly redirects.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getRedirect (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds substantial behavioral details: pagination semantics (cursor-based with limit/page), filter operator rules, compound filter structure, and the exact return format. This goes beyond what annotations provide, though a brief note on rate limits or error conditions would improve it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections: purpose, use-when, pagination, filter/sort, see also, and returns. Each sentence adds necessary detail without redundancy. Uses bold headings and bullet-like formatting for readability. Appropriately sized for the complexity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters, no output schema, and many sibling tools, the description is highly complete. It covers usage context, pagination behavior, filter/sort mechanics, return format, and cross-references. For a list tool, it provides all information needed for an AI agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description enhances understanding by explaining pagination cursor usage, filter operator semantics (with examples like 'eq, ne, lt'), compound filter pairing, and silent-drop detection. It references comprehensive rules for pagination and filter operators, adding meaning beyond the schema's property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List redirects (301) - Paginated list of all 301 redirect rules on the site.' It uses a specific verb (list) and resource (redirects), and distinguishes from sibling tools like getRedirect by noting it's for multiple records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides use cases: 'Use when: auditing existing 301 rules - useful before bulk URL changes to avoid duplicate rules, or when debugging why a URL unexpectedly redirects.' Also includes a cross-reference to getRedirect for single record retrieval, offering clear context and alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listReviewsARead-onlyIdempotent
List reviews - Paginated enumeration of review records. Read-only.
Lean by default: review_description is truncated to the first 500 chars + … when longer. Truncated rows are tagged review_description_truncated: true. Pass include_full_text=1 to restore the full body per call (use sparingly at high limit — review text is unbounded and can dominate payload).
Use when: building moderation queues (filter review_status=0 for Pending), exporting all reviews, running review-velocity reports, or paginating through every review on the site. For keyword-in-body matching, use property=review_description property_operator=LIKE property_value=<word>. For a single known review use getReview.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
Enums: property_operator: =, LIKE, >, <, >=, <=.
See also: getReview (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object (with review_description truncated by default; see Rule: Lean read responses).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| include_full_text | No | Opt in to return the full `review_description` body. Default is lean: bodies over 500 chars are truncated and tagged `review_description_truncated: true`. Set `1` when the agent needs full text (single-record inspection, exporting, keyword-in-body analysis). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, destructiveHint=false. Description adds key behaviors: truncation of review_description, pagination cursor semantics, filter/sort rules, and performance considerations for include_full_text.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections and front-loaded purpose. Every sentence adds value without redundancy. Despite length, it remains scannable and informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all key aspects: pagination, filtering/sorting, truncation, return format, usage guidance, and performance considerations. No missing context for effective tool invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds rich semantics: explains lean default truncation, pagination cursor usage, compound filter arrays, operator enumerations, and performance note for include_full_text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with 'List reviews - Paginated enumeration of review records. Read-only.' Clearly states verb (list), resource (reviews), and distinguishes from sibling getReview for single records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly lists use cases: moderation queues, exporting, reports, pagination. Specifies when to use getReview instead, and mentions keyword-in-body filtering approach.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listSidebarsARead-onlyIdempotent
List custom sidebars - Paginated enumeration of CUSTOM sidebars defined on this site. Read-only in this MCP (create/update/delete deliberately omitted - sidebars are layout infrastructure; changes belong in the BD admin UI).
Use when: an agent needs to set form_name on a WebPage (the sidebar assignment) and wants to verify a custom sidebar name exists on this site before using it.
Important - this endpoint returns ONLY custom sidebars. It does NOT return the Master Default Sidebars that are seeded in BD's master database and always valid on every site. Those are hardcoded in BD core and are NOT rows in the sidebars table. See Rule: Sidebars for the canonical Master Default list (use those names verbatim in form_name) and the agent workflow for matching a user-named sidebar against masters first, then customs from this endpoint, then asking the user if neither matches.
Returns: rows with sidebar_id, name (display name - this is the VALUE to pass to form_name), desc, active (1/0), separator, css, script, short_code, type, div_id, div_class, revision_timestamp.
Pagination + filter/sort: standard.
Site records and platform master defaults are merged in the response — see Rule: Default-merge models to filter to one and to sort.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. Description confirms read-only nature and explains that create/update/delete are deliberately omitted. It details the response fields and mentions pagination, filter/sort, and merging behavior. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately lengthy but well-structured with sections and priority ordering. Each sentence adds value. It is appropriately sized for the complexity, though slightly verbose in places.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description lists all returned fields. It explains the data scope (custom vs master), use case, response structure, pagination/filter standard, and merging behavior. References to rules provide additional context. Complete for a list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed parameter descriptions. The description does not add new parameter information beyond what the schema already provides, so baseline 3 is appropriate. It mentions 'standard pagination + filter/sort' but this is generic.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List custom sidebars - Paginated enumeration of CUSTOM sidebars defined on this site.' It specifies that create/update/delete are omitted, distinguishing it from write operations. It contrasts with sibling tools like 'getSidebar' by being a list endpoint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description explicitly says 'Use when: an agent needs to set form_name on a WebPage... and wants to verify a custom sidebar name exists.' It also warns that this endpoint returns only custom sidebars, not master default ones, and directs to Rule: Sidebars for the master list and workflow. This provides clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listSingleImagePostsARead-onlyIdempotent
List posts - Paginated enumeration of post records. Read-only.
Lean-by-default keep-list: rows return only the core identity + routing + load-bearing fields: post_id, post_title, post_filename, post_status, post_start_date, post_expire_date, post_location, post_venue, post_category, data_id, data_type, system_name, data_name, data_filename, user_id, post_image, original_image_url, revision_timestamp, plus total_clicks (only when > 0) / total_photos rollups. Everything else stripped — restore via flags:
include_content=1- returnpost_content(HTML body).include_post_seo=1- returnpost_meta_title,post_meta_description,post_meta_keywords.include_author_full=1- return the fullusernested object. Default omits author detail entirely; callgetUser(user_id)for author records.include_clicks=1- return the full click array underuser_clicks_schema.include_photos=1- return the fullusers_portfoliophoto array (multi-image posts).include_extras=1- return everything else (lat,lon,country_sn,state_sn,post_org_url,post_date,post_live_date,post_updated,post_token,post_clicks,recurring_type,sticky_post,post_featured,post_tags,post_job,post_video,post_price,image_imported, etc.).
Use when: enumerating posts of single-image families - blog articles, events, jobs, coupons, videos, discussions. Filter by user_id for one member's posts, or data_id to scope to one post type. Before using, confirm the target post type has data_type 9 or 20 (single-image); data_type=4 means multi-image and you want listMultiImagePosts instead.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getSingleImagePost (single record by ID). For keyword-in-body matching, use this tool with property=post_title property_operator=LIKE (or post_caption/post_content).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the lean-shaped resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| fields_only | No | Exact-list response trim: CSV of post field names; each returned row carries exactly these fields. Authoritative when present - include_* flags are moot. An unknown name errors (teaching message) so a typo never silently drops a field. Name the identity columns PLUS every column your match criteria judge: title-only checks use post_id,post_title,post_status,post_filename; checks that judge dates, venues, companies, or locations add post_start_date,post_venue,post_location. ~70% smaller responses, immune to output truncation, total/next_page always intact. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_clicks | No | Opt in to return `user_clicks_schema.clicks` array. Default: `total_clicks` count surfaced only when > 0; absent means zero clicks. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_photos | No | Opt in to return `photos_schema` array. Default: `total_photos` count only (`image_main_file` URL always returned). | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| include_content | No | Opt in to return the full `post_content` HTML body. Default stripped (`post_title` + `post_caption` always returned). | |
| include_post_seo | No | Opt in to return `post_meta_title`, `post_meta_description`, `post_meta_keywords`. Default stripped. | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_author_full | No | Opt in to return the full original `user` nested object (every field BD returns, including `password` hash, session `token`, `cookie`). Default: author detail omitted entirely — call `getUser(user_id)` when needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is known. The description adds substantial behavioral detail beyond annotations: lean-by-default keep-list semantics, silent-drop behavior for wrong property names, fields_only typo error behavior, pagination caveats, and filter operator limits. This is rich, non-redundant context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite being long, every section earns its place: use-when guidance, keep-list enumeration, flag explanations, pagination/filter rules, return shape, and sibling alternatives. Bolded labels and bullet-like structure make it scannable. It is detailed but not redundant; front-loads the core purpose and then layers operational specifics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 14 params and no output schema, the description fully compensates: it explains the return JSON shape, pagination semantics, filter/sort rules, field-selection flags, and error behavior. It also covers edge cases like silent empty results and unknown field name errors. This is comprehensive enough for an agent to use the tool correctly without external docs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed per-parameter descriptions, so baseline is 3. The description adds a cohesive explanation of the lean-default design and how include_* flags restore fields, which is beyond the individual schema descriptions. It also groups the filter/sort parameters into a meaningful operational pattern, adding value over the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'List posts - Paginated enumeration of post records. Read-only.' and clearly specifies that it enumerates single-image post families. It explicitly distinguishes itself from listMultiImagePosts by noting data_type=4 requires the sibling tool. This is a specific verb+resource+scope with sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' context (blog articles, events, jobs, coupons, videos, discussions), states when NOT to use (data_type=4 means use listMultiImagePosts instead), and points to getSingleImagePost for single record retrieval. It also gives concrete filter usage examples, covering when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listSmartListsARead-onlyIdempotent
List smart lists - Paginated enumeration of smartlist records. Read-only.
Use when: enumerating saved dynamic filter configurations the admin has created - these back the BD admin's saved-filter UI for members, leads, reviews, etc.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getSmartList (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, etc. Description adds behavioral context beyond annotations: pagination semantics (cursor-based), filter/sort behavior (silent-drop, derived-field unfilterability), and references to external rules. Some redundancy (repeats 'Read-only') but overall valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with headings (Use when, Pagination, Filter/sort, See also, Returns). Front-loaded with purpose. Slightly verbose due to detailed operator lists but each section is purposeful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with 7 params and no output schema, description covers pagination, filter/sort, return format, and cross-references rules. Missing some details like default sort order but sufficient for typical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage 100%, baseline 3. Description adds significant context: pagination params (cursor usage, next_page), filter/sort params (operator list, compound filter arrays, silent error behavior). Goes well beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states it lists smart lists (paginated enumeration of smartlist records) and distinguishes from getSmartList (single record by ID). Clearly identifies verb, resource, and scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly includes 'Use when:' enumerating saved dynamic filter configurations and references getSmartList as an alternative for single records, providing clear guidance on when to use this tool vs siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listStatesARead-onlyIdempotent
List states / provinces / regions - Paginated enumeration of states/provinces/regions enabled on this site. The location_states table is country-agnostic - it holds US states, Canadian provinces, UK regions, and any other first-admin-level division for any country active on this site, distinguished by country_sn. Read-only source-of-truth for state slugs in search-result URLs.
Use when: resolving a state/province name ("California", "Ontario") to its state_filename slug (california, ontario) before constructing a search-result URL.
Pagination + filter/sort: standard. Useful filters: state_ln (full name), state_sn (2-letter code), state_filename (slug), country_sn (scope to one country - e.g. US, CA).
Returns: rows with location_id (PK - NO typo here, unlike cities), state_sn, state_ln, state_filename, country_sn.
System-critical table - create & delete deliberately omitted. States are seeded by BD as needed. Use updateState only for corrections.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, etc. The description adds value by stating it is a 'read-only source-of-truth' for search URLs, that the table is system-critical, and that create/delete are omitted—context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with purpose first, then usage, then filter details, then return columns, then system notes. Efficient with no fluff, though slightly technical in places. Minor room for brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, when to use, parameter filter details, return columns (despite no output schema), and system-critical context. No gaps for a read-only list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description highlights key filters (state_ln, state_sn, state_filename, country_sn) but adds minimal new meaning beyond the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it lists states/provinces/regions as paginated enumeration, and distinguishes from siblings by specifying it is country-agnostic and holds first-admin-level divisions for all active countries, making it unique among list tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: resolving a state/province name to its state_filename slug before constructing a search-result URL.' Also mentions that create/delete are omitted and to use updateState only for corrections, guiding against improper use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listSubCategoriesARead-onlyIdempotent
List services (sub-categories) - Paginated enumeration of SUB-level member categories (services). Read-only.
Lean by default: each row keeps service_id, profession_id (parent Top Category link), master_id (parent Sub Category for sub-sub), name, filename. Strips desc, keywords, image, icon, sort_order, lead_price, revision_timestamp. Pass include_category_schema=1 to restore all category metadata. Hierarchy is always visible so agents can traverse top -> sub -> sub-sub without opt-in.
Sub Categories are level 2 of the 3-tier member classification (e.g., "Sushi" under "Restaurants"). Each has a profession_id pointing at its parent Top Category. master_id points at a parent Sub Category for sub-sub-category nesting (master_id=0 = directly under a Top Category). Backed by BD's list_services table.
Use when: enumerating sub-categories (services) - always filter by profession_id to scope to one Top Category, otherwise you get all sub-cats across all tops (noisy). For sub-sub nesting, master_id filter narrows further.
Permission note - platform gap: this endpoint (/api/v2/list_services/*) is NOT in BD's public Swagger spec, so the admin's API key permissions UI does NOT auto-generate a toggle for it. The admin's "Services" toggle gates the Swagger-documented /api/v2/service/* endpoints (a DIFFERENT legacy table) - enabling that toggle does NOT grant access here. On 403: admin must manually INSERT a row into bd_api_key_permissions for endpoint_path='/api/v2/list_services/get' (and the singular /api/v2/list_services/get/{service_id} for getSubCategory). Do NOT substitute /api/v2/service/* - different table, inconsistent data.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getSubCategory (single by ID), listTopCategories (parents), createSubCategory (add new).
Returns: { status: "success", total, ..., message: [...records] }. Each record has service_id, name, desc, profession_id, master_id, filename, keywords, sort_order, lead_price, image.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_category_schema | No | Opt in to restore full category metadata: `desc` (SEO description), `keywords`, `image`, `icon`, `sort_order`, `lead_price`, `revision_timestamp`. Default lean keeps: category ID + `name` + `filename` + hierarchy links (`profession_id` on top/sub, `master_id` on sub for sub-sub parent). Hierarchy is always visible so agents can traverse top -> sub -> sub-sub without opt-in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description explains default lean behavior, opt-in for full schema, cursor-based pagination, and hierarchy visibility. No contradiction with annotations (readOnlyHint, idempotentHint, destructiveHint: false). It adds significant context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long and includes additional background (member classification, internal tables) that could be separated into rules or notes. While well-structured with bold headers and sections, it exceeds conciseness expectations for a single tool description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description thoroughly explains the response shape ('{ status: "success", total, ..., message: [...records] }') and record fields. It also covers pagination, filtering, sorting, permissions, and relationships with other tools, making the context fully actionable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds valuable context: each parameter's effect (e.g., silent empty returns for wrong filter columns), compound filtering with parallel arrays, and the include_category_schema parameter's impact on response fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: paginated enumeration of sub-categories. It distinguishes from siblings like getSubCategory (single by ID) and listTopCategories (parents). The verb 'list' and resource 'services (sub-categories)' are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided: 'always filter by profession_id to scope to one Top Category' to avoid noise. Also advises against using API key permissions meant for other endpoints. Mentions alternative tools under 'See also'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listTagGroupsARead-onlyIdempotent
List tag groups - Paginated enumeration of taggroup records. Read-only.
Use when: discovering the tag groupings before creating tags - each tag belongs to a group.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getTagGroup (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false. The description adds significant behavioral details: pagination cursor semantics, silent-empty returns on wrong property/order_column names, reference to filter operator rules, and the exact return format. This goes well beyond annotations and preempts common pitfalls.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet comprehensive, structured with clear sections: purpose, use case, pagination, filter/sort, see also, and return format. It is front-loaded with the most critical info and every sentence adds unique value. No superfluous text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the absence of an output schema, the description fully specifies the return format. All parameters are thoroughly documented in the schema, and the description covers behavioral nuances. For a read-only enumeration tool, the description provides everything an agent needs to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining how to use the pagination cursor (use next_page), default/max limits, and referencing external rules for filters and operators. It also clarifies the intended use of 'property' arrays for AND conditions. This extra context earns a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'List tag groups - Paginated enumeration of taggroup records. Read-only.' It identifies the verb (list), resource (tag groups), and scope (paginated enumeration). It also distinguishes from the sibling 'getTagGroup' via the 'See also' note, making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states 'Use when: discovering the tag groupings before creating tags - each tag belongs to a group.' This tells the agent when to invoke the tool. It also references 'getTagGroup' as a single-record alternative, but does not explicitly list when not to use or other exclusions, which is a minor gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listTagRelationshipsARead-onlyIdempotent
List tag relationships - Paginated enumeration of tagrelationship records. Read-only.
Use when: auditing which tags are attached to which records. Filter by tag or by target record.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getTagRelationship (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint, idempotentHint, and destructiveHint. The description adds significant context: pagination semantics (cursor-based, limit/page), filter operator details, silent-drop detection for invalid property names, and compound filter support. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (summary, use-when, pagination, filter/sort, see also, returns). It is front-loaded with the core purpose and each sentence contributes value. No redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (7 parameters, pagination, filtering) and no output schema, the description covers output format and key behaviors. However, it references external rules (Rule: Pagination, Rule: Filter operators) which may not be accessible, slightly reducing completeness for agents without those rules.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (baseline 3). The description enriches parameters by explaining pagination, filter operator behavior (including silent drops and compound filters), and ordering. This adds meaning beyond the schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List tag relationships - Paginated enumeration of tagrelationship records. Read-only.' and explicitly distinguishes from sibling `getTagRelationship` (single record by ID). It also mentions filtering by tag or target record, providing a specific verb and resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a 'Use when:' section specifying 'auditing which tags are attached to which records' and suggests `getTagRelationship` for single-record lookup. It does not explicitly state when not to use, but the use case is well-defined and alternatives are referenced.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listTagsARead-onlyIdempotent
List tags - Paginated enumeration of tag records. Read-only.
Use when: enumerating member tags, fetching tag names for display, or building a tag-management UI. Tags are lightweight labels attached to members, different from categories (which are taxonomy).
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getTag (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description adds significant behavioral context beyond annotations: pagination (cursor-based, return structure), filtering/sorting rules (silent-drop, derived-field unfilterability), and return format. Annotations already indicate read-only, idempotent, open-world, non-destructive, so description complements them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured with clear sections: summary, use-when, pagination, filter/sort, see-also, returns. Each section is concise and front-loaded with essential information. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, pagination, filtering), the description is thorough. It covers usage context, pagination mechanics, filter behavior, sort, return format, and edge cases. No output schema exists, so return description is necessary and provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 7 parameters are described in schema (100% coverage), so baseline is 3. Description adds value by referencing rules for pagination and filtering, explaining return structure, and noting silent-drop behavior for wrong names, thus enhancing parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description starts with 'List tags - Paginated enumeration of tag records. Read-only.' providing a specific verb and resource. It distinguishes from categories and the getTag sibling, making the tool's purpose clear and distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Use when:' section explicitly states use cases: enumerating member tags, fetching tag names for display, or building a tag-management UI. It contrasts with categories and getTag, but does not cover when to use alternative list tools like listTagGroups or listTagRelationships.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listTagTypesARead-onlyIdempotent
List tag types - Paginated enumeration of tagtype records. Read-only.
Use when: enumerating the tag-type classifiers on this site.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getTagType (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true. The description adds critical behavioral details beyond annotations: pagination semantics (cursor-based with limit/page), filter/sort behavior with silent-drop detection for invalid columns, and the exact return structure. It also references rules for operators and derived-field unfilterability, providing comprehensive transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (purpose, use case, pagination, filter/sort, see also, returns). It is concise with no redundancy, and the most important information (purpose) is front-loaded. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 7 parameters with full schema coverage, no output schema, and annotations, the description provides complete context: it explains pagination, filter/sort intricacies, return format, and references rules for operators. The agent can correctly invoke the tool without ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds value by clarifying that pagination is cursor-based, that wrong filter column names silently return empty, and that filter operators have specific semantics with references to rules. These insights go beyond the schema descriptions, enhancing parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List tag types - Paginated enumeration of tagtype records' and mentions it is read-only, which distinguishes it from sibling tools like getTagType (single record) and createTag (write). The verb 'list' and resource 'tag types' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a 'Use when' section explicitly stating when to use the tool ('enumerating the tag-type classifiers') and a 'See also' reference to getTagType for single records. While it does not explicitly say when not to use it, the context is sufficient for an agent to choose appropriately among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listTopCategoriesARead-onlyIdempotent
List categories (professions) - Paginated enumeration of TOP-level member categories. Read-only.
Lean by default: each row keeps profession_id, name, filename. Strips desc, keywords, image, icon, sort_order, lead_price, revision_timestamp. Pass include_category_schema=1 to restore all category metadata.
Top Categories are the highest level of the 3-tier member classification (e.g., "Restaurants", "Dentists"). Each record's profession_id is what populates users_data.profession_id on member records. Backed by BD's list_professions table.
Use when: populating a category dropdown, generating a site map, or discovering the profession_id of an existing category before assigning members to it. Returns ALL top-level categories. For sub-categories under a specific top, use listSubCategories with a profession_id filter.
Permission note - platform gap: this endpoint (/api/v2/list_professions/*) is NOT in BD's public Swagger spec, so the admin's API key permissions UI does NOT auto-generate a toggle for it. New keys default to DENY on this path even if the admin enables the "Categories (Professions)" toggle - that UI toggle gates the Swagger-documented /api/v2/category/* endpoints (a DIFFERENT legacy table). On a 403 here: the fix is to MANUALLY INSERT a row into bd_api_key_permissions for endpoint_path='/api/v2/list_professions/get' (and the singular /api/v2/list_professions/get/{profession_id} for getTopCategory). This is a platform-level gap worth reporting to BD dev team. Do NOT substitute /api/v2/category/* as a fallback - it reads a different, possibly-empty table and returns inconsistent data.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getTopCategory (single by ID), listSubCategories (sub-categories filtered by profession_id), createTopCategory (add new).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record has profession_id, name, desc, filename, keywords, icon, sort_order, lead_price, image, revision_timestamp.
Member Category Hierarchy (3 levels):
BD classifies members through a 3-level taxonomy - AI agents MUST understand all three to correctly create, assign, and query member categories:
Level | Tool nicknames | Endpoint | BD internal table | Key field | Parent reference |
1. Top Category |
|
|
|
| - |
2. Sub Category |
|
|
|
|
|
3. Member ↔ Sub Category link |
|
|
|
|
|
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_category_schema | No | Opt in to restore full category metadata: `desc` (SEO description), `keywords`, `image`, `icon`, `sort_order`, `lead_price`, `revision_timestamp`. Default lean keeps: category ID + `name` + `filename` + hierarchy links (`profession_id` on top/sub, `master_id` on sub for sub-sub parent). Hierarchy is always visible so agents can traverse top -> sub -> sub-sub without opt-in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true. The description adds valuable behavioral context beyond annotations: it explains the 'lean by default' behavior and how to restore full metadata with include_category_schema, details pagination (cursor-based with limit and page), and importantly describes a permission nuance (endpoint not in public Swagger, workaround for 403 errors). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is thorough but overly long. It includes a large table about the member category hierarchy and extensive permission notes, which while informative, could be condensed. The key purpose is front-loaded, but the additional detail makes it less concise. It is structured with sections, which helps, but overall it could be more succinct.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (8 parameters, no output schema), the description is very complete. It explains the return format (status, total, pagination fields, records with all fields), the hierarchy, related tools, filtering and sorting rules, and edge cases like the permission workaround. It covers all necessary context for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning beyond the schema descriptions. For example, it explains the effect of include_category_schema (lean vs full), references external rules for filter operators and pagination, and describes the default values and behavior. It provides context that helps the agent understand parameter interactions and nuances.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'List categories (professions) - Paginated enumeration of TOP-level member categories. Read-only.' It specifies the resource (top-level member categories) and the verb (list). It distinguishes from siblings by mentioning that for sub-categories, one should use listSubCategories, and lists related tools like getTopCategory and createTopCategory.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Use when: populating a category dropdown, generating a site map, or discovering the profession_id of an existing category before assigning members to it.' It also provides alternatives: 'For sub-categories under a specific top, use listSubCategories with a profession_id filter.' This clearly guides the agent on context and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listUnsubscribesARead-onlyIdempotent
List unsubscribe records - Paginated enumeration of unsubscribe records. Read-only.
Use when: auditing the email unsubscribe list - useful for compliance (GDPR, CAN-SPAM) or before launching a new email campaign.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getUnsubscribe (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses pagination behavior (cursor-based, limit/page), filter/sort nuances (silent-drop detection, operator semantics, derived-field unfilterability), and the return object structure. These go well beyond the annotations, which already indicate read-only, idempotent, and non-destructive behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections: purpose, use when, pagination, filter/sort, see also, and returns. It is concise and front-loaded with the most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with 7 optional parameters, the description covers pagination, filtering, sorting, and return structure. It mentions silent-drop and derived-field quirks. It could detail the record fields but states each record is the full resource object, which is acceptable given no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with detailed descriptions. The description adds value by explaining pagination cursor semantics, filter operator word forms, and silent-drop behavior. It references external rules but provides enough standalone context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool lists unsubscribe records, is paginated, and is read-only. It distinguishes itself from the single-record retrieval tool 'getUnsubscribe' via the 'See also' section. The purpose is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit 'Use when' guidance for auditing, compliance, and campaign planning. It also points to the single-record alternative 'getUnsubscribe'. However, it does not explicitly exclude other list tools for different resources, but that is implicitly clear from the resource name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listUserMetaARead-onlyIdempotent
List user metadata records - Paginated enumeration of users_meta records (EAV key/value table). Read-only.
Use when: enumerating metadata rows (key/value pairs) attached to a parent record in any BD table.
IDENTITY RULE - (database, database_id) is ONE atomic compound identity, not two independent fields. The same numeric database_id routinely points at UNRELATED rows on different parent tables - any integer ID can exist as a PK on multiple parent tables simultaneously. A database_id=<n>-only query will return a MIX of rows from every parent table where that integer happens to be a PK (even low IDs like 1 return hundreds of rows spanning 2+ parent tables). Always pair database=<parent_table> WITH database_id=<id> whenever reading, writing, updating, or deleting users_meta. Pass database, database_id, and key as first-class query params; the MCP wrapper translates them into BD's multi-condition filter syntax so server-side scoping IS accurate — no client-side post-filter needed. The safety guard requires at least 2 of (database, database_id, key) on every read; single-filter queries are rejected. Do NOT mix first-class filters with the generic property/property_value style in the same call — pick one style. Never act on a partial-identity result - misidentifying a row can silently corrupt or destroy unrelated resource metadata on another table.
Commonly-seen database values (BD may accept other table names with users_meta rows - prefer these for known resources; if the user names an unfamiliar table, GET first to verify it actually has meta rows before writing): users_data, deleted_users_data, data_posts, list_seo, subscription_types, list_professions, list_services, rel_services, tags, tag_groups, rel_tags, leads, lead_matches, forms, form_fields, users_reviews, menus, menu_items, data_widgets, email_templates, 301_redirects, data_categories, smart_lists, users_clicks, unsubscribe_list.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter: prefer the first-class database / database_id / key params (see Rule: users_meta identity). The generic property / property_value / property_operator + order_column / order_type flow also works as a fallback and counts toward the 2-of-3 guard when property is one of the three target keys — but do not mix the two styles in the same call.
See also: getUserMeta (single record by ID), updateUserMeta, deleteUserMeta.
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record includes meta_id, database, database_id, key, value, date_added, revision_timestamp.
Note on duplicates: BD does NOT enforce a uniqueness constraint on (database, database_id, key) - the same field can have multiple rows (observed live). Read-layer merge uses last-write-wins, but stored data can bloat. When updating, consider patching ALL matching rows, or deleting duplicates first.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | EAV key/field-name filter (e.g. `hero_content_overlay_opacity`, `search_membership_permissions`). Pair with `database` (scope to one parent table) or with `database_id` (one specific row). The safety guard rejects this alone. | |
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| value | No | Exact-match filter on the stored `value` column. Optional fourth first-class param (listUserMeta only) — narrows a (database, key) scope to rows whose value equals this exactly. NOT counted toward the 2-of-3 safety guard; `value` alone is rejected. Use case: dedup lookups where (database=`list_seo`, key=`hero_image`, value=`<exact URL>`) returns 0-or-1 row in one call instead of paginating + client-filtering. Wrapper appends this as a 4th condition to BD's `property[]`/`property_value[]`/`property_operator[]==` multi-condition syntax. | |
| database | No | Parent table filter (e.g. `list_seo`, `users_data`, `data_posts`). First-class shortcut - the MCP wrapper translates it into BD's multi-condition filter syntax. Pair with `database_id` to target all EAV rows for one parent record, or with `key` to find one field across parents. The safety guard requires 2 of `(database, database_id, key)` on every query. | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| database_id | No | Parent record primary key filter. Pair with `database` (required - same `database_id` can exist on multiple parent tables) to target one parent's EAV rows, or with `key` to find one specific field. The safety guard rejects queries that send this alone. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Read-only behavior aligns with annotations. Adds pagination details, filter guard, duplicate handling, and return format. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and bold rules, but somewhat lengthy. However, complexity justifies the length, and content is well-organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: pagination, filters, identity, duplicates, common database values, and return format. No gaps given the tool's complexity and lack of output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds significant meaning beyond the 100% schema coverage: explains compound identity, safety guards, wrapper translation, special value parameter, and filter style restrictions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'List user metadata records - Paginated enumeration of users_meta records (EAV key/value table). Read-only.' Differentiates from siblings like getUserMeta and deleteUserMeta via explicit 'See also' section.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides extensive when-to-use guidance: identity rules, pagination, filter styles, and explicit alternatives. Includes safety guard requirements and warns against mixing filter styles.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listUserPhotosARead-onlyIdempotent
List user photos - Paginated enumeration of userphoto records. Read-only.
Use when: enumerating photos attached to members (profile, logo, cover). Filter by user_id.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
See also: getUserPhoto (single record by ID).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is the full resource object.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds cursor-based pagination semantics, filter operator behaviors (silent-drop detection, derived-field unfilterability), and return format. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections, front-loaded with purpose, and each sentence adds context. It is slightly long but justified by the complexity of pagination and filtering.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters, no output schema, but rich annotations, the description covers pagination rules, filter operators, return format, and silent-drop behavior. It is complete for effective tool invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% but the description adds meaning beyond raw schema: it explains cursor pagination (use next_page), filter operator word-forms and silent-drop, compound filter pairing, and sorts. This adds significant value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists user photos with pagination, is read-only, and distinguishes from getUserPhoto (single record). It specifies filtering by user_id and enumerates photo types (profile, logo, cover).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use when: enumerating photos attached to members' and provides filter/sort guidance, pagination rules, and a see-also to an alternative tool. This gives clear when-to-use and when-not-to-use context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listUsersARead-onlyIdempotent
List members/users - Get a paginated list of all members. Supports filtering by any user field and sorting.
Lean-by-default keep-list: rows return only identity + routing + location core: user_id, first_name, last_name, email, company, phone_number, subscription_id, profession_id, active, status, city, state_code, country_code, filename, image_main_file, signup_date, last_login, modtime. Everything else stripped — restore via flags: include_password=1, include_subscription=1 (full subscription_schema), include_clicks=1 (full click array), include_photos=1 (full photos_schema), include_transactions=1, include_profession=1 (profession_schema), include_tags=1, include_services=1 (services_schema), include_seo_hidden=1, include_about=1 (about_me HTML bio), include_legacy_fields=1 (image-import state on photos, requires include_photos), include_extras=1 (everything else — billing/analytics rollups like revenue/card_info/total_clicks/total_photos, duplicate location fields state_ln/country_ln/full_name/user_location/zip_code/lat/lon, plus social URLs, awards, credentials, position, quote, work_experience, rep_matters, cv, gmap, no_geo, user_consent, sign_up_origin, listing_type, profession_name, ref_code, booking_link, bitly, cookie, token, verified, featured, parent_id, clientid, etc.).
Use when: enumerating members for reports, CSV exports, bulk status updates, analytics, or pagination through the full member base. Also used for lookups by field - pass property=email + property_value=<email> to find a single user by email. For keyword/text search use searchUsers; for a single user by known user_id use getUser. Do NOT bulk-list users to enumerate cities the site has on file — use listCities (lean, BD-curated, surfaces only cities where members exist).
Pagination: cursor-based. Pass limit (default 25, max 100) and page token from the previous response's next_page. Do not assume integer offsets.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability.
Enums: property_operator: word-forms (eq, ne, lt, lte, gt, gte, like, in, contains, date/length/null ops) — see Rule: Filter operators; order_type: ASC, DESC.
Filter-property rule - use ACTUAL field names: property must reference a real column on users_data or a valid custom user field. If you don't know what's filterable, call getUserFields first - it returns the authoritative list for this site (includes custom fields). BD returns misleading errors like "user not found" when property names a nonexistent field - that is a BAD FILTER, not a 404 on the endpoint. Do not invent properties like user_group (not a real column).
Filtering by TOP CATEGORY (profession): the filter column is profession_id (integer), not a category name string. If the caller gives you a category name, chain: (1) listTopCategories -> find the row whose name matches; (2) grab its profession_id; (3) call listUsers with property=profession_id&property_value=<id>. Same principle for any taxonomy filter - resolve names to IDs first via listSubCategories, listMembershipPlans, etc. For sub-category filtering on users, the authoritative approach is listMemberSubCategoryLinks filtered by service_id -> collect user_ids -> fetch those users. (There is also a service CSV column on user records but exact-match filtering on it requires the complete CSV value and LIKE syntax support is not guaranteed - prefer the link-table route.)
Filtering by users_meta (custom/meta fields): for one custom field matching any of N values, use property=<meta_key> property_value=v1,v2,v3 property_operator=in (CSV, one field). For a custom field AND another condition, use equal-length parallel arrays — see Rule: Compound filters. BD ANDs array conditions; there is no OR operator.
Payment-method field (under include_extras=1): card_info is false when no card is on file (BD's convention), or an object with last4/brand/name when a card IS stored. Check card_info && card_info.last4 (truthy-guard). Authoritative signal for "does this member have a valid payment method on file" — do not infer from subscription_id alone.
See also: getUser (single record by ID), searchUsers (keyword search), getUserFields (list filterable fields).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record is lean-shaped per the keep-list above.
Profile URL: every user record has a filename field. To get the full public profile URL, concatenate: <site-domain>/<user.filename>. The filename is the complete relative path (e.g., united-states/monterey-park/doctor/harrison-hasanuddin-d-o) - DO NOT prepend /business/, /profile/, /member/, or any other segment. BD's router resolves filename verbatim.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| include_tags | No | Opt in to return `tags` array. Default stripped. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_about | No | Opt in to return the `about_me` HTML bio. Default stripped. | |
| include_clicks | No | Opt in to return `user_clicks_schema.clicks` array. Default: `total_clicks` count surfaced only when > 0; absent means zero clicks. | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| include_photos | No | Opt in to return `photos_schema` array. Default: `total_photos` count only (`image_main_file` URL always returned). | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| include_password | No | Opt in to return bcrypt `password` hash. Default stripped. | |
| include_services | No | Opt in to return `services_schema` sub-category array. Default stripped. | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. | |
| include_profession | No | Opt in to return `profession_schema` (category metadata). Default: `profession_id` only. | |
| include_seo_hidden | No | Opt in to return SEO meta fields (`seo_page_*_hidden`, `seo_social_*_hidden`, `search_description`). Default stripped. | |
| include_subscription | No | Opt in to return full `subscription_schema` (60+ plan fields). Default: `subscription_id` only. | |
| include_transactions | No | Opt in to return full `transactions` invoice array. Default stripped (`revenue` rollup always returned). | |
| include_legacy_fields | No | Return image-import state on `photos_schema` rows: `original`, `resized`, `error`. Requires `include_photos=1`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (read-only, idempotent), description reveals lean-by-default behavior, pagination cursor-based, filter error handling (silent drops, BD misleading errors), and specifics like card_info field behavior. Adds substantial context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
While long, the description is well-structured with sections and bullet points, front-loading purpose and then providing necessary details. Every sentence adds value; no redundancy given complexity. Could be slightly more terse but effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (19 parameters, extensive filtering), the description is complete: covers pagination, filtering, sorting, field selection, error handling, related tools, and even profile URL construction. No gaps identified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, baseline is 3. The description adds significant value by detailing which include flags restore which fields, explaining filter operator usage, compound filter arrays, and profile URL construction, far exceeding schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists members/users with pagination, filtering, and sorting. It distinguishes itself from sibling tools like searchUsers and getUser by specifying their appropriate use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides when to use (reports, exports, bulk updates) and when not to (enumerating cities). Mentions alternatives searchUsers, getUser, and listCities. Also guides on resolving filter values via other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listWebPagesARead-onlyIdempotent
List pages (list_seo) - Paginated enumeration of web pages (list_seo records). Read-only.
Returns every static/SEO page on the site - homepage, about, contact, custom landing pages, templates, etc. Filter by seo_type to get pages of a specific type (e.g., only content pages).
Use when: listing all site pages. Filter by seo_type to scope. For one page by seo_id use getWebPage.
Pagination: cursor-based (limit, page). See Rule: Pagination.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators.
Lean-by-default keep-list: rows return only the core identity + linkage fields: seo_id, seo_type, filename, title, h1, h2, nickname, linked_post_category, linked_post_type, date_updated, revision_timestamp. Everything else is stripped — restore via flags:
include_content=1- returncontent(body HTML).include_code=1- returncontent_css,content_head,content_footer_html.include_extras=1- return everything else (allhero_*fields,meta_desc,meta_keywords,seo_text,facebook_*,content_layout,content_sidebar,menu_layout, allhide_*toggles,master_id,content_active,database,section,custom_html_placement, etc.).
On sites with heavy pages, a single row can be 10-30KB with code assets; opt in only when you actually need the data (e.g. before updateWebPage edits to body/CSS/JS, or when reading hero config to display it).
See also: getWebPage (single by ID), createWebPage, updateWebPage.
Returns: { status: "success", total, ..., message: [...records] }.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| include_code | No | Opt in to return `content_css`, `content_head`, `content_footer_html` on each row. Default stripped. Needed before `updateWebPage` edits to CSS/head/JS. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| include_extras | No | Opt in to return ALL remaining fields on this resource that are not in the lean-by-default keep-list and not gated by another `include_*` flag. Lean default returns only the core identity, routing, and load-bearing fields. `include_extras=1` restores everything else (geo, all hero_*, layout/sidebar/menu config, all display toggles, admin metadata, etc.). Resource-specific — see each tool's description for what the extras bundle contains. | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| include_content | No | Opt in to return the `content` (body HTML) field on each row. Default stripped. | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, destructiveHint. Description adds rich behavioral context: lean-by-default keep-list, performance considerations (10-30KB per row), opt-in flags, pagination behavior, and filter/sort references. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections and bullet points. Front-loaded with purpose. Some redundancy (e.g., 'Read-only' appears twice), but overall efficient for the complexity. Slightly verbose but justified by the tool's richness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description explicitly states the return format: '{ status: 'success', total, ..., message: [...records] }'. Details the keep-list fields and extras. Covers pagination, filtering, sorting, and usage guidance comprehensively. Very complete for a complex listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes all 10 parameters (100% coverage). Description adds significant meaning by explaining the 'lean-by-default' pattern, what each include_* flag restores, and the pagination cursor mechanism. This exceeds baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with 'List pages (list_seo) - Paginated enumeration of web pages (list_seo records). Read-only.' and then lists the types of pages included. It clearly distinguishes from sibling tools like getWebPage (single by ID) and mentions create/update versions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use when: listing all site pages. Filter by seo_type to scope. For one page by seo_id use getWebPage.' Also advises when to opt into include_* flags (e.g., before updateWebPage edits).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listWidgetsARead-onlyIdempotent
List widgets - Paginated enumeration of widget records. Read-only.
Lean-by-default keep-list: rows return only widget_id, widget_name, widget_type, widget_viewport, short_code, date_updated, revision_timestamp, is_default. The code fields (widget_data, widget_style, widget_javascript) are stripped — restore with include_code=1.
Use when: discovering the reusable HTML/CSS/JS components available for embedding in pages (via [widget=Name] shortcode) or email templates. For fetching one specific widget by ID use getWidget.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Filter/sort: property+property_value+property_operator, order_column+order_type. See Rule: Filter operators for the verified-working operator set, silent-drop detection, and derived-field unfilterability. Useful filter: widget_viewport=front to list only public-facing widgets.
See also: getWidget (single by ID), createWidget (add new), updateWidget (modify).
Returns: { status: "success", total, current_page, total_pages, next_page, prev_page, message: [...records] }. Each record carries the full widget object (fields enumerated in the table that follows).
Widget object fields (from BD support article 12000108056):
Field | Type | Description |
| integer | Primary key (read-only) |
| string | Widget name/label - REQUIRED on create; unique per site |
| string | Widget classification (default: |
| text | Widget HTML content |
| text | Widget CSS styles |
| text | Widget JavaScript code |
| text | Configuration (JSON or serialized) |
| text | Widget variable values |
| string | CSS class names applied to container |
| string | Where widget appears: |
| string | Container element (default: |
| string | HTML ID attribute for container |
| string | Shortcode reference for this widget |
| integer |
|
| integer |
|
| integer |
|
| string | File type of the widget |
| timestamp | Last modified (auto-updated) |
| boolean |
|
Site records and platform master defaults are merged in the response — see Rule: Default-merge models to filter to one and to sort.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Pagination cursor (use next_page from previous response) | |
| limit | No | Records per page (default 25, max 100) | |
| property | No | Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters. | |
| order_type | No | Sort direction: ASC or DESC | |
| include_code | No | Opt in to return `widget_data`, `widget_style`, `widget_javascript` (the HTML/CSS/JS) on each row. Default stripped. Needed before `updateWidget` edits to the code. | |
| order_column | No | Column to sort by — a column key present on the response rows (a wrong name silently returns empty) | |
| property_value | No | Value to filter by; array to pair with a `property` array (same length). | |
| property_operator | No | Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains read-only nature (redundant with annotations but adds context), the lean-by-default keep-list, pagination cursor/cap/stop, silent-drop detection, derived-field unfilterability, and default-merge model. It significantly supplements the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with sections, bullet points, and a table. It front-loads the core purpose and then provides necessary details. Minor redundancy but overall efficient for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: pagination, filtering, default-value merging, the return format, and a full table of widget object fields. No output schema exists, so the description compensates thoroughly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaningful context: 'include_code=1 to restore widget_data/style/javascript', 'Useful filter: widget_viewport=front', and detailed filter operator descriptions. It provides value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'List widgets - Paginated enumeration of widget records.' It specifies that it's for discovering reusable components and distinguishes from related tools like getWidget, createWidget, and updateWidget.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use when: discovering the reusable HTML/CSS/JS components available for embedding...' and provides alternatives: 'For fetching one specific widget by ID use getWidget.' Also includes filter/sort tips and references to rules.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
loginUserARead-onlyIdempotent
Validate user credentials - Checks if email/password are valid. Does NOT return profile data - use getUser after.
Use when: implementing SSO or a custom login flow against BD - you need to verify a member's email+password is valid WITHOUT starting a web session. Does NOT return profile data; follow with getUser or listUsers to fetch the authenticated member's record.
Required: email, password.
Parameter interactions:
Does NOT return profile data on success - follow with
getUserusing the verified email to retrieve the member record
Returns: { status: "success"|"error", message: ... } - BD's standard response envelope.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | |||
| password | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds value beyond annotations by specifying that no session is started, no profile data is returned, and the response envelope is standard BD format. Annotations indicate readOnlyHint, destructiveHint, idempotentHint, which are consistent, and the description fills in behavioral details not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bold headings and clear sections, but it repeats the point about no profile data three times. It is relatively concise considering the context, but could be slightly more efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 2-parameter login tool with no output schema, the description covers the return format, use case, and next steps. It lacks error handling details but is sufficient for an agent to use correctly. The workflow guidance compensates for missing schema descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the burden. It lists required parameters (email, password) and notes they are required, but does not elaborate on their meaning or constraints beyond what the schema format provides. The parameter interaction note about no profile data is helpful but not per-parameter. Adequate but lacks depth.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool validates user credentials (email/password) and explicitly distinguishes it from related tools by noting it does not return profile data, directing the agent to use getUser instead. The verb 'validate' and resource 'credentials' are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: 'when implementing SSO or a custom login flow' and clarifies it does not start a web session. It also gives clear after-use guidance to follow with getUser or listUsers, differentiating from sibling tools like verifyToken or createUser.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
matchLeadA
Auto-match lead to members - Triggers automatic matching - system finds members matching category, location, and service area, then sends notification emails.
Use when: you've just created a lead (or need to re-distribute an existing one) and want BD to automatically email eligible members in matching category + location + service area. SIDE EFFECT: sends real emails to real members. Confirm with the user before calling on production data.
Required: lead_id.
Parameter interactions:
Side effect: sends notification emails to ALL members whose category, location, and service area match the lead
Not a dry-run - emails go out immediately. Not rate-limited per lead
lead_idmust reference an existing lead created viacreateLead
Returns: { status: "success"|"error", message: ... } - BD's standard response envelope.
| Name | Required | Description | Default |
|---|---|---|---|
| lead_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (which indicate not read-only and not destructive), the description discloses: 'SIDE EFFECT: sends real emails to real members', 'Not a dry-run - emails go out immediately', and returns a standard response envelope. This adds critical behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with headings and bullet points, front-loading the main action. It is slightly lengthy but each sentence adds value, especially the warnings. Minor redundancy could be trimmed but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter, the description covers the matching logic, side effects, return format, and prerequisite lead relationship. No output schema exists, but the return envelope is described. Complete given the complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, lead_id, is described as required and must reference an existing lead created via createLead. This adds meaning beyond the schema, which only specifies type integer. The description provides necessary constraints for correct usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Auto-match lead to members' and explains it triggers automatic matching and sends notification emails. It distinguishes from sibling tools like createLead and createLeadMatch by specifying the automatic matching and emailing behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: after creating a lead or needing to redistribute an existing one. Also warns to confirm with user before calling on production data, and notes it's not a dry-run. This provides clear guidance on appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
refreshSiteCacheA
Refresh the site cache (template/theme/widget/menu/page invalidation) - Clears BD's internal template/theme/widget caches. Useful when recent admin edits to design settings or widgets aren't showing on the public site yet.
Use when: the user has just updated a template, theme setting, widget, menu, or page layout and the public site is still serving the old version. Also a safe troubleshooting step if they report a recent admin-edit not appearing after ~1 minute.
Optional parameters:
scope- target one cache area only (data_widgets,settings,web_pages,css,menus,sidebars). Faster than a full refresh. Omit to refresh all 6.full=1- include heavier db_optimization + file_permissions passes in addition to the 6 core areas. Slower; use only when the user reports persistent issues and lighter refreshes didn't help.
Not needed after createWebPage / updateWebPage / createWidget / updateWidget — those tools auto-refresh and return auto_cache_refreshed: true in the response. Only call manually if a write returned auto_cache_refreshed: false (check auto_cache_refresh_error for the cause).
Do NOT use for:
Routine workflow noise - do not call after every bulk op on non-page resources. Most BD writes unrelated to pages are live immediately; cache invalidation is a targeted fallback, not a default post-step.
Returns: { status: "success", message: "Cache refreshed successfully", areas_refreshed: [...], scope: "full", full: false }. The areas_refreshed array lists exactly what was cleared - useful for logging or reporting back to the user. Example default response:
{
"status": "success",
"message": "Cache refreshed successfully",
"areas_refreshed": ["data_widgets", "settings", "web_pages", "css", "menus", "sidebars"],
"scope": "full",
"full": false
}With full=1 the areas_refreshed additionally includes db_optimization and file_permissions. Invalid scope values return an error listing the valid set: { status: "error", message: "Invalid scope value: <x>. Valid values: ..." }.
Undocumented by BD publicly; exposed via admin API-permissions UI.
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | Pass 1 to also run db_optimization + file_permissions refresh (heavier, slower). Pass 0 or omit for standard refresh of the 6 core areas only. | |
| scope | No | Target a specific cache area instead of refreshing all 6. Omit to refresh all. Valid values: data_widgets, settings, web_pages, css, menus, sidebars. Invalid scope returns an error listing the valid set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds context beyond annotations: describes it as a safe troubleshooting step, explains the side effects (clearing caches), return format, error behavior for invalid scope, and the fact it is undocumented publicly. No contradiction with annotations; readOnlyHint=false aligns with write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections: purpose, usage, parameter details, exceptions, and return value. Every sentence provides critical information, no redundancy. Front-loaded with verb+resource. Appropriate length for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all necessary aspects: what it does, when to use, parameters with examples, return format, error cases, and relationship to sibling tools. No output schema, but description details the return object sufficiently. Edge cases (invalid scope) are addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions, but description adds richer context: scope parameter targets a specific area for speed, full parameter adds heavier operations and when to use. Includes example responses with explanations of areas_refreshed list. Adds significant value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool refreshes BD's internal caches for templates, themes, widgets, menus, and pages. The verb 'refresh' and resource 'site cache' are specific, and it distinguishes from sibling CRUD operations (create/update/delete) which do not have cache refresh as primary function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (after admin edits not appearing), when not needed (auto-refresh after certain create/update tools), and what to avoid (routine noise). Also provides guidance on optional parameters (scope and full) with appropriate use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
renderWidgetARead-onlyIdempotent
Render a widget to HTML - Diagnostic tool only. Returns BD's rendered HTML output for a widget — useful for confirming render-pipeline symptoms during troubleshoot (backslash strip on widget_data, <style> auto-wrap on widget_style, <script> wrapper presence on widget_javascript). Production widget rendering on a customer's site is always via [widget=Name] shortcode in page or email content — never call this tool to deliver widget HTML to end users.
Use when: the user reports a widget is broken and you need to see what BD's render pipeline actually emits. See Rule: Widget code fields scenario 3 (TROUBLESHOOT).
Required: either widget_id OR widget_name.
Returns (distinct from standard envelope): { status, message, name, output }. The output field contains rendered widget_data HTML with template tokens expanded, plus BD's auto-wrapped <style type='text/css'>-block from widget_style, plus the verbatim widget_javascript content. CSS and JS are NOT in output if their fields are empty.
See also: getWidget (raw source for inspecting field placement), updateWidget (apply fixes after diagnosis).
| Name | Required | Description | Default |
|---|---|---|---|
| widget_id | No | ||
| widget_name | No | Alternative to `widget_id` - pass either one. Widget name lookup is case-sensitive and must match exactly. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds valuable behavioral details: it returns a distinct output structure, explains what the output includes (rendered HTML with auto-wrapped style/script), and notes that CSS/JS are omitted if empty. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bold headings, bullet points, and clear sections. Despite length, every sentence adds value—no redundancy. Information is front-loaded with purpose and warning, and structure aids readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description thoroughly explains the return format (distinct envelope with status, message, name, output) and details output contents. It also references related tools for further context. The tool is a simple read-only operation, and the description covers all necessary aspects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 2 parameters, with 50% description coverage (widget_id lacks description). The description adds that the tool requires either widget_id or widget_name, and notes that widget_name lookup is case-sensitive and must match exactly. This adds necessary clarity beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool renders a widget to HTML and explicitly marks it as a diagnostic tool only, distinguishing it from production usage. It also mentions it returns BD's rendered HTML output, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use (when user reports a broken widget, for troubleshooting render pipeline) and when not to use (never for production delivery). It references a specific rule and lists related tools (getWidget, updateWidget) for context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchUsersARead-onlyIdempotent
Search members/users - Full-text search across members with category, location, and sorting options.
Lean-by-default keep-list: same shape as listUsers — identity + routing + location core. Restore extras via the same include flags including include_extras=1 for stripped fields (billing/analytics rollups, duplicate location fields, social URLs, awards, credentials, work_experience, etc.).
Use when: (1) mirroring the public member-search experience - embedding search results in an external app, building a custom search-results page, or letting users search BD from outside the site; (2) verifying what is publicly findable for a given keyword / category / location combo (SEO coverage audits, "who shows up if a visitor searches X?"); (3) keyword / partial-name / location / category lookup in general. For exact-field lookup (by email, by user_id, by phone, by any admin column) use listUsers + property / property_value - faster, more precise, and supports admin-only filters (join date, subscription status, meta fields) that this endpoint does not.
Pagination: cursor-based (limit, page). See Rule: Pagination for full cursor/cap/stop semantics.
Enums: sort: reviews, name ASC, name DESC, last_name_asc, last_name_desc.
Parameter interactions:
q- keyword (matches first name, last name, company, about, search_description)pid(category ID),tid(sub-category/service ID),ttid(sub-sub-category) - taxonomy filters, use IDs fromlistTopCategories/listSubCategoriesaddress+dynamic=1- proximity/geographic filtering
See also: getUser (single record by ID), listUsers (full enumeration).
Returns: { status: "success", message: [...records] }. Supports pagination fields when result set is large.
Profile URL: every user record has a filename field. To get the full public profile URL, concatenate: <site-domain>/<user.filename>. The filename is the complete relative path (e.g., united-states/monterey-park/doctor/harrison-hasanuddin-d-o) - DO NOT prepend /business/, /profile/, /member/, or any other segment. BD's router resolves filename verbatim.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Search keyword | |
| pid | No | Category ID | |
| tid | No | Sub-category ID | |
| page | No | ||
| sort | No | ||
| ttid | No | Sub-sub-category ID | |
| limit | No | ||
| address | No | ||
| dynamic | No | ||
| include_tags | No | Opt in to return `tags` array. | |
| include_about | No | Opt in to return the `about_me` HTML bio. Heavy — when set, `limit` is auto-capped at 25 for transport stability. | |
| include_clicks | No | Opt in to return `user_clicks_schema.clicks` array. | |
| include_extras | No | Opt in to return ALL remaining user fields not in the lean keep-list and not gated by another `include_*` flag (social URLs, awards, credentials, quote, gmap, work_experience, ref_code, booking_link, listing_type, profession_name, verified, featured, etc.). | |
| include_photos | No | Opt in to return `photos_schema` array. Heavy — when set, `limit` is auto-capped at 25 for transport stability. | |
| include_password | No | Opt in to return bcrypt `password` hash. | |
| include_services | No | Opt in to return `services_schema` array. Heavy — when set, `limit` is auto-capped at 25 for transport stability. | |
| include_profession | No | Opt in to return `profession_schema`. | |
| include_seo_hidden | No | Opt in to return SEO-hidden meta fields. | |
| include_subscription | No | Opt in to return full `subscription_schema`. Heavy — when set, `limit` is auto-capped at 25 for transport stability. | |
| include_transactions | No | Opt in to return full `transactions` array. Heavy — when set, `limit` is auto-capped at 25 for transport stability. | |
| include_legacy_fields | No | Return image-import state on `photos_schema` rows: `original`, `resized`, `error`. Requires `include_photos=1`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=true and idempotent=true. The description adds value by detailing pagination, limit caps with heavy include flags, profile URL construction, and the lean-by-default keep-list. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with headings (Use when, Pagination, etc.) and front-loaded with purpose. It could be slightly more concise, but the structure helps navigate the complexity of 21 parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description covers output format, pagination, sort enums, and profile URL construction. Missing details: default sorting order, exact pagination fields. Overall quite complete for a search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high (76%), but the description adds meaningful context: groups parameters, explains interactions (q matches specific fields, address+dynamic for proximity), and clarifies the role of include_extras. This goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it performs full-text search across members with filters. It explicitly distinguishes itself from sibling tools like listUsers (exact-field lookup) and getUser (single record), making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit 'Use when' scenarios (public member-search, SEO audits, keyword/category/location lookup) and explicitly advises against using it for exact-field lookups, directing to listUsers instead. It also explains parameter interactions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateCityAIdempotent
Update a city (corrections only) - Update an existing city row. Read-mostly - use sparingly. Fields omitted are untouched (PATCH semantics - only send what you want to change).
Use when: correcting a typo in city_ln or city_filename, or reassigning a city's state_sn / country_sn if originally miscategorized. For a NEW city, DO NOT create via API - let the next member signup from that location auto-seed the row (BD handles this).
Required: locaiton_id (BD schema typo - sic).
Warning on city_filename edits: this is the URL slug used in every search-result page for that city. Changing it breaks all inbound links AND any static SEO pages (seo_type=profile_search_results) whose filename includes the old slug. If you must rename, create Redirect (301) records for each affected URL.
Returns: { status: "success", message: {...updatedRecord} }.
| Name | Required | Description | Default |
|---|---|---|---|
| city_ln | No | ||
| state_sn | No | ||
| country_sn | No | ||
| locaiton_id | Yes | City PK (BD typo - sic) | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| city_filename | No | URL slug. Changing this breaks inbound URLs - create redirects. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses PATCH semantics, the warning about city_filename edits breaking URLs requiring redirect creation, and the _clear_fields mechanism. Annotations are consistent and description adds valuable context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, but slightly verbose. Each sentence adds value, though some details could be more succinct.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage, behavioral notes, return format, and parameter details. With annotations providing safety info, this is fully complete for a mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond schema for locaiton_id (typo), city_filename (URL slug), and _clear_fields (detailed explanation). However, schema coverage is 50% and some parameters like city_ln and state_sn rely solely on schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it updates an existing city row, with specific uses like correcting typos or reassigning IDs. It distinguishes from creating a new city, which is not via API.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when to use (corrections, reassignments) and when not to (new city). Provides clear alternatives and prerequisites like required locaiton_id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateClickAIdempotent
Update a click record - Update an existing click record by ID. Fields omitted are untouched. Writes live data.
Use when: correcting click metadata. Rare - click records are typically append-only analytics.
Required: click_id.
See also: createClick (add new), deleteClick (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| click_id | Yes | ||
| click_url | No | ||
| click_name | No | ||
| click_type | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds context beyond annotations: 'Writes live data' and 'Fields omitted are untouched'. Annotations already indicate not read-only, not destructive, idempotent, and open world, but description reinforces behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise and well-structured with clear sections (purpose, usage, required, see also, returns). Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple update tool, covers required param, return format, and field behavior. Lacks detail on specific optional params but overall adequate given annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 20% schema coverage, only _clear_fields is documented in schema. Description only mentions required click_id, not the meaning of click_type, click_name, click_url. Fails to compensate for low schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update a click record' with a specific verb and resource, and distinguishes from siblings by mentioning createClick and deleteClick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('correcting click metadata') and notes rarity, with 'See also' referencing alternatives. Provides clear guidance on use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateCountryAIdempotent
Update a country (corrections / active toggle) - Update a country record. Read-mostly - primary use is toggling active to enable/disable a country on the site. Fields omitted are untouched (PATCH semantics - only send what you want to change).
Required: country_id.
| Name | Required | Description | Default |
|---|---|---|---|
| active | No | ||
| country_id | Yes | ||
| country_code | No | ISO 3166-1 alpha-2 (e.g. `US`, `CA`, `GB`) | |
| country_name | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotent and not destructive. The description adds valuable behavioral context: PATCH semantics, the role of `_clear_fields`, and that the primary action is toggling `active`. This goes beyond the annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise: two clear sentences and one bullet. Every sentence adds value, and critical information (purpose, PATCH semantics, required param) is at the beginning. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and a simple update operation, the description covers the essential aspects: main use case, required parameter, PATCH behavior, and the `_clear_fields` feature. It could optionally mention what happens if the country doesn't exist or permissions needed, but the annotations and schema already imply some flexibility. Overall, it's adequate for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (40%), but the description compensates by explaining the PATCH semantics and the special `_clear_fields` parameter in detail (including an example and reference to a rule). It also calls out `country_id` as required and mentions `active` toggling. The meaning of `country_code` and `country_name` is left to the schema, which already describes `country_code`.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Update a country record' with a specific focus on 'toggling `active` to enable/disable a country on the site'. The title 'Update a country (corrections / active toggle)' further clarifies the primary use cases. This distinguishes it from sibling update tools targeting other entities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides key usage guidance: it mentions 'Read-mostly - primary use is toggling `active`' and that 'Fields omitted are untouched (PATCH semantics - only send what you want to change)'. It also highlights the required parameter `country_id`. While it doesn't explicitly specify when not to use the tool or name alternatives, the context is clear enough for an AI agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateDataTypeAIdempotent
Update a data type - Update an existing datatype record by ID. Fields omitted are untouched. Writes live data.
Use when: renaming a data type.
Required: data_id.
Enums: category_active: 1=active and available for members to use, 0=inactive; limit_available: 0, 1.
See also: createDataType (add new), deleteDataType (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | Yes | Data type primary key (required to identify the record) | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| category_name | No | Display name for this content type (e.g. "Single Photo Post", "Multi-Photo Post", "Video Post") | |
| category_active | No | 1 = active and available for members to use; 0 = inactive | |
| limit_available | No | 1 = membership-plan posting limits apply to this data type; 0 = no per-plan limits |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Disclosed 'Writes live data,' 'Fields omitted are untouched,' and detailed the _clear_fields parameter behavior. Annotations confirm non-readonly and non-destructive nature, with no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structured with clear sections (Use when, Required, Enums, See also, Returns) and concise sentences. No redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: purpose, parameters, behavior (including clearing fields), return format, and references to related tools. Adequate for a mutation tool without output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%. Description adds value by repeating enums in plain language and explaining the _clear_fields parameter with examples, beyond what schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description explicitly states 'Update a data type' with specific verb and resource. It distinguishes from siblings by listing createDataType and deleteDataType as alternatives, making the purpose clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Includes 'Use when: renaming a data type.' and 'Required: data_id.' along with 'See also:' references to create/delete alternatives, providing explicit usage context and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateEmailTemplateAIdempotent
Update an email template - Update an existing emailtemplate record by ID. Fields omitted are untouched. Writes live data.
Use when: editing any field on an existing template — subject, body, wrapper mode (notemplate), category, signature, triggers, etc. Mirrors createEmailTemplate field-for-field; only email_id is required.
Required: email_id.
Enums (same as createEmailTemplate): signature: 0/1; notemplate: 0 (logo left), 2 (logo center), 3 (logo right), 4 (template, no logo), 1 (plaintext-only, no wrapper); category_id: 0/1/3/4/15/16 (unrestricted on update); unsubscribe_link: 0/1.
See also: createEmailTemplate (add new), deleteEmailTemplate (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } — the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| website | No | 0=platform-wide | |
| email_id | Yes | ||
| priority | No | ||
| triggers | No | Comma-separated events | |
| signature | No | Append the site's default email signature to this template. Set to `1` to include the site signature; BD appends it automatically at send time. | |
| email_body | No | Content-only HTML — BD wraps it in the document scaffold. Open with any content tag (`<p>`, `<table>`, `<div>`, `<h1>`/`<h2>`, `<img>`, etc.). Inline `style=""` only — no `<style>` blocks (Outlook strips them) and no `class=""` (emails have no site stylesheet). Gradients need a fallback `background-color:` first. Verify image URLs return 200 before embedding when possible. Supports `%%%merge_tag%%%` tokens and `[widget=Name]` shortcodes. See **Rule: Email template recipe**. | |
| email_from | No | ||
| email_name | No | Internal name for this email template (used by `[email-template name=...]` references and admin lookups). **Lowercase, hyphens, no spaces** (e.g. `welcome-email`, `password-reset`, `lead-notification-admin`) — see **Rule: Email template recipe**. | |
| email_type | No | ||
| notemplate | No | Template + logo wrapper mode. `0` = template + logo left; `2` = template + logo center; `3` = template + logo right; `4` = template, no logo; `1` = no template or logo (plaintext-only). When this is anything other than `1`, BD's global template wraps `email_body` in a 600px-wide containing table — do NOT add your own outer max-width wrapper in that case. | |
| category_id | No | Template category. `update` is unrestricted across `0`/`1`/`3`/`4`/`15`/`16`. (On `create`, only `0` is allowed — other values are system-populated.) | |
| content_type | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| email_subject | No | Supports merge tags | |
| unsubscribe_link | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false, destructiveHint=false, idempotentHint=true. Description adds 'Fields omitted are untouched' for partial update behavior and 'Writes live data' for immediacy, providing context beyond annotations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Highly structured with clear sections: purpose, use-when, required, enums, see-also, returns. Every sentence is informative and no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 15 parameters and no output schema, the description provides a solid overview, enum details, and return format. It references external rules but otherwise covers key aspects. Could be slightly more detailed on return behavior beyond the message.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 60%. Description explains enums for signature, notemplate, category_id, and unsubscribe_link, and describes _clear_fields. However, parameters like email_type, website, email_from, priority, content_type lack elaboration in description, so it partially compensates but not fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update an email template' and explains the action (update by ID), resource (email template), and key behavior (fields omitted are untouched, writes live data). It distinguishes from siblings like createEmailTemplate and deleteEmailTemplate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when:' section lists scenarios (editing subject, body, wrapper mode, etc.) and contrasts with create/delete tools via 'See also:' references. Required parameter specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateFormAIdempotent
Update a form - Update an existing form record by ID. Fields omitted are untouched. Writes live data.
Required: form_id.
Cross-refs same as createForm — see Rule: Forms § Form-level recipe / § Lead-match / § Member-dashboard. Before flipping form_action_type to a public-facing value, run listFormFields to confirm the tail pattern exists.
Wrapper-enforced refusal: form_action_type=redirect AND empty form_target → call refused.
See also: createForm, deleteForm, listFormFields / createFormField.
Returns: { status: "success", message: {...updatedRecord}, _admin_edit_url: "..." }. _admin_edit_url is a centralized-admin deep-link to the Form Builder editor for this form's form_name — surface it to the user so they can jump straight to the admin edit screen for the form just updated.
| Name | Required | Description | Default |
|---|---|---|---|
| form_id | Yes | ||
| form_url | No | Save Action URL. Canonical value: `/api/widget/json/post/Bootstrap%20Theme%20-%20Function%20-%20Save%20Form`. If a form was created via this API with the correct value, leave this field alone on update - only touch it to repair a form that was created without it. | |
| form_title | No | ||
| form_target | No | Destination URL, required when `form_action_type=redirect`, ignored otherwise. Full URL with `https://`. | |
| table_index | No | Primary key column matching `form_table`: `website_contacts` → `ID`, `leads` → `lead_id`, `users_data` → `user_id`. Leave alone on update unless repairing a broken form. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| form_email_on | No | Send admin notification email on each submission. `0` = OFF, `1` = ON. | |
| form_action_div | No | Target element ID (CSS selector with `#`) swapped on submit by the `widget` action type; harmlessly ignored on `notification` / `redirect`. Canonical value: `#main-content`. Override only when the user explicitly names a different target. | |
| form_action_type | No | Post-submit behavior. `widget` = success pop-up, `notification` = success alert banner, `redirect` = send user to `form_target` URL (wrapper-enforced: `form_target` required, see `form_target` field), `default` = member-dashboard class (admin-clone-only), `""` = no behavior (internal-only forms). When flipping FROM empty TO a public-facing value, verify the tail pattern (Button-last is agent-side, NOT wrapper-enforced) via `listFormFields`. See **Rule: Forms** § Form-level recipe. | |
| form_success_message | No | Post-submit success copy. Canonical default for Standard public AND Lead-saving classes: `Your Message has been Received`. If the existing record already has a value and the user hasn't flagged the message as a problem, leave it alone. Only set this on update when (a) the user asks for different copy, or (b) the field is empty and you're filling in the canonical default. Applies to `form_action_type` ∈ {`widget`, `notification`, `redirect`}; not used by `default` class. | |
| label_to_placeholder | No | Form-level toggle. When `"1"`, BD collapses each field's `field_text` (label) into placeholder text inside the input. Per-field `field_placeholder` is overridden when this is on. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations by disclosing partial-update semantics ('Fields omitted are untouched'), live data writes, and a specific refusal rule. It also details the return format and the meaning of `_admin_edit_url`, giving the agent full awareness of side effects and post-update actions. This aligns with the annotations (readOnlyHint=false, destructiveHint=false) without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a one-sentence summary, a required-field note, behavioral rules, cross-references, and a return-value specification. Every sentence earns its place without redundancy. The formatting with bold headings and bullet-like separators improves scannability for an AI agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex update tool with 11 parameters and no output schema, the description covers all critical aspects: required field, partial updates, prerequisites, refusal conditions, return structure, and how to surface the admin link. Cross-references to shared 'Rule: Forms' are acceptable given the schema's thoroughness and the presence of sibling tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers 82% of parameters with rich descriptions. The tool description adds cross-parameter context, such as the dependency between `form_action_type=redirect` and non-empty `form_target`, and the prerequisite to run `listFormFields` before certain changes. It also highlights `_clear_fields` as a special parameter, which is useful operational knowledge beyond the schema's per-field explanation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Update an existing form record by ID.' It clearly distinguishes from sibling tools like createForm and deleteForm by emphasizing partial updates ('Fields omitted are untouched') and live writes. The 'See also' list reinforces its role as an update operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use the tool (updating existing forms) and provides actionable prerequisites, such as running `listFormFields` before flipping `form_action_type` to a public-facing value. It also names the wrapper-enforced refusal condition. While it doesn't explicitly say 'use this instead of X', the context and cross-references effectively differentiate it from create/delete operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateFormFieldAIdempotent
Update a form field - Update an existing formfield record by ID. Fields omitted are untouched. Writes live data.
Required: field_id.
When renaming field_name on a form_table=website_contacts form, use canonical names (yourname / inquiry_email / phone / comments) — see createFormField and Rule: Forms § Form classes.
See Rule: Forms § Field anatomy for field shape, view-flag defaults, validators, and the canonical json_meta skeleton.
Wrapper-enforced refusals: (1) field_required=1 with field_type ∈ {HoneyPot, HTML, Tip, Button} — Hidden is allowed. (2) field_type not in the canonical enum (strict case match; textarea is the lone lowercase value). (3) field_type=Hidden with empty field_name or empty field_text. (4) Non-binary value on any of field_required / field_input_view / field_display_view / field_email_view / field_search_view / field_grid_view / field_input_view_admin_only (empty / omitted accepted — BD applies per-field defaults).
Agent pre-checks (NOT wrapper-enforced): field_name uniqueness within form, single submit element per form. See Rule: Forms § Wrapper-enforced invariants → Agent-side responsibilities.
See also: createFormField, deleteFormField, listFormFields.
| Name | Required | Description | Default |
|---|---|---|---|
| field_id | Yes | ||
| json_meta | No | JSON-stringified per-field metadata blob (UI rendering + validator config). See **Rule: Forms** § Field anatomy → `json_meta` for the canonical skeleton. | |
| field_text | No | ||
| field_type | No | Form field type. Copy spelling exactly — most are TitleCase but `textarea` is lowercase. Grouping + use cases at **Rule: Forms** § Field anatomy → Valid field_type values. | |
| field_ldesc | No | Helper text rendered under the input field. Use for instructions / format hints (e.g. "Use international format"). | |
| field_order | No | Display position (lower = earlier). New forms: multiples of 10 (10, 20, 30…), security tail included. Adding to an existing form: continue its pattern — don't renumber unrelated fields. | |
| input_class | No | HTML `class=` attribute. On `field_type=Button`, must be `btn btn-lg btn-block <variant>` - e.g. `btn btn-lg btn-block btn-secondary`. Variant is one of `btn-primary`/`btn-secondary`/`btn-danger`/`btn-success`/`btn-warning`/`btn-info`/`btn-dark`, OR a custom class targeted by site CSS. See `createFormField`. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| default_value | No | Prefilled value the field loads with on render. Accepts a static value OR PHP (e.g. `<?php echo date('Y-m-d'); ?>`) — BD evaluates at render time on any field_type. | |
| field_options | No | For `field_type` ∈ {`Radio`, `Checkbox`, `Select`}: `system_name=>label,system_name=>label,...`. LHS submitted value, RHS displayed text. Comma and `=>` are reserved separators. `%%%token%%%` translations supported. Silently ignored on other field types. | |
| field_required | No | `0` or `1`. Forbidden when `field_type` ∈ {`HoneyPot`, `HTML`, `Tip`, `Button`} — wrapper refuses these combinations because the requirement can't be satisfied at submit. `Hidden` is allowed (its value comes from `field_text`). | |
| field_grid_view | No | Table View flag — value renders in admin-dashboard / front-end data tables. | |
| field_email_view | No | Include value in notification emails. Binary `0`/`1`. | |
| field_input_view | No | Binary `0`/`1`. For readonly behavior, add the `readonly` CSS class to `input_class` (e.g. `form-control readonly`); do NOT use `field_input_view=2`. | |
| field_placeholder | No | ||
| field_search_view | No | Lead Previews flag — value visible in lead-preview cards before purchase. Applies to forms with `form_table=leads`. | |
| field_display_view | No | Show submitted value on front-end record-detail pages. Binary `0`/`1`. | |
| field_input_view_admin_only | No | Admin-only render flag. When `1`, field renders only when an admin is logged-in on the front end with admin-view enabled; members never see it. Use on `form_action_type=default` member-account forms. Default `0`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false (write operation), destructiveHint=false (non-destructive), idempotentHint=true (idempotent), and openWorldHint=true (allows extra fields). The description aligns perfectly: it says 'update' and 'writes live data', confirms non-destructive behavior, and provides details on partial updates ('Fields omitted are untouched') and constraints (wrapper-enforced refusals). No contradictions; the description adds valuable behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but well-structured. It starts with a concise one-line summary, then organizes information into sections: required field, special case for renaming, external references, wrapper-enforced refusals, agent pre-checks, and see-also. Every sentence adds value, though some sections are dense. It balances detail with clarity, earning a high score for its context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 18 parameters, no output schema, and complexity, the description is comprehensive. It covers purpose, usage, behavioral constraints, parameter semantics, and related tools. It references external rules for deeper details. While it doesn't describe return values explicitly (common for update operations without output schema), it provides sufficient context for an agent to use the tool effectively. Slight overhead in length but justified by complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 83% (high), so baseline is 3. The description adds significant meaning: for field_type, it warns about case sensitivity; for field_required, it explains forbidden combinations; for field_input_view, it clarifies not to use value 2; for _clear_fields, it details usage with examples. While the schema already describes most parameters, the description provides deeper behavioral context and cross-references, justifying a score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Update' and the resource 'form field'. It specifies updating by ID and notes that omitted fields are untouched, distinguishing it from creation or deletion. The phrase 'Writes live data' confirms it's a live operation. This is specific and distinct from siblings like createFormField, deleteFormField, and listFormFields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly notes the required parameter 'field_id' and provides extensive guidance on when to use the tool, including special cases like renaming fields on a specific form, referencing external rules for field anatomy and validators, detailing wrapper-enforced refusals, and listing agent pre-checks. It also lists related tools (createFormField, deleteFormField, listFormFields) as alternatives, offering clear context for choosing this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateLeadAIdempotent
Update a lead - Update an existing lead record by ID. Fields omitted are untouched.
Required: lead_id.
Custom (form-defined) lead fields — e.g. wizard-style hidden match_* fields — live in users_meta with database=leads and database_id=<lead_id>. Use updateUserMeta / createUserMeta for those. Rule: Forms § Form classes → Custom-field storage covers the pattern.
See also: createLead, deleteLead, matchLead, updateUserMeta.
Returns: { status: "success", message: {...updatedRecord} }.
| Name | Required | Description | Default |
|---|---|---|---|
| sub_id | No | Sub-category ID. Same `lead_matches` consideration as `top_id`. | |
| top_id | No | Top category ID. Changing this orphans existing `lead_matches` rows — re-run `matchLead` to re-route. | |
| lead_id | Yes | ||
| lead_more | No | Match-broadcast flag from the submitter's form input (radio/select). `0` = contact only the single matched member (default). `1` = broadcast to multiple matching members. | |
| lead_name | No | Submitter's full name. | |
| lead_email | No | Submitter email address. | |
| lead_notes | No | Owner-to-member notes about the lead (e.g. "phone number verified"). Visible to the matched member; never shown to the submitter. Leave blank unless the user asks. | |
| lead_phone | No | Submitter phone number. | |
| lead_price | No | Lead price (decimal). `0.00` = free. | |
| lead_status | No | Lead status (integer). NON-SEQUENTIAL enum - `3` does NOT exist; do not assume gaps are fillable: - `1` = Pending (received, awaiting action) - `2` = Matched (assigned to members) - `4` = Follow-Up (in progress) - `5` = Sold Out (no capacity) - `6` = Closed (resolved - converted or won't convert) - `7` = Bad Leads (spam/invalid) - `8` = Delete (soft-delete - hides from views) "Sold" / "won" -> `6` (Closed). Spam -> `7`. BD does NOT validate this enum - out-of-set integers are accepted and stored with undefined render behavior. Always use documented values. | |
| lead_message | No | Submitter's detailed request — what they typed describing their needs. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| lead_location | No | Geocoded location string. BD recomputes the derived geocode columns (`lat`/`lng`/bounding box/`country_sn`/`adm_lvl_1_sn`/`location_type`) when this changes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotentHint=true. The description adds behavioral context: fields omitted are untouched, and the return format is specified. It does not repeat side-effect warnings from the schema (e.g., top_id orphan matches), which is acceptable since the schema covers those. However, a brief mention of idempotent behavior could further enhance transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured with bullet points and sections. It front-loads the main purpose and keeps each sentence purposeful. No unnecessary content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (13 parameters, no output schema), the description provides necessary context: return format, custom field handling, and links to related tools. It does not cover every behavioral edge case, but the schema with 92% coverage fills gaps. A note about lead_matches impact could improve completeness, but overall it is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (92%), so baseline is 3. The description adds value by highlighting the required lead_id, explaining the return format, and clarifying custom field storage. It does not describe each parameter, but the schema already provides detailed descriptions. Overall, it supplements the schema effectively.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Update') and resource ('lead'), clearly states it updates an existing lead record by ID, and distinguishes itself from sibling tools like createLead, deleteLead, matchLead, and updateUserMeta by mentioning them in 'See also'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('Update an existing lead record by ID'), notes that omitted fields are untouched, indicates the required parameter (lead_id), and provides guidance on handling custom fields via updateUserMeta/createUserMeta, including a reference to related rules.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateLeadMatchAIdempotent
Update a lead match - Update an existing leadmatch record by ID. Fields omitted are untouched. Writes live data.
Use when: recording a member's response to a lead (lead_response, lead_accepted, lead_chosen) or adjusting lead_points/match_price for billing reconciliation.
Required: match_id.
Enums: lead_status: 1=Pending, 2=Matched, 4=Follow-Up, 5=Sold Out, 6=Closed, 7=Bad Leads, 8=Delete. (Verified against admin UI dropdown 2026-04-19. Value 3 does not exist. BD accepts out-of-range integers silently - stick to this set.)
See also: createLeadMatch (add new), deleteLeadMatch (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| match_id | Yes | ||
| lead_status | No | Lead status (integer). NON-SEQUENTIAL enum - `3` does NOT exist; do not assume gaps are fillable: - `1` = Pending (received, awaiting action) - `2` = Matched (assigned to members) - `4` = Follow-Up (in progress) - `5` = Sold Out (no capacity) - `6` = Closed (resolved - converted or won't convert) - `7` = Bad Leads (spam/invalid) - `8` = Delete (soft-delete - hides from views) "Sold" / "won" -> `6` (Closed). Spam -> `7`. BD does NOT validate this enum - out-of-set integers are accepted and stored with undefined render behavior. Always use documented values. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| lead_response | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains that fields omitted are untouched, writes live data, and returns the full updated record. It also details enum behavior and BD's silent acceptance of out-of-range values, adding context beyond annotations. However, it does not explicitly mention idempotency or non-destructiveness, though implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (main purpose, use when, required, enums, see also, returns). Every sentence provides value, and the key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the parameter count (4) and no output schema, the description covers enum details, return format, special parameter behavior, and references sibling tools. It is comprehensive enough for an agent to use correctly without additional information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds significant meaning to parameters: explains enum values for lead_status (non-sequential, accepted silently), details the _clear_fields parameter behavior, and notes that omitted fields are untouched. With 50% schema coverage, the description compensates well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'update' and resource 'lead match', and distinguishes from sibling tools (createLeadMatch, deleteLeadMatch) in the 'See also' section. The purpose is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly lists when to use ('recording a member's response...' or 'adjusting lead_points/match_price'), requires 'match_id', and references alternative tools for creating and deleting. This provides clear guidance on tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateMemberSubCategoryLinkAIdempotent
Update a user-service relationship - Update a Member ↔ Sub Category link by rel_id. Fields omitted are untouched. Writes live data.
Use when: adjusting per-link metadata - member's price for this service, specialty flag, completion counter.
Required: rel_id.
Updatable fields: avg_price, specialty, num_completed, date.
See also: createMemberSubCategoryLink (add new), deleteMemberSubCategoryLink (remove).
Returns: { status: "success", message: {...updatedRecord} }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. Optional — omit unless backfilling historical data. | |
| rel_id | Yes | ||
| avg_price | No | ||
| specialty | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| num_completed | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains that omitted fields are untouched and that writes affect live data, consistent with the idempotentHint and openWorldHint annotations. It also details the behavior of `_clear_fields`, which is critical for understanding updates. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is verbose, including lengthy contextual digressions about member classification and sub-sub-categories that are tangential to the tool's core purpose. The first paragraph is concise, but the extraneous information could be trimmed without losing essential guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 6 parameters and no output schema, the description provides a detailed return format and a rule for clearing fields. It also explains the data model context, aiding understanding of when this tool applies. Minor gaps: no mention of error handling or rate limits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 33% schema description coverage, the description compensates by explaining all updatable parameters (`avg_price`, `specialty`, `num_completed`, `date`) and providing a thorough explanation of `_clear_fields`. It adds meaningful context beyond the schema's basic type definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Update a user-service relationship - Update a Member ↔ Sub Category link by `rel_id`', clearly stating the verb (update) and resource (a specific link). It explicitly distinguishes from sibling tools like `createMemberSubCategoryLink` and `deleteMemberSubCategoryLink`, which are listed under 'See also'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context with 'Use when: adjusting per-link metadata' and lists the exact updatable fields. It also points to alternative tools for creating and deleting. However, it does not explicitly state when not to use this tool, though the context is sufficient for most cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateMenuAIdempotent
Update a menu - Update an existing menu record by ID. Fields omitted are untouched. Writes live data.
Use when: renaming a menu, toggling menu_active, or adjusting its CSS/HTML wrapper attributes.
Required: menu_id.
See also: createMenu (add new), deleteMenu (remove permanently).
Returns: { status: "success", message: {...updatedRecord}, _admin_edit_url: "..." } - the full updated record after changes applied. _admin_edit_url is a centralized-admin deep-link to the Menu Builder editor for this menu_id — surface it to the user so they can jump straight to the admin edit screen for the menu just updated.
| Name | Required | Description | Default |
|---|---|---|---|
| menu_id | Yes | ||
| menu_name | No | ||
| menu_title | No | ||
| menu_active | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description adds important behavioral details: 'Fields omitted are untouched' (partial updates) and 'Writes live data' (immediate effect). It also describes the return value including _admin_edit_url and instructs to surface it, providing actionable context not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bold section headers (Use when, Required, See also, Returns), making it easy to scan. It is slightly longer than necessary but each section adds value, particularly the detailed return explanation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an update tool with 5 parameters and no output schema, the description covers purpose, usage, required parameter, return value, and even provides a user-facing instruction about the admin edit link. It lacks explicit error-handling details, but this is acceptable for a CRUD operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (20%), and the description partially compensates by mentioning menu_id as required and referencing menu_active toggling. However, it does not explicitly explain menu_name vs. menu_title, leaving some ambiguity. The _clear_fields parameter is well-described in the schema, so that does not need repetition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Update a menu - Update an existing menu record by ID.' It uses a specific verb and resource, and explicitly distinguishes itself from siblings by mentioning 'See also: createMenu (add new), deleteMenu (remove permanently).'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage scenarios: 'Use when: renaming a menu, toggling menu_active, or adjusting its CSS/HTML wrapper attributes.' It also states the required field and names alternative tools, making it clear when to use this tool vs. alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateMenuItemAIdempotent
Update a menu item - Update an existing menuitem record by ID. Fields omitted are untouched. Writes live data.
Use when: renaming, re-linking (change menu_link), reordering (change menu_order), or hiding (change menu_active=0).
Required: menu_item_id.
See also: createMenuItem (add new), deleteMenuItem (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| menu_link | No | URL or path | |
| menu_name | No | Display text — the visible menu link label. Supports `[widget=Name]` shortcodes. | |
| menu_order | No | ||
| menu_active | No | ||
| menu_item_id | Yes | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a mutation (readOnlyHint false) and idempotent hint. The description adds: 'Fields omitted are untouched' (partial update) and 'Writes live data'. No contradiction. However, it could further detail idempotent behavior or side effects beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four well-structured sentences with bold headings. The most critical info (purpose, use cases, required param, returns) is front-loaded. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description specifies the return format ({ status, message }). It covers necessary context: update by ID, partial update, live data, and required parameter. The 6-parameter input schema is adequately addressed for a mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (3 of 6 parameters have descriptions). The description adds value by explaining that omitted fields are untouched and gives concrete examples for menu_link, menu_order, menu_active. It does not detail _clear_fields or menu_order/menu_active schemas, but the examples compensate partially.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update a menu item' and distinguishes from siblings by explicitly mentioning createMenuItem and deleteMenuItem as alternatives. It specifies the resource (menuitem) and operation (update by ID), leaving no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit use cases: renaming, re-linking, reordering, hiding. Also mentions required parameter (menu_item_id) and references related tools (createMenuItem, deleteMenuItem). This gives clear guidance on when to use this tool vs alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateMultiImagePostAIdempotent
Update an album group - Update an existing portfoliogroup record by ID. Fields omitted are untouched. Writes live data.
Use when: editing metadata (title, description, group_status) OR appending photos via post_image CSV + auto_image_import=1 (APPENDS, does not replace). Existing photos are edited via updateMultiImagePostPhoto (title/order only).
Required: group_id.
Enums: group_status: 0=Draft, 1=Published.
Verify appended photos via listMultiImagePostPhotos, NOT via getMultiImagePost.post_image. The parent's post_image field is a transient write-through, not a mirror of child rows — it does NOT reflect appended photos. Child rows land in users_portfolio. Silent-failure possible (empty file, image_imported=0) — check each child row.
group_name rename does NOT update group_filename (the URL slug). group_filename is writable — see Rule: URL slug rename for when to suggest a slug update + redirect. Report group_filename from getMultiImagePost when giving the user a URL.
See also: createMultiImagePost, deleteMultiImagePost, deleteMultiImagePostPhoto.
Returns: { status: "success", message: {...updatedRecord} } - photo rows land asynchronously.
| Name | Required | Description | Default |
|---|---|---|---|
| group_id | Yes | ||
| post_tags | No | Comma-separated keywords for the album. | |
| group_desc | No | Album description HTML. Froala body field — see **Rule: Post-body formatting** (structure, `fr-dib fr-fil`/`fr-fir` float + inline `width: 350px`, landscape Pexels images). | |
| group_name | No | ||
| post_image | No | Comma-separated image URLs — APPENDS new photos (does NOT replace existing). **LANDSCAPE only — verify each candidate's orientation via `getImageDimensions` per **Rule: Image dimensions** before commit; bare URLs, no `?query`, each must end in `.jpg`/`.jpeg`/`.png` (WebP/GIF/AVIF skipped pre-tool per the same rule) — see **Rule: Image URLs**.** Query strings get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| auto_geocode | No | ||
| group_status | No | 0=Not Published, 1=Published, 3=Pending Approval (rare — set when site admin requires manual moderation before albums go live). | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| group_filename | No | Public URL slug path (e.g. `photo-albums/my-slug`). Writable — BD does NOT regenerate the slug when `group_name` changes. See **Rule: URL slug rename** for when to suggest a slug update + redirect. | |
| auto_image_import | No | **Auto-import images to site storage.** Set `1` when any external image URL field on this multi-image post holds a URL - BD fetches and saves each image locally. Without the flag, BD stores URLs as-is; images break if source hosts go down. **Recommended default when supplying external image URLs**; omit or set `0` only if user explicitly wants external URL references. Supports JPG/PNG/GIF/WebP/SVG. Processing delay: several minutes per image. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description reveals appending photos and silent failures, but contradicts annotations: idempotentHint=true is false because appending photos is not idempotent (duplicates on retry). This is a major contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and bolded terms, but somewhat lengthy. Every sentence adds value, but could be more concise for quick scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers return format, async photo processing, verification via listMultiImagePostPhotos, silent failure conditions, and references to related rules. Adequate for a complex multi-faceted tool with no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 70% schema coverage, description adds critical meaning: post_image appends and requires landscape, auto_image_import fetches externally, group_status enum meanings, group_filename slug behavior, and _clear_fields mechanism. Fully compensates for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific action verb 'Update', identifies resource 'album group/portfoliogroup', and distinguishes from siblings like createMultiImagePost and deleteMultiImagePost. It also clarifies scope: 'by ID' and 'fields omitted are untouched'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use when' section lists editing metadata or appending photos, and notes alternative tool updateMultiImagePostPhoto for editing existing photos. 'See also' lists related tools, providing clear context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateMultiImagePostPhotoAIdempotent
Update an album photo - Update an existing portfoliophoto record by ID. Fields omitted are untouched. Writes live data.
Use when: reordering photos within an album (order field) or renaming (title).
Required: photo_id.
Cannot re-import a failed image. Only writes title and order. To fix an image_imported=0 row: deleteMultiImagePostPhoto, then updateMultiImagePost group_id=<same>&post_image=<new_url>&auto_image_import=1 (appends).
See also: createMultiImagePostPhoto (add new), deleteMultiImagePostPhoto (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| order | No | ||
| title | No | ||
| photo_id | Yes | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses imperative behavior (writes live data) and field omission semantics. Notes limitation on re-importing. Annotations provide idempotentHint=true; description doesn't confirm but doesn't contradict. Adds context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections (intro, use when, required, cannot, see also, returns). Every sentence adds value; no redundancy. Efficient for agent parsing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Provides return format description, parameter roles, and usage constraints. No output schema, but description covers expected output. With annotations and sibling context, the tool is fully specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is low (25%), the description explains purpose of title and order fields, and clarifies _clear_fields usage. It compensates by clarifying field update behavior and stating that omitted fields are untouched.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates an album photo by ID, specifying it writes live data and fields omitted are untouched. It distinguishes from sibling tools like createMultiImagePostPhoto and deleteMultiImagePostPhoto.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (reordering, renaming) and provides required parameter photo_id. Includes limitations (cannot re-import failed image) and alternatives (delete then update group). References sibling tools for reference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updatePostTypeAIdempotent
Update a post type - Update a post type. PATCH semantics (except per Rule: Post-type code fields). Writes live data.
Cache refresh is automatic. Response includes auto_cache_refreshed: true after successful writes; no manual refreshSiteCache call needed. If auto_cache_refreshed: false, check auto_cache_refresh_error and retry refreshSiteCache once.
Required: data_id.
Picking the right post type — disambiguation. Apply Rule: Resource disambiguation before editing. "Edit my classifieds page" is layer-ambiguous (a WebPage vs. the post type's code group vs. Member Listings UI vs. a category landing) — confirm WHICH layer even when only one record string-matches. Resolve to data_id via listPostTypes first; never proceed on semantic similarity alone.
Use when: toggling a post type active/inactive, renaming, changing per-page display counts, editing search-results UI or profile-page code. For Member Listings specifically: tuning keyword-search, pagination, sidebar, sort order. Custom field DEFINITIONS live in BD admin UI, not API.
Universal structural safety - NEVER mutate these fields on ANY post type: data_type, system_name, data_name, data_active, data_filename, form_name, software_version, display_order. BD system-seeds them; changes break rendering site-wide.
MEMBER LISTINGS SPECIAL CASE (data_type=10). Every BD site has exactly one post type with data_type=10 (system_name=member_listings) - it controls the Member Search Results page UI/UX. No profile/detail page of its own - members render via the normal profile system. data_id varies per site; discover via listPostTypes property=data_type property_value=10 property_operator==. Cache the data_id for the session - it never changes.
Member Listings cheat-sheet (12 commonly-edited UI/UX settings + 3 search-code fields - NOT a limit, any real column is writable per schema-is-documentation): h1, h2, per_page, keyword_search_filter, enableLazyLoad, category_order_by, category_ignore_search_priority, post_type_cache_system, category_sidebar, sidebar_search_module, sidebar_position_mobile, enable_search_results_map, category_header, search_results_div, category_footer.
Member Listings guardrails (apply ONLY to data_type=10):
profile_header/profile_results_layout/profile_footer/search_results_layouthave NO effect on Member Listings - skip them.data_activemust stay1; no legitimate reason to disable via API.On other post types (blog, event, coupon, property, product), these ARE legitimate rendering fields - write freely.
CODE FIELDS - master-fallback on GET + all-or-nothing save per group. Up to 8 code-template fields begin life backed by BD's MASTER post-type template; they only persist locally when saved. GET returns master value for un-customized fields (agent sees real rendered code, not empty string). Writing ANY field in a group requires sending ALL fields in that group (unchanged fields copied verbatim from prior GET); omitting group-mates causes them to drift back to master on next render.
Groups:
Search-results (every post type INCLUDING Member Listings):
category_header+search_results_div+category_footer. Send all 3.Profile/detail (post types WITH detail pages - NOT Member Listings):
profile_header+profile_results_layout+profile_footer. Send all 3. DO NOT send on Member Listings.Standalone (post types WITH detail pages - NOT Member Listings):
search_results_layout(single.php analogue - misleading name) andcomments_code(auxiliary footer, embeds/schema/pixels). Both save independently, no group rule. Master-fallback applies. DO NOT send on Member Listings.
Code-edit workflow:
getPostType(data_id)- returns current values with master fallback.Identify target group.
Build payload: changed field(s) + other group-mates copied verbatim from GET.
updatePostTypewithdata_id+ full group. (Cache flush is automatic post-write.)
Code-field trust level: all 8 code fields are widget-equivalent - accept arbitrary HTML/CSS/JS/iframes/PHP (BD evaluates PHP server-side at render). XSS/SQLi sanitization rules do NOT apply - anyone editing post-type code already has full site code control. Supports PHP variables (<?php echo $user_data['full_name']; ?>) and BD text-label tokens (%%%text_label%%%).
Member Listings code edits affect every member-search page on the site - confirm intent with user before editing Member Listings code fields.
See also: getPostType, listPostTypes (filter by data_type), deletePostType (NOT for Member Listings - system-required).
Returns: { status: "success", message: {...updatedRecord}, auto_cache_refreshed: true|false, auto_cache_refresh_error?: "..." }.
| Name | Required | Description | Default |
|---|---|---|---|
| h1 | No | Search Results page H1 heading. | |
| h2 | No | Search Results page H2 sub-heading. | |
| data_id | Yes | Post type primary key. Required. For the Member Listings post type (`data_type=10`, singleton per site), discover via `listPostTypes` filtered by `property=data_type&property_value=10&property_operator==` - `data_id` varies per site. | |
| per_page | No | Number of results per search results page. Default 9 (Member Listings). Recommended max 500 for site-speed reasons. | |
| category_tab | No | Admin-UI label for the post-type tab. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| comments_code | No | **CODE FIELD** - additional detail-page footer/embed code (HTML/CSS/JS/iframe/PHP; widget-equivalent trust). Renders directly AFTER `search_results_layout` on the single-record detail page - for embed widgets, schema markup, analytics pixels, structured data, auxiliary footer code. Applies ONLY to post types with per-record detail pages (blog, event, coupon, property, product, etc.). **NOT applicable to Member Listings (`data_type=10`)** - no post-type-driven detail page; do not send on Member Listings updates. Standalone - NOT in the profile triplet or search-results group; saves independently. Uses master-fallback-on-read like other code fields. | |
| enableLazyLoad | No | Pagination Display Options. `1` = Insta-Load Search Results (default on Member Listings), `0` = Standard Pagination, `2` = Hide Pagination. | |
| profile_footer | No | **CODE FIELD - profile/detail page FOOTER** (HTML/CSS/JS/iframe/PHP; widget-equivalent trust). Renders BELOW the main content on the single-record detail page. **Part of the profile code group** with `profile_header` + `profile_results_layout` — see **Rule: Post-type code fields**. | |
| profile_header | No | **CODE FIELD - profile/detail page HEADER** (HTML/CSS/JS/iframe/PHP; widget-equivalent trust). Renders ABOVE main content on the single-record detail page for post types with per-record detail pages (blog, event, coupon, property, product, etc.). Part of the profile code group (`profile_header` + `profile_results_layout` + `profile_footer`) - all-or-nothing save rule applies — see **Rule: Post-type code fields**. **NOT applicable to Member Listings (`data_type=10`)** - members render via BD's core profile system, not a post-type template. Field stores but has no rendering effect; do not send on Member Listings updates. | |
| category_footer | No | **CODE FIELD - search results FOOTER** (HTML/CSS/JS/iframe/PHP; widget-equivalent trust; no input sanitization). Renders BELOW the member-search results loop. Supports PHP variables and `%%%text_label%%%` tokens. Part of the search-results code group (`category_header` + `search_results_div` + `category_footer`) - master-fallback on read + all-or-nothing save — see **Rule: Post-type code fields**. | |
| category_header | No | **CODE FIELD - search results HEADER** (HTML/CSS/JS/iframe/PHP; widget-equivalent trust; no input sanitization). Renders ABOVE the member-search results loop. Supports PHP variables (`<?php echo $user_data['full_name']; ?>`) and `%%%text_label%%%` tokens. Part of the search-results code group - master-fallback on read + all-or-nothing save — see **Rule: Post-type code fields**. | |
| category_sidebar | No | Sidebar to display on search-results pages. Valid values: `""` (no sidebar), a Master Default Sidebar, or a custom sidebar `name` from `listSidebars`. See **Rule: Sidebars** for the canonical Master Default list and selection workflow. **Semantic equivalent of `form_name` on WebPages** - different variable name, same value set. Default on Member Listings: `Member Search Result`. | |
| category_order_by | No | Display order of results. `alphabet-asc` (Member Name A-Z, default) / `alphabet-desc` / `userid-asc` (Member ID Oldest First) / `userid-desc` (Newest First) / `last_name_asc` / `last_name_desc` / `reviews` (Most Reviews First) / `random`. | |
| feature_categories | No | Comma-separated category list for this post type's `post_category` dropdown. Sending REPLACES the entire CSV (no per-item PATCH). Existing posts using categories not in the new CSV become orphans — pre-audit via `listSingleImagePosts property=post_category` before pruning. | |
| search_results_div | No | **CODE FIELD - search results LOOP** (HTML/CSS/JS/iframe/PHP; widget-equivalent trust; no input sanitization). Renders ONCE PER matching member in the results list. Supports PHP variables and `%%%text_label%%%` tokens. Part of the search-results code group (`category_header` + `search_results_div` + `category_footer`) - master-fallback on read + all-or-nothing save — see **Rule: Post-type code fields**. | |
| keyword_search_filter | No | Post Keyword Search Options. `level_2` = default fields only (faster). `level_3` = default + custom fields (slower; sites with many posts/custom fields can be significantly slower). Default on Member Listings: `level_3`. | |
| search_results_layout | No | **CODE FIELD - single-record detail page code** (HTML/CSS/JS/iframe/PHP; widget-equivalent trust). **Misleading name** - despite the `search_results_` prefix, this is the DETAIL page code for a single post record (BD's equivalent of WordPress `single.php`). Applies ONLY to post types with per-record detail pages (blog, event, coupon, property, product, etc.). **NOT applicable to Member Listings (`data_type=10`)** - members render via BD's core member profile system, not a post-type template. Do not send on Member Listings updates. Standalone - NOT in the profile triplet; saves independently. Uses master-fallback-on-read like other code fields. | |
| sidebar_search_module | No | Widget name for the search module inside the sidebar. Must match an existing widget on the site - not server-enforced, BD ships new ones in core releases. Common values: `Bootstrap Theme - Search Module - Keyword_Location` (Member Listings default), `No Search Module - None` (disables), `Bootstrap Theme - Search Module - Keyword Only`, `Bootstrap Theme - Search Module - Local Radius Search`, `Bootstrap Theme - Search Module - Top Category Only`, `Bootstrap Theme - Search Module - Top_Category_Location`, `Bootstrap Theme - Search Module - Top_Sub_Category`, plus Dynamic Category Filter set and post-search variants. If unsure which is valid on THIS site, enumerate via `listWidgets` and match by `widget_name`. Also: the `category_sidebar` chosen must contain the `Bootstrap Theme - Search Module - Dynamic Sidebar Search` host widget for the module to render. | |
| post_type_cache_system | No | Enable search-results cache. `1` = Yes (recommended; subsequent matching searches load faster). `0` = No (always query DB). **Cannot be `1` when `category_order_by=random`** - admin UI disables cache in that case; sending `post_type_cache_system=1` with `category_order_by=random` is an invalid combination. | |
| profile_results_layout | No | **CODE FIELD - profile/detail page BODY** (HTML/CSS/JS/iframe/PHP; widget-equivalent trust). Main detail-page template - BD's equivalent of WordPress `single.php`. **Misleading name** - NOT search-results layout; this is the DETAIL page for a single record. For Member Listings, this drives the member profile page. **Part of the profile code group** with `profile_header` + `profile_footer` - all-or-nothing save rule applies (send all three together when editing any of them) — see **Rule: Post-type code fields**. | |
| sidebar_position_mobile | No | Sidebar position on mobile devices ONLY (desktop uses `menu_layout`/page-level defaults). `top` = above results, `bottom` = below results (default), `hide` = do not render sidebar on mobile. | |
| enable_search_results_map | No | Display Google Map option at top of search results pages. `1` = Yes, show the map pin icon (default on Member Listings). `0` = No. Requires the Google Maps site feature to be enabled for the map itself to load. | |
| category_ignore_search_priority | No | When sorting members, respect Membership Plan 'Search Priority'? `0` = Yes (respect plan priority, default), `1` = No (ignore plan priority). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds extensive behavioral context beyond annotations: PATCH semantics with all-or-nothing saves, automatic cache refresh, master-fallback on GET, trust level for code fields, and destructive potential of certain changes. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-organized with sections and front-loaded critical info (cache refresh, required data_id, disambiguation). The repetitive opening 'Update a post type - Update a post type' is slightly inefficient, but overall structured given the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all necessary context: field groups, safe/unsafe mutations, special Member Listings rules, code edit workflow, _clear_fields mechanism, and return format. No output schema, but the return structure is documented. Exceptionally complete for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the description still adds rich semantics: code field group rules, Member Listings cheat-sheet and guardrails, trust levels, and workflow explanations. This goes far beyond the schema's brief descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update a post type' and provides specific actions like toggling active/inactive, renaming, changing display counts, etc. It distinguishes from siblings by mentioning related tools (getPostType, listPostTypes, deletePostType) and provides disambiguation rules.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly lists when to use the tool (e.g., toggling, renaming, editing search-results UI) and when not to (e.g., never mutate listed system fields). It provides alternatives (see also) and detailed guardrails for Member Listings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateRedirectAIdempotent
Update a redirect - Update an existing redirect record by ID. Fields omitted are untouched. Writes live data.
Use when: adjusting an existing rule's destination or source path. Rare - most redirects are create-once.
Required: redirect_id.
type is wrapper-managed: not exposed as an input. All redirects created via this MCP are custom; other BD type values are reserved for system-generated redirects.
See also: createRedirect (add new), deleteRedirect (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Legacy secondary identifier; typically 0 for system-generated redirects | |
| db_id | No | Database record ID of the source content object this redirect was generated from (0 if not tied to a record) | |
| redirect_id | Yes | Redirect primary key (required to identify record) | |
| new_filename | No | The new destination URL path | |
| old_filename | No | The old URL path being redirected from, relative to the domain root (e.g. old-slug, not the full URL) | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint=false, idempotentHint=true), the description adds key behaviors: 'Fields omitted are untouched', 'Writes live data', and explains that the 'type' field is wrapper-managed and always 'custom'. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bold headings and concise paragraphs. Every sentence adds value—no fluff. Front-loaded with the core action, then usage guidance, then parameter notes, and finally return info.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 6 parameters, no output schema, but annotations present, the description covers the core behavior, usage context, type management, and return format. It lacks an explicit mention of idempotency but that's already annotated. Very good completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds value by highlighting the required parameter (redirect_id) and explaining the special _clear_fields parameter behavior, which is not detailed in the schema. This helps an agent understand how to clear fields correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates an existing redirect by ID, with the distinctive behavior 'Fields omitted are untouched.' It distinguishes from sibling tools like createRedirect and deleteRedirect by specifying it updates an existing record.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'adjusting an existing rule's destination or source path' and notes it's rare. Provides alternatives: 'See also: createRedirect (add new), deleteRedirect (remove permanently).' This perfectly guides selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateReviewAIdempotent
Update a review - Update an existing review record by ID. Fields omitted are untouched. Writes live data.
Use when: moderating - change review_status (0=Pending -> 2=Accepted to publish, 3=Declined to reject, 4=Waiting for Admin). Also used for admin corrections of typos in review text.
Required: review_id.
Enums: review_status: 0=Pending, 2=Accepted, 3=Declined, 4=Waiting for Admin.
See also: createReview (add new), deleteReview (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| recommend | No | ||
| review_id | Yes | ||
| review_name | No | ||
| review_title | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| review_status | No | Review status (integer): - `0` = Pending (awaiting moderation) - `2` = Accepted (visible on profile) - `3` = Declined (rejected, not public) - `4` = Waiting for Admin (member pre-accepted, needs admin sign-off) Value `1` is NOT documented. BD does NOT reject it - stores `"1"` verbatim with undefined render behavior. Stick to documented values. Normal flow: `0` -> `2` (accepted) or `0` -> `3` (declined). | |
| rating_overall | No | ||
| rating_results | No | ||
| rating_service | No | ||
| rating_language | No | ||
| rating_response | No | ||
| rating_expertise | No | ||
| review_description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate not read-only and not destructive, but the description adds meaningful behavior: 'Writes live data' and 'Fields omitted are untouched' (partial update). It also discloses the return format. No contradictions with annotations, and the extra details about enum semantics add transparency beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with bold labels (Use when, Required, Enums, See also, Returns), making it scannable. Every section serves a purpose: use cases, required ID, enum reference, sibling tools, and return value. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite 13 parameters and no output schema, the description covers the key contextual needs: when to use, what the partial-update behavior is, what the review_status enums mean (including the undocumented value 1 caveat), and what the response will look like. Combined with annotations, it provides a complete operational picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is low (15%), so the description must compensate. It thoroughly explains review_status enums and notes required review_id, but the rating fields, recommend, and text fields are only implicit from the 'typos' use case. The partial-update note ('Fields omitted are untouched') provides general parameter behavior, but individual field meanings are not fully elaborated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Update an existing review record by ID' — a clear verb+resource pair. It distinguishes from siblings by explicitly mentioning createReview and deleteReview in 'See also', and the top line 'Update a review' makes the action unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use: 'Use when: moderating - change review_status... Also used for admin corrections of typos in review text.' It also provides alternatives via 'See also: createReview (add new), deleteReview (remove permanently)', giving clear when-to-use vs alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateSingleImagePostAIdempotent
Update a post - Update an existing post record by ID. Fields omitted are untouched. Writes live data.
Use when: editing post content, switching from draft to published (post_status=0->1), updating post title/caption, or correcting post metadata. To move a post to a different post type (rare), pass data_id - but validate the new post type is still in the single-image family.
Required: post_id.
Enums: post_status: 0=Draft (saved but not publicly visible), 1=Published (publicly visible on the site).
post_title rename does NOT update post_filename (the URL slug). post_filename is writable — see Rule: URL slug rename for when to suggest a slug update + redirect. Report post_filename from getSingleImagePost when giving the user a URL.
See also: createSingleImagePost (add new), deleteSingleImagePost (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | ||
| lon | No | ||
| post_id | Yes | ||
| post_job | No | Employment type - Job post types only. | |
| post_url | No | Explicit CTA button link rendered under the feature image on the post-detail page. Use when the owner wants a prominent button. Full `http(s)://` URL. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_url`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post. | |
| state_sn | No | ||
| post_tags | No | Comma-separated keywords for the post. | |
| country_sn | No | ||
| post_image | No | Feature image URL. **LANDSCAPE only — verify orientation via `getImageDimensions` per **Rule: Image dimensions** before commit; bare URL, no `?query`, must end in `.jpg`/`.jpeg`/`.png` (WebP/GIF/AVIF skipped pre-tool per the same rule) — see **Rule: Image URLs**.** Query strings (`?w=1600`, `?auto=compress`) get baked into the imported filename and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| post_price | No | ||
| post_promo | No | Twin of post_price (job pay, event ticket price, coupon price — live-verified on jobs and events). BD requires post_promo to populate post_price — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null. | |
| post_title | No | ||
| post_venue | No | Event/post venue name/landmark where the event is held (e.g. `Staples Center`) - distinct from `post_location` (the street address). Free text. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_venue`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post. | |
| post_video | No | YouTube/Vimeo URL - Video post types only. | |
| post_status | No | 0=Not Published, 1=Published, 3=Pending Approval (rare — set when site admin requires manual moderation before posts go live). | |
| auto_geocode | No | Set to `1` to geocode the post's location. Requires the "Pretty URLs with Google Maps" site feature. | |
| post_caption | No | Deprecated. Leave unset unless user explicitly references it. | |
| post_content | No | Post body HTML. Froala body field — see **Rule: Post-body formatting** (structure, `fr-dib fr-fil`/`fr-fir` float + inline `width: 350px`, landscape Pexels images). | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| post_category | No | Per-post-type dropdown value, configured in BD admin on the post type's `feature_categories` field. Discover allowed values from `feature_categories` on your `listPostTypes`/`getPostType` result, or `getPostTypeCustomFields.post_category.choices` where your workflow routes through it - NOT from `getSingleImagePostFields.post_category.choices` (BD fills that from platform master defaults on some forms). Pass VERBATIM - BD does not trim whitespace, so leading spaces after commas in `feature_categories` persist in the stored option values. | |
| post_filename | No | Public URL slug path (e.g. `blog/my-post-slug`). Writable — BD does NOT regenerate the slug when `post_title` changes. See **Rule: URL slug rename** for when to suggest a slug update + redirect. | |
| post_location | No | Full or partial street address (Event/Coupon/Job/geo-enabled post types). | |
| post_live_date | No | Creation date stored on the post. Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. | |
| post_meta_title | No | ||
| post_start_date | No | Scheduled publish date — when the post becomes visible on the public site. Set a future timestamp to schedule (like WordPress's future-publish); set a past timestamp for immediate visibility. REQUIRED on Event post types (marks when the event begins); optional but commonly used on blog/article/news post types for scheduled publishing. Format: `YYYYMMDDHHmmss`. **Event post types: event-local wall-clock** — the time as a visitor in the event's city would read it; do NOT convert to the site's own timezone (a 7 PM Brooklyn event on a Los Angeles-timezoned site stores as `20260616190000`). **Scheduled-publish on blog/article/news types: site timezone.** BD silently truncates other formats, corrupting the value. The wrapper auto-derives `start_time` (`"H:MM AM/PM"`) from this value on `createSingleImagePost` / `updateSingleImagePost` so BD's form-edit time-of-day dropdown stays populated — agent never passes `start_time` directly. | |
| post_expire_date | No | End/expiration date. Coupon post types use this for expiration; Event post types use it for end time. Format: `YYYYMMDDHHmmss`. **Event post types: event-local wall-clock** (match `post_start_date`). **Coupons and other post types: site timezone.** BD silently truncates other formats, corrupting the value. The wrapper auto-derives `end_time` (`"H:MM AM/PM"`) from this value on `createSingleImagePost` / `updateSingleImagePost` — agent never passes `end_time` directly. | |
| auto_image_import | No | **Auto-import images to site storage.** Set `1` when any external image URL field on this single-image post (e.g. `post_image`) holds a URL - BD fetches the image and saves locally. Without the flag, BD stores the URL as-is; images break if source host goes down. **Recommended default when supplying external image URLs**; omit or set `0` only if user explicitly wants the external URL reference. Supports JPG/PNG/GIF/WebP/SVG. Processing delay: several minutes. | |
| post_meta_keywords | No | ||
| post_meta_description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotentHint=true and destructiveHint=false. The description adds valuable behavioral details: 'Fields omitted are untouched', 'Writes live data', the note that post_title rename does not update the slug, the behavior of _clear_fields, and timezone rules for dates. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with clear sections (summary, use when, required, enums, behaviors, see also, returns). It is front-loaded with essential purpose. While verbose, every sentence adds value; a very minor deduction for length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high complexity (29 parameters, no output schema), the description is exceptionally complete. It explains the return format, cross-references other rules and tools (e.g., 'Rule: URL slug rename', 'getSingleImagePost'), and covers edge cases like timezones and clearing fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 66% schema coverage, the description adds significant meaning for many parameters: post_image requirements (landscape orientation, URL format, auto_import), post_promo relationship (must send both), post_category discovery via other tools, _clear_fields special behavior, date formats and timezone rules, and more. This compensates for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'update' and the resource 'post', and specifies that it updates an existing post record by ID. It differentiates from siblings like createSingleImagePost and deleteSingleImagePost by stating 'Update an existing post record' and referencing them in 'See also'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly lists when to use the tool: 'editing post content, switching from draft to published, updating post title/caption, or correcting post metadata.' It also provides exclusion context: moving to a different post type is rare and requires validation via data_id. Additionally, it references sibling tools for creation and deletion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateSmartListAIdempotent
Update a smart list - Update an existing smartlist record by ID. Fields omitted are untouched. Writes live data.
Use when: editing the filter criteria or schedule on a saved list.
Required: smart_list_id.
See also: createSmartList (add new), deleteSmartList (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| schedule | No | Recurrence frequency | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| smart_list_id | Yes | ||
| smart_list_name | No | ||
| smart_list_modified_by | No | ||
| smart_list_query_params | No | Filter criteria — format depends on `smart_list_type`: - **newsletter** - pass a URL string (used directly as `href`) - **all other types** (members, leads, reviews, transaction, forms_inbox) - pass a JSON string of key-value filter pairs like `{"subscription_id":"1","active":"1"}` - **no filters** - pass `"NA"` Backend encrypts internally - do NOT pre-encrypt client-side. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint=true, destructiveHint=false, and openWorldHint=true. The description adds 'Writes live data' and 'Fields omitted are untouched', which are useful behavioral insights beyond what annotations offer. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise with 3 sentences plus bullet points for 'Use when', 'Required', 'See also', and 'Returns'. Information is front-loaded and every sentence adds value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema, the description includes the return format. It covers the required parameter, partial update behavior, and usage context. However, it does not mention error handling or rate limits, which would be helpful for completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50% (3 of 6 parameters have descriptions). The description adds the important note that 'Fields omitted are untouched' and highlights the required smart_list_id. However, it does not add detailed semantics for the remaining parameters beyond what the schema already provides, so it only partially compensates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Update a smart list' and clearly states it updates an existing record by ID. It distinguishes from siblings by explicitly mentioning createSmartList and deleteSmartList in the 'See also' section.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a 'Use when' section that states 'editing the filter criteria or schedule on a saved list', and a 'See also' section that names createSmartList (add new) and deleteSmartList (remove permanently), providing clear context for when to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateStateAIdempotent
Update a state (corrections only) - Update a state row. Read-mostly - use for corrections. Fields omitted are untouched (PATCH semantics - only send what you want to change).
Required: location_id.
Warning on state_filename: it's the URL slug in every search page using this state. Rename -> broken URLs + orphaned SEO pages. Create redirects if you must.
| Name | Required | Description | Default |
|---|---|---|---|
| state_ln | No | ||
| state_sn | No | ||
| country_sn | No | ||
| location_id | Yes | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| state_filename | No | URL slug. Rename breaks inbound URLs - create redirects. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=true), the description adds key behaviors: PATCH semantics ('Fields omitted are untouched'), the warning about state_filename breaking URLs, and the 'corrections only' nature. These details help the agent understand side effects and safe usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with purpose. It uses clear formatting with bold and warning. The only redundancy is 'Update a state (corrections only) - Update a state row.' Overall, it is well-structured and free of unnecessary text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 6 parameters, annotations, and no output schema, the description covers purpose, PATCH semantics, required field, and a critical warning. It misses guidance on usage relative to siblings and detailed field meanings, but for a PATCH update tool, it is reasonably complete and actionable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds PATCH semantics (fields omitted untouched) and warns about state_filename, which adds value beyond the schema. However, with only 33% schema description coverage, other parameters (state_sn, state_ln, country_sn) lack explanation in the description. The baseline is 3 due to low coverage, and the description partially compensates but not fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update a state (corrections only) - Update a state row.' This specifies the verb (update) and resource (state), and adds 'corrections only' to distinguish from general updates. The purpose is unambiguous and differentiates from sibling update* tools for other resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Read-mostly - use for corrections' and warns about state_filename renaming, implying when to use (corrections) and what to avoid (renaming without redirects). However, it does not explicitly state when not to use this tool or suggest alternatives, leaving room for improvement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateSubCategoryAIdempotent
Update a service - Update an existing SUB-level member category by service_id. Fields omitted are untouched. Writes live data.
Use when: renaming, re-parenting (change profession_id to move under a different Top, or master_id to re-nest as sub-sub), or adjusting lead_price for per-service lead pricing.
Required: service_id.
Filename rename caveat: if the existing filename has a seo_type=profile_search_results web page bound to it, renaming this category orphans that page. The wrapper rejects renames that would orphan a bound page — rename or delete the bound page first, then rename the category.
Parameter notes:
Change
profession_idto move this Sub Category to a different parent Top CategoryChange
master_idto re-nest as a sub-sub-category (non-zero) or flatten to direct-under-Top (0)
See also: createSubCategory (add new), deleteSubCategory (remove).
Returns: { status: "success", message: {...updatedRecord} }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| desc | No | Short internal taxonomy-row label. **Even if the user says "description" - this is NOT an SEO description.** Not a meta-tag surface, not Google-ranking copy, not the H1/intro on the public category search page. Most BD themes don't render this field. For ANY SEO task on a category or sub-category - "write a description that ranks," "improve SEO," "add meta tags," "write intro copy" - create a WebPage with `seo_type=profile_search_results` and the matching slug instead (see `createWebPage`). Short internal blurb only here. | |
| name | No | ||
| filename | No | URL slug. Renaming orphans any `seo_type=profile_search_results` web page bound to the OLD filename — that page can't query this category anymore and renders empty. Before renaming, run `listWebPages property=filename property_value=<old-filename>`; if a profile_search_results page exists, rename it in the same operation (and consider `createRedirect` for SEO continuity). | |
| keywords | No | Fuzzy-search synonyms for on-site category matching - NOT SEO meta-keywords. Comma-separated single words (no spaces): synonyms, abbreviations, slang, common misspellings. Example for `Doctor`: `doc,physician,md,medic,gp,specialist`. ~5-10 max. Skip SEO phrases like `doctor near me` - those aren't fuzzy matchers. Optional. | |
| master_id | No | ||
| lead_price | No | ||
| service_id | Yes | ||
| sort_order | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| profession_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that it writes live data, fields omitted are untouched, and provides a critical caveat about filename renaming orphaning web pages. It also states the return format. This adds valuable context beyond the annotations, which already mark it as read-only false and idempotent true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with clear sections (Use when, Required, Parameter notes, etc.), but it is somewhat lengthy, including tangential information about how members are classified and a note about tool naming. Every part is useful, but slight trimming could improve conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers update behavior, return format, related tools, and important caveats. It includes a sub-sub-category explanation. However, it does not detail all 10 parameters individually (e.g., sort_order, keywords from schema, name). Overall, it provides sufficient context for most use cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning for several parameters: profession_id (re-parenting), master_id (sub-sub-category nesting), filename (rename caveat), and lead_price (per-service pricing). However, it omits explanations for sort_order and name, and schema coverage is only 40%. Still, it compensates well for the low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it updates a SUB-level member category by service_id, with specific actions like renaming, re-parenting, and adjusting lead_price. It also distinguishes itself from create and delete siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a 'Use when:' section with explicit scenarios, a 'See also:' pointing to createSubCategory and deleteSubCategory, and a note clarifying that there is no createProfession or createService tool, guiding users to correct alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateTagAIdempotent
Update a tag - Update an existing tag record by ID. Fields omitted are untouched. Writes live data.
Use when: renaming a tag without losing the tag-to-member relationships.
Required: id.
updated_by is wrapper-managed: the audit-trail updated_by field is hardcoded to 0 by the wrapper on every update. Not exposed as an input.
See also: createTag (add new), deleteTag (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| tag_name | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds behavioral details beyond annotations: 'Fields omitted are untouched', 'Writes live data', and the wrapper-managed audit-trail field. Annotations already indicate idempotent and non-destructive, but description enriches understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with a clear header, bullet points, and front-loaded information. It is efficient without being overly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all necessary aspects: purpose, usage, parameters, return value, and special behaviors like wrapper-managed fields and clearing mechanism. Complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Low schema description coverage (33%) is compensated by description explaining 'id' as required, 'tag_name' as optional, and detailed behavior of '_clear_fields'. Adds context beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update a tag' and explains it updates an existing tag record by ID. It distinguishes itself from siblings by mentioning createTag and deleteTag in 'See also'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance with 'Use when: renaming a tag without losing tag-to-member relationships.' Also specifies required parameter 'id' and mentions wrapper-managed 'updated_by' field.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateTagGroupAIdempotent
Update a tag group - Update an existing taggroup record by ID. Fields omitted are untouched. Writes live data.
Use when: renaming a tag group.
Required: id.
See also: createTagGroup (add new), deleteTagGroup (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| group_tag_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description adds context beyond annotations: 'Fields omitted are untouched' clarifies idempotent behavior, 'Writes live data' aligns with readOnlyHint=false, and return format is detailed. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, well-structured with 'Use when:', 'Required:', 'See also:', and 'Returns:' sections. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage guidance, required fields, behavioral traits, return format, and special parameter details. Lacks explanation of group_tag_name, but overall sufficient for a 3-parameter tool with annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only 33% schema coverage, but description compensates by explaining the _clear_fields mechanism and partial update behavior. However, group_tag_name parameter lacks any description in schema or text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Update' and the resource 'tag group', and distinguishes from siblings like createTagGroup and deleteTagGroup by mentioning them in 'See also'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when:' guidance (renaming a tag group) and lists required parameter 'id'. 'See also' mentions alternatives. However, it could be more explicit about when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateTagRelationshipAIdempotent
Update a tag relationship - Update an existing tagrelationship record by ID. Fields omitted are untouched. Writes live data.
Use when: adjusting a tag-relationship record's metadata.
Required: id.
See also: createTagRelationship (add new), deleteTagRelationship (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| object_id | No | Primary key of the record being tagged. Which table it lives in depends on tag_type_id - look up via listTagTypes. For tag_type_id=1 (Users), object_id is a user_id from users_data. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses 'Writes live data', 'Fields omitted are untouched', and the exact return format. Annotations indicate idempotent and open world; description adds operational context without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise yet comprehensive: uses bold headers, single sentences for each section, no fluff. Every sentence provides value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, it explicitly describes the return format. Covers required param, optional params behavior, and complex clearing rule. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning beyond schema: describes _clear_fields behavior in detail (e.g., must use to clear fields, works on EAV rows), and notes that omitted fields remain untouched. Schema coverage is 67% but description compensates fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update a tag relationship' and specifies 'Update an existing tagrelationship record by ID', distinguishing it from createTagRelationship and deleteTagRelationship mentioned in 'See also'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: adjusting a tag-relationship record's metadata', lists required param 'id', and provides alternative tools via 'See also'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateTopCategoryAIdempotent
Update a category - Update an existing TOP-level member category by profession_id. Fields omitted are untouched. Writes live data.
Use when: renaming a category, changing its URL slug (filename), updating SEO keywords, or reordering. Changing filename breaks inbound links - also create a Redirect via createRedirect to preserve SEO.
Required: profession_id.
Filename rename caveat: if the existing filename has a seo_type=profile_search_results web page bound to it, renaming this category orphans that page. The wrapper rejects renames that would orphan a bound page — rename or delete the bound page first, then rename the category.
See also: createTopCategory (add new), deleteTopCategory (remove).
Writes live data: changes are immediately visible on the public site.
Returns: { status: "success", message: {...updatedRecord} }.
How a member gets classified on their public profile:
users_data.profession_id-> points at a single Top Category (the member's primary classification; shown in URL slug)users_data.services-> CSV of Sub Category IDs the member is tagged with (multiple allowed; simpler than the join table)rel_servicesrows (Member ↔ Sub Category links) -> used when you need per-link metadata likeavg_price,specialty,num_completed. Optional; most sites use just the CSV field.
Sub-sub-categories: createSubCategory with master_id=<parent service_id> creates a Sub Category nested under another Sub Category (a "sub-sub"). master_id=0 (default) means the Sub Category sits directly under a Top Category (the profession_id).
There is NO createProfession or createService tool in this MCP — those are BD's internal table names. Use createTopCategory / createSubCategory instead (BD's table-name → tool-name mapping is documented in Rule: Table to endpoint).
| Name | Required | Description | Default |
|---|---|---|---|
| desc | No | Short internal taxonomy-row label. **Even if the user says "description" - this is NOT an SEO description.** Most BD themes don't render this field. For SEO copy on the Top-Category public search page (H1, intro, meta tags), create a WebPage with `seo_type=profile_search_results` + matching slug (see `createWebPage`). Short internal blurb only here. | |
| icon | No | ||
| name | No | ||
| image | No | ||
| filename | No | URL slug. Renaming orphans any `seo_type=profile_search_results` web page bound to the OLD filename — that page can't query this category anymore and renders empty. Before renaming, run `listWebPages property=filename property_value=<old-filename>`; if a profile_search_results page exists, rename it in the same operation (and consider `createRedirect` for SEO continuity). | |
| keywords | No | Fuzzy-search synonyms for on-site category matching - NOT SEO meta-keywords. Comma-separated single words (no spaces): synonyms, abbreviations, slang, common misspellings. Example for `Doctor`: `doc,physician,md,medic,gp,specialist`. ~5-10 max. Skip SEO phrases like `doctor near me` - those aren't fuzzy matchers. Optional. | |
| lead_price | No | ||
| sort_order | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| profession_id | Yes | The top-level category ID to update (from createTopCategory / listTopCategories). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses live data writing, filename rename caveat (orphaning pages, rejection), and that fields omitted are untouched. No contradiction with annotations (idempotentHint=true, destructiveHint=false, readOnlyHint=false). Adds critical behavioral context beyond structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and front-loaded key points. Some repetition in explaining classification and subcategories could be condensed, but each part adds value. Efficient use of space given complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers return format, required fields, caveats, parameter details, and even background on member classification. No output schema, but return format is specified. Thorough for a 10-parameter mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds significant meaning for key parameters (filename with URL slug and SEO impact, desc as internal label, keywords as fuzzy synonyms, _clear_fields with clearing rules). For parameters without schema descriptions (name, icon, etc.), no extra detail, but overall compensation is high. Schema coverage 50% is adequately supplemented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (update), resource (top-level member category), and key behavior (fields omitted are untouched, writes live data). It distinguishes from sibling tools like createTopCategory and deleteTopCategory.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' scenarios, required parameter (profession_id), caveats about renaming filename and orphaning pages, and references to related tools. Clear guidance on when to use and when not to.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateUnsubscribeAIdempotent
Update an unsubscribe record - Update an existing unsubscribe record by ID. Fields omitted are untouched. Writes live data.
Use when: editing an unsubscribe record. Rare.
Required: id.
Enums: definitive: 0, 1.
See also: createUnsubscribe (add new), deleteUnsubscribe (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| definitive | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover idempotentHint and openWorldHint. Description adds valuable context: 'Fields omitted are untouched', 'Writes live data', return format, and detailed _clear_fields behavior. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear headings (Use when, Required, Enums, See also, Returns). No wasted words, front-loaded purpose, every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given openWorldHint and no output schema, description covers behavior (untouched fields, live data), return format, and clearing fields. References related tools. Complete for this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (33%). Description clarifies required id and definitive enum values, but mostly repeats schema description for _clear_fields. Does not add new information about other potential parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Update an unsubscribe record' with specific verb and resource. Distinguishes from siblings like createUnsubscribe and deleteUnsubscribe.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when: editing an unsubscribe record. Rare.' and provides 'See also:' with alternative tools. Includes required parameter id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateUserAIdempotent
Update an existing member/user - Update a member. PATCH semantics - omitted fields untouched; send only what changes.
Required: user_id.
Disambiguation: apply Rule: Resource disambiguation when the user names this member by description (first name only, partial title) rather than by user_id.
Use when: changing any field on an existing member. Prefer active=3 (Canceled) over deleteUser - reversible.
Enums: active: 1=Not Active, 2=Active, 3=Canceled, 4=On Hold, 5=Past Due, 6=Incomplete. listing_type: Individual, Company. verified/nationwide: 1/0.
Parameter interactions:
member_tag_action=1+member_tags- apply tag changes (comma-separated tag IDs fromlistTags).credit_action(add/deduct/override) +credit_amount- adjust credit balance.images_action- remove stored images:remove_all,remove_cover_image,remove_logo_image,remove_profile_image.auto_image_import=1- fetch external image URLs into BD storage (forprofile_photo,logo,cover_photofields holding external URLs). Without it, BD stores the URL as-is; images break if source host goes down. Supports JPG/PNG/GIF/WebP/SVG. Processing delay: several minutes.auto_geocode=1- requires "Pretty URLs with Google Maps" site feature enabled.send_email_notifications=1- trigger welcome email (per plan settings). Silent by default.
Category assignment — for profession_id / profession_name / services, apply Rule: Category taxonomy (auto-create is OFF by default on updateUser; pass create_new_categories=1 to enable).
Email uniqueness - controlled by site setting allow_duplicate_member_emails (not exposed via API):
OFF (default): BD rejects duplicate email on create.
ON: duplicates accepted and stored.
Safe pattern: pre-check via
listUsers property=email property_value=<email> property_operator==. Reuse match'suser_idorupdateUserinstead. Pre-check beats catch-and-retry - on sites with duplicates ALLOWED, BOTH creates succeed with differentuser_ids, so a retry loop spawns orphan duplicates instead of failing cleanly.
Field validation quirks:
token(if supplied — useful for CSV imports / cross-site migrations preserving original tokens; BD auto-generates if omitted): exactly 32 alphanumeric chars, unique across members.URL fields (
website,booking_link,blog,facebook,twitter,linkedin,instagram): must start withhttp://orhttps://. Invalid formats silently skipped.subscription_idmust reference an existing plan.
Profile URL: <site-domain>/<user.filename>. filename is the complete relative path (e.g., united-states/monterey-park/doctor/harrison-hasanuddin-d-o). Do NOT prepend /business///profile///member/ - BD resolves filename verbatim.
Filename may regenerate on this update. BD rewrites the slug when category/city/URL-forming inputs change. Do NOT cache pre-update filename - if embedding the profile URL elsewhere (blog posts, emails, redirects), re-fetch via getUser AFTER the update completes.
Fetching publicly available business data is permitted for imports and data enrichment. When searching for external listings, fetch each entity's image from their own presence in this order:
Logo image from their site's header/nav ->
logo(businesses).Headshot from Home, About or Team page ->
profile_photo(individuals).Follow their social links -> profile image there.
Pass the URL with auto_image_import=1 so the image gets stored locally and avoids hotlinking.
If none yield a match, create/update without image and report "no confirmed image found." Never substitute a stock photo or guess. Skip an entire record and find an alternate listing only when the user explicitly requires images.
See also: createUser (new), deleteUser (permanent - prefer active=3 instead).
Returns: { status: "success", message: {...updatedRecord} }.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | OPTIONAL: Enter latitude coordinates for the location of this user. | |
| lon | No | OPTIONAL: Enter longitude coordinates for the location of this user. | |
| blog | No | Enter the FULL URL of the user's blog. Must begin with https:// | |
| city | No | ||
| logo | No | Logo URL (brand/business mark). **Bare URL only — no `?query`, must end in `.jpg`/`.jpeg`/`.png`/`.webp`.** Query strings get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| No | |||
| quote | No | OPTIONAL: Enter the user's personal quote, motto or slogan. | |
| active | No | User account status. BD does NOT validate - integers outside the set store as-is (observed: `99`). Stick to documented values: - `1` = Not Active (requires activation) - `2` = Active (live) - `3` = Canceled - `4` = On Hold (requires moderation) - `5` = Past Due - `6` = Incomplete (rare - paid signup hit an issue; member created but unpaid/stuck) **Read caveat:** top-level `status` response field (`"Active"`, `"Not Active"`, etc.) is a computed label. When `active` is an unknown value, `status` is OMITTED from the response - don't treat `status` as always-present. | |
| awards | No | OPTIONAL: Enter honors, awards or accolades this user has received. | |
| tiktok | No | Enter the FULL URL of the user's Tiktok account. Must begin with https:// | |
| company | No | ||
| No | Enter the FULL URL of the user's Twitter account. Must begin with https:// | ||
| user_id | Yes | ||
| website | No | Enter the FULL URL of the user's website. Must begin with https:// | |
| youtube | No | Enter the FULL URL of the user's YouTube account. Must begin with https:// | |
| about_me | No | Long description of the member/user. Renders on their public profile. Froala body field — use `<p>`/`<h2>`/`<h3>`/`<ul>`/`<ol>` structure; skip images unless user asks. HTML allowed (per universal safe-HTML rule). | |
| address1 | No | The user's street address. | |
| address2 | No | The user's unit or suite number. | |
| No | Enter the FULL URL of the user's Facebook account. Must begin with https:// | ||
| filename | No | Override BD's auto-generated URL slug. **Usually OMIT** - let BD derive. BD may REGENERATE the slug on future updates (when city/category/name change), silently overwriting your override. Only set if you must control the public URL and will re-set it after every future update. | |
| No | Enter the FULL URL of the user's Linkedin account. Must begin with https:// | ||
| position | No | OPTIONAL: Enter the user's position, title or role at their company. Example: Account Executive | |
| services | No | Sub-categories for this member. Formats: `category=>service1,service2` OR `service1,service2` (top category defaults to member's current `profession_id`). Supports sub-sub-categories via `Parent=>Child` (e.g. `Honda=>2022,Honda=>2023,Toyota`). Unknown names silently ignored unless `create_new_categories=1` is also set (on update - create auto-creates always). **Additive by default** — these links are ADDED to the member's existing ones. To REPLACE the whole set instead, pass `delete_categories=1` in the same call. **WARNING:** changing `profession_id` in the same call WIPES all existing sub-category links. Re-send the full `services` list to preserve them. | |
| snapchat | No | Enter the FULL URL of the user's Snapchat account. Must begin with https:// | |
| state_ln | No | OPTIONAL: Enter the full name of the state / province for this user. | |
| verified | No | If YES, a verified icon badge will display on the user's listing.\n\nValid values:\n 1 = Yes\n 0 = No | |
| No | Enter the FULL URL of the user's Whatsapp account. Must begin with https:// | ||
| zip_code | No | The user's zip / postal code. | |
| No | Enter the FULL URL of the user's Instagram account. Must begin with https:// | ||
| last_name | No | ||
| No | Enter the FULL URL of the user's Pinterest account. Must begin with https:// | ||
| country_ln | No | OPTIONAL: Enter the full name of the country for this user. | |
| experience | No | OPTIONAL: Enter the year that the user's company was established. Example: 1982 | |
| first_name | No | ||
| last_login | No | Timestamp of user's last login. Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. BD updates on each login — omit unless backfilling historical data during import/migration. | |
| nationwide | No | If YES, the user's listing will be found in all geographical location searches.\n\nValid values:\n 1 = Yes\n 0 = No | |
| state_code | No | ||
| affiliation | No | OPTIONAL: Enter the accepted forms of payment this user accepts. | |
| cover_photo | No | Cover photo URL (user/profile banner). Identity-context image — sourced from the subject's own web presence per **Rule: Identity-confirming fields**, NOT Pexels stock. **Bare URL only — no `?query`, must end in `.jpg`/`.jpeg`/`.png`/`.webp`.** Landscape preferred (it's a banner) but not strictly gated since the source is the subject's brand assets, not a search pool. Query strings get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| member_tags | No | Comma-separated tag IDs to assign to the member (e.g. `1,2,3`). Discover via `listTags`. **Requires `member_tag_action=1` to take effect.** **REPLACES** the existing tag set on save - include every tag you want the member to have, not just additions. Unknown tag IDs are silently dropped - response echoes your submitted value, but `tags` array in the response reflects only successfully-attached tags. Re-GET after update and verify `tags` array. | |
| rep_matters | No | OPTIONAL: Enter the hours of operation for the member. EG: Monday - Friday, 9am - 5pm | |
| signup_date | No | User signup date. Format: `YYYYMMDDHHmmss` in the site's timezone. BD silently truncates other formats, corrupting the value. BD auto-fills on create — omit unless backfilling legacy signup dates during import/migration. | |
| auto_geocode | No | Use Google Maps to geocode this user's location. Requires the "Pretty URLs with Google Maps" feature to be enabled on the site. (string, "1" or "0").\n 1 = Yes\n 0 = No | |
| booking_link | No | Enter the FULL URL of the user's booking page. Must begin with https:// | |
| country_code | No | ||
| listing_type | No | Listing type classification. **BD does NOT validate this field - any string is stored verbatim.** Canonical values (exact case): `Individual` or `Company`. On `updateUser`, include only when reclassifying an existing member (e.g. fixing a record originally created as `Individual` that should be `Company`). If including, normalize case client-side - `individual` or other off-canonical casings will store as-is and break downstream logic. Otherwise omit to preserve the current value. | Company |
| phone_number | No | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| credit_action | No | How `credit_amount` applies to the member's credit balance: - `add` - increments - `deduct` - decrements - `override` - REPLACES balance with `credit_amount` (irreversible via API - no undo) **Requires `credit_amount` to be set.** Omit both fields to leave credits unchanged. BD does NOT reject deducts/overrides that produce negative balance. If non-negative required, validate client-side against current `credit_balance` (dollar-formatted string, may be negative) before calling. | |
| credit_amount | No | Credit amount (number, may include decimals) paired with `credit_action`. Meaning depends on the action: for `add` and `deduct` it's the delta; for `override` it's the new absolute balance. Ignored if `credit_action` is not set. | |
| images_action | No | Removes stored member images. PERMANENT via API - no undo. - `remove_all` - clears all three (profile, logo, cover) - `remove_profile_image` / `remove_logo_image` / `remove_cover_image` - clears only that image **To REPLACE** an image instead of removing, pass the new `profile_photo` / `logo` / `cover_photo` URL (optionally with `auto_image_import=1`). Do NOT set `images_action` for replacement. | |
| profession_id | No | Assign this user to a top level category. Input the ID number of the top level category. | |
| profile_photo | No | Profile photo URL (member headshot). **Bare URL only — no `?query`, must end in `.jpg`/`.jpeg`/`.png`/`.webp`.** Query strings get baked into imported filenames and 404. Pair with `auto_image_import=1` to fetch externals into site storage. | |
| profession_name | No | Alternative to `profession_id` - pass the top-level category NAME as a string. BD looks it up in `list_professions`. **Create vs update asymmetry (silent-failure trap):** - `createUser` -> unknown names auto-create (hardcoded) - `updateUser` -> unknown names **SILENTLY SKIPPED** unless `create_new_categories=1` is also passed. The write succeeds and returns success; the category just doesn't change. Always pass `create_new_categories=1` on update when supplying a `profession_name` that might not exist. | |
| subscription_id | No | ||
| auto_image_import | No | If YES, system will import user images and save them to your website. Processing may take several minutes after import.\n\nValid values:\n 1 = Yes\n 0 = No | |
| delete_categories | No | Set `1` to wipe ALL the member's sub- and sub-sub-category links (every `rel_services` row) BEFORE applying any `services` in the same call — turns `services` from append into replace. Does NOT remove the top-level category (`profession_id`) or any `list_services` definitions. Without it, `services` is additive. Combine with `services` (and `create_new_categories=1` for unknown names) to replace the member's entire sub-category set in one call. `updateUser` only. | |
| member_tag_action | No | **REQUIRED when modifying tags.** Set `1` alongside `member_tags` to apply the change - without this flag, `member_tags` value is ignored. **REPLACES** the current tag set (not additive): tag IDs NOT in `member_tags` are removed. To clear all tags, pass empty `member_tags` with `member_tag_action=1`. | |
| search_description | No | Short description shown under the user's name on search result pages. **170-char limit.** | |
| create_new_categories | No | Set `1` to auto-create unknown category names on `updateUser`. Without it, unknown names in `services`/`profession_name` are silently skipped. **No effect on `createUser`** (always auto-creates). Creates whatever level the name references: top-level via `profession_name`, sub via `services`, and sub-sub inline via the `Sub=>SubSub` format in `services` (no separate `createSubCategory` call needed). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description extensively discloses behavioral traits beyond annotations, such as PATCH semantics, filename regeneration, email uniqueness controlled by site settings, field validation quirks, parameter interactions (e.g., member_tag_action, credit_action), and processing delays. This adds significant value beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with sections, bullet points, and bold headings. It front-loads the core purpose and then provides detailed specifics. While it could be slightly more concise, the length is justified by the tool's complexity (60 parameters, many edge cases).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high parameter count, lack of output schema, and complex interactions, the description is remarkably complete. It covers return format, parameter interactions, validation quirks, disambiguation rules, and references external rules. No major gaps are present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 83% schema description coverage, the description adds substantial meaning by explaining parameter interactions, edge cases (e.g., profession_name silent failure), formatting requirements (e.g., URL fields, token), and behavioral nuances (e.g., additive vs. replace semantics for tags and categories). This goes well beyond the input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Update an existing member/user' with PATCH semantics, explicitly distinguishing from createUser (new) and deleteUser (permanent). It identifies the specific verb and resource, and differentiates from siblings by mentioning alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool ('Use when: changing any field on an existing member') and when not to ('Prefer active=3 (Canceled) over deleteUser - reversible'). It also includes a safe pattern for email uniqueness pre-check, offering clear context and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateUserMetaAIdempotent
Update a metadata record - Update an existing users_meta record's value by meta_id. Fields omitted are untouched. Writes live data.
IDENTITY RULE - (database, database_id) is ONE atomic compound identity, not two fields. ALWAYS confirm BOTH match the intended parent BEFORE updating. A users_meta row's identity is (database, database_id, key). The same numeric database_id routinely belongs to UNRELATED rows on different parent tables. Never use a meta_id blindly from an unscoped list - always either (a) getUserMeta(meta_id) first and inspect database+database_id, OR (b) obtain the meta_id from a listUserMeta whose results have been CLIENT-SIDE filtered to the intended database+database_id pair. Misidentifying a row silently overwrites unrelated resource metadata.
Use when:
Changing a metadata value on any BD table row that was previously created via
createUserMeta.For
list_seo(web page) EAV fields, useupdateWebPagedirectly — the wrapper auto-routes them throughusers_metafor you. ThisupdateUserMetaendpoint is for changing existing values on OTHER BD tables (e.g.users_data,subscription_types,data_postscustom meta), or for the rare case where alist_seoEAV field doesn't persist afterupdateWebPage— file that as a wrapper bug rather than working around it here.
Workflow: find the meta_id by calling listUserMeta with filter database=<table>, database_id=<parent_id>, key=<field>. Then call this endpoint with meta_id, value, and the same database + database_id you used for lookup. If no row exists, the row cannot be created via this endpoint — see Rule: users_meta writes. Never guess meta_id; 404 = stop, not retry.
Required: meta_id, value, database, database_id. All four - always. The identity pair (database, database_id) is enforced at the schema level to prevent cross-table corruption.
See also: listUserMeta (find the meta_id by filter), deleteUserMeta (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | ||
| meta_id | Yes | ||
| database | Yes | **REQUIRED** - parent table name this meta row attaches to (e.g. `list_seo`, `users_data`, `subscription_types`, `data_posts`). MUST match the `database` value stored on the row being updated. Hard safety rule: the same `database_id` number can exist across multiple parent tables. Scoping with `(database, database_id)` together prevents cross-table metadata corruption. See **Rule: users_meta identity**. | |
| database_id | Yes | REQUIRED - PK of the parent record this meta row is attached to. MUST match the `database_id` value stored on the row being updated. Same safety rule as `database`: the same numeric ID can belong to unrelated rows on different tables. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses writes live data, identity rule preventing cross-table corruption, and that fields omitted are untouched. Covers _clear_fields behavior. Annotations align (idempotentHint=true, openWorldHint=true). No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and bold emphasis. Some redundancy in identity rule, but necessary for clarity. Front-loaded purpose. Slightly long but justified by complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers prerequisites, alternatives, workflow, required params, identity rule, clearing fields, return format, and error handling. No output schema but describes return. Thorough and self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Description adds significant meaning beyond schema: explains identity pair requirement, confirms database/database_id must match existing row, details _clear_fields usage. Schema coverage 60% but description compensates well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Update a metadata record' and specifies updating the 'value' field by 'meta_id'. It distinguishes from siblings like createUserMeta, deleteUserMeta, and updateWebPage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use (existing meta from createUserMeta) and when-not (list_seo fields via updateWebPage). Includes a step-by-step workflow and identity rule, effectively guiding the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateUserPhotoAIdempotent
Update a user photo - Update an existing userphoto record by ID. Fields omitted are untouched. Writes live data.
Use when: changing a photo's type slot (logo/photo/cover_photo).
Required: photo_id.
Enums: type: logo, photo, cover_photo.
See also: createUserPhoto (add new), deleteUserPhoto (remove permanently).
Returns: { status: "success", message: {...updatedRecord} } - the full updated record after changes applied.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | ||
| photo_id | Yes | ||
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds value beyond annotations by stating 'Fields omitted are untouched' (aligning with idempotentHint) and 'Writes live data'. It also describes the return format. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly structured with clear sections, front-loaded main sentence, and no unnecessary words. Every sentence serves a purpose (use case, required param, enums, see also, returns).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters and no output schema, the description covers purpose, usage, return format, and sibling distinctions. It lacks detailed explanation of _clear_fields but the schema covers that. Overall complete for the complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description repeats enum values already in schema and mentions the required photo_id, but does not explain the meaning of photo_id or type beyond the enum. Schema description coverage is 33%, and the description partially compensates by restating enums, but misses adding new semantic context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates an existing user photo record by ID. It distinguishes from sibling tools by explicitly referring to createUserPhoto and deleteUserPhoto, clarifying its role as an update operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Use when' section provides a clear, specific scenario: changing a photo's type slot. It also references create and delete alternatives, but does not explicitly exclude other use cases or compare with other update tools like updateUser.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateWebPageAIdempotent
Update a page - Update an existing list_seo page by seo_id. PATCH semantics - omitted fields untouched.
Cache refresh is automatic. Every successful updateWebPage / createWebPage triggers refreshCache(scope=web_pages) server-side; the response includes auto_cache_refreshed: true. Do not call refreshSiteCache manually after — it's already done. If auto_cache_refreshed: false appears in the response, the write succeeded but cache flush failed; check auto_cache_refresh_error and retry refreshSiteCache once.
Required fields: seo_id. When changing seo_type to data_category, linked_post_type is also required (auto-validated at runtime).
Disambiguation: apply Rule: Resource disambiguation when the user names a page by title or partial filename rather than by seo_id. "Edit my [X] page" is layer-ambiguous — could be a seo_type=content WebPage, a post type's code group, or a category landing.
Common edits:
Copy/content:
content,h1,h2,seo_text,content_footer(access gate, not HTML)SEO meta:
title,meta_desc,meta_keywordsSocial (Open Graph):
facebook_title,facebook_desc,facebook_imageLayout:
content_layout,hide_header,hide_footer,hide_top_right,hide_header_linksHero:
enable_hero_section+hero_*+h1_*/h2_*
Misnamed fields (BD repurposed these columns - name is misleading):
show_form-> Apply NoIndex,NoFollow. NOT a contact-form toggle.1=add<meta name="robots" content="noindex,nofollow">.content_footer-> page access gate enum:""(public) /"members_only"/"digital_products". NOT footer HTML.form_name-> sidebar name. NOT a contact-form slug.seo_text-> Wildcard URL Rewrite (catch-all routing). NOT SEO copy.
Template tokens supported in title, meta_desc, meta_keywords, h1, h2: %%%website_name%%%, %industry%, %profession%. Expanded at render time.
Changing filename (URL slug) breaks inbound links - call createRedirect to create a 301 from old slug -> new slug, preserve SEO. Pre-check new slug for duplicate before renaming - listWebPages property=filename property_value=<new-slug> property_operator==. BD does NOT enforce unique filename; renaming to an existing slug silently creates two records at the same URL, render order undefined.
Asset field routing (Froala strips mismatched content silently):
content- body HTML only. No<style>/<script>tags. Supports[widget=Name]+%%%token%%%.content_css- raw CSS, no<style>wrapper, scope to a unique page class. Never target.container/.froala-table/.image-placeholder. Never@import(causes FOUC/CLS - usecontent_head<link>tag instead).content_footer_html- JavaScript + script embeds (<script>tags OK). IIFE-wrap + scope.content_head- head-only deps (<link>,<meta>, JSON-LD, external stylesheets, fonts).content_footer- MISLEADING NAME. Access gate enum only:""/"members_only"/"digital_products". NOT HTML.SVG/canvas prohibited in
content- Froala strips. Charts/diagrams -> custom Widget via[widget=Name].
All asset fields accept raw content verbatim. No CDATA, no <parameter>/<invoke>/<function_calls> scaffolding, no entity-escaped HTML — forbidden anywhere in the value, not just as wrappers. Server strips these as a safety net; do not rely on it.
EAV-stored fields — auto-routed by the wrapper, no special handling. BD's list_seo table mixes direct columns with EAV-stored fields in users_meta. BD's REST API itself silently ignores EAV fields on update, but the wrapper auto-detects fields like hero_*, h1_*, h2_*, linked_post_category, disable_* and routes them through users_meta automatically. Pass any field on updateWebPage directly — the response includes an eav_results array confirming which EAV fields were written. Reads merge automatically via getWebPage / listWebPages. Do NOT call updateUserMeta directly for these. If a field doesn't persist after updateWebPage, file as a wrapper bug (the wrapper's EAV routing table needs the field added) rather than working around with manual updateUserMeta.
Hero section — which hero does the user mean? Read the page's current enable_hero_section first. 1/2 = the user means this programmatic hero: change the relevant hero_* field to restyle, or set enable_hero_section=0 to remove it — do NOT rewrite content to remove a programmatic hero. 0 = no programmatic hero is rendering, so a hero the user references lives in content — edit content. If hero markup is also in content, or the user is ADDING a hero, ask which they mean.
**Hero section edits - when enable_hero_section toggles from 0/unset to 1 or 2, apply Rule: Hero readability bundle (atomic — all listed values must be sent together unless user overrides). Notes:
All color fields RGB ONLY, hex rejected.
h1_*/h2_*fields style hero; text comes from record's top-levelh1/h2.Hero image: Pexels stock; see Rule: Image URLs (imported field — bare URL, no query string). Never
picsum.photos/lorempixel/placekitten.Hero gap-fix CSS (
seo_type=contentONLY): add.hero_section_container + div.clearfix-lg {display:none}tocontent_css(closes BD's 40px clearfix gap). Never add this rule on any otherseo_type- onprofile_search_results/data_categorythe clearfix provides needed spacing before live search-results.Hero is cache-gated but
updateWebPage/createWebPageauto-refresh handles it; no separate call needed.Homepage hero is BENIGN:
seo_id=1stores hero fields but homepage template does NOT render them. Skip hero fields on homepage unless user explicitly asks.
Do NOT re-apply hero defaults on updates that don't touch enable_hero_section - respect the user's existing color/overlay/padding values; only change what they asked about.
H1/H2 double-render trap: when hero is enabled (enable_hero_section=1 or 2), the record's top-level h1/h2 text renders inside the hero banner. If content ALSO contains <h1>/<h2>, BOTH render -> duplicate headings (bad for SEO). Rule: either put headings in record's h1/h2 fields (leave them out of content), OR put them in content (leave h1/h2 fields empty). Never both.
profile_search_results updates - all create-time rules apply:
filenamemust be a real dynamic slug BD's router recognizes — see Rule: Member search SEO pages for the slug hierarchy (country/state/city/top_cat/sub_cat) and the live-lookup endpoints. Arbitrary slugs render 404. Country-only slug does NOT render forprofile_search_results. For arbitrary-URL pages useseo_type=content.Required defaults on every write:
custom_html_placement=4(Below Body Content),form_name="Member Search Result"(sidebar - Master Default; NOT "Member Profile Page"),menu_layout=3(Left Slim).custom_html_placementis only meaningful onprofile_search_results(anddata_category). Ignored oncontentpages.Auto-generate SEO meta for the specific combo - don't leave blank:
title- 50-60 chars ideal, <=70 max. Pattern:"[Category] in [City], [State] | [Site Name]".meta_desc- 150-160 chars ideal, <=170 max. 1-2 sentences with location + CTA.meta_keywords- ~200 chars, comma-separated (no spaces).facebook_title- 55-60 chars, differ fromtitle(more conversational).facebook_desc- 110-125 chars, punchier thanmeta_desc.Do NOT auto-set
facebook_image(needs uploaded asset).
No max-width wrappers in
contentorcontent_css- BD's layout already provides the outer container;max-width: 960px; margin: autodouble-constrains to a narrow strip. Let content flow at natural width.
SEO content for categories: route to updateWebPage seo_type=profile_search_results (NOT updateTopCategory.desc / updateSubCategory.desc - those are internal labels, not rendered).
seo_type enum: content, home, profile_search_results, data_category, custom_widget_page, password_retrieval_page, unsubscribed. OMIT on update unless intentionally changing it — most changes are destructive. home appears in the enum only so existing-record round-trips pass validation; never convert another page TO home (only one homepage per site).
On deleteWebPage: BD does NOT cascade-delete users_meta rows. After deleting, run the orphan cleanup per Rule: users_meta orphans - listUserMeta filtered by database=list_seo + database_id=<deleted seo_id>, then deleteUserMeta each match. Exception: for seo_type=data_category pages the wrapper auto-strips linked_post_type / linked_post_category rows on transition AWAY from data_category, AND auto-cascade-deletes the placeholder-slug 301 redirect on deleteWebPage (annotations: _data_category_orphans_stripped, _data_category_redirect_retired, _data_category_redirect_deleted). Hero / layout EAV rows still need manual cleanup.
See also: createWebPage (new page), deleteWebPage (remove + orphan users_meta cleanup), createRedirect (slug-change preservation).
Returns: { status: "success", message: {...updatedRecord}, auto_cache_refreshed: true|false, auto_cache_refresh_error?: "...", _admin_edit_url: "..." }. auto_cache_refreshed reports whether the automatic cache flush succeeded; if false, auto_cache_refresh_error explains why and the agent should retry refreshSiteCache manually once. _admin_edit_url is a centralized-admin deep-link to the WebPage editor for this seo_id — surface it to the user so they can jump straight to the admin edit screen for the page just updated.
| Name | Required | Description | Default |
|---|---|---|---|
| h1 | No | **H1 Heading** - Supports template tokens. Rendered as the page's main heading. H1 heading - supports template tokens | |
| h2 | No | **H2 Heading** - Supports template tokens. H2 heading - supports template tokens | |
| title | No | **Page Meta Title** - Supports template tokens: `%%%website_name%%%`, `%industry%`, `%profession%`, etc. ~30-60 chars recommended. HTML title tag - supports template tokens like %%%website_name%%% | |
| seo_id | Yes | Page primary key (required to identify record) | |
| content | No | Main page body - Froala rich-text editor. **Shortcodes:** `[form=<form_name>]` embeds a BD form; `[widget=<widget_name>]` embeds a widget; `%%%template_tokens%%%` for site vars. **HTML only** - Froala strips `<style>`, `<script>`, `<form>`, `<input>`, `<select>`, `<textarea>`, `contenteditable=`, AND inline `style="..."` attributes on save. Route all non-body assets to their dedicated fields: CSS -> `content_css` (target classes, not inline styles), JS -> `content_footer_html`, head deps (`<link>`, fonts, `<meta>`, JSON-LD) -> `content_head`. SVG/canvas also stripped; for charts/diagrams use a custom Widget embedded via `[widget=Name]` shortcode. | |
| filename | No | URL slug (e.g. home, about-us). Renaming to a slug already used by any web page, top category, sub category, plan public URL, or member profile slug is auto-rejected — pick a different slug or rename the conflict first. | |
| nickname | No | Human-readable label shown in admin panel | |
| seo_text | No | **Wildcard URL Rewrite.** `1` = any URL within this directory routes to this web page (catch-all behavior). Misnamed field - NOT SEO copy; SEO copy goes in `content` + meta fields. | |
| seo_type | No | Page type identifier. On update, safest to OMIT this field unless intentionally changing it (most seo_type changes are destructive). Values: content = Single Web Page (generic static/landing page) data_category = Post Search Results profile_search_results = Member Search Results custom_widget_page = Custom Widget as Web Page password_retrieval_page = Password Retrieval Page unsubscribed = Unsubscribed Page home = Homepage (system-seeded; included here so an update round-trip of the existing homepage record passes the enum check) | |
| form_name | No | **SIDEBAR name** for this page - BD's field is misnamed; controls sidebar slot, NOT a contact form. NOT for rendering forms on this page — to embed a form in the body, use `[form=<form_name>]` inside `content`. Pass exact sidebar `name` string. `""` = no sidebar. Valid values: a Master Default Sidebar OR a custom sidebar `name` from `listSidebars`. See **Rule: Sidebars** for the canonical Master Default list and selection workflow. `menu_layout` controls position when `form_name` is set. **Default on `profile_search_results` pages:** `Member Search Result` (NOT `Member Profile Page` - that's for profile/detail pages, not search results). | |
| meta_desc | No | **Meta Description** - Supports template tokens. ~150-160 chars recommended for search snippets. Meta description - supports template tokens | |
| show_form | No | **Apply NoIndex,NoFollow.** `1` = adds `<meta name="robots" content="noindex,nofollow">` to the page. Auto-applied to protected pages. **NOT a form-render toggle** despite the field name — BD repurposed this column. To render a form in the body, use `[form=<form_name>]` inside `content`. | |
| breadcrumb | No | **OMIT** — BD auto-generates the breadcrumb trail. Never set this yourself; a manual value overrides BD's generated trail and breaks the page. | |
| hero_image | No | Hero background image. Accepts BD-hosted relative path (`/images/bg202.webp`) OR external URL (`https://cdn.example.com/banner.jpg`) — external URLs render hotlinked on WebPages, no `auto_image_import` needed. **LANDSCAPE only — verify orientation via `getImageDimensions` per **Rule: Image dimensions** before commit; bare URL, no `?query`, must end in `.jpg`/`.jpeg`/`.png` (WebP/GIF/AVIF skipped pre-tool per the same rule) — see **Rule: Image URLs**.** Query strings get truncated/mangled in BD's form-urlencoded parsing and the stored URL becomes invalid. Recommended dimensions: 1800 × 600 px. | |
| content_css | No | Custom CSS for this page. Paste raw CSS rules directly - NO `<style>` wrapper. Renders in page `<head>` at load. Scope every selector to a unique page class/ID (e.g. `.my-about-page h2 { ... }`) - bare `body`/`h1`/`p` affect the whole site. Never target reserved BD classes: `.container`, `.froala-table`, `.image-placeholder`. Never `@import` (FOUC/CLS) - load external stylesheets/fonts via `<link>` tag in `content_head`. **Admin Froala editor gotcha** - editor applies `content_css` but does NOT run `content_footer_html` JS. Hide-by-default CSS (scroll reveals, tab panels, accordion collapsed, modal hidden, slider non-active slides) will permanently hide content in the editor. Gate such rules behind a `.js-ready` class that `content_footer_html` JS adds on load: `.my-page.js-ready .reveal { opacity:0 }` NOT `.my-page .reveal { opacity:0 }`. The paired JS rule lives in the `content_footer_html` field. | |
| hide_footer | No | **Hide Footer** - 1 = hides the site footer on this page. | |
| hide_header | No | **Hide Header** - 1 = hides the full site header on this page. | |
| menu_layout | No | Sidebar position + width (integer). Only effective when the page has a sidebar set via `form_name` - ignored without sidebar. NOT a navigation menu layout despite the field name. - `1` = Left Wide (BD default when unspecified) - `2` = Right Wide - `3` = Left Slim - `4` = Right Slim Ordering is NOT sequential by side - left positions are `1` and `3`, right are `2` and `4`. **Default on `profile_search_results` pages:** `3` (Left Slim). On `content` pages, omit unless user specifies (BD defaults to `1`). | |
| content_head | No | Page-scoped `<head>` dependencies - rendered inside `<head>`. Use for: `<link>` tags (external stylesheets, preconnect hints, canonical overrides, Google Fonts), `<meta>` tags beyond standard SEO fields, verification tags, JSON-LD structured data (`<script type="application/ld+json">`), head-required third-party scripts (rare - prefer `content_footer_html` for most JS). | |
| content_menu | No | Menu section this page belongs to | |
| h1_font_size | No | Main title (H1) font size in pixels. Accepts integer values from `30` to `80`. OMIT to inherit BD's per-`seo_type` default. | |
| h2_font_size | No | Sub-title (H2) font size in pixels. Accepts integer values from `20` to `60`. OMIT to inherit BD's per-`seo_type` default. | |
| org_template | No | **OMIT** — internal layout reference. No public lookup endpoint; setting an arbitrary value can render the page against a nonexistent layout. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| content_group | No | Admin-panel grouping label | |
| content_order | No | Sort order within menu/section | |
| facebook_desc | No | **Social Media Description (Open Graph)** - Description shown on social shares. Open Graph description | |
| h1_font_color | No | Main title (H1) font color in the hero. RGB format ONLY - e.g. `rgb(255, 255, 255)`. The H1 text itself comes from the page's `h1` field - these `h1_*` fields control ONLY the hero's H1 styling. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| h2_font_color | No | Sub-title (H2) font color in the hero. RGB format ONLY - e.g. `rgb(255, 255, 255)`. The H2 text itself comes from the page's `h2` field. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_link_url | No | Hero call-to-action (CTA) button link URL. If empty, no CTA button is rendered. For internal links, a relative path is fine (e.g. `/signup`); for external, full URL with `http://` or `https://`. | |
| meta_keywords | No | **Meta Keywords** - Supports template tokens (comma-separated). Meta keywords - supports template tokens | |
| content_footer | No | **MISLEADING NAME - NOT page footer HTML.** Misnamed relic column; BD repurposed as the **page-access gate**: - `""` (default) = Public For Everyone - `"members_only"` = Logged-in members only (non-members hit login/signup wall) - `"digital_products"` = Only buyers of digital-product items Finer rules (which members, which plans) live in other fields. Do NOT put HTML here. Page body -> `content`; scripts -> `content_footer_html`. No dedicated "below-body HTML" field - put below-body markup inside `content` itself. | |
| content_layout | No | **Full Screen Page Width override.** OMIT for normal pages (BD's default container width). Set to `1` for full-bleed pages — individual sections in `content` can then break edge-to-edge (background bands, hero strips, viewport-wide images). **For full-bleed sections, set `content_layout=1` FIRST.** Do NOT fake full-bleed with negative-margin/9999px-padding tricks in `content_css` — breaks horizontal scroll, fights `overflow: hidden` parents, prevents future layout changes. Anti-pattern. Pattern with `content_layout=1`: scoped CSS in `content_css` gives each section its own edge-to-edge background; inner `<div class="container">` (or page-scoped max-width wrapper) keeps readable copy centered. | |
| facebook_image | No | **Social Media Shared Image** - URL/filename of the OG image. BD recommends at least 200×200px. Open Graph image URL | |
| facebook_title | No | **Social Media Title (Open Graph)** - Title shown when the page is shared on Facebook/LinkedIn/etc. Open Graph title for social sharing | |
| h1_font_weight | No | Main title (H1) font weight. `300`=Light, `400`=Normal (default), `600`=Bold, `800`=Extra Bold. | |
| h2_font_weight | No | Sub-title (H2) font weight. `300`=Light, `400`=Normal, `600`=Bold (default), `800`=Extra Bold. | |
| hero_alignment | No | Horizontal alignment of the hero title/subtitle/content text block within its column. Default `center`. | |
| hero_link_size | No | CTA button size. MUST be exactly one of: `""` (empty = Normal), `btn-lg` (Large), `btn-xl` (Extra Large). Any other value (e.g. a font-size number like `16`) is stored verbatim and rendered as a broken class — BD does not validate server-side. | |
| hero_link_text | No | Hero CTA button label. Required (non-empty) for the button to render - `hero_link_url` alone without text will not produce a button. | |
| hide_top_right | No | **Hide Top Header Menu** - 1 = hides the top-right nav cluster (account/login links). | |
| content_sidebar | No | Sidebar configuration or widget shortcode | |
| hero_link_color | No | CTA button color variant — attention level, not literal color. MUST be exactly one of: `primary`, `info`, `success`, `warning`, `danger`, `default`, `secondary`. Any other value (e.g. a hex `#ffffff`) is stored verbatim and rendered as a broken class like `btn-#ffffff` — BD does not validate server-side. Choose by attention level needed: `primary` (main CTA), `danger` (urgent/can't-miss), `warning` (attention), `success` (positive action), `info` (neutral-blue), `secondary` (theme secondary), `default` (low-emphasis gray). Actual rendered color comes from the site's theme palette. | |
| allowed_products | No | Comma-separated plan/product IDs (empty = all plans) | |
| hero_top_padding | No | Top padding inside the hero banner, in pixels. Accepts multiples of 10 from `0` to `200`. BD field default `70` — wrapper auto-fills `100` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| linked_post_type | No | Post type's `data_id` (from `listPostTypes`). REQUIRED when `seo_type=data_category`; ignored on other seo_types. See **Rule: Resource disambiguation** when the user names a post type by description rather than `data_id`. | |
| hero_column_width | No | Hero text-content column width as Bootstrap 12-col span. `3`=25%, `4`=30%, `5`=40%, `6`=50%, `7`=60%, `8`=70%, `9`=75%, `10`=80%, `11`=90%, `12`=100%. Narrower = more side padding around the text block. BD field default `8` — wrapper auto-fills `5` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hide_header_links | No | **Hide Main Menu** - 1 = hides the main navigation menu on this page. | |
| page_render_widget | No | **OMIT** — internal widget reference for `seo_type=custom_widget_page` only. No public widget-ID lookup; setting on other page types breaks rendering. | |
| content_footer_html | No | Page-scoped JavaScript + script embeds - rendered before `</body>`. `<script>` tags accepted here (unlike `content`). jQuery loaded globally. Wrap JS in an IIFE `(function($){ ... })(jQuery);` and scope selectors to a unique page class. Also for third-party script embeds (analytics pixels, chat widgets, schema markup). NOT for extra body HTML - `content` is the body field. **If `content_css` uses a `.js-ready` gate for hide-by-default effects** (scroll reveals, tab panels, accordion collapse, modal hidden, slider non-active), JS MUST add that class to the page wrapper as the FIRST line (before any other init code): `document.querySelector('.my-page')?.classList.add('js-ready');`. The admin Froala editor applies CSS but does NOT run this field's JS, so without the gate, hide-rules make content permanently invisible in the editor. | |
| enable_hero_section | No | Hero banner master switch: - `0` = disabled (all other `hero_*`/`h1_font_*`/`h2_font_*` ignored at render; stored values preserved for later toggle-back) - `1` = enabled all devices - `2` = enabled desktop, hidden mobile **On hero off→on transition (`0`/unset → `1`/`2`), wrapper auto-fills the hero readability bundle** — `hero_top_padding=100`, `hero_bottom_padding=100`, `hero_column_width=5`, `hero_content_overlay_color=rgb(0, 0, 0)`, `hero_content_overlay_opacity=0.5`, `hero_content_font_color=rgb(255, 255, 255)`, `hero_content_font_size=18`, `h1_font_color=rgb(255, 255, 255)`, `h2_font_color=rgb(255, 255, 255)` — for any of those 9 fields you OMITTED. BD's per-field defaults render an unreadable hero (10px content text on a 0.4-opacity overlay, default top/bottom padding 70/60 — visually too cramped for most banner imagery); the bundle is the canonical readable recipe. User-supplied values pass through untouched. Filled fields are echoed in `_hero_bundle_autofilled`. **`hero_image` is required** on transition — wrapper rejects if missing (no safe default; walk the image-sourcing ladder). On no-transition updates (hero already on), no auto-fill fires. **Homepage benign** - `seo_type=home` ignores hero fields entirely regardless of value. BD stores but never renders on homepage; skip all `hero_*` fields on homepage updates. | |
| hero_bottom_padding | No | Bottom padding inside the hero banner, in pixels. Accepts multiples of 10 from `0` to `200`. BD field default `60` — wrapper auto-fills `100` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_hide_banner_ad | No | When `1`, suppresses the site-wide "Below Header Banner Ad" on THIS page only (useful when the hero visually replaces that slot). `0` (default) keeps the banner ad in its normal position. | |
| private_page_select | No | Access control setting | |
| hero_section_content | No | Additional text / HTML / widget shortcode rendered BELOW H1 and H2 in the hero section. Supports `[widget=Name]` shortcodes. EAV-routed by the wrapper — pass on `createWebPage` / `updateWebPage` directly, no manual `updateUserMeta` needed. | |
| linked_post_category | No | Either the literal `post_main_page` (pins to the post type's main search-results page) OR an exact category name from the linked post type's `feature_categories` (e.g. `"Category 1"`, case-sensitive). Optional on `seo_type=data_category` — wrapper auto-defaults to `post_main_page` when omitted on a fresh data_category create or content→data_category switch. Ignored on other seo_types. Wrapper enforces pair-uniqueness on `(linked_post_type, linked_post_category)`. | |
| custom_html_placement | No | Render position of `content` HTML relative to dynamic search results. Only meaningful on `seo_type=profile_search_results` (and `data_category`); ignored on `content` pages. - `0` = Inside Tab (content + members in separate nav tabs) - `1` = Above Member Results (within results container, sidebar-width) - `2` = Below Member Results (within results container) - `3` = Above Body Content (full page width, spans sidebar+results) - `4` = Below Body Content (full page width, below sidebar+results) <- **recommended default for AI-generated SEO pages** For boilerplate SEO intro/FAQ/local copy bolstering thin pages, `4` renders full-width below the live results without disrupting member-facing UX. | |
| hero_content_font_size | No | Font size in pixels for the additional hero content block (`hero_section_content`). Accepts integer values from `10` to `30`. BD field default `10` is too small for hero paragraph copy — wrapper auto-fills `18` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_link_target_blank | No | When `1`, opens the CTA link in a new tab (`target="_blank"`). `0` (default) opens in the same tab. | |
| disable_css_stylesheets | No | Disable BD's site stylesheets on this page (frontend only). `1` = page renders without BD's global CSS (use when embedding a fully self-styled custom page or iframe target). `0` (default) = normal BD styling. EAV-stored — agent passes directly; wrapper handles routing on update. | |
| hero_content_font_color | No | Font color for the additional hero content block rendered below H1/H2 (the `hero_section_content` field). RGB format ONLY - e.g. `rgb(0, 0, 0)`. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_background_image_size | No | Controls how the hero background image scales/crops across devices. `mobile-ready` (recommended) = responsive behavior tuned for mobile, `standard` = fixed-ratio behavior. | |
| hero_content_overlay_color | No | Semi-transparent color layer between hero background image and text, for legibility over busy images. **RGB format ONLY** - `rgb(0, 0, 0)` or `rgb(255, 255, 255)`. Hex (`#000000`) NOT accepted. Combine with `hero_content_overlay_opacity` to control strength. Wrapper auto-fills `rgb(0, 0, 0)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_content_overlay_opacity | No | Opacity of `hero_content_overlay_color` layer, 0.1 increments from `0.0` (transparent) to `1` (opaque). Admin UI labels 0-10. BD field default `0.4` is too transparent — wrapper auto-fills `0.5` on hero off→on transition (part of **Rule: Hero readability bundle**). EAV-routed by the wrapper — pass on `updateWebPage` directly, no manual `updateUserMeta` needed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate the tool is not read-only, not destructive, idempotent, and open-world. The description adds substantial behavioral context beyond these: automatic cache refresh, PATCH semantics (omitted fields untouched), hero bundle auto-fill on transition, EAV-routing behavior, and the fact that `seo_type` changes are destructive. It also documents misnamed fields (e.g., `show_form` for noindex). No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long (multiple paragraphs). While comprehensive, it includes repeated details (e.g., hero bundle defaults mentioned in both the `enable_hero_section` field description and the dedicated hero section). The structure front-loads the purpose but then dives into deep details. For a tool with 64 parameters, some length is justified, but it could be more concise and better organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (64 parameters, no output schema), the description is remarkably complete. It covers edge cases (e.g., homepage hero benign, `profile_search_results` slug requirements, double-render trap for H1/H2), common edits, misnamed fields, asset field routing, EAV routing, and even post-deletion orphan cleanup. It also provides specific guidance for `seo_type` changes and hero transitions. No gaps identified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds crucial meaning beyond field descriptions. It explains misnamed fields (e.g., `content_footer` is an access gate, not HTML), template tokens, asset field routing rules, hero bundle defaults, and EAV auto-routing. For fields like `enable_hero_section`, it details the auto-fill behavior and required companion fields. This dramatically enhances comprehension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Update'), resource ('an existing `list_seo` page'), and identifier (`seo_id`). It also differentiates from sibling tools by mentioning PATCH semantics and explicitly referencing `createWebPage`, `deleteWebPage`, and `createRedirect` in the 'See also' section. This leaves no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides extensive guidance on when to use this tool versus alternatives. It includes a 'Disambiguation' section that warns about resource ambiguity when users refer to pages by title, and directs to a rule for clarifying. It also explicitly states conditions for using `createRedirect` (slug change), `deleteWebPage` (with orphan cleanup), and `refreshSiteCache` (when cache refresh fails). This is exemplary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
updateWidgetAIdempotent
Update a widget - Update an existing widget by widget_id. Fields omitted are untouched. Writes live data.
Cache refresh is automatic. Response includes auto_cache_refreshed: true after successful writes; no manual refreshSiteCache call needed. If auto_cache_refreshed: false, check auto_cache_refresh_error and retry refreshSiteCache once.
Use when: editing widget HTML (widget_data), CSS (widget_style), JS (widget_javascript), or metadata. Any page or email referencing this widget via [widget=Name] shortcode will render the updated content on next view.
Required: widget_id.
Common edits:
Content:
widget_data,widget_style,widget_javascriptVisibility:
widget_viewport(front/admin/both)Framework:
bootstrap_enabled,mobile_enabled,ssl_enabled
Renaming via widget_name: DO NOT pass widget_name unless the user explicitly asks to rename the widget. Renaming a widget breaks every [widget=Name] shortcode reference to its old name on every page/email — silently. If the user does ask: same format rules as create ([A-Za-z0-9 -+_]+, runtime-rejected on bad chars); on collision follow the auto-suffix flow (-v2, -v3, ... up to -v10).
See also: createWidget (add new), deleteWidget (remove).
Writes live data: edits go live immediately for new page loads.
Returns: { status: "success", message: {...updatedRecord}, auto_cache_refreshed: true|false, auto_cache_refresh_error?: "..." }.
For the full field list, see listWidgets.
| Name | Required | Description | Default |
|---|---|---|---|
| widget_id | Yes | ||
| widget_data | No | HTML. Render strips backslashes here (`\d`→`d`, `\n`→`n`, `\t`→`t`, `\\`→`\`). JS with stripped escapes throws SyntaxError on parse — every handler unbound, widget renders but no clicks/inputs work. Fix: relocate to `widget_javascript`, do not rewrite JS to avoid backslashes. Never relocate existing `<style>`/`<script>` blocks here — only on user-reported breakage. New content: route by type (CSS→`widget_style`, JS→`widget_javascript`). See **Rule: Widget code fields**. | |
| widget_name | No | ||
| widget_style | No | Raw CSS. No `<style>` wrapper — BD wraps at render. Wholly-wrapped value: outer wrapper stripped on storage; concatenated wrappers not stripped. See **Rule: Widget code fields**. | |
| _clear_fields | No | Column names to clear to empty string. Available on every `update*` operation. Works on base columns AND EAV/`users_meta` rows (rows preserved with `value=""`). To actually clear a field you MUST use this parameter — sending the field with `""` alone is a no-op (BD drops empty values). To remove a `users_meta` row entirely, use `deleteUserMeta`. See **Rule: Clearing fields**. Example: `_clear_fields: ["h2", "hero_link_url"]`. | |
| widget_javascript | No | JS with `<script>...</script>` wrapper required. BD does not auto-wrap; unwrapped content renders as inert text. No backslash-strip on this field — regex literals (`\d`, `\w`, `\s`) AND string escapes (`\n`, `\t`, `\\`) survive intact. See **Rule: Widget code fields**. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond annotations by detailing cache refresh behavior, response format, side effects of renaming, and that fields omitted are untouched. Annotations provide little behavioral context, so the description is critical.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with sections, bolding, and bullet points. It front-loads the core action and avoids unnecessary repetition, though it could be slightly more concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (6 params, no output schema), the description covers primary use, caveats, and return format. It references external rules and 'listWidgets' for full field list, which is acceptable but not fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, and the description adds context for common edits and renaming. However, several parameters already have detailed schema descriptions, so the description complements rather than compensates fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Update an existing widget by `widget_id`', clearly stating the verb and resource. It distinguishes from siblings by referencing 'createWidget' and 'deleteWidget'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Use when: editing widget HTML, CSS, JS, or metadata.' It also warns against accidentally renaming and points to alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verifyTokenARead-onlyIdempotent
Verify API key - Verify that your API key is valid and check rate limit status.
Use when: at the start of any session or batch job, to confirm the API key is valid and the site is reachable BEFORE burning rate limit on real calls. Also useful for surfacing a clear "bad credentials" error to the user early.
Parameter interactions:
Call at the start of a session to confirm the API key is valid BEFORE issuing real calls - saves rate-limit budget on key-config errors
Returns: { status: "success"|"error", message: ... } - BD's standard response envelope.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent). Description adds practical return format and rate-limit context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise with clear sections (use-when, returns). Minor repetition but overall well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Fully covers purpose, usage, behavior, and return format. Complete for a zero-parameter tool with good annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters; schema coverage is 100%, baseline 4. Description doesn't need additional parameter info.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it verifies API key validity and checks rate limit status. Distinct from all sibling CRUD tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly recommends use at session start to save rate-limit budget. Lacks 'don't use when' but sufficient guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
2 tool updates
v6.58.608- Added
createCategoryTree - Changed
createSubCategory1 field changed- added
Input schema / properties / name / descriptionAdded value: +"Sub-category name. One name only — a comma-separated list is stored literally as one category named `A,B,C`. To create several at once use `createCategoryTree`."
3 tool updates
v6.58.592- Changed
createReview5 fields changed- added
Input schema / properties / rating_expertiseAdded value: +{ + "description": "Omitted on create -> BD stores 5 (server default), not null - send every category score you have.", + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_languageAdded value: +{ + "description": "Omitted on create -> BD stores 5 (server default), not null - send every category score you have.", + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_responseAdded value: +{ + "description": "Omitted on create -> BD stores 5 (server default), not null - send every category score you have.", + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_resultsAdded value: +{ + "description": "Omitted on create -> BD stores 5 (server default), not null - send every category score you have.", + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_serviceAdded value: +{ + "description": "Omitted on create -> BD stores 5 (server default), not null - send every category score you have.", + "maximum": 5, + "minimum": 1, + "type": "integer" +}
- Changed
listSingleImagePosts1 field changed- added
Input schema / properties / fields_onlyAdded value: +{ + "description": "Exact-list response trim: CSV of post field names; each returned row carries exactly these fields. Authoritative when present - include_* flags are moot. An unknown name errors (teaching message) so a typo never silently drops a field. Name the identity columns PLUS every column your match criteria judge: title-only checks use post_id,post_title,post_status,post_filename; checks that judge dates, venues, companies, or locations add post_start_date,post_venue,post_location. ~70% smaller responses, immune to output truncation, total/next_page always intact.", + "type": "string" +}
- Changed
updateReview7 fields changed- added
Input schema / properties / rating_expertiseAdded value: +{ + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_languageAdded value: +{ + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_overall / maximumAdded value: +5 - added
Input schema / properties / rating_overall / minimumAdded value: +1 - added
Input schema / properties / rating_responseAdded value: +{ + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_resultsAdded value: +{ + "maximum": 5, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / rating_serviceAdded value: +{ + "maximum": 5, + "minimum": 1, + "type": "integer" +}
1 tool update
v6.58.7- Changed
getImageDimensions1 field changed- changed
Input schema / properties / urls / descriptionPrevious value: -"Batch mode: comma-separated bare image URLs, up to 10. Probed in parallel; one response carries per-URL results in input order — a failed URL is its own error entry and never breaks the batch. Preferred whenever vetting 2+ candidates."New value: +"Batch mode: comma-separated bare image URLs, up to 50. Probed in parallel; one response carries per-URL results in input order — a failed URL is its own error entry and never breaks the batch. Preferred whenever vetting 2+ candidates."
37 tool updates
v6.58.3- Changed
createSingleImagePost2 fields changed- changed
Input schema / properties / post_category / descriptionPrevious value: -"Per-post-type dropdown value, configured in BD admin on the post type's `feature_categories` field. Discover allowed values via `getSingleImagePostFields(form_name=<post type's form_name>)` -> `post_category.choices[].key`.\n\nPass VERBATIM - BD does not trim whitespace, so leading spaces after commas in `feature_categories` persist in the stored option values."New value: +"Per-post-type dropdown value, configured in BD admin on the post type's `feature_categories` field. Discover allowed values from `feature_categories` on your `listPostTypes`/`getPostType` result, or `getPostTypeCustomFields.post_category.choices` where your workflow routes through it - NOT from `getSingleImagePostFields.post_category.choices` (BD fills that from platform master defaults on some forms).\n\nPass VERBATIM - BD does not trim whitespace, so leading spaces after commas in `feature_categories` persist in the stored option values." - changed
Input schema / properties / post_promo / descriptionPrevious value: -"Jobs-only twin of post_price. On job posts, BD requires post_promo to populate post_price too — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null."New value: +"Twin of post_price (job pay, event ticket price, coupon price — live-verified on jobs and events). BD requires post_promo to populate post_price — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null."
- Changed
listCities1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listClicks1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listCountries1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listDataTypes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listEmailTemplates1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listFormFields1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listFormInquiries1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listForms1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listLeadMatches1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listLeads1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMembershipPlans1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMemberSubCategoryLinks1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMenuItems1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMenus1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMultiImagePostPhotos1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMultiImagePosts1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listPostTypes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listRedirects1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listReviews1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSidebars1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSingleImagePosts1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSmartLists1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listStates1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSubCategories1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTagGroups1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTagRelationships1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTags1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTagTypes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTopCategories1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUnsubscribes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUserMeta1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUserPhotos1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUsers1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listWebPages1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listWidgets1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - } - ] - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
updateSingleImagePost2 fields changed- changed
Input schema / properties / post_category / descriptionPrevious value: -"Per-post-type dropdown value, configured in BD admin on the post type's `feature_categories` field. Discover allowed values via `getSingleImagePostFields(form_name=<post type's form_name>)` -> `post_category.choices[].key`.\n\nPass VERBATIM - BD does not trim whitespace, so leading spaces after commas in `feature_categories` persist in the stored option values."New value: +"Per-post-type dropdown value, configured in BD admin on the post type's `feature_categories` field. Discover allowed values from `feature_categories` on your `listPostTypes`/`getPostType` result, or `getPostTypeCustomFields.post_category.choices` where your workflow routes through it - NOT from `getSingleImagePostFields.post_category.choices` (BD fills that from platform master defaults on some forms).\n\nPass VERBATIM - BD does not trim whitespace, so leading spaces after commas in `feature_categories` persist in the stored option values." - changed
Input schema / properties / post_promo / descriptionPrevious value: -"Jobs-only twin of post_price. On job posts, BD requires post_promo to populate post_price too — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null."New value: +"Twin of post_price (job pay, event ticket price, coupon price — live-verified on jobs and events). BD requires post_promo to populate post_price — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null."
35 tool updates
v6.58.2- Changed
listCities1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listClicks1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listCountries1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listDataTypes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listEmailTemplates1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listFormFields1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listFormInquiries1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listForms1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listLeadMatches1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listLeads1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMembershipPlans1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMemberSubCategoryLinks1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMenuItems1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMenus1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMultiImagePostPhotos1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listMultiImagePosts1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listPostTypes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listRedirects1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listReviews1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSidebars1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSingleImagePosts1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSmartLists1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listStates1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listSubCategories1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTagGroups1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTagRelationships1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTags1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTagTypes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listTopCategories1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUnsubscribes1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUserMeta1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUserPhotos1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listUsers1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listWebPages1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
- Changed
listWidgets1 field changed- changed
Input schema / properties / property_value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "array" + } +]
41 tool updates
v6.58.0- Removed
createMembershipPlan - Removed
deleteMembershipPlan - Added
getFormInquiry - Changed
getImageDimensions3 fields changed- changed
Input schema / properties / url / descriptionPrevious value: -"Bare canonical image URL (e.g. `https://images.pexels.com/photos/<id>/pexels-photo-<id>.jpeg`). Must respond with HTTP 200/206 to a Range request for the first 64KB."New value: +"Single bare canonical image URL (e.g. `https://images.pexels.com/photos/<id>/pexels-photo-<id>.jpeg`). Must respond with HTTP 200/206 to a Range request for the first 64KB. Provide `url` OR `urls`." - added
Input schema / properties / urlsAdded value: +{ + "description": "Batch mode: comma-separated bare image URLs, up to 10. Probed in parallel; one response carries per-URL results in input order — a failed URL is its own error entry and never breaks the batch. Preferred whenever vetting 2+ candidates.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "url" -]
- Changed
getWidget1 field changed- added
Input schema / properties / include_codeAdded value: +{ + "default": 0, + "description": "Opt in to return `widget_data`, `widget_style`, `widget_javascript` (the HTML/CSS/JS). Default stripped. Needed before `updateWidget` edits to the code.", + "enum": [ + 0, + 1 + ], + "type": "integer" +}
- Changed
listCities10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listClicks10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listCountries10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listDataTypes10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listEmailTemplates10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listFormFields10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Added
listFormInquiries - Changed
listForms10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listLeadMatches10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listLeads10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listMembershipPlans11 fields changed- changed
Input schema / properties / include_plan_config / descriptionPrevious value: -"Opt in to restore plan config fields: `sub_active`, `search_priority`, `auto_activate`, `status_after_upgrade`, `upgradable_membership`, `search_membership_permissions`, `photo_limit`, `style_limit`, `service_limit`, `location_limit`, all form/sidebar/email-template fields, `profile_layout`, `menu_name`, `data_settings_read`, `location_settings`, `payment_default`, `hide_specialties`, `email_member`, `login_redirect`, `page_header`, `page_footer`, `display_ads`, `receive_messages`, `index_rule`, `nofollow_links`. Default stripped. (Note: `data_settings` is now in the lean-by-default keep-list — no opt-in needed.)"New value: +"Opt in to restore plan config fields: `sub_active`, `search_priority`, `auto_activate`, `status_after_upgrade`, `upgradable_membership`, `photo_limit`, `style_limit`, `service_limit`, `location_limit`, all form/sidebar/email-template fields, `profile_layout`, `menu_name`, `data_settings_read`, `location_settings`, `payment_default`, `hide_specialties`, `email_member`, `login_redirect`, `page_header`, `page_footer`, `display_ads`, `receive_messages`, `index_rule`, `nofollow_links`. Default stripped. (Note: `data_settings` is now in the lean-by-default keep-list — no opt-in needed.)" - changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listMemberSubCategoryLinks10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listMenuItems10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listMenus10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listMultiImagePostPhotos10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listMultiImagePosts10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listPostTypes10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listRedirects10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listReviews10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listSidebars10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listSingleImagePosts10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listSmartLists10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listStates10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listSubCategories10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listTagGroups10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listTagRelationships10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listTags10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listTagTypes10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listTopCategories10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listUnsubscribes10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listUserMeta10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listUserPhotos10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listUsers10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listWebPages10 fields changed- changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Changed
listWidgets11 fields changed- added
Input schema / properties / include_codeAdded value: +{ + "default": 0, + "description": "Opt in to return `widget_data`, `widget_style`, `widget_javascript` (the HTML/CSS/JS) on each row. Default stripped. Needed before `updateWidget` edits to the code.", + "enum": [ + 0, + 1 + ], + "type": "integer" +} - changed
Input schema / properties / order_column / descriptionPrevious value: -"Column to sort by"New value: +"Column to sort by — a column key present on the response rows (a wrong name silently returns empty)" - added
Input schema / properties / property / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property / descriptionPrevious value: -"Field name to filter by"New value: +"Column key to filter by (present on the response rows; a wrong name silently returns empty). For multi-condition AND, pass parallel arrays here and in `property_value`/`property_operator` — equal length, Nth entries paired. See Rule: Compound filters." - removed
Input schema / properties / property / typeRemoved value: -"string" - added
Input schema / properties / property_operator / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_operator / descriptionPrevious value: -"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. See Rule: Filter operators for value shapes."New value: +"Filter operator (word-form; symbol forms WAF-stripped). Single: eq, ne, lt, lte, gt, gte, like, not_like. CSV: in, not_in, between. Substring: contains, starts_with, ends_with (+not_). Date: year_eq, month_eq, day_eq (+not_), since_days, until_days. Length: length_eq, length_lt, length_gt, length_between. Null: is_set, is_not_set, is_null, is_not_null. Array to pair with a `property` array (same length). See Rule: Filter operators for value shapes." - removed
Input schema / properties / property_operator / typeRemoved value: -"string" - added
Input schema / properties / property_value / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / property_value / descriptionPrevious value: -"Value to filter by"New value: +"Value to filter by; array to pair with a `property` array (same length)." - removed
Input schema / properties / property_value / typeRemoved value: -"string"
- Removed
updateMembershipPlan
2 tool updates
v6.55.61- Changed
createSingleImagePost2 fields changed- added
Input schema / properties / post_urlAdded value: +{ + "description": "Explicit CTA button link rendered under the feature image on the post-detail page. Use when the owner wants a prominent button. Full `http(s)://` URL. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_url`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post.", + "type": "string" +} - added
Input schema / properties / post_venueAdded value: +{ + "description": "Event/post venue name/landmark where the event is held (e.g. `Staples Center`) - distinct from `post_location` (the street address). Free text. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_venue`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post.", + "type": "string" +}
- Changed
updateSingleImagePost2 fields changed- added
Input schema / properties / post_urlAdded value: +{ + "description": "Explicit CTA button link rendered under the feature image on the post-detail page. Use when the owner wants a prominent button. Full `http(s)://` URL. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_url`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post.", + "type": "string" +} - added
Input schema / properties / post_venueAdded value: +{ + "description": "Event/post venue name/landmark where the event is held (e.g. `Staples Center`) - distinct from `post_location` (the street address). Free text. Stored in `users_meta` (database=`data_posts`, database_id=this `post_id`, key=`post_venue`), not the `data_posts` column - the wrapper routes it automatically, scoped to this post.", + "type": "string" +}
6 tool updates
v6.55.60- Changed
createMenuItem1 field changed- changed
Input schema / properties / menu_name / descriptionPrevious value: -"Display text"New value: +"Display text — the visible menu link label. Supports `[widget=Name]` shortcodes."
- Added
createMultiImagePostPhoto - Added
deleteMultiImagePostPhoto - Added
getMultiImagePostFields - Changed
updateMenuItem2 fields changed- added
Input schema / properties / menu_link / descriptionAdded value: +"URL or path" - added
Input schema / properties / menu_name / descriptionAdded value: +"Display text — the visible menu link label. Supports `[widget=Name]` shortcodes."
- Changed
updateUser3 fields changed- changed
Input schema / properties / create_new_categories / descriptionPrevious value: -"Set `1` to auto-create unknown category/service names on `updateUser`. Without it, unknown names in `services`/`profession_name` are silently skipped. **Has no effect on `createUser`** (which always auto-creates, hardcoded).\n\nAuto-created sub-categories go under the member's current top-level category with `master_id=0`; deeper nesting requires a separate `createSubCategory` call."New value: +"Set `1` to auto-create unknown category names on `updateUser`. Without it, unknown names in `services`/`profession_name` are silently skipped. **No effect on `createUser`** (always auto-creates). Creates whatever level the name references: top-level via `profession_name`, sub via `services`, and sub-sub inline via the `Sub=>SubSub` format in `services` (no separate `createSubCategory` call needed)." - added
Input schema / properties / delete_categoriesAdded value: +{ + "description": "Set `1` to wipe ALL the member's sub- and sub-sub-category links (every `rel_services` row) BEFORE applying any `services` in the same call — turns `services` from append into replace. Does NOT remove the top-level category (`profession_id`) or any `list_services` definitions. Without it, `services` is additive. Combine with `services` (and `create_new_categories=1` for unknown names) to replace the member's entire sub-category set in one call. `updateUser` only.", + "enum": [ + "0", + "1" + ], + "type": "string" +} - changed
Input schema / properties / services / descriptionPrevious value: -"Sub-categories for this member. Formats: `category=>service1,service2` OR `service1,service2` (top category defaults to member's current `profession_id`). Supports sub-sub-categories via `Parent=>Child` (e.g. `Honda=>2022,Honda=>2023,Toyota`).\n\nUnknown names silently ignored unless `create_new_categories=1` is also set (on update - create auto-creates always).\n\n**WARNING:** changing `profession_id` in the same call WIPES all existing sub-category links. Re-send the full `services` list to preserve them."New value: +"Sub-categories for this member. Formats: `category=>service1,service2` OR `service1,service2` (top category defaults to member's current `profession_id`). Supports sub-sub-categories via `Parent=>Child` (e.g. `Honda=>2022,Honda=>2023,Toyota`).\n\nUnknown names silently ignored unless `create_new_categories=1` is also set (on update - create auto-creates always).\n\n**Additive by default** — these links are ADDED to the member's existing ones. To REPLACE the whole set instead, pass `delete_categories=1` in the same call.\n\n**WARNING:** changing `profession_id` in the same call WIPES all existing sub-category links. Re-send the full `services` list to preserve them."
5 tool updates
v6.55.42- Removed
createMultiImagePostPhoto - Changed
createSingleImagePost1 field changed- added
Input schema / properties / post_promoAdded value: +{ + "description": "Jobs-only twin of post_price. On job posts, BD requires post_promo to populate post_price too — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null.", + "type": "number" +}
- Removed
deleteMultiImagePostPhoto - Removed
getMultiImagePostFields - Changed
updateSingleImagePost1 field changed- added
Input schema / properties / post_promoAdded value: +{ + "description": "Jobs-only twin of post_price. On job posts, BD requires post_promo to populate post_price too — send post_promo (BD back-fills post_price). Sending post_price alone leaves post_promo null.", + "type": "number" +}
TDQS
Each tool targets a specific resource and action (create, read, update, delete, list). Resources like TopCategory, SubCategory, MemberSubCategoryLink are clearly distinguished. No two tools appear to do the same thing.
Every tool follows a consistent verb_noun pattern (e.g., createClick, deleteClick, getClick, listClicks). Even helper tools like getBrandKit, verifyToken are named predictably. No mixed conventions.
170 tools is excessive for a single MCP server. While each entity type has full CRUD, the sheer number makes the surface overwhelming and hard to navigate. Most servers with similar scope have 20-40 tools.
CRUD operations are present for nearly all entity types. Minor gaps exist (e.g., no createUserMeta, but meta is handled via updateUser/updateWebPage redirects). The set covers the full domain of BD site management.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Official MCP server for OmniDimension. Drive voice agents, dispatch calls, and run bulk campaigns.
Official MCP server for Certifier to issue, manage, and track certificates and badges.
Glide's official MCP server — build, manage, and operate GlideOS apps, data, and workflows.
- LovableOAuthdev.lovable
Official MCP server for Lovable, the AI-powered full-stack app builder.
Related MCP Servers
- AlicenseAqualityAmaintenanceNode.js server implementing Model Context Protocol (MCP) for filesystem operations.14668,80990,042-
- -licenseNot gradedqualityAmaintenanceThis MCP server integrates with Google Drive to allow listing, reading, and searching over files.6,70090,042MIT
- AlicenseAqualityAmaintenanceThis server enables LLMs to retrieve and process content from web pages, converting HTML to markdown for easier consumption.190,042MIT
- AlicenseAqualityCmaintenanceA Model Context Protocol (MCP) server implementation that integrates with FireCrawl for advanced web scraping capabilities.2640,1397,395MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/brilliantdirectories/brilliant-directories-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server