Skip to main content
Glama

Niche: Your niche, followed for you

Discover stories (signal scan)

niche_signal_scan

Scan a niche you describe, right now (Pro). Returns a ranked, sourced slate of the stories people in that field are talking about, with source links, the outlets, and why it matters. For a ready-made briefing use niche_feed_read instead. Assistant access requires Pro. Poll niche_session_state with the returned session_id until status is cp1_awaiting_story; the slate is in stories.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nicheYesNiche / beat description (2-200 chars). Specific is better.
recencyNoReporting window: 24h, week, month, quarter, or year. Pair with recency_strict for a hard cutoff.
recency_strictNoExclude reporting outside the requested window. Default false; strict windows can return fewer stories.
source_qualityNostrict prioritizes well-supported stories; balanced is the default; broad includes less-established reporting. Inspect the returned sources before relying on a claim.balanced
idempotency_keyNoOptional stable key for retries of the same scan, so a retry reuses the original run.
thinking_budgetNobalanced returns a session_id immediately. fast waits briefly for stories and returns them if ready; otherwise poll niche_session_state.balanced

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changed
    • addedInput schema / additionalProperties
      Added value: +false
    • removedInput schema / properties / brand_id
      Removed value: -{
      -  "description": "Binds this brand's voice, colors, offer, and CTA to the piece. Omit to use your default brand; on a multi-brand account pass the slug explicitly so a post about one product is not bound to another brand's identity. niche_whoami lists your brands.",
      -  "type": "string"
      -}
    • removedInput schema / properties / density
      Removed value: -{
      -  "default": "balanced",
      -  "description": "How tightly to pack visual formats (carousels especially).\n  • minimal: split a dense argument across more, shorter slides; favors skimmability.\n  • balanced (default): the standard per-slide caps.\n  • essay: permissive; allows longer slides/sections.\nOver-cap slides auto-split on sentence boundaries (never mid-sentence); over-280 tweets split into a chain regardless.",
      -  "enum": [
      -    "minimal",
      -    "balanced",
      -    "essay"
      -  ],
      -  "type": "string"
      -}
    • removedInput schema / properties / estimate_only
      Removed value: -{
      -  "default": false,
      -  "description": "When true, return the discovery credit cost without starting a run or holding a reservation. Use it to quote a price before committing.",
      -  "type": "boolean"
      -}
    • changedInput schema / properties / idempotency_key / description
      Previous value: -"Optional. A stable key for this logical scan: a retry with the same key reuses the original run instead of starting (and billing) a second. Even without it, an identical scan fired while one is still running is auto-deduped."New value: +"Optional stable key for retries of the same scan, so a retry reuses the original run."
    • removedInput schema / properties / profile_overrides
      Removed value: -{
      -  "description": "Optional. Deep-merge these overrides onto the persisted profile for this run only. Use case: same brand, different register for a specific piece (e.g. a product-launch voice over an editorial one). Requires brand_id.",
      -  "type": "object"
      -}
    • changedInput schema / properties / recency / description
      Previous value: -"Optional recency window that constrains discovery to fresh sources. One of '24h' | 'week' | 'month' | 'quarter' | 'year' (aliases: 'today'/'day'→24h, 'this week'→week, etc.). Use '24h' for 'today only / breaking'. Putting the demand in the niche string does not constrain recency; use this param. Omit to use the niche's default window."New value: +"Reporting window: 24h, week, month, quarter, or year. Pair with recency_strict for a hard cutoff."
    • changedInput schema / properties / recency_strict / description
      Previous value: -"When true, `recency` is a hard cutoff: sources outside the window are dropped before clustering, so 'nothing older than yesterday' is honored exactly. Default false: the window is a strong bias but older corroborating sources can still attach to a fresh cluster. Set true when exactness matters more than slate depth (strict can thin the slate)."New value: +"Exclude reporting outside the requested window. Default false; strict windows can return fewer stories."
    • changedInput schema / properties / source_quality / description
      Previous value: -"How aggressively to filter the slate on source quality (niche-relative; never penalizes a small publication that is the authority for the niche).\n  • strict: drop uncorroborated single-source silos that aren't a primary/official or a niche authority; surfaces only well-sourced stories. Can thin the slate.\n  • balanced (default): down-weight weak sources, don't drop.\n  • broad: surface everything, including low-coverage emerging clusters, with authority as a tiebreaker only.\nUse strict for a high-trust brief, broad to scout early signal."New value: +"strict prioritizes well-supported stories; balanced is the default; broad includes less-established reporting. Inspect the returned sources before relying on a claim."
    • removedInput schema / properties / target_outputs
      Removed value: -{
      -  "description": "Output cells to generate (platform×content_type matrix). Each cell is a 'platform:content_type' string or a cross-platform content type. Valid cells:\n  • linkedin:text_post: short LinkedIn post (text only)\n  • linkedin:image_post: LinkedIn post plus 1.91:1 image card\n  • linkedin:carousel: multi-slide carousel\n  • linkedin:reel: LinkedIn-native vertical video\n  • x:single_tweet: standalone tweet\n  • x:thread: multi-tweet thread\n  • x:image_post: tweet plus 16:9 image card\n  • x:reel: tweet plus 9:16 video\n  • instagram:image_post: caption plus 4:5 image card\n  • instagram:carousel: multi-image swipe\n  • instagram:reel: caption plus 9:16 reel\n  • long_form_article: universal essay (Substack/blog)\n\nA bare platform name also works and maps to that platform's default cell: 'x'/'twitter'→x:single_tweet (pass 'x:thread' for a thread), 'linkedin'/'li'→linkedin:text_post, 'instagram'/'ig'→instagram:image_post, 'longform'→long_form_article. The resolved cells are echoed back as target_outputs.\nDefaults to ['linkedin:text_post']; request only the cells you need (each additional cell adds generation cost).",
      -  "items": {
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
    • removedInput schema / properties / target_platforms
      Removed value: -{
      -  "description": "Optional. A flat platform list (linkedin, linkedin_carousel, twitter, longform, instagram), coerced into target_outputs cells. Prefer target_outputs.",
      -  "items": {
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
    • changedInput schema / properties / thinking_budget / description
      Previous value: -"Agent-side polling control. A full editorial workflow is structurally 15-20 tool calls (scan, poll, poll, poll, pick, poll, pick, poll, read). Use this to tune how many of those calls collapse into single waits.\n  • fast: scan blocks briefly (up to ~45s, under the tool-call timeout) for CP1 and returns the stories inline when they land in time. One call instead of many polls. Cheaper agent tokens, smaller cognitive surface. If CP1 isn't ready by the cap it still returns the session_id (status=discovering); poll niche_session_state from there, the run is never lost. Pick when you just want stories and the user is waiting.\n  • balanced (default): scan returns immediately with session_id; the agent polls niche_session_state (with wait plus since_status long-poll)."New value: +"balanced returns a session_id immediately. fast waits briefly for stories and returns them if ready; otherwise poll niche_session_state."
  2. Changed1 schema field changed
    • changedInput schema / properties / target_outputs / description
      Previous value: -"Output cells to generate (platform×content_type matrix). Each cell is a 'platform:content_type' string or a cross-platform content type. Valid cells:\n  • linkedin:text_post: short LinkedIn post (text only)\n  • linkedin:image_post: LinkedIn post plus 1.91:1 image card\n  • linkedin:carousel: multi-slide carousel\n  • linkedin:reel: LinkedIn-native vertical video\n  • x:single_tweet: standalone tweet\n  • x:thread: multi-tweet thread\n  • x:image_post: tweet plus 16:9 image card\n  • x:reel: tweet plus 9:16 video\n  • instagram:image_post: caption plus 4:5 image card\n  • instagram:carousel: multi-image swipe\n  • instagram:reel: caption plus 9:16 reel\n  • long_form_article: universal essay (Substack/blog)\n\nA bare platform name also works and maps to that platform's default cell: 'x'/'twitter'→x:thread, 'linkedin'/'li'→linkedin:text_post, 'instagram'/'ig'→instagram:image_post, 'longform'→long_form_article. The resolved cells are echoed back as target_outputs.\nDefaults to ['linkedin:text_post']; request only the cells you need (each additional cell adds generation cost)."New value: +"Output cells to generate (platform×content_type matrix). Each cell is a 'platform:content_type' string or a cross-platform content type. Valid cells:\n  • linkedin:text_post: short LinkedIn post (text only)\n  • linkedin:image_post: LinkedIn post plus 1.91:1 image card\n  • linkedin:carousel: multi-slide carousel\n  • linkedin:reel: LinkedIn-native vertical video\n  • x:single_tweet: standalone tweet\n  • x:thread: multi-tweet thread\n  • x:image_post: tweet plus 16:9 image card\n  • x:reel: tweet plus 9:16 video\n  • instagram:image_post: caption plus 4:5 image card\n  • instagram:carousel: multi-image swipe\n  • instagram:reel: caption plus 9:16 reel\n  • long_form_article: universal essay (Substack/blog)\n\nA bare platform name also works and maps to that platform's default cell: 'x'/'twitter'→x:single_tweet (pass 'x:thread' for a thread), 'linkedin'/'li'→linkedin:text_post, 'instagram'/'ig'→instagram:image_post, 'longform'→long_form_article. The resolved cells are echoed back as target_outputs.\nDefaults to ['linkedin:text_post']; request only the cells you need (each additional cell adds generation cost)."
  3. First observed

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover safety/open-world flags, so the description adds real value: the Pro access requirement, the session-based async lifecycle, the terminal status to poll for, and the idempotency/retry semantics. It does not cover failure modes, timeouts, or cancellation (a niche_session_cancel sibling exists), which keeps it short of full disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with purpose, then alternative, prerequisite, and polling instructions – every sentence carries information. Minor redundancy from stating the Pro requirement twice ('right now (Pro)' and 'Assistant access requires Pro').

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and 6 parameters, the description compensates well by describing the return contents, naming the `stories` field, and explaining the polling loop needed to retrieve results. It omits what to do on failure or how to cancel an in-flight session, which is a modest gap for an async job tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter (niche, recency, recency_strict, source_quality, idempotency_key, thinking_budget) is already documented in the schema, including enum meanings. The description adds no syntax or format detail beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a concrete verb and resource ('Scan a niche you describe, right now') and states the output shape ('ranked, sourced slate of the stories... with source links, the outlets, and why it matters'). It explicitly distinguishes itself from the sibling niche_feed_read, so an agent can route without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the alternative and the condition that selects it ('For a ready-made briefing use niche_feed_read instead') and states the prerequisite ('Assistant access requires Pro'). It also spells out the async completion path: poll niche_session_state with the returned session_id until status is cp1_awaiting_story.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.