Skill instructions
omneky-analytics7.83 KB
View saved version →
---
name: omneky-analytics
description: >-
Read Omneky paid-media performance: ROAS, CTR, CPA, spend, impressions,
conversions, trends, daily metrics, and dimension summaries. Use when the
user asks how Meta/Facebook, Google, TikTok, LinkedIn, Reddit, Pinterest,
or X Ads are performing, or wants HubSpot CRM / Semrush / Ahrefs / GSC
lookups for the signed-in brand. Intent keywords: ROAS, CTR, CPA, spend,
paid media, Meta ads, Facebook ads, Google Ads, TikTok ads, which ads
should I make more of, campaign breakdown, creative leaderboard,
trending, HubSpot, Semrush, Ahrefs, GSC, coverage check.
---
# Omneky analytics
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Read-only performance and brand-connector reporting for the signed-in user's
brands. Answer “how did we do?” and “what should we make more of?” with
structured MCP tools only — never invented SQL, warehouse tables, or lift
endpoints.
## When to use
- How ads performed (ROAS, CTR, CPA, spend, conversions) over a date range
- Which creatives, campaigns, or channels are winning
- What rose or fell versus the prior period (also see
`omneky-performance-movers`)
- Coverage check before querying (dates + channels)
- HubSpot CRM search, Semrush domain/keyword overview, Ahrefs DR /
keywords / backlink stats, or Google Search Console analytics
## When not to use
- Launching, pausing, or budgeting ads → `omneky-launch-manage` /
`omneky-pause-budget`
- Generating or editing creatives → `omneky-creative` /
`omneky-image-ads` / `omneky-product-video` / `omneky-edit-resize`
- Catalogue SKU writes → `omneky-catalogue` / `omneky-product-import`
- Arbitrary SQL — there is **no** public `run_sql_query`
- Plan / Stripe portal as the primary ask → `omneky-billing`
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: end the turn after Approve / Deny (or Generate / Cancel) via host UI or plain chat; mutate only after affirmative Approve / Generate. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Never invent metrics, score / lift endpoints, or warehouse table names.
- Always call `check_reporting_data_available` (preferred over deprecated
`data_available`) **before** treating empty results as real zeros.
- `selected_conversion_metric_value` **varies per channel**. Never sum it
across channels; group by channel or use a named metric.
- Prefer `get_performance_breakdown` over deprecated
`get_dimension_summary`; prefer `get_performance_movers` over deprecated
`get_trending` (aliases may still appear on `tools/list`).
- Prefer `search_reporting_values` over deprecated
`search_dimension_values` when both exist.
- If brand or date range is missing, ask once. Do not guess `brand_id`.
- Lead with the answer; name the channel / campaign when filtered.
- Auth is host OAuth; never ask for a token.
## Staged workflow
### Stage 1 — Session + brand
1. `get_current_user` when `user_id` is required by later tools.
2. `list_brands` / brand picker if `brand_id` unknown.
3. `get_brand` / `get_brand_details` as needed.
### Stage 2 — Coverage gate
1. Confirm date range with the user (default a tight recent window if they
said “lately” / “this week” — still state the range you will use).
2. Call `check_reporting_data_available` for brand + dates + channels.
3. If coverage is empty for the requested slice, report coverage — do not
fabricate zeros.
### Stage 3 — Choose the performance tool
| Intent | Tool |
| --- | --- |
| What moved vs prior period | `get_performance_movers` |
| Day-by-day time series | `get_daily_metrics` |
| Ranked breakdown (campaign / creative / channel / …) | `get_performance_breakdown` |
| Resolve a name → id for filters | `search_reporting_values` |
| AI creative / media recommendations | `get_recommendations` (tight window; on `status=timeout` narrow — no identical retry this turn) |
| Channel spend / budget snapshot | `get_channel_budget` |
### Stage 4 — Interpret safely
1. Summarize winners / losers with evidence from tool payloads only.
2. Keep conversion metric commentary channel-scoped when using
`selected_conversion_metric_value`.
3. If the user asks what to create or launch next, hand off to
`omneky-creative` / `omneky-launch-manage` after the read-out.
### Stage 5 — Brand connectors (reads only)
HubSpot / Semrush / Ahrefs / GSC have **no** connect or disconnect tools on
this surface. Check status first. Semrush is **not** in
`list_connector_statuses` — call `get_semrush_connection_status` directly.
GSC is included in that fanout.
**HubSpot**
1. `get_hubspot_connection_status`
2. `hubspot_search_contacts` / `hubspot_search_companies` /
`hubspot_search_deals`
3. Then `hubspot_get_contact` / `hubspot_get_company` / `hubspot_get_deal`
**Semrush**
1. `get_semrush_connection_status`
2. `get_semrush_domain_overview` / `get_semrush_keyword_overview`
3. Respect Nexus unit quotas (HTTP 429 / 503 → say capped; do not hammer)
**Ahrefs**
1. `ahrefs_connection_status`
2. `ahrefs_domain_rating` / `ahrefs_organic_keywords` /
`ahrefs_backlinks_stats`
**GSC (organic — not paid media)**
1. `get_gsc_connection_status`
2. `gsc_list_sites`
3. `gsc_query_analytics` with a `site_url` from the list
### Stage 6 — Billing adjacent
Company plan / Stripe portal / credit balance live on prod
`mcp.omneky.com` when listed. See `omneky-billing` /
`omneky-credit-balance`. Out of credits for creatives → upgrade plan path
— never invent prepaid purchase tools.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Empty-looking metrics | Run `check_reporting_data_available`; explain coverage gaps. |
| Temptation to sum conversions across channels | Refuse; break out by channel. |
| `get_recommendations` timeout | Narrow dates; no identical retry this turn. |
| Missing brand / dates | One question; stop. |
| Invented `run_sql_query` | Refuse; stay on structured tools. |
| Connector disconnected | Status-first; tell user to connect in brand settings (no public connect tools for HubSpot/Semrush/Ahrefs/GSC). |
| Semrush / Ahrefs 429 | Report quota; do not tight-loop. |
| User pivots to launch / gen | Hand off to the matching skill with safety contracts. |
| Auth failure | `omneky-failure-modes` / host re-OAuth. |
## Worked intake example
User: “How did Meta and TikTok do last week for Brand X?”
1. Resolve Brand X → `brand_id` via `list_brands` (picker if ambiguous).
2. `check_reporting_data_available` for last 7 days, channels facebook + tiktok.
3. If covered: `get_daily_metrics` for trend + `get_performance_breakdown` by
creative or campaign (channel-filtered when the tool allows).
4. Optional movers: `get_performance_movers`.
5. Report channel-separated conversion commentary; never sum
`selected_conversion_metric_value` across Meta + TikTok.
6. Offer: recommendations (`get_recommendations`) or hand off to creative /
pause-budget if they ask what to do next.
## Sibling map
| Need | Skill |
| --- | --- |
| Movers-only | `omneky-performance-movers` |
| Credits / plan | `omneky-billing` / `omneky-credit-balance` |
| Launch / pause | `omneky-launch-manage` / `omneky-pause-budget` |
| Failures | `omneky-failure-modes` |
| First-run | `omneky-getting-started` |
omneky-billing6.27 KB
View saved version →
---
name: omneky-billing
description: >-
Company plan upgrade, Stripe Customer Portal, and prepaid credit balance /
history for the signed-in Omneky account. Production mcp.omneky.com exposes
these tools; still confirm they appear on tools/list before calling. Out of
credits → upgrade plan. Never collect a card PAN. Intent keywords: upgrade
plan, Stripe portal, invoices, card on file, checkout session, credit
balance, billing summary.
---
# Omneky billing
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Operational plan / portal / prepaid-credit workflows via cgp-backend-backed
MCP tools. Flow = Stripe Checkout / Customer Portal **URL redirects**. Never
complete Checkout yourself. Never collect a PAN. Never invent Nexus debit or
prepaid-credit purchase tools.
## When to use
- User asks which plan they are on, remaining credits, card on file, invoices,
or wants to upgrade
- Creative path returned `credit_insufficient`
- Tools below appear on this session’s `tools/list`
## When not to use
- Paid-media ROAS / campaign spend → `omneky-analytics`
- Bank transfers / third-party invoices / general payment rails
- Inventing auto-topup or card-PAN capture
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval turns: end the turn after Approve / Deny (host UI or plain chat); mutate only next turn after Approve.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Confirm tool names on `tools/list` before calling. Billing tools may be
**absent** on some ChatGPT sessions — follow `omneky-failure-modes`
§ Billing tools absent. If absent, tell the user to manage the plan in the
Omneky app / settings; never invent balance or billing tools.
- Out of credits → **plan upgrade** path (`list_available_plans` +
`start_plan_upgrade`, or Customer Portal). Do not invent prepaid purchase.
- `list_available_plans` returns lookup keys — Nexus has **no dollar prices**
here; do not invent a price catalog.
- Owner-only tools may refuse for non-owners — explain; do not bypass.
- After handing `checkout_url` / `portal_url`, wait for the user; poll
`get_checkout_session_status` **once** after they say they paid (plan-upgrade
Checkout only). Managed-launch payment uses
`get_managed_launch_payment_status` instead — do not mix them.
- Credits / deductions: existing MCP balance / history / upgrade tools only
(cgp-backend path). Never invent Nexus debit routes.
- No subscription promo copy in chat — operational gates only (e.g. image ~5 /
video ~30 credit callouts belong on creative skills).
## Staged workflow
### Stage 1 — Presence check
1. Confirm allowlisted names exist on `tools/list`. If **absent**, stop —
do not invent tools or a fake balance; point to Omneky app / settings
(`omneky-failure-modes` § Billing tools absent). Creative siblings may
still generate after operational-cost callout and rely on
`credit_insufficient` as the hard gate.
### Stage 2 — Snapshot
1. `get_billing_summary` — plan + credit snapshot (not a price catalog).
2. Optional: `get_company` for identity / plan fields.
3. Dedicated balance: `get_account_credit_balance` (`credit_balance`,
`usd_per_credit`).
4. Ledger: `get_credit_history` (capped JSON rows).
5. Card on file: `get_payment_method_summary` (brand / last4 / expiry only).
### Stage 3 — Upgrade / portal
1. `list_available_plans` → keys such as `cgp_standard_monthly`, …
2. Either:
- `start_plan_upgrade` with a chosen key (saved-card change or
`checkout_url`), **or**
- `create_billing_portal_session` → `portal_url` when the user should pick
a plan / see live prices / invoices.
3. Ask the user to open the URL in the browser. End turn if waiting.
### Stage 4 — After payment
1. User says they finished plan-upgrade Checkout →
`get_checkout_session_status` **once**.
2. Re-read `get_account_credit_balance` / `get_billing_summary` if useful.
3. Managed-launch `status=payment_required` Checkout →
`get_managed_launch_payment_status` (not `get_checkout_session_status`).
### Stage 5 — Hand back
Return to `omneky-creative` / `omneky-image-ads` / `omneky-product-video`
when the original intent was generation.
## Allowlisted tools (when listed)
`get_billing_summary`, `get_company`, `get_account_credit_balance`,
`get_credit_history`, `list_available_plans`, `start_plan_upgrade`,
`create_billing_portal_session`, `get_payment_method_summary`,
`get_checkout_session_status`, `get_managed_launch_payment_status`.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Tools missing from `tools/list` | Stop; Omneky app / settings; never invent tools (`omneky-failure-modes` § Billing tools absent). |
| Non-owner on upgrade / portal | Explain owner-only; do not invent bypass. |
| User pastes card PAN in chat | Refuse to process PAN; send them to Stripe portal URL only. |
| Invented prepaid top-up tool | Refuse; use plan upgrade / portal. |
| Tight-loop checkout polling | One `get_checkout_session_status` after user confirmation. |
| Confused managed-launch vs plan Checkout | Use the matching status tool only. |
| `credit_insufficient` mid-creative | If balance/upgrade tools present → upgrade path; else Omneky app; do not retry generate until funded. |
## Sibling map
| Need | Skill |
| --- | --- |
| Balance-only gate | `omneky-credit-balance` |
| Resume image/video after top-up | `omneky-creative` / `omneky-image-ads` / `omneky-product-video` |
| Auth / tool missing | `omneky-failure-modes` / `omneky-getting-started` |
## Never invent
- Prepaid-credit purchase, auto-topup, webhook, or card-PAN tools
- Nexus debit routes or non-cgp balance endpoints
- Dollar prices from `list_available_plans` (keys only)
omneky-catalogue5.25 KB
View saved version →
---
name: omneky-catalogue
description: >-
Maintain the Omneky brand product catalogue: list products, fetch details,
create or update SKUs, and import a product-page URL. Use when the user
wants to add, update, or inspect catalogue products before a paid-media
launch or creative. Intent keywords: list my products, turn this product
URL into, product catalogue, catalog, SKU, PDP, scrape product, import URL,
product images, merchandise, upsert product.
---
# Omneky product catalogue
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Read and write the brand product catalogue that grounds product-specific
creatives and launches. There is **no product-delete tool** on this public
surface.
## When to use
- List or inspect products for a brand before a launch or creative
- Add a product by hand (name, description, images, URL)
- Update an existing completed product or its PDP URL
- Import a single product page (identify → scrape → confirm → finalize)
## When not to use
- ROAS / CTR / spend → `omneky-analytics`
- Launching the product onto Meta / Google / TikTok →
`omneky-launch-manage` after `product_id` + imagery exist
- Generating image/video from the product → `omneky-creative` /
`omneky-image-ads` / `omneky-product-video`
- Listing / category URLs without classify — always
`identify_product_from_url` first (see `omneky-product-import`)
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: end the turn after Approve / Deny (or Generate / Cancel) via host UI or plain chat; mutate only after affirmative Approve / Generate. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Prefer numeric `brand_id` when thumbnails matter.
- Confirm create / update fields with the user before writes when they asked
to confirm, or when fields are ambiguous — use `request_user_decision` or
a host Approve widget; end turn after the widget.
- Scrape drafts: complete with `finalize_scraped_product`, **not**
`upsert_brand_product`.
- `scrape_product_from_url` creates a **new draft** each successful start —
do not spam scrapes.
- No public product-delete — say so if asked; do not invent one.
- Do not launch or charge creative credits from this skill.
## Staged workflow
### Stage 1 — Resolve brand
1. If `brand_id` unknown: `list_brands` → picker → `get_brand_details` when
logo / colors / `company_id` are needed.
### Stage 2 — Read
1. List: `list_brand_products` (`brand_id`).
2. One product: `get_product_details` (also accepted: `fetch_product_details`)
with `brand_id` + `product_id`.
### Stage 3 — Create or update (manual)
1. New product: `create_product` **or** `upsert_brand_product` /
`update_brand_product` without `product_id`. Confirm fields first.
2. Update completed product: `upsert_brand_product` with `product_id`. Pass
current `product_name` / `product_description` when leaving them unchanged.
3. URL only: `update_product_url`.
### Stage 4 — Import from URL (delegate detail)
Follow `omneky-product-import` stages, summarized:
1. `identify_product_from_url` — skip scrape on listing/category pages.
2. `scrape_product_from_url` — if `status=pending`, retry later same
`brand_id` + url; no tight loop this turn.
3. Confirm fields + selected images with the user (widget / one question).
4. `finalize_scraped_product`.
### Stage 5 — Hand off
- Image ads → `omneky-image-ads` / `omneky-creative`
- Product video → `omneky-product-video`
- Launch → `omneky-launch-manage` (paused by default; Approve first)
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Listing/category URL | Stop scrape; ask for a single PDP URL. |
| `status=pending` scrape | Later retry same args; no tight poll. |
| User asks to delete product | Explain no public delete tool. |
| Ambiguous update fields | `request_user_decision` / Approve; no silent overwrite. |
| Missing imagery for later gen | Tell user before creative handoff; do not pretend assets exist. |
| Auth / brand errors | `omneky-failure-modes` / `omneky-getting-started`. |
## Sibling map
| Need | Skill |
| --- | --- |
| URL import detail | `omneky-product-import` |
| Image/video from product | `omneky-creative` / `omneky-image-ads` / `omneky-product-video` |
| Launch product ads | `omneky-launch-manage` |
| Failures / pending scrape | `omneky-failure-modes` |
## Tool alias notes
Prefer canonical names when both appear on `tools/list`:
- `get_product_details` (also accepted: `fetch_product_details`)
- `upsert_brand_product` (also accepted: `update_brand_product`)
- `finalize_scraped_product` for scrape drafts (not upsert)
omneky-channel-connect3.12 KB
View saved version →
---
name: omneky-channel-connect
description: >-
Connect Meta, Google, TikTok, LinkedIn, Reddit, Pinterest, or X ad
accounts for a brand via OAuth URL and link_ad_channel_account. Keywords:
connect ads, link ad account, Facebook page, channel OAuth, Pinterest,
twitter, TikTok ads connect.
---
# Connect ad channels
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Focused paid-media channel attachment (OAuth URL → authorized accounts →
link). Prefer `omneky-self-connect` when OpenAI Ads / PostHog / Drive are
also in scope.
## When to use
- User asks to connect Meta / Google / TikTok / LinkedIn / Reddit /
Pinterest / X Ads only
- Launch blocked by disconnected channel
## When not to use
- OpenAI Ads / PostHog / Drive → `omneky-self-connect`
- HubSpot / Semrush / Ahrefs / GSC connect (not on this surface)
- Launch / pause / budget mutations → launch-manage / pause-budget skills
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: end the turn after Approve / Deny (or Generate / Cancel) via host UI or plain chat; mutate only after affirmative Approve / Generate. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed. Never ask the user to paste a JWT or API key into chat.
## Non-negotiable output / safety contract
- X Ads wire name is `twitter`, never `x`.
- Do not claim connected until status re-check succeeds.
- Never invent API keys for paid-media channels — use
`get_channel_connect_url` OAuth.
## Staged workflow
### Stage 1 — Brand + status
1. Resolve brand (`list_brands` / picker) if needed.
2. `get_channel_connection_status` (and `get_pinterest_connection_status`
when Pinterest). Optional snapshot: `list_connector_statuses`.
### Stage 2 — OAuth
1. `get_channel_connect_url` for the channel.
2. Hand URL to user; end turn while they complete browser OAuth.
### Stage 3 — Link
1. `list_authorized_ad_accounts`.
2. Meta: also `list_authorized_facebook_pages` when needed.
3. Confirm selection → `link_ad_channel_account`.
4. Re-check status.
### Stage 4 — Next
Offer launch via `omneky-launch-manage` (paused by default) or Meta path
`omneky-meta-launch`.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Still disconnected after OAuth | Re-check once; ask user to retry OAuth; do not invent tokens. |
| Wrong wire name `x` | Use `twitter`. |
| Multiple accounts | Confirm before `link_ad_channel_account`. |
| Non–paid-media connector | Hand off to `omneky-self-connect` or analytics (reads-only). |
omneky-creative11.6 KB
View saved version →
---
name: omneky-creative
description: >-
Generate, edit, or resize Omneky paid-media image and video ads, grounded
in the brand product catalogue when the brief is product-specific. Use
when the user wants a new image ad, a multi-scene product video, an edit
of an existing creative, or another aspect ratio (9:16, 4:5, Stories,
Reels). Intent keywords: turn this product URL into video ads, generate
image ads for this product, image ad, product video, creative, catalogue,
edit ad, resize ad, Meta creative, TikTok video, Reels, credits.
---
# Omneky creative
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Paid-media image and multi-scene product video generation plus sync edit /
resize on `https://mcp.omneky.com/mcp`. Ground product-specific briefs in the
catalogue. Never claim success without a completed status or sync result URL.
## When to use
- New static image ads or multi-scene product video commercials
- Edit copy, layout, or style on an existing finished ad
- Resize a paid-media creative into another placement (9:16, 4:5, 16:9)
- Product-specific briefs that need the brand catalogue first
## When not to use
- Launching the finished creative → `omneky-launch-manage` after
`register_creative_for_launch` (Approve before launch)
- ROAS / CTR → `omneky-analytics`
- Creating / updating catalogue products → `omneky-catalogue`
- Central-only names (`trigger_ac_ad_generation`,
`trigger_multi_scene_product_video`, sibling video triggers, UGC,
`edit_video`, `trigger_product_video_v2`) — clients use public aliases below
- Thin single-path asks may use `omneky-image-ads` /
`omneky-product-video` / `omneky-edit-resize` instead
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Generate / Cancel / Approve turns: end the turn after the choice UI (or plain chat); mutate only after affirmative Generate / Approve.
- Never invent tokens; OAuth is host-managed.
- Prefer runtime `tools/list` when it differs from skill hardcoding.
## Non-negotiable output / safety contract
- **Credit callout before paid generation**: image ads typically **~5**
credits; multi-scene product videos typically **~30**, charged when the job
is submitted. Show Generate / Cancel (host UI preferred; else plain chat).
Billing gating: `omneky-failure-modes` § Billing tools absent —
call balance only when listed; if absent, state operational cost, proceed
after user confirms, rely on `credit_insufficient` as the hard gate.
- `credit_insufficient` ⇒ render **did not start** — relay that; do not retry;
upgrade path via billing skill **when those tools are listed**.
- Never claim success without `get_generation_status` completion (async) or a
sync tool’s returned URL (`edit_image` / `resize_ad` / `resize_image`).
- On hosts with MCP Apps widgets (ChatGPT): the widget owns
`poll_image_generation` / `poll_video_generation` / `sync_generation_group`
— do **not** call those as the agent and do not loop
`get_generation_status` in one turn. On text-only hosts: stop after
submit; on the next user message call `get_generation_status(job_id,
kind=…)` **once**.
- Ask whether the creative is for a **specific product** or the **brand in
general**. Product-specific: catalogue grounding. Brand-general:
`get_brand_details` assets only.
- Unique `gpt_ad_gen_id` per image job (`<short-slug>-<uuid4>`), never reused.
Ambiguous submit recovery: `omneky-failure-modes` § Ambiguous paid submit
recovery (status with that key as `job_id`; on `not_found` wait/ask —
do **not** auto-mint a new key).
- **Video:** `fetch_product_video_narratives` returns **slim cards** with a
minted `narrative_id` (may also echo `id`); full narrative is persisted
server-side. On pick, prefer `generate_product_video` with
**`narrative_id`** (server hydrates segments). Full `narrative` with
`video_gen.segments` is still OK if available — prefer the id. Do not
invent partial narratives or fake ids.
- Thin/string picks without a resolvable id → `narrative_unresolved` (no
job, no credits) — re-fetch; never invent; never silent Generate Now.
- Generate Now: **omit both** `narrative_id` and `narrative`; pass
`target_duration` 10–30 (default **12**). Optional `hook` for Generate
Now only.
- Prefer runtime `tools/list` over skill hardcoding when schemas differ.
- `environment_setting` / `location_url` is optional **HTTPS image URL** only
— never scene prose; omit if no URL; never invent a URL.
- Resizes are **not charged** (adapt already-paid creative) — follow
`omneky-failure-modes` § Resize / edit charge. No “premium resize tiers”.
- Prefer pause-ready launch handoff; never auto-launch after gen.
## Staged workflow
### Stage 1 — Brand + credits + brief type
1. Resolve brand: `list_brands` / picker / `get_brand_details`.
2. `get_current_user` when `user_id` is required.
3. If `get_account_credit_balance` is on `tools/list` and balance unknown,
call it. Else follow `omneky-failure-modes` § Billing tools absent.
4. Credit callout (image ~5 / video ~30) with Generate / Cancel (host UI or
plain chat). End turn after Cancel or while waiting for Generate.
5. Ask product-specific vs brand-general if unclear.
### Stage 2 — Catalogue grounding (product-specific)
1. `list_brand_products` / `get_product_details`.
2. For image gens, pass **one** product library image URL in `user_assets`
when possible. Quality drops with more than two assets per ad — send more
only when the user explicitly asks.
3. If the product has **no library images** and the user did not supply
imagery: **do not** call `generate_image_ad` — ask for another product,
an upload, or a brand-general brief (empty-asset jobs often fail).
### Stage 3 — Image ads
1. `generate_image_ad` with `ad_concept` (full prompt — no separate `prompt`
arg), required `gpt_ad_gen_id` / `brand_id` / `brand_name` / `company_id` /
`user_id`, and unique `gpt_ad_gen_id` (`<short-slug>-<uuid4>`).
2. Remember the intended key. Tool returns `job_id` immediately — not a
finished image.
3. Widget host: let widget poll. Text host: one
`get_generation_status(job_id, kind="image")` on a later turn.
4. Ambiguous timeout after possible submit: `omneky-failure-modes`
§ Ambiguous paid submit recovery (status with `gpt_ad_gen_id` as
`job_id`; on `not_found` wait ~30–60s and/or ask user — do not auto
mint a new key).
5. Variants: `omneky-edit-resize` (`edit_image`, `resize_ad`,
`resize_image`).
### Stage 4 — Video ads (narrative select → generate)
1. `fetch_product_video_narratives` when you need narrative options.
Present **slim cards** (`narrative_id` / `id`, title, hook, duration,
description). Do **not** auto-trigger video.
2. Wait for the user to pick a card (host UI / plain chat / one question);
end turn. Keep the chosen **`narrative_id`**.
3. `generate_product_video` with that **`narrative_id`** and orientation:
`9:16` → `portrait`, `16:9` → `landscape`, `1:1` → `square`.
Server hydrates `video_gen.segments`. Prefer omitting the fat
`narrative` blob when the id is available. A full `narrative` with
non-empty `video_gen.segments` is still OK if you have it — prefer id.
Also pass required top-level: `product_image_urls`, `product_name`,
`product_description`, `orientation`, `brand_id`, `company_id`.
4. If `error=narrative_unresolved`: re-fetch and pick again. No job started,
no credits. Do not invent segments; do not silent Generate Now.
5. Generate Now (no picked story): **omit both** `narrative_id` and
`narrative`. Pass `target_duration` 10–30 (default **12**; 10–15 short
invent, 16–30 longform). Optional `hook`. Generate Now invents a
commercial; it is **not** animation.
6. Same poll rule as images with `kind="video"`.
### Stage 5 — Edit and resize (sync — no poll)
1. `edit_image` — change an existing finished ad (natural language). Returns
edited URL when done (often 30–120s). **No** `job_id` / status poll.
2. `resize_ad` — marketing aspect-ratio outpaint; returns `resized_ad_url`.
**Not charged** (adapt already-paid creative).
3. `resize_image` — explicit pixel dimensions; prefer `resize_ad` for
placements. **Not charged.**
4. Follow `omneky-failure-modes` § Resize / edit charge. Do not invent
premium resize tiers or balance-before-resize. If live `tools/list` text
changes later, follow the live tool text.
### Stage 6 — Register + launch handoff
1. Persist chat creative when launching later:
`register_creative_for_launch` (also accepted:
`register_ad_instance_item`).
2. Hand off to `omneky-launch-manage` / `omneky-meta-launch` with Approve
before any `launch_*` (`omneky-failure-modes` § Approval / plain-chat
fallback). Default paused.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| `credit_insufficient` | Did not start; billing / upgrade if tools present; else Omneky app; no retry. |
| Billing tools absent | `omneky-failure-modes` § Billing tools absent. |
| Ambiguous paid submit | `omneky-failure-modes` § Ambiguous paid submit recovery. |
| Empty product imagery | Do not generate; ask for assets / other product / brand-general. |
| Agent called widget poll tools | Stop; leave polling to widget / one status peek next turn. |
| Looping `get_generation_status` in one turn | Forbidden; one peek per follow-up. |
| Thin / invented narrative without resolvable id | Forbidden — prefer `narrative_id` from fetch (or full object with segments). |
| `narrative_unresolved` | Re-fetch narratives; no credit charge. Never invent; never silent Generate Now. |
| Live `tools/list` schema differs | Prefer live schema over skill hardcoding. |
| Prose in `environment_setting` | Omit or pass HTTPS URL only. |
| Invented Central trigger names | Refuse; use public `generate_*` / `fetch_product_video_narratives`. |
| Premium resize / balance-before-resize | Forbidden — § Resize / edit charge. |
| Auto-launch after gen | Forbidden; Approve + paused default via launch-manage. |
| Claim success without URL / completed status | Forbidden. |
## Batching and media limits
- Prefer **one** strong product image in `user_assets` per image ad. More than
two assets per ad usually hurts quality unless the user explicitly wants a
multi-image collage.
- For multiple image concepts, submit separate `generate_image_ad` jobs with
**distinct** `gpt_ad_gen_id` values. Do not reuse ids.
- Do not start a large unpaid speculative batch — credit callout must reflect
the count (≈5 × image jobs, ≈30 × multi-scene video jobs).
- On widget hosts, `sync_generation_group` is widget-owned so one iframe can
track siblings — the agent must not call it.
- Never mix sync edit/resize polling with async gen polling rules.
## Sibling map
| Need | Skill |
| --- | --- |
| Image-only | `omneky-image-ads` |
| Video-only | `omneky-product-video` |
| Edit / resize only | `omneky-edit-resize` |
| Credits | `omneky-credit-balance` / `omneky-billing` |
| Launch after gen | `omneky-launch-manage` / `omneky-meta-launch` |
| Catalogue grounding | `omneky-catalogue` / `omneky-product-import` |
| Shared recoveries | `omneky-failure-modes` |
omneky-credit-balance4.07 KB
View saved version →
---
name: omneky-credit-balance
description: >-
Check prepaid creative credit balance and history before paid generation.
Keywords: credits, credit balance, out of credits, credit history,
usd_per_credit, credit_insufficient.
---
# Credit balance
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Lightweight prepaid-credit gate before image / video generation. Balance and
history only; upgrades live in `omneky-billing`.
## When to use
- Before `generate_image_ad` / `generate_product_video` / paid `edit_image`
(not for uncharged `resize_ad` / `resize_image`)
- After `credit_insufficient`
- User asks “how many credits do I have?”
## When not to use
- Full plan / portal / checkout flows as the primary task → `omneky-billing`
- Campaign budgets / media spend → `get_channel_budget` via analytics /
launch-manage (different concept)
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Generate / Cancel turns: end the turn after the choice UI (or plain chat); mutate only after affirmative Generate.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Confirm `get_account_credit_balance` (and related) appear on `tools/list`
first (`omneky-failure-modes` § Billing tools absent).
- **If present**: call balance before paid creative jobs when unknown.
- **If absent**: skip the balance call; state operational cost (image ~5 /
video ~30); proceed after user confirms intent; rely on
`credit_insufficient` as the hard gate. Never invent a balance number.
- Operational credit callouts are OK — not subscription promo copy.
- On `credit_insufficient`, the job **did not start** — do not retry generate;
hand off to `omneky-billing` only when upgrade/portal tools are listed;
else point to Omneky app / settings.
- Never invent Nexus debit / auto-topup tools. Never collect a PAN.
- Resize is not charged — do not gate `resize_ad` / `resize_image` on
balance (`omneky-failure-modes` § Resize / edit charge).
## Staged workflow
### Stage 1 — Presence + balance
1. If `get_account_credit_balance` is **absent** from `tools/list`: state
operational cost (~5 image / ~30 video), return to creative skill after
user confirms intent; skip Stages 2–3 balance reads.
2. If present: call it → report `credit_balance` and `usd_per_credit` when
present.
### Stage 2 — Optional history
1. Only if `get_credit_history` is listed: recent grants / usage (capped
rows).
### Stage 3 — Gate or upgrade
1. If balance tools were absent: creative path uses operational callout +
`credit_insufficient` hard gate.
2. If balance is sufficient for the intended job, return to
`omneky-creative` / `omneky-image-ads` / `omneky-product-video` /
`omneky-edit-resize` with a credit callout (Generate / Cancel; host UI
or plain chat) before submit. Do not gate uncharged resizes.
3. If insufficient and upgrade tools are listed: `omneky-billing`
(`list_available_plans` + `start_plan_upgrade` or
`create_billing_portal_session`). If upgrade tools absent: Omneky app /
settings.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Tool missing | Say unavailable; Omneky app / settings; never invent balance (`omneky-failure-modes` § Billing tools absent). |
| `credit_insufficient` | No retry; billing upgrade path if tools present; else Omneky app. |
| User confuses credits with ad budget | Clarify prepaid creative credits ≠ channel budget. |
| Balance gate on resize | Forbidden — resizes not charged. |
omneky-edit-resize3.79 KB
View saved version →
---
name: omneky-edit-resize
description: >-
Edit an existing Omneky creative or resize it for Stories, Reels, 9:16,
4:5, or 16:9. Resizes are not charged (adapt an already-paid creative).
Keywords: edit ad, resize ad, Stories, Reels, aspect ratio, outpaint,
edit_image, resize_ad, uncharged resize.
---
# Edit and resize
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Synchronous edit / resize of **existing** finished creatives. No async
`job_id` polling for these tools.
## When to use
- Change copy / layout / style on a finished image ad
- New placement aspect ratio for an already-paid creative
## When not to use
- Net-new concepts → `omneky-image-ads` / `omneky-creative`
- Product video generation → `omneky-product-video`
- Calling `get_generation_status` for these sync tools
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- `edit_image`, `resize_ad`, and `resize_image` are **synchronous** — they
return URLs when done. Do **not** call `get_generation_status` for them.
- **Resizes are not charged** (live tool text): `resize_ad` / `resize_image`
adapt an already-paid creative. Do **not** invent “premium resize tiers”
or require balance-before-resize. Follow
`omneky-failure-modes` § Resize / edit charge. If a future `tools/list`
description changes, follow the live tool text over this skill.
- `edit_image` charge: follow live tool text for that tool only; gate with
balance tools only when listed and the live text indicates a charge
(`omneky-failure-modes` § Billing tools absent).
- Confirm the source asset id / URL with the user when ambiguous.
- Never invent Central-only enhance / variation / upscale tool names if they
are not on `tools/list`.
## Staged workflow
### Stage 1 — Resolve asset + brand
1. Confirm brand if needed.
2. Confirm which finished creative to edit/resize.
### Stage 2 — Charge check (edit only when applicable)
1. Resize path: no credit gate — uncharged per live tool text.
2. Edit path: if live tool text indicates a charge and
`get_account_credit_balance` is on `tools/list`, check balance; else skip
inventing a balance. Optional Apply vs Cancel for paid edit.
### Stage 3 — Mutate (sync)
1. Edit: `edit_image` with natural-language instruction → edited image URL
(often 30–120s).
2. Placement resize: `resize_ad` → `resized_ad_url` (often 30–180s).
3. Pixel resize: `resize_image` → `presigned_url` / `resized_image_url`.
Prefer `resize_ad` for marketing placements.
### Stage 4 — Next
1. More variants, or `register_creative_for_launch` + launch-manage handoff
(Approve, paused default — `omneky-failure-modes` § Approval / plain-chat
fallback).
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Agent starts status poll loop | Stop — sync tools do not use job polling. |
| “Premium resize” / balance-before-resize | Forbidden — resizes not charged; § Resize / edit charge. |
| `credit_insufficient` on edit | Billing path if tools present; no retry. |
| Missing source asset | Ask once; do not invent URLs. |
| Invented upscale / UGC tool | Refuse unless on `tools/list`. |
omneky-failure-modes12.7 KB
View saved version →
---
name: omneky-failure-modes
description: >-
Recover from Omneky MCP failures: JWT re-OAuth, missing brand_id, empty
reporting, timeouts, launch 400s, needs_user_decision, credit_insufficient,
billing tools absent from tools/list, approval plain-chat fallback,
ambiguous paid-submit recovery, disconnected connectors, and pending
scrapes. Intent keywords: unauthorized, reconnect, empty metrics, timeout,
400, credits, billing absent, needs_user_decision, pending scrape, failure
playbook.
---
# Omneky — failure modes (shared playbook)
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Cross-cutting recovery rules other skills point to by section (§). Encode
recoveries with **exact** public tools. Do not invent SQL, auto-topup,
card-PAN, Nexus debit, Central-only tools, fake widgets, or shared files
outside skill folders.
## When to use
- A tool returned 401 / unauthorized / invalid token
- `brand_id` missing or unresolvable from user language
- Metrics look empty or “zero”
- `status=timeout` / `status=pending` / `status=needs_user_decision`
- Launch 400s (locations, LinkedIn start_date, Reddit microcurrency)
- `credit_insufficient` on creative submit
- Billing / balance tools missing from this session’s `tools/list`
- Approval UI needed and no host widget / `request_user_decision` is available
- Ambiguous paid submit (timeout / transport error after a possible charge)
- Connector disconnected mid-workflow
- User asks “what went wrong?” after an Omneky tool error
## When not to use
- Not a substitute for happy-path skills (`omneky-getting-started`,
`omneky-analytics`, `omneky-creative`, `omneky-launch-manage`, …)
- Not a license to invent tools absent from `tools/list`
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) **when that tool is on tools/list**.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: follow **§ Approval / plain-chat fallback** below — never invent a fake “summary widget” tool; never stall waiting for a widget that did not appear.
- Never invent tokens; OAuth is host-managed. Never ask the user to paste a JWT or API key into chat.
## Non-negotiable output / safety contract
- Credits / deductions / balance: **cgp-backend path only** via existing MCP
tools when present on `tools/list`. Never invent Nexus debit routes or
prepaid-purchase tools. When billing tools are absent, follow **§ Billing
tools absent**.
- Never dump raw `clarification_needed` JSON into chat — present plain
questions / host UI.
- Never identical tight-loop retries in one turn for timeout / pending.
- Prefer pause over delete when a mutate failed mid-flight and the user
only wanted to stop spend.
- Point siblings back here by name + section from other skills’ failure tables.
---
## § Billing tools absent / tools/list gating
Billing tools (`get_account_credit_balance`, `get_billing_summary`,
`list_available_plans`, `start_plan_upgrade`, `create_billing_portal_session`,
`get_credit_history`, …) may be present on some connectors and **absent** on
some ChatGPT / host sessions (smaller tool snapshots).
1. **Before calling**: check whether the tool appears on the host’s
`tools/list` / available tools.
2. **If present**: call balance before paid gen when unknown; on low balance
offer upgrade / portal tools **only if those are also present**.
3. **If absent**:
- Do **not** call balance / billing tools.
- Do **not** invent a balance number or a billing tool name.
- State operational cost (~**5** credits per image job / ~**30** credits
per multi-scene video job when submitted).
- Proceed to generate after the user confirms intent (Generate / Cancel
via host UI or plain chat).
- Rely on the generate tool’s `credit_insufficient` (or equivalent) as
the hard gate.
4. Same gating for plan / portal tools: if absent, tell the user to manage
plan / credits in the Omneky app / settings — never invent Checkout tools.
Creative skills should say: “follow `omneky-failure-modes` § Billing tools
absent” rather than duplicating divergent copy.
## § Approval / plain-chat fallback
Do **not** require an unimplemented custom “summary widget” binary. Contract:
1. Prefer host-native decision UI when available: OpenAI/ChatGPT confirmation
cards, MCP Apps UI, or MCP `request_user_decision` when that tool is on
`tools/list`.
2. If **none** of those exist: **plain-chat fallback** — send a one-card
summary in chat (`Brand · Channel · Objective · Budget · Paused|Live ·
Creative`) with explicit options **Approve / Deny / Edit**, then **end
the turn** and wait for the user’s reply text; mutate only after an
affirmative Approve (or clear yes).
3. Never invent a fake widget tool. Never stall waiting for a widget that
did not appear.
4. Same pattern for Generate / Cancel credit callouts when no host widget
is available: plain-chat Generate / Cancel, end turn, wait.
Launch / pause / budget skills should say: “follow `omneky-failure-modes`
§ Approval / plain-chat fallback”.
## § Ambiguous paid submit recovery
Paid submits (`generate_image_ad` with `gpt_ad_gen_id`, optional video
`job_id` you supplied) can fail clearly **or** leave the outcome unknown.
**Clear failure** before accept (`credit_insufficient`, validation error,
explicit reject): a **new** key / new attempt is OK.
**Ambiguous** (timeout / transport error / unknown **after** you may have
already submitted):
1. Do **not** immediately resubmit with a new `gpt_ad_gen_id` (duplicate
spend risk — commit lag can still mean charged). Remember the intended
key.
2. On the next turn call `get_generation_status(job_id=<that gpt_ad_gen_id>,
kind="image")` **once**. For images, the status `job_id` arg accepts the
same `gpt_ad_gen_id` used at submit.
3. If status shows running / complete → continue that job (do not re-mint).
4. If `not_found` **or** `queued` with `source=not_found`: **WAIT ~30–60s
and/or ask the user** before any new paid submit. Do **not** auto-mint a
new key and resubmit — a missing status row often means commit lag, not
a safe never-started.
5. New key / resubmit only after:
- a **clear pre-accept failure**, or
- **explicit user OK** after the wait still shows never-started /
`not_found`.
6. If still ambiguous after wait → ask the user before a second paid submit.
Same spirit for video when you supplied a client `job_id`: one status peek
with `kind="video"`; on `not_found` / queued+source not_found wait/ask —
do not auto-resubmit. Widget hosts: leave in-flight polling to the MCP Apps
widget; do not loop status in one turn.
Creative / image / video skills should say: “follow `omneky-failure-modes`
§ Ambiguous paid submit recovery”.
## § Resize / edit charge (follow live tool text)
Public tool text for `resize_ad` / `resize_image`: **resizes are not
charged** — they adapt an already-paid creative. Synchronous; no status
poll. Do **not** invent “premium resize tiers” or require balance-before-
resize.
- `edit_image` may still be a separate paid path — check live tool text on
`tools/list` for that tool only.
- If a future `tools/list` description changes charge language, **follow the
live tool text** over any skill copy.
Edit-resize / creative skills should say: “follow `omneky-failure-modes`
§ Resize / edit charge”.
---
## Staged workflow (other recoveries)
### Stage A — Auth / JWT
1. Send the user through **host OAuth** for Omneky again.
2. Optionally `health_check` after reconnect.
3. Re-run `get_current_user` before brand-scoped calls.
4. Never ask them to paste a Nexus JWT or API key into chat.
### Stage B — brand_id
1. `list_brands` + confirm (host UI / plain chat / one question).
2. Prefer numeric `brand_id` when thumbnails matter.
3. Do not guess.
### Stage C — Empty reporting
1. Call `check_reporting_data_available` (not deprecated `data_available`)
for brand + date range + channels **before** treating empty as zero.
2. If coverage is missing, say so; do not invent metrics.
3. Never sum `selected_conversion_metric_value` across channels.
### Stage D — Timeouts / pending
| Signal | Response |
| --- | --- |
| `get_recommendations` → `status=timeout` | Narrow date window; do not identical retry this turn. |
| Unscoped `get_ad_groups` → timeout | Pass `campaign_id` (and ids when known); retry once narrowed. |
| `scrape_product_from_url` → `status=pending` | Retry later same `brand_id` + url; no tight poll this turn. |
| Async gen still running | On widget hosts, let the widget poll; on text hosts call `get_generation_status` **once** next turn — never loop in one turn. |
### Stage E — Launch / targeting 400s
- LinkedIn: `search_ad_targeting` with `types=["locations"]` and a
`urn:li:adTargetingFacet:locations` entry; `start_date` required when
creating a new campaign group.
- TikTok: `get_tiktok_location_ids` then pass `location_ids` on the ad group.
- Google Demand Gen: `search_google_countries` → `targeting_fragments`.
- X Ads: wire name `twitter`, never `x`.
- Reddit: `bid_value` is microcurrency (dollars × 1,000,000).
- Meta leads: `lead_gen_form_id` on ad specs for native forms.
- Disconnected channel: `omneky-self-connect` /
`get_channel_connect_url` → link → re-check.
### Stage F — needs_user_decision
1. If `request_user_decision` is on `tools/list`, call it (not deprecated
`ask_user`).
2. Else use plain-chat questions (§ Approval / plain-chat fallback).
3. Never dump `clarification_needed` JSON.
4. Never auto-retry the failed write in the same turn.
### Stage G — Credits / plan
1. `credit_insufficient` means the render **did not start**.
2. If balance tools are on `tools/list`: `get_account_credit_balance` (and
optional `get_credit_history`).
3. If upgrade / portal tools are present: `list_available_plans` +
`start_plan_upgrade`, or `create_billing_portal_session`. Hand Stripe URL;
never collect a PAN.
4. If billing tools are **absent**: follow **§ Billing tools absent**; do not
invent balance; point to Omneky app / settings for plan management.
5. After user finishes Checkout (when those tools exist):
`get_checkout_session_status` **once**. Details: `omneky-billing` /
`omneky-credit-balance`.
### Stage H — Connector disconnected mid-flow
1. `get_channel_connection_status` / `list_connector_statuses`.
2. Hand off to `omneky-self-connect` / `omneky-channel-connect`.
3. Do not invent alternate launch endpoints.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| 401 / unauthorized | Host re-OAuth; never pasted JWT. |
| Unknown brand | `list_brands` + confirm. |
| Empty metrics | `check_reporting_data_available` first; never invent. |
| Cross-channel conversion sum temptation | Group by channel or named metric only. |
| `status=timeout` | Narrow scope; no identical retry this turn. |
| `status=pending` scrape | Later retry same args; no tight loop. |
| `needs_user_decision` | `request_user_decision` if listed; else plain chat; no auto-retry. |
| Launch location 400 | Channel pre-call (LinkedIn / TikTok / Google DG). |
| `credit_insufficient` | Did not start; upgrade path if tools present; else Omneky app; no retry. |
| Billing tools missing | § Billing tools absent — operational cost + `credit_insufficient` gate. |
| No approval widget | § Approval / plain-chat fallback — never invent widget tools. |
| Ambiguous paid submit | § Ambiguous paid submit recovery — status once; on not_found wait/ask — never auto new key. |
| Resize charge guess | § Resize / edit charge — follow live tool text (uncharged today). |
| Missing tool on `tools/list` | Say unavailable; do not invent. |
| Delete urge after error | Prefer `set_ad_entity_status` pause; deletes need dual confirm. |
| Widget poll tools called by model | Do not call `poll_image_generation` / `poll_video_generation` / `sync_generation_group` as the agent on widget hosts. |
## Sibling map
Other skills should point here for recovery, then return to:
| Domain | Skill |
| --- | --- |
| Session / brand | `omneky-getting-started` |
| Connectors | `omneky-self-connect` / `omneky-channel-connect` |
| Analytics empty | `omneky-analytics` |
| Credits | `omneky-credit-balance` / `omneky-billing` |
| Creative async | `omneky-creative` |
| Launch 400s | `omneky-launch-manage` / `omneky-meta-launch` |
omneky-getting-started6.92 KB
View saved version →
---
name: omneky-getting-started
description: >-
Start any Omneky ChatGPT plugin session: host OAuth, health_check,
get_current_user, list_brands / brand picker, get_brand_details, and
list_connector_statuses. Use when the user is new, auth failed, brand_id
is unknown, or they ask what Omneky can do. Intent keywords: sign in,
OAuth, who am I, list brands, brand picker, connector status, getting
started, first run, reconnect, capability summary.
---
# Omneky — getting started
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Bootstrap a signed-in Omneky session before brand-scoped analytics, catalogue,
creative, or launch work. Prove the connector is up, resolve identity and
`brand_id`, summarize connected channels, and route to the right sibling
skill — without inventing keys, charging credits, or launching spend.
Omneky helps with paid-media on Meta/Facebook, Google (Performance Max and
Demand Gen), TikTok, LinkedIn, Reddit, Pinterest, and X Ads (`twitter`):
catalogue, image/video creatives, paused-by-default launches, and ROAS/CTR
reporting.
## When to use
- First turn on a new host / plugin session
- Auth / JWT / 401 errors (re-run host OAuth)
- Need `user_id`, `brand_id`, company context, or a capability snapshot
- User asks “what can Omneky do?” or “which brands do I have?”
## When not to use
- ROAS / CTR reporting → `omneky-analytics` / `omneky-performance-movers`
- Launches, pause, budget, delete → `omneky-launch-manage` /
`omneky-meta-launch` / `omneky-pause-budget`
- Image/video generation → `omneky-creative` / `omneky-image-ads` /
`omneky-product-video`
- Catalogue writes → `omneky-catalogue` / `omneky-product-import`
- Plan upgrade / Stripe portal as the primary goal → `omneky-billing`
- Do not treat `health_check` as a data source — reachability only
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: end the turn after Approve / Deny (or Generate / Cancel) via host UI or plain chat; mutate only after affirmative Approve / Generate. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Never ask the user to paste a JWT, Nexus token, or API key into chat.
- Prefer a **brand-picker** host widget when multiple brands exist (≤3 options
+ custom when the host allows). Confirm before guessing `brand_id`.
- Prefer a **numeric** `brand_id` when thumbnails / catalogue imagery matter.
- Do not launch, delete, pause, enable, change budget, or submit paid
generation from this skill — hand off with a clear next skill name.
- Safety defaults to mention when orienting: launches paused by default;
pause > delete; credit callout before paid gen (image ~5 / video ~30);
never invent metrics; `check_reporting_data_available` before empty=zero.
- ChatGPT-safe: omit Cursor-only / Grok-Bot-only avatar / profile-picture
steps unless the host explicitly supports avatar update; if unsupported,
skip silently.
- Cross-link siblings by name. Recovery detail → `omneky-failure-modes`.
## Staged workflow
### Stage 1 — Session / auth
1. If the host has no Omneky login, tell the user to complete the plugin
connector OAuth for Omneky. On JWT / 401 / unauthorized, ask them to
re-OAuth in the host. Never paste a token.
2. Optionally call `health_check` when diagnosing connect failures. Skip on
every happy-path turn.
### Stage 2 — Identity
1. Call `get_current_user`. Capture `user_id` (needed later for movers / some
creative args). Do not ask the user for a numeric user id.
2. If company context is needed: `get_company` (identity / plan fields only —
not prepaid credit snapshot).
### Stage 3 — Brand resolution
1. Call `list_brands`.
2. If more than one brand: present a brand-picker widget or one concise chat
question. Wait for the choice. End the turn after the widget when the host
requires exclusive-tool turns.
3. Call `get_brand` and/or `get_brand_details` for the chosen id (logo,
colors, copy, `company_id`, creative assets).
### Stage 4 — Connector snapshot
1. Call `list_connector_statuses` for paid-media channels (including
`pinterest` / `twitter`) plus HubSpot, Ahrefs, GSC, OpenAI Ads, PostHog,
Drive.
2. Semrush is **not** in that fanout — if the user cares about Semrush, call
`get_semrush_connection_status` directly (see `omneky-analytics`).
3. Disconnected ad channel the user wants to use → `omneky-self-connect` /
`omneky-channel-connect` (`get_channel_connect_url` /
`link_ad_channel_account`).
### Stage 5 — Orient and hand off
Summarize in one short beat what is ready (brand, connected channels) and
offer next asks:
| User intent | Skill |
| --- | --- |
| Performance / ROAS | `omneky-analytics` / `omneky-performance-movers` |
| Catalogue / import URL | `omneky-catalogue` / `omneky-product-import` |
| Image / video creatives | `omneky-creative` (+ `omneky-credit-balance`) |
| Launch / pause | `omneky-launch-manage` (paused by default) |
| Meta-only launch | `omneky-meta-launch` |
| Plan / credits | `omneky-billing` / `omneky-credit-balance` |
| Something failed | `omneky-failure-modes` |
Example next asks to offer:
- “Show ROAS by creative last 7 days”
- “Import this product URL into the catalogue”
- “Generate a 1:1 Meta image ad for [product]”
- “Prepare a paused Meta sales launch for [brand]”
Support: support@omneky.com · Privacy: https://www.omneky.com/privacy-policy
## Failure boundaries
| Failure | Required response |
| --- | --- |
| 401 / unauthorized / invalid token | Re-run **host** Omneky OAuth. Never ask for a pasted JWT. |
| `health_check` fails / unreachable | Tell user the connector is down; retry later; do not invent alternate endpoints. |
| `list_brands` empty | Explain no brands on this account; do not invent a `brand_id`. |
| Multiple brands, no selection | Brand-picker or one question; stop — do not guess. |
| User asks to launch / spend immediately | Confirm brand first, then hand off to `omneky-launch-manage` with Approve-before-mutate rules. |
| Billing / credits question | Hand off to `omneky-billing` / `omneky-credit-balance` after tools appear on `tools/list`. |
| Tool name missing from `tools/list` | Do not invent it; say unavailable on this surface; Omneky app / settings when appropriate. |
| Avatar / mark setup on unsupported host | Skip silently; continue onboarding. |
omneky-image-ads5.18 KB
View saved version →
---
name: omneky-image-ads
description: >-
Generate branded still image ads for a product or brand brief. Use when
the user wants image ads, static creatives, or Meta/feed stills.
Keywords: image ad, branded ad, still creative, feed ad, generate image,
gpt_ad_gen_id, 5 credits, ambiguous submit recovery.
---
# Image ads
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Focused still-image generation path (subset of `omneky-creative`). Submit
async `generate_image_ad`, wait correctly for completion, then offer edit /
resize / launch handoff.
## When to use
- User wants static / feed / still image ads
- Product or brand-general image concepts
## When not to use
- Multi-scene product video → `omneky-product-video`
- Launch without confirmation → `omneky-launch-manage`
- Catalogue import → `omneky-product-import`
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Generate / Cancel turns: end the turn after the choice UI (or plain chat); mutate only after affirmative Generate.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Credit callout before generate (~**5** credits per image job when submitted).
Generate / Cancel via host UI or plain chat.
- Credits / balance: follow `omneky-failure-modes` § Billing tools absent —
call `get_account_credit_balance` only when listed; if absent, state ~5
operational cost, proceed after user confirms intent, rely on
`credit_insufficient` as the hard gate. Never invent balance.
- Unique `gpt_ad_gen_id` (`<short-slug>-<uuid4>`), never reused across
variants. Required with `brand_id`, `brand_name`, `company_id`, `user_id`;
prompt field is `ad_concept`.
- Ambiguous submission (timeout / transport / unknown after possible
submit): follow `omneky-failure-modes` § Ambiguous paid submit recovery —
status-check with `gpt_ad_gen_id` as `job_id` (kind=image). If
`not_found` / queued+source not_found: **WAIT ~30–60s and/or ask user** —
do **not** auto-mint a new key (commit lag can still mean charged). New
key only after clear pre-accept failure, or explicit user OK after wait
still shows never-started.
- Prefer one product library image in `user_assets`; do not generate with
empty assets when product-specific and no imagery exists.
- Widget hosts own `poll_image_generation` / `sync_generation_group` — agent
must not call them. Text hosts: one `get_generation_status(..., kind="image")`
on a later turn.
- Never claim success without completed status / asset URL.
- Hand off launch only after user confirms (paused default).
## Staged workflow
### Stage 1 — Brand + brief
1. `list_brands` / picker / `get_brand_details`.
2. Product-specific: `list_brand_products` / `get_product_details` (or
`identify_product_from_url` → import via `omneky-product-import` first).
3. Brand-general: brand assets only.
4. `get_current_user` when `user_id` is required.
### Stage 2 — Credits
1. If `get_account_credit_balance` is on `tools/list`, call when balance
unknown.
2. Else: state ~5 credits operational cost (`omneky-failure-modes`
§ Billing tools absent).
3. Credit callout Generate / Cancel (host UI or plain chat); end turn if
waiting.
### Stage 3 — Generate
1. Mint unique `gpt_ad_gen_id` (`<short-slug>-<uuid4>`).
2. `generate_image_ad` with `ad_concept` + that key + required brand /
company / user fields + assets.
3. Remember the intended key for recovery.
4. Capture returned `job_id` when present.
### Stage 4 — Completion
1. Widget path: wait for widget / user follow-up.
2. Text path: `get_generation_status(job_id, kind="image")` once next turn.
3. Offer `edit_image` / `resize_ad` via `omneky-edit-resize` (resizes
uncharged per live tool text — `omneky-failure-modes` § Resize / edit charge).
### Stage 5 — Launch handoff
1. `register_creative_for_launch` when attaching to a campaign later.
2. `omneky-launch-manage` / `omneky-meta-launch` with Approve + paused default.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| `credit_insufficient` | No retry; billing path if tools present; else Omneky app. |
| Billing tools absent | `omneky-failure-modes` § Billing tools absent. |
| Clear failure before accept | New `gpt_ad_gen_id` OK for a new attempt. |
| Timeout / transport / unknown after possible submit | Status with `gpt_ad_gen_id` as `job_id`; on `not_found` wait/ask — never auto new key (`omneky-failure-modes` § Ambiguous paid submit recovery). |
| No product imagery | Stop; ask upload / other product / brand-general. |
| Poll loop in one turn | Forbidden. |
| Success claimed early | Forbidden until status/URL. |
omneky-launch-manage9.81 KB
View saved version →
---
name: omneky-launch-manage
description: >-
Launch and manage Omneky paid-media ads on Meta/Facebook, Google Ads,
TikTok, LinkedIn, Reddit, Pinterest, and X Ads (Twitter). Use when the
user wants to create, pause, budget, retarget, or delete campaigns, or
attach a catalogue/creative to a live ad account. Intent keywords: paid
media, Meta ads, Facebook ads, Instagram, Google PMax, Demand Gen,
TikTok ads, LinkedIn ads, Reddit ads, Pinterest ads, X Ads, Twitter ads,
launch Meta sales ads, ROAS, launch campaign, pause ad, budget,
targeting, product catalogue, Approve launch.
---
# Omneky launch and manage
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Create and operate paid-media campaigns across connected channels with
**Approve-before-mutate** discipline. Default new launches to **PAUSED**.
Prefer pause over delete. X Ads wire name is **`twitter`**, never `x`.
## When to use
- Launch, pause, resume, budget, or retarget paid-media campaigns
- Meta / Facebook / Instagram, Google Ads, TikTok, LinkedIn, Reddit,
Pinterest, or X Ads
- Attach a catalogue product or chat-generated creative to an existing
campaign or ad set
- Connect a missing ad account (delegate detail to `omneky-self-connect`)
## When not to use
- ROAS / CTR / spend reporting → `omneky-analytics`
- Generating or editing creatives → `omneky-creative` (then return here)
- Catalogue SKU writes → `omneky-catalogue`
- Inventing Central-only or OpenAI Ads **launch** names (`launch_openai_*`,
managed-Meta launch tools)
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval turns: end the turn after Approve / Deny / Edit (host UI or plain chat); mutate only next turn after Approve. Never invent a fake summary-widget tool; never stall for a widget that did not appear.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Before any `launch_*`, `set_ad_entity_status` / `set_ad_budget` /
`update_ad_targeting` / `delete_*`: show a one-card summary
(`Brand · Channel · Objective · Budget · Paused|Live · Creative`) with
**Approve / Deny / Edit** via host-native confirmation / MCP Apps /
`request_user_decision` when available; otherwise **plain-chat fallback**
(`omneky-failure-modes` § Approval / plain-chat fallback). End the turn.
Mutate only next turn after affirmative Approve (or clear yes).
- Default `status_on_launch` / `configured_status` to **`PAUSED`** unless the
user explicitly asked to go live.
- Prefer **pause** over **delete**. Deletes: first offer Pause instead /
Delete permanently / Cancel; then a **second** Approve confirm.
- Prefer `set_ad_entity_status` over deprecated `set_ad_status`.
- Prefer `request_user_decision` over deprecated `ask_user` when that tool
is on `tools/list` and fields are missing / `needs_user_decision`. Else
plain-chat questions. Never dump `clarification_needed` JSON; never
auto-retry failed writes same turn.
- Hierarchy: Campaign → Ad Set (`ad_group`) → Ad. Creative is an asset on
the Ad (`ad_specs`), never on the campaign. Status/budget tools do not
add ads.
- Confirm channel connected before launch; else `omneky-self-connect`.
- After success: post-launch next steps (host UI or plain chat) — Check
status / Pull 7d metrics / Done (metrics via `omneky-analytics`).
- Keep decision options to ≤3 when possible.
## Staged workflow
### Stage 1 — Brand + intent
1. Resolve brand (`list_brands` / picker) → `get_brand_details`.
2. Confirm live launch vs creative-only. Creative-only → `omneky-creative`
first (credit callouts image ~5 / video ~30).
3. Catalogue product when relevant: `list_brand_products` /
`get_product_details`.
### Stage 2 — Channel readiness
1. `get_channel_connection_status` (X: `channel="twitter"`; Pinterest also
`get_pinterest_connection_status`).
2. `get_channel_budget` / `minimum_budget_for_objective`.
3. Optional: `reach_estimate` for targeting size questions.
4. Optional: `get_ad_custom_properties` for custom conversion definitions.
5. Disconnected → `get_channel_connect_url` path via `omneky-self-connect` /
`omneky-channel-connect`.
### Stage 3 — Targeting pre-calls
| Channel | Required pre-call | Notes |
| --- | --- | --- |
| Meta / Facebook | none | Inline `targeting`: countries / age_min / age_max |
| Google PMax | none | Set `link_url`; Google places automatically |
| Google Demand Gen | `search_google_countries` | Pass values as `targeting_fragments` |
| LinkedIn | `search_ad_targeting` `types=["locations"]` | Must include `urn:li:adTargetingFacet:locations`; `start_date` on new group |
| TikTok | `get_tiktok_location_ids` | `location_ids` required on ad group |
| Reddit | none | Inline `targeting`; `bid_value` microcurrency (dollars × 1e6) |
| X Ads | none | Wire name `twitter` |
| Pinterest | none | `get_pinterest_*` list helpers |
### Stage 4 — Creative attach
1. Chat creative → `register_creative_for_launch` (alias
`register_ad_instance_item`) before launch when required.
2. Confirm copy, CTA, landing URL.
### Stage 5 — Approve (exclusive-tool turn)
1. Show summary Approve / Deny / Edit (host UI when available; else
plain-chat card — `omneky-failure-modes` § Approval / plain-chat
fallback).
2. **End the turn.** Do not call `launch_*` yet.
### Stage 6 — Launch (next turn after Approve)
Call the matching tool with paused default. Existing campaign:
`campaign_spec={"id": …}`. Existing ad set: `ad_group_spec={"id": …}`.
**Meta / Facebook:** `launch_facebook_sales_ad`,
`launch_facebook_leads_ad`, `launch_facebook_awareness_ad`,
`launch_facebook_traffic_ad`, `launch_facebook_video_views_ad`
(Meta-focused detail also in `omneky-meta-launch`).
**Google:** `launch_google_performance_max_ad`,
`launch_google_demand_gen_ad`.
**LinkedIn:** `launch_linkedin_brand_awareness_ad`,
`launch_linkedin_website_visits_ad`, `launch_linkedin_conversions_ad`,
`launch_linkedin_engagement_ad`.
**Reddit:** `launch_reddit_awareness_ad`, `launch_reddit_traffic_ad`,
`launch_reddit_conversions_ad`, `launch_reddit_leads_ad`,
`launch_reddit_video_views_ad`.
**TikTok:** `launch_tiktok_traffic_ad`, `launch_tiktok_video_views_ad`,
`launch_tiktok_conversions_ad`, `launch_tiktok_leads_ad`.
**X Ads (`twitter`):** `launch_twitter_awareness_ad`,
`launch_twitter_traffic_ad`, `launch_twitter_engagements_ad`,
`launch_twitter_followers_ad`, `launch_twitter_video_views_ad`.
**Pinterest:** `launch_pinterest_awareness_ad`,
`launch_pinterest_traffic_ad`, `launch_pinterest_sales_ad`,
`launch_pinterest_leads_ad`, `launch_pinterest_video_views_ad`.
No Omneky-managed Meta / OpenAI **launch** tools. OpenAI Ads can be
*connected* (`connect_openai_ads`); do not invent `launch_openai_*`.
### Stage 7 — Manage existing
**Inspect:** `get_campaigns`, `get_ad_groups` (pass `campaign_id` — unscoped
brand-wide lists can time out), `get_ads`, `get_channel_budget`,
`minimum_budget_for_objective`, `get_campaign_ad_group_names`.
Pinterest: `get_pinterest_campaigns` / `get_pinterest_ad_groups` /
`get_pinterest_ads`.
**Mutate (after Approve):** `set_ad_entity_status`, `set_ad_budget`,
`update_ad_targeting` (Facebook-only retarget),
`set_pinterest_entity_status`.
**Delete (dual confirm):** `delete_campaign`, `delete_ad_group`,
`delete_ads`.
Specialized pause/budget path: `omneky-pause-budget`.
### Stage 8 — Post-launch
Next-steps (host UI or plain chat): Check status / Pull 7d metrics
(`omneky-analytics`) / Done.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Mutate without Approve | Forbidden — show summary (host UI or plain chat) and end turn. |
| Invented summary-widget tool | Forbidden — `omneky-failure-modes` § Approval / plain-chat fallback. |
| Disconnected channel | Self-connect / channel-connect; do not invent launch. |
| LinkedIn / TikTok / Google DG 400 | Run required targeting pre-call; see `omneky-failure-modes`. |
| `needs_user_decision` | `request_user_decision` if listed; else plain chat; no auto-retry. |
| Unscoped `get_ad_groups` timeout | Pass `campaign_id`; narrow. |
| User said go live but widget still paused | Confirm explicitly before ACTIVE. |
| Delete request | Pause-first offer; dual Approve for delete. |
| `channel=x` | Correct to `twitter`. |
| Reddit $ budgets entered as dollars in `bid_value` | Convert to microcurrency. |
| OpenAI Ads launch request | Connect only; no public launch tool. |
## Channel gotchas
- Reddit `bid_value` is microcurrency (dollars × 1,000,000). $5/day = `5000000`.
- LinkedIn `start_date` is required when creating a new campaign group.
- Facebook lead ads: set `lead_gen_form_id` on ad specs for native forms.
- Google Demand Gen needs `search_google_countries` → `targeting_fragments`.
- TikTok needs `get_tiktok_location_ids` → `location_ids`.
- Pinterest list/status helpers exist alongside generic getters.
- OpenAI Ads: `connect_openai_ads` / `get_openai_ads_connection_status` only —
connect ≠ launch.
- Drive assets: `get_google_drive_connect_url` via `omneky-self-connect`.
## Sibling map
| Need | Skill |
| --- | --- |
| Meta-only | `omneky-meta-launch` |
| Pause / budget only | `omneky-pause-budget` |
| Connect channel | `omneky-self-connect` / `omneky-channel-connect` |
| Creatives | `omneky-creative` |
| Metrics after launch | `omneky-analytics` |
| Failures | `omneky-failure-modes` |
omneky-meta-launch4.91 KB
View saved version →
---
name: omneky-meta-launch
description: >-
Prepare and launch Meta/Facebook/Instagram ads (sales, traffic, leads,
awareness, video views) after user confirmation. Keywords: Meta launch,
Facebook ads, Instagram ads, launch campaign, PAUSED, sales, leads,
ThruPlay, lead_gen_form_id.
---
# Meta launch
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Meta-first launch path using `launch_facebook_*` tools. Same Approve-before-
mutate and paused-default rules as `omneky-launch-manage`, narrowed to
Facebook / Instagram.
## When to use
- User wants Meta / Facebook / Instagram paid launch
- Sales / conversions, traffic, leads, awareness, or video views objectives
## When not to use
- Google / TikTok / LinkedIn / Reddit / Pinterest / X → `omneky-launch-manage`
- Creative generation → `omneky-creative` first
- Analytics-only → `omneky-analytics`
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval turns: end the turn after Approve / Deny / Edit (host UI or plain chat); mutate only next turn after Approve. Never invent a fake summary-widget tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Confirm brand, creative, objective, budget, targeting, CTA, landing URL.
- Approve / Deny / Edit one-card summary **before** any `launch_facebook_*`
(host-native confirmation / MCP Apps / `request_user_decision` when
available; else plain-chat fallback — `omneky-failure-modes` § Approval /
plain-chat fallback). End turn; launch only next turn after affirmative
Approve.
- Default paused / disabled unless user clearly asks to go live.
- Prefer pause over delete (`omneky-pause-budget` /
`set_ad_entity_status`).
- If a preflight / validate tool appears on this session’s `tools/list`, use
it before create — never invent a preflight tool name that is absent.
- Facebook lead ads: set `lead_gen_form_id` on ad specs for native forms.
- Inline targeting example shape: countries + age_min / age_max — do not
invent unsupported facets.
- No `launch_openai_*` / managed-Meta launch names on public `/mcp`.
## Staged workflow
### Stage 1 — Brand + connection
1. `list_brands` / picker / `get_brand_details`.
2. `get_channel_connection_status` for Facebook. If disconnected →
`omneky-self-connect` (`get_channel_connect_url` →
`list_authorized_ad_accounts` / `list_authorized_facebook_pages` →
`link_ad_channel_account`).
3. `get_channel_budget` / `minimum_budget_for_objective`.
### Stage 2 — Creative + catalogue
1. Product: `list_brand_products` / `get_product_details` when relevant.
2. Generate if needed via `omneky-creative` (credits first).
3. `register_creative_for_launch` when attaching a chat creative.
### Stage 3 — Objective + specs
1. Map user intent → tool:
- Sales / purchases / ROAS → `launch_facebook_sales_ad`
- Leads → `launch_facebook_leads_ad` (+ `lead_gen_form_id` when native form)
- Traffic → `launch_facebook_traffic_ad`
- Awareness / reach → `launch_facebook_awareness_ad`
- Video views / ThruPlay → `launch_facebook_video_views_ad`
2. New vs existing: `campaign_spec={"id": …}` / `ad_group_spec={"id": …}`
when extending.
3. Optional `get_ad_custom_properties` / `reach_estimate`.
### Stage 4 — Approve then launch
1. Summary Approve / Deny / Edit (host UI or plain chat); end turn.
2. After Approve: call the chosen `launch_facebook_*` with paused default.
3. Post-launch next steps → status / 7d metrics (`omneky-analytics`) / Done.
### Stage 5 — Manage after
Pause / budget / retarget via `omneky-pause-budget` or
`set_ad_entity_status` / `set_ad_budget` / `update_ad_targeting`
(Facebook-only targeting updates) after Approve.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Launch without Approve | Forbidden. |
| Invented summary-widget tool | Forbidden — plain-chat fallback OK. |
| Disconnected Meta | Self-connect; re-check status. |
| Missing countries / targeting | Ask once / `request_user_decision`; do not guess. |
| Lead form missing when required | Ask for `lead_gen_form_id` or switch objective. |
| Invented preflight tool | Skip if not on `tools/list`. |
| User wants ACTIVE casually | Confirm explicitly; still prefer stating spend risk. |
| `needs_user_decision` | `request_user_decision` if listed; else plain chat; no JSON dump; no auto-retry. |
omneky-pause-budget4.23 KB
View saved version →
---
name: omneky-pause-budget
description: >-
Pause or enable ads and change budgets on connected channels after user
confirmation. Keywords: pause ad, enable ad, resume ad, change budget,
set budget, set_ad_entity_status, set_ad_budget, prefer pause over delete.
---
# Pause and budget
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Safe mutations for status and budget on live entities. Pause-first culture;
never delete from this skill unless the user explicitly insisted and completed
dual confirm (prefer redirecting deletes through `omneky-launch-manage`).
## When to use
- Pause / enable / resume campaign, ad set, or ad
- Change daily or lifetime budget on Meta / Google (and channel-supported sets)
- Pinterest status via `set_pinterest_entity_status`
## When not to use
- Creating new campaigns → `omneky-launch-manage` / `omneky-meta-launch`
- Reporting-only → `omneky-analytics`
- Creative generation → `omneky-creative`
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval turns: end the turn after Approve / Deny (host UI or plain chat); mutate only next turn after Approve. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Confirm brand, entity (campaign / ad set / ad ids), channel, and action
with Approve / Deny before writes (host UI or plain-chat summary —
`omneky-failure-modes` § Approval / plain-chat fallback). End turn after
showing the choice.
- Prefer `set_ad_entity_status` (not deprecated `set_ad_status`).
- Prefer **pause** over **delete**. If user asks to delete, offer pause
first; dual confirm before `delete_*` (or hand off to launch-manage).
- Facebook CBO vs ABO: accepted budget level depends on campaign
configuration — do not invent hierarchy overrides.
- X Ads: `channel="twitter"`.
- Unscoped entity lists can time out — pass `campaign_id` into
`get_ad_groups` when inspecting.
## Staged workflow
### Stage 1 — Resolve entities
1. Brand: `list_brands` / picker if needed.
2. `get_channel_connection_status`.
3. Inspect: `get_campaigns` → `get_ad_groups(campaign_id=…)` → `get_ads`.
Pinterest helpers: `get_pinterest_campaigns` /
`get_pinterest_ad_groups` / `get_pinterest_ads`.
4. Optional name resolve: `get_campaign_ad_group_names` /
`search_reporting_values`.
### Stage 2 — Budget context
1. `get_channel_budget` / `minimum_budget_for_objective` before raising spend.
2. Confirm currency / daily vs lifetime with the user when ambiguous.
### Stage 3 — Approve
1. One-card summary: Brand · Channel · Entity · Action (Pause|Enable|Budget) ·
Amount — host UI when available; else plain chat with Approve / Deny /
Edit.
2. End turn.
### Stage 4 — Mutate (next turn)
1. Status: `set_ad_entity_status` (Pinterest: `set_pinterest_entity_status`).
2. Budget: `set_ad_budget`.
3. Meta retarget only when asked: `update_ad_targeting` (Facebook-only).
### Stage 5 — Verify
1. Re-read entity via `get_ads` / `get_ad_groups` / `get_campaigns` as needed.
2. Offer metrics via `omneky-analytics` / `omneky-performance-movers`.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Write without Approve | Forbidden — host UI or plain-chat summary first. |
| Invented approval widget tool | Forbidden — `omneky-failure-modes` § Approval / plain-chat fallback. |
| Delete-first request | Offer pause; dual confirm or hand off. |
| Timeout listing ad groups | Scope with `campaign_id`. |
| Budget below minimum | Show `minimum_budget_for_objective`; do not submit invalid. |
| Wrong channel wire `x` | Use `twitter`. |
| Disconnected channel | Self-connect before mutate. |
omneky-performance-movers3.55 KB
View saved version →
---
name: omneky-performance-movers
description: >-
Find which ads to make more of: performance movers, ROAS/CTR leaders, and
creative recommendations. Keywords: which ads, ROAS, CTR, movers,
recommendations, leaderboard, what rose, what fell, make more of.
---
# Performance movers
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Fast read-only path for “what rose / fell?” and “which creatives should I
make more of?” grounded in movers + recommendations + optional drill-downs.
## When to use
- Which ads / campaigns / creatives improved or declined vs the prior period
- Leaderboard / “what should I scale?” questions
- Follow-on from a thin analytics ask that is clearly mover-centric
## When not to use
- Full multi-connector / GSC / HubSpot deep dives → `omneky-analytics`
- Mutations (pause / budget / launch) → launch-manage / pause-budget
- Inventing causal “lift” scores without tool support
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: end the turn after Approve / Deny (or Generate / Cancel) via host UI or plain chat; mutate only after affirmative Approve / Generate. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Brand-scoped and read-only.
- Coverage first: `check_reporting_data_available` before treating empty as zero.
- Prefer `get_performance_movers` (not deprecated `get_trending`).
- Prefer `get_performance_breakdown` for ranked drill-down (not deprecated
`get_dimension_summary`).
- Never invent metrics; never sum `selected_conversion_metric_value` across channels.
- Summarize winners and losers with evidence.
## Staged workflow
### Stage 1 — Brand + coverage
1. Resolve brand (`list_brands` / picker) if needed; `get_current_user` when required.
2. Confirm date window.
3. `check_reporting_data_available`.
### Stage 2 — Movers
1. `get_performance_movers` for up / down vs prior period.
2. Present a short leaderboard (top gains / top drops) with channel labels.
### Stage 3 — Drill / recommend
1. Optional: `get_daily_metrics` for a nominated entity’s trend.
2. Optional: `get_performance_breakdown` for creative / campaign ranks.
3. Optional: `search_reporting_values` to resolve names → ids.
4. When they ask what to change or test next: `get_recommendations`
(tight window; timeout → narrow, no identical retry).
### Stage 4 — Hand off
- “Make more like winner X” → `omneky-creative` / `omneky-image-ads` /
`omneky-product-video`
- “Pause the losers” → `omneky-pause-budget` (Approve before mutate)
- Broader reporting → `omneky-analytics`
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Empty movers | Coverage check; explain gap; do not invent ranks. |
| Recommendations timeout | Narrow window; stop identical retry. |
| Cross-channel conversion sum | Refuse; channel-group. |
| User requests pause mid-read | Hand off; Approve widget required. |
omneky-product-import3.46 KB
View saved version →
---
name: omneky-product-import
description: >-
Import a product page URL into the Omneky brand catalogue or update a SKU
after scrape confirmation. Keywords: import product, product URL, scrape
product, catalogue, SKU, identify product, finalize scraped product, PDP.
---
# Product import
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
URL → catalogue draft → user confirm → finalize. Specialized path of
`omneky-catalogue` for PDP imports.
## When to use
- User pastes a product URL to import
- Re-scrape / refresh an existing PDP into a new draft then finalize
## When not to use
- Manual field entry without URL → `omneky-catalogue` (`create_product` /
`upsert_brand_product`)
- Generating creatives from the product before finalize completes
- Category / collection listing URLs (classify first; usually skip scrape)
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: end the turn after Approve / Deny (or Generate / Cancel) via host UI or plain chat; mutate only after affirmative Approve / Generate. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed.
## Non-negotiable output / safety contract
- Always `identify_product_from_url` before scrape.
- Finalize with `finalize_scraped_product` — never treat scrape draft as
completed via `upsert_brand_product`.
- Confirm selected images + fields before finalize (Approve widget preferred).
- No public product-delete tool.
- Pending scrapes: no tight-loop polling in one turn.
## Staged workflow
### Stage 1 — Brand
1. Resolve `brand_id` (`list_brands` / picker). Prefer numeric id.
### Stage 2 — Identify
1. `identify_product_from_url`.
2. If listing/category: tell the user; ask for a single product PDP. Stop.
### Stage 3 — Scrape
1. `scrape_product_from_url`.
2. If `status=pending`: explain; retry later with the same `brand_id` + url.
3. Do not start multiple parallel scrapes for the same URL in one turn.
### Stage 4 — Confirm
1. Present name, description, images, URL.
2. Host Approve / Deny / Edit (or plain-chat fallback / `request_user_decision` when listed) — `omneky-failure-modes` § Approval / plain-chat fallback.
3. End turn after the widget.
### Stage 5 — Finalize
1. On Approve: `finalize_scraped_product` with chosen fields / images.
2. Optionally `update_product_url` if only the URL should change later.
3. Hand off to creative or launch skills with the new `product_id`.
### Stage 6 — Re-import
1. Optional `update_product_url` first.
2. Scrape again → confirm → finalize.
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Listing URL | No scrape; request PDP. |
| Pending | Later retry; no tight loop. |
| User denies finalize | Leave draft; do not upsert as completed. |
| Wrong brand | Re-resolve brand; do not finalize onto guessed id. |
| Delete request | No public delete; explain. |
omneky-product-video5.9 KB
View saved version →
---
name: omneky-product-video
description: >-
Generate multi-scene product video ads from catalogue or a product URL.
Use for product video, narrative picks, or Generate Now commercials.
Keywords: product video, video ad, narrative, narrative_id, multi-scene,
slim cards, target_duration, 30 credits, portrait, landscape, square.
---
# Product video ads
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Multi-scene product video commercials via
`fetch_product_video_narratives` → user pick → `generate_product_video`.
Fetch returns **slim cards** with a minted `narrative_id` (may also echo
`id`); the full narrative is persisted server-side. Prefer passing
**`narrative_id`** on generate so the server hydrates segments. Not a
substitute for launch.
## When to use
- Product video / multi-scene commercial requests
- Narrative card selection flows
- Generate Now (omit both `narrative_id` and `narrative`; pass `target_duration`)
## When not to use
- Still image ads → `omneky-image-ads`
- Treating Generate Now as “animation only” or as an auto-launch
- Central-only video triggers / UGC / `edit_video` (not public)
- Inventing segments, title-only `narrative` blobs, or fake `narrative_id`s
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Generate / Cancel turns: end the turn after showing the choice UI (or plain-chat Generate / Cancel); mutate only after affirmative Generate.
- Never invent tokens; OAuth is host-managed.
- **Prefer runtime `tools/list`:** if the live tool schema differs from this skill (e.g. `narrative_id` present/absent, `narrative` shape), follow the live schema over hardcoded skill copy.
## Non-negotiable output / safety contract
- Credit callout before generate (~**30** credits for multi-scene video when
submitted). Generate / Cancel via host UI or plain chat. Billing tools
gating: `omneky-failure-modes` § Billing tools absent.
- After narrative fetch, present **slim cards** for UI (`narrative_id` / `id`,
title, hook, duration, description). On pick, prefer
`generate_product_video` with **`narrative_id`** from the card (server
hydrates `video_gen.segments`). Do **not** invent a partial narrative;
do **not** invent an id.
- Full `narrative` object with non-empty `video_gen.segments` is still OK
when available, but **prefer `narrative_id`**.
- Thin/string picks without a resolvable minted id → `narrative_unresolved`
(no job, no credits) — re-fetch and re-pick; never invent segments or
silently switch to Generate Now.
- Generate Now: **omit both** `narrative_id` and `narrative`; pass
`target_duration` 10–30 (default **12** when omitted by server). 10–15
short invent; 16–30 longform. Optional `hook` for Generate Now only.
- `environment_setting` / `location_url` = optional HTTPS image URL only.
- Widget owns `poll_video_generation`; agent uses one
`get_generation_status(..., kind="video")` on text hosts next turn.
- Ambiguous submit after optional client `job_id`: follow
`omneky-failure-modes` § Ambiguous paid submit recovery.
- Never claim success without completion.
## Staged workflow
### Stage 1 — Brand + product
1. Brand pick (`list_brands` / `get_brand_details`).
2. Product: `list_brand_products` / `get_product_details`, or import URL via
`omneky-product-import` first.
3. Required generate args later: `product_image_urls`, `product_name`,
`product_description`, `orientation` (`landscape`|`portrait`|`square`),
`brand_id`, `company_id`.
### Stage 2 — Narratives (selected-story flow)
1. `fetch_product_video_narratives`.
2. Present slim cards from the fetch result (`narrative_id` / `id`, title,
hook, duration, description).
3. Wait for pick; end turn after UI / plain-chat options.
4. Keep the chosen **`narrative_id`** (and card metadata) for Stage 3.
### Stage 3 — Credits + generate
1. Balance check if `get_account_credit_balance` is on `tools/list`; else
operational ~30 callout (`omneky-failure-modes` § Billing tools absent).
2. Selected story: `generate_product_video` with **`narrative_id`** from the
card + orientation mapping (`9:16` → `portrait`, `16:9` → `landscape`,
`1:1` → `square`). Prefer omitting the fat `narrative` blob when the id
is available. Still pass required product fields.
3. Generate Now (user skipped pick): omit both `narrative_id` and
`narrative`; pass `target_duration` 10–30 (default 12); optional `hook`.
### Stage 4 — Completion + handoff
1. Poll rules as in `omneky-creative` / failure-modes Stage D.
2. Register + `omneky-launch-manage` only after Approve (paused default).
## Failure boundaries
| Failure | Required response |
| --- | --- |
| Thin / invented / title-only narrative without resolvable id | Forbidden — use `narrative_id` from fetch (or full object with segments); never invent. |
| `narrative_unresolved` | Re-fetch + re-pick; no credit charge. Do not invent; do not silent Generate Now. |
| `credit_insufficient` | Did not start; billing path if tools present; else Omneky app; no retry. |
| Billing tools absent | `omneky-failure-modes` § Billing tools absent. |
| Ambiguous paid submit | `omneky-failure-modes` § Ambiguous paid submit recovery. |
| Auto-picked narrative | Forbidden. |
| Prose in `environment_setting` | Omit / URL only. |
| Early success claim | Forbidden. |
| Live `tools/list` conflicts with skill copy | Prefer live schema. |
omneky-self-connect5.95 KB
View saved version →
---
name: omneky-self-connect
description: >-
Connect a missing Omneky ad channel or OpenAI Ads / PostHog / Google Drive
for the signed-in brand. Use when get_channel_connection_status is
disconnected or the user asks to link an ad account, Facebook Page,
Pinterest, X Ads (twitter), PostHog, or Drive. Intent keywords: connect
ads, OAuth URL, link ad account, Facebook page, Pinterest, Twitter, X Ads,
OpenAI Ads, PostHog, Google Drive, disconnect Drive.
---
# Omneky self-connect
## Activation analytics
If the host exposes a skill-activation / analytics hook, call it once per new user request with this skill name; otherwise skip silently. Never invent a tracking tool. Omneky MCP does **not** expose `track_skill_activation`.
## Purpose
Attach authorized ad accounts and optional brand connectors so later
`launch_*` / asset flows can succeed. Browser OAuth (or one-shot API key
forward for OpenAI Ads / PostHog) is user-completed; this skill never
collects secrets into free chat beyond what the tool schema requires, and
never invents disconnect tools that are not on `tools/list`.
## When to use
- Channel is disconnected and the user wants to launch or manage ads
- User asks to connect Meta / Google / TikTok / LinkedIn / Reddit /
Pinterest / X Ads (`twitter`), OpenAI Ads, PostHog, or Google Drive
- After `get_channel_connection_status` or `list_connector_statuses` shows
a gap blocking a requested workflow
## When not to use
- Not HubSpot / Semrush / Ahrefs / GSC **connect** — those are status +
reads only on this surface (see `omneky-analytics`). Users connect them
in brand settings.
- Not OpenAI Ads / managed-Meta **launches** — connect ≠ launch. There is
no `launch_openai_*` / `launch_omneky_managed_*` on public `/mcp`.
- Not Datadog / Shopify / GTM / invented connectors
- Not for pausing / budgeting (→ `omneky-pause-budget`) or launching
(→ `omneky-launch-manage`)
## OpenAI runtime contract
- Use only tools from the current OpenAI host + Omneky MCP (`https://mcp.omneky.com/mcp`). Never invent tools.
- Prefer native ChatGPT / host widgets and question UI for decisions. Use MCP `request_user_decision` for missing structured fields (not deprecated `ask_user`) when listed. Else follow `omneky-failure-modes` § Approval / plain-chat fallback.
- When intake is incomplete, ask **one** concise chat question. Never invent a question tool.
- Approval / Generate turns: end the turn after Approve / Deny (or Generate / Cancel) via host UI or plain chat; mutate only after affirmative Approve / Generate. Never invent a fake widget tool.
- Never invent tokens; OAuth is host-managed. Never ask the user to paste a JWT or API key into chat.
## Non-negotiable output / safety contract
- Wire name for X Ads is **`twitter`**, never `x`.
- Hand the user the OAuth / connect URL; they finish in the browser. Do not
claim the channel is connected until a status re-check says so.
- OpenAI Ads / PostHog keys are forwarded **once** by the tool and never
logged back — do not echo keys into chat.
- Destructive disconnects (`disconnect_posthog`, `disconnect_google_drive`)
need an Approve widget / explicit confirm; prefer leave-connected unless
the user asked to disconnect.
- Never invent Pinterest / Twitter disconnect tools if absent from
`tools/list`.
- After connect, offer next step: launch (`omneky-launch-manage`) or
verify with a read-only list (`get_campaigns`).
## Staged workflow
### Stage 1 — Resolve brand
1. If `brand_id` unknown: `list_brands` → brand picker → `get_brand_details`.
2. Snapshot: `list_connector_statuses`.
### Stage 2 — Paid-media channel connect (Meta / Google / TikTok / LinkedIn / Reddit / Pinterest / X)
1. `get_channel_connection_status` with the correct `channel`
(`facebook` / `google` / `tiktok` / `linkedin` / `reddit` /
`pinterest` / `twitter`). Pinterest also has
`get_pinterest_connection_status`.
2. If disconnected: `get_channel_connect_url` — show the URL; end turn if
waiting on the user.
3. After the user says they finished OAuth: `list_authorized_ad_accounts`.
For Meta also `list_authorized_facebook_pages` when a Page is required.
4. Confirm which account (and Page) to attach via widget / one question.
5. `link_ad_channel_account` with the chosen ids.
6. Re-check `get_channel_connection_status` / `list_connector_statuses`.
### Stage 3 — OpenAI Ads
1. `get_openai_ads_connection_status`.
2. If connecting: `connect_openai_ads` with the user-provided API key
(schema-required; do not store or reprint).
3. Re-check status. Remind: connect ≠ launch.
### Stage 4 — PostHog
1. `get_posthog_connection_status`.
2. Connect: `connect_posthog` with personal `phx_…` key (not `phc_…`) and
host `us.posthog.com` or `eu.posthog.com`.
3. Disconnect only on explicit Approve: `disconnect_posthog`.
### Stage 5 — Google Drive
1. `get_google_drive_connection_status`.
2. Connect: `get_google_drive_connect_url` → user OAuth → re-check.
3. Disconnect only on explicit Approve: `disconnect_google_drive`.
### Stage 6 — Hand off
- Ready to launch → `omneky-launch-manage` / `omneky-meta-launch`
- Channel-only questions → `omneky-channel-connect` (thin channel path)
- Failures → `omneky-failure-modes`
## Failure boundaries
| Failure | Required response |
| --- | --- |
| 401 / unauthorized | Host re-OAuth; never paste JWT. |
| OAuth URL opened but status still disconnected | Wait; re-check status once; do not re-link blindly with stale ids. |
| User has multiple authorized accounts | Picker / one question; do not pick silently. |
| Meta missing Page | `list_authorized_facebook_pages` then include page on `link_ad_channel_account`. |
| User said `channel=x` | Correct to `twitter` and proceed. |
| HubSpot/Semrush/Ahrefs/GSC “connect” request | Explain status+read only; point to brand settings; use analytics skill for queries. |
| Disconnect without confirm | Show Approve / Deny; do not call disconnect yet. |
| Invented disconnect / launch tool missing | Refuse; stay on `tools/list` names. |