MCP App Store
by KeenEthics

Overview

Ninjo turns Instagram and WhatsApp inboxes into a 24/7 sales channel: AI agents that answer DMs, qualify leads, follow up, and book calls or sales for creators and businesses. This connector lets Claude operate your Ninjo workspace end to end. With it, Claude can: - Create and iterate agents: system prompts, SDK configuration, triggers (keywords, comments, ads, story replies), voice replies, and context documents - Wire the automation around each agent: custom properties, contact limits, follow-up workflows, and operator notifications - Analyze performance: real conversations, funnel metrics, agent insights, and diagnostics that return ranked defects with the exact fix - Test safely: generate synthetic conversations against an agent before going live - Manage content: knowledge documents, agent-sendable audio/image resources, WhatsApp templates, and Instagram profile/post data Requires a Ninjo account. Sign in with your Ninjo credentials via OAuth when connecting.

Tools

add_crm_contact_to_pipeline

ChatGPT
Pipelines: add a contact to a native pipeline at a stage (ids from get_crm_pipelines), creating a pipeline record. Call it again after the contact's previous record in that pipeline closed to start a new cycle. Team-scoped operators must pass assignmentTeamId. Configured pipeline automations may run.

add_crm_product_price

ChatGPT
Products: add a new immutable price to a product. amount is a decimal string in major units ("19.95") in the given ISO currency.

add_crm_team_member

ChatGPT
Teams: add an admitted workspace member (userId from get_crm_teams) to a team, using the team's current revision.

archive_crm_pipeline_automation

ChatGPT
Pipeline automations: archive an automation rule so it stops acting on records, using its current revision from get_crm_pipeline_automations.

archive_crm_product

ChatGPT
Products: archive a product (productId from get_crm_commerce). Quotes and sales keep their immutable price snapshots.

archive_crm_tag

ChatGPT
Tags: archive a contact tag so it can no longer be assigned. Existing assignments are kept, and restore_crm_tag restores it. expectedRevision is the tag's timestamp revision from list_crm_tags.

archive_crm_team

ChatGPT
Teams: archive a team, using its current revision from get_crm_teams. Records the team owns may block archiving; restore_crm_team restores it.

assign_crm_owner

ChatGPT
Ownership: assign a conversation or pipeline record (subject) to a team, a person or both. ONLY_IF_UNASSIGNED keeps existing ownership; FORCE replaces it and, like outsideTeamOverride, needs extra permission and an assignmentReason. expectedRevision comes from get_crm_assignment (0 when nothing is assigned yet).

associate_whatsapp_direct_numbers

ChatGPT
Queue one or more allowed customer phone numbers for Cortex WhatsApp direct routing. The gateway forwards the request to mk1-tasks, which normalizes the numbers, checks whether any number already belongs to another influencer, and enqueues the association task when there are no conflicts. Returns { status: "queued", taskId } on success or { error: "phone_number_conflict", requested_influencer_id, conflicts: [...] } when a number is already mapped elsewhere.

bootstrap_discord_channel

ChatGPT
Queue mk1-tasks bootstrap for the influencer's Discord operator channel. This creates or repairs the stored Discord mapping asynchronously through mk1-tasks. The downstream bootstrap creates the role, private channel, and permanent invite when needed. Returns { status: "queued", taskId } on success.

claim_crm_ownership

ChatGPT
Ownership: claim a conversation or pipeline record (subject) for the signed-in user. expectedRevision comes from get_crm_assignment (0 when nothing is assigned yet). Human claims are protected from ordinary automation.

close_crm_pipeline_record

ChatGPT
Pipelines: close a pipeline record, with an optional outcome (SUCCESS or FAILURE) and closeReason, using the record's current revision. The closed record stays in history; add_crm_contact_to_pipeline starts a new cycle.

configure_crm_airtable_sync

ChatGPT
External CRM sync: map a connected Airtable account to a base and contacts table so Ninjo contacts sync there. Run refresh_crm_sync with airtableBaseId first to get table and field ids. fieldMappings needs the Ninjo contact id and first-name columns; stageFieldId must be a single-select field and monetaryValueFieldId a numeric one. Replaces any existing mapping and re-registers the Airtable webhook.

create_agent

ChatGPT
Create a new Ninjo agent with its initial system prompt. Creates the Agent, AgentConfig, and first AgentPromptVersion atomically, with safe humanization defaults (message chunking on, MEDIUM delay split, 2–6s response delay — all overridable). Returns { agent_id, agent_config_id, prompt_version_id, completeness }. completeness is the deterministic build/wiring audit of the new agent: a fresh agent reports critical gaps by design (no terminal stop, not linked to a connected account) — wire them with scaffold_agent_activation before treating it as done.

create_crm_contact

ChatGPT
Create contact: add one native contact with Studio's validation and duplicate detection; returns contactId. Fill the identity fields you know, then set properties with set_crm_contact_property and tags with replace_crm_contact_tags. After a timeout, look the contact up before retrying.

create_crm_pipeline_automation

ChatGPT
Pipeline automations: create a rule that moves, adds or transfers pipeline records when a record enters a stage or a contact property changes. Read get_crm_pipeline_automations for stages, property definitions and operators first. actionReason is recorded on the records it acts on. Enable only the configuration you intend.

create_crm_product

ChatGPT
Products: create a product with its first price. amount is a decimal string in major units ("19.95") in the given ISO currency.

create_crm_property

ChatGPT
Create property: add a typed property (string, integer, boolean, datetime or option) in a fact scope (contact, conversation or pipeline record). Scoped facts need the workspace rollout. Options are comma-separated labels; defaults and evaluation settings are validated. The codename is generated.

create_crm_quote

ChatGPT
Quotes: create a quote for a contact. Lines use either immutable productPriceId versions or productId with a custom unitAmount in minor units, all lines the same way. It does not message the contact.

create_crm_routing_rule

ChatGPT
Routing: create an assignment routing rule that assigns matching conversations or pipeline records to a team or person. Read get_crm_routing for criteria, targets and options first. Pass a fresh createRuleId and reuse it with the same payload when retrying. FORCE needs forceReason and permission.

create_crm_sync_trigger

ChatGPT
External CRM sync: create a stage trigger that sets a contact property when the contact reaches a stage in the external CRM. syncConnectionId and stageId come from get_crm_sync; customPropertyId must be a GENERIC property (list_crm_properties); value is the text to set, after delayMinutes (0 to 525600). It keeps acting on live contacts until deleted with delete_crm_sync_trigger.

create_crm_tag

