Skip to main content
Glama

agents_trigger_create

Create a new trigger for an AI agent.

Triggers determine when the agent activates.

Trigger types:

  • incoming_message: Activates on new incoming messages

  • schedule: Activates on a schedule

  • webhook: Activates on webhook events

  • event: Activates on system events

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
enabledNoWhether the trigger is enabled. OMIT to use the default (true).
agent_idYesID of the agent to create a trigger for
priorityNoTrigger priority — lower numbers run first (default: 100)
send_modeNoSend mode override for this trigger. OMIT to inherit from the agent.
conditionsNoTrigger conditions (JSON). Supported fields for incoming_message: - keywords: ["pricing","demo"] — message must contain keyword(s) (free, no LLM cost) - keyword_match: "any" (default, OR) or "all" (AND) - channel_types: ["telegram","whatsapp","livechat_voice","twilio_voice","telegram_voice","voice",...] — filter by channel. For voice, use EITHER the three per-channel keys (scoped) OR "voice" alone (wildcard matching all three) — mixing them is redundant. Per-channel keys: "livechat_voice" (web widget), "twilio_voice" (PSTN inbound), "telegram_voice" (Telegram p2p calls) - context_types: ["dm","group","channel","livechat"] — filter by chat type - group_mode: "mentions_only" or "questions" — for group chats - channel_account_ids: ["123"] — restrict to specific accounts - folder_ids: [5,10] — restrict to threads in folders - ai_tag_ids: [1,2] — restrict to threads with AI tags - ai_filter_ids: [1,2] — semantic intent filters (message matched via embedding similarity, works in noisy groups) - ai_filter_mode: "any" (default, OR) or "all" (AND) — how multiple AI filters combine - ai_filters: [{id: 1}, {name: "...", description: "..."}] — shorthand: reference existing by id or create inline (calls Voyage embedding API). If a filter with the same name already exists, it is reused by id. Prefer referencing existing filters by id when available. Use ai_filters.create + ai_filters.test for fine-tuning before assigning. - template: the reply a rule_based agent sends, with no model run. Either a string ("Hi {from_name}, we open at 9") or a card object {text, attachments, buttons} — text is required, attachments is a list of file ids (files.upload), buttons is a list of {label, value|url|web_app} carrying exactly ONE target each: value = a reply the bot receives back, url = opens a link (add track: true to count each tap per conversation, readable as analytics_link_clicks_v in analytics.query), web_app = opens a Mini App over https. The string, and a card's text, substitute {from_name}, {message_text}, {channel_type}, {thread_id}, {raw_data}; button labels and targets are sent verbatim. A card with buttons needs send_mode auto — a draft row cannot carry a keyboard. Buttons need a channel that renders them (telegram_bot). A card needs a chat to land in, so it refuses on webhook, schedule and other thread-less triggers where a string still drafts. - handoff: {agent_id, task} — only on a rule_based agent's trigger (refused elsewhere). After the rule's deterministic part has actually happened — the template's message delivered, or the agent's script completed — the named agent runs on the same thread, in its own send mode, exactly as its own trigger would run it: the customer's message reaches it as the incoming message, and `task` reaches it as the handoff brief from this rule. The rule stays instant; the thinking — a reminder, a referral code, a personal follow-up — happens behind it. Script plus handoff is how a workspace does something deterministic the platform has no verb for (file the thread, stamp a tag, push a row) and still lets an agent answer, with the deterministic part living in that agent's own script rather than in platform code. `task` substitutes {channel_type} and {thread_id} only; {message_text}, {from_name} and {raw_data} are refused (the sender would be writing the instruction — the message and its sender already reach the target as the incoming message). The target must be an active agentic or claude_channels agent in this workspace (the engines that read the brief). The target's run is a normal trigger run: it holds the thread lock, its own safety gates apply, and its final answer is delivered like any DM reply — a follow-up that should stay silent must call agent.silence. Nothing runs when the message was drafted, refused or failed, when the script failed, when a safety gate has the rule in draft mode, or when the event carries no thread for the target to answer on. A target paused or deleted after the trigger was written does not stop the rule's message: it goes out, and the reason the follow-up did not start is recorded in the rule's activity row (error field) and in the target's activity as an execution_error. - contact_states: ["active"] — filter by contact state - cooldown_seconds: 30 — min gap between runs per thread - max_runs_per_thread_per_hour: 5 — rate limit - once_per_thread: true — after this trigger completes on a conversation it steps aside there and the next matching trigger answers later messages. For a rule that files / tags / hands off once, not for the agent that holds the conversation. - answer_delay_s: 15 — voice pickup only (incoming_call, or incoming_message scoped to a voice channel). Ring the human's own devices this long before the agent answers; if they pick up, the agent stands down. 0/absent = answer immediately. Honoured on WhatsApp and Telegram 1:1 — other voice channels have nothing ringing to wait for and still answer at once. - auto_join: true|false — voice pickup, GROUP calls only. Whether the bot enters a matching group call on its own (true) or the call becomes a pending invite an operator accepts (false). OMIT THE KEY to defer to the channel setting (channel_account.state.voice_auto_join_policy, default 'approval'); resolution is trigger-when-present, then channel, then approval, so an explicit false beats a channel set to auto. Absent and false are different answers. - chat_ids: ["-5172634473"] — voice pickup, Telegram GROUP calls only. Scopes the trigger to specific groups; omit for every group call. Any id spelling works (5172634473, -5172634473, -1005172634473 are the same group). A call whose chat is unknown never satisfies it, so do NOT set this together with 1:1 / Twilio / Telnyx / WhatsApp / Android / LiveChat voice channels or the "voice" wildcard: those calls have no chat and the trigger would stop answering them. Supported fields for job_completed (proactive callback when a delegated job finishes): - source_agent_id: <int> — fire only when this agent's job completed - source_agent_slug: <str> — alternate to source_agent_id - job_type: "agentic_session" — match a specific job type (default: any) - outcome: ["completed"] | ["escalated"] | ["completed","escalated"] — default ["completed"] - min_duration_seconds: <int> — skip very-short jobs (noise filter) - thread_filter: {thread_ids: [<int>...]} — restrict to specific threads Supported fields for calendar_event (fires N minutes before a Google Calendar event starts): - window_minutes_before: <int 1-1440> — REQUIRED, fire when an event starts within this window - channel_account_ids: [<int>...] — restrict to specific calendar accounts (default: all) - keywords: ["standup"] — word-boundary match on event title - prepare_meet_join: true — pre-invite pool bots to the event (enables unattended Meet join) incoming_message action fields: - action: "reply_text" (default, normal agent run) or "join_voice" (deterministically join the voice channel resolved from the message — requires send_mode=auto) - message_source: "real" (default) | "transcript" | "both" — real messages vs turns during a live call. Transcripts are turns that address the agent. calendar_event run-mode field (incoming_message uses `action` instead): - run_mode: "text" (default) or "voice" (join the meeting — requires send_mode=auto) - voice: {speak_first: <bool — greet immediately vs stay silent until addressed>, vision_mode: "off"|"on_demand"|"continuous_0_3fps"} — pairs with action=join_voice (incoming_message) or run_mode=voice (calendar_event)
thread_idsNoRestrict this trigger to specific threads (chats) by their numeric thread IDs. When set, the trigger only fires for messages in these threads. Only for incoming_message and job_completed triggers. Maps to conditions.thread_filter.thread_ids.
in_workspaceNoRun this one call in this workspace id instead of the session's. Nothing is stored; other sessions are not affected.
trigger_typeYesType of trigger: 'incoming_message', 'incoming_call', 'schedule', 'webhook', 'event', 'blockchain_event', 'job_completed', 'calendar_event', or 'lead_captured'
target_sessionNoWhich Claude Code desktop session this trigger's runs go to, by the name / client id / session id that workspace.desktops lists. Only meaningful on a claude_channels agent: that engine hands the run to a connected desktop, and without an address it can only be delivered when EXACTLY ONE is connected (a second open window turns every run into channel_target_missing). A task assigned to the agent still wins — its own target_session is per-request and more specific than the trigger's default. Stored as conditions.target_session.
blocked_sender_idsNoNever react to these senders/callers, by their channel-side id — a phone number, a WhatsApp JID, a Telegram user id, an email address. Explicit deny: it beats every allow-list, and it applies to ALL trigger types, including incoming_call, so it is how you stop an agent answering one nuisance caller without silencing it for everybody. Phone-shaped ids are matched by their digits, so '+998901234567', '998901234567' and '998901234567@s.whatsapp.net' are the same person. Maps to conditions.sender_filter.excluded_external_ids.
excluded_thread_idsNoExclude specific threads (chats) by their numeric thread IDs — the opposite of thread_ids. When set, the trigger NEVER fires for messages in these threads, even if thread_ids would otherwise allow them (explicit deny wins). Only for incoming_message and job_completed triggers. Maps to conditions.thread_filter.excluded_thread_ids.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / conditions / description
      Previous value: -"Trigger conditions (JSON). Supported fields for incoming_message:\n- keywords: [\"pricing\",\"demo\"] — message must contain keyword(s) (free, no LLM cost)\n- keyword_match: \"any\" (default, OR) or \"all\" (AND)\n- channel_types: [\"telegram\",\"whatsapp\",\"livechat_voice\",\"twilio_voice\",\"telegram_voice\",\"voice\",...] — filter by channel. For voice, use EITHER the three per-channel keys (scoped) OR \"voice\" alone (wildcard matching all three) — mixing them is redundant. Per-channel keys: \"livechat_voice\" (web widget), \"twilio_voice\" (PSTN inbound), \"telegram_voice\" (Telegram p2p calls)\n- context_types: [\"dm\",\"group\",\"channel\",\"livechat\"] — filter by chat type\n- group_mode: \"mentions_only\" or \"questions\" — for group chats\n- channel_account_ids: [\"123\"] — restrict to specific accounts\n- folder_ids: [5,10] — restrict to threads in folders\n- ai_tag_ids: [1,2] — restrict to threads with AI tags\n- ai_filter_ids: [1,2] — semantic intent filters (message matched via embedding similarity, works in noisy groups)\n- ai_filter_mode: \"any\" (default, OR) or \"all\" (AND) — how multiple AI filters combine\n- ai_filters: [{id: 1}, {name: \"...\", description: \"...\"}] — shorthand: reference existing by id or create inline (calls Voyage embedding API). If a filter with the same name already exists, it is reused by id. Prefer referencing existing filters by id when available. Use ai_filters.create + ai_filters.test for fine-tuning before assigning.\n- template: the reply a rule_based agent sends, with no model run. Either a string (\"Hi {from_name}, we open at 9\") or a card object {text, attachments, buttons} — text is required, attachments is a list of file ids (files.upload), buttons is a list of {label, value|url|web_app} carrying exactly ONE target each: value = a reply the bot receives back, url = opens a link, web_app = opens a Mini App over https. The string, and a card's text, substitute {from_name}, {message_text}, {channel_type}, {thread_id}, {raw_data}; button labels and targets are sent verbatim. A card with buttons needs send_mode auto — a draft row cannot carry a keyboard. Buttons need a channel that renders them (telegram_bot). A card needs a chat to land in, so it refuses on webhook, schedule and other thread-less triggers where a string still drafts.\n- handoff: {agent_id, task} — only on a rule_based agent's trigger (refused elsewhere). After the rule's deterministic part has actually happened — the template's message delivered, or the agent's script completed — the named agent runs on the same thread, in its own send mode, exactly as its own trigger would run it: the customer's message reaches it as the incoming message, and `task` reaches it as the handoff brief from this rule. The rule stays instant; the thinking — a reminder, a referral code, a personal follow-up — happens behind it. Script plus handoff is how a workspace does something deterministic the platform has no verb for (file the thread, stamp a tag, push a row) and still lets an agent answer, with the deterministic part living in that agent's own script rather than in platform code. `task` substitutes {channel_type} and {thread_id} only; {message_text}, {from_name} and {raw_data} are refused (the sender would be writing the instruction — the message and its sender already reach the target as the incoming message). The target must be an active agentic or claude_channels agent in this workspace (the engines that read the brief). The target's run is a normal trigger run: it holds the thread lock, its own safety gates apply, and its final answer is delivered like any DM reply — a follow-up that should stay silent must call agent.silence. Nothing runs when the message was drafted, refused or failed, when the script failed, when a safety gate has the rule in draft mode, or when the event carries no thread for the target to answer on. A target paused or deleted after the trigger was written does not stop the rule's message: it goes out, and the reason the follow-up did not start is recorded in the rule's activity row (error field) and in the target's activity as an execution_error.\n- contact_states: [\"active\"] — filter by contact state\n- cooldown_seconds: 30 — min gap between runs per thread\n- max_runs_per_thread_per_hour: 5 — rate limit\n- once_per_thread: true — after this trigger completes on a conversation it steps aside there and the next matching trigger answers later messages. For a rule that files / tags / hands off once, not for the agent that holds the conversation.\n- answer_delay_s: 15 — voice pickup only (incoming_call, or incoming_message scoped to a voice channel). Ring the human's own devices this long before the agent answers; if they pick up, the agent stands down. 0/absent = answer immediately. Honoured on WhatsApp and Telegram 1:1 — other voice channels have nothing ringing to wait for and still answer at once.\n- auto_join: true|false — voice pickup, GROUP calls only. Whether the bot enters a matching group call on its own (true) or the call becomes a pending invite an operator accepts (false). OMIT THE KEY to defer to the channel setting (channel_account.state.voice_auto_join_policy, default 'approval'); resolution is trigger-when-present, then channel, then approval, so an explicit false beats a channel set to auto. Absent and false are different answers.\n- chat_ids: [\"-5172634473\"] — voice pickup, Telegram GROUP calls only. Scopes the trigger to specific groups; omit for every group call. Any id spelling works (5172634473, -5172634473, -1005172634473 are the same group). A call whose chat is unknown never satisfies it, so do NOT set this together with 1:1 / Twilio / Telnyx / WhatsApp / Android / LiveChat voice channels or the \"voice\" wildcard: those calls have no chat and the trigger would stop answering them.\n\nSupported fields for job_completed (proactive callback when a delegated job finishes):\n- source_agent_id: <int> — fire only when this agent's job completed\n- source_agent_slug: <str> — alternate to source_agent_id\n- job_type: \"agentic_session\" — match a specific job type (default: any)\n- outcome: [\"completed\"] | [\"escalated\"] | [\"completed\",\"escalated\"] — default [\"completed\"]\n- min_duration_seconds: <int> — skip very-short jobs (noise filter)\n- thread_filter: {thread_ids: [<int>...]} — restrict to specific threads\n\nSupported fields for calendar_event (fires N minutes before a Google Calendar event starts):\n- window_minutes_before: <int 1-1440> — REQUIRED, fire when an event starts within this window\n- channel_account_ids: [<int>...] — restrict to specific calendar accounts (default: all)\n- keywords: [\"standup\"] — word-boundary match on event title\n- prepare_meet_join: true — pre-invite pool bots to the event (enables unattended Meet join)\n\nincoming_message action fields:\n- action: \"reply_text\" (default, normal agent run) or \"join_voice\" (deterministically join the voice channel resolved from the message — requires send_mode=auto)\n- message_source: \"real\" (default) | \"transcript\" | \"both\" — real messages vs turns during a live call. Transcripts are turns that address the agent.\n\ncalendar_event run-mode field (incoming_message uses `action` instead):\n- run_mode: \"text\" (default) or \"voice\" (join the meeting — requires send_mode=auto)\n- voice: {speak_first: <bool — greet immediately vs stay silent until addressed>, vision_mode: \"off\"|\"on_demand\"|\"continuous_0_3fps\"} — pairs with action=join_voice (incoming_message) or run_mode=voice (calendar_event)"New value: +"Trigger conditions (JSON). Supported fields for incoming_message:\n- keywords: [\"pricing\",\"demo\"] — message must contain keyword(s) (free, no LLM cost)\n- keyword_match: \"any\" (default, OR) or \"all\" (AND)\n- channel_types: [\"telegram\",\"whatsapp\",\"livechat_voice\",\"twilio_voice\",\"telegram_voice\",\"voice\",...] — filter by channel. For voice, use EITHER the three per-channel keys (scoped) OR \"voice\" alone (wildcard matching all three) — mixing them is redundant. Per-channel keys: \"livechat_voice\" (web widget), \"twilio_voice\" (PSTN inbound), \"telegram_voice\" (Telegram p2p calls)\n- context_types: [\"dm\",\"group\",\"channel\",\"livechat\"] — filter by chat type\n- group_mode: \"mentions_only\" or \"questions\" — for group chats\n- channel_account_ids: [\"123\"] — restrict to specific accounts\n- folder_ids: [5,10] — restrict to threads in folders\n- ai_tag_ids: [1,2] — restrict to threads with AI tags\n- ai_filter_ids: [1,2] — semantic intent filters (message matched via embedding similarity, works in noisy groups)\n- ai_filter_mode: \"any\" (default, OR) or \"all\" (AND) — how multiple AI filters combine\n- ai_filters: [{id: 1}, {name: \"...\", description: \"...\"}] — shorthand: reference existing by id or create inline (calls Voyage embedding API). If a filter with the same name already exists, it is reused by id. Prefer referencing existing filters by id when available. Use ai_filters.create + ai_filters.test for fine-tuning before assigning.\n- template: the reply a rule_based agent sends, with no model run. Either a string (\"Hi {from_name}, we open at 9\") or a card object {text, attachments, buttons} — text is required, attachments is a list of file ids (files.upload), buttons is a list of {label, value|url|web_app} carrying exactly ONE target each: value = a reply the bot receives back, url = opens a link (add track: true to count each tap per conversation, readable as analytics_link_clicks_v in analytics.query), web_app = opens a Mini App over https. The string, and a card's text, substitute {from_name}, {message_text}, {channel_type}, {thread_id}, {raw_data}; button labels and targets are sent verbatim. A card with buttons needs send_mode auto — a draft row cannot carry a keyboard. Buttons need a channel that renders them (telegram_bot). A card needs a chat to land in, so it refuses on webhook, schedule and other thread-less triggers where a string still drafts.\n- handoff: {agent_id, task} — only on a rule_based agent's trigger (refused elsewhere). After the rule's deterministic part has actually happened — the template's message delivered, or the agent's script completed — the named agent runs on the same thread, in its own send mode, exactly as its own trigger would run it: the customer's message reaches it as the incoming message, and `task` reaches it as the handoff brief from this rule. The rule stays instant; the thinking — a reminder, a referral code, a personal follow-up — happens behind it. Script plus handoff is how a workspace does something deterministic the platform has no verb for (file the thread, stamp a tag, push a row) and still lets an agent answer, with the deterministic part living in that agent's own script rather than in platform code. `task` substitutes {channel_type} and {thread_id} only; {message_text}, {from_name} and {raw_data} are refused (the sender would be writing the instruction — the message and its sender already reach the target as the incoming message). The target must be an active agentic or claude_channels agent in this workspace (the engines that read the brief). The target's run is a normal trigger run: it holds the thread lock, its own safety gates apply, and its final answer is delivered like any DM reply — a follow-up that should stay silent must call agent.silence. Nothing runs when the message was drafted, refused or failed, when the script failed, when a safety gate has the rule in draft mode, or when the event carries no thread for the target to answer on. A target paused or deleted after the trigger was written does not stop the rule's message: it goes out, and the reason the follow-up did not start is recorded in the rule's activity row (error field) and in the target's activity as an execution_error.\n- contact_states: [\"active\"] — filter by contact state\n- cooldown_seconds: 30 — min gap between runs per thread\n- max_runs_per_thread_per_hour: 5 — rate limit\n- once_per_thread: true — after this trigger completes on a conversation it steps aside there and the next matching trigger answers later messages. For a rule that files / tags / hands off once, not for the agent that holds the conversation.\n- answer_delay_s: 15 — voice pickup only (incoming_call, or incoming_message scoped to a voice channel). Ring the human's own devices this long before the agent answers; if they pick up, the agent stands down. 0/absent = answer immediately. Honoured on WhatsApp and Telegram 1:1 — other voice channels have nothing ringing to wait for and still answer at once.\n- auto_join: true|false — voice pickup, GROUP calls only. Whether the bot enters a matching group call on its own (true) or the call becomes a pending invite an operator accepts (false). OMIT THE KEY to defer to the channel setting (channel_account.state.voice_auto_join_policy, default 'approval'); resolution is trigger-when-present, then channel, then approval, so an explicit false beats a channel set to auto. Absent and false are different answers.\n- chat_ids: [\"-5172634473\"] — voice pickup, Telegram GROUP calls only. Scopes the trigger to specific groups; omit for every group call. Any id spelling works (5172634473, -5172634473, -1005172634473 are the same group). A call whose chat is unknown never satisfies it, so do NOT set this together with 1:1 / Twilio / Telnyx / WhatsApp / Android / LiveChat voice channels or the \"voice\" wildcard: those calls have no chat and the trigger would stop answering them.\n\nSupported fields for job_completed (proactive callback when a delegated job finishes):\n- source_agent_id: <int> — fire only when this agent's job completed\n- source_agent_slug: <str> — alternate to source_agent_id\n- job_type: \"agentic_session\" — match a specific job type (default: any)\n- outcome: [\"completed\"] | [\"escalated\"] | [\"completed\",\"escalated\"] — default [\"completed\"]\n- min_duration_seconds: <int> — skip very-short jobs (noise filter)\n- thread_filter: {thread_ids: [<int>...]} — restrict to specific threads\n\nSupported fields for calendar_event (fires N minutes before a Google Calendar event starts):\n- window_minutes_before: <int 1-1440> — REQUIRED, fire when an event starts within this window\n- channel_account_ids: [<int>...] — restrict to specific calendar accounts (default: all)\n- keywords: [\"standup\"] — word-boundary match on event title\n- prepare_meet_join: true — pre-invite pool bots to the event (enables unattended Meet join)\n\nincoming_message action fields:\n- action: \"reply_text\" (default, normal agent run) or \"join_voice\" (deterministically join the voice channel resolved from the message — requires send_mode=auto)\n- message_source: \"real\" (default) | \"transcript\" | \"both\" — real messages vs turns during a live call. Transcripts are turns that address the agent.\n\ncalendar_event run-mode field (incoming_message uses `action` instead):\n- run_mode: \"text\" (default) or \"voice\" (join the meeting — requires send_mode=auto)\n- voice: {speak_first: <bool — greet immediately vs stay silent until addressed>, vision_mode: \"off\"|\"on_demand\"|\"continuous_0_3fps\"} — pairs with action=join_voice (incoming_message) or run_mode=voice (calendar_event)"
  2. Changed1 schema field changed
    • addedInput schema / properties / in_workspace
      Added value: +{
      +  "description": "Run this one call in this workspace id instead of the session's. Nothing is stored; other sessions are not affected.",
      +  "type": "integer"
      +}
  3. First observed

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already state that this is a non-read-only, non-destructive, non-idempotent write operation. The description adds useful conceptual context about trigger activation, but it does not disclose permissions, side effects, or creation semantics beyond what the annotations and schema already provide.

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

Conciseness4/5

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

The description is short, front-loaded, and easy to scan. Each sentence is short and purposeful. The trigger-type list is under-inclusive, but the overall structure is appropriately compact.

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

Completeness3/5

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

The schema and annotations carry most of the detail, including full parameter descriptions and safety hints. The description is therefore serviceable, but it is incomplete: the trigger types listed do not match the full trigger_type enum, which could cause an agent to miss supported trigger categories.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema documents all 11 parameters in detail. The description adds brief semantic meaning for four trigger types, but because it omits five enum values and does not supplement other parameters, it does not improve much beyond the schema baseline.

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

Purpose4/5

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

States a specific verb and resource: 'Create a new trigger for an AI agent.' It is clear what the tool does. However, it does not distinguish this tool from sibling trigger tools such as agents_trigger_update or agents_trigger_delete, and its short trigger-type list is incomplete relative to the schema.

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

Usage Guidelines3/5

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

The description implies usage by explaining that triggers determine when an agent activates and by naming trigger types. But it gives no explicit when-to-use guidance, no prerequisites, and no alternatives to this tool versus agents_trigger_update or agents_trigger_delete.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.