Skip to main content
Glama
Ownership verified

Server Details

Find the stories worth writing about: discover emerging stories, rank the angle, draft from sources.

Status
Healthy
Last Tested
Transport
Streamable HTTP
URL
Repository
sailquery/niche-mcp
GitHub Stars
0
Server Listing
Niche MCP

Glama MCP Gateway

Connect through Glama MCP Gateway for full control over tool access and complete visibility into every call.

MCP client
Glama
MCP server

Full call logging

Every tool call is logged with complete inputs and outputs, so you can debug issues and audit what your agents are doing.

Tool access control

Enable or disable individual tools per connector, so you decide what your agents can and cannot do.

Managed credentials

Glama handles OAuth flows, token storage, and automatic rotation, so credentials never expire on your clients.

Usage analytics

See which tools your agents call, how often, and when, so you can understand usage patterns and catch anomalies.

100% free. Your data is private.
Tool DescriptionsA

Average 4.7/5 across 25 of 25 tools scored. Lowest: 4.1/5.

Server CoherenceA
Disambiguation4/5

Tools are mostly distinct across the pipeline—discovery, brand setup, drafting, rendering, publishing, session management—and descriptions are detailed. Minor overlap exists between niche_signal_scan and niche_intelligence_query (both discovery) and between niche_add_output and niche_draft_create (both generate outputs), but the descriptions clearly differentiate them. Overall, an agent can reliably select the right tool.

Naming Consistency3/5

All tools share the `niche_` prefix and snake_case, but the verb/noun order is inconsistent: some are verb-first (add_output, render_image_card, list_sessions) while many are noun-first (angle_propose, brand_kit_ingest, draft_create, session_cancel). This mixed convention requires the agent to learn each name individually rather than predict the pattern.

Tool Count3/5

25 tools is on the heavy side but appropriate for the platform's scope—full editorial intelligence from discovery to publish. No redundant tools, and each covers a distinct aspect, but the count is high enough that it feels dense and may require orientation (which niche_whoami addresses).

Completeness4/5

The toolset covers the full workflow: discovery, angle proposal, drafting, revision, publishing, rendering, asset attachment, brand setup, and session management. Minor gaps exist, such as no direct read tool for the current BrandKit (only via ingest status) and no hard-delete tool (session_cancel mentions the REST endpoint instead), but these are edge cases and agents can work around them.

Available Tools

25 tools
niche_add_outputAdd an outputAInspect

Add an output cell to a session that's already reached CP3. Use this when the user picked a small initial cell set, previewed the drafts, and now wants another surface (e.g. the session started with linkedin:text_post and the user wants to add instagram:carousel too).

Text-only cells (linkedin:text_post, x:thread, long_form_article, etc.): generates text via the matching generator if it hasn't run yet, then creates the Output row. This call blocks synchronously ~20-30s when it must run a new generator family (no status to poll); it returns fast when that family already generated. Idempotent: if the cell is already on the session, returns the existing Output unchanged.

Asset cells (linkedin:image_post, x:reel, instagram:image_post, etc.): creates the text Output row; image-bearing cells auto-attach a free branded card (static_urls populated without an explicit render, swappable anytime), while video/reel assets are never auto-rendered. The response's next_step says exactly what to call for more: niche_render_image_card (cell plus an explicit background: 'photo' or 'brand_color') or niche_render_reel (cell). The response's copy_lineage says whether this cell drafted fresh text or shares its generator family's existing copy.

Remove: pass remove_cell to delete a produced cell the user no longer wants on this run. Idempotent: a clean message when the cell isn't present.

Errors: 400 if session is pre-CP3; 422 if cell is invalid.

ParametersJSON Schema
NameRequiredDescriptionDefault
cellNoCell to add. Must be one of the valid cells (see niche_signal_scan's target_outputs for the list).
session_idYes
remove_cellNoCell to remove from this run (deletes the produced output). Idempotent: a no-op message when the cell isn't present. Pass this instead of `cell` to remove rather than add.
estimate_onlyNoWhen true, return the credit cost of adding this cell without creating a row or generating. Returns 0 when the cell's platform family already generated (text is reused).
Behavior5/5

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

The description goes far beyond the minimal annotations (readOnlyHint=false, destructiveHint=false). It discloses blocking behavior (~20-30s), idempotency, auto-attachment of branded cards for image cells, no auto-render for video/reel assets, next_step guidance, copy_lineage semantics, and error conditions (400 pre-CP3, 422 invalid cell). This is rich behavioral context that an agent needs to invoke correctly and set user expectations.

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

Conciseness5/5

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

The description is structured in clear paragraphs: purpose/usage, text vs asset behavior, next_step guidance, removal, and errors. Each sentence contributes meaningful information; no filler or repetition beyond the necessary emphasis on idempotency (which is important). For a tool with this complexity, the length is justified and front-loaded with the core purpose.

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

Completeness5/5

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

Despite having no output schema, the description fully explains what the response contains (next_step, copy_lineage) and covers all major behaviors: adding text/asset cells, blocking, idempotency, auto-rendering rules, removal, and error cases. Given the tool's complexity (4 params, multiple cell types, sub-operations), this description is complete and leaves no critical gaps.

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 75%, with cell, remove_cell, and estimate_only already described. The description adds usage context (e.g., text-only vs asset cells) but does not significantly elaborate on parameter syntax beyond the schema. It reinforces that remove_cell is an alternative to cell, but the schema already states this. Since schema does the heavy lifting and the description adds marginal parameter-specific value, a baseline 3 is appropriate.

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 opens with a specific verb and resource: 'Add an output cell to a session that's already reached CP3.' It clearly distinguishes from sibling tools like niche_render_image_card and niche_render_reel by stating when to use and what the response's next_step directs to. It also differentiates text-only vs asset cells, making the tool's scope and behavior unambiguous.

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?

The description provides explicit when-to-use context: 'Use this when the user picked a small initial cell set, previewed the drafts, and now wants another surface.' It also names alternatives (niche_render_image_card, niche_render_reel) and explains the removal path via remove_cell. This is a clear usage guideline that distinguishes this tool from siblings.

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

niche_angle_proposePropose anglesAInspect

Niche content angles: pick a story from the discovery slate and surface the strongest angles worth publishing, the editorial-judgment step that turns a development into a piece. Returns five angles[], each with frame, hook, tension, cta_direction, and cta_variants (a swap palette). niche_session_state then carries an angle_recommendation (recommended_angle_id plus reasoning); when a brand profile is bound it is brand-fit-scored, otherwise recommended_angle_id is null with recommendation_basis='default_ordering' (no invented pick). Returns immediately with status=cp2_generating; poll niche_session_state until angles[] is populated.

Custom framing (provenance-preserving): to draft your own angle on this researched story, not one of the proposed five, pass custom_framing (after the story is locked and angles are ready). The framing is shaped onto the real story and drafted on this session, so the trust block keeps the story's actual sources. Use this instead of niche_draft_direct when you have a researched story in hand; draft_direct works from your take alone, so it has no researched sources to cite.

Regenerate: pass regenerate=true (story locked, angles ready) for a fresh set of five angles on the same story; pair with lens to steer the rerun. Capped per session and metered like a generation.

ParametersJSON Schema
NameRequiredDescriptionDefault
lensNoOptional steer (e.g. 'more contrarian', 'lead with the data'). Read on a regenerate run, and as a fallback steer for a custom_framing draft when custom_framing is set without its own wording.
story_idYesid from niche_session_state.stories[].id
regenerateNoGenerate a fresh set of angles on the locked story instead of returning the existing set. Requires the story locked and angles ready. Capped per session; metered like a generation.
session_idYes
custom_framingNoOptional. Your own angle in a sentence ('the contrarian take: X is overhyped because Y'). When set, drafts that angle on the real story (provenance preserved) instead of returning the proposed five. Requires the story locked and angles ready (cp2_awaiting_angle).
Behavior5/5

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

The description goes well beyond annotations: it discloses asynchronous behavior (status=cp2_generating, poll niche_session_state), brand-fit scoring logic, the fallback recommendation_basis='default_ordering' when no brand profile is bound, and per-session caps/metering. 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.

Conciseness5/5

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

Despite its length, the description is well-organized into sections (main behavior, custom framing, regenerate) with bolded key terms. Each sentence contributes operational detail—no fluff—and critical info is front-loaded.

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

Completeness5/5

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

The description fully specifies return shape (five angles[] with fields, angle_recommendation, status), the async poll pattern, and edge cases (no brand profile, capped sessions). With no output schema, it takes on the burden and succeeds; an agent can invoke and interpret results correctly.

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

Parameters4/5

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

Schema coverage is 80% (4/5 params documented). The description adds extra meaning beyond schema, e.g., lens is 'read on a regenerate run, and as a fallback steer for custom_framing', and custom_framing 'drafts that angle on the real story... instead of returning the proposed five'. Only session_id remains undocumented, but its purpose is self-evident.

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 clearly states the verb+resource: 'pick a story from the discovery slate and surface the strongest angles worth publishing'. It also explicitly differentiates from sibling tool niche_draft_direct by explaining when to use custom_framing instead, thus distinguishing from alternatives.

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?

The description provides explicit usage guidance: 'Use this instead of niche_draft_direct when you have a researched story in hand; draft_direct works from your take alone'. It also establishes clear preconditions for custom_framing and regenerate (story locked, angles ready), and explains the async polling workflow.

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

niche_attach_imageAttach a user-supplied photoAInspect

Upload or attach a user-supplied or externally-designed image (bring-your-own asset) to a post: the creator's own visual (a product shot, their actual work, a card designed elsewhere) instead of an AI-generated image (niche_render_image_card photo, paid) or a flat brand card. Free, with no image-generation spend. For a visual-product maker the real piece is the sale.

Input modes, in order of preference: (1) upload_ref, the FAST path for an agent that built the asset itself and can run a shell: POST the raw file to /asset/upload (multipart/form-data, your bearer token) to get back an upload_ref, then pass it here. The bytes travel over HTTP and never round-trip through the model as base64, so it's effectively instant for a real graphic. (2) image_url, a fetchable https URL (the server fetches + stores it; for an asset that already lives on the web). (3) image: {mime_type, data_base64}, inline base64, fine for small images only. (4) image_chunk, the no-shell FALLBACK: upload bounded chunks of base64. It still re-types the bytes through the model (slow), so use it only when the agent has no shell to curl with. Split the file's bytes into ~32-48KB pieces, base64 EACH independently, send in order, each with a sha256 of that piece's raw bytes so the server catches a mis-transcribed chunk and has you resend just that one (this is what makes the slow path reliable). Omit upload_id on the first chunk; the response returns one to pass on the rest. Set final:true on the last chunk (optionally with total_sha256); that call assembles, validates, and attaches.

The cell's output must already exist (use niche_add_output first if needed). Sets it as the post's image; publishes with the caption. A dimension_note warns if the image's aspect won't fit the cell. Undo-able (the prior image is kept in history).

ParametersJSON Schema
NameRequiredDescriptionDefault
cellYesPost cell to attach onto (e.g. 'linkedin:image_post', 'x:image_post', 'instagram:image_post').
imageNoInline image as base64: {mime_type, data_base64} (plus optional name). Max 8MB, but large inline payloads are unreliable over MCP, so prefer upload_ref or image_url. One of upload_ref / image_url / image / image_chunk is required.
image_urlNoA fetchable image URL (https). For an asset that already lives on the web: the server fetches and stores it, so you don't inline a large base64 payload. One of upload_ref / image_url / image / image_chunk is required.
session_idYes
upload_refNoFAST bring-your-own path. First POST the raw file to /asset/upload (multipart/form-data field 'file', Authorization: Bearer <token>); the response returns an upload_ref. Pass it here. The bytes go over HTTP, not through the model, so it's instant for a real graphic. Preferred whenever the agent can run a shell.
image_chunkNoChunked upload for bring-your-own bytes you hold locally (no URL). Split the file's BYTES into ~32-48KB pieces, base64-encode EACH piece, send in order. Always include a per-chunk `sha256` (hex of that piece's raw bytes): the server verifies it and rejects a mis-transcribed chunk so you resend just that one, which is what makes this path reliable (valid base64 can still decode to wrong bytes and silently corrupt the image). Omit upload_id on the first chunk (the response returns one); set final:true on the last, optionally with `total_sha256` of the whole file.
Behavior5/5

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

Despite annotations being minimal (all false), the description adds rich behavioral context: it is free with no image-generation spend, undo-able with prior image preserved, publishes with caption, warns via dimension_note, and details the HTTP upload path avoiding base64 round-trip. No annotation contradictions.

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?