ChatGPT
Tags: create a reusable contact tag with a name and an optional six-digit hex color (for example #336699). Assign it to contacts with replace_crm_contact_tags.

create_crm_team

ChatGPT
Teams: create a team with a name and an optional description. Repeating the same create is deduplicated; reload get_crm_teams for its id and revision.

create_document

ChatGPT
Upload a context document for a Ninjo agent. If file_base64 is provided, uploads to S3 at agents/{influencer_id}/context/{uuid}/{file_name}. Returns the created document row.

create_feedback_upload_url

ChatGPT
Step 1 of reporting feedback (optional, only when you want to attach the agent session). Returns a short-lived presigned S3 PUT URL + s3_key. Write the full agent session to a file and PUT it to upload_url (no special headers needed) — the bytes never pass through the tool-call payload or model context. Then call report_feedback with the returned s3_key as session_s3_key. Returns { upload_url, s3_key }.

create_messaging_channel

ChatGPT
Create a messaging channel on a connected GoHighLevel or Kommo account, so a Ninjo agent can answer conversations that live inside the CRM. WHEN THIS IS THE RIGHT ANSWER: a WhatsApp number can only be connected in ONE place at a time. If the number already lives in GoHighLevel/Kommo, it CANNOT also be connected directly to Ninjo — this channel is how you get around that: the number stays in the CRM and Ninjo replies THROUGH the CRM. For Instagram and Facebook you usually do NOT need this: they can be in the CRM and in Ninjo simultaneously, so create_connect_link with 'instagram'/'facebook' is the better path. PREREQUISITES, in order: 1. The CRM account is connected — create_connect_link with 'gohighlevel_crm' or 'kommo_crm'. 'gohighlevel_booking' does NOT work for this; it is a different integration on a different table. 2. The channel ALREADY EXISTS inside the CRM. Ninjo attaches to a channel that is set up in GoHighLevel/Kommo; it does not create one there. If it doesn't exist yet, the user must add it in the CRM first. There is NO manual webhook step in either CRM — do not ask the user to paste a webhook URL anywhere, and never ask for an API key or private-integration token. third_party_whatsapp (GoHighLevel + WHATSAPP only): set true when the number reaches GHL through an EXTERNAL provider (a WhatsApp QR/app integration) rather than GoHighLevel's own official WhatsApp. GHL rejects official-WhatsApp sends for those numbers, so a wrong value silently breaks outbound. ASK the user which of the two they have; do not guess. If it turns out wrong afterwards, fix it with set_messaging_channel_whatsapp_provider — the channel cannot simply be recreated. The channel is created ENABLED. Pass agent_id here to route it in one step; assigning later via set_agent_crm_channel needs a user JWT and fails for API-key callers. Common failures: 409 "already exists" (one channel per type per account), 409 asking for connected_account_id (more than one account of that CRM — take it from a list_crm_connections row for that provider, NOT from list_connected_accounts, which lists Meta sub-accounts from another table), 409 telling you to reconnect (the CRM account predates OAuth). A connected_account_id from the wrong table comes back as "No GoHighLevel account connected" — that error means the id did not match, not that the CRM is unconnected, so re-read it before telling the user to reconnect anything. Returns { channel, webhook_registered? }. On Kommo, webhook_registered: false means the channel exists but receives nothing — retry with register_messaging_channel_webhook before telling the user it is live.

create_resource_upload_url

ChatGPT
Step 1 of uploading an agent-sendable audio/image clip. Returns a presigned S3 PUT URL + s3_key — the file bytes are NOT sent through this tool. AUDIO must be M4A/AAC (MP3 rejected); IMAGE must be JPG/PNG/GIF. Next: PUT the file to upload_url with the same Content-Type header (e.g. curl -T file.m4a -H 'Content-Type: audio/mp4' '<upload_url>'), then call register_creator_resource with the s3_key. Returns { upload_url, s3_key }.

create_thread

ChatGPT
Create a new Cortex thread (conversation between the influencer and their AI agent). Returns the new conversation object with id, title, status, created_at. Uses JWT for RLS when available; with API key/admin, pass influencer_id.

create_trigger

ChatGPT
Create a trigger for a Ninjo agent. type selects the variant and which fields apply: • keywords — DM keyword trigger: keyword (required), match_mode (KEYWORD_ONLY|ANYWHERE), allow_typo. • all-messages — fires on every DM or comment: keyword must be ALL_DM or ALL_COMMENTS; prompt_evaluator optional. • comments — comment keyword trigger: keyword (required), match_mode, allow_typo, responses (public reply templates). • ads — ad referral trigger: ad_id (required). • outgoing-messages — fires on an outgoing message keyword: keyword (required), assign_unpaused. • instagram-story — story reply trigger: story_id (required), story_created_at. Returns the created trigger row.

create_whatsapp_template

ChatGPT
Create a new WhatsApp message template and submit it to Meta for review (via mk1-chat). This SENDS NOTHING — it registers a template that can be broadcast later, once Meta approves it. Creation is asynchronous, so plan for the wait: 1. Call this tool. It returns { templateId, status } — status is normally PENDING, which means NOT usable yet. 2. Meta review usually takes minutes but can take up to 24h. Poll list_whatsapp_templates with includeAllStatuses:true and find this template by name/templateId: watch its status go PENDING → APPROVED. (The default listing shows APPROVED only, so on that path the template simply appears once approved — but includeAllStatuses:true lets you see it the whole time, including while PENDING.) 3. If it comes back REJECTED, the same includeAllStatuses:true listing carries its rejectedReason (why Meta rejected it) — no need to wait for Meta's email. Fix the wording that reason points at and create it again under a NEW name (a rejected name stays taken). 4. Once APPROVED, MARKETING/UTILITY can be broadcast the normal way: preview_whatsapp_template_recipients → confirm with the user → send_whatsapp_template. headerType decides which header field travels with it, and the two must agree: TEXT needs headerText, IMAGE needs headerImageUrl, the default NONE takes neither. A mismatch (an image URL on a NONE/TEXT header, a headline on a NONE/IMAGE one) is refused here before the call leaves, because headerType is what builds the template — a stray headerImageUrl would otherwise be dropped and the template created with no picture at all. For an IMAGE header, the headerImageUrl passed here is the sample Meta reviews. When you broadcast, pass the SAME headerImageUrl to send_whatsapp_template — that is what the contacts actually receive. AUTHENTICATION uses preset wording and a COPY_CODE OTP button. Omit bodyText/bodyExamples/headers/footerText/buttons; use authentication options for security disclaimer, expiry minutes and optional button label. After approval, your authentication backend sends one code per login attempt through POST /api/n8n/send-template with template.variables: [code] and a new idempotencyKey. send_whatsapp_template is a broadcast tool and cannot deliver authentication codes. The backend generates, expires and verifies codes. A template lives inside one WhatsApp Business Account, so pass fromWhatsAppAccountId (from list_whatsapp_templates) when the influencer has more than one number connected, and send it later from that same account. Returns { ok, influencerId, templateId, status, name, languageCode, category }.

deactivate_crm_product_price

ChatGPT
Products: deactivate a product price (productPriceId from get_crm_commerce) so it can no longer be used. Existing quotes and sales keep their price snapshots.

delete_agent

ChatGPT
Permanently delete a Ninjo agent and all its associated data (triggers, prompt versions, documents, workflow relations, config). Cannot delete agents with active conversations — will return an error with the count. Returns { success: true }.

delete_contact_limit

ChatGPT
Delete a contact limit by id. Returns { success: true }.

delete_creator_resource

ChatGPT
Delete a creator resource (removes the S3 object and the DB row). Returns { deleted, resource_id }.

delete_crm_property

ChatGPT
Delete property: permanently delete a property after reviewing preview_crm_property_delete. Can remove stored values; this is not archiving. Dependency blockers still apply.

delete_crm_sync_trigger

ChatGPT
External CRM sync: delete a stage-to-contact-property trigger (triggerId from get_crm_sync). Values it already set on contacts are kept.

delete_custom_notification

ChatGPT
Delete a custom notification by id. Returns { success: true }.

delete_custom_property

ChatGPT
Delete a custom property by id. Returns { success: true }.

delete_document

ChatGPT
Delete a context document from a Ninjo agent. If the document has an S3 file_key, deletes it from S3 as well. Returns { success: true }.

delete_notification_destination

ChatGPT
Delete a notification destination by id. Returns { success: true }.

delete_property_action

ChatGPT
Delete a property action by id. Its subtype row (http / crm_*) is removed too. Returns { success: true }.

delete_thread

ChatGPT
Delete a Cortex thread and all its messages.

delete_trigger

ChatGPT
Delete a trigger by ID and type. type must be one of: keywords, all-messages, comments, ads, outgoing-messages, instagram-story. Cascades to trigger_negative_config if present. Returns { success: true }.

delete_trigger_negative_config

ChatGPT
Remove the negative config from a trigger. The trigger itself is not affected.

delete_whatsapp_template_definition

ChatGPT
Delete a WhatsApp template definition by id (via mk1-chat). Refused with 409 if any notification destination still references it (detach or delete those first) — the definition is never silently orphaned. Returns { ok, influencerId, id }.

delete_workflow

ChatGPT
Delete a workflow by id. Returns { success: true }.

deploy_agent_sdk

ChatGPT
Deploy the Cortex SDK (system.md + the 8 v5Config fields) to a Ninjo agent in one correct-by-construction call. Bakes the multi-step deploy the cortex skills enforce but the raw tools don't: (1) update the prompt column if system changed, (2) merge changed v5Config fields, (3) re-sync trigger_keywords whenever keywords is provided — so keyword changes are always dual-written (v5Config context AND what actually fires) and system never lands in v5Config. Diffs each provided field against the live config and only calls what changed; omitted fields are left untouched (PATCH semantics — there is no set-to-null). Then re-fetches and verifies (version bumped, fields match, no v5Config↔trigger_keywords drift). On verified=false or partial=true the deploy did NOT fully succeed: pass rollback_version_id to restore_prompt_version to revert both prompt and config. Returns the deploy report. IMPORTANT: this ships the agent's MESSAGES only (prompt + v5Config). It does NOT create the contact limits, custom notifications, or follow-up workflows that turn a prompt into a working agent — build those separately (upsert_contact_limit / upsert_custom_notification / upsert_workflow), gated on your custom properties. verified=true means the messages are live, not that the system is complete. The result also carries a completeness report (the same deterministic build/wiring audit as diagnose_agent mode=quick) run AFTER the deploy — resolve its critical/warn findings (or run scaffold_agent_activation) before treating the agent as done.

diagnose_agent

ChatGPT
Audit a live agent and return ranked defects, each with the exact fix tool. An agent is a SYSTEM, not a prompt: this is the "definition of done" as code. mode="quick" (default) — DETERMINISTIC tier only. Free, fast, reproducible: run it after every iterate. Service-role checks: no terminal contact limit, an active agent not linked to a connected account, ungated follow-ups, string-typed gating properties, hand-made properties duplicating an auto one (e.g. agendo_llamada ↔ call_booked), inert properties, missing conversion notification, robotic cadence (humanization off), and v5Config↔trigger_keywords drift. score/complete come from this tier. mode="full" — also runs two LLM-graded tiers (costs model calls — run pre-deploy or periodically, NOT every iteration): - behavioral: samples recent low-quality conversations (bad/stuck/low-happy) and grades them server-side — filter leak, NO_RESPONSE paraphrase, reasoning leak, premature booking. Needs a JWT-scoped token. Returns the sampled transcripts too. - prompt_audit: grades the deployed SDK (system.md + v5Config) against the Best-Practices rubric BP-2…BP-10 (fetched live from the wiki) — contradictions, example coverage, unguarded actions, voice drift, stale CTAs. Returns { agent_id, checked_at, mode, score (0–100, deterministic), complete, findings, behavioral, prompt_audit }. Resolve every critical/warn finding (across all tiers) before treating the agent as done.

disconnect_crm_sync

ChatGPT
External CRM sync: disconnect a connected CRM account (accountId from get_crm_sync). Its sync connections stop syncing and are marked disconnected; messaging channels on the same account and historic opportunities are kept.

expire_crm_quote

ChatGPT
Quotes: expire a quote now (quoteId from get_crm_commerce or get_crm_contact_commerce).

export_crm_contacts

ChatGPT
Contacts export: one filtered page of the contacts table as CSV, with its totalCount. Requires the export:contacts permission. Iterate pages for larger exports. Spreadsheet formulas are neutralized.

export_crm_opportunities

ChatGPT
Deals export: export up to 50 selected opportunities (quote ids with their current revisions) to CSV with Studio's export authorization.

generate_image

ChatGPT
Generate an image using Gemini AI (gemini-3-pro-image-preview). Pass a prompt and an optional background image as base64. Returns { image_base64, mime_type }.

generate_synthetic_conversations

ChatGPT
Generate synthetic conversations for an agent by invoking the replicant Lambda. Two mutually-exclusive modes: pass personas for AI-simulated leads (user generated by an LLM), or pass scripted_scenarios to replay fixed user messages with no user-side inference (only the agent responds). Fan-out across the chosen items and return conversations in both structured and markdown formats. Returns { conversations, test_run_ids, lambda_invocations, lambda_errors, conversations_fetched, conversations_filtered, elapsed_seconds, warning }. min_turns defaults to 1 in scripted mode and 3 with personas; warning is non-null when every fetched conversation was dropped by min_turns (returned 0), suggesting a lower min_turns. influencer_id is inferred from the JWT when using an influencer-scoped token — only required when using admin or API key auth.

get_agent_config

ChatGPT
Get the full configuration snapshot for a Ninjo agent: agent metadata, system prompt, and AgentConfig settings. Requires an influencer-scoped JWT. Returns { agent, config }.

get_agent_insights

ChatGPT
Fetch operational insights snapshot for an agent: quick stats (24h activity), hot leads waiting for follow-up, stalled leads by objection type, funnel transition rates, and content source performance. Returns: - quick_stats: { new_conversations_24h, qualified_leads_24h, bookings_sent_24h } - hot_leads: leads with funnel≥2, lead_score≥3, last message INBOUND 24–72h ago (up to 20) - stalled_by_objection: leads stalled 1–3 funnel, grouped by objection (MONEY/TRUST/TIMING/PRIORITY/UNKNOWN) - funnel_transitions: conversion rates between funnel stages for the lookback period - content_sources: per-source (Organic DM / Story Reply / Ad) conversion performance influencer_id is inferred from the JWT when using an influencer-scoped token.

get_agent_metrics

ChatGPT
Calculate performance metrics for one or all agents. Includes engagement, funnel, lead score, booking rates, happy path, nurturing quality, monotonicity of funnel progression, and relative risk scores (z-scores). Returns { days, min_leads, agents: [{ influencer_id, influencer_username, leads, avg_engagement_score, avg_funnel, avg_lead_score, funnel_to_lead_score_ratio, bookings_sent, booking_send_rate, call_booked_observed_leads, calls_booked, call_book_rate_total, call_book_rate_per_lead_observed, call_book_rate_per_booking_observed, pct_calls_booked_low_lead_score, avg_happy_path_score, avg_nurturing_score, pct_happy_lt_60, pct_nurture_lt_60, pct_lead_score_eq_1, pct_funnel_ge_4, premature_rate_refined, stages_compared, monotonic_violations, worst_drop, lead_score_monotonic_non_decreasing, risk_raw, risk_score_0_100 }] }.

get_connection_status

ChatGPT
Report, per integration, whether it is authorized AND whether it is actually finished: Instagram, Facebook, the CRMs ('gohighlevel_crm', 'hubspot_crm', 'kommo_crm'), booking ('gohighlevel_booking', 'calendly'), 'google_calendar' and 'manychat'. Use this to poll after handing the owner a connect link, and to verify setup instead of asking the user whether it worked. Read setup_complete, not connected. oauth_ok:true with setup_complete:false is a real state — booking is fail-closed, so an authorized calendar account with nothing selected tracks zero bookings. pending_step says what to do next: "select_calendars" → set_booking_calendars; "paste_api_key_in_studio" → send the user to /studio/{influencer_id}/integrations/manychat to set the channel AND the API key (never ask for the key); "authorize_with_connect_link"/"reconnect" → create_connect_link; "enable_for_agent_in_studio" (Google Calendar) → set_google_calendar_agent, which finishes it without leaving the chat. For 'manychat', setup_complete:true means everything Ninjo can SEE is configured (channel + key). It cannot see whether the user pasted Ninjo's webhook URL into ManyChat, which is what makes messages actually arrive — so remind them of that step rather than declaring the integration live. Returns { influencer_id, channels: { <provider>: { connected, invalid_token, oauth_ok, setup_complete, pending_step, name } } }. Only requested channels are present (pass provider to narrow).

get_contact

ChatGPT
Everything the platform knows about ONE contact: native fields, the value of every custom property defined on the account, and the contact's conversations. This is the tool for "why did nothing happen for this person" — follow-ups, contact limits and notifications all gate on custom-property values, and this is the only way to read them for a given contact. Identify the contact with EXACTLY ONE of: contact_id (from search_contacts), whatsapp_number, instagram_username, email, phone. Passing two is rejected rather than silently AND-ed. If an identifier matches more than one contact row (which happens after a partial merge), the call fails with the count and asks you to use contact_id — it never picks one for you. READ is_set BEFORE DRAWING ANY CONCLUSION. Every property the influencer defines comes back, including ones this contact has never been given: - is_set: true → value holds the stored value (typed: boolean, number, option text, or string). This is what the automations see. - is_set: false → the evaluator has NEVER written this property for this contact, and value is null. That is NOT "false" and NOT "empty". A contact limit gated on compra_realizada behaves the same whether the property is false or unset, but the first means the evaluator ran and said no, and the second means it never ran — opposite fixes. Custom properties are written by the post-hoc evaluator agent, never by the conversational agent, so a wrong value is an evaluator question, not a prompt question. conversations lists the contact's conversations (newest first, up to 20) with conversation_id for get_conversation_messages / get_conversation_decisions, plus agent_conversation so you can see at a glance whether an agent was ever attached. whatsapp_identity explains a null whatsapp_number: bsuid means the lead hid their number in WhatsApp's privacy settings. That is not lost data and there is nothing to backfill — the number cannot be recovered, the team cannot call them, but WhatsApp messages and templates still reach them. comment_post_url, comment_media_id and commented_at describe the contact's first public comment (the post it was left on); null when they never commented. Returns { contact_id, first_name, last_name, email, phone_number, whatsapp_number, whatsapp_identity, is_whatsapp_subscribed, instagram_username, picture_url, created_at, comment_post_url, comment_media_id, commented_at, properties: [{ codename, label, type, is_set, value, selected_options, updated_at }], properties_set_count, conversations: [{ conversation_id, type, agent_conversation, agent_id, last_message_at }] }.

get_contact_limits_context

ChatGPT
Fetch context data required to configure contact limits: available agents and custom properties with options. Returns { agents, customProperties }.

get_conversation_decisions

ChatGPT
Explain why a lead saw no reply. Returns the platform's own recorded decisions for one conversation: NO_RESPONSE events, contact-limit events (a limit fired and muted the conversation permanently) and send failures (kind send_failed: the agent DID reply, the channel rejected it, the lead never saw the text that is still in the transcript; detail is <error_code>: <description>, e.g. THREAD_OWNER_MISMATCH = another Meta app such as ManyChat owns the Instagram thread, MESSAGE_WINDOW_EXPIRED = outside the 24h window, INVALID_TOKEN = reconnect the account). READ THE DETAIL, not just the kind: NO_RESPONSE alone means the agent chose silence (prompt-side); NO_RESPONSE: last_message_not_user means there was nothing to reply to and is benign; NO_RESPONSE - cot_filter_blocked means the chain-of-thought filter suppressed a leaking message (a platform safety net, see knowledge/reasoning-leak.md); NO_RESPONSE - <text> is the agent's own stated reason. Only the first is a prompt problem. Call this FIRST whenever an operator says the agent did not answer a specific lead, or that a lead stopped answering, before reading the prompt — an empty transcript looks identical whether the agent chose silence or the message never arrived, and a transcript with agent text looks identical whether it was delivered or rejected; this is the only way to tell. An empty result means none of those fired, so the cause is upstream (routing, trigger, connected account) — work knowledge/runbooks/agent-not-answering.md. Note NO_RESPONSE on a comment trigger suppresses BOTH legs, the public reply and the private DM.

get_conversations

ChatGPT
Fetch real production conversations from influencer_conversation_rollup_view_rls + messages table. Returns conversation metadata and full message history. Modes: - recent: latest conversations with ≥3 messages - booking: booking link was shared with the lead - high-funnel: funnel stage ≥ 4 - high-score: Lead Score > 3 - bad: funnel ≥ 4 but lead score ≤ 3 (high funnel, low quality) - low-happy: happy_path_score < 60 - high-happy: happy_path_score ≥ 80 - stuck: agent sent ≥ 6 messages but funnel < 3 influencer_id is inferred from the JWT when using an influencer-scoped token. Returns { influencer_id, mode, count, conversations: [{ conversation_id, contact_id, contact_username, meta: {...}, messages: [{direction, sent_at, content}] }] }. The contact_id can be passed to the WhatsApp template preview/send tools.

get_crm_assignment

ChatGPT
Ownership: read who owns one exact conversation or pipeline record, its assignment history, eligible teams and people, and your capabilities, including the current revision. Use cursor for older history.

get_crm_booking_conversions

ChatGPT
Booking won/lost outcomes: read the Booking Link manual won/lost records (at most one per outcome) for one contact. Requires read:pipelines and read:contacts. These legacy records are separate from native sales and quote opportunities (deals).

get_crm_commerce

ChatGPT
Commerce: read the product and price catalog, quotes, configured payment providers and commerce capabilities. Prices and quote snapshots are immutable versions. Filter with productQuery and quoteQuery; use get_crm_contact_commerce for one contact and list_crm_commerce_records for older records and line items.

get_crm_contact

ChatGPT
Contact 360: one contact's identity, tags, visible conversations, scoped properties (facts), pipeline records and commercial history. History pages are bounded; use get_crm_contact_history for older pages. Contacts have no owner of their own: ownership belongs to exact conversations or pipeline records (get_crm_assignment).

get_crm_contact_commerce

ChatGPT
Contact commerce: read one contact's quotes, sales, payments, refunds, No Sale outcomes and imported commercial history, with available products and provider capabilities. Page with historyCursor and importedHistoryCursor.

get_crm_contact_edit_context

ChatGPT
Contact edit snapshot: read a contact's editable identity and document identity before replace_crm_contact. Copy every identity field you want to keep into the replacement; empty strings clear values.

get_crm_contact_history

ChatGPT
Contact 360 history: page through a contact's facts, conversations or pipeline timeline after get_crm_contact. Facts and conversations need the returned next cursor; the pipeline timeline may omit it for its first page. Keep the opaque cursor and the exact contact. Results and conversation links obey record scope.

get_crm_contact_tags

ChatGPT
Contact tags: read one contact's tags and the active tags available to add.

get_crm_overview

ChatGPT
Start here for native Ninjo CRM: contacts, tags, properties, pipelines and stages, deals (opportunities), products, quotes, sales, payment links, teams, routing and external CRM sync. Returns your permissions in the workspace, the rollout flags per area, an index of the CRM tools grouped by area, and workflow guidance. Native pipelines are not the external-CRM mirrors of list_crm_pipelines and list_crm_stages.

get_crm_pipeline_automations

ChatGPT
Pipeline automations: read the rules that move, add or transfer pipeline records when a record enters a stage or a contact fact changes, with active stages, contact fact definitions and options, and recent runs. Ownership routing is separate (get_crm_routing).

get_crm_pipeline_draft

ChatGPT
Pipeline draft preview: read a saved pipeline configuration draft and recompute its publish preview without changing it: current revisions, blockers and the fingerprint publish_crm_pipeline_draft needs. Requires read:pipelines and manage:workspace-settings.

get_crm_pipelines

ChatGPT
Native pipelines: read Ninjo pipelines, their ordered stages and records (deals in a stage). Filter by pipelineId, status and stageId; page with after; pass recordId for one record's detail and history. These ids are not the external-CRM mirror ids of list_crm_pipelines and list_crm_stages. Use get_crm_pipeline_draft for a draft and its publish preview.

get_crm_property

ChatGPT
Property definition: read one property's full edit state and dependency context before replace_crm_property or a deletion.

get_crm_routing

ChatGPT
Routing rules: read the automatic assignment rules with their typed fact criteria and options, eligible targets, revisions and recent outcomes. Routing picks the human owner; pipeline automations move records.

get_crm_sync

ChatGPT
External CRM sync: read the connected external CRM accounts with their sync settings, mirrored pipelines, stage-to-property triggers and Airtable mappings. Never returns provider tokens, webhook secrets or event URLs. Use create_connect_link to authorize or reconnect a provider. Mirrored pipelines belong to the external CRM; native Ninjo pipelines are in get_crm_pipelines.

get_crm_teams

ChatGPT
Teams: read teams, their members, eligible workspace users and team revisions. Teams do not grant workspace access. Read before changing membership.

get_discord_invite

ChatGPT
Return the stored Discord invite for the influencer's mapped operator channel (invite_url + metadata). Throws if no invite is stored — run bootstrap_discord_channel first. influencer_id is inferred from an influencer-scoped JWT; admin/API-key auth must pass it.

get_instagram_posts

ChatGPT
Fetch the influencer's recent Instagram posts via Meta Graph API. influencer_id from auth when available; from param when admin.

get_instagram_profile

ChatGPT
Fetch the influencer's Instagram profile via Meta Graph API. influencer_id from auth when available; from param when admin.

get_knowledge

ChatGPT
Fetch a specific platform knowledge document by slug. Use list_knowledge first to discover available slugs.

get_me

ChatGPT
Return the current authenticated context: influencer_id (the one active for this request), user_id, scope (single-influencer | multi-influencer | admin), available_influencer_ids (selectable via X-Influencer-Id when the token carries a user_id; multi-influencer + admin tokens), and influencers (map of influencer_id → Instagram handle — identify a creator by handle but pass the influencer_id to tools). 'scope' is the selection mode, NOT a DB role, and does not limit which tools you can call. Same shape as GET /api/v1/me.

get_peer_managed_files

ChatGPT
Returns managed files (e.g. changelog.md) from peer influencers that share the same use_case or vertical as the requesting influencer. influencer_id from auth when available; from param when admin. At least one of use_case or vertical must be provided. Returns { peers: [...], total }.

get_playbook_doc

ChatGPT
Fetch one playbook, template, or worked-example SDK by an id from get_playbook_index. For sample SDKs, call with no section to get the file manifest, then pass section to select a file (e.g. system, examples, objections, keywords, meta). Large docs paginate: when has_more is true, call again with the returned next_cursor.

get_playbook_index

ChatGPT
Call this FIRST before creating, iterating, analyzing, or answering any question about a Ninjo agent or the cortex SDK. Returns the catalog of operating manual, knowledge base, prompt-architecture templates, and worked-example SDKs; fetch the relevant ones with get_playbook_doc before drafting. A Ninjo agent is a SYSTEM (system prompt + the 8 v5Config fields + triggers + automation), not just a prompt — the playbook is how you build the whole system instead of a bare prompt.

get_self_serve_data

ChatGPT
Fetch self-serve onboarding data from MongoDB for an influencer. Returns data from four collections: - influencer_bio: IG profile processed by GPT (bio, audience, content formats, engagement patterns) - instagram_post: Posts with metrics and video transcriptions - instagram_conversation: DM conversations with followers - creator_input: Self-serve onboarding form (program details, lead magnets, style, use case) Missing sources are listed in missing_sources — expected for incomplete onboarding. Returns { influencer_id, sections: [{ source, count?, data }], missing_sources: string[] }.

get_synthetic_conversations

ChatGPT
Fetch synthetic conversations from MongoDB by one or more test_run_ids. Use this to retrieve results after a generate_synthetic_conversations call or to re-fetch existing runs. Returns { conversations, count }.

get_thread_messages

ChatGPT
Get message history for a Cortex thread, ordered chronologically. Supports cursor-based pagination via the before parameter (ISO timestamp). Returns { messages: [{ id, role, content, created_at }] }.

get_trigger_negative_config

ChatGPT
Get the negative config (temporary block) of a trigger. When enabled and now < expires_at, the trigger is suppressed even if it would otherwise match. Returns { negative_config } which is null if none is set. trigger_type: keywords | all-messages | comments | ads (outgoing-messages and instagram-story are not supported).

get_workflow_activity

ChatGPT
Get workflow activity snapshot (fires/evaluations) for the last N days. Returns { days, since, activity }.

import_crm_contacts

ChatGPT
Import contacts: create or update contacts from a CSV (at most 250 KB) with Studio's importer; returns per-row created/updated/skipped/error results. Use the native headers from the import guidance; an optional bulk property value applies to every row. Does not change subscription consent or accept non-contact facts. Review the counts before repeating a partial import.

list_agent_channels

ChatGPT
List every messaging channel a Ninjo agent answers, from BOTH sources, in one unified view. Returns { channels, count }; each channel carries source: "direct" (a Meta account — Instagram/WhatsApp — connected directly in Ninjo) or "crm" (a CRM sync connection — GoHighLevel, Kommo, HubSpot, Airtable — that RELAYS its messages to this agent). Use this to tell whether an agent is a free Meta agent or is dedicated to a CRM channel: a source:"crm" channel means the agent is NOT connected to Instagram directly — it answers the messages that arrive from GHL/Kommo through that channel. channel_type is the account type (direct) or the CRM provider (crm); connected is the single 'is this channel live' flag (direct: the Meta token is valid; crm: the connection is enabled and not disconnected). Metadata only — no access tokens or webhook secrets are returned.

list_agent_tools

ChatGPT
List all tools/skills assigned to a Ninjo agent, including their enabled status, settings, and prompt.

list_agents

ChatGPT
List all agents belonging to the authenticated influencer. Returns { agents: AgentRow[], count: number }. Useful to resolve an agent_id when only the influencer identity is known.

list_booking_calendars

ChatGPT
List the GoHighLevel calendars (or Calendly event types) on the connected booking account, flagging which ones Ninjo currently tracks. This is step 3 of connecting booking: create_connect_link → the owner authorizes → list_booking_calendars → set_booking_calendars. Read the names back to the user and let them pick; the ids are opaque provider ids (a Calendly id is a URI) and must never be guessed. connected:false means the platform was never authorized — send a connect link instead. load_failed:true means the list could not be read (expired token / provider down), so an empty list is NOT evidence the account has no calendars. Returns { platform, connected, load_failed, calendars: [{ id, name, selected }], count }.

list_connected_accounts

ChatGPT
List connected Meta sub-accounts linked to a Ninjo agent. Returns { accounts, count }. Metadata only — no access tokens or secrets are returned.

list_contact_limits

ChatGPT
List configured contact limits for an influencer. Returns { contactLimits: ContactLimit[] } including related agents and propertyConditions.

list_creator_resources

ChatGPT
List the influencer's agent-sendable resources (audio/image clips sent mid-conversation). Filter by type (IMAGE | AUDIO) and agent_usable_only. Returns { resources: [{ id, name, type, agent_usable, agent_usage_context, ... }], count }.

list_crm_commerce_records

ChatGPT
Commerce history: page through native products, prices, quotes and quote lines, sales and sale lines, payments and payment events, payment links and No Sale records beyond the bounded snapshots of get_crm_commerce and get_crm_contact_commerce. Pick one entity with its parent id, then follow nextCursor until hasMore is false, keeping the same selection. Money is in minor-unit strings. Provider secrets, error bodies and hidden conversation provenance are never returned.

list_crm_connections

ChatGPT
List the influencer's CRM connections (GoHighLevel, Kommo, HubSpot, Airtable). This is the ROOT of CRM discovery — it returns the sync_connection_id you pass to CRM property actions, to list_crm_pipelines / list_crm_fields, and to set_messaging_channel_enabled. Unlike list_agent_channels (which shows only connections routed to a given agent), this shows ALL of the influencer's connections. Returns { connections, count }. Metadata only — no tokens or webhook secrets. It returns TWO different kinds of row, distinguished by event_name: a row WITHOUT a '.messaging.' event_name is the CRM SYNC connection (contacts, opportunities, fields — one per connected account); a row whose event_name contains '.messaging.' (e.g. 'gohighlevel.messaging.whatsapp', 'kommo.messaging.instagram') is a MESSAGING CHANNEL that relays conversations from the CRM to a Ninjo agent. They are not interchangeable: property actions and pipelines belong to the sync row, while set_messaging_channel_enabled and set_agent_crm_channel act on the messaging rows. Read enabled here before toggling a channel.

list_crm_contacts

ChatGPT
Contacts table: list native contacts with typed properties and tags, using filters, sorting and page/pageSize, with totalCount. Iterate pages to read everything. Use get_crm_contact for one contact's full 360 view.

list_crm_fields

ChatGPT
List a CRM connection's custom fields, fetched LIVE from the CRM. entity picks which object's fields — 'contact' or 'opportunity' — because CRM fields hang off a specific object. Each field's id is the crm_external_field_id you pass to a CRM_FIELD_UPDATE property action. Returns { fields, count }.

list_crm_opportunities

ChatGPT
Deals (opportunities): list quote-based opportunities with stage, owner, won/lost, follow-up and payment state, and valid filter options. One row per quote. Page with after; the API reports filter issues. Commerce stays authoritative for money and quote status.

list_crm_pipelines

ChatGPT
List the CRM pipelines synced for an influencer (optionally narrowed to one sync_connection_id). Use this to find the pipeline that holds the stage you want for a CRM_STAGE_TRANSITION property action. Pipelines come from the local synced mirror — if a connection has never synced they come back empty. Returns { pipelines, count }.

list_crm_properties

ChatGPT
Properties: list native property definitions with their scope (CONTACT, CONVERSATION and PIPELINE_RECORD facts are distinct), type, options, defaults and evaluation settings. Tags are managed separately.

list_crm_stages

ChatGPT
List the stages of a CRM pipeline (from list_crm_pipelines). Each stage's id is the crm_target_stage_id / crm_stage_id you pass to a CRM_STAGE_TRANSITION or CRM_PUSH_CONTACT property action. Stages come from the local synced mirror. Returns { stages, count }.

list_crm_tags

ChatGPT
Tags: list the workspace's reusable contact tags, including archived ones, with colors, assigned counts and timestamp revisions (the expectedRevision for update_crm_tag, archive_crm_tag, restore_crm_tag and remove_archived_crm_tag_assignments).

list_custom_notifications

ChatGPT
List custom notifications for an influencer. Includes linked destinations. Returns { customNotifications }.

list_custom_properties

ChatGPT
List custom properties for an influencer. Includes rich metadata and options. Returns { customProperties }.

list_documents

ChatGPT
List all context documents (agent_document_contents) for a Ninjo agent. Returns { documents, count }.

list_influencer_connected_accounts

ChatGPT
List ALL connected Meta sub-accounts that belong to the influencer (Instagram, WhatsApp, etc.), whether or not they are linked to an agent. Use this to DISCOVER the connected_account_id to pass to set_connected_account when linking a fresh agent — list_connected_accounts only shows accounts already linked to a given agent, so it is empty for a new agent. Returns { accounts, count }. Metadata only — no access tokens or secrets are returned.

list_knowledge

ChatGPT
List all available platform knowledge documents (playbooks, templates, strategy guides, platform docs). Returns slug, category, and title for each doc. Use get_knowledge with a slug to fetch the full content.

list_notification_destinations

ChatGPT
List custom notification destinations for an influencer. Optional channel filter. Returns { notificationDestinations }.

list_property_actions

ChatGPT
List the property actions configured for an influencer. A property action is a side-effect that fires when a custom property reaches a value: an HTTP_REQUEST (webhook) or one of the CRM actions — CRM_STAGE_TRANSITION (move an opportunity to a stage), CRM_FIELD_UPDATE (write a CRM field), CRM_TASK_CREATE (open a task), CRM_PUSH_CONTACT (push the contact into the CRM), CRM_CONTACT_TAG (write a tag on the CRM contact, or on its Kommo lead). Each item carries its condition (the operator + value that triggers it) and exactly one populated subtype block (http / crm_stage_transition / crm_field_update / crm_task_create / crm_push_contact / crm_contact_tag) matching its action_type. Use this to see how a custom property is wired to downstream automation and to CRM channels. Returns { propertyActions, count }. Metadata only — no secrets.

list_schedules

ChatGPT
List the influencer's real bookings from the schedules table — who booked, when, from where, and their status. This is the ground-truth booking record, distinct from calls_booked on get_agent_metrics (an LLM-inferred custom-property estimate read from the conversation, not this table). Filters (all optional, combined with AND; status/source are OR'd internally): status (ACTIVE | CANCELLED | SHOWED | NO_SHOW), source (GO_HIGH_LEVEL | CALENDLY | ESCULPE_CRM | AGENT | GOOGLE_CALENDAR | AGENDAPRO | IMPORT; AGENDAPRO = synced from the workspace's AgendaPro account; agent_id is always null; IMPORT = a past visit imported from the workspace's historical records: status SHOWED, the date is real but the time is a 12:00 local placeholder, created_at equals the visit time, name lists the services, agent_id is always null), agent_id, contact_id, has_agent, scheduled_after/scheduled_before (on the appointment datetime), booked_after/booked_before (on when the booking was created), search (contains, on the contact's name/phone/email). TIMEZONE — read this before quoting any hour to anyone. Pass timezone (an IANA name, e.g. "America/Argentina/Buenos_Aires") and the tool does all the conversion for you: every returned datetime/created_at comes back in that zone with its offset attached ("2026-08-01T16:00:00.000-03:00", i.e. a 4pm call), and bare dates in the filters are read as local days — scheduled_after/booked_after as 00:00 local, scheduled_before/booked_before as the end of that local day, so "bookings in August" is just booked_after "2026-08-01" + booked_before "2026-08-31". Never add or subtract hours yourself; set timezone and quote the wall clock you get back. The response echoes the zone it used in its top-level "timezone" field. Omit timezone and everything stays UTC with a Z — correct, but then 19:00Z is a 4pm call for a UTC-3 workspace and it is on you to say so. Where to get the zone: the agent's own config already has one — call get_agent_config and read its "timezone" field (the same value the agent's native get_current_time tool uses). That is the operator's business zone and the right thing to pass here. If the agent has none set, or the question spans several agents, ask the operator which zone they work in — never infer it from a contact's phone number, and never assume UTC-3 because most workspaces are. Filters also accept full ISO 8601 instants with a zone at any time; a bare date without timezone is rejected rather than assumed to be UTC midnight. Three things you MUST get right when reading the response: 1. agent_id credits the booking to a Ninjo agent; a null agent_id does not by itself mean the contact never talked to one. AGENT and GOOGLE_CALENDAR bookings carry the agent that booked them in the conversation. GO_HIGH_LEVEL, CALENDLY and ESCULPE_CRM bookings carry the agent of the contact's most recent agent conversation when the booking first arrived, so null there means there was none yet (direct link, web form, manual entry). AGENDAPRO bookings are never attributed: their agent_id is always null, whether or not the lead talked to an agent. IMPORT rows are past visits imported from the workspace's historical records and are never attributed either. Any booking's agent_id becomes null when its agent is deleted, and bookings made before mid-March 2026 have no attribution at all. Use has_agent:true/false to split attributed from unattributed bookings, and do not filter by agent on bookings made before mid-March 2026 expecting it to mean anything. 2. datetime ≠ created_at. scheduled_after/scheduled_before answer "what's on the calendar" (the appointment); booked_after/booked_before answer "who booked recently" (when the row was created). They are not interchangeable — pick the one that matches the question. 3. form_data is raw and its shape depends on source. GO_HIGH_LEVEL rows carry [{id, value}] with GoHighLevel's internal field id, not the question text; it's inspectable but not interpretable without the CRM's field dictionary. AGENDAPRO rows carry an agendaProScheduleSync object (AgendaPro sync provenance), a…

list_threads

ChatGPT
List Cortex threads for an influencer, ordered by most recently updated. Each item includes id, title, status, last_message, created_at, updated_at.

list_trigger_audios

ChatGPT
List the audios attached to a trigger, ordered by order ascending. type selects which trigger family: keywords (DM keyword trigger) or ads (ad referral trigger). Each audio references a CreatorResource (type=AUDIO) played in rotation when the trigger matches. Returns { audios }.

list_trigger_canned_responses

ChatGPT
List the canned text response variants configured on a trigger, ordered by order ascending. On the FIRST trigger match in a conversation, mk1-chat sends one variant at random instead of invoking the LLM (saving agent cost); follow-up messages are handled by the normal agent. type selects the trigger family: keywords | all-messages | comments | ads | instagram-story (outgoing-messages is not supported). Returns { canned_responses }.

list_triggers

ChatGPT
List all triggers for a Ninjo agent, grouped by type: keywords (DM keyword triggers), all_messages (ALL_DM / ALL_COMMENTS), comments (comment keyword triggers), ads (ad referral triggers), outgoing_messages, instagram_story. Keyword and ad referral triggers include audios when configured.

list_whatsapp_template_definitions

ChatGPT
List the influencer's stored WhatsApp template definitions (via mk1-chat). A template definition is the persisted binding that a WHATSAPP_TEMPLATE notification destination points at (whatsappTemplateDefinitionId). Use this to obtain that UUID when wiring upsert_notification_destination, or to inspect the current variable values. Returns { ok, influencerId, definitions: [{ id, templateId, templateName, languageCode, variableMappings: [{ id, name, value, locations }] }], count }.

list_whatsapp_templates

ChatGPT
List the influencer's Meta-approved WhatsApp message templates (via mk1-chat). Use this first when the user wants to start a WhatsApp conversation outside the 24-hour customer-service window — only APPROVED templates can be sent. Returns { ok, influencerId, templates: [{ templateId, name, language, status, components }], count }.

list_workflows

ChatGPT
List workflows for an influencer. Optional filters: type and customNotificationId. Returns { workflows }.

mark_crm_opportunities_lost

ChatGPT
Deals (opportunities): mark up to 50 selected opportunities lost with a lostReason, each with its current revision from list_crm_opportunities. Changes CRM state only; quotes and payments are untouched. Check per-row results for partial failures.

mark_crm_opportunity_won

ChatGPT
Deals (opportunities): mark one opportunity won, with its current revision from list_crm_opportunities. Changes CRM state only; it never sends quotes or moves payments.

mark_crm_quote_sent

ChatGPT
Quotes: mark a quote as sent, advancing its status. It does not message the contact; share the quote with the messaging tools.

move_crm_opportunities_to_stage

ChatGPT
Deals (opportunities): move up to 50 selected opportunities to a stage of a pipeline, each with its current revision from list_crm_opportunities. Check per-row results for partial failures.

move_crm_pipeline_record

ChatGPT
Pipelines: move a pipeline record to another stage of its pipeline, using the record's current revision. History is preserved and configured pipeline automations may run. To move it to another pipeline use transfer_crm_pipeline_record.

pause_conversation_agent

ChatGPT
Pause the agent on a specific conversation. The agent will stop responding to inbound messages in that conversation until resumed. Identify the conversation by the contact's platform identifier (Instagram username, Facebook ID, or WhatsApp phone number).

preview_crm_property_delete

ChatGPT
Property delete preview: read a property's dependencies and usage before delete_crm_property. Changes nothing.

preview_whatsapp_template_recipients

ChatGPT
Resolve candidate contact ids server-side before sending a WhatsApp template. Contacts without a WhatsApp number or unsubscribed from WhatsApp are excluded. ALWAYS call this before send_whatsapp_template: show the eligible sample and counts to the user and obtain their explicit confirmation. Then send with the SAME contactIds you previewed. Returns { ok, influencerId, requestedCount, eligibleCount, excludedCount, eligibleSample, eligibleSampleTruncated, eligibleSampleLimit, excludedContactIds }.

publish_crm_pipeline_draft

ChatGPT
Pipeline setup, step 2: publish exactly the reviewed draft preview, with its draft revision, the current configuration revision (null for a new pipeline) and previewFingerprint. Stale previews and unsafe stage removals or archives fail; reload and review a new preview before retrying.

record_crm_booking_conversion

ChatGPT
Booking won/lost: record a contact's Booking Link outcome as won (with a positive amount in major currency units) or lost, and push it to connected CRMs. Requires write:opportunities. One record per contact and outcome: repeating overwrites amount and note and may repeat the external push. Currency defaults to USD on creation and is kept on updates. Read get_crm_booking_conversions first. Does not create a native sale or close a quote.

record_crm_no_sale

ChatGPT
Sales: record a No Sale outcome for a contact with an uppercase reasonCode such as NOT_INTERESTED, PRICE, TIMING or OTHER, and an optional note.

record_crm_outside_payment

ChatGPT
Sales: record a payment received outside Ninjo against a contact's sale. amountMinor is an integer string in minor units (USD 19.95 is "1995"). Records evidence only; it never charges through a provider.

record_crm_outside_refund

ChatGPT
Sales: record a refund made outside Ninjo against a contact's payment. amountMinor is an integer string in minor units (USD 19.95 is "1995"). Records evidence only; it never refunds through a provider.

record_crm_outside_sale

ChatGPT
Sales: record a sale paid outside Ninjo for a contact, optionally against a quote. Lines use either productPriceId versions or productId with a unitAmount in minor units. Records evidence only; it never charges through a provider.

refresh_crm_sync

ChatGPT
External CRM sync: refresh a connected provider's pipeline mirror and health/setup metadata through the existing integration. Calls the provider, may refresh its tokens and overwrites the synced mirror. For Airtable setup, pass airtableBaseId to discover table and field ids. Returns safe account metadata and setup choices, never credentials.

register_creator_resource

ChatGPT
Step 2 of uploading: after PUTting the file to the presigned URL, register the DB row pointing at s3_key and make it agent-usable. usage_context is required when agent_usable is true (the default) — a concrete sentence telling the agent WHEN to send it. Returns { resource }.

register_messaging_channel_webhook

ChatGPT
Re-register the Kommo account webhook for an existing messaging channel. Kommo only — GoHighLevel needs no per-channel webhook and is rejected. Use this when create_messaging_channel came back with webhook_registered: false. That channel exists but receives NOTHING: Kommo does not know where to deliver its messages, so the agent stays silent and the symptom looks like a broken agent rather than a setup step. This is the recovery path — without it the only fix is re-saving the channel in Studio. Safe to call more than once: the destination and secret are unchanged, so Kommo upserts rather than adding a duplicate. It is also harmless on a channel that is already registered. Returns { channel, webhook_registered }. If webhook_registered is still false the retry failed too — tell the user the channel is not receiving messages yet instead of reporting the channel as live; a repeated failure usually means the Kommo account's token is stale and needs a reconnect.

remove_archived_crm_tag_assignments

ChatGPT
Tags: permanently remove an archived tag from every contact it was assigned to. Requires write:contacts. Archiving alone keeps the assignments; this cannot be undone. expectedRevision is the tag's timestamp revision from list_crm_tags.

remove_crm_team_member

ChatGPT
Teams: remove a member from a team, using the team's current revision from get_crm_teams. Records the member owns may block the removal.

replace_crm_contact

ChatGPT
Replace contact identity: overwrite a contact's complete editable identity (names, notes, phone, email, WhatsApp, Instagram, verification flags). Read get_crm_contact_edit_context first and resend every value you keep: all fields are required and empty strings clear them. Verification and attested-identity protections still apply. Gender and country use update_crm_contact_attributes.

replace_crm_contact_tags

ChatGPT
Set contact tags: replace a contact's complete set of active tags. To add or remove one tag, read get_crm_contact_tags and resend every tag you keep; [] clears them all. Archived tags cannot be newly added. Tag facts, routing and automations react to the change.

replace_crm_product

ChatGPT
Products: replace a product's name, description and SKU; an empty description or SKU clears it. Prices are immutable versions: change pricing with add_crm_product_price and deactivate_crm_product_price.

replace_crm_property

ChatGPT
Replace property definition: overwrite a property's editable definition. Read get_crm_property first and resend every field you keep. The scope cannot change here; option and dependency protections still apply.

replace_objectives

ChatGPT
Replace all objectives for a Ninjo agent. Deletes existing objectives and inserts the provided array. Pass an empty array to clear all objectives. Returns { success: true }.

report_feedback

ChatGPT
Report a problem to the Ninjo developers when you cannot complete a task (missing tool/skill/playbook/info, a bug, or a feature request). Files an issue in Linear (Cortex-ops project, label by type: ERROR→Bug, FEATURE_REQUEST→Feature, MISSING_INFO→Improvement) and pings the devs Slack channel with the ticket + affected client. Provide what you were trying to do (operation), what went wrong (problem), and the type. To attach the full session, first call create_feedback_upload_url, upload the session, and pass its s3_key as session_s3_key. Returns { ok, issue_id, issue_identifier, issue_url, slack_posted }. slack_posted may be false (partial success) even when the issue was created.

reset_crm_airtable_sync

ChatGPT
External CRM sync: reset a connected Airtable account's setup, removing its webhook and field mappings. Configure it again with configure_crm_airtable_sync after refresh_crm_sync.

restore_crm_tag

ChatGPT
Tags: restore an archived contact tag so it can be assigned again, with the assignments it kept. expectedRevision is the tag's timestamp revision from list_crm_tags.

restore_crm_team

ChatGPT
Teams: restore an archived team, using its current revision from get_crm_teams.

restore_prompt_version

ChatGPT
Restore a previous prompt version. Sets the agent's active prompt to the specified version and updates current_prompt_version_id.

resume_conversation_agent

ChatGPT
Resume the agent on a previously paused conversation. The agent will start responding to inbound messages again. Identify the conversation by the contact's platform identifier (Instagram username, Facebook ID, or WhatsApp phone number).

save_crm_pipeline_draft

ChatGPT
Pipeline setup, step 1: save a full pipeline configuration (name, default flag, ordered stages with colors and success/failure outcomes) as a draft for a NEW pipeline, an EXISTING one (current configuration revision) or an existing DRAFT (current draft revision). Keep existing stage ids; omit ids only for new stages. Returns a preview: review its blockers, then publish_crm_pipeline_draft with the exact returned fingerprint and revisions.

save_image

ChatGPT
Upload a base64 image to S3 (ninjo-prod-content, key: amplify/campaigns/{campaign_id}/{sequence}.{ext}) and update campaign_sections.image_url in the database. Returns { cdn_url }.

scaffold_agent_activation

ChatGPT
Wire the standard activation kit onto an agent, correct-by-construction. diagnose_agent DETECTS missing activation infra; this REMEDIATES it. The gateway can't infer an agent's conversion property or motion, so you supply the intent and this guarantees correct wiring: - ensures terminal_property exists as a BOOLEAN (string properties gate unreliably), - an enabled contact limit gated on it, so the agent stops messaging contacts who converted, - (followup) a FOLLOW_UP gated on not-converted (+ optional interest) — never ungated, - (notify) a conversion notification (workflow + custom notification) on an existing destination. Idempotent: re-running reuses any piece already wired for this agent instead of duplicating it. Returns what was created vs reused, plus a fresh completeness report. NOTE: if terminal_property is not a recognized terminal codename (call_booked / purchased / …), diagnose may still report no_terminal_stop — recognized_terminal in the result tells you.

search_contacts

ChatGPT
Search the influencer's contact directory with composable AND filters and pagination — the same audience picker behind the studio contacts/templates page. Returns each contact's contact_id, which you pass to preview_whatsapp_template_recipients and send_whatsapp_template. Native filters (all optional): name (partial, first or last), email, phone, whatsapp_number, instagram_username, is_whatsapp_subscribed, has_whatsapp_number, created_after / created_before (ISO 8601). Ad attribution: from_ads (true → only contacts who came from a Meta ad — at least one inbound Instagram/Facebook message carries an ad referral; false → only contacts with no ad referral on any inbound), ad_id (only contacts with an inbound referral for that exact Meta ad id; implies from_ads). When either is set, each contact is enriched with its first-touch ad metadata — the earliest ad-tagged inbound — (referral_ad_id, referral_source, referral_type, referral_ref, ad_title, ad_post_id, ad_photo_url, ad_video_url, post_url); otherwise those fields come back null. Custom-property filters (custom_properties[]): each { codename, ... } is resolved to the property's type and matched accordingly: - boolean → equals_boolean - integer → min and/or max - option → value (the option's text, case-insensitive) - string → value (case-insensitive contains) Get codenames from list_custom_properties. Pagination: limit (default 25, max 100), page (default 1). To target a WhatsApp template send: filter here (often is_whatsapp_subscribed: true + has_whatsapp_number: true), collect contact_id values, then preview before sending. Preview re-applies eligibility server-side, so search is for audience selection, not the final eligibility gate. Returns { influencer_id, filters_applied, total_count, page, total_pages, pages_remaining, count, contacts: [{ contact_id, first_name, last_name, email, phone_number, whatsapp_number, is_whatsapp_subscribed, instagram_username, created_at, referral_ad_id, referral_source, referral_type, referral_ref, ad_title, ad_post_id, ad_photo_url, ad_video_url, post_url }] }.

search_conversations

ChatGPT
Search real production conversations from influencer_conversation_rollup_view_rls + messages table using composable AND filters, with pagination. Returns conversation metadata and full message history. Unlike get_conversations (curated modes), this has NO implicit minimum message count — pass min_messages: 3 to reproduce the "recent" behavior. Omitting all filters returns every agent conversation for the influencer. Filters (all optional, combined with AND): - conversation_id: exact match — returns that single conversation - contact_username: case-insensitive partial match on the contact identifier (instagram/tiktok handle, phone, whatsapp) - messages/funnel: min_messages, max_messages, min_agent_messages, min_funnel, max_funnel - scores: min_lead_score, max_lead_score, min_happy_path, max_happy_path, min_nurturing, max_nurturing, min_engagement, max_engagement - booleans: has_booking_link, is_lead, call_booked, open_conversation - date ranges (ISO 8601): last_message_after, last_message_before, first_message_after, first_message_before - pagination: limit (default 10, max 100), page (default 1) influencer_id is inferred from the JWT when using an influencer-scoped token. Returns { influencer_id, filters_applied, total_count, page, total_pages, pages_remaining, count, conversations: [{ conversation_id, contact_id, contact_username, meta, messages }] }. The contact_id can be passed to the WhatsApp template preview/send tools.

search_playbook

ChatGPT
Search the playbook for relevant passages instead of fetching whole docs; returns ranked snippets with the id (and section for samples) you can pass to get_playbook_doc to read more. Use get_playbook_index first to understand the catalog.

send_thread_message

ChatGPT
Send a message to a Cortex thread. The request is accepted immediately (202) and processed asynchronously — the agent response is inserted once OpenClaw responds. Returns { message_id }.

send_whatsapp_template

ChatGPT
Send a Meta-approved WhatsApp template to one or more contacts (via mk1-chat). HIGH IMPACT: this delivers real WhatsApp messages, billed by Meta. MANDATORY workflow — never skip a step: 1. list_whatsapp_templates — discover APPROVED templates 2. preview_whatsapp_template_recipients — resolve eligible recipients 3. Show the user the eligible sample/counts and ask for explicit confirmation 4. Call this tool with userConfirmed: true and the SAME contactIds you previewed Returns { ok, influencerId, templateId, createdCount, skippedCount, totalContacts }.

set_agent_crm_channel

ChatGPT
Route a CRM sync connection (GoHighLevel, Kommo, HubSpot, Airtable) to a Ninjo agent, or unroute it. Pass agent_id to make that agent answer the messages this CRM channel relays into Ninjo; pass agent_id: null to unroute the channel from any agent. Unlike Meta sub-accounts (many-to-many via set_connected_account), a CRM sync connection routes to a SINGLE agent, so routing it to a new agent replaces the previous one. Use list_agent_channels first to see which sync connections exist and where they point. Returns { success: true }.

set_agent_status

ChatGPT
Enable or disable a Ninjo agent by setting is_active. Requires an influencer-scoped JWT. Returns { success: true }.

set_booking_calendars

ChatGPT
Choose which GoHighLevel calendars / Calendly event types Ninjo tracks bookings from. BOOKING IS FAIL-CLOSED: with NO calendars selected, NOT A SINGLE booking is tracked — OAuth alone leaves the integration connected but dead. So never report booking as ready before this call succeeds, and never leave the selection empty by default. calendar_ids REPLACES the whole selection (it is not additive), so include every calendar that should stay tracked. Every id must come from list_booking_calendars — an invented id is rejected rather than silently disabling tracking. Passing [] switches tracking off entirely; only do it when the user explicitly asks. Returns { platform, selected, count, calendars }. Confirm back by name, not by id.

set_connected_account

ChatGPT
Link or unlink a connected Meta sub-account to/from a Ninjo agent (many-to-many). Pass connected_account_id to ADD a link (leaves existing links intact), or null to unlink ALL sub-accounts from this agent. Returns { success: true }.

set_crm_auto_sync

ChatGPT
External CRM sync: turn automatic contact sync on or off for one sync connection from get_crm_sync. When turning it on, stageId optionally picks the destination stage (from get_crm_sync, null for none); turning it off clears the stage.

set_crm_contact_property

ChatGPT
Set contact property: set or clear one CONTACT-scoped property value with the typed writer. Read the definition first: options take the option UUID, booleans "true"/"false", integers integer strings, dates ISO timestamps; "" clears. May fire configured property actions and external CRM hooks. Never use it for conversation or pipeline-record facts.

set_crm_opportunities_next_action

ChatGPT
Deals (opportunities): set the next follow-up date and note on up to 50 selected opportunities, or clear them with null, each with its current revision from list_crm_opportunities. Check per-row results for partial failures.

set_crm_opportunities_owner

ChatGPT
Deals (opportunities): set the owner of up to 50 selected opportunities, or clear it with null, each with its current revision from list_crm_opportunities. Check per-row results for partial failures.

set_google_calendar_agent

ChatGPT
Switch the workspace's connected Google Calendar ON or OFF for one agent. This is the last step of connecting it — the one get_connection_status reports as pending_step:"enable_for_agent_in_studio". A consented calendar books NOTHING until an agent is linked to it: the four runtime tools (get_google_calendar_availability, book_google_calendar_event, cancel_google_calendar_event, reschedule_google_calendar_event) are loaded only for a linked agent. So never report Google Calendar as ready before this call succeeds. There is ONE calendar per workspace and it is shared — this only decides which agents may use it. Order matters: create_connect_link(provider:'google_calendar') → the owner authorizes in the browser → this. Calling it first fails with "no Google Calendar connected". v5 agents only — an older engine is refused rather than linked, because it would arm the legacy scheduler (UTC, none of the booking rules). Switching an agent ON also lets it CANCEL and RESCHEDULE, whether or not the prompt mentions those tools. Say so when the operator only asked for booking. Then have them review the booking rules at /studio/{influencer_id}/integrations/google-calendar (calendar, hours per weekday, duration, minimum notice, days ahead, in person with address or video call) — left unset they default to Monday–Friday 9:00–18:00, 30-minute slots and a Google Meet link. enabled:false unlinks only this agent: the connection, its booking rules and every other agent are untouched. Returns { agent_id, enabled, agents: [{ id, name, enabled }], enabled_count }. Confirm back by name. enabled_count:0 means the calendar is connected and dead.

set_messaging_channel_enabled

ChatGPT
Pause or resume a GoHighLevel / Kommo messaging channel without deleting it. Reversible; deleting a channel is not exposed here (do that in Studio). A channel is created already enabled, so there is NO need to call this after create_messaging_channel — use it to pause a channel while the user reconfigures something in the CRM, and to turn it back on. Get sync_connection_id from list_crm_connections (or list_agent_channels), picking a row whose event_name contains '.messaging.'. A row with a provider and no messaging event_name is the CRM SYNC connection, not a channel — this tool refuses those, since pausing it would stop contact sync for the whole account. Returns { channel }.

set_messaging_channel_whatsapp_provider

ChatGPT
Switch an existing GoHighLevel WhatsApp channel between GoHighLevel's official WhatsApp and an external provider (a WhatsApp QR/app integration registered inside GHL). Use this when create_messaging_channel was called with the wrong third_party_whatsapp value — the symptom is that inbound messages arrive but Ninjo's replies never send. The channel cannot simply be recreated (one WhatsApp channel per account), which is why this exists. Only applies to GoHighLevel WHATSAPP channels; Kommo and every other channel type are rejected. Returns { channel, third_party }. Check third_party, not channel: the flag lives on the connected account, so channel is byte-identical before and after — third_party is read back from the account after the write and is the only confirmation the flip landed.

sync_keyword_triggers

ChatGPT
Reconcile the agent's DM keyword triggers with the provided list using a diff: existing keywords are preserved (created_at untouched), match_mode is patched when it differs, new keywords are inserted, and keywords absent from the input are deleted. Inputs are lowercased + trimmed + deduplicated before diffing. match_type values (SDK format): any_mention/anywhere → ANYWHERE, isolated_word/keyword_only → KEYWORD_ONLY. Returns { deleted, created, updated, keywords } where keywords is the final state sorted alphabetically.

sync_trigger_audios

ChatGPT
Reconcile the audios attached to a trigger with the provided list: kept audios preserve their row (and created_at), reordered audios get their order patched, new ones are inserted, and ones absent from the input are deleted. type selects the trigger family: keywords or ads. Input is deduplicated by resource_id. Each resource_id must reference a CreatorResource of type AUDIO owned by this influencer — creation/upload of CreatorResources is handled elsewhere. If order is omitted for an item it defaults to the item's index. Returns { deleted, created, updated, audios } where audios is the final list sorted by order.

sync_trigger_canned_responses

ChatGPT
Replace the canned text response variants of a trigger with the provided list, via diff by id: items WITH an existing id update that row in place (text/order), items WITHOUT an id are inserted as new variants, and existing variants absent from the input are deleted. Pass an empty list to remove all variants. To edit safely, call list_trigger_canned_responses first and resend items with their ids. Max 10 variants per trigger; each text is trimmed, must be non-empty and at most 950 characters. If order is omitted for an item it defaults to the item's index. Rejected (400) while the trigger's negative config is enabled — negative triggers cannot carry canned responses. type: keywords | all-messages | comments | ads | instagram-story. Returns { deleted, created, updated, canned_responses } with the final state sorted by order.

toggle_crm_routing_rule

ChatGPT
Routing: switch an assignment routing rule between enabled and disabled, using its current revision from get_crm_routing. Read the rule again before changing it once more.

transfer_crm_pipeline_record

ChatGPT
Pipelines: atomically close a pipeline record and continue the contact in another pipeline at destinationStageId, with an optional outcome and transferReason. Uses the source record's current revision; ids come from get_crm_pipelines.

trigger_fetch_info

ChatGPT
Ensure MongoDB has the influencer's Instagram data by triggering the fetch-info Step Function if needed. Workflow: 1. Checks if influencer_bio already exists in MongoDB → returns status: skipped if yes (unless force=true) 2. Verifies Instagram is connected (access token present in Postgres) 3. Starts the fetch-info Step Function and polls until completion (up to timeout_seconds) 4. Returns the final status Returns { status: "skipped"|"no_ig_connected"|"no_sf_arn"|"succeeded"|"failed"|"timed_out", reason?, execution_arn?, bio_existed? }.

unassign_crm_owner

ChatGPT
Ownership: clear the team and person that own a conversation or pipeline record (subject), with an optional unassignReason, using the current revision from get_crm_assignment.

update_agent

ChatGPT
Update basic fields on a Ninjo agent: name and/or description. Requires an influencer-scoped JWT. Returns { success: true }.

update_agent_config

ChatGPT
Update AgentConfig settings. All fields are optional. model, temperature, conversation_summary_enabled, should_respond_check_enabled, is_test_agent, response_filter go into the config JSON. set_on_conversation goes to the agents table. All other fields update agent_configs directly. response_filter tunes the CoT reasoning-leak filter (config.responseFilter): { enabled, extra_patterns (extra JS-regex patterns to strip, additive), disabled_defaults (default patterns to drop for this agent) } — PATCH-merged, so pass only what you change.

update_agent_mode

ChatGPT
Update a Ninjo agent's mode and workflow relations. For non-INDIVIDUAL modes, workflow_agents is required. Each workflow_agent must be a valid UUID and cannot be the same as agent_id. Returns { success: true }.

update_agent_voice

ChatGPT
Update voice reply configuration for a Ninjo agent. All fields are optional and merged into the existing voiceReply config JSON. Returns { success: true }.

update_creator_resource

ChatGPT
Update an existing creator resource's name or agent metadata (agent_usable, usage_context, caption_guidance). PATCH semantics — omitted fields are left untouched. Returns { resource }.

update_crm_contact_attributes

ChatGPT
Contact attributes: partially update a contact's native gender and countryCode. Omitted attributes are kept; null clears one. Read get_crm_contact first; other identity fields use replace_crm_contact. Contact identity is shared, but CRM sync effects stay within the selected workspace.

update_crm_pipeline_automation

ChatGPT
Pipeline automations: replace an automation rule's complete configuration, using its current revision from get_crm_pipeline_automations. actionReason is recorded on the records it acts on.

update_crm_routing_rule

ChatGPT
Routing: replace an assignment routing rule's complete configuration, using its current revision from get_crm_routing. FORCE needs forceReason and permission.

update_crm_tag

ChatGPT
Tags: rename or recolor a contact tag (optionId from list_crm_tags). name replaces the current name; an empty color clears it and an omitted color keeps it. expectedRevision is the tag's timestamp revision from list_crm_tags.

update_crm_team

ChatGPT
Teams: replace a team's name and description (an empty description clears it), using the team's current revision from get_crm_teams.

update_managed_file

ChatGPT
Write a managed file to influencer_managed_files. influencer_id from auth when available; from param when admin. filepath is relative (e.g. 'changelog.md'). Returns { filepath, content_sha256, updated_at }.

update_prompt

ChatGPT
Update the system prompt for a Ninjo agent. Automatically creates a new prompt version and sets it as current. Returns { agent_config_id, prompt_version_id, version }.

update_resource_sending

ChatGPT
Enable/configure the agent sending creator-uploaded audio/image clips mid-conversation (config.resourceSending). enabled toggles the feature; allowed_types is a subset of [IMAGE, AUDIO] (only these are deliverable); max_per_conversation caps how many times the same resource is sent per conversation. PATCH semantics — omitted fields are left untouched. This does NOT create a new prompt version. Returns the merged resourceSending config.

update_tool

ChatGPT
Update an agent tool. Only allowed fields: enabled (boolean), settings (object), prompt (string). credentials are never modifiable via this tool. Returns { success: true }.

update_trigger

ChatGPT
Update an existing trigger. type selects the variant: keywords (keyword, match_mode, allow_typo) or outgoing-messages (keyword, assign_unpaused). Only provided fields change. NOTE: for keyword changes that must stay in sync with v5Config, prefer deploy_agent_sdk or sync_keyword_triggers — a single-row keyword edit here does not update v5Config.keywords. Returns { success: true }.

update_trigger_comment_response

ChatGPT
Update the text of one existing saved public reply on a comment-keyword trigger, preserving its ID and the trigger. Get trigger_id and response_id from list_triggers → comments[].responses[]. This edits public responses, not private-DM canned_responses (use sync_trigger_canned_responses for those). Other reply variants and AI settings are unchanged. This works without enabling AI replies and does not send a message; the text is used by the saved public-reply path on future matching comments. Returns { response } with the updated reply row.

update_v5_config

ChatGPT
Update the v5Config (Cortex SDK) for an agent. Each field is a text blob that maps to an SDK file (knowledge_base.md, examples.md, etc.). Only the keys you provide are merged; others are preserved. Returns the merged config.

upsert_contact_limit

ChatGPT
Create or update a contact limit — the lever that STOPS an agent from messaging a contact once a terminal state is reached (e.g. they booked a call or purchased). Gate it on a custom property via propertyConditions: this is how you silence the agent after a conversion so the operator stops babysitting DMs by hand. Pass id to update an existing limit; omit id to create a new one. Returns { success: true, contactLimit }.

upsert_custom_notification

ChatGPT
Create or update a custom notification — alerts the operator the moment something happens (e.g. a lead booked a call). Pair it with a workflow (type CUSTOM_NOTIFICATION) or a contact limit, gated on the custom property that marks the event, so the operator is pinged automatically instead of watching DMs by hand. Pass id to update; omit id to create. Returns { success: true, customNotification }.

upsert_custom_property

ChatGPT
Create or update a custom property. Pass id to update, omit id to create. A property is INERT on its own: an external evaluator fills its value, but nothing happens until a contact limit, custom notification, or workflow CONSUMES it via a propertyCondition — defining the property is only half the job. For any property you will gate automation on (a booking flag, a funnel stage), use a boolean or number type, NOT a string: "true"/"false" string values compare unreliably in conditions. Returns { success: true, customProperty }.

upsert_notification_destination

ChatGPT
Create or update a notification destination. Pass id to update; omit id to create. Returns { success: true, notificationDestination }.

upsert_property_action

ChatGPT
Create (omit id) or update (pass id) a property action — a side-effect that fires when a custom property reaches a value. Set action_type: HTTP_REQUEST for a webhook (needs http_url), or CRM_STAGE_TRANSITION / CRM_FIELD_UPDATE / CRM_PUSH_CONTACT / CRM_CONTACT_TAG to act on a CRM (needs crm_sync_connection_id; CRM_STAGE_TRANSITION also needs crm_target_stage_id, CRM_CONTACT_TAG needs crm_tag_name). A CRM_CONTACT_TAG only works on a contact already pushed to the CRM — pair it with a CRM_PUSH_CONTACT action if the contacts are not synced yet. The action fires when the property's value satisfies operator against the value_* you set. For HTTP_REQUEST, read the http_body_template description before writing a body: it takes {{contact.first_name}}-style tokens from a fixed vocabulary, and an unrecognised token renders as an empty string with no error rather than failing. Use list_property_actions to see existing actions and list_crm_connections / list_crm_stages / list_crm_fields to discover the CRM ids. Returns { success: true, id, action_type }.

upsert_trigger_negative_config

ChatGPT
Create or update the negative config (temporary block) of a trigger. The trigger is suppressed while enabled=true AND now < expires_at. A null or past expires_at means the block is effectively inactive even if enabled; for an 'indefinite' block, pass a far-future expires_at (mk1-chat UI uses +100 years). Setting enabled=false clears activated_at. user_timezone is informational (IANA tz). Returns the upserted config.

upsert_whatsapp_template_definition

ChatGPT
Create or update a WhatsApp template definition and its variable bindings (via mk1-chat). Returns the UUID consumed by upsert_notification_destination (whatsappTemplateDefinitionId), closing the workflow-driven outbound WhatsApp path end-to-end via MCP. Identity is the natural key (templateId, influencerId): omit id to create-or-update by that key; pass id to assert you are updating a specific existing definition. mk1-chat rebuilds the full template structure (components/buttons) from the live Meta template — you only supply variable values via variableMappings (an id→value map). templateName/languageCode default to the Meta template when omitted. To discover the variable ids of a new template, call this once with no/partial variableMappings and read them from the returned definition.variableMappings, then call again with the id→value map. Returns { ok, influencerId, created, definition: { id, templateId, templateName, languageCode, variableMappings } }.

upsert_workflow

ChatGPT
Create or update a workflow — scheduled automation that runs OFF custom properties. The most common use is re-engaging stalled leads: type FOLLOW_UP with a propertyCondition on a funnel/stage property re-nudges contacts who went quiet (a prompt alone never follows up). Other types: CUSTOM_NOTIFICATION (alert the operator), SCHEDULE_REMINDER, CUSTOM_ACTION. Pass id to update; omit id to create. Returns { success: true, workflow }.

void_crm_quote

ChatGPT
Quotes: void a quote (quoteId from get_crm_commerce or get_crm_contact_commerce).

void_crm_sale

ChatGPT
Sales: void a contact's recorded sale (saleId from get_crm_contact_commerce). Payments and refunds recorded against it are preserved.

associate_whatsapp_direct_numbers

Claude

bootstrap_discord_channel

Claude

create_agent

Claude

create_document

Claude

create_feedback_upload_url

Claude

create_resource_upload_url

Claude

create_thread

Claude

create_trigger

Claude

delete_agent

Claude

delete_contact_limit

Claude

delete_creator_resource

Claude

delete_custom_notification

Claude

delete_custom_property

Claude

delete_document

Claude

delete_notification_destination

Claude

delete_thread

Claude

delete_trigger

Claude

delete_trigger_negative_config

Claude

delete_whatsapp_template_definition

Claude

delete_workflow

Claude

deploy_agent_sdk

Claude

diagnose_agent

Claude

generate_synthetic_conversations

Claude

get_agent_config

Claude

get_agent_insights

Claude

get_agent_metrics

Claude

get_contact_limits_context

Claude

get_conversations

Claude

get_instagram_posts

Claude

get_instagram_profile

Claude

get_knowledge

Claude

get_me

Claude

get_peer_managed_files

Claude

get_playbook_doc

Claude

get_playbook_index

Claude

get_self_serve_data

Claude

get_thread_messages

Claude

get_trigger_negative_config

Claude

get_workflow_activity

Claude

list_agent_tools

Claude

list_agents

Claude

list_connected_accounts

Claude

list_contact_limits

Claude

list_creator_resources

Claude

list_custom_notifications

Claude

list_custom_properties

Claude

list_documents

Claude

list_influencer_connected_accounts

Claude

list_knowledge

Claude

list_notification_destinations

Claude

list_threads

Claude

list_trigger_audios

Claude

list_trigger_canned_responses

Claude

list_triggers

Claude

list_whatsapp_template_definitions

Claude

list_whatsapp_templates

Claude

list_workflows

Claude

pause_conversation_agent

Claude

preview_whatsapp_template_recipients

Claude

register_creator_resource

Claude

replace_objectives

Claude

report_feedback

Claude

restore_prompt_version

Claude

resume_conversation_agent

Claude

save_image

Claude

scaffold_agent_activation

Claude

search_contacts

Claude

search_conversations

Claude

search_playbook

Claude

send_thread_message

Claude

send_whatsapp_template

Claude

set_agent_status

Claude

set_connected_account

Claude

sync_keyword_triggers

Claude

sync_trigger_audios

Claude

sync_trigger_canned_responses

Claude

trigger_fetch_info

Claude

update_agent

Claude

update_agent_config

Claude

update_agent_mode

Claude

update_agent_voice

Claude

update_creator_resource

Claude

update_managed_file

Claude

update_prompt

Claude

update_resource_sending

Claude

update_tool

Claude

update_trigger

Claude

update_v5_config

Claude

upsert_contact_limit

Claude

upsert_custom_notification

Claude

upsert_custom_property

Claude

upsert_notification_destination

Claude

upsert_trigger_negative_config

Claude

upsert_whatsapp_template_definition

Claude

upsert_workflow

Claude

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

App Stats

303

Tools

3

Prompts

ChatGPT, Claude

Platforms

Works with

ChatGPT
Claude

Data refreshed daily