triggers
Create and manage condition-based Manus automations using provider events, webhooks, or scheduled JavaScript monitoring. Also use to inspect executions and debug saved script Triggers. For reminders o
SKILL.mdskills/triggers/SKILL.md
GitHubTriggers
Prefer a discovered event with filters. Consider a scheduled script only when the event catalog cannot express the requested condition—not to bypass unavailable resources, missing authorization, or validation errors. Scripts cannot receive webhook or mail input. Do not monitor by polling in an Agent loop; a recurring ScheduleTask that asks an Agent to check a condition is such a loop. When neither an event nor an approved script can express the condition, report the limitation. Never edit connector configuration or account authorization to make a Trigger succeed; report the authorization failure instead. Call Trigger tools only as native MCP tool calls; manus-mcp-cli in the terminal cannot authorize them.
When talking to the user, describe what the Trigger does: an event trigger (runs when a connected service reports an event), a webhook trigger, or a scheduled script trigger. Tool field names such as fixed, script, entries, and bindings are for tool calls only; do not use them or internal service names in replies.
Discover and configure an event
- Call
triggers.list_eventswith a focusedquery(one string or up to 10 OR terms). It returns a compact, ranked index; source and event matches come first, and events matched only through settings or filter fields listmatched_fields(ormatched_field_countwhen capped). Search is local and case-insensitive; broaden or remove the query before concluding that an event is unsupported.omitted_eventsmeans the index was capped: narrow the query rather than treating the missing events as absent. The same broaden-first rule applies totriggers.list_data_apis. - Call
triggers.list_eventsagain with the chosensourceandevent_typeto get its full definition, then readsettings,filter_fields, and availability. Each filter field names anoperator_set; look it up inoperator_setsfor the operators,operand_kind, andvalue_schema. If the definition is too large it arrives as an outline, withvalues_countinstead ofvalues; call again withfield_keysnaming the settings and filter fields you need to read them in full. An outline still means the event is supported. These live definitions govern supported fields, operators, operands, and polling cadence; do not invent a local catalog. - Resolve required settings using
triggers.list_event_options. Pass the setting or filter field's key and declared dependencies, using setting keys such asaccount_uid, not dotted paths. Select stable option values, then place settings at their declaredvalue_path. Acquisition settings belong inparams/bindings; business conditions belong infilter. - Refresh discovery after selecting resources that determine available fields. For Google Forms, request the exact source/event with
dependencies: { account_uid, form_uid }before using the returned question fields. Discard stale options and pagination tokens when dependencies change.
Follow option pagination. For Slack channel_uid, instead supply a non-empty query and omit page_token: the tool searches every page itself. A timeout or overly broad search is an error, not an empty result. is_member says whether the user has joined the channel; channel-scoped events require it. Options with unavailable_code are listed for guidance but must not be selected: provider_reauthentication_required means the account or workspace needs to be reconnected in Manus (for example an expired token that can no longer refresh) before it can be used. Tell the user which account to reconnect; do not silently pick another resource.
Combine binding.connector.* settings into one binding; omit account/resource selections not exposed by discovery. For mailbox values such as mail_user:42, split at the first colon into binding.mailbox = { kind, mailbox_uid }.
Filters
filter.groups[] OR between groups
.conditions[] AND within a group
{ field_key, operator, value?, case_sensitive? }
Use only advertised operators and their operand_kind / value_schema. Omit value for operand-free operators, preserve exact decimal strings, and set case_sensitive only when supported. Missing or incomplete values are unknown, including under negation; they are not explicitly empty values.
Omit the filter to accept every event. Groups cannot be empty, nested, or negated. Use one entry per listening identity; represent alternative conditions with OR groups rather than duplicate listeners. Multiple entries are also OR—not cross-event AND or event-order correlation.
Create
Use triggers.create_trigger for event-based entries. If a script fallback is needed, explain the event limitation and propose what the script would monitor and how often. Ask the user to approve that alternative and wait for explicit approval before starting script creation; a general monitoring request is not consent to use a script. Once approved, use triggers.create_script_trigger with one schedule. If the user explicitly asks for a script but a discovered event can express the condition, explain the event option and let the user choose.
Both tools create an enabled Trigger immediately; there is no draft or pre-create test.
- Supply a concise
titleand an actionableinstructionfor the receiving Agent, including context needed in a new session. Place{{payload}}where the event data should appear; without it the data follows the instruction. Event triggers supply the event's data; script triggers supply the payload they return. The receiving Agent sees that data as untrusted content, not instructions. Keep the user's wording; tell the user about any text you add to it. - Generate one
create_request_uidper intended configuration. Reuse it only for retries of that same configuration, including uncertain outcomes. - Omit
targetfor the current session. Select another destination and connector accounts only from verified user context. - For each fixed entry, send its discovered
sourceandevent_type; omitentry_uidfor new entries. Provider polling uses the catalog cadence, not a user-supplied schedule. - Return the service-confirmed resource link and state. Distinguish an enabled definition from a source that is pending synchronization or credential setup.
Schedules
Use triggers.preview_schedule before creating or replacing a timed entry. Choose exactly one schedule branch: interval, cron, or once. Use decimal-string milliseconds, IANA timezones, and timestamps with explicit offsets.
Recurring schedules on event triggers require at least 10 minutes; script triggers require at least 15 minutes on free plans or 5 minutes on paid plans. Once schedules have no recurring minimum. Preview checks only the most permissive (5-minute) minimum, so creation or update can still fail the mode- and plan-specific check.
Webhooks
Use source: "webhook" with an event_type discovered through triggers.list_events, without a binding or schedule. The event type belongs to the configuration; senders do not add it to HTTP payloads. Filter only on fields exposed by discovery.
Events that receive requests get a webhook URL: omit webhook_suffix for new entries (the tool generates it) and preserve it when updating existing entries. webhook.retrieve_poll polls a JSON URL instead and never has a webhook URL or webhook_suffix; an existing entry cannot switch between polling and receiving. Bearer credentials and auto_confirm are managed in Manus, never tool inputs or instruction content. If authentication is required but no credential is configured, direct the user to the Triggers page in Manus.
Scripts
Pass the script in the code argument of a native MCP tool call even when it is long, not through a file.
Before authoring a script, read Connector runtime: its Script runtime section is the complete ctx contract (KV, Data APIs, AI, connectors, return value, limits). Use only the APIs it documents—do not guess names such as ctx.data_api. The script is an async function body receiving ctx; return { payload: string } to trigger, otherwise null/undefined. Keep state idempotent and bound external reads, pagination, KV, and payload size.
triggers.dry_run_script accepts a saved trigger_uid only. It neither injects the instruction nor advances production KV, but can perform real external operations and consumes Data API budgets. Inspect the saved code and confirm authorization for those effects before running it. Dry runs are limited to 6 per user per minute, and a dry run waits only about 50 seconds: a timeout (code deadline_exceeded) means the script is too slow to dry-run, not that it failed, so do not retry it; check the first real execution with triggers.get_execution instead. Dry runs are not a creation gate, but for a read-only script that finishes quickly run one after creation and fix any failure before reporting the Trigger as working.
Manage existing Triggers
- Find: Paginate
triggers.list_triggers. Results are summaries, not update templates. - Edit: Read
triggers.get_trigger, then send the complete configuration totriggers.update_triggerwith the exact decimal-stringexpected_revision. This is full replacement: preserve unrelated fields, title, existingentry_uidvalues, and webhook suffixes. Omitted entries are deleted; mode cannot change. Exclude read-only entry display data. - Pause, resume, or delete: Use
triggers.set_trigger_enabledortriggers.delete_triggerfor the user's requested operation with the current revision. Re-enabling rechecks source/target/resource authorization and the enabled-trigger limit; re-enabling a disabled script trigger also rechecks its recurring schedule against the minimum gap of the current plan (for example after a downgrade), so update the schedule if that fails. Re-enabling aonceschedule whose time has passed does not run it again; updatefire_atto a future time instead. - Enabled-trigger limit: When creating or re-enabling fails on the enabled-trigger limit, report the limit and let the user choose which Trigger to disable, delete, or merge. Never disable, delete, update, or merge another Trigger to make room unless the user explicitly chose that change, even one the user mentioned or one that watches the same resource.
- Inspect: Use
triggers.list_executionsandtriggers.get_executionfor history and attachment links; do not poll history or expect raw event bodies.
On a revision conflict, re-read and apply the user's change to the latest configuration. For validation errors, use field_errors to locate the invalid field. A field_errors code provider_reauthentication_required means the selected account or workspace must be reconnected by the user; an entry paused with last_error_code provider_reauthentication_required resumes only after reconnecting and then disabling and re-enabling the Trigger. Report authorization or source-confirmation failures as such; do not blindly retry, switch accounts, or switch to a script.
Debug a failed script
triggers.get_execution reports status, error_code, and a bounded error_message (exception name and message). Codes:
error_code |
Meaning |
|---|---|
script_failed |
Uncaught error or non-zero exit (including process.exit(1)); error_message names the exception. |
script_timeout |
The run exceeded its time limit. A dry run cannot reproduce it; reduce the work per run (smaller pages, batches carried in KV). |
invalid_return |
The value was not null/undefined/{ payload: string }, the script wrote to stdout, or it called process.exit(0) before returning. |
runtime_unreachable |
No result from the execution runtime; usually transient. |
console.* output is not stored. A failed dry run returns only the first 2 KiB of stderr—console output first, the stack last—so when error_message is insufficient, reproduce with one dry run and keep diagnostic logging short. Correct the saved code with one triggers.update_trigger, then dry-run again; do not iterate edits on a live Trigger without telling the user.
Debug a paused or silent event entry
When an event Trigger does not fire, read triggers.get_trigger first: each entry reports runtime_status and last_error_code, and triggers.list_executions with the entry_uid shows the failed run (failed_stage, error_code, error_message). An entry in needs_attention stops polling and does not resume on its own, even after the cause is fixed: the user must disable and re-enable the Trigger (or change its listening scope), which starts from a new baseline and does not deliver events from the paused period. Tell the user this when reporting a fix.
- Run
triggers.dry_run_entry({trigger_uid, entry_uid})to reproduce the next scheduled check. It supports only connected-account polling entries: Gmail, Google Calendar, Google Workspace, Outlook Mail/Calendar, Shopify, Meta Ads, Instagram, Google Ads, GitHub and Notion events withpoll_interval_seconds > 0inlist_events. RSS, webhook entries (includingwebhook.retrieve_poll), Slack, X and push events are rejected withfailed_precondition; for those, readerror_messagefromtriggers.list_executions/triggers.get_executionor wait for the next real execution. It reads from where that check would start and applies the current filter; a provider failure returnserroras<error_code>: <detail>, and matches return the payload a real run would deliver. It makes real provider reads but never advances the entry, delivers, records an execution, or clearsneeds_attention. - Entry dry runs share the 6-per-minute limit with
triggers.dry_run_script. A dry run waits only about 50 seconds; a timeout (codedeadline_exceeded) means the read (for example a large Notion data source scan) is too slow to dry-run and the entry was not changed. It is not a failure: do not retry it; inspecterror_messageintriggers.list_executions/triggers.get_executionor wait for the next real execution instead. - Prefer a dry run over writing test rows into the watched resource. Do not add test data to shared or team-owned resources without the user's agreement, and remove any test data you did add.
provider_response_invalidmeans the provider returned something the reader does not accept; the detail names the failed check (for example a property or row). Report it with the trigger and entry UIDs as a product issue; do not retry it or switch accounts.triggers.update_triggerand re-enabling can return an entry toreadywithout the cause being fixed. Confirm a fix withtriggers.dry_run_entryor the next real execution before reporting that the error is resolved.