The description is long but well-organized with numbered input modes and bolded labels. It is front-loaded with the core purpose. However, there is some redundancy with the schema's image_chunk details, making it slightly more verbose than necessary, though each section earns its place.

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

Completeness5/5

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

For a complex tool with four input modes, the description covers all input paths, prerequisites, output behavior (sets post image, publishes), cost, undo capability, and performance trade-offs. Since there is no output schema, it compensates by explaining the result clearly. It is exceptionally complete.

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

Parameters5/5

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

Schema coverage is high (83%), but the description adds substantial meaning beyond the schema: it explains the full upload_ref workflow (POST to /asset/upload with bearer token), chunk size and sha256 integrity mechanics, and clarifies the 'one of upload_ref/image_url/image/image_chunk' requirement not enforced by the schema.

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 clearly states the tool's function: 'Upload or attach a user-supplied or externally-designed image... to a post.' It distinguishes from sibling tools by explicitly contrasting with niche_render_image_card (AI-generated image) and flat brand cards, 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.

Usage Guidelines5/5

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

Provides explicit when-to-use guidance and alternatives: names niche_render_image_card as the alternative for AI-generated images, gives a prioritized input-mode order (upload_ref, image_url, image, image_chunk) with conditions for each (e.g., 'agent can run a shell'), and notes prerequisite 'use niche_add_output first.'

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

niche_brand_kit_guided_setupBrand kit guided setupA
Read-only
Inspect

