Modem
Server Details
Search customer feedback, topics, people and companies in Modem, and run the Modem Agent.
The last two health checks of this connector failed. If this server requires authentication, missing or expired test credentials may be the cause. A test profile lets Glama authenticate for health checks and discover tools; it is separate from your personal connections.
If you are the author, claim ownership, then add or update a test profile under Admin → Test Profile.
- Status
- Unhealthy
- Uptime
- 88.8% over 63 days
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- ChatGPT
- –
- Claude
- Modem
TDQS
Scored across 20 tools
Each tool has a clearly distinct action and resource: company/person/topic create-update-merge operations, automation lifecycle, agent-run operations, docs, skills, and feedback are all separated. Similar-looking pairs such as update_topic vs. bulk_update_topics and modem_agent_invoke vs. modem_agent_send_message are explicitly differentiated by their descriptions.
The tool set is consistently snake_case and mostly follows verb_resource naming, with clear domain groupings for companies, people, topics, automations, and agent runs. Minor deviations include noun-only names like modem_docs and modem_skills, the modem_agent_ prefix, and the relational add_people_to_company.
Twenty tools is slightly above the typical well-scoped range, but the server covers several distinct domains: CRM-like companies and people, topics, automations, agent runs, docs/skills, and feedback. Each category has a small number of purposeful tools, with no obvious redundant entries.
The surface covers writes and merges for companies, people, and topics, plus automation lifecycle and agent-run operations, but it lacks direct list/get/delete operations for several core entities and has no create_people tool. The modem_agent_invoke tool provides a broad query fallback, but the direct CRUD/lifecycle coverage remains noticeably incomplete.
Available Tools
20 toolsadd_people_to_companyAdd People to CompanyBIdempotentInspect
Associate one or more people with a company. Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| companyId | Yes | ||
| personIds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false, idempotentHint=true, and destructiveHint=false, so the description doesn't need to restate safety. However, the description adds no behavioral context beyond the hint to read the skill, which is not about tool behavior. For a mutation tool, it could disclose idempotency implications or error cases, but it doesn't, so it falls short of the higher bar.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that states the core purpose, followed by a direct instruction to read a skill. It's concise and front-loaded with the primary action, with no unnecessary fluff, but it could be clearer about the skill's role.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 params, no output schema, no nested objects), so the description covers the basic action and points to a skill for further details, which is adequate. However, it doesn't clarify what happens after the call (e.g., whether it returns anything) or any side effects, and given the instruction to read a skill, it somewhat relies on external context, making it minimally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, meaning it only provides types and patterns but no semantic meaning. The description explicitly mentions 'one or more people' and 'a company', which clarifies that personIds is an array (at least one) and companyId is a single ID, adding value beyond the schema. It doesn't explain the ID format, but the patterns are self-explanatory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Associate' and the resource 'one or more people with a company', which aligns with the tool name and title. It is distinct from siblings like merge_companies or update_people, though it doesn't explicitly name them, making it clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions 'Before your first call, read the skill: modem_skills(...)', which implies a prerequisite for using the tool, giving some usage guidance. However, it doesn't provide explicit when-to-use or when-not-to-use conditions, nor does it contrast with alternative tools like merge_people or update_companies, so it's only minimally helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bulk_update_topicsBulk Update TopicsADestructiveIdempotentInspect
Update multiple topics at once (e.g. archive or re-prioritize a set of topics). Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| archived | No | Set to true to archive topics, false to unarchive them. | |
| priority | No | Update all topics to this priority. Valid values: very_low, low, default, high, very_high. | |
| topicIds | Yes | ||
| archivedReason | No | Optional reason for archiving. Only used when archived=true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered without the description. The description adds the meaningful pre-call skill requirement and the operation types, but says nothing about partial-failure behavior when updating up to 100 topics, which matters for a destructive bulk write.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero waste, with the operation scope front-loaded before the prerequisite. Nothing is repeated from the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive bulk mutation with no output schema, the description covers scope, examples, and a mandatory prerequisite. The remaining gap is outcome behavior (all-or-nothing vs partial success across up to 100 topics), which is useful but not strictly required to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75% with per-field descriptions for archived, priority, and archivedReason; only topicIds lacks a description but its uuid pattern and min/maxItems are self-documenting. The description adds no parameter detail beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Update multiple topics at once" states a specific verb (update) and resource (topics) with bulk scope plus concrete examples (archive, re-prioritize). It implicitly contrasts with the single-item update_topic sibling through "multiple topics," but never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical examples give clear usage context, and the description states an explicit precondition (read the write-tools skill before the first call). It stops short of saying when to prefer update_topic versus this bulk variant, so the routing between siblings is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_automationCreate AutomationAInspect
Create an automation. Useful for reminders, follow-ups, periodic tasks, or event-driven workflows per user. Returns the full automation object including computed nextRunAt.
Schedule field accepts 5 formats:
{type: "at", at: "<ISO 8601>"} - one-time execution (must be future)
{type: "every", unit: "minutes"|"hours", n: } - recurring interval (min 30 min)
{type: "cron", expr: ""} - cron schedule (min 30 min between runs)
{type: "rrule", rrule: ""} - iCalendar rule (min 30 min between occurrences)
{type: "event", events: ["", ...]} - event-driven (triggers immediately on ANY of the listed events, up to 20; each occurrence fires one run carrying just that event's payload). {type: "event", event: ""} (single string field) is a legacy alias for a one-event array and is still accepted, but "events" is canonical for new automations. GitHub PR triggers may also include {targetBranches: ["main", ...]} to run only when the PR's target branch matches one of those case-sensitive names or * patterns (e.g. "release/*").
matches zero or more characters, including slashes. Omit it to match every target branch. An activity event shares its schedule only with other conversation activity events (chat.activity, call.activity, support_ticket.activity, feedback.activity, social_post.activity); pull_request.activity and issue.activity stand alone. An activity schedule may add {filter: ""} to run only for matching events, e.g. "source.name in ['zendesk', 'intercom'] && author.role == 'customer'". On several conversation events it may name only source.name, placement, author.role and topic.priority_change. The filter field's schema lists the grammar and each event's fields. Optionally add {delaySeconds: <int 1..604800>} to an event schedule to defer the run until N seconds after the trigger event fires (e.g. 1800 = 30 minutes later; max 604800 = 7 days). Omit for immediate execution. A delayed run is cancelled if the automation is disabled during the wait. Optionally add {condition: "<natural language, up to 2000 chars>"} to run only for events that satisfy it (e.g. "the customer is on the Enterprise plan"); Modem checks it against each event's payload before running. A filter or condition also satisfies an event that requires a channel or product scope. conditionMode and conditionSchemaVersion are set by Modem and ignored on input.
Available events: github.pr.created, github.pr.merged, github.pr.dismissed, github.issue.closed, gitlab.mr.created, gitlab.mr.merged, gitlab.mr.closed, topic.created, topic.priority.high, stripe.customer.created, stripe.subscription.created, stripe.subscription.canceled, stripe.subscription.trial_ending, stripe.invoice.payment_failed, sentry.feedback.created, feedback.created, topic.group.added, topic.group.updated, chat.activity, call.activity, support_ticket.activity, feedback.activity, social_post.activity, pull_request.activity, issue.activity
Prompt guidelines: must be self-contained with ALL context the executing agent needs. Write in plain language. Structure as a clear plan with steps. Include external service IDs (Slack channel/user IDs). Never include database internals.
MODEL LEVEL GUIDELINES: Pick the model level that best matches the automation's complexity. Do NOT default to "high".
"low" (Fast): Lookup/linking tasks, simple data retrieval, pattern matching, forwarding/routing. Examples: linking PRs to topics, tagging items with keywords, posting simple notifications, checking statuses.
"med" (Balanced): Summaries of structured data, daily digests, status rollups, template-based reports. Examples: daily standup summaries, weekly metric rollups, changelog digests, review request roundups.
"high" (Smart): Complex analysis, nuanced writing, multi-step reasoning, customer-facing content, creative tasks. Examples: user health analysis, strategic recommendations, personalized outreach, complex triage decisions. When in doubt, use "med" (Balanced).
timezone is required and must be an IANA time zone such as America/New_York. You become its owner. The automation's dashboard page is https://app.modem.dev/<org-slug>/automations/<id>. Before your first call, read the skill: modem_skills({ name: "automations" }).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Human-friendly name for the workflow run, e.g. "weekly_summary_for_alex" | |
| prompt | No | Natural language instructions for what the automation should do. Required unless outcome is a webhook. | |
| enabled | No | Whether the automation should be enabled to run on its schedule. | |
| outcome | No | What the automation does when it fires. Omit for the default: run the Modem agent with the prompt. {type: "webhook", url} POSTs the trigger event to the URL instead of running the agent; the prompt, model level, capabilities and output channels are then unused. The signing secret receivers verify deliveries with is shown on the automation's page in the Modem dashboard; the API never returns it. | |
| schedule | Yes | Defines when an automation should run. | |
| timezone | Yes | ||
| modelLevel | No | Model level: "low" (Fast), "med" (Balanced), or "high" (Smart). | |
| capabilityMode | No | Capability mode: "all" (all visible capabilities, including ones added later) or "custom" (only listed capabilities). If omitted on create, defaults to "custom" with a snapshot of every currently-available capability so the automation does not silently inherit future integrations. | |
| outputChannels | No | Allowed output channels and optional destination restrictions. | |
| allowedCapabilities | No | Capability keys to enable when capabilityMode is "custom". On create, providing this field implies custom mode when capabilityMode is omitted. An empty array means core-only. | |
| sourceDefaultTaskSlug | No | Template-library default task slug this automation is being created from, if any. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare this is a non-readonly, non-destructive, non-idempotent write. The description adds real value beyond that: it notes you become the owner, timezone is required as an IANA zone, the dashboard URL is available, and the skill should be read before first use. Return shape is disclosed. Not exhaustive on side effects or webhook signing persistence, but strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but front-loaded and organized into logical blocks (schedule formats, prompt guidelines, model level guidelines, timezone). Almost every sentence carries operative detail for a genuinely complex tool. It borders on verbose but earns most of its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter, high-complexity creation tool with no output schema, the description covers the tricky parts (schedule variants, model levels, prompt guidance, return value). Some parameters (outcome/webhook, outputChannels, capabilityMode, allowedCapabilities) are left to the 91%-covered schema, which is reasonable, so completeness is strong but not total.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 91%, yet the description still adds substantial meaning: the five schedule formats with constraints (min 30 min cadence, at must be future, event lists up to 20), the legacy event alias vs canonical events, delaySeconds semantics, condition filtering, and model-level selection heuristics. This is well beyond restating schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ("Create an automation"), enumerates concrete use cases (reminders, follow-ups, periodic tasks, event-driven workflows), and states the return value (full automation object including nextRunAt). It is clearly distinguishable from siblings like update_automation and list_automations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives rich guidance on how to choose schedule types, model level tiers (with examples of low/med/high), and a prerequisite to read the automations skill before the first call. It does not explicitly contrast create vs update_automation, but the context for correct invocation is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_companiesCreate CompaniesCInspect
Create one or more companies in the organization. Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| companies | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false, and the description does not contradict them. The description adds the bulk-creation trait and a required skill precondition, but does not discuss duplicate behavior, permissions, or side effects. This is modest context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with the core action front-loaded and the skill prerequisite placed second. There is no filler or redundant restatement of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no output schema and one parameter with zero schema descriptions, so the description needed to carry more weight. It omits parameter semantics, error or duplicate handling, and any distinction from update/merge siblings. The skill link is helpful but does not fill these gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description adds no meaning for the 'name' or 'domain' fields, including format, uniqueness, or validation. The phrase 'one or more companies' merely restates what the schema already encodes via minItems/maxItems. No parameter semantics are conveyed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Create one or more companies in the organization.' The phrase 'one or more' clarifies bulk capability. It does not explicitly contrast with update_companies or merge_companies, but the create verb inherently distinguishes them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives like update_companies or merge_companies. The instruction to read the write-tools skill is a prerequisite, not a tool-selection guideline. The agent is left to infer when creation is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_feedback_channelCreate Feedback ChannelAInspect
Create a feedback channel for one app and return its feedback token. Send name (the app’s name) and allowedOrigins (every browser origin the app is served from, such as https://app.example.com and http://localhost:3000; omit for an app that does not run in a browser). The channel is created in the organization’s default project. The returned token is shown only in this response, so write it where the app reads it before you do anything else. The token is safe to ship in a browser bundle or a binary: it is valid only for sending feedback to this channel and cannot read anything. Requires an organization admin. Before your first call, read the skill: modem_skills({ name: "install-feedback" }).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| allowedOrigins | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover mutation/idempotency safety, but the description adds crucial non-obvious behavior: the token is shown only in this response (must be persisted immediately), it is write-only for sending feedback, safe to embed in bundles/binaries, and creation targets the org's default project. These are exactly the traits an agent cannot infer from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly five sentences, front-loaded with the action and return value, then parameters, then the critical write-it-down warning and auth/skill prerequisites. No filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter creation tool with no output schema, the description covers the return value (token), its one-time visibility, its security properties, the project scope, and the auth requirement — everything needed to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description fully compensates: `name` is defined as the app's name, and `allowedOrigins` is defined as every browser origin with concrete format examples and an explicit omission rule for non-browser apps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+scope ('Create a feedback channel for one app and return its feedback token'), making it clearly distinguishable from the sibling send_feedback which presumably posts feedback rather than creating a channel.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives strong context: requires an organization admin, instructs reading the `install-feedback` skill before the first call, and explains when to omit allowedOrigins (non-browser apps). It does not explicitly contrast with alternatives like send_feedback, but the prerequisite and gating guidance is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_automationsList AutomationsARead-onlyIdempotentInspect
List every automation in the organization with its schedule, enabled flag, model level, output channels, creator, and a summary of its recent runs. Call it before create_automation to avoid creating a duplicate, and to find the automationId that update_automation needs. Send userId to list only the automations that user created. Before your first call, read the skill: modem_skills({ name: "automations" }).
| Name | Required | Description | Default |
|---|---|---|---|
| userId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds valuable context beyond them: org-wide scope, filter semantics for userId, and the prerequisite skill step before first invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what the tool returns, then routes to related tools, then explains the filter, then the skill prerequisite. Three tight sentences with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-param read tool with no output schema, it covers return fields, filtering, sibling-tool relationships, and a prerequisite. Adequate and complete for invocation; only the default sort/limit behavior is unstated, which is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry parameter meaning. It explains what userId does ('list only the automations that user created'), which meaningfully compensates, though the param is optional and no format details are given.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('List every automation') and enumerates the returned fields (schedule, enabled flag, model level, output channels, creator, recent runs), which distinguishes it from sibling write tools like create_automation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to call it: before create_automation to avoid duplicates, and to obtain the automationId needed by update_automation. It also names the userId filter behavior and a required skill read before first call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_companiesMerge CompaniesADestructiveInspect
Merge one or more source companies into a target company. Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| targetCompanyId | Yes | ||
| sourceCompanyIds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry destructiveHint=true and readOnlyHint=false, and the description does not contradict them. It adds no details about whether source companies are deleted, reversibility, or permissions; the only addition is the prerequisite to read the write-tools skill, which is useful but not a disclosure of merge behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with the core operation front-loaded and a single actionable prerequisite following. No filler or redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive multi-source merge with no output schema, the description alone lacks the consequences of merging, but it explicitly directs the agent to read the write-tools skill before first use. That reference makes the definition actionable and fairly complete in context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must carry the semantic load, and it does convey which parameter is the target and which are sources, plus 'one or more' cardinality. However, it adds little beyond the property names and minItems in the schema, and does not elaborate on ID formats or parameter-specific constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the action ('Merge'), the object ('companies'), and the relationship ('source companies into a target company'). This is specific enough to distinguish it from sibling tools like merge_people and merge_topics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear operation and a prerequisite (read the write-tools skill), but it does not explicitly say when to use this over merge_people/update_companies or what conditions exclude it. The skill reference is a procedural instruction, not a usage-alternative explanation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_peopleMerge PeopleBDestructiveInspect
Merge one or more source people into a target person. Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| targetPersonId | Yes | ||
| sourcePersonIds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true and readOnlyHint=false. The description does not add behavioral specifics beyond the annotation, such as whether source people are deleted, whether the merge is reversible, or what side effects occur on related data. It simply restates the merging action without enriching the agent's understanding of what gets destroyed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is delivered in one clear sentence, followed by a concise prerequisite instruction. There is no redundancy or filler; every sentence earns its place. The core behavior is front-loaded before the skill instruction.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation tool with no output schema and minimal parameter descriptions, the description should clarify side effects, return behavior, and any constraints. It only provides the merge concept and a skill reference. An agent would still need to inspect the skill or infer critical details about what happens to source records.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry semantic weight. It does clarify the roles of 'source' and 'target' and notes 'one or more' source people, which aligns with sourcePersonIds' minItems: 1. However, it does not explain ID formats, uniqueness expectations, or what happens if a source person equals the target person. Basic semantics are present but not comprehensive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Merge'), a clear resource ('people'), and the relationship between source and target persons: 'Merge one or more source people into a target person.' This clearly differentiates it from sibling tools like merge_companies and merge_topics by resource type.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a prerequisite for first use ('read the skill: modem_skills(...)') but does not explicitly state when to use this tool versus alternatives such as merge_companies, merge_topics, or update_people. Usage is only implied by the tool name and resource type. There are no exclusions or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_topicsMerge TopicsADestructiveInspect
Merge one or more source topics into a target topic. Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| targetTopicId | Yes | ID of the topic to merge into. Must not be in the sourceTopicIds array. | |
| sourceTopicIds | Yes | IDs of topics to merge into the target. Must not include the target topic ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, and openWorldHint=false, so the bar is lower. The description adds the skill-reading prerequisite, which is real context, but it never says what happens to the source topics (deleted? archived?) — the single most important behavioral fact for a destructive merge.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the core action front-loaded and the prerequisite trailing. Nothing extraneous.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent operation the description omits the post-merge state of the source topics and any irreversibility warning. With annotations and a fully described schema covering much of the surface, this is adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters document the target-not-in-sources constraint themselves. The description adds no format, ordering, or limit details beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (merge) and resource (topics), including the direction of the merge (sources into target). It does not differentiate from siblings like update_topic or bulk_update_topics, but the operation itself is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Adds a concrete prerequisite: read the write-tools skill before the first call. It gives no guidance on when to merge versus use update_topic or bulk_update_topics, and no exclusions, so usage is only partly covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modem_agent_cancel_runCancel Agent RunADestructiveIdempotentInspect
Cooperatively cancel one exact durable Modem agent run. Completed external actions are not reversed.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | Run ID returned by modem_agent_invoke or modem_agent_send_message. | |
| conversation_id | Yes | Conversation ID returned by modem_agent_invoke. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond annotations with 'cooperatively' and especially 'completed external actions are not reversed,' which is critical for an agent deciding whether to cancel. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded action, no redundancy. The key caveat is included.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Definitions clear with both params documented, plus the critical non-reversal caveat. Missing only explicit routing to siblings and return expectations, which are not essential for a destructive cancel action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers both parameters with clear descriptions (IDs returned by modem_agent_invoke). Description adds no new parameter-level meaning beyond 'exact' run targeting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('cancel') and identifies the exact target ('one exact durable Modem agent run'). It is clearly distinguished from sibling tools like modem_agent_get_run or modem_agent_invoke.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives, no prerequisites or conditions for cancellation, and no mention of what to check before invoking. The caveat about external actions is behavioral, not usage routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modem_agent_get_runGet Agent RunARead-onlyIdempotentInspect
Get the status and result of a Modem agent run. Pass wait_seconds: 25 to wait for the run: the call returns as soon as the run finishes, or with status "working" after 25 seconds. While the status is "working", call again right away, without sleeping between calls.
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | Yes | Run ID returned by modem_agent_invoke or modem_agent_send_message. | |
| wait_seconds | No | Seconds to wait for the run to finish, from 0 to 25. The call returns as soon as the run finishes. Omit or pass 0 to return the current status at once. | |
| conversation_id | Yes | Conversation ID returned by modem_agent_invoke. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive behavior. The description adds useful runtime context beyond annotations: the long-poll window is capped at 25 seconds, the call returns early if the run finishes, and it may return status "working" with a recommendation to re-call immediately without sleeping.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core purpose and then the polling-specific operational guidance. Every sentence contributes directly to correct invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a simple read/poll operation with full schema coverage and clear annotations. The description covers the key behavioral nuance, though it could say slightly more about the returned status/result shape given there is no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents conversation_id, run_id, and wait_seconds. The description adds practical semantic guidance for wait_seconds by recommending 25 and explaining the polling behavior when the result is "working".
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: get the status and result of a Modem agent run. It clearly distinguishes this polling/read operation from sibling run-mutating tools like modem_agent_invoke and modem_agent_cancel_run.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear polling guidance: use wait_seconds 25 to wait, and immediately call again while status is "working". The surrounding lifecycle (run_id comes from invoke or send_message) is documented in the schema, but the description does not explicitly compare against cancel_run or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modem_agent_invokeRun Modem AgentADestructiveIdempotentInspect
Ask the Modem agent a question or give it a task. Use it for questions about the organization's data, such as which customers asked for something, topics, companies, people, conversations, and the PRs and issues that resolved them, and for work that needs several steps or an action in Linear, Slack, or GitHub. Pass the user's question as written; add only context the agent cannot see in its own conversation. Spends agent credits. Returns immediately with conversation_id and run_id; poll modem_agent_get_run for the result. Before your first call, read the skill: modem_skills({ name: "agent-runs" }).
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | Natural-language prompt for the Modem agent. | |
| idempotency_key | Yes | Stable retry key. Reuse only for the exact same prompt. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive=true and openWorld=true, but the description adds non-obvious behavior the schema cannot convey: it consumes agent credits, it is asynchronous (returns conversation_id and run_id immediately), and results require polling modem_agent_get_run. The prerequisite to read the agent-runs skill before the first call is a critical operational constraint stated nowhere else.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and cost/async consequences are front-loaded and no sentence is filler. The middle enumeration of data domains is somewhat long and runs together as one dense clause, which slightly hurts scanability, but overall the text is efficient for the amount of critical information it carries.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an asynchronous, credit-consuming, open-world agent invocation with no output schema, the description covers everything needed to call it correctly: what it does, what it returns (conversation_id, run_id), how to retrieve results, and the mandatory skill read first. No important gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are documented structurally, giving a baseline of 3. The description goes beyond that by specifying how to compose the prompt (verbatim user question plus only out-of-band context), which meaningfully changes how an agent fills the parameter. The idempotency_key is left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and resource ('Ask the Modem agent a question or give it a task'), then scopes it to concrete data domains (customers, topics, companies, people, conversations, PRs/issues) and multi-step or cross-tool work. An agent can immediately distinguish this from sibling operations like modem_agent_get_run or modem_agent_cancel_run.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states clear triggering conditions — organizational data questions, multi-step work, and actions in Linear/Slack/GitHub — and routes to modem_agent_get_run for results. It also gives prompt-construction guidance ('pass the user's question as written; add only context the agent cannot see'). What's missing is any exclusion or differentiation from modem_agent_send_message, which is presumably the follow-up path in an existing conversation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modem_agent_send_messageSend Agent MessageADestructiveIdempotentInspect
Continue an existing Modem agent conversation when a question builds on an earlier answer, such as drilling in, narrowing, or acting on the results; the agent keeps that conversation's context. Start a new run with modem_agent_invoke for an unrelated question. Returns immediately with a new run_id; poll modem_agent_get_run for the result.
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | Follow-up prompt for the Modem agent. | |
| conversation_id | Yes | Existing MCP conversation ID. | |
| idempotency_key | Yes | Stable retry key for this follow-up. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds critical behavioral information: 'Returns immediately with a new run_id; poll modem_agent_get_run for the result.' This defines the asynchronous nature of the call and the required workflow, which goes beyond the functional guarantees provided by the annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly efficient. The first sentence defines the scope (continuation), and the second defines the workflow (immediate response + polling). Both sentences are necessary and well-placed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the richness of the input schema and annotations, the description perfectly covers the remaining operational aspects of the tool. It covers intent, usage context, and execution flow without unnecessary padding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema coverage is 100%, so the schema itself handles the detailed documentation of parameters. The description successfully frames the parameters within the functional context (e.g., `prompt` is a 'Follow-up prompt'), but adds no semantic value beyond what is already clear in the required fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies the exact function: 'Continue an existing Modem agent conversation.' It sharply distinguishes its purpose from the sibling tool, `modem_agent_invoke`, by stating it is for continuing threads rather than starting new, unrelated runs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit rules for usage and exclusion: it should be used when a question builds upon earlier context, and the agent must use `modem_agent_invoke` for entirely unrelated questions. This prevents common invocation errors.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modem_docsModem DocsARead-onlyIdempotentInspect
Search or read Modem's public docs to answer how Modem works: setup, integrations, this MCP server and its scopes, the API, and automations. Not for your organization's data; ask the Modem agent with modem_agent_invoke for that. Send a query to search, or a page path from a search result (such as api/modem-mcp-server) to read the whole page. Send exactly one. Read-only, spends no agent credits.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | A docs page path exactly as a search result prints it, such as `api/modem-mcp-server`. Returns the whole page. | |
| query | No | What to look up in the Modem docs, in plain words. Returns the matching doc sections. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive and closed-world. The description adds genuinely new behavioral context beyond them: it spends no agent credits, and reading requires a path taken from a prior search result. It doesn't cover result-set size or truncation, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences: scope, exclusion, mode selection, cost. Front-loaded with purpose and immediately followed by the routing rule; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers what is searched, how to invoke each mode, the mutual-exclusion rule, cost behavior, and the shape of each return (matching sections vs whole page). With no output schema needed and only two simple params, nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds the crucial constraint that the schema does not encode: send exactly one of query/page. It also clarifies provenance of the page value (must come from a search result) and includes a concrete example format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair (search or read) and resource (Modem's public docs), enumerates the covered topic areas, and explicitly names what it is not for (organization data). An agent can separate it from the modem_agent_* siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives both the positive routing ('answer how Modem works') and the negative routing ('Not for your organization's data; ask the Modem agent with modem_agent_invoke') plus the mode-selection rule: send a query to search, a page path from a result to read. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modem_skillsModem SkillsARead-onlyIdempotentInspect
Skills that teach you how to use THIS Modem MCP server's tools. Call before your first modem_agent_invoke or write-tool call, or when unsure which Modem tool to use. Pass name for the full skill, one of agent-runs, write-tools, install-feedback, automations. Omit name to list them with descriptions. This is not the Skills page in dashboard settings.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | A skill from this server's catalog, e.g. "agent-runs". Not a path or an outside skill name. Omit to list the catalog. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered. The description adds genuinely new behavior: omitting `name` returns a catalog listing, supplying it returns the full skill, and it warns that names are server-catalog entries rather than paths or external skills.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the purpose and the calling trigger; the catalog values and the disambiguation note follow in descending priority. No filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only, no-output-schema tool, the description covers purpose, trigger, both call modes, and valid values. The only gap is that it never tells the agent how it differs from `modem_docs`, leaving one routing decision to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description earns above baseline by enumerating the valid values (`agent-runs`, `write-tools`, `install-feedback`, `automations`), which the schema does not encode as an enum, and by contrasting `name` present vs. omitted behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: returns skill documents that teach usage of this MCP server's own tools, and explicitly excludes the dashboard Skills page. It does not, however, differentiate itself from the sibling `modem_docs`, which an agent could reasonably confuse with this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggers — before the first `modem_agent_invoke` or any write-tool call, or whenever unsure which Modem tool to use — plus a clarifying exclusion of a similarly named non-tool feature. An agent knows both when to call and what mistake this prevents.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_feedbackSend Feedback to ModemAInspect
Send feedback about Modem to the Modem team. Offer it when a Modem tool fails or returns something you cannot act on, when you need a capability Modem does not have, or when an error is unclear (category agent_friction); and when the user voices feedback or frustration or asks for something Modem cannot do (category user_feedback, the default, in the user’s words). Call it only when the user asks to or agrees, never on your own: tell them what you will send, and tell them when it is sent. In message (up to 4096 characters), describe what you tried, what happened, and what you expected instead. Include only what explains the problem: never credentials, tokens, or personal data unrelated to it. Send the user’s name and email: the Modem team replies to that address, so ask for them if the conversation does not already have them. For a failing tool, send its name in tags as tool_name, its trace ID in trace_id, and what you were attempting in context. Add release for your client’s version when you know it. Your MCP client is attached for you. Returns the id of the feedback event Modem recorded.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | ||
| name | Yes | ||
| tags | No | ||
| Yes | |||
| context | No | ||
| message | Yes | ||
| release | No | ||
| category | No | ||
| trace_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the generic write/openWorld/non-idempotent profile; the description adds the consequential behavior an agent actually needs: user consent required before sending, PII/credential prohibitions, that the Modem team replies to the given email, and that the call returns a feedback event id. This goes well beyond the structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then usage, then parameter-filling instructions, so scanning order matches decision order. It is dense with nested parenthetical conditions, which costs some readability, but for a 9-parameter tool every sentence adds real instruction rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the consent workflow, the required-vs-optional field split, nested object contents (tags, context), the enum decision, and the return value despite there being no output schema. Nothing an agent needs to invoke this correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage the description carries the full burden and delivers: content and length guidance for message (4096), when each category enum applies, tool_name/trace_id/context for failures, release, and the reply semantics of name/email. Only url is left unexplained, a minor gap against otherwise rich compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Send feedback about Modem to the Modem team') and clearly separates itself from the sibling create_feedback_channel, which manages channels rather than transmitting feedback. An agent can identify the operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggering conditions for each category (tool failure/unclear error → agent_friction; user frustration/missing capability → user_feedback) and a hard when-not rule: 'Call it only when the user asks to or agrees, never on your own.' The consent protocol (tell them what you will send, and when it is sent) closes the loop.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_automationUpdate AutomationADestructiveInspect
Update an automation. Only provide fields that need to change.
Schedule field accepts the same 5 formats as create:
{type: "at", at: "<ISO 8601>"} - one-time execution
{type: "every", unit: "minutes"|"hours", n: } - recurring interval (min 30 min)
{type: "cron", expr: ""} - cron schedule (min 30 min between runs)
{type: "rrule", rrule: ""} - iCalendar rule (min 30 min between occurrences)
{type: "event", events: ["", ...]} - event-driven (triggers immediately on ANY of the listed events, up to 20). {type: "event", event: ""} is a legacy single-event alias, still accepted but not canonical. Optionally add {delaySeconds: <int 1..604800>} to defer the run until N seconds after the event fires (max 604800 = 7 days); omit for immediate. GitHub PR triggers may include {targetBranches: ["main", "release/*", ...]} with case-sensitive names or * wildcards. An activity event shares its schedule only with other conversation activity events, and may add {filter: ""} (see create). Optionally add {condition: "<natural language, up to 2000 chars>"} to run only for events that satisfy it; omit it to run on every event. conditionMode and conditionSchemaVersion are set by Modem.
Available events: github.pr.created, github.pr.merged, github.pr.dismissed, github.issue.closed, gitlab.mr.created, gitlab.mr.merged, gitlab.mr.closed, topic.created, topic.priority.high, stripe.customer.created, stripe.subscription.created, stripe.subscription.canceled, stripe.subscription.trial_ending, stripe.invoice.payment_failed, sentry.feedback.created, feedback.created, topic.group.added, topic.group.updated, chat.activity, call.activity, support_ticket.activity, feedback.activity, social_post.activity, pull_request.activity, issue.activity
Send automationId and only the fields that change. The automation's dashboard page is https://app.modem.dev/<org-slug>/automations/<id>. Before your first call, read the skill: modem_skills({ name: "automations" }).
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| prompt | No | Natural language instructions for what the task should do. | |
| enabled | No | ||
| outcome | No | What the automation does when it fires. Omit for the default: run the Modem agent with the prompt. {type: "webhook", url} POSTs the trigger event to the URL instead of running the agent; the prompt, model level, capabilities and output channels are then unused. The signing secret receivers verify deliveries with is shown on the automation's page in the Modem dashboard; the API never returns it. | |
| schedule | No | Defines when an automation should run. | |
| timezone | No | ||
| modelLevel | No | Persisted model level for automation execution. | |
| automationId | Yes | ||
| capabilityMode | No | Capability mode: "all" (all visible capabilities) or "custom" (only listed capabilities). | |
| outputChannels | No | Allowed output channels and optional destination restrictions. | |
| allowedCapabilities | No | Capability keys to enable when capabilityMode is "custom". Providing this field implies custom mode when capabilityMode is omitted. An empty array means core-only. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: minimum 30-minute intervals, max 20 events, delay cap of 7 days, legacy `event` accepting a non-canonical form, and that conditionMode/conditionSchemaVersion are not writable. It does not warn about what an update destroys or whether omitted fields are preserved (partial-update semantics are only implied by "only provide fields that need to change").
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the partial-update rule are correctly front-loaded, and the events list earns its place because the schema does not enumerate valid event names. But the bulk of the schedule-format block duplicates the schema's nested descriptions verbatim, and the last line about dashboard URLs and skill reading is appended without structure, making the description longer than the net new information justifies.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter mutation with no output schema, the description covers the hardest part (the five schedule shapes with their limits), routes the agent to the automations skill, and points at the dashboard page. The remaining omissions (semantics of name/enabled/timezone, and explicit partial-update behavior) are low-risk for an agent that has the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 64% schema description coverage, the description does supply meaning for schedule alternatives and for the event/condition/delaySeconds knobs, and it enumerates the available event names, which the schema does not. However, most of the per-schedule-format detail is a near-verbatim restatement of the schema's own nested field descriptions, and fields the schema leaves bare (name, enabled, timezone, automationId) are not explained at all, so the gaps are not compensated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
First two sentences state a specific verb and resource ("Update an automation") plus the key constraint "only provide fields that need to change." It implicitly contrasts with create_automation ("same 5 formats as create", "see create") but never explicitly tells the agent to use create_automation for new automations, so sibling differentiation is inferred rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete invocation guidance: send automationId and only changed fields, and notes conditionMode/conditionSchemaVersion are server-set and ignored on input, which prevents a plausible misuse. It also mandates reading the automations skill before the first call. It stops short of an explicit when-to-use-this-vs-create_automation rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_companiesUpdate CompaniesBDestructiveIdempotentInspect
Update fields on one or more existing companies. Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| companies | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false, idempotentHint=true, and destructiveHint=true, so the description does not need to restate the mutation safety profile. It adds the useful prerequisite that the write-tools skill must be read first, but it does not clarify overwrite/merge semantics for omitted fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, action first, with no filler. The skill prerequisite is a necessary operational instruction and earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The definition covers the prerequisite and basic purpose, but for a mutation tool with destructiveHint=true and no output schema it stays minimal: it omits update semantics, alternative routing, and any mention of what happens to values not supplied. It is adequate for a simple schema but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description should compensate by explaining the companies array, the required companyId, and field update semantics; it only adds 'one or more existing companies,' which the schema's minItems/maxItems already conveys. The nested connections and optional fields are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('update') and resource ('existing companies'), which makes the core action clear and separates it from create/merge siblings. It does not explicitly name or contrast any sibling, so it stops short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'existing companies' implies this is for modifying already-created records rather than creating or merging, and the skill-reading instruction provides a clear prerequisite for use. However, it does not explicitly state when to prefer this over update_people, merge_companies, or other alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_peopleUpdate PeopleBDestructiveIdempotentInspect
Update fields on one or more existing people. Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| people | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, readOnlyHint=false and openWorldHint=false, so the safety profile is covered structurally. The description adds the bulk scope and skill prerequisite, but never explains what makes this destructive (e.g., whether null values clear existing fields) even though that is the most consequential behavior here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the purpose front-loaded and the required prerequisite second. Nothing is wasted and nothing is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a write tool with no output schema, annotations carry the safety story and the skill pointer may offload deeper detail. Still, the description omits how field clearing works and any indication of what a call returns, which leaves a real gap for a destructive, idempotent mutation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single array parameter is entirely undocumented in the schema. The description only implies the array/plural shape and says nothing about which fields are updatable, what a null value does, or the 1-50 item bounds — leaving the agent to reverse-engineer the payload.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Update fields on ... existing people') and adds the scope detail 'one or more', which signals bulk-update capability. It does not explicitly distinguish itself from siblings like merge_people or update_companies, but the operation is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete prerequisite ('Before your first call, read the skill: modem_skills(...)'), which is genuinely useful workflow guidance. It gives no when-to-use/when-not-to-use guidance relative to alternatives such as merge_people, so usage is only partially framed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_topicUpdate TopicCDestructiveIdempotentInspect
Update a single topic (priority, lifecycle state, archived status, issue type, or keywords). Before your first call, read the skill: modem_skills({ name: "write-tools" }).
| Name | Required | Description | Default |
|---|---|---|---|
| topicId | Yes | ||
| archived | No | Set to true to archive the topic, false to unarchive it. | |
| keywords | No | Not supported: the topic pipeline derives the keywords. Sending this field returns 400. | |
| priority | No | Update the topic priority. Valid values: very_low, low, default, high, very_high. | |
| issueType | No | Not supported: the topic pipeline derives the issue type. Sending this field returns 400. | |
| archivedReason | No | Optional reason for archiving. Only used when archived=true. | |
| lifecycleState | No | Update the topic lifecycle state. Valid values: open, in_progress, completed, dismissed. The unknown state is AI-assessed and cannot be set directly. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true and non-read-only, so the mutation profile is covered. The description adds the skill-reading precondition, which is genuinely useful behavioral context the annotations don't carry. It does not disclose the 400-error behavior for unsupported fields or what archiving does to a topic.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and followed by the prerequisite. Very little waste, though the parenthetical field list is inaccurate rather than merely redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists and this is a destructive 7-parameter write, so the description should say more about required topicId, rejection behavior for unsupported fields, and the effect of archiving. The skill pointer partially compensates by routing the agent to fuller documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 86% and the schema itself flags keywords and issueType as unsupported, so the structured data does the heavy lifting. The description's field list adds nothing beyond the schema and in fact repeats the two fields that cannot be sent, so it falls to the baseline rather than above it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Update a single topic') and enumerates the modifiable fields. However, two of the enumerated fields — issue type and keywords — are explicitly unsupported and return 400, so the purpose statement actively misleads an agent about what can be changed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Tells the agent to read the 'write-tools' skill before the first call, which is a useful prerequisite. But it gives no guidance on when to choose this tool over the obvious sibling bulk_update_topics, nor when a topic should be merged instead of updated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
- Changed
modem_agent_get_run1 field changed- added
Input schema / properties / wait_secondsAdded value: +{ + "description": "Seconds to wait for the run to finish, from 0 to 25. The call returns as soon as the run finishes. Omit or pass 0 to return the current status at once.", + "maximum": 25, + "minimum": 0, + "type": "integer" +}
- Changed
modem_skills1 field changed- changed
Input schema / properties / name / descriptionPrevious value: -"A skill from this server's catalog, e.g. \"search-modem\". Not a path or an outside skill name. Omit to list the catalog."New value: +"A skill from this server's catalog, e.g. \"agent-runs\". Not a path or an outside skill name. Omit to list the catalog."
- Removed
search_modem
2 tool updates
- Changed
create_automation3 fields changed- added
Input schema / properties / outcomeAdded value: +{ + "description": "What the automation does when it fires. Omit for the default: run the Modem agent with the prompt. {type: \"webhook\", url} POSTs the trigger event to the URL instead of running the agent; the prompt, model level, capabilities and output channels are then unused. The signing secret receivers verify deliveries with is shown on the automation's page in the Modem dashboard; the API never returns it.", + "oneOf": [ + { + "properties": { + "type": { + "const": "agent", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "properties": { + "type": { + "const": "webhook", + "type": "string" + }, + "url": { + "description": "HTTPS URL Modem POSTs a Standard Webhooks-signed JSON envelope to each time the automation fires.", + "maxLength": 2048, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "url" + ], + "type": "object" + } + ] +} - changed
Input schema / properties / prompt / descriptionPrevious value: -"Natural language instructions for what the automation should do."New value: +"Natural language instructions for what the automation should do. Required unless outcome is a webhook." - changed
Input schema / requiredPrevious value: -[ - "name", - "timezone", - "schedule", - "prompt" -]New value: +[ + "name", + "timezone", + "schedule" +]
- Changed
update_automation1 field changed- added
Input schema / properties / outcomeAdded value: +{ + "description": "What the automation does when it fires. Omit for the default: run the Modem agent with the prompt. {type: \"webhook\", url} POSTs the trigger event to the URL instead of running the agent; the prompt, model level, capabilities and output channels are then unused. The signing secret receivers verify deliveries with is shown on the automation's page in the Modem dashboard; the API never returns it.", + "oneOf": [ + { + "properties": { + "type": { + "const": "agent", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "properties": { + "type": { + "const": "webhook", + "type": "string" + }, + "url": { + "description": "HTTPS URL Modem POSTs a Standard Webhooks-signed JSON envelope to each time the automation fires.", + "maxLength": 2048, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "url" + ], + "type": "object" + } + ] +}
2 tool updates
- Changed
create_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "filter": { - "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change, audience; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name), audience; issue.activity: source.name, change.kind, audience. audience is internal (only the organization can read where the item lives) or public (people outside it can, or Modem cannot confirm it is internal). On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role, topic.priority_change and audience.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Filter", - "type": "string" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "filter": { + "description": "Optional filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change, audience; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into; == and in match it exactly, base.ref.matches('^release/') takes an RE2 regex), audience; issue.activity: source.name, change.kind, audience. audience is internal (only the organization can read where the item lives) or public (people outside it can, or Modem cannot confirm it is internal). On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role, topic.priority_change and audience.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Filter", + "type": "string" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
- Changed
update_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "filter": { - "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change, audience; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name), audience; issue.activity: source.name, change.kind, audience. audience is internal (only the organization can read where the item lives) or public (people outside it can, or Modem cannot confirm it is internal). On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role, topic.priority_change and audience.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Filter", - "type": "string" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "filter": { + "description": "Optional filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change, audience; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into; == and in match it exactly, base.ref.matches('^release/') takes an RE2 regex), audience; issue.activity: source.name, change.kind, audience. audience is internal (only the organization can read where the item lives) or public (people outside it can, or Modem cannot confirm it is internal). On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role, topic.priority_change and audience.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Filter", + "type": "string" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
2 tool updates
- Changed
create_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "filter": { - "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name); issue.activity: source.name, change.kind. On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role and topic.priority_change.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Filter", - "type": "string" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "filter": { + "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change, audience; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name), audience; issue.activity: source.name, change.kind, audience. audience is internal (only the organization can read where the item lives) or public (people outside it can, or Modem cannot confirm it is internal). On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role, topic.priority_change and audience.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Filter", + "type": "string" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
- Changed
update_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "filter": { - "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name); issue.activity: source.name, change.kind. On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role and topic.priority_change.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Filter", - "type": "string" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "filter": { + "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change, audience; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name), audience; issue.activity: source.name, change.kind, audience. audience is internal (only the organization can read where the item lives) or public (people outside it can, or Modem cannot confirm it is internal). On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role, topic.priority_change and audience.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Filter", + "type": "string" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
3 tool updates
- Changed
bulk_update_topics4 fields changed- removed
Input schema / properties / topicIds / items / anyOfRemoved value: -[ - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - } -] - added
Input schema / properties / topicIds / items / formatAdded value: +"uuid" - added
Input schema / properties / topicIds / items / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - added
Input schema / properties / topicIds / items / typeAdded value: +"string"
- Changed
merge_topics8 fields changed- removed
Input schema / properties / sourceTopicIds / items / anyOfRemoved value: -[ - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - } -] - added
Input schema / properties / sourceTopicIds / items / formatAdded value: +"uuid" - added
Input schema / properties / sourceTopicIds / items / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - added
Input schema / properties / sourceTopicIds / items / typeAdded value: +"string" - removed
Input schema / properties / targetTopicId / anyOfRemoved value: -[ - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - } -] - added
Input schema / properties / targetTopicId / formatAdded value: +"uuid" - added
Input schema / properties / targetTopicId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - added
Input schema / properties / targetTopicId / typeAdded value: +"string"
- Changed
update_topic4 fields changed- removed
Input schema / properties / topicId / anyOfRemoved value: -[ - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - } -] - added
Input schema / properties / topicId / formatAdded value: +"uuid" - added
Input schema / properties / topicId / patternAdded value: +"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$" - added
Input schema / properties / topicId / typeAdded value: +"string"
2 tool updates
- Changed
create_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "filter": { + "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name); issue.activity: source.name, change.kind. On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role and topic.priority_change.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Filter", + "type": "string" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
- Changed
update_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "filter": { + "description": "Optional exact-match filter on an activity event's payload, checked before any trigger condition or agent runs. One CEL expression: field == 'value' or field in ['a', 'b'], joined with && and || (parentheses allowed). Fields: chat.activity, call.activity, feedback.activity: source.name, placement, author.role, topic.priority_change; support_ticket.activity: those and support_ticket.status; social_post.activity: those and social_post.kind; pull_request.activity: source.name, change.kind, base.ref (the branch it merges into, exact name); issue.activity: source.name, change.kind. On a conversation activity event, source.name is one of its built-in sources or a custom source's name. E.g. \"source.name in ['zendesk', 'intercom'] && author.role == 'customer'\". Omit to run on every occurrence. Valid on one activity event, or on several conversation activity events, where it may name only source.name, placement, author.role and topic.priority_change.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Filter", + "type": "string" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
2 tool updates
- Changed
create_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
- Changed
update_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "condition": { - "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event.", - "maxLength": 2000, - "minLength": 1, - "title": "Trigger Condition", - "type": "string" - }, - "conditionMode": { - "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", - "enum": [ - "judge", - "agent" - ], - "title": "Condition Mode", - "type": "string" - }, - "conditionSchemaVersion": { - "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Condition Schema Version", - "type": "integer" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event. A condition also satisfies an event that requires a channel or product scope.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
2 tool updates
- Changed
create_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
- Changed
update_automation1 field changed- changed
Input schema / properties / schedule / oneOfPrevious value: -[ - { - "properties": { - "expr": { - "description": "Standard cron expression string.", - "minLength": 1, - "title": "Cron Expression", - "type": "string" - }, - "type": { - "const": "cron", - "type": "string" - } - }, - "required": [ - "type", - "expr" - ], - "type": "object" - }, - { - "properties": { - "rrule": { - "description": "iCalendar recurrence rule (RFC 5545) string.", - "minLength": 1, - "title": "RRule", - "type": "string" - }, - "type": { - "const": "rrule", - "type": "string" - } - }, - "required": [ - "type", - "rrule" - ], - "type": "object" - }, - { - "properties": { - "at": { - "description": "ISO 8601 timestamp for one-time execution.", - "minLength": 1, - "title": "At Time", - "type": "string" - }, - "type": { - "const": "at", - "type": "string" - } - }, - "required": [ - "type", - "at" - ], - "type": "object" - }, - { - "properties": { - "n": { - "description": "Number of time units between executions.", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "title": "Interval", - "type": "integer" - }, - "type": { - "const": "every", - "type": "string" - }, - "unit": { - "description": "Time unit for interval scheduling.", - "enum": [ - "minutes", - "hours" - ], - "title": "Time Unit", - "type": "string" - } - }, - "required": [ - "type", - "unit", - "n" - ], - "type": "object" - }, - { - "properties": { - "channelIds": { - "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Channel IDs", - "type": "array" - }, - "delaySeconds": { - "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", - "maximum": 604800, - "minimum": 1, - "title": "Delay (seconds)", - "type": "integer" - }, - "event": { - "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", - "minLength": 1, - "title": "Event Name (legacy single-event form)", - "type": "string" - }, - "events": { - "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", - "items": { - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "title": "Event Names", - "type": "array" - }, - "productIds": { - "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", - "items": { - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", - "type": "string" - }, - "minItems": 1, - "title": "Product IDs", - "type": "array" - }, - "targetBranches": { - "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", - "items": { - "minLength": 1, - "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", - "type": "string" - }, - "minItems": 1, - "title": "Target Branches", - "type": "array" - }, - "type": { - "const": "event", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "expr": { + "description": "Standard cron expression string.", + "minLength": 1, + "title": "Cron Expression", + "type": "string" + }, + "type": { + "const": "cron", + "type": "string" + } + }, + "required": [ + "type", + "expr" + ], + "type": "object" + }, + { + "properties": { + "rrule": { + "description": "iCalendar recurrence rule (RFC 5545) string.", + "minLength": 1, + "title": "RRule", + "type": "string" + }, + "type": { + "const": "rrule", + "type": "string" + } + }, + "required": [ + "type", + "rrule" + ], + "type": "object" + }, + { + "properties": { + "at": { + "description": "ISO 8601 timestamp for one-time execution.", + "minLength": 1, + "title": "At Time", + "type": "string" + }, + "type": { + "const": "at", + "type": "string" + } + }, + "required": [ + "type", + "at" + ], + "type": "object" + }, + { + "properties": { + "n": { + "description": "Number of time units between executions.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Interval", + "type": "integer" + }, + "type": { + "const": "every", + "type": "string" + }, + "unit": { + "description": "Time unit for interval scheduling.", + "enum": [ + "minutes", + "hours" + ], + "title": "Time Unit", + "type": "string" + } + }, + "required": [ + "type", + "unit", + "n" + ], + "type": "object" + }, + { + "properties": { + "channelIds": { + "description": "Optional channel scope: message channel UUIDs this automation is limited to. Omit for all channels (global). Only valid when every selected event supports channel scoping (see EVENT_CHANNEL_SCOPING).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Channel IDs", + "type": "array" + }, + "condition": { + "description": "Optional free-form natural-language condition (\"only run when …\"), up to 2000 characters, evaluated against each trigger event's payload; the automation runs only for events that satisfy it. Omit to run on every matching event.", + "maxLength": 2000, + "minLength": 1, + "title": "Trigger Condition", + "type": "string" + }, + "conditionMode": { + "description": "Server-derived; ignored on input. judge = the condition is decided from the event payload before the run starts; agent = the agent decides it at the start of every run.", + "enum": [ + "judge", + "agent" + ], + "title": "Condition Mode", + "type": "string" + }, + "conditionSchemaVersion": { + "description": "Server-derived; ignored on input. The version of the event field guide the condition was judged against; absent when it was not judged.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "title": "Condition Schema Version", + "type": "integer" + }, + "delaySeconds": { + "description": "Optional delay, in seconds, before running the automation after its trigger event fires (e.g. 1800 = 30 minutes after the event). Omit for immediate execution. Maximum 604800 (7 days).", + "maximum": 604800, + "minimum": 1, + "title": "Delay (seconds)", + "type": "integer" + }, + "event": { + "description": "Legacy single-event trigger (e.g., github.pr.created). Still accepted on read/write for backwards compatibility; prefer `events` for new writes. When both are present, `events` is canonical.", + "minLength": 1, + "title": "Event Name (legacy single-event form)", + "type": "string" + }, + "events": { + "description": "Trigger events for this automation (e.g., [\"github.pr.created\", \"github.pr.dismissed\"]). The automation fires once per matching event occurrence. Canonical form — prefer this over the legacy `event` field.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "title": "Event Names", + "type": "array" + }, + "productIds": { + "description": "Optional product scope: the products this automation is limited to. Omit for all products (global); an empty array is rejected so 'global' has one representation. Acts as a channel preset — at dispatch time the scoped products' currently linked message channels (product_channels) are resolved and the automation fires when the triggering event's channels intersect ANY of them. It additionally instructs the agent to scope the run's output to those products. May be combined with channelIds — both scopes must pass (AND semantics).", + "items": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", + "type": "string" + }, + "minItems": 1, + "title": "Product IDs", + "type": "array" + }, + "targetBranches": { + "description": "Optional case-sensitive allowlist of GitHub PR base_ref branches. Names match exactly; * matches zero or more characters, including slashes. Only valid for GitHub PR triggers. Omit for all target branches; channel and product scopes must also pass. Nonmatching events are skipped before launching a workflow or agent.", + "items": { + "minLength": 1, + "pattern": "^[^\\s\\p{Cc}~^:?[\\]\\\\]+$", + "type": "string" + }, + "minItems": 1, + "title": "Target Branches", + "type": "array" + }, + "type": { + "const": "event", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } +]
1 tool update
- Changed
update_people1 field changed- changed
Input schema / properties / people / items / properties / primaryEmail / anyOfPrevious value: -[ - { - "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "format": "email", + "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", + "type": "string" + }, + { + "type": "null" + } +]
3 tool updates
- Added
create_automation - Added
list_automations - Added
update_automation
1 tool update
- Changed
send_feedback1 field changed- added
Input schema / properties / categoryAdded value: +{ + "enum": [ + "agent_friction", + "user_feedback" + ], + "type": "string" +}
2 tool updates
- Added
create_feedback_channel - Added
send_feedback
1 tool update
- Changed
update_topic2 fields changed- changed
Input schema / properties / issueType / descriptionPrevious value: -"Update the topic issue type classification. Valid values: bug_report, feature_request, complaint, praise, or null to clear."New value: +"Not supported: the topic pipeline derives the issue type. Sending this field returns 400." - changed
Input schema / properties / keywords / descriptionPrevious value: -"Replace the topic keywords/categories. Provide the full list of keywords."New value: +"Not supported: the topic pipeline derives the keywords. Sending this field returns 400."
1 tool update
- Added
modem_docs
1 tool update
- Changed
search_modem1 field changed- added
Input schema / properties / contextAdded value: +{ + "description": "What the user is trying to accomplish with this search. It does not change the results, so put every filter in question.", + "maxLength": 1000, + "type": "string" +}
1 tool update
- Added
modem_skills
Related MCP Connectors
Search your customer interviews, calls, feedback, competitor intel and roadmap from any AI agent.
Search the Cerebrium docs: deployment, cerebrium.toml, hardware, endpoints. Also sends feedback.
Search UserVoice ideas, feedback and users; post ideas, comments, notes and status updates.
Search and act on Letter AI sales enablement content, deals, and call recordings.
Related MCP Servers
AlicenseNot gradedqualityDmaintenanceSearch your company's connected knowledge from any AI tool that speaks the Model Context Protocol. Supports querying across sources like Drive, SharePoint, Confluence, Slack, and Notion with permission filtering.4 npmMIT- AlicenseNot gradedqualityBmaintenanceEnables Claude and Cursor to search a team's synced Slack, GitHub and Notion content through permission-aware hybrid search with citations, retrieve a source document with its review and comment thread, and query time-aware knowledge graph facts when the graph is enabled. Every tool call runs with the signed-in user's permissions, so the assistant sees exactly what that user can see.10 npmApache 2.0
- AlicenseBqualityCmaintenanceEnables AI agents to check brand mentions across AI search surfaces like ChatGPT, Claude, Gemini, Perplexity, and Google AI Overviews using natural language queries.415 npm1MIT
- AlicenseNot gradedqualityCmaintenanceEnables agents to search indexed documents and GitHub repository code through stdio-exposed tools, returning relevant evidence for grounded answers and code reviews.16Apache 2.0
Glama MCP Gateway
Add one secure layer between your agents and this server.