ChatFeatured
Grow visibility in AI search
- Category
- Pending
- Primary Subcategory
- Pending
Integration details
Description
ChatFeatured helps brands understand and improve how they appear in AI-generated answers. Users can analyze visibility, competitors, citations, crawler activity, and site health; manage tracked prompts, brand data, opportunities, and tasks; and create, review, schedule, and publish optimized articles to connected content systems.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Category
- Pending
- Primary Subcategory
- Pending
- Secondary Subcategories
- None listed
- Brand
- Unknown
- Access
- Account required
- First tracked
- 2026-09-24
- Tool count
- 41
- Geography
- US
The broad Category that contains the Primary Subcategory.
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for ChatFeatured
Get updates when ChatFeatured’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competitive lineup
41 tools agents can invoke
Check for additional tools whenever your task might benefit from specialized capabilities - even if existing tools could work as a fallback.
get_more_tools
Adds one or more opportunities to the user's task list (writes to the database). Call this ONLY when the user has explicitly asked to add, track, or save an opportunity as a task. This creates a real task that appears on the Tasks page — it is NOT the same as surfacing an opportunity for review. Each opportunity becomes an "opportunity" task with status "open". Duplicates (same type + title already added for this brand) are skipped and reported. Pass the same opportunity fields you would surface (type, title, description, priority, sourceUrls, context) — typically the ones you just surfaced.
Approves pending articles and queues them for content generation. First checks billing limits (trial users: 3 articles/month, paid users: 40 articles/month) and pipeline limits (max unscheduled articles). If limits are reached, returns an error with limitReached=true and a message explaining the limit. Otherwise, manages the writing queue (max 3 articles in draft/review at once) and triggers background content generation. Responses include articleLimits (used / limit / remaining for the monthly article allowance) so you can report how many articles the brand has left. Returns immediately - does not wait for content generation to complete. Approving already STARTS the writing workflow (2-5 minutes in the background) — never also call generate-articles on an article you just approved; that would run generation twice. Use this when users want to approve articles, start writing content, or begin the content creation process.
Archives articles by ID. Releases reserved billing credits for draft/review/queued articles and dismisses associated tasks. Use list_articles with status='archived' to see archived articles, or unarchiveArticle to restore. Prefer this over deleteArticles when articles might be needed later.
Saves article titles with their descriptions and "why" explanations to the database, along with associations to keywords and prompts. Use this after generating your content strategy to persist all article recommendations. Articles whose title already exists for the brand (same slug) are skipped, not saved — they are returned in the "skipped" array so you can tell the user they already exist and avoid re-suggesting them.
Creates a new tracking prompt for the brand. Each prompt is a search query that will be tracked across AI models to monitor brand visibility. Respects billing limits — checks available prompt slots before creating. Geo defaults to ["US"] if not specified. Each geo location uses one prompt slot. The prompt is created as "active" by default and will be picked up by the next scheduled run. The brand ID and user ID are automatically provided from context.
Permanently deletes articles. This cannot be undone. Consider using archiveArticles instead if the articles might be needed later. Cleans up associated tasks before deleting.
Fetches keywords for an organization brand with flexible filtering and sorting options. Returns keyword data including search volume, competition level, and bid estimates. Also returns the total count of keywords available for the brand. Use this to explore available keywords before creating articles or content strategy.
Triggers the article research, writing, and metadata generation workflow for one or more articles. Articles must be in "draft" status (approved). The workflow conducts web research, generates a GEO-optimized article, and creates metadata. Articles typically take 2-5 minutes to complete. NOTE: approve-articles already starts this workflow — do NOT call this for an article you just approved (the duplicate run is rejected). Use this only to restart generation for an article whose previous generation stalled or was interrupted; failed articles (status "error") are retried via the retry flow instead.
Fetches a complete article overview by articleId, including: - Article title, description, why, status, and timestamps - All associated keywords (keyword text, search volume, competition data) - All associated prompts (prompt title and content) Use this to get full details about an article before editing or reviewing it.
Gets the current schedule information for an article. Use this when users want to check when an article is scheduled, verify the scheduled date/time, or see the schedule status before making changes.
Fetches comprehensive brand book information including brand name, industry, categories, and brand description. Use this to understand the brand's context before generating keyword recommendations.
Fetches existing opportunities that have been previously identified for this brand. Use this at the start of analysis to understand what opportunities already exist, so you can avoid suggesting duplicates and focus on new insights. Returns opportunities from the last 30 days with their type, title, and creation date.
Checks the publish/sync status of an article on its connected CMS platform. Returns sync status, external URL, external ID, and platform-specific metadata. Use this after publishing to verify the article reached the external CMS.
Reads actual AI response text from prompt responses. Returns the full text of what AI models said, along with which model generated it, the country, prompt text, and any brand mentions with sentiment context. Use this ONLY when the user explicitly asks about what an AI model said or wants to see actual response content. Do NOT call this proactively — it returns large amounts of text. Use mentionedBrandId to filter to only responses where a specific brand (own or competitor) was mentioned. Use brandMentioned=true as a shorthand to filter to only responses where the user's own brand was mentioned.
Search the brand's knowledge base to find relevant information. Use this tool to retrieve context about the brand, its products, services, competitors, or any custom information that has been added to the knowledge base. The knowledge base contains text, scraped web content, and uploaded documents. NOTE: This tool is only available when the user has enabled Knowledge Base access.
Lists articles for a brand with optional status filtering. Returns a lightweight list with ID, title, status, and creation date. Use this to discover what articles exist, especially to find pending articles that need approval or to check article statuses. Much more efficient than fetching full article details. The brand ID is automatically provided from context - do not pass organizationBrandId.
Lists all brands the user has access to, optionally filtered by organization. Use the returned brand ID as the `brandId` argument for other tools.
Fetches all competitors configured for the current brand. Returns each competitor group with its display name, domain, associated brands, and total mention count across all AI model responses. The brand ID is automatically provided from context.
Lists all CMS integrations connected to the brand (WordPress, Ghost, Webflow, Framer, Shopify, Git-based CMS) and the ChatFeatured CMS with available authors. Shows integration type, active status, connection health, and platform-specific details. For Ghost: returns available authors (with emails) and tags — you MUST pass an authorEmail when publishing to Ghost. When the brand's ChatFeatured CMS site is enabled it is a publish destination alongside integrations — address it in publishArticle with integrationId "chatfeatured-cms". Returns available authors — pass authorIds when publishing or scheduling. Use this before publishing to see what options are available for each platform.
Lists all organizations the authenticated user is a member of, including their role in each. Next step: list_brands to see available brands.
Fetches the prompts for an organization brand. Returns prompt IDs, text content, status, geo targeting, tags, and metadata. Inactive (deactivated) prompts are excluded by default — pass includeInactive: true only when the user explicitly asks about deactivated/old prompts. Use this to see what prompts are available when associating articles with prompts. Tags can be used to filter prompts by category/topic when querying analytics. The brand ID is automatically provided from context.
Fetches all tags for the current brand. Returns tag IDs, names, colors, and how many prompts each tag is associated with. The brand ID is automatically provided from context.
Lists tasks for the brand (read-only). Use to answer "what tasks do I have?", to check progress, or to find a task's ID before updating its status. Filter by status and/or task type. Returns the taskId for follow-up calls — refer to tasks by title in your replies, never by ID.
Manages brand personas for the current brand. Use action "list" to get all personas, "create" to add a new one, "update" to modify an existing one, or "delete" to remove one. The brand ID is automatically provided from context.
Add, update, or remove competitors for the current brand. - "add": Creates a new competitor group. Requires name and domain. Will reject if a competitor with the same name or domain already exists. - "update": Updates an existing competitor's display name and/or domain. Requires competitorGroupId. - "remove": Deletes a competitor group. Requires competitorGroupId. - "add_brand": Adds a brand to an existing competitor group (confirms a fuzzy suggestion). Requires competitorGroupId and memberBrandId. - "ignore_brand": Marks a suggested brand as NOT belonging to this competitor (user said "No"). Requires competitorGroupId and memberBrandId. The brand won't be suggested again for this competitor. - "remove_brand": Removes a brand from a competitor group. Requires competitorGroupId and memberBrandId. The (organization) brand ID is automatically provided from context.
Creates, updates, or deletes tags for the current brand. Use action "create" to create a new tag with a name and optional color. Use action "update" to rename or recolor an existing tag, or change its prompt associations. Use action "delete" to remove a tag entirely (cascades to prompt associations). The brand ID is automatically provided from context.
Publishes an article to one of the brand's publish destinations: a connected CMS integration (WordPress, Ghost, Webflow, Framer, Shopify, Git-based CMS) or the ChatFeatured CMS when the brand's cms site is live. Brands can have multiple destinations (even several integrations of the same type, e.g. two WordPress sites): pass integrationId to pick one — use "chatfeatured-cms" for the ChatFeatured CMS. With a single destination it is chosen automatically; with several and no integrationId the call fails and lists the options. If no destination exists, marks the article as published locally. Article must be in review, scheduled, or draft status. An article whose content is still being written cannot be published — the call fails while generation is in progress. Wait for the generation-completed notification, then publish. Use listIntegrations first to see connected integrations and their ids, then call this to publish.
Generic analytics query tool that replaces all individual analytics tools. Supports presets for common queries and custom dimensions/metrics/filters for ad-hoc analysis. ## Presets (use these first, override fields as needed): - brand_overview: Brand visibility & sentiment by prompt and model - competitor_comparison: Brand vs competitor visibility/sentiment/mentions by prompt - source_analysis: Top cited sources per prompt (top 5 per prompt) - time_comparison: Visibility & sentiment changes vs previous period, by prompt and model - source_changes: Sources that appeared/disappeared vs previous period (sorted by delta) - cited_urls: Top 50 cited source URLs, each with its citation count AND the number of distinct prompts citing it (prompt_count) - cited_urls_by_platform: Same as cited_urls but each row ALSO includes citationsByModel — citations split by AI platform (ChatGPT, Perplexity, Google AI, Gemini, etc.). Use this for the full "source URL + citations + prompts + per-platform split" report in ONE query. - source_mentions: Top 50 cited domains, each with its citation count AND the number of distinct prompts citing it (prompt_count) ## Common query patterns: - Brand overview: { preset: "brand_overview" } - What changed this week: { preset: "time_comparison" } - Source changes (appeared/disappeared): { preset: "source_changes" } - Competitor comparison: { preset: "competitor_comparison" } - Top sources per prompt: { preset: "source_analysis" } - Top source URLs by citations AND how many prompts cite each: { preset: "cited_urls" } - Top source domains by citations AND how many prompts cite each: { preset: "source_mentions" } - Source URLs ranked by how many distinct prompts cite them: { preset: "cited_urls", sortBy: "prompt_count" } - Top source URLs with citations, prompts, AND per-platform (ChatGPT/Perplexity/Google AI) citation split: { preset: "cited_urls_by_platform" } — read citationsByModel on each row; it sums to current.citations, and whether the brand was found in the source is on source.brandFoundInSource - Source changes for specific prompt: { preset: "source_changes", filters: { prompts: ["id"] } } - All prompts with a specific tag: { preset: "brand_overview", filters: { tags: ["tagId"] } } - Which models dropped visibility: { metrics: ["visibility"], groupBy: ["model"], compareWithPrevious: true, sortBy: "delta.visibility", sortDirection: "asc" } - Sources only where brand is mentioned: { preset: "source_analysis", filters: { brandPresence: "mentioned" } } - Where am I not showing up: { preset: "brand_overview", filters: { brandPresence: "not_mentioned" } } - Are competitors citing new sources: { metrics: ["citations"], groupBy: ["source", "competitor"], compareWithPrevious: true } ## Sort options: - Sort by current metric: sortBy: "visibility", "sentiment", "citations", "mention_count", "prompt_count" - Sort by delta: sortBy: "delta.visibility", "delta.citations", etc. - Sort by previous: sortBy: "previous.visibility", etc. ## Reading results — quoting numbers accurately: - visibility = % of AI runs (among runs where at least one brand was mentioned) where THIS brand appears. This is the exact formula the dashboard uses, so the values here match the dashboard. - meta.summary.current holds the OVERALL metrics for the entire filtered period (plus meta.summary.previous / meta.summary.delta when comparing periods). For any headline number — "what's my visibility?", "how's my sentiment?" — quote meta.summary, which matches the dashboard's top-level widgets. - NEVER average per-row visibility/sentiment values to produce an overall figure: rows cover different numbers of runs, so an unweighted average is wrong and will not match the dashboard. Rows are for per-prompt/per-model/per-competitor detail only.
Advanced analytics tool: run a single READ-ONLY PostgreSQL SELECT over THIS brand's AI-search data. Use it for complex or custom analysis the queryAnalyticsTool presets can't express — per-day/per-week trends, visibility or share-of-voice over time, source/domain breakdowns, custom pivots, distinct counts, or any custom grouping. (queryAnalyticsTool is still the quickest path for its standard preset reports.) Your query is AUTOMATICALLY scoped to the current brand — never add an organization/brand filter (it is injected server-side and you cannot see other brands). TIP: call this tool with explain:true to get the full schema PLUS this brand's actual competitor group names and tag names (returned as competitorGroups / tags). Do that first whenever you need an exact competitor or tag label to filter on — don't guess it. RELATIONS YOU MAY QUERY (these are the only names allowed; call with explain:true for full column lists): - mentions(created_at, prompt_run_id, prompt_response_id, prompt_id, model, country, brand_id, brand_name, sentiment, tags, is_self, competitor_group) — ONE ROW PER BRAND MENTIONED in an AI response. INCLUDES COMPETITORS. Use is_self (server-computed boolean) for YOUR brand and competitor_group to compare specific competitors (see SELF / COMPETITORS). Visibility is computed from this relation alone — see VISIBILITY. - citations(created_at, prompt_run_id, prompt_response_id, prompt_id, model, country, source_domain, source_type, source_url, source_title, citation_count, tags, brand_found_in_source) — one row per source citation in an AI response. brand_found_in_source (nullable boolean, server-computed) = was YOUR brand actually found on the cited page (TRUE features you, FALSE verified-absent, NULL not verified) — use WHERE brand_found_in_source for "sources that feature my brand". - runs(prompt_run_id, prompt_id, model, country, created_at) — the FULL universe of completed AI runs, INCLUDING runs that mentioned nobody. Use it for run counts and coverage questions (how many runs executed, per model/day). It is NOT the visibility denominator — see VISIBILITY. - competitor_dim(competitor_group, competitor_domain) — the brand's configured competitor groups (use to discover/list competitors). - prompt_dim(prompt_id, prompt_text) — the brand's tracked prompts. INACTIVE prompts are excluded everywhere (prompt_dim, runs, mentions, citations) — deactivated prompts and their historical runs never appear in results. - tag_dim(tag_id, name) — the brand's tags. - prompt_tag_dim(prompt_id, tag_id) — which prompts have which tags. SELF / COMPETITORS / VISIBILITY (use the server flags — never hard-code brand names): - YOUR brand = WHERE is_self. - A specific COMPETITOR = filter on competitor_group, NOT brand_name (one competitor spans several brand_name variants; competitor_group groups them). competitor_group is the configured DISPLAY NAME and is CASE-SENSITIVE (e.g. 'Semrush', 'HubSpot' — not 'semrush'). NEVER compare it with '=' and a guessed literal — a case/spelling mismatch silently returns 0 rows and looks like the competitor has no presence. Instead match case-insensitively with ILIKE: WHERE competitor_group ILIKE 'semrush' (no wildcards = case-insensitive exact), or resolve the exact stored label inside the query: WHERE competitor_group IN (SELECT competitor_group FROM competitor_dim WHERE competitor_group ILIKE '%semrush%'). Discover the exact labels with SELECT competitor_group FROM competitor_dim ORDER BY 1, or call this tool with explain:true (it lists this brand's competitor groups + tags). - If a named-competitor filter returns 0 / no rows, DO NOT conclude the competitor has no visibility — it almost always means the label didn't match. Re-list competitor_dim and retry with the exact label (via ILIKE) before reporting anything. - VISIBILITY (matches the dashboard) over a group = 100.0 * COUNT(DISTINCT prompt_run_id) FILTER (WHERE is_self) / NULLIF(COUNT(DISTINCT prompt_run_id), 0) over `mentions` — the denominator is runs with AT LEAST ONE brand mention (any brand), computed from mentions itself. Do NOT divide by the `runs` relation (it counts zero-mention runs too and understates visibility vs the dashboard), and do NOT ratio raw mention ROW counts without DISTINCT prompt_run_id (that's share-of-voice and trends ~100%). Works for you (is_self) or a competitor (competitor_group in the FILTER). - SHARE-OF-VOICE (your share of all brand mentions) = COUNT(*) FILTER (WHERE is_self) / COUNT(*) over mentions in the group (no runs needed). - selfBrandResolved: the result includes this flag. If false, this brand has no entry in the mention index (is_self all false), which almost always means it has genuinely never been mentioned. Report the 0% as the real answer and say the brand has not been detected in any tracked AI response yet. KEY FACTS: - model holds the clean model NAME for filtering, grouping, AND results, and these are the ONLY values that exist: ChatGPT, Perplexity, Google AI, Gemini, Claude, Grok, Copilot. WHERE model = 'ChatGPT' just works. Values are case-sensitive — copy them exactly. If a model filter returns 0 rows, re-check against this list — never invent other spellings or ids. - Filter time on created_at, e.g. WHERE created_at >= now() - interval '30 days'. - runs, mentions, and citations SHARE column names (prompt_run_id, prompt_id, model, country, created_at). When you join them, alias each relation and qualify EVERY column reference — in SELECT, GROUP BY, and ORDER BY too (r.model, not model) — or the query fails as ambiguous. - Never reuse an existing column name as a SELECT alias for a different expression (e.g. AS source_type on citations) — GROUP BY/ORDER BY then resolve to the real column, not your alias. Pick a fresh name. - When joining, put the created_at window on EVERY joined relation (in the JOIN's subquery or ON/WHERE), not just one side — an unfiltered side is scanned in full and can time out. Compare several brands with one pass and conditional aggregates (COUNT(DISTINCT ...) FILTER (WHERE ...)), never one mentions join per brand. - tags is text[]: filter with 'tagname' = ANY(tags), or join prompt_tag_dim/tag_dim by name. - YOUR brand = WHERE is_self. A specific competitor = WHERE competitor_group ILIKE '<name>' (case-insensitive — competitor_group is a case-sensitive display label, so never use '='; groups brand variants, brand_name does not). MORE RECIPES: - citations = SUM(citation_count); prompt_count = COUNT(DISTINCT prompt_id) - mention counts by brand = COUNT(*) or COUNT(DISTINCT prompt_run_id) GROUP BY brand_name - your sentiment = AVG(sentiment) WHERE is_self RULES: - Single SELECT (or WITH … SELECT). No DDL/DML, no '$' placeholders, no RECURSIVE CTEs. These are rejected. Set-returning functions like generate_series() are allowed — use one instead of a recursive CTE to build a date series. - Results are HARD-CAPPED at 1000 rows. For overviews/averages, aggregate in SQL — do NOT add a small LIMIT, it corrupts the aggregate. Add LIMIT only for explicit top-N rankings. - Results are ALSO capped at ~200,000 serialized characters. An oversized result is refused with an error and NO rows, never shortened. Wide text columns (prompt_text, response_text) across many rows are what trigger it. Aggregate in SQL, select fewer columns, or narrow the range, then try again. - Returns { columns, rows, rowCount, truncated, sql, selfBrandResolved }. If truncated is true, more rows exist — aggregate or narrow the range. If selfBrandResolved is false, read the accompanying notice before describing self-metrics. EXAMPLES: -- Your visibility by week (dashboard formula: % of runs with any brand mention that mention YOU) since you started SELECT date_trunc('week', created_at) AS week, COUNT(DISTINCT prompt_run_id) AS runs_with_any_mention, COUNT(DISTINCT prompt_run_id) FILTER (WHERE is_self) AS runs_with_you, ROUND(100.0 * COUNT(DISTINCT prompt_run_id) FILTER (WHERE is_self) / NULLIF(COUNT(DISTINCT prompt_run_id), 0), 2) AS visibility_pct FROM mentions GROUP BY week ORDER BY week -- Share of voice vs competitors, last 30 days SELECT ROUND(100.0 * COUNT(*) FILTER (WHERE is_self) / NULLIF(COUNT(*), 0), 2) AS share_of_voice_pct, COUNT(*) FILTER (WHERE is_self) AS your_mentions, COUNT(*) AS all_mentions FROM mentions WHERE created_at >= now() - interval '30 days' -- Your visibility vs a SPECIFIC named competitor (e.g. "Semrush"), last 90 days — one pass over mentions. -- Matches competitor_group case-insensitively (ILIKE), so 'Semrush' resolves from "semrush". -- If competitor_runs is 0 here, the label likely didn't match — list competitor_dim, don't report 0%. SELECT COUNT(DISTINCT prompt_run_id) AS runs_with_any_mention, COUNT(DISTINCT prompt_run_id) FILTER (WHERE is_self) AS your_runs, ROUND(100.0 * COUNT(DISTINCT prompt_run_id) FILTER (WHERE is_self) / NULLIF(COUNT(DISTINCT prompt_run_id), 0), 2) AS your_visibility_pct, COUNT(DISTINCT prompt_run_id) FILTER (WHERE competitor_group ILIKE 'semrush') AS competitor_runs, ROUND(100.0 * COUNT(DISTINCT prompt_run_id) FILTER (WHERE competitor_group ILIKE 'semrush') / NULLIF(COUNT(DISTINCT prompt_run_id), 0), 2) AS competitor_visibility_pct FROM mentions WHERE created_at >= now() - interval '90 days' -- You vs each competitor group: share of all brand mentions, last 30 days SELECT CASE WHEN is_self THEN 'You' ELSE COALESCE(competitor_group, 'Other') END AS brand_group, COUNT(*) AS mentions, ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 2) AS share_pct FROM mentions WHERE created_at >= now() - interval '30 days' GROUP BY brand_group ORDER BY mentions DESC -- How often each brand (incl. competitors) is mentioned — COUNTS, not visibility — last 30 days SELECT brand_name, COUNT(*) AS mention_rows, COUNT(DISTINCT prompt_run_id) AS runs_mentioning FROM mentions WHERE created_at >= now() - interval '30 days' GROUP BY brand_name ORDER BY mention_rows DESC LIMIT 25 -- Top cited source URLs with citation totals and how many distinct prompts cite each, last 30 days SELECT source_url, SUM(citation_count) AS citations, COUNT(DISTINCT prompt_id) AS prompt_count FROM citations WHERE created_at >= now() - interval '30 days' GROUP BY source_url ORDER BY citations DESC LIMIT 25 -- Sources that actually FEATURE your brand, ranked by citations, last 90 days SELECT source_domain, source_url, SUM(citation_count) AS citations FROM citations WHERE brand_found_in_source AND created_at >= now() - interval '90 days' GROUP BY source_domain, source_url ORDER BY citations DESC LIMIT 25 -- Pivot: citations per source domain split by platform (one query, no manual merge) SELECT source_domain, SUM(CASE WHEN model = 'ChatGPT' THEN citation_count ELSE 0 END) AS chatgpt, SUM(CASE WHEN model = 'Perplexity' THEN citation_count ELSE 0 END) AS perplexity, SUM(citation_count) AS total FROM citations WHERE created_at >= now() - interval '30 days' GROUP BY source_domain ORDER BY total DESC LIMIT 25 -- Citations per day (time series), last 30 days SELECT date_trunc('day', created_at) AS day, SUM(citation_count) AS citations FROM citations WHERE created_at >= now() - interval '30 days' GROUP BY day ORDER BY day
Queries AI crawler/agent analytics data from Tinybird. Shows how AI crawlers (ChatGPT, Claude, Perplexity) are visiting the brand's website. Query types: - "stats": Request counts per crawler type (ChatGPT, Claude, Perplexity) with period-over-period change % - "timeseries": Daily breakdown by crawler type for charting trends - "top_pages": Most visited host+pathname pairs by crawlers (top 20) - "top_crawlers": Most active crawler agents (top 20) - "page_detail": Per-page, per-crawler breakdown with visit counts and first/last seen dates. Use with "pages" filter to check specific URLs. - "logs": Raw crawler log entries (most recent 100). Use with "pages" and/or "crawlers" filters to investigate specific crawl events. - "search_pages": Discover all crawled pages. Use "pathPattern" for LIKE filtering (e.g. "%/blog/%"). Use this when users ask about: - Which AI bots are crawling their site - How often ChatGPT/Claude/Perplexity visit - Which pages are being crawled most - Crawler activity trends over time - Whether a specific page/article has been crawled - Raw crawl event details for a page Semantics of this dataset: - It records only requests that REACHED the site. A block (firewall, WAF, robots.txt) produces no row at all, never an error row. This data can therefore never show that a crawler is blocked, and any row for a crawler proves it is not. - A brand can span several hosts (apex domain, blog subdomain). Every page-level row carries "host" — always read host + pathname together. - "status" is null when no HTTP status was recorded (always the case on the ChatFeatured CMS, where hits are logged before a response exists). Null means unknown, not an error. - "agent_type" is the self-reported User-Agent and is NOT verified. Vulnerability scanners spoof well-known bots (usually Googlebot) while probing for exploits — requests to /wp-login.php, /wp-content/*, /wp-admin/*, /xmlrpc.php, /.env are scanner traffic, not real crawls. Every public domain gets them, whatever it runs on. Never treat such rows as evidence of the site's CMS or hosting stack, and don't count them as crawler interest in a page.
Query site audit data for the brand's website. Supports multiple query types: - "overview": Run counts by status + latest run, page counts by audit status, average scores, and open-issue counts - "pages_needing_improvement": Pages ranked by lowest scores with their open issues (audited pages only) - "open_issues": All open issues grouped by category and check type - "page_detail": Detailed scores and issues for a single page; pass the page's URL in "pageUrl". Over MCP there is no current-page context, so "pageUrl" is required here; in the in-app chat it defaults to the page in view. - "run_status": Status of the last 5 audit runs Semantics: a run maps the brand's configured domain and DISCOVERS pages; each page is then scored only when the user runs it from the Site Audit page. Read "pages.byStatus" to tell those cases apart — "not_audited" means nobody has run that page, "failed" means the audit ran and could not fetch or score it. Only "failed" pages (or a failed run, see "runs.byStatus" and "runs.latest.errorMessage") indicate something went wrong; a large "not_audited" count is just unused coverage. Scores and issue counts describe the audited pages only. The audit does not follow links onto other hosts — a subdomain needs its own audit.
Manages article publishing schedule - can schedule, reschedule, or cancel. Use action "schedule" to: - Set a publish date for an article (article must be in "review" status) - Change the date for an already scheduled article (automatically detects and reschedules) Use action "cancel" to: - Remove the scheduled publish date (article must be in "scheduled" status) - Article status will change back to "review" Pass integrationId (from listIntegrations) to schedule the publish on a specific CMS integration — the platform then publishes it at the scheduled time. Without it the article simply flips to published at the scheduled time (or commits to the repo when the brand has a Git-based CMS connected). The tool automatically handles whether this is a new schedule or a reschedule.
Searches Pexels for stock photos to use as a featured image for an article. Returns a list of photos with preview URLs, photographer info, and dimensions. Use this to find a suitable featured image, then call setArticleFeaturedImage with the chosen photo details.
Downloads a Pexels photo and sets it as an article's featured image. Use searchPexelsImages first to find photos, then pass the chosen photo's details here. This downloads the image to R2 storage and updates the article's featuredImageUrl and attribution metadata.
Restores an archived article to its appropriate status: - If it was published → "published" - If it was scheduled → "scheduled" - Otherwise → "review" Only works on articles with "archived" status.
Updates an article and its associations to keywords and prompts. Can update article title, description, and why fields. Can add new keyword/prompt associations and remove existing ones. Use this when you need to modify an article's content or its keyword/prompt relationships.
Updates brand book fields for the current brand. Supports partial updates — only provided fields will be changed. Fetches the current brand book first and merges the provided fields before saving. The brand ID is automatically provided from context.
Updates an existing tracking prompt's text, geo targeting, or tags. Use this when users want to change what a prompt says, add/remove countries, or change tag assignments. To update multiple prompts with the same geo or tags, pass promptIds once instead of calling this tool repeatedly. At least one of promptText, geo, or tags must be provided. promptText can only be changed for a single prompt. When updating geo, billing slot limits are checked (each country uses one slot). The brand ID is automatically provided from context.
Activates or deactivates tracking prompts. When activating, checks billing limits to ensure there are enough prompt slots available. When deactivating, frees up prompt slots for other prompts. Use this when users want to pause/resume tracking for specific prompts. The brand ID is automatically provided from context.
Updates a task's status. Use to mark a task completed, dismissed, in progress, or to reopen it (open). Find the taskId first with list-tasks. Only call when the user asks to change a task's status.
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.