Return a structured question chain the agent walks the user through to populate the BrandKit, VoiceProfile, and (optionally) BrandProfile. Each entry carries an intent describing what the answer is for (so the agent paraphrases in its own voice based on the conversation it's already having) plus a prompt_hint fallback for agents that relay tools verbatim.

Use this when the agent is helping a new user set up Niche and wants a predictable, brand-aware Q&A sequence instead of improvising. Tiered by impact:

  • Tier 0 (primary): URL ingest, fills 70-90% in one ask.

  • Tier 1 (gap_fill): only the fields URL ingest didn't fill.

  • Tier 2 (discipline): opt-in guardrails (topics off, banned terms, competitor stance).

  • Tier 3 (no_url): full fallback for users without a site.

Per-question applies_to_field tells the agent where the answer writes (via niche_brand_kit_update or niche_brand_profile_set). is_already_set is computed from the user's current BrandKit and BrandProfile state so the agent skips questions already answered.

Returns the full chain in one call; the agent inspects state, decides flow, and asks in any order (or skips entirely if the user volunteered the answer earlier in the conversation).

ParametersJSON Schema
NameRequiredDescriptionDefault
brand_idNoOptional. If set, also reads the persisted BrandProfile for that brand_id so questions whose answers live in the profile (banned_terms, framing.allowed, etc.) get their is_already_set computed against profile state too.
include_filledNoIf true, return all questions including those already answered. Default false: the agent only sees the gaps.
Behavior5/5

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

Beyond the annotations (readOnlyHint true), the description reveals the tool returns a full chain in one call, includes per-question metadata (intent, prompt_hint, applies_to_field, is_already_set), and computes state based on the user's current BrandKit/BrandProfile. It also clarifies the optional brand_id reads profile state, giving a complete behavioral picture.

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

Conciseness5/5

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

The description is lengthy but well-structured with tiers and per-question details, every sentence adds necessary context about how to use the chain. Front-loaded with the main purpose and then use cases, making it easy to scan.

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

Completeness5/5

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 structure (intent, prompt_hint, applies_to_field, is_already_set) and the agent's possible actions (inspect state, decide flow, ask any order, skip). It covers all necessary context for correct tool invocation.

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?

The input schema already provides descriptions for both brand_id and include_filled, including default behavior and purpose. The main description doesn't add significant extra parameter semantics beyond what the schema covers, so 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 opens with a specific verb 'Return a structured question chain' and identifies the resource (setup for BrandKit, VoiceProfile, BrandProfile). It clearly distinguishes from sibling write tools like niche_brand_kit_update by focusing on the guidance chain, not the actual update.

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?

Explicitly states 'Use this when the agent is helping a new user set up Niche and wants a predictable, brand-aware Q&A sequence instead of improvising.' It further describes tiered scenarios and notes the agent can skip or reorder questions, providing clear contextual guidance versus alternatives.

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

niche_brand_kit_ingestIngest a brand kit from a URLAInspect

Auto-populate the user's BrandKit (palette / fonts / tagline / logo / wordmark / boilerplate / voice notes) from files, a URL, or pasted text. Additive by default: fills empty fields, leaves populated ones alone. Idempotent: re-running the same inputs doesn't double-write.

Overwrite rule: if the target brand kit already has an identity (a tagline/boilerplate/voice for a different brand), do not silently overwrite it. First ask the user whether to replace it. If the account supports multiple brand profiles, prefer creating a separate brand instead: pass a new brand_id slug plus brand_name rather than clobbering the existing one. Only pass replace=true once the user has confirmed they want this brand re-learned from the new source.

Use when the agent has brand assets in scope (a working directory with logos / press-kit / brand-guide PDFs, the user's portfolio or Substack URL, pasted boilerplate copy) and wants to populate Niche's BrandKit so future signal_scan and content generation inherit the brand context. Agent-side equivalent of the Niche web app brand-kit ingest surface, same backend engine.

Async, then poll: a URL or multi-file ingest runs in the background, so this call returns fast with {ingest_id, status:'ingesting'}. Then poll niche_brand_kit_ingest_status(ingest_id) until status is 'done'; that response carries the populated BrandKit, the ingest report (detected[] / skipped[] / errors[]), and a diff[] of changed fields. (Loop: ingest, then poll status until done/failed; same pattern as niche_signal_scan to niche_session_state.) Do not re-call ingest while one is running; a duplicate of the same inputs attaches to the in-flight job. URL ingest also fills voice primitives when the page has post-shaped text (Substack/blog/X). If a URL is slow or thin to scrape, the visual fields may land before the voice pass completes; when the report flags this, paste the page's About/homepage copy via text= to complete the brand voice.

ParametersJSON Schema
NameRequiredDescriptionDefault
textNoOptional URL (homepage, Substack, portfolio, LinkedIn) or a paste of brand text (tagline, boilerplate, voice notes). URL takes precedence when both look URL-shaped.
filesNoFiles to ingest (logos, brand-guide PDFs, screenshots, color swatches, headshots). Each entry: {name, mime_type, data_base64}. The engine classifies each by image content and routes to logo/wordmark/headshot/brand-guide/color-swatch slots.
replaceNoDefault false (additive: fill empty fields only). Set true only after the user confirms they want an already-populated brand re-learned from this source; it overwrites the detected identity fields. Do not set true to silently clobber a different brand's kit; create a new brand_id instead.
brand_idNoWhich brand slot to ingest into. Omit for the default brand. Pass a slug (e.g. 'acme') to target or create a separate brand kit; do this when the default kit already belongs to another brand, so you don't merge two brands into one. If the account isn't entitled to additional brands, the call returns a clear error explaining what's needed.
brand_nameNoOptional display name when creating a new brand_id slot (e.g. 'Acme Co').
Behavior5/5

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

The description reveals crucial behavioral traits beyond the annotations: additive by default, idempotent re-runs, the overwrite rule, async background execution with fast initial response, polling expectations, duplicate attachment to in-flight jobs, voice primitives from URL text, and the possibility of visual fields landing before the voice pass. This is far richer than the annotations alone and directly guides agent expectations.

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?

The description is longer than average, but every sentence serves a distinct purpose: purpose, overwrite safety, usage context, async protocol, duplicate handling, and edge-case completion. It is front-loaded with the primary action and then logically organized into safety, usage, and async flow. It could be slightly trimmed, but for a complex, stateful, async tool the density is justified.

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

Completeness5/5

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

Given the tool's complexity (multiple input types, async behavior, overwrite rules, no output schema), the description covers everything an agent needs: what the return value looks like immediately ({ingest_id, status}), how to poll via the status sibling, what the final response contains (populated BrandKit, ingest report with detected/skipped/errors, diff[]), and even niche completion actions like pasting text via text= if the voice pass fails. This is outstanding completeness.

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

Parameters4/5

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

Schema description coverage is 100%, so the base is 3. The description adds meaningful context beyond the schema: text is ambiguous (URL vs paste) but URL takes precedence when both look URL-shaped; files are classified by image content and routed to slots; replace defaults to false and must only be true after confirmation; brand_id is for targeting/creating separate brand kits with a slug; brand_name is for display when creating new slots. This adds behavioral nuance not present in the schema.

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 opens with a specific verb+resource: 'Auto-populate the user's BrandKit' and enumerates the exact fields (palette, fonts, tagline, etc.). It also clearly identifies the input sources (files, URL, pasted text) and distinguishes this from sibling tools like niche_brand_kit_ingest_status by stating that this call initiates ingestion while the status tool polls for results.

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?

Explicit usage context is provided: 'Use when the agent has brand assets in scope...' and the tool is placed as the agent-side equivalent of the web app's ingest surface. The description gives clear when-not-to-use guidance via the overwrite rule, instructing to ask the user first, prefer creating a new brand_id rather than clobbering, and only set replace=true after explicit confirmation. It even names the polling sibling and compares the pattern to niche_signal_scan/niche_session_state.

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

niche_brand_kit_ingest_statusPoll a brand-kit ingestA
Read-only
Inspect

Poll the result of an async niche_brand_kit_ingest. Pass the ingest_id it returned. status: 'ingesting' (keep polling) | 'done' (response carries the full kit plus detected[]/skipped[]/errors[]/diff[]/left_unchanged_because_populated[]) | 'failed' (error plus failed_step; the kit was not written). The marker expires 30 min after the ingest starts.

ParametersJSON Schema
NameRequiredDescriptionDefault
ingest_idYesThe ingest_id returned by niche_brand_kit_ingest.
Behavior5/5

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

Beyond the annotations (readOnlyHint, destructiveHint), the description discloses key behavioral traits: the marker expires after 30 minutes, 'failed' means the kit was not written and gives failed_step, and 'done' includes specific arrays (detected/skipped/errors/diff/left_unchanged). This adds significant operational context not available in the 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.

Conciseness5/5

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

The description is two sentences, front-loaded with the core purpose, and uses a compact pipe-separated list for status details. Every sentence adds necessary information with no redundancies or filler.

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

Completeness5/5

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

Given the absence of an output schema, the description thoroughly covers return behavior: statuses, payload contents for 'done', failure details for 'failed', and the expiration timer. This is complete for an async status poll tool with a single parameter.

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?

The only parameter `ingest_id` is fully documented in the schema with the same meaning as in the description ('The ingest_id returned by niche_brand_kit_ingest'). The description adds no additional semantic value beyond confirming this association, so the baseline of 3 applies given 100% schema coverage.

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 clearly states the tool's purpose with a specific verb+resource: 'Poll the result of an async niche_brand_kit_ingest.' It distinguishes itself from the sibling `niche_brand_kit_ingest` by explicitly referencing that async process as the context for this status polling tool.

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

Usage Guidelines4/5

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

It provides clear usage context: 'Pass the `ingest_id` it returned' and explains the statuses to guide the polling loop ('ingesting' keep polling, 'done' response, 'failed' kit not written). It does not explicitly discuss when not to use it or alternatives, but given the tool's specific role, the context is strong enough for a 4.

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

niche_brand_kit_updateUpdate brand kitAInspect

Set specific BrandKit fields by name. The write path for the structured fields (tagline / boilerplate / voice_notes / forbidden_phrases / signature_phrases / endcard preferences / video voice preference / colors / fonts) without going through the ingest engine. Use after niche_brand_kit_ingest fills the easy stuff, or to commit values the user answered through niche_brand_kit_guided_setup.

Only fields you pass are touched; fields you omit stay at their current value. Lists replace the current value (they do not append). Response includes a diff[] of fields that changed and the full updated kit.

Archiving: pass archive=true to archive a brand (soft and reversible; it disappears from every list but is not deleted), or archive=false to restore one. The default/active brand can't be archived (promote another to default first). A brand with published history won't archive unless you also pass acknowledge=true. Use archive_scope='test' to archive every scratch brand at once (never the default). There is no hard delete here; archive is the removal verb agents have.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoRename an existing brand's display name (its brand_id is unchanged).
accentNo
archiveNotrue archives the brand (soft, reversible; hidden from every list, not deleted); false restores it. Refuses the default/active brand and refuses a brand with published history unless acknowledge=true.
taglineNoBrand tagline (5-12 words).
brand_idNoWhich brand slot to update. Omit for default; pass a slug to target a specific brand kit (for multi-brand accounts).
cta_textNoOne-line call to action appended to generated posts, e.g. 'DM to commission'.
logo_urlNo
brand_nameNoDisplay name when creating a new brand_id slot.
primary_bgNoPrimary background color (#rrggbb).
acknowledgeNoRequired (true) to archive a brand that has published history, confirming the user means to remove it from the roster even though it shipped work.
boilerplateNoBrand boilerplate (one paragraph, ≤350 chars).
voice_notesNoVoice direction in plain prose. A string or a list of strings (the guided-setup text_list form); a list is joined server-side.
external_urlNoCanonical brand URL (homepage).
headshot_urlNo
secondary_bgNo
text_primaryNo
wordmark_urlNo
archive_scopeNoWith archive=true, 'test' archives every scratch brand in one call (never the default). Returns the list of brands archived; each is reversible with archive=false.
text_secondaryNo
body_font_familyNo
endcard_templateNo
forbidden_phrasesNoPhrases never to use in generated copy. Max 16; trimmed beyond.
signature_phrasesNoPhrases the brand uses. Max 16.
endcard_outro_textNo
headline_font_familyNo
video_voice_preferenceNo
endcard_mark_preferenceNo
Behavior5/5

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

The description reveals key behaviors beyond annotations: partial-field updates ('Only fields you pass are touched'), list replacement semantics, response shape (diff[] and full updated kit), and soft-reversible archiving ('soft and reversible; no hard delete'). These details are critical for a mutation tool with destructiveHint=false, adding context annotations don't provide.

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?

The description is lengthy but efficiently organized: purpose first, then update semantics, then archiving. Each sentence adds value, and the length is justified for a tool with 27 parameters and complex archiving behavior. It avoids redundancy and front-loads the core action.

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

Completeness5/5

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

Despite no output schema, the description states the response includes a diff and full kit, covering the main expected return. It addresses edge cases for archiving (default brand, published history, archive_scope='test') and alternative usage flows via siblings, making it comprehensive for the tool's complexity.

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

Parameters4/5

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

With schema coverage at 52%, the description compensates by grouping fields (tagline, boilerplate, voice_notes, etc.) and explaining behavior patterns like list replacement and omit-preserves-current-value. It also clarifies archiving parameters and their consequences, though it doesn't enumerate every parameter individually.

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 opens with 'Set specific BrandKit fields by name', clearly identifying the write path and distinguishing it from the ingest engine and guided setup. It enumerates the structured fields, making the resource scope explicit and differentiating it from sibling tools like niche_brand_kit_ingest.

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?

Explicitly states when to use: 'Use after niche_brand_kit_ingest fills the easy stuff, or to commit values the user answered through niche_brand_kit_guided_setup.' It also provides exclusion conditions for archiving (default/active brand can't be archived, published history requires acknowledge=true), offering clear guidance over alternatives.

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

niche_brand_profile_getGet brand profileA
Read-only
Inspect

Read back the persisted brand profile without modifying it. Use it to confirm a profile landed as expected, to check the active profile a run is bound to, or to inspect the current shape before a partial update.

Pass brand_id to read one profile; omit it to list all (brand_id, updated_at) summaries. Returns the full profile JSON, schema_version, created/updated timestamps, and a brand_kit_sync_status indicating whether the profile's mirrored fields are in sync with the brand kit.

ParametersJSON Schema
NameRequiredDescriptionDefault
brand_idNoBrand identifier to read. Omit to list all.
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds meaningful behavior: omit brand_id to list all summaries vs. pass it to get full profile, and it specifies the return fields (full profile JSON, schema_version, timestamps, brand_kit_sync_status). This goes beyond the 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.

Conciseness5/5

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

Two compact paragraphs: the first condenses purpose and use cases, the second covers parameter modes and return details. Every sentence earns its place; no redundancy or filler.

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

Completeness5/5

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

With no output schema, the description compensates by specifying the return payload and its fields. It also covers both operational modes (get vs list) and the purpose context. For a simple read-only tool, this is complete and well-rounded.

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

Parameters4/5

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

The input schema has 100% coverage with 'Omit to list all.' The description adds value by clarifying the output differences: listing returns summaries of (brand_id, updated_at), while reading one returns the full profile JSON with additional metadata. This enriches the parameter's meaning beyond the schema.

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 opens with 'Read back the persisted brand profile without modifying it'—a specific verb, resource, and non-mutating scope. It distinguishes itself from the sibling 'set' tool by framing a use case as 'inspect the current shape before a partial update.'

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

Usage Guidelines4/5

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

The description gives three explicit usage contexts: confirm a profile landed, check the active profile, or inspect before a partial update. It doesn't explicitly name alternative tools or state when not to use it, but the read-only framing and update context imply the boundary.

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

niche_brand_profile_setSet brand profileAInspect

Set or update the persisted brand profile for a brand. The profile is a structured JSON document applied across every pipeline stage: voice rules, banned terms, canonical vocabulary, framing allowlist, channel config, compliance disclosures, and verifier overrides. Use it to persist a profile derived from a repo or docs so future runs inherit the rules, or to update voice rules and banned terms before the next run.

Required sections: identity and voice (a profile with no voice falls back to generic drafts). A re-set that omits voice is accepted with a default voice stub rather than rejected.

Validation: tiered lints (error / warn / info). 'error' lints reject the set; 'warn' lints accept with a note. The response includes lints[]. conflicts[] lists fields locked by the brand kit, which takes precedence; those profile values are not stored.

brand_id is unique per user; re-setting the same brand_id replaces the prior profile.

ParametersJSON Schema
NameRequiredDescriptionDefault
profileYesThe brand profile JSON. Schema sections (each drives a pipeline stage): identity (who the brand is), audience (who it's for), voice (register/rhythm/lexicon rules the copy obeys), lexicon (canonical_terms plus banned_terms the verifier enforces), framing (frame slugs from Niche's editorial taxonomy; pass `allowed` and/or `blocked` as lists of slugs. The set is closed: an unrecognized frame rejects the set and the error returns the valid slugs, so nothing is silently dropped), structure (default article shapes), offers (what the creator sells: {product, what_it_is, proof_point?, cta, link}; lands signal-led posts on the offer), verifier_overrides (truthfulness thresholds), channels (per-platform config), source_quality (trusted/blocked domains), compliance (required disclosures), metadata. Fill the load-bearing ones (identity / voice / lexicon / framing / verifier_overrides) for a strong profile; the rest are optional. A malformed set returns a `template` of the full schema with inline field docs in the error response, so no separate discovery call is needed.
brand_idYesUnique-per-user identifier for this brand (e.g. 'acme', 'acme-blog'). Stored as a string; lowercase kebab-case recommended.
schema_versionNoProfile schema version. Defaults to '1.0'.1.0
Behavior5/5

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

The description extensively discloses behavior beyond the annotations: re-setting replaces prior profile, validation uses tiered lints (error/warn/info), conflicts with brand kit are not stored, missing voice falls back to a default stub, and malformed sets return a template. This far exceeds the minimal readOnly/destructive hints.

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

Conciseness5/5

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

The description is long but appropriately so for a complex tool with nested objects. It is front-loaded with the core purpose, then logically organized into required sections, validation, and brand_id semantics. Every sentence adds actionable information without fluff.

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

Completeness5/5

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

With no output schema, the description compensates by disclosing the response format (lints[], conflicts[], template) and edge-case behaviors (default voice stub, brand kit precedence). It covers all necessary operational context for a complex setter tool.

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

Parameters5/5

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

Schema coverage is 100% and the description adds substantial meaning: profile structure details (identity, voice, lexicon, framing, verifier_overrides, etc.), encoding of closed framing set behavior, error response with valid slugs, and the template return on malformed sets. brand_id format and uniqueness are also clarified.

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 explicitly states 'Set or update the persisted brand profile for a brand' with a clear verb and resource. It enumerates the pipeline stages the profile applies to, distinguishing it from sibling tools like niche_brand_profile_get and niche_brand_kit_update. The scope is unambiguous.

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

Usage Guidelines4/5

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

The description provides clear context for when to use the tool: 'persist a profile derived from a repo or docs so future runs inherit the rules, or to update voice rules and banned terms before the next run.' It does not explicitly name alternatives or exclusion criteria, but the usage context is well-defined.

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

niche_draft_createCreate draftsAInspect

Niche draft content: lock the chosen angle and turn it into platform-native social drafts (LinkedIn post, X thread, Instagram, newsletter/long-form), ready to review and publish, the downstream payoff once the story and angle are decided. Returns immediately with status=cp3_generating; poll niche_session_state until outputs[] is populated. Each output carries its trust data nested under outputs[i].trust: source_faithfulness_score, source_ungrounded_claims[], source_diversity_passed, source_recency_passed, overall_severity, a severity-tagged flags[], and verifier_blocked_reason/verifier_blocked_claim when a fabrication was refused. (No top-level verifier_audit field; read outputs[i].trust.) BRAND: voice/offer/CTA come from the run's bound brand. If this account has MULTIPLE brands and the run isn't bound to one, this returns brand_choice_required with brand_options[] and generates NOTHING. STOP, ask the user which brand, then re-call with brand_id (or brand_id:'none' to draft deliberately unbranded). A single/default brand binds automatically.

ParametersJSON Schema
NameRequiredDescriptionDefault
angle_idYesid from niche_angle_propose.angles[].id
brand_idNoBind this draft to a brand (its voice/offer/CTA). Usually unnecessary (the run inherits the scan's brand). Pass it to answer a `brand_choice_required` on a multi-brand account, or `'none'` to draft deliberately unbranded.
session_idYes
estimate_onlyNoWhen true, return the per-platform content credit cost without locking the angle or generating. Quote a price before committing.
Behavior4/5

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

Annotations give no safety hints (all false), so description carries the burden. It discloses async behavior (returns status=cp3_generating, poll session_state), trust data nested under outputs[i].trust, and the brand_choice_required refusal mode. However, 'lock the chosen angle' is vague about whether the angle is consumed/irreversible, and no mention of rate limits or cost beyond estimate_only.

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?

Well-structured with clear sections (functionality, async/polling, trust data, brand edge case). Though long, every sentence adds operational value. A bit dense but not bloated; front-loads the core purpose.

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?

For a complex async tool with no output schema, it covers purpose, async flow, trust data specifics, and brand branching. Missing a clear description of the output object structure (beyond trust fields) and how outputs[] items are shaped, but sufficient for invocation and follow-up polling.

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 covers 75% of parameters (angle_id, brand_id, estimate_only described). Description repeats brand_id behavior but adds little beyond schema; session_id remains undocumented, and estimate_only isn't mentioned in description. Thus no significant added meaning over schema.

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 clearly states the tool's function: lock an angle and create platform-native drafts (LinkedIn, X thread, Instagram, newsletter/long-form). It distinguishes from sibling tools like publish/revise by emphasizing 'ready to review and publish' and 'downstream payoff once the story and angle are decided.'

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

Usage Guidelines4/5

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

It provides context for when to use (after angle is decided) and describes the multi-brand workflow including stopping to ask the user and re-calling with brand_id. It doesn't explicitly name alternatives, but the workflow implies sequencing. Slightly short of 5 due to lack of explicit 'when not 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.

niche_draft_directDraft directly (no scan, BYOC)AInspect

Draft the creator's own take or product straight into posts, with no research scan and no story/angle picks. Use this for product-led or bring-your-own-content work: a specific thing to say ('new walnut dining table, live edge, $2,800') or a page to repurpose. The signal pipeline (niche_signal_scan) is for 'what's worth writing about my niche'; this is for 'write this exact thing.'

Provide at least one of: take (what to say), source_url, or source_text (the last two repurpose an existing page). Returns a session_id in under 2s; poll niche_session_state(wait:30, wait_until:'checkpoint') to cp3_awaiting_review/complete, then read outputs[]. Pass brand_id to bind the creator's voice, offer, and call to action so the draft sounds like them and includes their offer (set those first via niche_brand_profile_set).

ParametersJSON Schema
NameRequiredDescriptionDefault
takeNoWhat the post should say: the creator's own message or product. Required unless a source is given.
imageNoProduce an image in the same run when the user wants one: 'photo' = generated AI image (paid, ~30 credits/cell), 'card' = free brand card. Omit for text-only.
verifyNoWhen true, run the per-claim grounding check against the provided source and record the clean result on each output, so the draft reads checked-and-clean rather than unchecked. Recommended when repurposing a source_url or source_text.
brand_idNoBinds 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.
source_urlNoOptional page to repurpose: fetches and extracts the page's readable text. Use to turn an essay or landing page into platform posts.
source_textNoOptional pasted source text to repurpose (alternative to source_url).
source_titleNoOptional title for the pasted/fetched source.
target_outputsNoCells to draft, e.g. ['linkedin:text_post','x:thread','instagram:image_post']. Bare platforms (linkedin/x/instagram) coerce automatically. Defaults to ['linkedin'].
Behavior5/5

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

Adds rich behavioral context beyond annotations: the async session flow (returns session_id in under 2s, poll niche_session_state to checkpoint, then read outputs[]), the no-scan/no-picks behavior, and the brand binding effect. 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.

Conciseness5/5

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

The description is well-structured and front-loaded, with every sentence earning its place. It starts with purpose, then usage, contrast, requirements, and async behavior—all concise and no fluff.

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

Completeness5/5

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 conditional required inputs, the description covers all essential context: purpose, usage, asynchronous flow, brand binding, and reading outputs. The schema handles parameter details, so the description complements it without redundancy.

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

Parameters4/5

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

Schema already covers all parameters 100%, so baseline is 3. The description adds meaningful semantic value by stating the 'at least one of take/source_url/source_text' constraint (not in schema) and clarifying that the source parameters repurpose an existing page.

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 opens with a specific verb-resource pairing ('Draft the creator's own take or product straight into posts') and explicitly contrasts with the signal pipeline ('this is for write this exact thing'), clearly distinguishing it from sibling tools like niche_signal_scan. The title 'Draft directly (no scan, BYOC)' 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.

Usage Guidelines5/5

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

Explicitly states when to use this tool ('product-led or bring-your-own-content work'), gives concrete examples, and names the alternative pipeline (niche_signal_scan) with a clear when-not-to-use boundary. Also provides operational guidance on required inputs and brand binding.

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

niche_draft_publishPublish a draftA
Destructive
Inspect

Publish a single output to its platform. Defaults to dry_run=true: returns the would-publish payload plus any verifier blocks without actually filing. Set dry_run=false and provide an idempotency_key to commit. The commit is the only irreversible action in the workflow; the agent should present the dry-run preview to the human and only commit on explicit go-ahead. For any piece with a rendered image, reel, or card, show the human the actual pixels (the preview_url / image_url) first: never let publish be the first time a human sees the final visual. Verifier-blocked outputs refuse to publish even with dry_run=false; clear the block on the row first. When the target social isn't linked, returns status='not_connected' plus a connect_url instead of publishing; send the user to connect once, then retry.

Scheduling: pass scheduled_for (an ISO-8601 datetime in the future) to file the post for later instead of publishing now; it dispatches automatically through the same publish path. Pass cancel_scheduled=true to clear a pending schedule for this platform.

Prefer an exact cell string (e.g. 'x:thread', 'x:single_tweet') over a bare family name. A bare family that matches more than one draft on the session returns status='ambiguous_platform' with the candidate cells rather than guessing. Every publish and dry-run response echoes resolved_cell so you can confirm which artifact shipped.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNo
platformYesAccepts either: • cell string: the platform×content_type the run produced (linkedin:text_post, linkedin:image_post, linkedin:carousel, x:single_tweet, x:thread, x:image_post, instagram:image_post, instagram:carousel), preferred for new code • family name: linkedin, linkedin_carousel, twitter, instagram, which coerces to the registered default cell for that family (e.g. linkedin maps to linkedin:text_post) Reels (linkedin:reel / x:reel / instagram:reel) and long_form_article have no in-app publish path: reels get a download URL, long-form ships as Markdown for paste-to-Substack.
session_idYes
scheduled_forNoISO-8601 datetime to publish this output later (must be in the future). Files a pending scheduled post and returns status='scheduled' instead of publishing now. Requires the platform's social account connected; long-form has no scheduled path.
idempotency_keyNoRequired when dry_run=false. Same key returns the prior result without re-publishing.
cancel_scheduledNoClear a pending scheduled post for this platform on this run. Idempotent: returns a clean message when nothing is scheduled.
acknowledge_surfacedNoRequired true to commit when the dry-run surfaced claims/flags worth a human look (the dry-run's next_step names them). Affirms the agent showed the human the surfaced items and got go-ahead. Ignored when nothing was surfaced. Default false.
acknowledge_publish_costNoRequired true to commit an X post that carries a link (X charges per link-post, so the dry-run returns a `publish_cost` in credits). Affirms the agent showed the human the cost and got go-ahead. Ignored when the publish is free (plain X / LinkedIn / Instagram). Default false.
Behavior5/5

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

Annotations already indicate destructiveHint and readOnlyHint=false, but the description goes far beyond by explaining that commit is irreversible, defaults to dry_run=true, requires idempotency_key for commit, verifier blocks prevent publishing, and not_connected returns a connect_url. Also covers scheduling and cancellation 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.

Conciseness4/5

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

The description is fairly long but well-structured with paragraphs separating safety, scheduling, and platform selection. Every sentence contributes critical operational detail, though a slightly tighter edit could improve scannability. It is not wastefully verbose.

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

Completeness5/5

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

Without an output schema, the description compensates by explaining response states (status='not_connected', 'ambiguous_platform', 'scheduled', resolved_cell, publish_cost, next_step). It covers edge cases, scheduling, dry-run behavior, and human-in-the-loop requirements, making it nearly complete for a complex publish tool.

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

Parameters4/5

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

Schema covers 75% of parameters with descriptions. The tool description adds valuable context beyond the schema, such as preferring exact cell strings over family names, the meaning of status='ambiguous_platform', and the idempotency guarantee. This enriches understanding but some parameters like session_id are minimally described.

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 opens with 'Publish a single output to its platform,' a clear verb+resource statement. It immediately distinguishes itself from sibling draft/rendering tools by focusing on the publish action and its dry-run/commit flow.

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

Usage Guidelines4/5

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

Provides clear context on when to use the tool (final publish step) and when to use dry-run vs commit. Does not explicitly name alternative sibling tools for other scenarios, but the guidance around previews and explicit human go-ahead is strong. Lacks explicit 'rather than using X' statements.

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

niche_draft_reviseRevise a draftAInspect

Applies the values you pass to a specific output. Accepts any subset of the output's fields: caption, hashtags, or partial script updates (hook / body / cta / hook_tweet / body_tweets / title / subtitle / pull_quote / cover_slide / slides / cta_slide / alt_text / card_headline, where card_headline rewords the image card's header). Pass apply_hook_variant_index to splice an existing hook_variants[N] into the live hook in one move without rewriting the rest. If you pass no editable field (or values identical to the current draft) it changes nothing and returns status:'no_change' naming the params that edit content. Angle and story changes still go back through niche_angle_propose; they invalidate the verifier trust block and need fresh generation.

Response includes a diff[] array listing every field that changed ({field, before, after}) so agents can show users the delta rather than the full new payload.

ParametersJSON Schema
NameRequiredDescriptionDefault
captionNoReplace the full caption (legacy field; same effect as setting `script.body` for LinkedIn, `script.caption` for Instagram).
hashtagsNoReplace the hashtag list. Sanitized server-side (whitespace stripped, non-alphanumerics removed, case-insensitive dedup).
output_idYes
slide_patchesNolinkedin_carousel only. Two modes, one per call (do not mix). In-place edit: {index, headline?, body?} patches a slide's text without resending the whole slides[] array, and re-renders just that slide. Structural op: {op, index, ...} reorders the deck, where op is 'move' ({op:'move', index, to_index}), 'insert' ({op:'insert', index, headline?, body?}; index may equal the slide count to append), or 'delete' ({op:'delete', index}). Structural ops keep the slide text and the rendered images in lockstep, preserving the cover and closing slides; an inserted slide is rendered automatically. Out-of-bounds index errors; passing slide_patches on a non-carousel output errors.
script_updatesNoPartial updates to the output.script JSON. Shallow-merged: keys present here replace the matching fields, keys absent are preserved. Available fields depend on platform: linkedin {hook, body, cta, structure}; twitter {hook_tweet, body_tweets[], landing_tweet, single_tweet}; longform {title, subtitle, body, pull_quote}; instagram {hook, caption, alt_text}; linkedin_carousel {cover_slide, slides[], cta_slide}.
regenerate_hooksNoGenerate this many fresh alternate opening lines for the output and return them as hook_variants for you to present. The body stays put. After the user picks one, splice it with apply_hook_variant_index. Metered like a short generation.
apply_hook_variant_indexNoSplice an existing hook_variants[N] into the live hook. 0-indexed. Cheaper than rewriting the caption by hand. Errors if the index is out of bounds.
Behavior5/5

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

Without relying on annotations (readOnlyHint=false, destructiveHint=false), the description discloses no-op behavior, server-side sanitization, error conditions for out-of-bounds indices and non-carousel slide_patches, and the response's diff[] array. It also reveals the consequence of angle/story changes invalidating the verifier trust block, which annotations do not capture.

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

Conciseness5/5

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

Despite being a dense paragraph, every clause adds behavioral detail and no sentence is redundant. The description is appropriately scaled to the tool's 7-parameter complexity, front-loading the purpose and then layering edge cases.

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

Completeness5/5

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

The description provides a thorough operational picture: accepted fields, no-op/change behaviors, angle-change routing, response diff, platform-specific constraints, and sanitization rules. With no output schema, it still informs agents what the response contains, making the tool highly navigable.

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

Parameters4/5

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

Schema coverage is 86%, so the schema already explains most parameters. The description adds unique context by mentioning card_headline (rewords image card header) and clarifying caption as a legacy alias for script.body/script.caption, but largely reiterates schema descriptions for other fields.

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 opens with 'Applies the values you pass to a specific output,' immediately establishing the tool's role as a revision/edit operation on an existing draft. It enumerates editable fields (caption, hashtags, script updates, carousel slides) and contrasts with niche_angle_propose for angle/story changes, distinguishing it from siblings.

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?

It explicitly states when not to use the tool: 'Angle and story changes still go back through niche_angle_propose' and warns that passing no editable field returns status:'no_change'. It also specifies platform-specific usage, e.g., slide_patches is for linkedin_carousel only, and directs agents to apply_hook_variant_index for cheap hook splicing.

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

niche_intelligence_queryIntelligence queryAInspect

Niche (nicheangle.com) research and analysis: answer an analyst-shaped question over fresh-scanned sources and get an intelligence answer as the deliverable, not a single post. Use for: 'the 10 biggest developments in X this week', 'what's emerging before it goes mainstream', 'where is investment activity rising', 'find 3 non-obvious narratives to publish on LinkedIn'. The answer is the ranked slate plus engine-grounded narratives or patterns: every narrative cites real slate stories and is fact-verified by a second pass (no source, no narrative). This uses the same engine as the Niche web app, so both surfaces return the identical grounded answer; do not synthesize your own narratives over the slate, present these.

Non-blocking: returns a session_id immediately (under 2s). Poll niche_session_state every ~3-5s. At status == cp1_awaiting_story the ranked slate (stories[]) is ready; present it right away. Synthesis runs concurrently and usually lands 20-90s after the slate (hard cap ~2 min); if you requested it, call niche_session_state(wait:30, wait_until:'synthesis') and repeat until synthesis_pending == false (usually 1-3 calls); don't give up early, you'll always get synthesis[] or a synthesis_shortfall_note. With synthesis:'none', synthesis stays null and synthesis_pending is false at cp1, so stop there. To turn a narrative into a post, pick its supporting story id and call niche_angle_propose; no new scan needed. BRAND: omit brand_id and a single/default brand binds automatically; on a MULTI-brand account you'll get brand_choice_required with brand_options[] (the query still runs). Ask the user which brand before drafting. Pass brand_id to bind one, or 'none' for unbranded.

ParametersJSON Schema
NameRequiredDescriptionDefault
lensNoRanking posture. 'mainstream' (default) = authority-weighted. 'emerging' = inverts saturation to surface low-coverage, pre-mainstream signal. 'investment' = lifts stories carrying funding/raise/round/term-sheet markers.
countNoHow many developments / narratives to return (3-15). Default ~5-10.
windowNoRecency window: '24h' | 'week' | 'month' | 'quarter' | 'year'. 'this week' maps to 'week'. Overrides the niche's default recency. A strong bias by default; pair with recency_strict for a hard cutoff.
subjectYesThe subject/space to investigate (2-200 chars). Specific is better.
brand_idNoBinds 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.
platformNoOptional publish target (linkedin / x / instagram) that shapes each narrative's publish_hook.
synthesisNo'narratives' = N non-obvious publishable threads across the slate. 'patterns' = the named movement (pairs with lens:'investment'). 'none' (default) = ranked slate only, no synthesis.
recency_strictNoWhen true, `window` is a hard cutoff (out-of-window sources dropped before clustering) so 'nothing older than yesterday' is exact. Default false (bias only). Strict returns fewer, higher-confidence stories; use when precision matters more than breadth.
source_qualityNoSource-quality filter (niche-relative). 'strict' drops uncorroborated single-source silos that aren't primary/official or a niche authority, for high-trust answers only. 'balanced' (default) down-weights weak sources without dropping. 'broad' surfaces everything (incl. low-coverage emerging clusters), authority as a tiebreaker only.balanced
target_outputsNoOptional. The draft cells produced if you later draft a narrative into content (same cell list as niche_signal_scan, e.g. ['linkedin:image_post', 'x:thread']). Without this, a draft defaults to a single 'long_form_article'. Set it when you know the surfaces you want, so niche_draft_create yields them directly instead of needing niche_add_output after.
idempotency_keyNoOptional. Stable key so a retry reuses the original run instead of billing a second; an identical query fired while one is still running is auto-deduped regardless.
Behavior5/5

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

Annotations only provide readOnlyHint=false, openWorldHint=true, destructiveHint=false, so the description carries the full burden of explaining side effects and lifecycle. It adds rich behavioral detail: non-blocking session_id return, polling cadence, cp1_awaiting_story status, synthesis timing with a hard cap, and the synthesis:'none' branch. This goes far beyond the structured annotations and contains 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.

Conciseness4/5

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

The description is long but well-structured into purpose, async workflow, and brand handling. The opening sentence front-loads the core purpose, and each subsequent paragraph addresses a distinct aspect (polling, synthesis, brand binding, handoff to niche_angle_propose). Every sentence earns its place for this complex tool, though the web-app equivalence sentence 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.

Completeness5/5

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

With no output schema, the description must explain return values and state transitions, and it does so explicitly: session_id, cp1_awaiting_story, stories[], synthesis[], synthesis_shortfall_note, brand_choice_required, and brand_options are all named. It covers the entire lifecycle from submission through polling to handing off to niche_angle_propose. The only minor omission is error/rate-limit behavior, which is not critical given the detailed workflow guidance.

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

Parameters4/5

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

Input schema covers 100% of parameters with descriptions, so the baseline is 3. The description adds brand_id semantics not fully captured in the schema: omitting brand_id auto-binds a single/default brand, multi-brand accounts return brand_choice_required with brand_options, and 'none' is a valid unbranded value. It also clarifies the behavioral effect of synthesis:'none', adding value beyond the schema.

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 opens with a specific verb+resource: 'research and analysis: answer an analyst-shaped question over fresh-scanned sources and get an intelligence answer as the deliverable, not a single post.' It lists concrete use cases and explicitly contrasts with single-post tools, distinguishing it from siblings like niche_angle_propose and niche_draft_create. The 'same engine as the Niche web app' note further clarifies its scope.

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?

The description explicitly says 'Use for:' and gives four analyst-style example questions, making the intended context unmistakable. It also tells the agent what not to do ('do not synthesize your own narratives over the slate, present these') and describes the follow-up path to niche_angle_propose. This is strong when/when-not guidance, even though it doesn't name an alternative for the initial query.

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

niche_list_sessionsList sessionsA
Read-only
Inspect

Enumerate the user's recent sessions. Returns id, niche_input, status, outcome, target_platforms, picked story/angle ids, and created/updated_at for each. Use this when the session_id has been lost (across agent invocations, hours of work, etc.) or to find an in-flight session to resume. Returns newest-first.

Judge a terminal run by outcome, not raw status: a failed status is usually a walk-away, not an error. outcome ∈ {complete, expired (a slate was produced but nobody picked; re-open and choose), interrupted (a restart ended it, credits refunded; just re-run), cancelled (stopped on purpose), failed (a real error; see error_message), running}. (status_filter still matches the raw status value.)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax sessions to return (default 25, max 100).
offsetNoSkip this many sessions before returning, for paging through history. Default 0.
brand_idNoOptional filter to sessions tied to one brand profile slot.
status_filterNoOptional status filter, e.g. 'cp1_awaiting_story', 'cp3_awaiting_review', 'complete', 'failed'. Omit for all.
niche_containsNoOptional case-insensitive substring filter on the niche input, to find sessions on a topic (e.g. 'walnut').
include_outputsNoWhen true, also returns `recent_outputs`: the account's produced posts/images/reels across all sessions, newest first, each with its session_id, cell, a reachable asset_url, and publish state. Use it to locate a past asset (e.g. an image made on a prior run). Default false.
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety profile is known. The description adds significant nuance: return ordering, the distinction between `outcome` and `status`, and that a `failed` status is usually a walk-away not an error. It also details what `recent_outputs` contains. Goes well 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.

Conciseness5/5

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

The description is two tight paragraphs. First states action, return fields, use case, and ordering. Second explains the crucial outcome/status distinction. Every sentence carries information, no filler.

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

Completeness5/5

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

With no output schema, the description compensates by listing exact return fields and the structure of `recent_outputs`. It also explains sorting and outcome semantics. Fully covers the tool's role among many siblings and all relevant aspects.

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

Parameters4/5

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 semantic value by clarifying that `status_filter` matches raw status not the derived `outcome`, and by explaining the purpose of `include_outputs` for locating past assets. These clarifications are not in the schema.

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 opens with a specific verb+resource: 'Enumerate the user's recent sessions.' It clearly lists the return fields and explicitly states when to use it (when session_id lost or to find an in-flight session), distinguishing it from sibling tools that mutate sessions (e.g., niche_session_cancel).

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

Usage Guidelines4/5

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

It explicitly states 'Use this when the session_id has been lost... or to find an in-flight session to resume' and explains the `include_outputs` use case ('Use it to locate a past asset'). However, it does not mention alternatives or exclusion criteria; sibling tools like niche_session_state are not referenced. Clear context without exclusions/alternatives.

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

niche_render_image_cardRender an image cardAInspect

Render a visual onto a post at CP3, or edit an existing image.

scope: 'full' (default) renders a new visual and requires background. 'recomposite' re-composites new text, color, or size over the retained background at no charge. 'restore' reverts to the prior image from history, at no charge. 'reframe' produces a per-platform aspect variant from the retained background, at no charge.

background (required for scope='full'): • 'photo': a generated AI/photographic image with the headline composited over it. ~30 credits, ~30-90s, asynchronous: returns status='rendering_image_card'; poll niche_session_state (image_render.status: rendering, then done with static_urls on the output, or failed with credits refunded). A repeat call while a render is in flight is a no-op. • 'design': the INFOGRAPHIC, a generated editorial graphic that DRAWS the argument (a ranked bar chart, a two-column diagram, a stat, a before/after, a pull-quote), on-brand and legible, with vetted icons. The designer art-directs the treatment from the brand PALETTE (leads light for data, dark for narrative; accent as a spice), and honors a look steer in design_concept ('brighten it up', 'a ranked bar chart', 'navy and gold'). ~30 credits, asynchronous (poll as above). • 'brand_color': a flat brand card with the headline on the brand's solid color with logo and wordmark. No generation, no credits, synchronous. • 'svg': you author the card exactly as SVG markup (pass svg); the server rasterizes it to the cell's dimensions. Free, instant, deterministic. The right choice for data, labels, charts, and comparisons (where generated images fail at layout), and the only visual that works from a network-locked sandbox (SVG is text). The SVG owns the whole canvas; use brand colors and fonts from niche_whoami. Static shapes, paths, and text only (no scripts, external references, or foreignObject).

headline sets the bold header (defaults to the post's card_headline; auto-fits, not truncated). Idempotent: a prior render is replaced. Errors: render_not_ready before CP3; render_not_configured when image generation is unavailable; render_card_unavailable when background='brand_color' but the piece has no card-bearing platform.

ParametersJSON Schema
NameRequiredDescriptionDefault
svgNoRequired when background='svg': the card's SVG markup as a string (<svg ...>...</svg>). You author the exact layout; the server rasterizes it to the cell's pixel dimensions. Use brand colors and fonts from niche_whoami to stay on-brand. Bundled fonts (set font-family to any by name; an unknown family or the generics 'sans-serif'/'serif'/'monospace' fall back to a real font so text always draws): sans (Inter, Geist, Open Sans, Montserrat, Lato, Poppins, DejaVu Sans), serif (DejaVu Serif, Lora, Playfair Display), mono (DejaVu Sans Mono, JetBrains Mono). Allowed: static shapes, paths, text, gradients, internal (#id) and inline data: references. Rejected with a named error: scripts, event handlers, foreignObject, external/file references, and DOCTYPE/ENTITY declarations. Max 512KB.
cellNoOptional. Render at the canvas size for this cell: • linkedin:image_post: 1200×627 (1.91:1 landscape) • x:image_post: 1200×675 (16:9 landscape) • instagram:image_post: 1080×1350 (4:5 portrait) • linkedin:carousel / instagram:carousel: 1080×1080 (cover slide) When omitted: 1080×1080 universal-square asset stored under platform='image_card' (shared across all image cells).
scopeNo'full' (default): render a new visual (background required). 'recomposite': free text edit on the existing image, with new headline/subhead/color/size composited over the retained background, pixels otherwise identical, synchronous, 0 credits. Use this for wording iteration; it avoids paying a re-render to change words. 'restore': bring back the prior image from history, free. 'reframe': free per-platform aspect variant that re-composites an existing card's retained background at the `cell`'s canvas size (x 16:9, instagram 4:5, linkedin 1.91:1), same text and grounding, synchronous, 0 credits. Requires `cell` (the target aspect).
subheadNoThe smaller line under the header. On scope='full' it sets the subhead in the single render; on scope='recomposite' it edits it for no charge. Omit to keep the current one; pass '' to clear it.
headlineNoThe bold header words; works for both backgrounds. Defaults to the post's `card_headline` (the short, sized-for-the-box line). Pass this to force exact text, e.g. a brand name leading it ('Acme drew a line'). It auto-fits the box and is never truncated.
font_sizeNoHeadline size. A relative word ('bigger'/'smaller'/'reset') steps from the current size and compounds; an absolute value (a number like 80, '80px', or '120%') sets it directly. Applies on scope='full' and scope='recomposite'. The response's font_changed/font_at_limit report whether it actually moved.
backgroundNoRequired for scope='full' (ignored otherwise): what's behind the text. 'photo' = a generated AI/photographic image (the actual picture; ~30 credits, ~30-90s, async). 'design' = a generated editorial design graphic that draws the argument (concept diagram / stat / pull-quote / comparison / method / abstract), on-brand and legible, no photo, no clichés, ~30 credits, async. 'brand_color' = a free, instant flat brand card (no generation). 'svg' = a free, instant card you author exactly as SVG markup (pass `svg`), rasterized at the cell's size; best for data, labels, and charts, and the only visual that works from a network-locked sandbox. No default: choose deliberately.
session_idYesSession UUID that's reached cp3_awaiting_review or complete.
text_colorNoText color as a name ('blue') or hex ('#ec4899'). Applies on scope='full' (set the color in the render) and scope='recomposite' (re-color for no charge). On background='brand_color' it colors the card text; omit to auto-pick a legible color from the background.
design_colorNoOptional, background='design': color control for the design card. Free text. Sets the card BACKGROUND when the phrase names a background or the card overall ('cream background', 'navy', 'on a green card'), or the ACCENT when it names one ('blue accent', '#0a3d62'); the rest stays on the brand's palette (or the default style when the brand has no kit). Omit to use the brand's palette.
art_directionNoOptional free-text direction for a generated photo background (applies only when background='photo'). State the visual concept and any negatives, such as subjects or styles to avoid. Without it the background is generated from the story alone and tends toward category clichés (e.g. a robot for 'AI'); use this to steer toward a specific concept or an abstract, non-literal composition. The no-in-image-text rule still applies.
estimate_onlyNoIf true, return {credit_cost} without rendering or spending. Use to learn the cost before committing.
text_positionNoWhere the overlay sits: 'top', 'center', or 'bottom'. On scope='full' it places the text in the render; on scope='recomposite' it moves the text on the existing image for no charge. Omit to keep the position the card was rendered at.
design_conceptNoOptional, background='design' only: free-text art direction for the design graphic, the layout/shape and concept (e.g. 'a 2-column comparison', 'an abstract composition, no literal imagery', 'a concept diagram of intended vs actual'). Omit to let the designer pick the shape that best carries the argument.
background_colorNoThe background colour of a SOLID brand card (background='brand_color') as a name ('cream'/'navy'), a hex, or a brand keyword ('primary'/'accent'/'secondary'). Applies on a full brand_color render AND on scope='recomposite' (free, persists, so the colour does not snap back to the brand default on a later edit). (A generated-photo card recolours its text, not its photo background.)
needs_legible_textNoscope='full', background='photo' only. Set true when in-image text is genuinely the subject of the scene, which routes the render to a text-capable image generator. Defaults false (an atmospheric, text-free background, the usual choice).
Behavior5/5

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

Annotations only declare readOnlyHint=false, openWorldHint=false, destructiveHint=false. The description goes far beyond this by disclosing credit costs, async vs synchronous behavior, idempotency ('A repeat call while a render is in flight is a no-op'), the fact that 'restore' reverts from history, and named error cases (render_not_ready, render_not_configured, render_card_unavailable). All of this is useful and non-contradictory 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.

Conciseness4/5

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

The description is long but well-structured with scopes and backgrounds broken out. The first sentence front-loads the core purpose, and subsequent bullets are scannable. Some redundancy exists with the schema (e.g., background options are repeated nearly verbatim), but the complexity of the tool justifies the length. Not maximally concise, but certainly not bloated.

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

Completeness5/5

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

For a tool with 16 parameters and no output schema, the description is remarkably complete. It covers asynchronous status ('returns status='rendering_image_card''), polling flow via niche_session_state, credit costs, sync vs async modes, idempotency, error conditions, and the zero-cost scopes (recomposite, restore, reframe, brand_color, svg). The agent has enough context to select and invoke the tool correctly in most situations.

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 in the schema already carries a detailed description (including credits, timing, defaults, and the 'ignored otherwise' clarifications). The top-level description largely repeats this information rather than adding new semantic layers. Since the schema does the heavy lifting, a baseline of 3 is appropriate.

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 opens with a specific verb and resource: 'Render a visual onto a post at CP3, or edit an existing image.' It clearly distinguishes this tool from siblings like niche_render_reel (video) and niche_attach_image (attaching existing assets) by scoping it to image cards on a post at CP3.

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

Usage Guidelines4/5

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

The description provides excellent in-tool guidance: 'recomposite' for wording iteration, 'svg' as 'the right choice for data, labels, charts', and the note that SVG is the only visual that works from a network-locked sandbox. It also explains when to poll and what error conditions mean. However, it does not explicitly compare to sibling tools like niche_render_reel or niche_reuse_asset, so the agent must infer those boundaries from titles alone.

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

niche_render_reelRender a reelAInspect

Render a 9:16 vertical reel for a session at CP3. A per-beat script (typically 4-7 beats) is composited into one video: stills, voiceover, motion, caption overlays, and an endcard (~30-120s). Reels are delivered as a downloadable file for the user to publish.

scope: 'full' (default) renders a new reel. 'recomposite' re-renders presentation only (captions on/off, caption_sync_mode, endcard text) from the retained footage at no charge. 'endcard' is the same, limited to the endcard. 'beat:N' re-renders a single beat's still (optional beat_direction), charged for that one image; everything else is reused.

Idempotent on the video output: a prior render is replaced.

Options: captions_enabled (default true) overlays per-beat captions; music_enabled (default false) mixes background music under the voiceover; tone shapes the script (default | punchy | direct | reflective), with reel_direction for free-form direction beyond those words; length or target_duration_sec set the runtime target; music_direction shapes the music; voice picks the voiceover voice; endcard_mark chooses the endcard brand mark; needs_legible_text forces a text-capable still generator; caption_sync_mode (default 'phrase') reveals captions phrase-by-phrase in sync with the voiceover at no extra cost, and is ignored when captions_enabled is false.

Errors: 503 if reel rendering is unavailable; 400 before CP3; 422 if the script is unusable. Cost: ~350 credits.

ParametersJSON Schema
NameRequiredDescriptionDefault
cellNoOptional. Cell to tag the rendered Output row (linkedin:reel / x:reel / instagram:reel). All reels are 9:16 1080×1920 universal, so cell only affects bookkeeping, not pixels. When omitted: stored under platform='video' (shared across all reel cells).
toneNoScript tone hint (scope='full'). Default 'default'. For direction beyond these four, use reel_direction.
scopeNo'full' (default): render a new reel (script plus stills plus voiceover, ~350 credits). 'recomposite': re-render presentation from the retained footage (captions on/off, caption_sync_mode, endcard_text/endcard_outro), at no charge, async. 'endcard': the same, limited to the endcard (endcard_text/endcard_outro/endcard_mark; use 'recomposite' to change captions). 'beat:N': re-render shot N's still (1-based, optional beat_direction and motion), ~15 credits; everything else is reused. Script changes (tone, voiceover words, music) require scope='full'. Partial scopes require a reel whose footage was retained, otherwise the response indicates scope='full' is needed.
voiceNoscope='full': voiceover voice for this render, overriding the brand kit's saved preference just this once. Use 'auto', 'male', or 'female', or a short hint like 'a warm female narrator'.
lengthNoscope='full': total runtime target the script is budgeted to hit. 'short' ~10-15s, 'standard' ~15-22s, 'long' ~25-40s. For an exact number of seconds, use target_duration_sec instead.
motionNoscope='beat:N': the Ken Burns motion for the re-rolled shot ('zoom-in', 'zoom-out', 'static', or a plain steer like 'slow push-out'). Overrides that shot's existing motion. Omit to keep the current motion.
session_idYesSession UUID that's reached cp3_awaiting_review or complete.
endcard_markNoWhich brand mark stamps the endcard for this render, overriding the brand kit's saved preference just this once (e.g. end on the logo, not the name). Honored on scope='full', 'recomposite', and 'endcard'. Falls back to the brand name text when the chosen asset is not set on the kit.
endcard_textNoscope='recomposite'/'endcard' only: the big endcard words (replaces the brand stamp text). Omit to keep the current endcard.
endcard_colorNoThe endcard background color, a name or hex ('navy', '#0a3d62'), overriding the brand color on the closing frame just this once. The endcard text re-resolves to stay legible on it. Honored on scope='full', 'recomposite', and 'endcard'; ignored on 'beat:N'.
endcard_outroNoscope='recomposite'/'endcard' only: the smaller endcard line under the mark. Omit to keep the current one; pass '' to clear it.
estimate_onlyNoIf true, return {credit_cost} without rendering or spending. Use to learn the cost before committing.
music_enabledNoMix background music behind the voiceover. Default false.
beat_directionNoscope='beat:N' only: optional plain-language steer for the re-rolled shot ('warmer light, no people'). Omit for a fresh take on the same brief.
reel_directionNoscope='full': free-form creative direction applied alongside tone, for steers the four tone words do not cover (pacing, narrative shape, mood), e.g. 'courtroom-drama narration, build to a reveal'. The free-form sibling of tone.
music_directionNoscope='full': free-form style, genre, and tempo for the background music, e.g. 'calm lo-fi, no vocals'. Supplying it turns music on for this render. Music is generated audio, so a free re-render or shot re-roll cannot change it.
captions_enabledNoOverlay caption text on each beat. Default true. With scope='recomposite': omit to keep the reel's current setting.
caption_sync_modeNoHow captions track the voiceover. 'beat' (default): each beat's caption shows for that beat's spoken window. 'phrase': the caption reveals phrase-by-phrase in lockstep with the spoken words (caption text is taken from the spoken VO). Ignored when captions_enabled is false. No extra cost.
needs_legible_textNoscope='full': force the text-capable still generator for every shot, for a reel whose stills carry readable words. Default false lets each shot pick the best generator on its own.
target_duration_secNoscope='full': exact total runtime target in seconds (8 to 45). Wins over `length`. The script budgets each beat to land near this total; the delivered duration can vary by a second or two.
Behavior5/5

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

Despite annotations only providing readOnlyHint=false and destructiveHint=false, the description discloses idempotency ('a prior render is replaced'), per-scope charges, error codes (503/400/422), and nuanced behaviors such as caption_sync_mode being ignored when captions are disabled and music being unchangeable on re-render. 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.

Conciseness4/5

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

Description is structured into overview, scope, options, and error/cost sentences and front-loads the main deliverable. The options paragraph is a dense run-on but condenses 20 parameters usefully; minor redundancy with schema and one default-value error keep it just below excellent.

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?

For a 20-parameter tool with no output schema, the description covers scope semantics, cost, errors, and edge cases like retained footage requirements. It lacks explicit detail on return/download mechanics beyond 'downloadable file' and does not explain how the agent should poll or locate the result, so it is complete but not fully.

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

Parameters4/5

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 prose adds cross-parameter semantics such as length vs target_duration_sec, music_direction implicitly enabling music, cell only affecting bookkeeping, and endcard_color re-resolving text. However, the prose states caption_sync_mode defaults to 'phrase' while the schema says default is 'beat', a misleading inconsistency preventing a 5.

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?

Description opens with specific verb 'Render' and resource '9:16 vertical reel for a session at CP3', detailing compositing of stills, voiceover, motion, captions, and endcard. This clearly distinguishes the tool from sibling niche_render_image_card and conveys the exact deliverable.

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

Usage Guidelines4/5

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

Description gives clear context requiring a session at CP3 and explains scope variants ('full', 'recomposite', 'endcard', 'beat:N') with when each is appropriate. It does not explicitly name alternatives relative to sibling tools, but the CP3 prerequisite and scope handling provide actionable usage guidance.

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

niche_reuse_assetReuse an image across cellsAInspect

Copy an image that already exists on one output onto another cell, instant and free (no regeneration, no credits). Use this when the user wants 'the same image' on a second surface ('use the LinkedIn image on X', 'same picture on the newsletter') instead of niche_render_image_card (which generates a new image and costs credits).

Both cells must already exist on the session (add the target via niche_add_output first if needed) and the source must have a rendered image. Copies the source's static_urls onto the target so it publishes with that image. Idempotent: source==target is a no-op.

ParametersJSON Schema
NameRequiredDescriptionDefault
to_cellYesCell to copy the image onto (e.g. 'x:image_post').
from_cellYesCell that has the image (e.g. 'linkedin:image_post').
session_idYes
Behavior5/5

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

The description discloses behavior beyond the annotations: it copies static_urls, is instant/free/no credits, idempotent, and requires a rendered source. Since readOnlyHint=false aligns with the mutation action, there is no contradiction. The added detail fully informs the agent of operational 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.

Conciseness5/5

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

The description is compact and well-structured: first sentence states the core action and benefit, second provides usage context with a counterexample, and third covers prerequisites and idempotency. No redundant phrases; every sentence adds value.

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

Completeness5/5

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

Given the tool's moderate complexity, the description fully covers what it does, when to use it, prerequisites, behavioral effects, and idempotency. The absence of an output schema is acceptable because the purpose is a simple copy operation and the outcome is implied by the description.

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

Parameters4/5

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

Schema covers 67% of parameters with examples (from_cell and to_cell). The description adds the mechanism 'Copies the source's static_urls onto the target', which explains the relationship between parameters and the effect. session_id is left to inference but is a common field; the description partially compensates for the gap.

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 opens with a specific verb and resource: 'Copy an image that already exists on one output onto another cell.' It immediately clarifies the operation's purpose and distinguishes it from niche_render_image_card by contrasting cost and outcome, making the tool's intent unmistakable.

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?

Explicit usage guidance is provided: 'Use this when the user wants "the same image" on a second surface... instead of niche_render_image_card.' It also states prerequisite conditions (both cells must exist, source must have rendered image) and points to niche_add_output as a fallback, offering both 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.

niche_session_cancelCancel a sessionA
Destructive
Inspect

Cancel a running session. Marks status=failed with an error_message ('cancelled by user' or the caller's reason), and stops the in-flight orchestrator if any.

Used when you want to free a slot under the concurrent-session cap without deleting the session (history and audit trail preserved). Use the REST DELETE endpoint if you want a hard archive cleanup that also wipes outputs.

Idempotent: cancelling a completed / already-failed session returns its current state unchanged.

Credits: the unused hold is released; work already committed (e.g. the discovery for a story you picked) stays charged, so cancelling does not refund committed work. A pre-CP1 cancel (nothing committed yet) is effectively free. A full refund applies only to an actual run failure.

ParametersJSON Schema
NameRequiredDescriptionDefault
reasonNoOptional. Surfaced as session.error_message.
session_idYes
Behavior5/5

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

Beyond the annotations (destructiveHint=true), the description discloses key behaviors: status changes to failed, error_message default, idempotency, and detailed credit handling. It also clarifies what is NOT affected (history and audit trail preserved), which is useful context for a potentially destructive operation.

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

Conciseness5/5

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

The description is well-structured into clear paragraphs, each addressing a distinct aspect: action, use case, idempotency, and credits. Every sentence adds value, with no fluff or repetition. It is slightly longer but appropriately so for a tool with complex side effects.

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

Completeness5/5

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

For a cancellation tool with no output schema, the description thoroughly covers behavior, side effects, idempotency, and credit implications. It also addresses the destructive nature and provides guidance on when to use an alternative. This is complete enough for an agent to confidently invoke the tool.

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

Parameters4/5

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

Schema coverage is 50% (reason has a description, session_id does not). The description adds context that the reason becomes the error_message and that a default 'cancelled by user' is used when omitted. It does not detail session_id further, but the purpose is clear. The description compensates reasonably for the schema gap.

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 clearly states the tool cancels a running session, marking it as failed with an error_message and stopping the orchestrator. This distinguishes it from related sibling tools like niche_session_revert and niche_session_state, and it also contrasts with the REST DELETE endpoint for hard cleanup.

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?

Explicitly states when to use this tool: to free a slot under the concurrent-session cap without deleting the session. It also provides an alternative: use the REST DELETE endpoint for hard archive cleanup that wipes outputs. This gives 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.

niche_session_exportExport a sessionA
Read-only
Inspect

Export a session as a structured calendar artifact preserving session_id and per-story story_id traceability. Use after a niche_signal_scan when you want a metadata-rich content backlog instead of running individual pieces end-to-end. Outputs a standard editorial-calendar shape suitable for content-backlog and planning workflows.

Two formats: • markdown: human-readable and agent-citable. Session metadata at top (session_id, niche, scan timestamp, and brand_profile_active state). Then a card per story with title, headline_candidate, summary, recency_score, publication_breakdown, source_breakdown, and empty slots for the user to fill (Frame, Hook, Article-shape, Ship Order). Followed by a 'recommended ship order' section and cross-cutting notes. • json: structured shape ready to pipe to other tools or load into a notebook. Same data, machine-shaped.

Preserves story_id and session_id traceability so you can come back in N weeks and re-run niche_angle_propose / niche_draft_create against the same stories with the same brand profile bound. The artifact is the entry point to a calendar-builder workflow.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNoOutput shape. Default markdown.markdown
session_idYes
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds details about output formats (markdown vs. json), what each contains, and that it preserves session_id/story_id traceability, providing 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.

Conciseness4/5

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

The description is detailed but well-structured: opening purpose, usage guidance, two bullet-point formats, and a traceability paragraph. Every sentence earns its place, though the format bullets are somewhat verbose. Still within reason for a tool with complex output shapes.

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

Completeness5/5

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

With no output schema, the description thoroughly explains what the tool returns (content of markdown and json exports, traceability, and workflow fit). It also covers when to use it, making the description near-complete for an export tool with only two parameters.

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

Parameters4/5

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

Schema covers format with enum/default but not session_id. The description adds substantial detail about both formats (markdown human-readable vs. json machine-shaped) and the artifact's content, compensating for the 50% schema coverage. It doesn't elaborate on session_id, but that is self-explanatory.

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 states 'Export a session as a structured calendar artifact' with a specific verb, resource, and output type. It distinguishes from siblings like niche_list_sessions and niche_signal_scan by emphasizing the structured backlog artifact and workflow integration.

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?

It explicitly says 'Use after a niche_signal_scan when you want a metadata-rich content backlog instead of running individual pieces end-to-end.' This gives clear when-to-use context and an implicit alternative, making it easy for an agent to choose correctly.

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

niche_session_revertRevert a session checkpointA
Destructive
Inspect

Revert a session back to an earlier checkpoint. Use when the user (or you) decided the picked story / angle isn't the right one and you want to re-pick without starting a new scan.

to='story': cancels current generation, returns to CP1_AWAITING_STORY with the same ranked stories list. Clears selected_story_id and selected_angle_id. to='angle': returns to CP2_AWAITING_ANGLE with the same angles list. Clears selected_angle_id only.

Idempotent: reverting a session already at the target checkpoint returns the current state unchanged.

Safety: reverting a finished run (cp3/complete) discards its paid-for drafts. The first call returns status='confirm_discard' with the count instead of reverting; pass acknowledge_discard=true to actually proceed. Credits: the discarded drafts are not refunded (the generation already ran), and re-picking re-runs and re-charges content generation. Revert to change direction, not to reclaim spend.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYes
session_idYes
acknowledge_discardNoRequired to revert a cp3/complete session; confirms you accept discarding its finished, paid-for drafts.
Behavior5/5

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

Goes far beyond the destructiveHint annotation by detailing idempotency, state transitions (CP1/CP2), cleared fields, the confirm_discard flow, and the financial consequence of discarding paid-for drafts. This richly discloses behavior not otherwise visible.

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

Conciseness5/5

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

The description is well-organized and front-loaded with the purpose. Each paragraph adds unique value: usage context, parameter behavior, idempotency, and safety. No fluff or repetition; every sentence earns its place.

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

Completeness5/5

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

For a complex destructive tool with no output schema, the description covers all essential aspects: what triggers use, exact state changes, idempotent behavior, the confirmation safety mechanism, and credit implications. It leaves no critical gaps for an agent to safely invoke it.

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

Parameters5/5

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

Schema coverage is only 33% (only acknowledge_discard has a description). The description compensates by explaining the 'to' parameter's two values (story/angle) and their distinct effects, plus clarifies acknowledge_discard's necessity and consequence. session_id is self-evident.

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 clearly states the tool reverts a session to an earlier checkpoint, with specific verbs and resources. It distinguishes itself from siblings like niche_session_cancel by focusing on checkpoint reversion without starting a new scan, and elaborates on the two target checkpoints (story/angle).

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?

Explicitly states when to use: when the picked story/angle isn't right and you want to re-pick 'without starting a new scan.' It also covers exclusions and caution around reverting finished runs, providing clear context for safe use.

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

niche_session_stateRead session stateA
Read-only
Inspect

Universal poll endpoint: read the full current state of a session. Returns status, ranked stories, picked story_id, generated angles, picked angle_id, draft outputs (with trust fields), and an elicitation hint for whatever decision is next. Call this whenever you need to check progress; it's safe and cheap.

Each story includes title, summary, headline_candidate (the post-shaped headline distinct from the cluster title), recency_score, relevance_score, freshness_label, and the publication_breakdown of contributing outlets (provenance). Each story also carries a recommended_story_id plus recommendation_reason before a pick. Each draft output's trust data lives under outputs[i].trust.* (verifier_blocked_reason, source_faithfulness_score, source_ungrounded_claims, source_diversity_passed, source_recency_passed, source_distinct_count, plus a flags[] array with explicit severity and source_grounding_map). The output top level does not mirror these; read them from .trust.

Response also includes phase (high-level: scanning / drafting / filed / spiked / awaiting), phase_message (a rotating gerund, e.g. 'Reading 337 signals'), and phase_hint (a one-line agent-facing tooltip with a typical timing band, e.g. 'Clustering, usually 8-15s, no action needed'). The full 17-status state machine is enumerated under status_glossary so you can introspect what every state means without discovering it experimentally. For a terminal run, read outcome (complete / expired / interrupted / cancelled / failed) rather than the raw status: a failed status is usually an expired walk-away (a slate was produced) or a refunded interruption, not a real error.

Recommended loop: kick off work, then one niche_session_state(wait:30, wait_until:'checkpoint') per stage. It sleeps through the noisy transient statuses (clustering, ranking, generating_*) and wakes only at the next actionable stop (cpN_awaiting_* / complete / failed), or when an async render settles. So a full run is one wait per checkpoint, not several wakes per stage. (wait_for is an accepted alias for wait_until.) The wait plus since_status long-poll (wait_until:'change', wakes on any status change) is also supported; prefer 'checkpoint'. Each status' actionable flag in status_glossary[] indicates which states a 'checkpoint' wait wakes for. Avoid polling every few seconds without wait, which may be rate-limited (HTTP 429).

niche_story_search is an accepted alias for this tool.

Response shape is sparse by default: after a story is picked, only the picked story is returned (not all candidates); same for angles. Set include_unpicked=true to get the full candidate set, useful when revising to a different story or angle. A sparse_mode field in the response reports how many items were dropped.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNo`status` (lean): a few-hundred-byte control envelope of status, phase, picked ids, `content_versions` (per-section change counters), `counts`, `output_ids`, cost, and next_step. Use this for the poll loop. `full` (default): the complete state with stories/angles/outputs. Fetch `full` once when a content_version moves, rather than re-shipping the full state every poll. Pairs with wait plus since_status.full
waitNoLong-poll for up to N seconds (0-30) waiting for the session state to change. Returns immediately if the state already differs from `since_status` (or if the session is awaiting a checkpoint / complete / failed). Drops agent token burn from N polls to 1 wait. Default 0 (no wait, behave as before).
wait_forNoAlias for `wait_until` (same values and semantics). Use either; if both are set, `wait_until` wins. An unrecognized value is rejected (not silently ignored), and it only takes effect with `wait` > 0.
session_idYessession_id from niche_signal_scan.
wait_untilNoWhat the `wait` long-poll resolves on. `change` (default): any status change vs since_status, a reached checkpoint, or a status-less change (synthesis fill, render completion, new output). `checkpoint`: only an actionable checkpoint (cpN_awaiting_* / complete / failed), skipping the noisy intermediate cpN_generating and generating_* transitions, so you get one wake per checkpoint. `render`: a reel/image render marker settles (done|failed). Use this after niche_render_reel / niche_render_image_card, since a render leaves status unchanged and won't wake a `change` wait on status alone. Works on a session already at complete (the normal case, since renders are post-completion add-ons): the wait holds on the render marker, not the session status. `synthesis`: a niche_intelligence_query's synthesis lands (narratives or a shortfall_note). Synthesis filling is not a status change, so block on this in one call instead of busy-polling.change
since_statusNoUsed with `wait` (wait_until='change'). The status the caller last saw; the wait returns as soon as session.status differs. If unset, any state-change event wakes the wait. Note the pipeline has paired vocabulary: a transient `cpN_generating` (checkpoint about to produce) and a `generating_*` work status (e.g. cp2_generating maps to generating_angles). To skip both and wake only at the next actionable stop, use wait_until='checkpoint' rather than chasing since_status through the intermediates.
include_unpickedNoWhen true, return the full candidate set even after picks have been made. Default false (sparse: only the picked story / angle come back). Meaningful only with view='full'; ignored in view='status' (the lean envelope never carries the candidate slate).
include_status_glossaryNoWhen true, response includes `status_glossary[]`, the full 17-status state-machine descriptor list with phase, hint, and `actionable` (whether a wait_until='checkpoint' wakes for it) per status. Useful on the first call of an agent session so the agent caches the full map; leave false on subsequent polls. Default false.
Behavior5/5

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

Discloses numerous behavioral traits beyond the readOnly/destructive annotations: sleep-and-wake polling semantics, sparse response behavior, outcome vs. raw status nuance ('a failed status is usually an expired walk-away'), alias behavior, and rate-limit risk (HTTP 429). Annotations already mark readOnlyHint=true and destructiveHint=false, so the description adds rich context rather than repeating safe-read facts.

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?

The description is long but exceptionally dense and well-organized: front-loaded purpose, then return fields, then polling guidance, then sparsity and edge cases. Each section earns its keep; there is no filler or repetition. It could arguably be tightened, but the structured paragraphs and clear topical separation make it easy to scan despite the length.

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

Completeness5/5

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

Given the tool's complexity (8 params, 17-status state machine, no output schema), the description covers everything an agent needs: response fields, trust data location, status_glossary, outcome semantics, aliases, rate limits, sparse mode, and recommended loop. It fully compensates for the missing output schema and leaves no obvious gap.

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

Parameters4/5

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

Input schema already covers all 8 parameters with full descriptions, defaults, and enums (100% coverage). The description elevates this by explaining how parameters interact operationally—e.g., wait_until='checkpoint' vs 'change', wait_for alias precedence, include_unpicked sparsity semantics, and recommended concrete values (wait=30). The baseline for 100% coverage is 3, but the added operational context justifies a 4.

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 opens with 'Universal poll endpoint: read the full current state of a session' and enumerates exact return fields (status, ranked stories, picked IDs, draft outputs, trust fields, elicitation hint). This specific verb+resource scope clearly distinguishes it from siblings like niche_signal_scan (kickoff) and niche_list_sessions (session list).

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?

Provides explicit when-to-use and how-to-use guidance: 'Call this whenever you need to check progress; it's safe and cheap' and recommends a polling loop with wait=30 and wait_until='checkpoint'. It also warns against rapid polling ('Avoid polling every few seconds without wait, which may be rate-limited') and explains when to use wait_until='render' or 'synthesis' for sibling render/query tools, effectively defining alternatives.

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

niche_signal_scanDiscover stories (signal scan)AInspect

Niche (nicheangle.com) story discovery: find stories worth writing about, then draft and publish platform-native social content (LinkedIn, X threads, Instagram, newsletter) from them. This is story discovery, not content generation: Niche reads primary sources, separates signal from noise, and clusters it into a ranked story slate with provenance, the editorial-intelligence step before any writing. Returns a session_id plus initial status; poll niche_session_state with the session_id until status is cp1_awaiting_story to read the slate.

Brand profile: the run's voice/offer/CTA. You do NOT need niche_whoami to brand a run: OMIT brand_id and a single or default brand binds automatically (silently). On a MULTI-brand account, an omitted brand_id returns brand_choice_required with brand_options[] inline (the slate still lands). Ask the user which brand, then re-call with brand_id (or brand_id:'none' for a deliberately unbranded run); don't draft until one is chosen. Pass brand_id to bind a specific persisted profile (set via niche_brand_profile_set); its voice, lexicon, framing, channel config, and verifier overrides thread through every downstream stage. Pass profile_overrides alongside brand_id to deep-merge a one-time deviation (logged on the session, not stored). The effective profile is snapshotted at scan time; later updates to the persisted profile don't affect in-flight runs.

ParametersJSON Schema
NameRequiredDescriptionDefault
nicheYesNiche / beat description (2-200 chars). Specific is better.
densityNoHow tightly to pack visual formats (carousels especially). • minimal: split a dense argument across more, shorter slides; favors skimmability. • balanced (default): the standard per-slide caps. • essay: permissive; allows longer slides/sections. Over-cap slides auto-split on sentence boundaries (never mid-sentence); over-280 tweets split into a chain regardless.balanced
recencyNoOptional 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.
brand_idNoBinds 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.
estimate_onlyNoWhen true, return the discovery credit cost without starting a run or holding a reservation. Use it to quote a price before committing.
recency_strictNoWhen 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).
source_qualityNoHow aggressively to filter the slate on source quality (niche-relative; never penalizes a small publication that is the authority for the niche). • 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. • balanced (default): down-weight weak sources, don't drop. • broad: surface everything, including low-coverage emerging clusters, with authority as a tiebreaker only. Use strict for a high-trust brief, broad to scout early signal.balanced
target_outputsNoOutput cells to generate (platform×content_type matrix). Each cell is a 'platform:content_type' string or a cross-platform content type. Valid cells: • linkedin:text_post: short LinkedIn post (text only) • linkedin:image_post: LinkedIn post plus 1.91:1 image card • linkedin:carousel: multi-slide carousel • linkedin:reel: LinkedIn-native vertical video • x:single_tweet: standalone tweet • x:thread: multi-tweet thread • x:image_post: tweet plus 16:9 image card • x:reel: tweet plus 9:16 video • instagram:image_post: caption plus 4:5 image card • instagram:carousel: multi-image swipe • instagram:reel: caption plus 9:16 reel • long_form_article: universal essay (Substack/blog) A 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. Defaults to ['linkedin:text_post']; request only the cells you need (each additional cell adds generation cost).
idempotency_keyNoOptional. 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.
thinking_budgetNoAgent-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. • 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. • balanced (default): scan returns immediately with session_id; the agent polls niche_session_state (with wait plus since_status long-poll).balanced
target_platformsNoOptional. A flat platform list (linkedin, linkedin_carousel, twitter, longform, instagram), coerced into target_outputs cells. Prefer target_outputs.
profile_overridesNoOptional. 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.
Behavior5/5

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

The description discloses substantial behavioral traits beyond the annotations: it starts a run, may hold a reservation, can bill, supports idempotency, auto-dedupes identical scans, and can block up to ~45s in fast mode. It also notes the effective profile is snapshotted at scan time. This far exceeds the minimal annotation set and gives the agent critical operational expectations.

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?

The description is long but dense; every sentence provides actionable guidance. It is front-loaded with the core purpose, then return semantics, then brand profile nuances. While it could be trimmed slightly, the complexity of the tool justifies most of the length, and there is no filler or repetition.

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?

The description covers the return value (session_id plus initial status), how to retrieve results (poll niche_session_state), cost estimation via estimate_only, and idempotency. With no output schema, it explains what the agent needs to know to proceed. It doesn't describe the slate's internal structure, but this is not strictly necessary for successful invocation and polling.

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

Parameters4/5

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

The schema already provides 100% coverage with detailed parameter descriptions, so the baseline is 3. The description adds extra semantics beyond the schema, especially around brand_id: multi-brand behavior, brand_choice_required, brand_id:'none' for unbranded runs, and the deep-merge of profile_overrides. It also adds context for idempotency and retry behavior, supplementing the schema's parameter docs.

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 opens with a specific verb+resource: 'Niche story discovery: find stories worth writing about, then draft and publish platform-native social content.' It explicitly distinguishes itself from content generation: 'This is story discovery, not content generation,' and describes the output as a 'ranked story slate with provenance.' This clearly separates it from sibling draft/publishing tools.

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

Usage Guidelines4/5

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

The description gives clear context for when to use the tool ('the editorial-intelligence step before any writing') and when to poll via niche_session_state. It also provides exclusions such as 'You do NOT need niche_whoami to brand a run.' However, it doesn't explicitly name alternative sibling tools for when not to use this tool, but the 'when' and 'when-not' guidance is strongly implied.

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

niche_voice_profile_ingestIngest a voice profileAInspect

Extract voice primitives (register / sentence rhythm / lexicon preferences / punctuation habits) from post-shaped text and persist onto the user's VoiceProfile. The voice primitives thread into content generation so generated copy matches the user's actual writing voice.

Two input shapes: pass posts (list of pre-collected text snippets, ≥80 chars each) or pass url (the server scrapes post-shaped snippets from the page: Substack / Medium / blog / X profile). Inline posts win when both are given. Inline post-shaped snippets need to be the user's own writing, not press articles or marketing copy.

Returns the extracted primitives + a diff of what changed on the stored VoiceProfile.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNoURL to scrape post-shaped text from. Substack / Medium / blog homepages work best; X / LinkedIn profile pages are supported but yield less per-snippet text.
postsNoPost-shaped text snippets the user wrote. ≥80 chars each; 3-10 snippets is the sweet spot for primitives extraction.
brand_idNoWhich brand's voice to ingest into. Voice is brand-scoped: omit for the default brand, or pass a brand_id (from niche_brand_profile_get) to set up that brand's voice without touching another brand's. A brand with no voice of its own falls back to the default voice at generation time.
archetypeNoOptional label for how the profile was acquired; tags the VoiceProfile.archetype field. Defaults to 'agent_ingest'.agent_ingest
overwriteNoWhether to replace an existing VoiceProfile. Default false: first run wins, subsequent runs are no-ops unless explicitly opted in, so an automated re-run does not overwrite a hand-curated voice.
Behavior5/5

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

Beyond annotations (readOnlyHint=false, destructiveHint=false), the description discloses that this is a persist operation, explains the no-op default behavior ('first run wins, subsequent runs are no-ops'), describes server-side scraping for URLs, and notes the return of a diff of changes. This adds substantial behavioral context and does not contradict any annotation.

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

Conciseness5/5

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

The description is organized into three focused paragraphs: purpose, input shapes, and return value. It is front-loaded with the main action, and every sentence contributes meaningful information without redundancy or fluff.

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

Completeness5/5

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

Given 5 parameters, useful annotations, and no output schema, the description covers the core purpose, both input modes, precedence, content quality, side effects (overwrite behavior), and return value. It provides enough context for an agent to select and invoke the tool correctly.

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

Parameters4/5

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

Schema coverage is 100% with detailed parameter descriptions, so the baseline is 3. The description adds value by explicitly stating the posts-vs-url precedence rule and explaining the brand-scoped behavior, which is not fully apparent from individual parameter descriptions.

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 clearly states 'Extract voice primitives ... and persist onto the user's VoiceProfile,' identifying the specific verb, resource, and outcome. It distinguishes the tool from siblings like niche_brand_profile_get/set by focusing on voice ingestion from post-shaped text, and it explains the purpose ('thread into content generation').

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

Usage Guidelines4/5

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

Provides explicit guidance on input shapes: pass `posts` or `url`, with precedence ('Inline posts win when both are given'). Also gives quality requirements ('≥80 chars each', 'user's own writing, not press articles or marketing copy'). However, it does not directly contrast with sibling tools such as niche_brand_profile_set, so explicit alternatives are not named.

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

niche_whoamiWho am I (account + capability map)A
Read-only
Inspect

List the full tool catalog and orient the agent, in one read-only call. Returns every registered tool name and the live tool count, the account (plan and credit balance), a capability map (tools grouped into bands: discover, decide, draft, render, publish, brand, session, plus the recommended flow), and the brand state (whether a brand profile, kit, or voice will personalize output). Call it first to discover what's available, plan a session, and check credits before spending.

ParametersJSON Schema
NameRequiredDescriptionDefault
include_testNoInclude scratch and experimental brand slots in available_brands. Default false so only real brands are listed and an agent does not bind a throwaway by accident.
include_all_brandsNoList every brand on the account in available_brands. Default false: only the active brand is returned (with other_brand_count) so a single orienting call does not enumerate the whole roster. Set true when you genuinely need to pick among multiple brands.
include_brand_assetsNoInclude usable brand asset URLs (logo, wordmark) in brand_palette. Default false: the palette returns colours and fonts plus logo_available / wordmark_available booleans, and the renderer fetches the actual asset when a render needs it. Set true only if you need the asset URL directly.
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this with 'read-only call.' It adds valuable context beyond annotations by detailing what the tool returns: registered tool names, live tool count, account plan/credit balance, capability map, and brand state. This helps the agent predict the output and plan actions, though it does not describe internal mechanics or edge cases.

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

Conciseness5/5

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

The description is three sentences long and front-loaded with the core purpose. It lists the main return categories in a compact, scannable style, and every sentence adds value—no filler, no redundancy. The structure effectively conveys both behavior and usage in minimal space.

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

Completeness5/5

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

The description is complete for a tool with no output schema: it covers the full set of return values (catalog, account, capability map, brand state), the intended usage ('Call it first'), and the safety profile (read-only call). It even hints at the recommended flow within the capability map. The optional parameters that alter output are already detailed in the schema, so the description does not need to repeat them.

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%, with all three optional boolean parameters clearly documented in the input schema (include_test, include_all_brands, include_brand_assets) including their defaults and effects. The description does not add extra parameter semantics beyond what the schema provides, but this is acceptable because the schema already carries the full burden. 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 clearly states the tool's function: 'List the full tool catalog and orient the agent, in one read-only call.' It enumerates the exact resources returned (tool catalog, account info, capability map, brand state) and distinguishes itself from sibling action tools like niche_draft_create or niche_render_image_card by serving as an orientation/meta tool. The phrase 'Call it first' reinforces its unique role.

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?

The description gives explicit usage guidance: 'Call it first to discover what's available, plan a session, and check credits before spending.' This tells the agent exactly when to invoke it and why, while also implying it should precede other tool calls. It does not explicitly mention exclusions, but given its read-only and orientation purpose, the guidance is sufficient and clear.

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

Discussions

No comments yet. Be the first to start the discussion!

Related MCP Servers

  • A
    license
    -
    quality
    B
    maintenance
    A writing tool your agent calls: it finds timely sources across news, social, and the web, ranks them by relevance, and writes human-sounding posts worth publishing.
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    Enables detection and analysis of pre-public product launches through web search, content extraction, AI-powered scoring, and automated alerting. Provides comprehensive tools for surfacing stealth startup signals before they trend publicly.
    MIT

View all MCP Servers

Try in Browser

Your Connectors

Sign in to create a connector for this server.