Niche

Editorial intelligence for creators and their agents.

От сообщества: Добавлен пользователем или импортирован; проверьте владельца перед подключениемРаботаетБез входаГлобальныйБесплатноМожет изменять данные

Что умеет

  • Niche Signal Scan: Niche (nicheangle.com) story discovery: find stories worth writing about, then draft and publish platform-native social content (LinkedIn, X threads, Instagram, newsletter) from the
  • Niche Draft Direct: Draft the creator's OWN take or product straight into posts — NO research scan, no story/angle picks. Use this for product-led / bring-your-own-content work: a specific thing to sa
  • Niche Intelligence Query: 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 po

Какие данные видит

Нужен ли аккаунт

Не нужен: сервер работает без входа

Editorial intelligence for creators and their agents. Most tools help you write, Niche helps you decide what's worth writing. It reads primary-source signal, discovers emerging stories, ranks the strongest angle, and turns that signal into publishable, platform-native content that's grounded in real sources, in your voice.

25 tools across discovery, drafting, render, and brand. Remote (Streamable HTTP), OAuth 2.1 + PAT.

Список инструментов сервера (25)

Технические названия из tools/list. Нужны только разработчикам.

niche_signal_scanNiche (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 + initial status; poll niche_session_state with the session_id until status is `cp1_awaiting_story` to read the slate. BRAND PROFILE: pass `brand_id` to bind this run to a persisted brand profile (set via niche_brand_profile_set). The profile's 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 onto the persisted profile (logged on the session, not stored). The effective profile is snapshotted at scan time — subsequent updates to the persisted profile don't affect in-flight runs.
niche_draft_directDraft the creator's OWN take or product straight into posts — NO research scan, no story/angle picks. Use this for product-led / 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` / `source_text` (the last two repurpose an existing page). Async: returns a session_id in <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 + CTA so the draft sounds like them and pitches their wares (set those first via niche_brand_profile_set).
niche_intelligence_queryNiche (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 (<2s). Poll niche_session_state every ~3-5s. At status == cp1_awaiting_story the ranked slate (`stories[]`) is ready — present it right away. Synthesis fills in a few seconds AFTER the slate: if you requested it, keep polling while `synthesis_pending == true`; once false, `synthesis[]` holds the grounded narratives (or `synthesis_shortfall_note`). With synthesis:'none', `synthesis` stays null and `synthesis_pending` is false at cp1 — stop there. To turn a narrative into a post, pick its supporting story id and call niche_angle_propose — no new scan needed. Pass brand_id to thread a brand profile.
niche_session_stateUniversal 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 + 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 + 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` (rotating gerund — Reading 337 signals…), `phase_hint` (one-line agent-facing tooltip with a typical timing band — 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. BEST LOOP (do this): 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 2-3 wakes per stage. (`wait_for` is an accepted alias for `wait_until`.) The older `wait` + `since_status` long-poll (wait_until:'change', wakes on ANY status change) still works for back-compat, but prefer 'checkpoint'. Each status' `actionable` flag in `status_glossary[]` tells you which states a 'checkpoint' wait wakes for. Do NOT poll every few seconds without `wait` — that's what trips a 429. Alias: niche_story_search (legacy name, supported for back-compat — the new name reflects the actual job). 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.
niche_angle_proposeNiche 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 (swap palette). niche_session_state then carries an angle_recommendation (recommended_angle_id + reasoning); when a brand profile is bound it is brand-fit-scored, otherwise recommended_angle_id is null with recommendation_basis='default_ordering' (no fake 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 + 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 seeds a synthetic 1-source session and drops the provenance.
niche_draft_createNiche 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 + 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`.)
niche_draft_reviseYOU write the new caption/fields and pass them in — this does NOT rewrite from an instruction (unlike a chat 'make it punchier'). To change the copy, supply the new copy as `caption`. 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). 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 / 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.
niche_draft_publishPublish a single output to its platform. Defaults to dry_run=true — returns the would-publish payload + 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. 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' + a `connect_url` instead of publishing — send the user to connect once, then retry.
niche_brand_profile_setSet (or update) the persisted brand profile for a brand the user manages. The profile is a structured JSON document that's load-bearing across every pipeline stage — voice rules, banned terms, canonical vocabulary, framing allowlist, channel config, compliance disclosures, verifier overrides. Use this when: - The agent has derived a brand profile from a repo / docs and wants to persist it so future runs inherit the rules. - An update to voice rules / banned terms needs to land before the next run. REQUIRED sections: `identity` and `voice` (a profile with no voice is rejected — it's what drives the generic-fallback drafts). A profile saved before this requirement is grandfathered: a re-set that omits voice gets a default voice stub auto-added rather than rejected, so legacy profiles aren't stranded. Validation: tiered lints (error / warn / info). `error` lints REFUSE the set entirely. `warn` lints accept-with-note. The response always includes `lints[]` so the caller sees ambient warnings. `conflicts[]` surfaces BrandKit-locked field collisions — the BrandKit wins on those paths and the profile values are dropped from storage. v1 ships persisted scope only; session and inline_overrides scopes are per-call constructs (passed alongside other tool arguments). brand_id is unique-per-user — re-setting the same brand_id replaces the prior profile.
niche_list_sessionsEnumerate 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 + 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.)
niche_brand_kit_ingestAuto-populate the user's BrandKit (palette / fonts / tagline / logo / wordmark / boilerplate / voice notes) from files OR a URL OR pasted text. By default ADDITIVE — fills empty fields, leaves populated ones alone. Idempotent: re-running the same inputs doesn't double-write. OVERWRITE RULE (important): 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 + `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 + content_generation stages inherit the brand context. Agent-side equivalent of the web /brand-kit ingest surface — same backend engine. ASYNC + 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 → poll status until done/failed; same pattern as niche_signal_scan → 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.
niche_brand_kit_ingest_statusPoll 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 + detected[]/skipped[]/errors[]/diff[]/left_unchanged_because_populated[]) | 'failed' (error + failed_step; the kit was NOT written). The marker expires 30 min after the ingest starts.
niche_voice_profile_ingestExtract 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 prompts 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` (we scrape 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.
niche_brand_profile_getRead-back tool: verify what's actually persisted for a brand profile WITHOUT re-setting it. Use after niche_brand_profile_set to confirm the schema landed as expected; use mid-session to double-check the active profile a run is bound to; use before niche_brand_profile_set when an agent is about to write a partial update and wants to inspect the current shape first. 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 + a brand_kit_sync_status hint reflecting whether the profile's mirrored fields are in lock-step with BrandKit. Lets an agent introspect the active profile shape instead of inferring it from prior set calls.
niche_brand_kit_guided_setupReturn a structured question chain the agent walks the user through to populate the BrandKit + VoiceProfile + (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 + 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).
niche_brand_kit_updateSet 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 (not append). Response includes a diff[] of fields that changed and the full updated kit.
niche_render_image_cardRender a visual onto a CP3 post — or, with scope='recomposite', EDIT THE TEXT on an existing image for FREE (same background, new words/color/size — NEVER re-render just to change text, that costs ~30cr and swaps the art under the user). scope='restore' brings back the prior image from history, also free. House rule: presentation changes never route through generation. For a NEW render (scope='full', the default) you MUST pick `background` — there is NO default, on purpose: the two modes differ sharply in cost + result, and a wrong guess either burns credits or returns a flat color when you wanted a picture. • background='photo' — a GENERATED AI/photographic image made for the story, with your headline composited over it. This is the actual picture. The output's script keeps `bg_url` — the CLEAN generated background retained separately from the composited card; it powers FREE text/color/size re-composites + restore (no regen). ~30 credits, ~30-90s, ASYNC: returns status='rendering_image_card'; poll niche_session_state (`image_render.status`: rendering → done, static_urls land on the output / failed, credits refunded). Don't re-call on a perceived hang (a second call no-ops while one is in-flight). • background='brand_color' — a FREE, instant flat BRAND CARD: your headline on the brand's solid color with logo + wordmark. No image generation, no credits, milliseconds. SYNCHRONOUS: the card is in outputs[] right away. `headline` sets the bold header for either mode (defaults to the post's card_headline; auto-fits, never truncated). Idempotent: a prior render is replaced. Errors: render_not_ready if pre-CP3; render_not_configured (photo) if no image-gen key; render_card_unavailable if brand_color but the piece has no card-bearing platform.
niche_render_reelRender a 9:16 vertical reel for a session that's reached CP3: a per-beat script (typically 4-7 beats) becomes stills + voiceover + motion + caption overlays + an endcard, composited into one video (~30-120s). scope='recomposite' re-renders an EXISTING reel's presentation for FREE from its kept footage — captions on/off, caption_sync_mode, endcard words — same beats, same voiceover, 0 credits (house rule: presentation changes never route through generation). NEVER pay a full re-render just to flip captions or fix the endcard line. scope='endcard' is the same free door narrowed to the endcard only; scope='beat:N' re-rolls ONE shot's image (same script, fresh take, optional beat_direction steer) for a small honest charge and reuses everything else. HEADS-UP before spending: reels are DOWNLOAD-ONLY for now (direct Instagram publishing is pending platform approval) — the user posts the file themselves. Set that expectation before the render. Idempotent on the video platform: any prior render is replaced. Toggles: `captions_enabled` (default true) overlays the per-beat caption text on each still; `music_enabled` (default false) mixes background music behind the voiceover; `tone` shapes the script — `default` | `punchy` | `direct` | `reflective`; `caption_sync_mode` (default 'phrase' — captions track the voiceover in lockstep) — 'phrase' reveals captions phrase-by-phrase in lockstep with the spoken words (text taken from the VO). Phrase mode adds NO extra credits (it reuses timestamps already fetched). Ignored when captions_enabled is false. Errors: 503 if the render backend isn't configured; 400 if pre-CP3; 422 if the script came back unusable. Cost: standard tier = ~350 credits (one still per non-endcard beat + voiceover + composite). Premium opt-in is a separate path.
niche_session_revertRevert 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 + 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 + re-charges content generation — revert to change direction, not to reclaim spend.
niche_session_cancelCancel 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 + 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 — cancelling does not refund committed work. A pre-CP1 cancel (nothing committed yet) is effectively free. A full refund is reserved for an actual run FAILURE.
niche_session_exportExport a session as a structured calendar artifact preserving session_id + 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 + agent-citable. Session metadata at top (session_id + niche + scan timestamp + 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 + 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.
niche_add_outputAdd 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. session started with linkedin:text_post, 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 — swap it 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 + 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. Errors: 400 if session is pre-CP3; 422 if cell is invalid.
niche_reuse_assetCopy an image that ALREADY exists on one output onto another cell — instant + FREE (no regen, 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.
niche_attach_imageAttach a USER-SUPPLIED photo to a post — the creator's OWN image (a product shot, their actual work) as the post's visual, instead of an AI-generated image (niche_render_image_card photo, paid) or a flat brand card. FREE — no image-gen spend. For a visual-product maker the real piece IS the sale. Pass the cell + the image as base64 ({mime_type, data_base64}). 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. Undo-able (the prior image is kept in history).
niche_whoamiOne safe read-only call that orients an agent: WHO it is (the authenticated account, plan, and credit balance), WHAT the server is (version, endpoint, transport, live tool count), the CAPABILITY MAP (every tool grouped into functional bands — discover / decide / draft / render / publish / brand / session — plus the recommended flow), and the BRAND STATE (whether a brand profile / kit / voice will shape output, so the agent knows BEFORE a run whether drafts will read personalized or as neutral commentary). Call this first to plan a session and to check credits before spending.
Niche: подключить к Claude, ChatGPT, Cursor · Connectors.fun