Notis Automation Skill
Use this skill whenever the user wants something to happen later, on a schedule, or in response to an event. It covers the three Notis building blocks and how they fit together:
- Skills hold the business logic — the reusable "what to do".
- Automations are the glue: they link a trigger to business logic. They are also how you make Notis do something in the future.
- Reminders are dumb: they deliver a fixed message at a time or on a schedule. No reasoning, no tools, no computed content.
The single most important job of this skill is to pick the right primitive, then build a valid payload for it.
Tool names
These are native Notis tools. When their canonical
names are available in the current tool set, call them directly. Do not send an already-available native automation or reminder tool through
or wrap it in
COMPOSIO_MULTI_EXECUTE_TOOL
; discovery is only for a capability that is not loaded. Always call native tools by their canonical names:
| Area | Canonical tools |
|---|
| Reminders | LOCAL_NOTIS_INSERT_REMINDER
, LOCAL_NOTIS_UPDATE_REMINDER
, LOCAL_NOTIS_LIST_REMINDERS
, LOCAL_NOTIS_DELETE_REMINDER
|
| Automations | LOCAL_NOTIS_INSERT_AUTOMATION
, LOCAL_NOTIS_UPDATE_AUTOMATION
, LOCAL_NOTIS_LIST_AUTOMATIONS
, LOCAL_NOTIS_GET_AUTOMATION
, LOCAL_NOTIS_RUN_AUTOMATION
, LOCAL_NOTIS_LIST_AUTOMATION_RUNS
, LOCAL_NOTIS_GET_AUTOMATION_RUN
, LOCAL_NOTIS_DELETE_AUTOMATION
, LOCAL_NOTIS_LIST_INTEGRATION_TRIGGERS
|
| Skills | , , , LOCAL_NOTIS_INSTALL_SKILL
, LOCAL_NOTIS_DISABLE_SKILL
, |
| Databases (for triggers) | LOCAL_NOTIS_DATABASE_LIST_DATABASES
, LOCAL_NOTIS_DATABASE_GET_DATABASE
|
The paradigm
trigger -> automation -> business logic (often a skill)
time -> reminder -> static message
- A trigger is anything that should start work: a clock (cron), a future moment (one-time), an inbound HTTP call (webhook), an external integration event (new email, new calendar event), or a change to a Notis database record.
- An automation binds a trigger to a that the Notis agent actually runs (a full agent turn). The prompt is the glue, not the place to dump a long procedure.
- A skill is where the real, reusable procedure lives. When the work is non-trivial or will be reused, put the steps in a skill and have the automation's prompt cite that skill (). Keep automation prompts thin; keep logic in skills.
- A reminder is for when there is literally nothing to compute — the user just wants a nudge with fixed text.
Choose the primitive
| The user wants... | Use | Why |
|---|
| A fixed nudge at a time or on a schedule ("remind me to call the dentist at 5pm") | Reminder | No reasoning needed — just deliver the exact text |
| Work to run on a schedule, on an event, or via a webhook ("every Monday summarize last week's deals", "reply when a new Gmail arrives") | Automation | A trigger must run business logic |
| To run a one-off task in the future ("in two hours, draft the recap") | Automation with | "Do something later" that involves work is still an automation |
| A future message with fixed text and no computation ("at 6pm tonight, message me 'leave for the airport'") | Reminder with | Future, but still just a static message |
| The procedure to be reusable across many triggers/threads | A skill (cited by the automation) | Business logic belongs in a skill |
Rules of thumb:
- If the action needs the agent to think, read or write a database, call any tool, fetch anything, or produce computed text → automation, never a reminder.
- "In the future" alone does not mean reminder. A future task with work is a one-time automation; a future fixed message is a one-time reminder.
- If you find yourself writing a long step-by-step procedure inside an automation , stop and move it into a skill, then cite the skill from the prompt.
Before creating anything,
list what already exists (
LOCAL_NOTIS_LIST_REMINDERS
,
LOCAL_NOTIS_LIST_AUTOMATIONS
) so you do not create a duplicate, and confirm the trigger and the action with the user in plain language.
Two rules for writing automation prompts
These two mistakes break automations. Always follow them.
1. Never put the delivery destination in the prompt
Where the automation's response goes is set by the
(and
) field —
not the prompt. The automation's output is delivered to that channel automatically.
- Do not write "send this to me on WhatsApp", "post the summary to Slack", "email me the result", or "reply in this thread" in the prompt.
- The prompt describes only the work and the output to produce. Delivery is configured separately.
Bad prompt: "Summarize yesterday's sales and post it to my Slack."
Good prompt: "Summarize yesterday's sales." (with channel: "slack")
2. Never put scheduling / recurrence wording in the prompt
The schedule lives in the trigger (the cron expression / one-time timestamp). The prompt runs once each time the trigger fires. If the prompt says "every morning", "each Monday", "daily", or "set this up to run…", the agent may interpret it as an instruction to create another automation — causing a recursive loop instead of doing the work.
- Write the prompt as a single, present-tense action to perform right now.
- Leave all timing/frequency to the trigger.
Bad prompt: "Every morning, send me a digest of new emails."
Good prompt: "Compile a digest of emails received since yesterday." (with cron: "0 8 * * *")
Reminders (dumb message delivery)
A reminder stores a static
and delivers it verbatim through a channel — no agent run. Tools:
LOCAL_NOTIS_INSERT_REMINDER
,
LOCAL_NOTIS_UPDATE_REMINDER
,
LOCAL_NOTIS_LIST_REMINDERS
,
LOCAL_NOTIS_DELETE_REMINDER
.
is
(recurring) or
(single future delivery). Cannot be changed after creation.
Fields:
- (required) — the exact text to send (max 5000 chars). Static only. If it needs computation, it is an automation.
- (required) — or .
- (schedule only) — standard 5-field cron. Cannot run more often than once per hour.
- (one_time only) — ISO 8601 with timezone, in the future.
- (optional) — , , , , , , . Defaults to the channel the user is talking on.
- / (optional) — required when the user has more than one account on the target channel. Resolve which account before asking the user for an id.
Recurring reminder:
json
{
"trigger_type": "schedule",
"message": "Stand up and stretch.",
"cron_expression": "0 14 * * 1-5",
"channel": "whatsapp"
}
One-time reminder:
json
{
"trigger_type": "one_time",
"message": "Leave now for the airport.",
"expires_at": "2026-06-19T16:30:00-07:00"
}
Notes:
LOCAL_NOTIS_INSERT_REMINDER
returns the new , the user's , and an asking you to check for duplicates — actually do that check and delete any duplicates.
LOCAL_NOTIS_UPDATE_REMINDER
can change , , (/), and / for the matching type. It cannot change . For schedule reminders, the next run is managed by cron — do not try to set .
LOCAL_NOTIS_DELETE_REMINDER
is a soft delete.
Automations (trigger -> business logic)
An automation runs its
as a real agent turn when its trigger fires. Tools:
| Tool | Purpose |
|---|
LOCAL_NOTIS_INSERT_AUTOMATION
| Create an automation |
LOCAL_NOTIS_UPDATE_AUTOMATION
| Change fields (not ) |
LOCAL_NOTIS_LIST_AUTOMATIONS
| Browse/search existing automations |
LOCAL_NOTIS_GET_AUTOMATION
| Read one automation in full |
LOCAL_NOTIS_RUN_AUTOMATION
| Fire it now (manual / test run) |
LOCAL_NOTIS_LIST_AUTOMATION_RUNS
| See past runs and whether delivery happened |
LOCAL_NOTIS_GET_AUTOMATION_RUN
| Inspect one run |
LOCAL_NOTIS_DELETE_AUTOMATION
| Remove it |
LOCAL_NOTIS_LIST_INTEGRATION_TRIGGERS
| Discover available integration triggers + config schemas (call before building an automation) |
Common
LOCAL_NOTIS_INSERT_AUTOMATION
fields:
- (required) — the instruction the agent runs when the trigger fires (max 5000 chars). Keep it thin, present-tense, single-run; cite a skill for real logic. Follow the two prompt rules above: no delivery destination, no recurrence wording.
- (required) — one of , , , , . Cannot be changed later.
- (optional) — short label.
- / (optional) — where the result is delivered; defaults to the current channel. This is the one and only place delivery is set.
- (optional, default false) — reuses a single pinned thread across runs; starts a fresh thread each run.
- (optional) — (default), , , or .
LOCAL_NOTIS_INSERT_AUTOMATION
returns
, the portal URLs, and — for webhooks — the
. Surface those to the user.
Trigger type: schedule (recurring)
Standard 5-field cron, minimum interval one hour. The recurrence lives here — keep it out of the prompt.
is reserved for one-time automations and must not be set on a recurring schedule. To stop a recurring automation, pause or delete it explicitly.
json
{
"trigger_type": "schedule",
"name": "Weekly deal recap",
"cron_expression": "0 9 * * 1",
"prompt": "Compile last week's closed deals using /weekly-deal-recap and produce the summary.",
"channel": "slack"
}
Cron quick reference:
hourly ·
daily 09:00 ·
Mondays 09:00 ·
weekdays 09:00. Build a concrete expression — never leave the schedule unresolved.
Trigger type: one_time (do something in the future)
A single future run that does real work.
is ISO 8601 with timezone, in the future.
json
{
"trigger_type": "one_time",
"name": "Draft launch recap",
"expires_at": "2026-06-20T18:00:00-07:00",
"prompt": "Draft the launch recap from today's notes."
}
If the future action is just a fixed message, use a one-time reminder instead.
Trigger type: webhook (inbound HTTP)
No trigger config; the tool returns a generated
to POST to. Give that URL to the user.
json
{
"trigger_type": "webhook",
"name": "Lead intake",
"prompt": "A new lead was posted to this webhook. Enrich it with /lead-intake and add a row to the CRM database."
}
Trigger type: integration (connected app events)
Fires on an external event (new Gmail message, new calendar event, PostForMe social post or account changes, etc.).
Always call LOCAL_NOTIS_LIST_INTEGRATION_TRIGGERS
first — it returns providers, connected toolkits, valid
s, each trigger's
, and the user's
s. Never invent a provider, trigger name, or account id; use the exact values it returns. If the toolkit has multiple connected accounts, ask which one. PostForMe supports post created, updated, deleted, publish-result-created, and account-updated events; account-created is intentionally unavailable because integration cards target an existing account.
The trigger catalog is authoritative. Once the event and account are resolved, call
LOCAL_NOTIS_INSERT_AUTOMATION
directly with the returned values.
Do not call between listing triggers and inserting the automation: PostForMe events are provider webhook events, not Composio action tools, and the native insert tool is already known.
json
{
"trigger_type": "integration",
"name": "Auto-file new emails",
"prompt": "A new email arrived. Classify it with /email-triage and file the action items.",
"integration_trigger_config": {
"provider": "composio",
"toolkit": "GMAIL",
"triggers": [
{
"provider": "composio",
"toolkit": "GMAIL",
"triggerName": "GMAIL_NEW_GMAIL_MESSAGE",
"config": { "label": "inbox" },
"connectedAccountId": "ca_xxx"
}
]
}
}
PostForMe example:
json
{
"trigger_type": "integration",
"name": "Notify on new LinkedIn posts",
"prompt": "Summarize the new social post in one sentence.",
"channel": "manager",
"integration_trigger_config": {
"provider": "postforme",
"toolkit": "LINKEDIN",
"triggers": [
{
"provider": "postforme",
"toolkit": "LINKEDIN",
"triggerName": "social.post.created",
"connectedAccountId": "spc_xxx",
"config": {}
}
]
}
}
Trigger type: database (Notis record change)
Fires when records in a native Notis database are added or changed. Use
LOCAL_NOTIS_DATABASE_LIST_DATABASES
and
LOCAL_NOTIS_DATABASE_GET_DATABASE
(see the
skill) to resolve the real
and the exact
s before building the config — never guess them.
The config is
, where
is a condition tree. Each condition's
is one of
(record inserted),
(any property changed), or
(a specific property changed, requires
+
). Comparators depend on the property kind (e.g.
,
,
,
,
).
needs
+
; value-based comparators need
.
json
{
"trigger_type": "database",
"name": "Notify on task done",
"prompt": "A task was just marked Done. Run /task-followup to add a note and check for follow-ups.",
"database_trigger_config": {
"database_id": "tasks-db-id",
"root": {
"kind": "group",
"operator": "and",
"children": [
{
"kind": "condition",
"event": "property_edited",
"property_id": "prop_status",
"comparator": "changed_from_to",
"from_value": "In Progress",
"to_value": "Done"
}
]
}
}
}
Running, verifying, updating
LOCAL_NOTIS_RUN_AUTOMATION
fires immediately (good for a test) and returns a .
LOCAL_NOTIS_LIST_AUTOMATION_RUNS
shows whether each run produced a delivered message () — use it to confirm an automation actually works.
LOCAL_NOTIS_UPDATE_AUTOMATION
changes any field except ; set to / to disable/enable. Automations synced from a team template ( present) lock and — tell the user to duplicate it to edit.
The skill-as-business-logic pattern
This is the core of the paradigm: put logic in a skill, point an automation at it.
Creating the skill: use . Whenever the business logic needs to live in a new (or updated) skill, follow the
skill — it is the source of truth for the authoring workflow: defining the
/
, structuring
(and optional
/
/
), validating the frontmatter, and saving directly into Notis with
(
,
, and
or
). Do not hand-roll skill creation here; defer to
for the details, then come back and wire the automation to it.
Worked example — "Every Monday, summarize last week's closed deals and post to Slack":
-
Logic → skill. If no skill covers it, author one by following
and saving it with
. The skill
holds the real procedure: which database to query, how to filter to last week's closed deals, and the summary format.
-
Trigger + delivery → automation. Create a
automation whose
cites the skill, and set the delivery channel on the
field — not in the prompt:
json
{
"trigger_type": "schedule",
"name": "Weekly deal recap",
"cron_expression": "0 9 * * 1",
"prompt": "Run /weekly-deal-recap for last week and produce the summary.",
"channel": "slack",
"channel_account_id": "channel_slack:acme#T123"
}
The cron carries the "every Monday"; the channel carries "to Slack". The prompt carries neither.
-
When the trigger fires, Notis injects the cited skill's full
as the workflow and executes it, then delivers the output to the configured channel. The automation stayed thin; the logic stayed reusable.
Use the same pattern for webhook, integration, and database automations: the trigger differs, but the
should still hand off to a skill for any non-trivial work. Reach for an inline prompt only when the action is a single, self-evident instruction.
House rules
- Plain language to the user. Talk about "a reminder", "a weekly automation", "the Slack channel", "the Tasks database" — not tool names, values, or raw JSON. Build and validate the payloads internally.
- Delivery is the channel, never the prompt. Set where output goes via /. Keep "send to…", "post to…", "email me…", "reply in thread" out of the automation .
- No recurrence wording in the prompt. The schedule lives in the trigger. A prompt that says "every morning" or "set up a daily…" risks the agent creating another automation instead of doing the work. Write the prompt as one present-tense action.
- Discover before you ask. Resolve picker-backed values yourself before asking the user: channel account (when multiple), integration toolkit/trigger/connected account (
LOCAL_NOTIS_LIST_INTEGRATION_TRIGGERS
), and database id + property ids (LOCAL_NOTIS_DATABASE_LIST_DATABASES
/ LOCAL_NOTIS_DATABASE_GET_DATABASE
). One match → confirm; several → offer the choices; none → ask or defer.
- Never invent identifiers. Integration providers, s, s, s, and s must come from discovery, not memory.
- Resolve the schedule. A schedule trigger needs a concrete cron expression; a one-time trigger needs a real future timestamp with timezone. Do not create a scheduled item with the timing unresolved.
- Dedupe. List existing reminders/automations first and remove duplicates rather than stacking near-identical ones.
- Confirm, then create. Recap the trigger and the action in one short plain-language line, get a yes, create it, then surface the portal URL (and webhook URL, if any).
- Right primitive. Static message → reminder. Work on a trigger → automation. Reusable logic → skill cited by the automation. When in doubt between a one-time reminder and a one-time automation, ask whether the future action is fixed text or actual work.