reassign
Server Details
Reassign: a circular 24-hour calendar and time-tracking copilot with ADHD-friendly scheduling.
- Status
- Healthy
- Uptime
- 99.5% over 39 days
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- reassignai/plugins
- GitHub Stars
- 1
TDQS
Scored across 15 tools
Most tools have clearly distinct purposes: scheduling, reading, writing, backlog management, categories, reviews, etc. However, there is some overlap between 'schedule' and 'write_events' (both can create events), and 'show_day' and 'get_schedule' both provide day views, though descriptions help clarify when to use each.
Tools use a consistent verb_noun pattern (get_schedule, write_events, delete_events, manage_backlog, manage_categories, review_day, show_day, undo). Minor deviations like 'confirm_schedule' and 'find_event' still follow the pattern. The naming is clear and predictable, with only slight variance in verb choice (get vs show).
With 15 tools, the server provides a comprehensive set for calendar/scheduling management. This is at the higher end of the ideal range, but each tool addresses a distinct function (scheduling, reading, writing, deleting, reviewing, weather, energy, feedback, etc.), so the count is justified and not excessive.
The tool surface covers the core lifecycle: read (get_schedule, show_day, find_event), create (schedule, write_events), update (write_events, manage_categories), delete (delete_events), and review (review_day). Minor gaps exist, such as lack of explicit calendar management (e.g., create/delete calendars) or more granular weather details, but the main workflows are covered.
Available Tools
15 toolsconfirm_scheduleConfirm proposed timesAInspect
Confirm — accept a proposal, pick an option, commit — one or more times that schedule proposed. Pass items, each a token (the commitToken) and optional choice (0-based index into that proposal's options; defaults to the first/best). Each is re-checked for conflicts before writing — a slot taken meanwhile is reported as an error; re-run schedule. Returns per-item results (each commit echoes its event) and one undoToken that reverts every commit in the call.
| Name | Required | Description | Default |
|---|---|---|---|
| items | Yes | ||
| render | No | When the user is looking at their reassign dial, set true to repaint it with the updated day in this same call. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond readOnly=false/destructive=false by disclosing conflict re-checking before writing, error behavior for taken slots, per-item results, and a single undoToken that reverts all commits in the call. It does not cover permissions or partial-failure details, but the key side effects are transparent.
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 front-loads the purpose and packs parameter semantics, conflict handling, and return values into a compact paragraph with no filler. The em-dash-heavy structure is somewhat dense, but every clause 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?
Since there is no output schema, the description appropriately explains the return shape: per-item `results` and a single `undoToken`, which an agent needs to know. It also covers the error condition and the re-run-schedule guidance; only minor edge cases like invalid-token behavior are left unspecified.
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 description adds meaning beyond the schema by explaining that `choice` is a 0-based index into that proposal's `options` and defaults to the first/best. It does not mention `render`, but the schema itself documents that parameter fully, so the core semantics are covered.
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 action set — 'Confirm — accept a proposal, pick an option, commit — one or more times that `schedule` proposed. It names the resource (schedule proposals) and the key mechanism (commitToken and choice), distinguishing it from sibling tools like `schedule` and `undo`.
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 clearly frames this as the commit step after `schedule` proposes times, and even tells the agent to re-run `schedule if a slot is taken. It does not explicitly list when-not-to-use alternatives, but the context and references to commitToken and undoToken provide strong situational guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_eventsDelete eventsADestructiveInspect
Delete events or clear whole days — one or many in a single call. Pass ops, an array where each item has an op (delete | clear): delete removes one event by id. A bare series id addresses the whole series; seriesId@YYYY-MM-DD addresses one occurrence; add scope:"future" to an occurrence id for that occurrence and every later one. clear removes everything from from to to (inclusive, equal for one day). By default the whole batch is atomic: if ANY op fails, nothing is removed; pass partial: true for best-effort. Every removal is reversible with the returned undoToken (call undo before expiresAt). Deleting a calendar-linked event also removes it from that calendar; an event marked readOnly can't be deleted this way. A delete result lists deletedIds; a scope:"future" delete also returns the truncated series as updated. To create or edit events use write_events.
| Name | Required | Description | Default |
|---|---|---|---|
| ops | Yes | ||
| render | No | When the user is looking at their reassign dial, set true to repaint it with the updated day in this same call. Otherwise the change reaches an open dial only if the host forwards this result. | |
| partial | No | Best-effort mode: apply the ops that succeed and report the rest as errors, instead of the default all-or-nothing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, and the description adds substantial behavioral context: atomicity by default, partial mode, undoToken reversibility, calendar-linked event behavior, readOnly restriction, and return values. This goes well beyond the annotation.
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 dense but well-structured, front-loading the core action and then systematically covering modes, atomicity, reversibility, edge cases, and alternatives. Every sentence adds value, though it is long and could benefit from slight restructuring.
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 tool's complexity (two op types, scope semantics, atomicity, undo, calendar integration), the description covers nearly all necessary context. No output schema exists, but the description lists key return fields (deletedIds, updated). Minor gaps like the exact undoToken format are acceptable.
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 67%, and the description adds meaning for the ops parameter by explaining the op types, id formats, scope semantics, and clear range. It also explains partial and render behavior. The description compensates for the schema's gaps, though some details like the exact format of undoToken are not covered.
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 tool deletes events or clears whole days, with a specific verb and resource. It distinguishes itself from write_events by explicitly saying 'To create or edit events use write_events.'
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 provides explicit when-to-use guidance, including the alternative write_events for creating/editing. It also explains the different modes (delete vs clear) and the partial flag for best-effort, giving clear context for when to use each.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_eventFind eventARead-onlyInspect
Search for, look up, or locate SCHEDULED events by name when you do not have an id: fuzzy, case- and accent-insensitive. (For an un-timed Inbox block, use get_schedule with includeBacklog: true and backlogQuery; those are not events.) Searches the past week through the next 30 days by default; pass from/to (ISO "YYYY-MM-DD", e.g. "2026-06-01") to widen or shift the window, and optionally filter by areaId, activityTypeId, or timeOfDay. Returns events (best match first, one per event) in the same event shape as get_schedule, and the timezone of their times. An event with readOnly: true lives on a calendar the user does not own: do not edit or delete it. When two different events tie, ambiguous is true: ask the user which one they meant. Two days of the same recurring event are not ambiguous.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Range end, ISO date, e.g. "2026-07-01". Defaults to +30 days. | |
| from | No | Range start, ISO date, e.g. "2026-06-01". Defaults to 7 days ago. | |
| query | Yes | Text to match against event names, e.g. "standup", "gym". | |
| areaId | No | Only match events linked to this area id. | |
| timeOfDay | No | Only match events that start in this part of the day. | |
| activityTypeId | No | Only match events linked to this activity-type id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds meaningful behavioral context: it returns events best-match-first, includes a timezone, marks readOnly events as not editable/deletable, and explains the ambiguous flag for ties. It also clarifies that two days of the same recurring event are not ambiguous. This goes well beyond the 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 dense but well-organized: it front-loads the core purpose and the key alternative, then explains defaults, filters, and result semantics in a logical order. Every sentence earns its place, and there is no fluff.
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 read-only search tool with 100% schema coverage and no output schema, the description covers the essential context: what it searches, the default window, how to widen it, optional filters, result ordering, timezone, readOnly caveat, and ambiguity handling. Nothing an agent needs to call it correctly 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 description coverage is 100%, so the schema already documents all six parameters. The description adds value by explaining the default date window (past week through next 30 days), the ISO format for from/to, and the meaning of the readOnly flag in results. It doesn't add much beyond the schema for areaId/activityTypeId/timeOfDay, but the defaults and result semantics are useful.
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 ('Search for, look up, or locate') and a specific resource ('SCHEDULED events by name'), and explicitly distinguishes itself from un-timed Inbox blocks. It also names the sibling tool get_schedule as the alternative for a different resource, so an agent can tell them apart without opening schemas.
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 explicitly says when to use this tool ('when you do not have an id') and when not to ('For an un-timed Inbox block, use get_schedule with includeBacklog: true and backlogQuery'). It also explains the default search window and how to widen it, plus optional filters, which is clear context for choosing this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_energyGet energy curveARead-onlyInspect
Get the user's forecast energy curve for a day, to schedule by their alertness: focus/deep work in a peak, admin/errands in the afternoon dip. Built from their logged sleep (+ tracked caffeine), personalized from energy levels they log. get_schedule and show_day don't include energy, so use this when energy matters or the user asks about it. Defaults to today; pass date (ISO YYYY-MM-DD) for another day. Returns a compact overview (peak + dip windows, today's current level, calibration state), not an hourly dump. Needs at least one logged night of sleep; with none it returns a short nudge to log sleep first.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | The day to read, ISO "YYYY-MM-DD". Defaults to today. A future day forecasts from the user's habitual sleep; a past day reflects their actual logged sleep where recorded, but energy itself is modeled, not measured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds valuable behavioral context: it returns a compact overview (peak + dip windows, current level, calibration state) rather than an hourly dump, defaults to today, and handles the no-sleep-data case with a nudge. It also explains the modeling nature of energy (modeled, not measured) for past days. This goes beyond annotations without contradicting them.
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 sentences, each earning its place: purpose, differentiation, parameter behavior, return format, and edge-case handling. Front-loaded with the core purpose and use case. No fluff or repetition.
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?
Complete for a read-only single-parameter tool. The description covers what it returns, when to use it, prerequisites, and edge cases. The output schema is absent, but the description explicitly describes the return shape (peak + dip windows, current level, calibration state), so an agent knows what to expect. Nothing critical 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 description coverage is 100%, so the schema already documents the date parameter. The description adds context about defaulting to today and the meaning of future vs past days, which is useful but not strictly necessary given the schema's full coverage. Baseline 3 is appropriate.
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 ('Get'), resource ('forecast energy curve'), and purpose ('to schedule by their alertness'), and distinguishes itself from siblings by noting get_schedule and show_day don't include energy. The description clearly identifies what the tool does and how it differs from related tools.
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 use this tool ('when energy matters or the user asks about it'), names alternatives (get_schedule, show_day) and states they don't include energy. Also provides a prerequisite (at least one logged night of sleep) and behavior when unmet. This is comprehensive usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_more_toolsARead-onlyIdempotentInspect
Check for additional tools whenever your task might benefit from specialized capabilities - even if existing tools could work as a fallback.
| Name | Required | Description | Default |
|---|---|---|---|
| context | Yes | A description of your goal and what kind of tool would help accomplish it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds no additional behavioral context such as what 'check' entails, whether it makes a network call, or what side effects (if any) occur beyond the 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 a single, front-loaded sentence with no wasted words. It quickly communicates the action and the conditions for use, making it efficient and easy to parse, though it could be slightly more structured with a separate usage note.
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 description gives clear usage guidance but does not explain what the tool returns or what happens after 'checking' for tools. With no output schema present, the description carries the burden of explaining the result, which it fails to do. For a simple one-parameter tool, this is a notable gap, though not severe.
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%, and the single parameter 'context' is already documented with a clear description in the schema. The tool description adds no additional semantic meaning beyond what the schema provides, which aligns with the baseline of 3.
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 tool's function: checking for additional tools when a task could benefit from specialized capabilities. It distinguishes itself from the sibling clipform_* tools by being a meta-tool for tool discovery rather than a domain-specific operation, though it does not explicitly name this distinction.
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 provides explicit usage guidance: use this tool whenever specialized capabilities might help, even if existing tools could work as a fallback. This gives the agent a clear decision rule, though it does not mention when not to use it or list alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scheduleGet scheduleARead-onlyInspect
Read the calendar: the agenda, what is on, how busy the user is, free time, or where the time goes. One call returns the current local time (now, "YYYY-MM-DDTHH:MM"), the user's timezone, the user's areas and activityTypes (the lookup lists for areaId / activityTypeId), userPreferences, and a days array. Each day has its events, its freeSlots, and its blocking load per area and activity type (non-blocking overlay load comes separately). Call it before you schedule, to anchor relative times ('this afternoon'). Pass from and to (ISO YYYY-MM-DD, inclusive; equal for one day). Pass includeSeries: true to also get the recurring masters as series.
Time spans: every event and free slot is start + end, two local datetimes "YYYY-MM-DDTHH:MM" in the top-level timezone (e.g. start "2026-09-23T22:00", end "2026-09-24T01:00"). The end is always after the start; a slot to midnight ends at the next day's T00:00. An event from an earlier day that runs into this day is listed first, with its real start, on every day that it touches; only its time inside the day counts for load and free slots. A warning marks a start time that a DST change skips.
Each event carries its source ("reassign", else a provider like "google"), its home calendarId (absent = the default calendar, null = dial only) and any mirrorCalendarIds. An event with readOnly: true is on a calendar the user does not own: do not edit or delete it (tell them to change it there). kind "non_blocking" is an overlay that may overlap others (fasting, an away marker); "reference" is see-only: its hours stay free, so do not move, delete, or schedule work into it unless asked. A confirmed past day carries a review adherence rollup and per-event reflect actuals; use them for how a day or week actually went. When a calendar is connected, integrations describes it. For a single day, a one-line weather headline is included when the user has a city; call get_weather only for hourly detail.
Inbox: backlogCount is the number of Inbox blocks (un-timed intentions). Pass includeBacklog: true for the items (top of tray first, up to 50); backlogQuery, backlogPlannedOn and backlogOffset filter or page them and need includeBacklog: true. When nextBacklogOffset is not null, pass it as backlogOffset with the same filters for the next page. Place or manage items with manage_backlog.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Last day of the range, inclusive. | |
| from | Yes | First day of the range, inclusive. | |
| backlogQuery | No | Filter the Inbox blocks by name (fuzzy, case/accent-insensitive), e.g. "dentist". Needs includeBacklog: true. | |
| backlogOffset | No | Inbox page offset from nextBacklogOffset; keep the same filters. Needs includeBacklog: true. | |
| includeSeries | No | Also return the recurring masters as `series`. | |
| includeBacklog | No | Include the Inbox items (the `backlog` array), not just `backlogCount`. Pass true when the user wants to see, schedule, or manage their Inbox. | |
| backlogPlannedOn | No | Filter the Inbox blocks to those planned for this day (a planned day, or a planned window that covers it). Needs includeBacklog: true; composes with backlogQuery. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the readOnlyHint/openWorldHint annotations by documenting inclusive ranges, cross-day event handling, DST warnings, readOnly calendar semantics, non_blocking/reference event kinds, review/reflect actuals, and backlog pagination. It also tells the agent what not to do with certain returned events, which is behavior annotations alone cannot express.
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 the tool has no output schema and returns a rich document, so most of the length is justified. It is front-loaded with purpose and required parameters before the detailed return semantics, and the paragraphs are logically grouped. Still, some event-level detail could be trimmed or moved to an output schema if one existed.
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 absence of an output schema, the description carries the full burden of explaining the return shape, and it does so comprehensively: timezones, events, free slots, event kinds, calendar semantics, weather, and inbox pagination. An agent has enough context to invoke the tool correctly and interpret its response.
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 input schema describes all 7 parameters, but the description adds meaning: from/to are ISO and inclusive, equal for one day; includeSeries returns recurring masters; includeBacklog returns items top-of-tray-first up to 50; and backlogOffset pagination must preserve the same filters. This is genuinely useful operational detail beyond 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 opens with a specific verb–resource pair ('Read the calendar') and immediately clarifies scope: agenda, busyness, free time, and where time goes. It also distinguishes itself from sibling tools by saying to call it before scheduling, to use get_weather only for hourly detail, and to use manage_backlog for Inbox item management.
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 explicitly directs 'Call it before you schedule, to anchor relative times,' and explains when to pass includeSeries and includeBacklog. It also gives explicit when-not-to-use guidance for get_weather and routes backlog management to manage_backlog, giving an agent clear selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_weatherGet weatherARead-onlyInspect
Get the weather forecast for a day, for scheduling around it. Use ONLY for outdoor or weather-sensitive plans (exercise, commute, travel, anything outside) or when the user explicitly asks about the weather — indoor plans don't need it. get_schedule and show_day already include a one-line weather headline for the day, so prefer that for a quick glance and reach for this only when an outdoor plan needs the hourly detail (e.g. the exact dry/daylight window). Defaults to today and the user's city; pass date (ISO YYYY-MM-DD) for another day, or location (a city/place name) to ask about somewhere else. Returns a compact day overview (condition, temp range, rain window, daylight) plus a part-of-day breakdown — not an hourly dump.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | The day to forecast, ISO "YYYY-MM-DD". Defaults to today. Open-Meteo covers ~16 days ahead; far-future/far-past days have no hourly data. | |
| location | No | A city/place name to forecast instead of the user's own city, e.g. "London" or "Tahoe". Omit to use their saved (or timezone-guessed) city. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations already declare readOnlyHint=true, the description adds substantial behavioral context: defaults to today and the user's city, returns a compact day overview plus part-of-day breakdown (not an hourly dump), and mentions the ~16-day coverage limit. This goes well beyond the structured annotations and helps the agent set expectations.
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 well-structured paragraph that front-loads purpose, then usage, parameters, and return format in logical order. Every sentence earns its place—no fluff, no repetition—and it remains readable despite being thorough.
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 simple 2-parameter read-only tool with no output schema, the description covers purpose, usage boundaries, parameter semantics, defaults, and output shape. Nothing an agent needs to call it correctly is missing, and the sibling differentiation adds critical routing 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?
Schema coverage is 100%, yet the description still enriches both parameters: date gets ISO format, default-to-today, and coverage range; location gets example values and default-to-saved-city behavior. This clarifies usage beyond the schema's bare definitions, making parameter semantics exceptionally clear.
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 (get), resource (weather forecast), and scope (for a day), and explicitly distinguishes it from get_schedule and show_day by noting they only provide a one-line headline. An agent can immediately understand what this tool does and how it differs from siblings.
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 explicit when-to-use (outdoor/weather-sensitive plans, explicit user request) and when-not-to-use (indoor plans), plus names specific alternatives (get_schedule, show_day) for quick glances. The condition for choosing this tool—needing hourly detail like the dry/daylight window—is clearly stated, leaving no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_backlogManage InboxADestructiveInspect
Write to the Inbox — the tray of time-blocks captured without a time yet: intentions like "wash the car" or "call the dentist". To READ Inbox blocks, use get_schedule (backlogCount, then includeBacklog: true for the items, with backlogQuery to find one by name); THIS tool is the write surface. Pass ops, an array where each item has an op plus its fields — one or many in a single call, atomic by default (if any op fails nothing is written; pass partial: true for best-effort). Ops: capture creates an Inbox block (name, optional notes, durationMinutes, kind, checklist, areaId/activityTypeId, and an optional plannedDate or plannedDate+plannedUntil window — the still-untimed days it is meant for; pass enrich: true for RAW captured text, e.g. a web-page selection, to have AI propose a readable name and a duration first — never for a name the user chose); update edits one by id (plannedDate: null moves it back to Someday; areaId/activityTypeId: null clears the link; a task-app-linked block's date is provider-owned and refused); remove deletes one by id; schedule PLACES an Inbox block on the dial at start (local "YYYY-MM-DDTHH:MM"; its duration sizes it; pass an RRULE recurrence to make it repeat) and removes it from the Inbox; park MOVES a dial event (by id) back into the Inbox. park only works on a native or owned-calendar one-off that hasn't been reviewed — a recurring, sleep, reviewed, or not-owned event is refused with a reason. Moving a calendar-linked event to the Inbox removes its calendar copy but remembers the calendar, so re-scheduling it republishes there. Results are created / updated objects and deletedIds. Every call that writes returns one undoToken + expiresAt; pass it to undo to reverse the whole call. The Inbox needs Reassign Pro; the 7-day free trial includes it. schedule and park are inverses, and both keep the block's kind.
| Name | Required | Description | Default |
|---|---|---|---|
| ops | Yes | ||
| partial | No | Best-effort mode instead of the default all-or-nothing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations (readOnlyHint=false, destructiveHint=true). It discloses atomicity ('atomic by default... pass partial: true for best-effort'), undo behavior ('Every call that writes returns one undoToken + expiresAt'), refusal conditions for park, calendar-linked behavior ('removes its calendar copy but remembers the calendar'), and the Reassign Pro requirement. This is rich behavioral context that annotations alone do not provide.
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 dense but well-organized: it front-loads the core purpose, then explains ops in order, then covers edge cases and requirements. Every sentence carries information, though the length is substantial. It earns a 4 rather than 5 because the density could be slightly overwhelming, but it is structured logically and avoids fluff.
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 complex multi-op write tool with no output schema, the description covers the essential context: what each op does, when it fails, what results look like ('created/updated objects and deletedIds'), undo support, and licensing. An agent has enough to call this tool correctly across all five ops.
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 50%, and the description compensates by explaining the ops array structure, the meaning of each op, and key fields like plannedDate, plannedUntil, enrich, and recurrence. It doesn't restate every schema field, but it adds semantic context (e.g., 'plannedDate: null moves it back to Someday', 'schedule and park are inverses') that helps an agent use the parameters correctly. A small deduction because some field-level details are left 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 opens with a clear verb and resource ('Write to the Inbox') and immediately distinguishes this tool from the read path (get_schedule). It enumerates the five ops (capture, update, remove, schedule, park) with precise semantics, so an agent can tell exactly what this tool does and how it differs from siblings like schedule, write_events, and delete_events.
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 explicitly says when to use this tool vs alternatives: 'To READ Inbox blocks, use get_schedule... THIS tool is the write surface.' It also gives per-op conditions (e.g., 'park only works on a native or owned-calendar one-off that hasn't been reviewed', 'enrich: true ... never for a name the user chose'). This is strong routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_categoriesManage categoriesADestructiveInspect
Create, update, or delete areas (categories / groups / colour-coded labels) and activity types (tags / fill patterns) — one or many in a single call. Pass areas and/or activityTypes, each an array of ops: {op:"create", name, color?} / {op:"update", id, name?, color?} / {op:"delete", id, reassignTo?} for areas; pattern instead of color for activity types (valid patterns: solid, hatch_r, hatch_l, cross, horizontal, vertical, grid, dots, waves, chevron). Colours are lowercase "#rrggbb"; omit color or pattern to auto-pick. Editing a shared global default forks it into your own copy, so the returned id may differ — each result reports the effective id (and forkedFrom). Delete only your own (non-global) entries; if events still use one, pass reassignTo (another id) to move them first. Names are deduplicated case- and whitespace-insensitively: creating one that matches an existing area/type is rejected (reuse the existing id instead). A create or update result is the created/updated row; a delete result lists deletedIds (plus movedEvents after a reassign). Every call that writes returns one undoToken + expiresAt; pass it to undo to reverse the whole call. Atomic by default: if any op is invalid nothing is written; pass partial: true for best-effort. Create areas/types here first, then reference the returned ids in write_events.
| Name | Required | Description | Default |
|---|---|---|---|
| areas | No | ||
| partial | No | Best-effort mode instead of the default all-or-nothing. | |
| activityTypes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate destructiveHint=true, and the description thoroughly explains the destructive behaviors: deletion only of own entries, forking of shared global defaults, reassignment of events, atomicity vs partial mode, deduplication, and undo support. It adds significant context beyond the annotation, covering what happens on each op and the side effects. 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?
The description is long but dense and well-organized. It front-loads the core purpose and then systematically covers ops, parameters, forking, deletion rules, deduplication, output format, undo, atomicity, and workflow. Each sentence adds unique value; there is minimal redundancy. While lengthy, the complexity of the tool justifies it, and the structure (with semicolons and parentheticals) keeps it readable.
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 tool's complexity (two resource types, multiple ops, nested schemas, no output schema), the description covers all necessary operational details: op structures, required fields, valid patterns and colors, forking behavior, deletion constraints, reassignment, deduplication, atomic vs partial, undo token, and integration with write_events. The only minor omission is the 'order' field (only in schema), but it's not essential for core usage. Overall, an agent can correctly invoke this tool without further clarification.
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 only 33% (partial, color, pattern, reassignTo have brief descriptions). The tool description compensates comprehensively: it explains the structure of ops, required fields, optional fields like color/pattern with valid values, the meaning of reassignTo, the behavior of partial, and the semantics of areas vs activityTypes. It details the op variants (create/update/delete) and their required fields, effectively documenting all parameters beyond 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?
Description explicitly states the tool creates, updates, or deletes areas and activity types, with specific synonyms for each. It clearly distinguishes the resource types and operations, and the 'Create areas/types here first...' guidance sets it apart from sibling tools like write_events. No ambiguity about what the tool does.
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 clear when-to-use context: 'Create areas/types here first, then reference the returned ids in write_events.' It also advises on deletion constraints (only own entries) and reassignment when events still use an entry. It doesn't explicitly name alternative tools or say when not to use it, but the workflow is well implied. Lacks explicit exclusion of alternatives, but adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
review_dayReview a dayADestructiveInspect
Confirm or discard a whole day's reflection (by date, ISO YYYY-MM-DD), once you've marked its events with write_events' reflect op. action:"confirm" marks the day reviewed — "this is how it went" — freezing a per-day adherence snapshot (how closely actuals matched the plan, with per-area/per-type breakdowns), which get_schedule then returns as that day's review block and which the stats use; re-confirming refreshes it. action:"discard" fully resets the day: it removes the review, clears the kept/skipped/changed marks + actual times off the day's planned events (returned as updated), and deletes events ADDED only as part of the reflection (deletedIds) — use it to start a day's reflection over or drop one confirmed by mistake. Only a past day can be confirmed; discard works on any day, also on today's check-offs. Reversible: the response returns an undoToken; call undo before its expiresAt.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | ||
| action | Yes | "confirm" freezes the day's adherence snapshot; "discard" fully resets the day's reflection (removes the review, clears every mark). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare mutation and destructiveness (readOnlyHint=false, destructiveHint=true), leaving the description to carry the full behavioral burden — and it does, in detail. It discloses what 'confirm' freezes (adherence snapshot, re-confirm refresh), exactly what 'discard' destroys (review, kept/skipped/changed marks, actual times, reflection-added events), the per-day validity windows, and the undoToken/expiresAt reversibility mechanism.
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 nearly every sentence carries load-bearing information for a destructive, two-mode tool with no output schema. It is front-loaded with the core purpose and flows logically from confirm behavior to discard behavior to constraints to reversibility; minor structural formatting (e.g., separating the two actions) could improve scannability without adding 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 tool with two divergent behaviors, destructive side effects, and no output schema, the description is remarkably complete: it names the key return fields (`updated`, `deletedIds`, `undoToken`, `expiresAt`), downstream effects (get_schedule's `review` block, stats), prerequisites, validity restrictions, and how to undo. An agent has everything needed to call it correctly for either 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 coverage is only 50% (the `action` enum has a brief description, `date` has only type+pattern), so the description must compensate — and it does thoroughly. It confirms the date format and adds the past-day restriction, and it expands each action value far beyond the schema ('confirm' freezes a snapshot, 'discard' resets marks and deletes reflection-added events), giving the agent real semantic understanding of both parameters.
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 states a specific verb-resource pair ('Confirm or discard a whole day's reflection by `date`'), and the two action values are each given distinct, concrete meanings. It is easy to differentiate from siblings like delete_events (per-event deletion) and confirm_schedule (schedule-level confirmation) because the scope is clearly the day-level reflection state.
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 an explicit prerequisite ('once you've marked its events with write_events' `reflect` op'), concrete guidance for choosing confirm vs discard ('use it to start a day's reflection over or drop one confirmed by mistake'), and a hard constraint ('Only a past day can be confirmed; discard works on any day'). It also names the downstream consumers (get_schedule, stats) and the reversal path (undo), so an agent knows exactly when and how to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scheduleSchedule into free timeAInspect
Find conflict-free time and place one or more events — the easiest way to book work without computing slots yourself. (If you already know both an exact start AND end, use write_events create instead.) YOU resolve any relative phrasing ("tomorrow", "next monday", "this afternoon") into the structured fields; this tool does no date parsing. Pass requests, each with a name, an integer durationMinutes (e.g. 90), and EITHER an exact start (local "YYYY-MM-DDTHH:MM") to place there, OR an earliest + latest window (local datetimes, at most 24 hours; it may cross midnight) to search within (map "tomorrow afternoon" → earliest "T13:00", latest "T18:00"; "tomorrow" → "T08:00" to "T22:00"). A request with both start and a window is rejected. For each request: a free exact start is created immediately (the row result has the event). A window request returns ranked options (each a start/end span, also when only one fits) and a commitToken that expires at expiresAt — call confirm_schedule to pick one. Only autoCommitBest: true on a window request books the top pick in one shot and skips that round-trip. Requests are placed in order and kept off each other's committed slots. Each request may carry a requestId so retries don't double-book. Areas and activity types are attached by id only. If the user has a Google Calendar connected with a default sync calendar, a scheduled event is also pushed to Google, the same as a dial create. The response reports per-request results (each with its 0-based index) and, when something was booked, one undoToken that reverts it.
| Name | Required | Description | Default |
|---|---|---|---|
| render | No | When the user is looking at their reassign dial, set true to repaint it with the updated day in this same call. | |
| requests | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say the tool is not read-only and not destructive, but the description adds substantial behavioral context: no date parsing, immediate creation for exact starts, ranked options with an expiring commitToken, autoCommitBest behavior, in-order placement, requestId idempotency, Google Calendar push, and an undoToken for reverting bookings. None of this contradicts the 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 long but every sentence adds a necessary rule, example, or piece of behavior. It front-loads the core purpose and the main alternative before diving into request semantics, and the complexity of two mutually exclusive request shapes justifies the density.
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?
Despite having no output schema, the description fully explains the response shape: per-request results with 0-based indexes, options, commitToken with expiresAt, and a single undoToken. It also covers idempotency, Google Calendar integration, and ordering constraints, making the tool usable end-to-end.
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 only 50%, so the description carries the heavy lifting: it explains the exact-start vs earliest/latest window disjunction, concrete examples like mapping 'tomorrow afternoon' to specific datetimes, the 24-hour window cap, and the commit/autoCommit distinction. This goes well beyond the raw schema 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 opens with a specific verb and resource: 'Find conflict-free time and place one or more events.' It also distinguishes itself from sibling write_events by explicitly saying to use write_events when both an exact start AND end are already known.
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 explicit when-to-use guidance: choose write_events for exact start+end, and use schedule for conflict-free scheduling. It also dictates the agent's responsibility to resolve relative phrases into structured fields, warns that a request with both start and a window is rejected, and directs the caller to confirm_schedule when a commitToken is returned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_feedbackSend feedbackAInspect
Report a bug, limitation, friction, or idea about reassign itself — its tools, their results, or this MCP integration — to the product team, who read every message. Covers errors, confusing or wrong results, retries or workarounds, loops, and rough edges that could be smoother, plus feedback the user asks to send. This is meta-feedback ABOUT the product, not a way to change the schedule (use write_events for events). kind is "bug" | "idea" | "other". In message, describe what you tried, what happened, what you expected, and any event ids or steps to reproduce; send one concise report per issue rather than repeating it. Describe the problem in your own words — don't paste the user's personal details or private schedule contents; their account is attached automatically for follow-up. Returns {} once the report is accepted.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Type of feedback: "bug" for something broken or wrong, "idea" for a suggestion or feature request, "other" for anything else. | |
| message | Yes | The feedback itself. For a bug, say what happened, what you expected, and any event ids or steps that reproduce it. | |
| submissionId | No | A UUID for this submission. Reuse it with identical content on retries within 24 hours; use a new UUID for a new report. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate readOnlyHint=false, openWorldHint=true, and destructiveHint=false, so the description carries most of the burden. It adds useful behavioral context: the report goes to a product team that reads every message, the user's account is attached automatically for follow-up, and the tool returns {} once the report is accepted. It does not cover rate limits or API-level retry behavior, but submissionId in the schema addresses deduplication.
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 longer than average but every sentence carries distinct information: scope, exclusions, parameter guidance, privacy, and return value. It is front-loaded with the purpose and the schedule-change exclusion, and the added length is justified by the need for privacy and content guidance.
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 a small 3-parameter schema, no output schema, and minimal annotations, the description covers all the operational details an agent needs: what counts as feedback, what to exclude, how to phrase the message, that the user account is attached, and what the return value means. It is complete for selecting and invoking the tool 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?
Schema coverage is 100%, so the baseline is 3, but the description adds value beyond the schema by explaining what to put in message (what was tried, expected, event ids, reproduction steps), the meaning of kind, and a privacy constraint about not pasting personal details. It doesn't restate submissionId's format, which the schema already covers.
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 begins with a specific verb ('Report') and a clear resource: bugs, limitations, friction, or ideas about reassign itself and its MCP integration. It also explicitly distinguishes itself from schedule-changing operations by naming write_events, so an agent can tell it apart from siblings.
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 says exactly when to use the tool — for product/meta feedback about the product — and when not to: it is not a way to change the schedule, and write_events is named as the alternative. It also gives actionable guidance like sending one concise report per issue rather than repeating it and submitting user-requested feedback.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_dayShow day on the dialARead-onlyInspect
Render the user's day as the interactive 24-hour reassign dial, right in the conversation — use it whenever they want to SEE their day, their schedule laid out, how full it looks, or to visually move things around. Defaults to today; pass date (ISO YYYY-MM-DD) for another day. For reading or reasoning about the plan in text, prefer get_schedule.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds useful behavioral detail: it renders an interactive dial, defaults to today, and accepts ISO dates. Minor gap: the phrase 'visually move things around' could imply persistence, but readOnlyHint clarifies that this is not a mutating operation, so no contradiction exists.
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, no filler. The primary purpose is front-loaded, usage guidance follows, and the alternative is cited at the end. Every clause 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?
For a one-parameter visual renderer with readOnlyHint, the description is nearly complete. It covers purpose, usage, parameter, default, and alternative. The only small gap is not explicitly stating that interactive moves are not persisted, but this is implied by the readOnly annotation and the description's focus on 'SEE' rather than 'change.'
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?
Even though schema description coverage is 0%, the description fully explains the only parameter: 'Defaults to today; pass `date` (ISO YYYY-MM-DD) for another day.' It covers format, default, and semantics in one clause.
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 opens with a specific verb and resource: 'Render the user's day as the interactive 24-hour reassign dial.' It clearly distinguishes itself from get_schedule by contrasting visual rendering with text-based reading, so an agent can tell them apart without opening schemas.
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 states when to use: 'use it whenever they want to SEE their day, their schedule laid out, how full it looks, or to visually move things around.' It also names the alternative for text-based reasoning: 'For reading or reasoning about the plan in text, prefer get_schedule.' This is unambiguous routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undoUndo recent changesADestructiveInspect
Undo — revert, roll back, take back, or cancel the last — a recent schedule / confirm_schedule booking, a write_events / delete_events batch, a review_day action, a manage_backlog call (capture, update, remove, schedule, park), or a manage_categories call (create, update, delete). Pass tokens: the undoToken those calls returned. Each works only while still active and before its expiresAt (30 minutes). A schedule / confirm_schedule token deletes the events that call booked and voids its open proposals; the other tokens reverse the whole change (delete what it created, restore what it changed or removed). To discard a whole day's reflection by date instead, use review_day with action 'discard'. Returns per-token results.
| Name | Required | Description | Default |
|---|---|---|---|
| tokens | Yes | The `undoToken` that an earlier write returned. Every write that can be reversed returns one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations already mark the tool as destructive, the description goes beyond those booleans by specifying what each token type reverses: schedule/confirm_schedule tokens delete booked events and void proposals, while other tokens undo creations, changes, or removals. This gives an agent concrete expectations about side effects and limits.
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 dense and informative, with the purpose front-loaded and the token mechanics explained after. The initial synonym string 'revert, roll back, take back, or cancel' is redundant, but the rest of the content is purposeful and earns its place given the breadth of reversible operations.
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, reversible-action tool with no output schema, the description covers the core essentials: what to pass, how long tokens are valid, what different tokens do, what is returned, and the sibling alternative for date-based discard. It does not detail failure behavior for expired or invalid tokens, but the constraints are stated clearly enough for an agent to invoke it 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?
The schema already documents the tokens parameter at 100% coverage. The description adds valuable context by clarifying that these are the undoToken values returned by prior writes, that they expire after 30 minutes, and that each token type has distinct reversal behavior. This meaningfully supplements the schema rather than merely repeating 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?
The description clearly states the tool's purpose: undo a recent reversible operation by passing its undoToken. It explicitly enumerates which sibling operations produce such tokens, which distinguishes it from the other tools in scope. The verb 'undo / revert' is specific and matches the tool name without being a tautology.
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 explicit usage conditions: pass tokens containing the undoToken, works only while active before expiresAt (30 minutes), and returns per-token results. It also names the alternative approach for discarding a whole day via review_day with action 'discard', providing clear when-to-use vs when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_eventsWrite eventsAInspect
Create, update (edit, move, resize), shift, reflect, or manage a block's checklist — one or many in a single call. Pass ops, an array where each item has an op (create | update | shift | reflect | checklist) plus that op's fields; a single edit is a 1-item array. A span is start + end as local datetimes "YYYY-MM-DDTHH:MM" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event simply ends on a later day. A bare series id addresses the whole series; seriesId@YYYY-MM-DD addresses one occurrence; add scope:"future" to an occurrence id for that occurrence and every later one. update with start/end moves or resizes an event, also to another day; a lone start keeps the duration and a lone end keeps the start. shift nudges by byMinutes. reflect records how a PAST planned event actually went (kept | skipped | changed | added; actual times only for changed/added) — it never renames or re-times the plan. checklist manages a block's microtasks: items replaces the ordered list (bare id = the series template, occurrence id = that day), and check/uncheck take item ids and tick them off for one occurrence. Recurrence is an RRULE; null on update stops the repeat. Reference areas and activity types by areaId/activityTypeId (null on update clears the link; null on create is the same as omitted); create new ones first with manage_categories. calendarId is the home calendar (omit = the default calendar, null = dial only) and mirrorCalendarIds the one-way copies. If you know the duration but not a conflict-free time, use schedule instead of a create. By default the whole batch is atomic: if ANY op fails (e.g. a conflict), nothing is written and the failing ops are returned as errors — fix and resend. Pass partial: true for best-effort. Ops apply in order as one transaction and are checked against each other: two creates can't double-book a slot, and an earlier move frees a slot a later op can reuse. Target each event id at most once per batch. Changes to a calendar-linked event also reach that calendar; don't edit an event marked readOnly (the change would silently revert). To remove events or clear days use delete_events. The response has per-op results (each with its 0-based index), one undoToken + expiresAt, and timezone when a result carries a span.
| Name | Required | Description | Default |
|---|---|---|---|
| ops | Yes | ||
| render | No | When the user is looking at their reassign dial, set true to repaint it with the updated day in this same call. Otherwise the change reaches an open dial only if the host forwards this result. | |
| partial | No | Best-effort mode: apply the ops that succeed and report the rest as errors, instead of the default all-or-nothing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are minimal (three hints), so the description carries the behavioral burden and does so thoroughly: it discloses default atomicity with all-or-nothing semantics on any failure, transactional ordering with cross-op conflict checking, the one-id-per-batch constraint, the readOnly silent-revert pitfall, calendar-link propagation to mirrors, and the response shape (per-op results, undoToken, expiresAt, timezone). No contradiction with the 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 front-loaded with the purpose and op list, and every sentence earns its place given the tool's complexity — five op types plus cross-cutting semantics, atomicity, and routing. However, it is a single dense paragraph; breaking it into op-type or concern-based sections would improve scannability for agents.
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 tool with five op variants, no output schema, and minimal annotations, the description is remarkably complete: it covers edge cases (duration-preserving moves, overnight events), failure/retry behavior with partial mode, intra-batch conflict checking, series occurrence addressing, and the readOnly warning. An agent has everything needed to invoke it 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?
Despite 67% schema coverage, the description adds substantial meaning: the time format constraint is repeated, and it explains op-specific semantics the schema cannot — lone start keeps duration, lone end keeps start, series addressing forms (bare id vs seriesId@YYYY-MM-DD vs scope:"future"), reflect's non-mutating behavior, and null-clears versus omit-keeps distinctions across 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 states specific verbs and a resource: create, update, shift, reflect, and checklist operations on blocks/events, in one batch call. It differentiates from siblings explicitly — 'use `schedule` instead of a create' when duration is known but a conflict-free time isn't, and 'use delete_events' for removal — so an agent can distinguish it without opening schemas.
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 explicit when-to-use guidance: create new categories first with manage_categories, prefer schedule when a conflict-free slot isn't known, and route removal to delete_events. It also explains when partial:true is appropriate (best-effort) versus the default atomic batch, leaving nothing to inference.
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.
2 tool updates
- Changed
schedule1 field changed- changed
Input schema / properties / requests / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "description": "An exact request: book at `start`.", - "properties": { - "activityTypeId": { - "description": "Activity-type id to attach (from the schedule read's `activityTypes`); null or omitted leaves it unset.", - "type": [ - "string", - "null" - ] - }, - "areaId": { - "description": "Area id to attach (from the schedule read's `areas`); null or omitted leaves it unset.", - "type": [ - "string", - "null" - ] - }, - "durationMinutes": { - "description": "How long, in whole minutes, e.g. 90.", - "maximum": 1440, - "minimum": 5, - "type": "integer" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", - "enum": [ - "blocking", - "non_blocking", - "reference" - ], - "type": "string" - }, - "name": { - "description": "Event title, e.g. \"Deep work\", \"Gym\".", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "recurrence": { - "description": "Repeat rule as an RRULE, e.g. \"FREQ=WEEKLY;BYDAY=MO\"; omit for a one-off.", - "type": "string" - }, - "requestId": { - "description": "Idempotency key; reuse on retry to avoid double-booking.", - "type": "string" - }, - "sourceUrl": { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - "start": { - "description": "Exact local start \"YYYY-MM-DDTHH:MM\"; place there (alternatives proposed on a conflict).", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - } - }, - "required": [ - "name", - "durationMinutes", - "start" - ], - "type": "object" - }, - { - "additionalProperties": false, - "description": "A window request: search from `earliest` to `latest`, at most 24 hours.", - "properties": { - "activityTypeId": { - "description": "Activity-type id to attach (from the schedule read's `activityTypes`); null or omitted leaves it unset.", - "type": [ - "string", - "null" - ] - }, - "areaId": { - "description": "Area id to attach (from the schedule read's `areas`); null or omitted leaves it unset.", - "type": [ - "string", - "null" - ] - }, - "autoCommitBest": { - "description": "When true, immediately book the top-ranked slot instead of returning `options` + a commitToken. Use for routine one-shot bookings (\"block 2h this afternoon\") to skip the confirm step; leave off (the default) when slots are scarce/contested and you want to review options first.", - "type": "boolean" - }, - "durationMinutes": { - "description": "How long, in whole minutes, e.g. 90.", - "maximum": 1440, - "minimum": 5, - "type": "integer" - }, - "earliest": { - "description": "Start of the local \"YYYY-MM-DDTHH:MM\" window to search.", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", - "enum": [ - "blocking", - "non_blocking", - "reference" - ], - "type": "string" - }, - "latest": { - "description": "End of the search window: after `earliest` and at most 24 hours later; it may be on the next day.", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - }, - "name": { - "description": "Event title, e.g. \"Deep work\", \"Gym\".", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "recurrence": { - "description": "Repeat rule as an RRULE, e.g. \"FREQ=WEEKLY;BYDAY=MO\"; omit for a one-off.", - "type": "string" - }, - "requestId": { - "description": "Idempotency key; reuse on retry to avoid double-booking.", - "type": "string" - }, - "sourceUrl": { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - } - }, - "required": [ - "name", - "durationMinutes", - "earliest", - "latest" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "description": "An exact request: book at `start`.", + "properties": { + "activityTypeId": { + "description": "Activity-type id to attach (from the schedule read's `activityTypes`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "Area id to attach (from the schedule read's `areas`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "durationMinutes": { + "description": "How long, in whole minutes, e.g. 90.", + "maximum": 1440, + "minimum": 5, + "type": "integer" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "name": { + "description": "Event title, e.g. \"Deep work\", \"Gym\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "recurrence": { + "description": "Repeat rule as an RRULE, e.g. \"FREQ=WEEKLY;BYDAY=MO\"; omit for a one-off.", + "type": "string" + }, + "requestId": { + "description": "Idempotency key; reuse on retry to avoid double-booking. Only this key replays: a request without it is always booked as new.", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + "start": { + "description": "Exact local start \"YYYY-MM-DDTHH:MM\"; place there (alternatives proposed on a conflict).", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + } + }, + "required": [ + "name", + "durationMinutes", + "start" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A window request: search from `earliest` to `latest`, at most 24 hours.", + "properties": { + "activityTypeId": { + "description": "Activity-type id to attach (from the schedule read's `activityTypes`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "Area id to attach (from the schedule read's `areas`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "autoCommitBest": { + "description": "When true, immediately book the top-ranked slot instead of returning `options` + a commitToken. Use for routine one-shot bookings (\"block 2h this afternoon\") to skip the confirm step. Omitted or false never books, also when only one slot fits: the result is `options` + a commitToken to review first.", + "type": "boolean" + }, + "durationMinutes": { + "description": "How long, in whole minutes, e.g. 90.", + "maximum": 1440, + "minimum": 5, + "type": "integer" + }, + "earliest": { + "description": "Start of the local \"YYYY-MM-DDTHH:MM\" window to search.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "latest": { + "description": "End of the search window: after `earliest` and at most 24 hours later; it may be on the next day.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "name": { + "description": "Event title, e.g. \"Deep work\", \"Gym\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "recurrence": { + "description": "Repeat rule as an RRULE, e.g. \"FREQ=WEEKLY;BYDAY=MO\"; omit for a one-off.", + "type": "string" + }, + "requestId": { + "description": "Idempotency key; reuse on retry to avoid double-booking. Only this key replays: a request without it is always booked as new.", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + } + }, + "required": [ + "name", + "durationMinutes", + "earliest", + "latest" + ], + "type": "object" + } +]
- Changed
write_events1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "activityTypeId": { - "description": "The activity type id (from the schedule read). null or omitted leaves it unset.", - "type": [ - "string", - "null" - ] - }, - "areaId": { - "description": "The area id (from the schedule read). null or omitted leaves it unset.", - "type": [ - "string", - "null" - ] - }, - "calendarId": { - "description": "The home calendar: a calendar id (from the calendars list or the schedule's `integrations`). Omit it to use the account's default calendar if one is set, else the event stays on the dial only. null keeps the event on the dial only. A calendar id requires Reassign Pro; whole-series only.", - "type": [ - "string", - "null" - ] - }, - "checklist": { - "additionalProperties": false, - "description": "Starter microtasks written to the new event's checklist.", - "properties": { - "items": { - "items": { - "additionalProperties": false, - "properties": { - "done": { - "description": "true ticks the item off, false clears it; omit to keep the current state (a new item starts not done).", - "type": "boolean" - }, - "id": { - "description": "Keep an existing item's id; omit for a new item.", - "minLength": 1, - "type": "string" - }, - "text": { - "maxLength": 200, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - }, - "maxItems": 100, - "type": "array" - } - }, - "required": [ - "items" - ], - "type": "object" - }, - "end": { - "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day.", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - }, - "focusIntervals": { - "additionalProperties": false, - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus. A non_blocking or reference event rejects it.", - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - "id": { - "description": "Optional client-minted event id, so the caller can read the new event back by a known id. Omit it and the server mints one.", - "type": "string" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non_blocking", - "reference" - ], - "type": "string" - }, - "mirrorCalendarIds": { - "description": "The one-way copy calendars, as calendar ids. It must not contain the home `calendarId`. On update it REPLACES the set; [] clears it. Requires Reassign Pro; whole-series only.", - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats, as an RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive last day of the repeat, \"YYYY-MM-DD\". Needs `recurrence`.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "sourceUrl": { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - "start": { - "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Its day is the event's day.", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - } - }, - "required": [ - "op", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "activityTypeId": { - "description": "The activity type id (from the schedule read). null clears the link; omit to keep it.", - "type": [ - "string", - "null" - ] - }, - "areaId": { - "description": "The area id (from the schedule read). null clears the link; omit to keep it.", - "type": [ - "string", - "null" - ] - }, - "calendarId": { - "description": "Re-home the event: a calendar id (from the calendars list or the schedule's `integrations`) moves it to that calendar; null unlinks it (keeps the dial block). Omit to keep the current home. Requires Reassign Pro; whole-series only.", - "type": [ - "string", - "null" - ] - }, - "end": { - "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. A lone end keeps the start.", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - }, - "focusIntervals": { - "anyOf": [ - { - "additionalProperties": false, - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus. A non_blocking or reference event rejects it. Pass null to remove an existing rhythm." - }, - "id": { - "description": "The event id from a read. A bare series id addresses the whole series; `seriesId@YYYY-MM-DD` addresses one occurrence.", - "minLength": 1, - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non_blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non_blocking", - "reference" - ], - "type": "string" - }, - "mirrorCalendarIds": { - "description": "The one-way copy calendars, as calendar ids. It must not contain the home `calendarId`. On update it REPLACES the set; [] clears it. Requires Reassign Pro; whole-series only.", - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "A new RRULE for the series; null stops the repeat.", - "type": [ - "string", - "null" - ] - }, - "recurrenceEnd": { - "description": "Inclusive last day of the repeat, \"YYYY-MM-DD\". Needs `recurrence`.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "scope": { - "const": "future", - "description": "Only with a `seriesId@YYYY-MM-DD` id: \"future\" edits that occurrence and every later one. Omit it to edit only that occurrence; a bare series id edits the whole series.", - "type": "string" - }, - "sourceUrl": { - "anyOf": [ - { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Replace where this event was captured from (http(s)); null clears it. Whole-series only." - }, - "start": { - "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. A new start moves the event, also to another day (on an occurrence id, that occurrence only). A lone start keeps the duration.", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "description": "The event id from a read. A bare series id addresses the whole series; `seriesId@YYYY-MM-DD` addresses one occurrence.", - "minLength": 1, - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "const": "future", - "description": "Only with a `seriesId@YYYY-MM-DD` id: \"future\" edits that occurrence and every later one. Omit it to edit only that occurrence; a bare series id edits the whole series.", - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "actualEnd": { - "description": "When it actually ended. Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Send it with actualStart, only for \"changed\" or \"added\".", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - }, - "actualStart": { - "description": "When it actually started. Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Send it with actualEnd, only for \"changed\" or \"added\".", - "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", - "type": "string" - }, - "id": { - "description": "The event id, echoed verbatim from a schedule or search read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", - "type": "string" - }, - "op": { - "const": "reflect", - "type": "string" - }, - "status": { - "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart + actualEnd to record the real time); \"added\" = unplanned but happened (its actualStart + actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", - "enum": [ - "kept", - "skipped", - "changed", - "added" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "status" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "check": { - "description": "Item ids to mark DONE for the occurrence. On a recurring event this ticks off that occurrence only.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "id": { - "description": "The event id, echoed verbatim from a schedule or search read. A bare series id edits the template of the whole series; the `seriesId@YYYY-MM-DD` id edits or ticks off that one occurrence.", - "type": "string" - }, - "items": { - "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", - "items": { - "additionalProperties": false, - "properties": { - "done": { - "description": "true ticks the item off, false clears it; omit to keep the current state (a new item starts not done).", - "type": "boolean" - }, - "id": { - "description": "Keep an existing item's id; omit for a new item.", - "minLength": 1, - "type": "string" - }, - "text": { - "maxLength": 200, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - }, - "maxItems": 100, - "type": "array" - }, - "op": { - "const": "checklist", - "type": "string" - }, - "uncheck": { - "description": "Item ids to mark NOT-done for the occurrence.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "activityTypeId": { + "description": "The activity type id (from the schedule read). null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "The area id (from the schedule read). null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "calendarId": { + "description": "The home calendar: a calendar id (from the calendars list or the schedule's `integrations`). Omit it to use the account's default calendar if one is set, else the event stays on the dial only. null keeps the event on the dial only. A calendar id requires Reassign Pro; whole-series only.", + "type": [ + "string", + "null" + ] + }, + "checklist": { + "additionalProperties": false, + "description": "Starter microtasks written to the new event's checklist.", + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "done": { + "description": "true ticks the item off, false clears it; omit to keep the current state (a new item starts not done).", + "type": "boolean" + }, + "id": { + "description": "Keep an existing item's id; omit for a new item.", + "minLength": 1, + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + }, + "end": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "focusIntervals": { + "additionalProperties": false, + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus. A non_blocking or reference event rejects it.", + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + "id": { + "description": "Optional client-minted event id, so the caller can read the new event back by a known id. Omit it and the server mints one.", + "type": "string" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "mirrorCalendarIds": { + "description": "The one-way copy calendars, as calendar ids. It must not contain the home `calendarId`. On update it REPLACES the set; [] clears it. An id already on the event may stay even if its calendar is read-only now; only an added id is checked. Adding an id requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats, as an RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive last day of the repeat, \"YYYY-MM-DD\". Needs `recurrence`.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + "start": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Its day is the event's day.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + } + }, + "required": [ + "op", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "activityTypeId": { + "description": "The activity type id (from the schedule read). null clears the link; omit to keep it.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "The area id (from the schedule read). null clears the link; omit to keep it.", + "type": [ + "string", + "null" + ] + }, + "calendarId": { + "description": "Re-home the event: a calendar id (from the calendars list or the schedule's `integrations`) moves it to that calendar; null unlinks it and deletes its mirror copies (keeps the dial block). An unlink may carry start, end, name, notes, areaId, activityTypeId and kind, applied first in the same write. Omit to keep the current home. A calendar id requires Reassign Pro; whole-series only.", + "type": [ + "string", + "null" + ] + }, + "end": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. A lone end keeps the start.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "focusIntervals": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus. A non_blocking or reference event rejects it. Pass null to remove an existing rhythm." + }, + "id": { + "description": "The event id from a read. A bare series id addresses the whole series; `seriesId@YYYY-MM-DD` addresses one occurrence.", + "minLength": 1, + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non_blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "mirrorCalendarIds": { + "description": "The one-way copy calendars, as calendar ids. It must not contain the home `calendarId`. On update it REPLACES the set; [] clears it. An id already on the event may stay even if its calendar is read-only now; only an added id is checked. Adding an id requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "A new RRULE for the series; null stops the repeat.", + "type": [ + "string", + "null" + ] + }, + "recurrenceEnd": { + "description": "Inclusive last day of the repeat, \"YYYY-MM-DD\". Needs `recurrence`.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "scope": { + "const": "future", + "description": "Only with a `seriesId@YYYY-MM-DD` id: \"future\" edits that occurrence and every later one. Omit it to edit only that occurrence; a bare series id edits the whole series.", + "type": "string" + }, + "sourceUrl": { + "anyOf": [ + { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Replace where this event was captured from (http(s)); null clears it. Whole-series only." + }, + "start": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. A new start moves the event, also to another day (on an occurrence id, that occurrence only). A lone start keeps the duration.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "description": "The event id from a read. A bare series id addresses the whole series; `seriesId@YYYY-MM-DD` addresses one occurrence.", + "minLength": 1, + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "const": "future", + "description": "Only with a `seriesId@YYYY-MM-DD` id: \"future\" edits that occurrence and every later one. Omit it to edit only that occurrence; a bare series id edits the whole series.", + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "actualEnd": { + "description": "When it actually ended. Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Send it with actualStart, only for \"changed\" or \"added\".", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "actualStart": { + "description": "When it actually started. Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Send it with actualEnd, only for \"changed\" or \"added\".", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "id": { + "description": "The event id, echoed verbatim from a schedule or search read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", + "type": "string" + }, + "op": { + "const": "reflect", + "type": "string" + }, + "status": { + "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart + actualEnd to record the real time); \"added\" = unplanned but happened (its actualStart + actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", + "enum": [ + "kept", + "skipped", + "changed", + "added" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "status" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "check": { + "description": "Item ids to mark DONE for the occurrence. On a recurring event this ticks off that occurrence only.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "id": { + "description": "The event id, echoed verbatim from a schedule or search read. A bare series id edits the template of the whole series; the `seriesId@YYYY-MM-DD` id edits or ticks off that one occurrence.", + "type": "string" + }, + "items": { + "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", + "items": { + "additionalProperties": false, + "properties": { + "done": { + "description": "true ticks the item off, false clears it; omit to keep the current state (a new item starts not done).", + "type": "boolean" + }, + "id": { + "description": "Keep an existing item's id; omit for a new item.", + "minLength": 1, + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "op": { + "const": "checklist", + "type": "string" + }, + "uncheck": { + "description": "Item ids to mark NOT-done for the occurrence.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
1 tool update
- Added
get_more_tools
14 tool updates
- Changed
confirm_schedule2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / items / items / additionalPropertiesAdded value: +false
- Changed
delete_events4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / conciseRemoved value: -{ - "description": "Drop the human-readable `suggestedFollowup` prose from the response (the structured `undoToken` is still returned). Saves tokens.", - "type": "boolean" -} - removed
Input schema / properties / ops / items / defaultRemoved value: -{ - "op": "__invalid__" -} - changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "delete", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "Day to clear, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "clear", - "type": "string" - }, - "to": { - "description": "Optional inclusive range end.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - } - }, - "required": [ - "op", - "date" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "id": { + "description": "The event id from a read. A bare series id addresses the whole series; `seriesId@YYYY-MM-DD` addresses one occurrence.", + "minLength": 1, + "type": "string" + }, + "op": { + "const": "delete", + "type": "string" + }, + "scope": { + "const": "future", + "description": "Only with a `seriesId@YYYY-MM-DD` id: \"future\" edits that occurrence and every later one. Omit it to edit only that occurrence; a bare series id edits the whole series.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "description": "First day to clear, ISO \"YYYY-MM-DD\".", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "clear", + "type": "string" + }, + "to": { + "description": "Last day to clear (inclusive), ISO \"YYYY-MM-DD\". Equal to `from` for one day.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + } + }, + "required": [ + "op", + "from", + "to" + ], + "type": "object" + } +]
- Changed
find_event2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / timeOfDay / descriptionPrevious value: -"Only match events starting in this part of the day."New value: +"Only match events that start in this part of the day."
- Changed
get_energy1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_schedule11 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / backlogOffset / descriptionPrevious value: -"Inbox page offset from nextBacklogOffset; keep the same filters. Implies includeBacklog."New value: +"Inbox page offset from nextBacklogOffset; keep the same filters. Needs includeBacklog: true." - changed
Input schema / properties / backlogPlannedOn / descriptionPrevious value: -"Filter the Inbox blocks to those PLANNED for this day (a block's planned day, or a planned window covering it) — e.g. today's date to answer \"what did I plan to get to today?\". Implies includeBacklog; composes with backlogQuery. Overdue blocks carry `overdue: true` on the unfiltered read instead."New value: +"Filter the Inbox blocks to those planned for this day (a planned day, or a planned window that covers it). Needs includeBacklog: true; composes with backlogQuery." - changed
Input schema / properties / backlogQuery / descriptionPrevious value: -"Filter the Inbox blocks by name (fuzzy, case/accent-insensitive) — e.g. \"dentist\". Implies includeBacklog; use it to FIND a specific Inbox block by name instead of paging the whole Inbox."New value: +"Filter the Inbox blocks by name (fuzzy, case/accent-insensitive), e.g. \"dentist\". Needs includeBacklog: true." - removed
Input schema / properties / compactRemoved value: -{ - "type": "boolean" -} - removed
Input schema / properties / dateRemoved value: -{ - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" -} - removed
Input schema / properties / datesRemoved value: -{ - "items": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "maxItems": 366, - "type": "array" -} - added
Input schema / properties / from / descriptionAdded value: +"First day of the range, inclusive." - added
Input schema / properties / includeSeries / descriptionAdded value: +"Also return the recurring masters as `series`." - added
Input schema / properties / to / descriptionAdded value: +"Last day of the range, inclusive." - added
Input schema / requiredAdded value: +[ + "from", + "to" +]
- Changed
get_weather1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
manage_backlog2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "enrich": { - "description": "Let AI clean this capture up before it is saved: propose a better name, estimate durationHours, and copy out any microtasks the captured text spells out. For RAW captures only — text grabbed off a web page, where the name is a paragraph rather than an intention. Do NOT set it for something the user typed or dictated: it may RENAME the block, and a name they chose must stand. Fields you send yourself always win; only the name can be replaced.", - "type": "boolean" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "capture", - "type": "string" - }, - "plannedDate": { - "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "plannedUntil": { - "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "sourceUrl": { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - "steps": { - "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). An Inbox block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "type": "array" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id.", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "id": { - "description": "The Inbox block id (from get_schedule's `backlog`).", - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "plannedDate": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." - }, - "plannedUntil": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." - }, - "sourceUrl": { - "anyOf": [ - { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Replace where this block was captured from (http(s)); null clears the source chip." - }, - "steps": { - "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). An Inbox block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "type": "array" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "description": "The Inbox block id to delete from the Inbox.", - "type": "string" - }, - "op": { - "const": "remove", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "description": "The Inbox block id to place on the dial.", - "type": "string" - }, - "op": { - "const": "schedule", - "type": "string" - }, - "recurrence": { - "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "start": { - "description": "Start time HH:MM; duration comes from the block.", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id", - "date", - "start" - ], - "type": "object" - }, - { - "properties": { - "eventId": { - "description": "The dial event id to move to the Inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", - "type": "string" - }, - "op": { - "const": "park", - "type": "string" - } - }, - "required": [ - "op", - "eventId" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "activityTypeId": { + "description": "The activity type id. null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "The area id. null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "checklist": { + "additionalProperties": false, + "description": "The block's microtasks, in order — REPLACES the whole list (send every item you want kept; an empty `items` clears them). An Inbox block has no occurrence, so nothing is ticked off until it is scheduled.", + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "description": "Keep an item id from a read; omit for a new item.", + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + }, + "durationMinutes": { + "description": "Estimated length in whole minutes, 5 to 1440. Sizes the block when placed.", + "maximum": 1440, + "minimum": 5, + "type": "integer" + }, + "enrich": { + "description": "Let AI clean this capture up before it is saved: propose a better name, estimate durationMinutes, and copy out any microtasks the captured text spells out. For RAW captures only — text grabbed off a web page, where the name is a paragraph rather than an intention. Do NOT set it for something the user typed or dictated: it may RENAME the block, and a name they chose must stand. Fields you send yourself always win; only the name can be replaced.", + "type": "boolean" + }, + "kind": { + "description": "The kind the event takes when scheduled: \"blocking\" occupies time, \"non_blocking\" is an overlay that may overlap others, \"reference\" is something to see but not do. Omit for \"blocking\".", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "capture", + "type": "string" + }, + "plannedDate": { + "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "plannedUntil": { + "description": "Inclusive end of a planned window; it must fall after plannedDate.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "activityTypeId": { + "description": "The activity type id. null clears the link; omit to keep it.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "The area id. null clears the link; omit to keep it.", + "type": [ + "string", + "null" + ] + }, + "checklist": { + "additionalProperties": false, + "description": "The block's microtasks, in order — REPLACES the whole list (send every item you want kept; an empty `items` clears them). An Inbox block has no occurrence, so nothing is ticked off until it is scheduled.", + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "description": "Keep an item id from a read; omit for a new item.", + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + }, + "durationMinutes": { + "description": "Estimated length in whole minutes, 5 to 1440. Sizes the block when placed.", + "maximum": 1440, + "minimum": 5, + "type": "integer" + }, + "id": { + "description": "The Inbox block id (from the schedule read's `backlog`).", + "type": "string" + }, + "kind": { + "description": "The kind the event takes when scheduled: \"blocking\" occupies time, \"non_blocking\" is an overlay that may overlap others, \"reference\" is something to see but not do. Omit to keep it.", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "plannedDate": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Google Tasks, Microsoft To Do and Linear sync this date both ways. Todoist dates must be changed in Todoist." + }, + "plannedUntil": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Inclusive end of a planned window; it must fall after plannedDate. null collapses the window to one day." + }, + "sourceUrl": { + "anyOf": [ + { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Replace where this block was captured from (http(s)); null clears the source chip." + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "description": "The Inbox block id to delete from the Inbox.", + "type": "string" + }, + "op": { + "const": "remove", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "description": "The Inbox block id to place on the dial.", + "type": "string" + }, + "op": { + "const": "schedule", + "type": "string" + }, + "recurrence": { + "description": "Optionally make the placed block repeat, as an RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "start": { + "description": "Local start \"YYYY-MM-DDTHH:MM\"; the block's duration sizes it.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + } + }, + "required": [ + "op", + "id", + "start" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "description": "The dial event id to move to the Inbox (from a schedule or search read). Must be a native or owned-calendar one-off that hasn't been reviewed.", + "type": "string" + }, + "op": { + "const": "park", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
- Changed
manage_categories3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / activityTypes / items / oneOfPrevious value: -[ - { - "properties": { - "id": { - "type": "string" - }, - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "pattern": { - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "id": { - "type": "string" - }, - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "order": { - "type": "number" - }, - "pattern": { - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "type": "string" - }, - "op": { - "const": "delete", - "type": "string" - }, - "reassignTo": { - "description": "Another activity type's id to move events onto; required if events still use this type.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "pattern": { + "description": "A fill pattern; omit to auto-pick.", + "enum": [ + "solid", + "hatch_r", + "hatch_l", + "cross", + "horizontal", + "vertical", + "grid", + "dots", + "waves", + "chevron" + ], + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "order": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "pattern": { + "description": "A fill pattern; omit to auto-pick.", + "enum": [ + "solid", + "hatch_r", + "hatch_l", + "cross", + "horizontal", + "vertical", + "grid", + "dots", + "waves", + "chevron" + ], + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "op": { + "const": "delete", + "type": "string" + }, + "reassignTo": { + "description": "Another activity type's id to move events onto; required if events still use this type.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +] - changed
Input schema / properties / areas / items / oneOfPrevious value: -[ - { - "properties": { - "color": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "color": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "order": { - "type": "number" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "type": "string" - }, - "op": { - "const": "delete", - "type": "string" - }, - "reassignTo": { - "description": "Another area's id to move events onto; required if events still use this area.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "color": { + "description": "Lowercase \"#rrggbb\"; omit to auto-pick.", + "pattern": "^#[0-9a-f]{6}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "color": { + "description": "Lowercase \"#rrggbb\"; omit to auto-pick.", + "pattern": "^#[0-9a-f]{6}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "order": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "op": { + "const": "delete", + "type": "string" + }, + "reassignTo": { + "description": "Another area's id to move events onto; required if events still use this area.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
- Changed
review_day2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / action / descriptionPrevious value: -"\"confirm\" freezes the day's adherence snapshot; \"discard\" fully resets the day's reflection (deletes the marker, clears every mark)."New value: +"\"confirm\" freezes the day's adherence snapshot; \"discard\" fully resets the day's reflection (removes the review, clears every mark)."
- Changed
schedule5 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / requests / items / anyOfAdded value: +[ + { + "additionalProperties": false, + "description": "An exact request: book at `start`.", + "properties": { + "activityTypeId": { + "description": "Activity-type id to attach (from the schedule read's `activityTypes`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "Area id to attach (from the schedule read's `areas`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "durationMinutes": { + "description": "How long, in whole minutes, e.g. 90.", + "maximum": 1440, + "minimum": 5, + "type": "integer" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "name": { + "description": "Event title, e.g. \"Deep work\", \"Gym\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "recurrence": { + "description": "Repeat rule as an RRULE, e.g. \"FREQ=WEEKLY;BYDAY=MO\"; omit for a one-off.", + "type": "string" + }, + "requestId": { + "description": "Idempotency key; reuse on retry to avoid double-booking.", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + "start": { + "description": "Exact local start \"YYYY-MM-DDTHH:MM\"; place there (alternatives proposed on a conflict).", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + } + }, + "required": [ + "name", + "durationMinutes", + "start" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A window request: search from `earliest` to `latest`, at most 24 hours.", + "properties": { + "activityTypeId": { + "description": "Activity-type id to attach (from the schedule read's `activityTypes`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "Area id to attach (from the schedule read's `areas`); null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "autoCommitBest": { + "description": "When true, immediately book the top-ranked slot instead of returning `options` + a commitToken. Use for routine one-shot bookings (\"block 2h this afternoon\") to skip the confirm step; leave off (the default) when slots are scarce/contested and you want to review options first.", + "type": "boolean" + }, + "durationMinutes": { + "description": "How long, in whole minutes, e.g. 90.", + "maximum": 1440, + "minimum": 5, + "type": "integer" + }, + "earliest": { + "description": "Start of the local \"YYYY-MM-DDTHH:MM\" window to search.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "latest": { + "description": "End of the search window: after `earliest` and at most 24 hours later; it may be on the next day.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "name": { + "description": "Event title, e.g. \"Deep work\", \"Gym\".", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "recurrence": { + "description": "Repeat rule as an RRULE, e.g. \"FREQ=WEEKLY;BYDAY=MO\"; omit for a one-off.", + "type": "string" + }, + "requestId": { + "description": "Idempotency key; reuse on retry to avoid double-booking.", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + } + }, + "required": [ + "name", + "durationMinutes", + "earliest", + "latest" + ], + "type": "object" + } +] - removed
Input schema / properties / requests / items / propertiesRemoved value: -{ - "activityTypeId": { - "description": "Activity-type id to attach.", - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "description": "Area id to attach.", - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "autoCommitBest": { - "description": "Flexible requests only (an `earliest`/`latest` window, or neither — NOT an exact `start`). When true, immediately book the top-ranked slot instead of returning `options` + a commitToken. Use for routine one-shot bookings (\"block 2h this afternoon\") to skip the confirm_schedule round-trip; leave off (the default) when slots are scarce/contested and you want to review options first.", - "type": "boolean" - }, - "date": { - "description": "Day to place on, ISO \"YYYY-MM-DD\" (you resolve \"tomorrow\" etc.).", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "duration": { - "description": "How long, e.g. \"90m\", \"1h30\", \"2h\", \"45 min\".", - "type": "string" - }, - "earliest": { - "description": "Lower bound of an \"HH:MM\" window to search within; omit `start` to use a window.", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "latest": { - "description": "Upper bound of the \"HH:MM\" search window.", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "name": { - "description": "Event title, e.g. \"Deep work\", \"Gym\".", - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "recurrence": { - "description": "Repeat rule (preset or RRULE); omit for a one-off.", - "type": "string" - }, - "request_id": { - "description": "Idempotency key; reuse on retry to avoid double-booking.", - "type": "string" - }, - "sourceUrl": { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - "start": { - "description": "Exact 24-hour \"HH:MM\" start; given ⇒ place there (alternatives proposed on a conflict).", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } -} - removed
Input schema / properties / requests / items / requiredRemoved value: -[ - "name", - "duration", - "date" -] - removed
Input schema / properties / requests / items / typeRemoved value: -"object"
- Changed
send_feedback1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
show_day1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
undo2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / tokens / descriptionPrevious value: -"undoToken(s) returned by schedule, confirm_schedule, write_events, delete_events, review_day, or manage_backlog (incl. a `batchUndoToken`)."New value: +"The `undoToken` that an earlier write returned. Every write that can be reversed returns one."
- Changed
write_events4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / conciseRemoved value: -{ - "description": "Drop the human-readable `suggestedFollowup` prose from the response (the structured `undoToken` is still returned). Saves tokens.", - "type": "boolean" -} - removed
Input schema / properties / ops / items / defaultRemoved value: -{ - "op": "__invalid__" -} - changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "checklist": { - "description": "Starter microtasks written to the new event's checklist.", - "items": { - "properties": { - "id": { - "type": "string" - }, - "text": { - "maxLength": 200, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - }, - "maxItems": 100, - "type": "array" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - "id": { - "description": "Optional client-minted section id. The onboarding funnel supplies it so the reveal step can read the new rows back; omit to let the server mint.", - "type": "string" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "mirrorTo": { - "description": "Also fan this event out as one-way copies to these calendar ids (on top of the home from `syncTo`). The home id is dropped if listed. Requires Reassign Pro; whole-series only.", - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "description": "Publish this event to one of the user's calendars: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`). Omit to follow the user's default calendar; pass null to force it dial-only. Requires Reassign Pro; whole-series only.", - "type": [ - "string", - "null" - ] - } - }, - "required": [ - "op", - "date", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "anyOf": [ - { - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." - }, - "id": { - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "mirrorTo": { - "description": "Replace the one-way copy set with these calendar ids; pass [] to clear all copies. The home calendar is dropped if listed. Requires Reassign Pro; whole-series only.", - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "description": "Re-home this event: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`) moves it to that calendar; null unlinks it (removes it from the calendar, keeps the dial block). Omit to leave the current home. Requires Reassign Pro; whole-series only.", - "type": [ - "string", - "null" - ] - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "New date, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "move", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "description": "New start time, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - }, - { - "properties": { - "actualEnd": { - "description": "When it actually ended, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "actualEndNextDay": { - "description": "Set true when the actual run crossed midnight.", - "type": "boolean" - }, - "actualStart": { - "description": "When it actually started, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", - "type": "string" - }, - "op": { - "const": "reflect", - "type": "string" - }, - "status": { - "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", - "enum": [ - "kept", - "skipped", - "changed", - "added" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "status" - ], - "type": "object" - }, - { - "properties": { - "check": { - "description": "Mark these items DONE for the occurrence, by item id or exact text. On a recurring event this ticks off THIS occurrence only.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To edit or tick off ONE occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day.", - "type": "string" - }, - "items": { - "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", - "items": { - "properties": { - "id": { - "description": "Keep an existing item's id (from a read) to preserve its checked state; omit to add a new microtask.", - "type": "string" - }, - "text": { - "maxLength": 200, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - }, - "maxItems": 100, - "type": "array" - }, - "occurrenceDate": { - "description": "The occurrence to edit, \"YYYY-MM-DD\", for a scope:\"this\" template edit on a recurring event (or supply the composite `seriesId@YYYY-MM-DD` id).", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "checklist", - "type": "string" - }, - "scope": { - "description": "For a recurring TEMPLATE edit (`items`): \"all\" (every occurrence, the default) or \"this\" (one occurrence — needs an occurrence id or `occurrenceDate`). Ticking items off is ALWAYS per-occurrence, so it ignores this.", - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "uncheck": { - "description": "Mark these items NOT-done for the occurrence, by item id or exact text.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "activityTypeId": { + "description": "The activity type id (from the schedule read). null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "The area id (from the schedule read). null or omitted leaves it unset.", + "type": [ + "string", + "null" + ] + }, + "calendarId": { + "description": "The home calendar: a calendar id (from the calendars list or the schedule's `integrations`). Omit it to use the account's default calendar if one is set, else the event stays on the dial only. null keeps the event on the dial only. A calendar id requires Reassign Pro; whole-series only.", + "type": [ + "string", + "null" + ] + }, + "checklist": { + "additionalProperties": false, + "description": "Starter microtasks written to the new event's checklist.", + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "done": { + "description": "true ticks the item off, false clears it; omit to keep the current state (a new item starts not done).", + "type": "boolean" + }, + "id": { + "description": "Keep an existing item's id; omit for a new item.", + "minLength": 1, + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + }, + "end": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "focusIntervals": { + "additionalProperties": false, + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus. A non_blocking or reference event rejects it.", + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + "id": { + "description": "Optional client-minted event id, so the caller can read the new event back by a known id. Omit it and the server mints one.", + "type": "string" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non_blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "mirrorCalendarIds": { + "description": "The one-way copy calendars, as calendar ids. It must not contain the home `calendarId`. On update it REPLACES the set; [] clears it. Requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats, as an RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive last day of the repeat, \"YYYY-MM-DD\". Needs `recurrence`.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + "start": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Its day is the event's day.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + } + }, + "required": [ + "op", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "activityTypeId": { + "description": "The activity type id (from the schedule read). null clears the link; omit to keep it.", + "type": [ + "string", + "null" + ] + }, + "areaId": { + "description": "The area id (from the schedule read). null clears the link; omit to keep it.", + "type": [ + "string", + "null" + ] + }, + "calendarId": { + "description": "Re-home the event: a calendar id (from the calendars list or the schedule's `integrations`) moves it to that calendar; null unlinks it (keeps the dial block). Omit to keep the current home. Requires Reassign Pro; whole-series only.", + "type": [ + "string", + "null" + ] + }, + "end": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. A lone end keeps the start.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "focusIntervals": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus. A non_blocking or reference event rejects it. Pass null to remove an existing rhythm." + }, + "id": { + "description": "The event id from a read. A bare series id addresses the whole series; `seriesId@YYYY-MM-DD` addresses one occurrence.", + "minLength": 1, + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non_blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non_blocking", + "reference" + ], + "type": "string" + }, + "mirrorCalendarIds": { + "description": "The one-way copy calendars, as calendar ids. It must not contain the home `calendarId`. On update it REPLACES the set; [] clears it. Requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "A new RRULE for the series; null stops the repeat.", + "type": [ + "string", + "null" + ] + }, + "recurrenceEnd": { + "description": "Inclusive last day of the repeat, \"YYYY-MM-DD\". Needs `recurrence`.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "scope": { + "const": "future", + "description": "Only with a `seriesId@YYYY-MM-DD` id: \"future\" edits that occurrence and every later one. Omit it to edit only that occurrence; a bare series id edits the whole series.", + "type": "string" + }, + "sourceUrl": { + "anyOf": [ + { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Replace where this event was captured from (http(s)); null clears it. Whole-series only." + }, + "start": { + "description": "Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. A new start moves the event, also to another day (on an occurrence id, that occurrence only). A lone start keeps the duration.", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "description": "The event id from a read. A bare series id addresses the whole series; `seriesId@YYYY-MM-DD` addresses one occurrence.", + "minLength": 1, + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "const": "future", + "description": "Only with a `seriesId@YYYY-MM-DD` id: \"future\" edits that occurrence and every later one. Omit it to edit only that occurrence; a bare series id edits the whole series.", + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "actualEnd": { + "description": "When it actually ended. Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Send it with actualStart, only for \"changed\" or \"added\".", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "actualStart": { + "description": "When it actually started. Local datetime \"YYYY-MM-DDTHH:MM\" (no seconds, offset or Z). The end must be after the start; an overnight or multi-day event just ends on a later day. Send it with actualEnd, only for \"changed\" or \"added\".", + "pattern": "^(\\d{4}-\\d{2}-\\d{2})T([01]\\d|2[0-3]):([0-5]\\d)$", + "type": "string" + }, + "id": { + "description": "The event id, echoed verbatim from a schedule or search read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", + "type": "string" + }, + "op": { + "const": "reflect", + "type": "string" + }, + "status": { + "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart + actualEnd to record the real time); \"added\" = unplanned but happened (its actualStart + actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", + "enum": [ + "kept", + "skipped", + "changed", + "added" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "status" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "check": { + "description": "Item ids to mark DONE for the occurrence. On a recurring event this ticks off that occurrence only.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "id": { + "description": "The event id, echoed verbatim from a schedule or search read. A bare series id edits the template of the whole series; the `seriesId@YYYY-MM-DD` id edits or ticks off that one occurrence.", + "type": "string" + }, + "items": { + "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", + "items": { + "additionalProperties": false, + "properties": { + "done": { + "description": "true ticks the item off, false clears it; omit to keep the current state (a new item starts not done).", + "type": "boolean" + }, + "id": { + "description": "Keep an existing item's id; omit for a new item.", + "minLength": 1, + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "op": { + "const": "checklist", + "type": "string" + }, + "uncheck": { + "description": "Item ids to mark NOT-done for the occurrence.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
14 tool updates
- Changed
confirm_schedule1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
delete_events1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
find_event1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
get_energy1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
get_schedule2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / properties / backlogOffsetAdded value: +{ + "description": "Inbox page offset from nextBacklogOffset; keep the same filters. Implies includeBacklog.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +}
- Changed
get_weather1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
manage_backlog1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
manage_categories3 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Input schema / properties / activityTypes / items / oneOfPrevious value: -[ - { - "properties": { - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "pattern": { - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "id": { - "type": "string" - }, - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "pattern": { - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "type": "string" - }, - "op": { - "const": "delete", - "type": "string" - }, - "reassignTo": { - "description": "Another activity type's id to move events onto; required if events still use this type.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "pattern": { + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "order": { + "type": "number" + }, + "pattern": { + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "op": { + "const": "delete", + "type": "string" + }, + "reassignTo": { + "description": "Another activity type's id to move events onto; required if events still use this type.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +] - changed
Input schema / properties / areas / items / oneOfPrevious value: -[ - { - "properties": { - "color": { - "type": "string" - }, - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "color": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "maxLength": 60, - "minLength": 1, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "type": "string" - }, - "op": { - "const": "delete", - "type": "string" - }, - "reassignTo": { - "description": "Another area's id to move events onto; required if events still use this area.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "color": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "properties": { + "color": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "maxLength": 60, + "minLength": 1, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "order": { + "type": "number" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "op": { + "const": "delete", + "type": "string" + }, + "reassignTo": { + "description": "Another area's id to move events onto; required if events still use this area.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
- Changed
review_day1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
schedule1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
send_feedback2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / properties / submissionIdAdded value: +{ + "description": "A UUID for this submission. Reuse it with identical content on retries within 24 hours; use a new UUID for a new report.", + "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" +}
- Changed
show_day1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
undo1 field changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
- Changed
write_events2 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "mirrorTo": { - "description": "Also fan this event out as one-way copies to these calendar ids (on top of the home from `syncTo`). The home id is dropped if listed. Requires Reassign Pro; whole-series only.", - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Publish this event to one of the user's calendars: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`). Omit to follow the user's default calendar; pass null to force it dial-only. Requires Reassign Pro; whole-series only." - } - }, - "required": [ - "op", - "date", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "anyOf": [ - { - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." - }, - "id": { - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "mirrorTo": { - "description": "Replace the one-way copy set with these calendar ids; pass [] to clear all copies. The home calendar is dropped if listed. Requires Reassign Pro; whole-series only.", - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Re-home this event: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`) moves it to that calendar; null unlinks it (removes it from the calendar, keeps the dial block). Omit to leave the current home. Requires Reassign Pro; whole-series only." - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "New date, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "move", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "description": "New start time, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - }, - { - "properties": { - "actualEnd": { - "description": "When it actually ended, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "actualEndNextDay": { - "description": "Set true when the actual run crossed midnight.", - "type": "boolean" - }, - "actualStart": { - "description": "When it actually started, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", - "type": "string" - }, - "op": { - "const": "reflect", - "type": "string" - }, - "status": { - "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", - "enum": [ - "kept", - "skipped", - "changed", - "added" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "status" - ], - "type": "object" - }, - { - "properties": { - "check": { - "description": "Mark these items DONE for the occurrence, by item id or exact text. On a recurring event this ticks off THIS occurrence only.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To edit or tick off ONE occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day.", - "type": "string" - }, - "items": { - "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", - "items": { - "properties": { - "id": { - "description": "Keep an existing item's id (from a read) to preserve its checked state; omit to add a new microtask.", - "type": "string" - }, - "text": { - "maxLength": 200, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - }, - "maxItems": 100, - "type": "array" - }, - "occurrenceDate": { - "description": "The occurrence to edit, \"YYYY-MM-DD\", for a scope:\"this\" template edit on a recurring event (or supply the composite `seriesId@YYYY-MM-DD` id).", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "checklist", - "type": "string" - }, - "scope": { - "description": "For a recurring TEMPLATE edit (`items`): \"all\" (every occurrence, the default) or \"this\" (one occurrence — needs an occurrence id or `occurrenceDate`). Ticking items off is ALWAYS per-occurrence, so it ignores this.", - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "uncheck": { - "description": "Mark these items NOT-done for the occurrence, by item id or exact text.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "checklist": { + "description": "Starter microtasks written to the new event's checklist.", + "items": { + "properties": { + "id": { + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + "id": { + "description": "Optional client-minted section id. The onboarding funnel supplies it so the reveal step can read the new rows back; omit to let the server mint.", + "type": "string" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "mirrorTo": { + "description": "Also fan this event out as one-way copies to these calendar ids (on top of the home from `syncTo`). The home id is dropped if listed. Requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "description": "Publish this event to one of the user's calendars: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`). Omit to follow the user's default calendar; pass null to force it dial-only. Requires Reassign Pro; whole-series only.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "op", + "date", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "anyOf": [ + { + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." + }, + "id": { + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "mirrorTo": { + "description": "Replace the one-way copy set with these calendar ids; pass [] to clear all copies. The home calendar is dropped if listed. Requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "description": "Re-home this event: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`) moves it to that calendar; null unlinks it (removes it from the calendar, keeps the dial block). Omit to leave the current home. Requires Reassign Pro; whole-series only.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "description": "New date, ISO \"YYYY-MM-DD\".", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "move", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "description": "New start time, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + }, + { + "properties": { + "actualEnd": { + "description": "When it actually ended, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "actualEndNextDay": { + "description": "Set true when the actual run crossed midnight.", + "type": "boolean" + }, + "actualStart": { + "description": "When it actually started, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", + "type": "string" + }, + "op": { + "const": "reflect", + "type": "string" + }, + "status": { + "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", + "enum": [ + "kept", + "skipped", + "changed", + "added" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "status" + ], + "type": "object" + }, + { + "properties": { + "check": { + "description": "Mark these items DONE for the occurrence, by item id or exact text. On a recurring event this ticks off THIS occurrence only.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To edit or tick off ONE occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day.", + "type": "string" + }, + "items": { + "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", + "items": { + "properties": { + "id": { + "description": "Keep an existing item's id (from a read) to preserve its checked state; omit to add a new microtask.", + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "occurrenceDate": { + "description": "The occurrence to edit, \"YYYY-MM-DD\", for a scope:\"this\" template edit on a recurring event (or supply the composite `seriesId@YYYY-MM-DD` id).", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "checklist", + "type": "string" + }, + "scope": { + "description": "For a recurring TEMPLATE edit (`items`): \"all\" (every occurrence, the default) or \"this\" (one occurrence — needs an occurrence id or `occurrenceDate`). Ticking items off is ALWAYS per-occurrence, so it ignores this.", + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "uncheck": { + "description": "Mark these items NOT-done for the occurrence, by item id or exact text.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
1 tool update
- Changed
write_events1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "date", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "anyOf": [ - { - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." - }, - "id": { - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "New date, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "move", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "description": "New start time, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - }, - { - "properties": { - "actualEnd": { - "description": "When it actually ended, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "actualEndNextDay": { - "description": "Set true when the actual run crossed midnight.", - "type": "boolean" - }, - "actualStart": { - "description": "When it actually started, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", - "type": "string" - }, - "op": { - "const": "reflect", - "type": "string" - }, - "status": { - "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", - "enum": [ - "kept", - "skipped", - "changed", - "added" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "status" - ], - "type": "object" - }, - { - "properties": { - "check": { - "description": "Mark these items DONE for the occurrence, by item id or exact text. On a recurring event this ticks off THIS occurrence only.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To edit or tick off ONE occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day.", - "type": "string" - }, - "items": { - "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", - "items": { - "properties": { - "id": { - "description": "Keep an existing item's id (from a read) to preserve its checked state; omit to add a new microtask.", - "type": "string" - }, - "text": { - "maxLength": 200, - "minLength": 1, - "type": "string" - } - }, - "required": [ - "text" - ], - "type": "object" - }, - "maxItems": 100, - "type": "array" - }, - "occurrenceDate": { - "description": "The occurrence to edit, \"YYYY-MM-DD\", for a scope:\"this\" template edit on a recurring event (or supply the composite `seriesId@YYYY-MM-DD` id).", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "checklist", - "type": "string" - }, - "scope": { - "description": "For a recurring TEMPLATE edit (`items`): \"all\" (every occurrence, the default) or \"this\" (one occurrence — needs an occurrence id or `occurrenceDate`). Ticking items off is ALWAYS per-occurrence, so it ignores this.", - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "uncheck": { - "description": "Mark these items NOT-done for the occurrence, by item id or exact text.", - "items": { - "type": "string" - }, - "maxItems": 100, - "type": "array" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "mirrorTo": { + "description": "Also fan this event out as one-way copies to these calendar ids (on top of the home from `syncTo`). The home id is dropped if listed. Requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Publish this event to one of the user's calendars: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`). Omit to follow the user's default calendar; pass null to force it dial-only. Requires Reassign Pro; whole-series only." + } + }, + "required": [ + "op", + "date", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "anyOf": [ + { + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." + }, + "id": { + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "mirrorTo": { + "description": "Replace the one-way copy set with these calendar ids; pass [] to clear all copies. The home calendar is dropped if listed. Requires Reassign Pro; whole-series only.", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Re-home this event: a calendar id from GET /api/v1/calendars (or get_schedule's `integrations`) moves it to that calendar; null unlinks it (removes it from the calendar, keeps the dial block). Omit to leave the current home. Requires Reassign Pro; whole-series only." + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "description": "New date, ISO \"YYYY-MM-DD\".", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "move", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "description": "New start time, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + }, + { + "properties": { + "actualEnd": { + "description": "When it actually ended, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "actualEndNextDay": { + "description": "Set true when the actual run crossed midnight.", + "type": "boolean" + }, + "actualStart": { + "description": "When it actually started, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", + "type": "string" + }, + "op": { + "const": "reflect", + "type": "string" + }, + "status": { + "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", + "enum": [ + "kept", + "skipped", + "changed", + "added" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "status" + ], + "type": "object" + }, + { + "properties": { + "check": { + "description": "Mark these items DONE for the occurrence, by item id or exact text. On a recurring event this ticks off THIS occurrence only.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To edit or tick off ONE occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day.", + "type": "string" + }, + "items": { + "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", + "items": { + "properties": { + "id": { + "description": "Keep an existing item's id (from a read) to preserve its checked state; omit to add a new microtask.", + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "occurrenceDate": { + "description": "The occurrence to edit, \"YYYY-MM-DD\", for a scope:\"this\" template edit on a recurring event (or supply the composite `seriesId@YYYY-MM-DD` id).", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "checklist", + "type": "string" + }, + "scope": { + "description": "For a recurring TEMPLATE edit (`items`): \"all\" (every occurrence, the default) or \"this\" (one occurrence — needs an occurrence id or `occurrenceDate`). Ticking items off is ALWAYS per-occurrence, so it ignores this.", + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "uncheck": { + "description": "Mark these items NOT-done for the occurrence, by item id or exact text.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
2 tool updates
- Changed
get_schedule3 fields changed- changed
Input schema / properties / backlogPlannedOn / descriptionPrevious value: -"Filter the parked blocks to those PLANNED for this day (a block's planned day, or a planned window covering it) — e.g. today's date to answer \"what did I plan to get to today?\". Implies includeBacklog; composes with backlogQuery. Overdue blocks carry `overdue: true` on the unfiltered read instead."New value: +"Filter the Inbox blocks to those PLANNED for this day (a block's planned day, or a planned window covering it) — e.g. today's date to answer \"what did I plan to get to today?\". Implies includeBacklog; composes with backlogQuery. Overdue blocks carry `overdue: true` on the unfiltered read instead." - changed
Input schema / properties / backlogQuery / descriptionPrevious value: -"Filter the parked blocks by name (fuzzy, case/accent-insensitive) — e.g. \"dentist\". Implies includeBacklog; use it to FIND a specific parked block by name instead of paging the whole inbox."New value: +"Filter the Inbox blocks by name (fuzzy, case/accent-insensitive) — e.g. \"dentist\". Implies includeBacklog; use it to FIND a specific Inbox block by name instead of paging the whole Inbox." - changed
Input schema / properties / includeBacklog / descriptionPrevious value: -"Include the parked-block items (the `backlog` array), not just `backlogCount`. Pass true when the user wants to see, schedule, or manage their inbox."New value: +"Include the Inbox items (the `backlog` array), not just `backlogCount`. Pass true when the user wants to see, schedule, or manage their Inbox."
- Changed
manage_backlog1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "enrich": { - "description": "Let AI clean this capture up before it is saved: propose a better name, estimate durationHours, and copy out any microtasks the captured text spells out. For RAW captures only — text grabbed off a web page, where the name is a paragraph rather than an intention. Do NOT set it for something the user typed or dictated: it may RENAME the block, and a name they chose must stand. Fields you send yourself always win; only the name can be replaced.", - "type": "boolean" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "capture", - "type": "string" - }, - "plannedDate": { - "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "plannedUntil": { - "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "sourceUrl": { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - "steps": { - "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "type": "array" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id.", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "id": { - "description": "The parked block id (from get_schedule's `backlog`).", - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "plannedDate": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." - }, - "plannedUntil": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." - }, - "sourceUrl": { - "anyOf": [ - { - "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", - "maxLength": 2048, - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Replace where this block was captured from (http(s)); null clears the source chip." - }, - "steps": { - "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "type": "array" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "description": "The parked block id to delete from the inbox.", - "type": "string" - }, - "op": { - "const": "remove", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "description": "The parked block id to place on the dial.", - "type": "string" - }, - "op": { - "const": "schedule", - "type": "string" - }, - "recurrence": { - "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "start": { - "description": "Start time HH:MM; duration comes from the block.", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id", - "date", - "start" - ], - "type": "object" - }, - { - "properties": { - "eventId": { - "description": "The dial event id to move to the inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", - "type": "string" - }, - "op": { - "const": "park", - "type": "string" - } - }, - "required": [ - "op", - "eventId" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "enrich": { + "description": "Let AI clean this capture up before it is saved: propose a better name, estimate durationHours, and copy out any microtasks the captured text spells out. For RAW captures only — text grabbed off a web page, where the name is a paragraph rather than an intention. Do NOT set it for something the user typed or dictated: it may RENAME the block, and a name they chose must stand. Fields you send yourself always win; only the name can be replaced.", + "type": "boolean" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "capture", + "type": "string" + }, + "plannedDate": { + "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "plannedUntil": { + "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + "steps": { + "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). An Inbox block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id.", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "id": { + "description": "The Inbox block id (from get_schedule's `backlog`).", + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "plannedDate": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." + }, + "plannedUntil": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." + }, + "sourceUrl": { + "anyOf": [ + { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Replace where this block was captured from (http(s)); null clears the source chip." + }, + "steps": { + "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). An Inbox block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "id": { + "description": "The Inbox block id to delete from the Inbox.", + "type": "string" + }, + "op": { + "const": "remove", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "description": "The Inbox block id to place on the dial.", + "type": "string" + }, + "op": { + "const": "schedule", + "type": "string" + }, + "recurrence": { + "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "start": { + "description": "Start time HH:MM; duration comes from the block.", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id", + "date", + "start" + ], + "type": "object" + }, + { + "properties": { + "eventId": { + "description": "The dial event id to move to the Inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", + "type": "string" + }, + "op": { + "const": "park", + "type": "string" + } + }, + "required": [ + "op", + "eventId" + ], + "type": "object" + } +]
2 tool updates
- Changed
manage_backlog1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "capture", - "type": "string" - }, - "plannedDate": { - "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "plannedUntil": { - "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "steps": { - "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "type": "array" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id.", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "id": { - "description": "The parked block id (from get_schedule's `backlog`).", - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "plannedDate": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." - }, - "plannedUntil": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." - }, - "steps": { - "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", - "items": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "type": "array" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "description": "The parked block id to delete from the inbox.", - "type": "string" - }, - "op": { - "const": "remove", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "description": "The parked block id to place on the dial.", - "type": "string" - }, - "op": { - "const": "schedule", - "type": "string" - }, - "recurrence": { - "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "start": { - "description": "Start time HH:MM; duration comes from the block.", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id", - "date", - "start" - ], - "type": "object" - }, - { - "properties": { - "eventId": { - "description": "The dial event id to move to the inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", - "type": "string" - }, - "op": { - "const": "park", - "type": "string" - } - }, - "required": [ - "op", - "eventId" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "enrich": { + "description": "Let AI clean this capture up before it is saved: propose a better name, estimate durationHours, and copy out any microtasks the captured text spells out. For RAW captures only — text grabbed off a web page, where the name is a paragraph rather than an intention. Do NOT set it for something the user typed or dictated: it may RENAME the block, and a name they chose must stand. Fields you send yourself always win; only the name can be replaced.", + "type": "boolean" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "capture", + "type": "string" + }, + "plannedDate": { + "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "plannedUntil": { + "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "sourceUrl": { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + "steps": { + "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id.", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "id": { + "description": "The parked block id (from get_schedule's `backlog`).", + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "plannedDate": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." + }, + "plannedUntil": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." + }, + "sourceUrl": { + "anyOf": [ + { + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Replace where this block was captured from (http(s)); null clears the source chip." + }, + "steps": { + "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "id": { + "description": "The parked block id to delete from the inbox.", + "type": "string" + }, + "op": { + "const": "remove", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "description": "The parked block id to place on the dial.", + "type": "string" + }, + "op": { + "const": "schedule", + "type": "string" + }, + "recurrence": { + "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "start": { + "description": "Start time HH:MM; duration comes from the block.", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id", + "date", + "start" + ], + "type": "object" + }, + { + "properties": { + "eventId": { + "description": "The dial event id to move to the inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", + "type": "string" + }, + "op": { + "const": "park", + "type": "string" + } + }, + "required": [ + "op", + "eventId" + ], + "type": "object" + } +]
- Changed
schedule2 fields changed- added
Input schema / properties / requests / items / properties / kindAdded value: +{ + "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but is not doing — non-blocking, and don't move, delete, or schedule work into it unless asked. Note a non-blocking request still SEARCHES for a free slot like any other; it simply does not occupy one once placed.", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" +} - added
Input schema / properties / requests / items / properties / sourceUrlAdded value: +{ + "description": "Where this was captured from — the http(s) page address. Shown as a source chip; never parsed. Set it only for something grabbed off a real page, not for an intention the user typed.", + "maxLength": 2048, + "type": "string" +}
2 tool updates
- Changed
manage_backlog1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "capture", - "type": "string" - }, - "plannedDate": { - "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "plannedUntil": { - "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id.", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "id": { - "description": "The parked block id (from get_schedule's `backlog`).", - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "plannedDate": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." - }, - "plannedUntil": { - "anyOf": [ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "description": "The parked block id to delete from the inbox.", - "type": "string" - }, - "op": { - "const": "remove", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "description": "The parked block id to place on the dial.", - "type": "string" - }, - "op": { - "const": "schedule", - "type": "string" - }, - "recurrence": { - "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "start": { - "description": "Start time HH:MM; duration comes from the block.", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id", - "date", - "start" - ], - "type": "object" - }, - { - "properties": { - "eventId": { - "description": "The dial event id to move to the inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", - "type": "string" - }, - "op": { - "const": "park", - "type": "string" - } - }, - "required": [ - "op", - "eventId" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "capture", + "type": "string" + }, + "plannedDate": { + "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "plannedUntil": { + "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "steps": { + "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id.", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "id": { + "description": "The parked block id (from get_schedule's `backlog`).", + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "plannedDate": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." + }, + "plannedUntil": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." + }, + "steps": { + "description": "The block's microtask steps, in order — REPLACES the whole list (send every step you want kept, not just new ones; an empty array clears them). A parked block has no occurrence, so steps here are template-only — there is nothing to tick off until it is scheduled onto the dial.", + "items": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "id": { + "description": "The parked block id to delete from the inbox.", + "type": "string" + }, + "op": { + "const": "remove", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "description": "The parked block id to place on the dial.", + "type": "string" + }, + "op": { + "const": "schedule", + "type": "string" + }, + "recurrence": { + "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "start": { + "description": "Start time HH:MM; duration comes from the block.", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id", + "date", + "start" + ], + "type": "object" + }, + { + "properties": { + "eventId": { + "description": "The dial event id to move to the inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", + "type": "string" + }, + "op": { + "const": "park", + "type": "string" + } + }, + "required": [ + "op", + "eventId" + ], + "type": "object" + } +]
- Changed
write_events1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "date", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "focusIntervals": { - "anyOf": [ - { - "properties": { - "breakMin": { - "maximum": 60, - "minimum": 1, - "type": "integer" - }, - "focusMin": { - "maximum": 180, - "minimum": 5, - "type": "integer" - } - }, - "required": [ - "focusMin", - "breakMin" - ], - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." - }, - "id": { - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "New date, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "move", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "description": "New start time, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - }, - { - "properties": { - "actualEnd": { - "description": "When it actually ended, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "actualEndNextDay": { - "description": "Set true when the actual run crossed midnight.", - "type": "boolean" - }, - "actualStart": { - "description": "When it actually started, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", - "type": "string" - }, - "op": { - "const": "reflect", - "type": "string" - }, - "status": { - "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", - "enum": [ - "kept", - "skipped", - "changed", - "added" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "status" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "date", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "anyOf": [ + { + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." + }, + "id": { + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "description": "New date, ISO \"YYYY-MM-DD\".", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "move", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "description": "New start time, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + }, + { + "properties": { + "actualEnd": { + "description": "When it actually ended, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "actualEndNextDay": { + "description": "Set true when the actual run crossed midnight.", + "type": "boolean" + }, + "actualStart": { + "description": "When it actually started, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", + "type": "string" + }, + "op": { + "const": "reflect", + "type": "string" + }, + "status": { + "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", + "enum": [ + "kept", + "skipped", + "changed", + "added" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "status" + ], + "type": "object" + }, + { + "properties": { + "check": { + "description": "Mark these items DONE for the occurrence, by item id or exact text. On a recurring event this ticks off THIS occurrence only.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To edit or tick off ONE occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day.", + "type": "string" + }, + "items": { + "description": "REPLACE the whole checklist with these microtasks, in order — add, rename, remove, and reorder are all expressed as the resulting list. Read the current items first, then send the full desired list. Pass [] to clear the checklist. A checkoff on a removed item is dropped automatically.", + "items": { + "properties": { + "id": { + "description": "Keep an existing item's id (from a read) to preserve its checked state; omit to add a new microtask.", + "type": "string" + }, + "text": { + "maxLength": 200, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "occurrenceDate": { + "description": "The occurrence to edit, \"YYYY-MM-DD\", for a scope:\"this\" template edit on a recurring event (or supply the composite `seriesId@YYYY-MM-DD` id).", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "checklist", + "type": "string" + }, + "scope": { + "description": "For a recurring TEMPLATE edit (`items`): \"all\" (every occurrence, the default) or \"this\" (one occurrence — needs an occurrence id or `occurrenceDate`). Ticking items off is ALWAYS per-occurrence, so it ignores this.", + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "uncheck": { + "description": "Mark these items NOT-done for the occurrence, by item id or exact text.", + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + } +]
1 tool update
- Changed
write_events1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "date", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "New date, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "move", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "description": "New start time, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - }, - { - "properties": { - "actualEnd": { - "description": "When it actually ended, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "actualEndNextDay": { - "description": "Set true when the actual run crossed midnight.", - "type": "boolean" - }, - "actualStart": { - "description": "When it actually started, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "id": { - "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", - "type": "string" - }, - "op": { - "const": "reflect", - "type": "string" - }, - "status": { - "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", - "enum": [ - "kept", - "skipped", - "changed", - "added" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "status" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it.", + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "date", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "focusIntervals": { + "anyOf": [ + { + "properties": { + "breakMin": { + "maximum": 60, + "minimum": 1, + "type": "integer" + }, + "focusMin": { + "maximum": 180, + "minimum": 5, + "type": "integer" + } + }, + "required": [ + "focusMin", + "breakMin" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Split a BLOCKING block into a repeating focus/break rhythm (pomodoro), e.g. {focusMin:25,breakMin:5}. The breaks fall BETWEEN the focus intervals and the block always ends on a focus — both derived from the block's length, so you never list individual intervals. Only valid on a blocking event; a non-blocking/reference block ignores it. Pass null to remove an existing rhythm." + }, + "id": { + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "description": "New date, ISO \"YYYY-MM-DD\".", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "move", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "description": "New start time, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + }, + { + "properties": { + "actualEnd": { + "description": "When it actually ended, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "actualEndNextDay": { + "description": "Set true when the actual run crossed midnight.", + "type": "boolean" + }, + "actualStart": { + "description": "When it actually started, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", + "type": "string" + }, + "op": { + "const": "reflect", + "type": "string" + }, + "status": { + "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", + "enum": [ + "kept", + "skipped", + "changed", + "added" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "status" + ], + "type": "object" + } +]
2 tool updates
- Changed
get_schedule1 field changed- added
Input schema / properties / backlogPlannedOnAdded value: +{ + "description": "Filter the parked blocks to those PLANNED for this day (a block's planned day, or a planned window covering it) — e.g. today's date to answer \"what did I plan to get to today?\". Implies includeBacklog; composes with backlogQuery. Overdue blocks carry `overdue: true` on the unfiltered read instead.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" +}
- Changed
manage_backlog1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "capture", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id.", - "type": "string" - }, - "durationHours": { - "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", - "exclusiveMinimum": 0, - "maximum": 24, - "type": "number" - }, - "id": { - "description": "The parked block id (from get_schedule's `backlog`).", - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "id": { - "description": "The parked block id to delete from the inbox.", - "type": "string" - }, - "op": { - "const": "remove", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "description": "The parked block id to place on the dial.", - "type": "string" - }, - "op": { - "const": "schedule", - "type": "string" - }, - "recurrence": { - "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "start": { - "description": "Start time HH:MM; duration comes from the block.", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id", - "date", - "start" - ], - "type": "object" - }, - { - "properties": { - "eventId": { - "description": "The dial event id to move to the inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", - "type": "string" - }, - "op": { - "const": "park", - "type": "string" - } - }, - "required": [ - "op", - "eventId" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "capture", + "type": "string" + }, + "plannedDate": { + "description": "The day this intention is planned for (still untimed — placing it on the dial is a separate `schedule`). Groups it under that day in the tray.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "plannedUntil": { + "description": "Optional inclusive window end after plannedDate — a flexible \"sometime in this range\" window.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id.", + "type": "string" + }, + "durationHours": { + "description": "Estimated length in hours (e.g. 1.5). Sizes the block when placed.", + "exclusiveMinimum": 0, + "maximum": 24, + "type": "number" + }, + "id": { + "description": "The parked block id (from get_schedule's `backlog`).", + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "plannedDate": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set/move the block's planned day; null clears it back to Someday (also clears any window end). Refused on a task-app-linked block — its date is owned by the provider (change it there)." + }, + "plannedUntil": { + "anyOf": [ + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set the inclusive window end (must fall after the planned day); null collapses the window to the single day." + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "id": { + "description": "The parked block id to delete from the inbox.", + "type": "string" + }, + "op": { + "const": "remove", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "description": "The parked block id to place on the dial.", + "type": "string" + }, + "op": { + "const": "schedule", + "type": "string" + }, + "recurrence": { + "description": "Optionally make the placed block repeat: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "start": { + "description": "Start time HH:MM; duration comes from the block.", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id", + "date", + "start" + ], + "type": "object" + }, + { + "properties": { + "eventId": { + "description": "The dial event id to move to the inbox (from get_schedule/find_event). Must be a native or owned-calendar one-off that hasn't been reviewed.", + "type": "string" + }, + "op": { + "const": "park", + "type": "string" + } + }, + "required": [ + "op", + "eventId" + ], + "type": "object" + } +]
3 tool updates
- Changed
get_schedule2 fields changed- added
Input schema / properties / backlogQueryAdded value: +{ + "description": "Filter the parked blocks by name (fuzzy, case/accent-insensitive) — e.g. \"dentist\". Implies includeBacklog; use it to FIND a specific parked block by name instead of paging the whole inbox.", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / includeBacklogAdded value: +{ + "description": "Include the parked-block items (the `backlog` array), not just `backlogCount`. Pass true when the user wants to see, schedule, or manage their inbox.", + "type": "boolean" +}
- Added
manage_backlog - Changed
undo1 field changed- changed
Input schema / properties / tokens / descriptionPrevious value: -"undoToken(s) returned by schedule, confirm_schedule, write_events, delete_events, or review_day (incl. a `batchUndoToken`)."New value: +"undoToken(s) returned by schedule, confirm_schedule, write_events, delete_events, review_day, or manage_backlog (incl. a `batchUndoToken`)."
1 tool update
- Added
get_energy
3 tool updates
- Added
review_day - Changed
undo1 field changed- changed
Input schema / properties / tokens / descriptionPrevious value: -"The undoTokens from schedule/confirm_schedule."New value: +"undoToken(s) returned by schedule, confirm_schedule, write_events, delete_events, or review_day (incl. a `batchUndoToken`)."
- Changed
write_events1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "date", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "New date, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "move", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "description": "New start time, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "date", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "description": "New date, ISO \"YYYY-MM-DD\".", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "move", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "description": "New start time, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + }, + { + "properties": { + "actualEnd": { + "description": "When it actually ended, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "actualEndNextDay": { + "description": "Set true when the actual run crossed midnight.", + "type": "boolean" + }, + "actualStart": { + "description": "When it actually started, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "id": { + "description": "The event id, echoed verbatim from a get_schedule/find_event read. To mark one occurrence of a recurring event, pass the `seriesId@YYYY-MM-DD` id the read returned for that day — don't fabricate the @date yourself.", + "type": "string" + }, + "op": { + "const": "reflect", + "type": "string" + }, + "status": { + "description": "How a past planned event actually went. \"kept\" = happened as planned; \"skipped\" = didn't happen; \"changed\" = happened but differently (pass actualStart/actualEnd to record the real time, otherwise it's logged as changed with no exact time); \"added\" = unplanned but happened (its actualStart/actualEnd become the event's time). Marking only records the reflection — it never renames or re-times the plan.", + "enum": [ + "kept", + "skipped", + "changed", + "added" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "status" + ], + "type": "object" + } +]
1 tool update
- Changed
write_events1 field changed- changed
Input schema / properties / ops / items / oneOfPrevious value: -[ - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "kind": { - "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting or sleep band) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "op": { - "const": "create", - "type": "string" - }, - "recurrence": { - "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "date", - "start", - "end", - "name" - ], - "type": "object" - }, - { - "properties": { - "activityTypeId": { - "type": "string" - }, - "activityTypeName": { - "description": "Activity type by name instead of id.", - "type": "string" - }, - "areaId": { - "type": "string" - }, - "areaName": { - "description": "Area by name instead of id (case/accent-insensitive).", - "type": "string" - }, - "date": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "end": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "endNextDay": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "kind": { - "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", - "enum": [ - "blocking", - "non-blocking", - "reference" - ], - "type": "string" - }, - "name": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "notes": { - "maxLength": 2000, - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "update", - "type": "string" - }, - "recurrence": { - "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", - "type": "string" - }, - "recurrenceEnd": { - "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - }, - "syncTo": { - "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "date": { - "description": "New date, ISO \"YYYY-MM-DD\".", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "move", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - }, - "start": { - "description": "New start time, 24-hour \"HH:MM\".", - "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", - "type": "string" - } - }, - "required": [ - "op", - "id" - ], - "type": "object" - }, - { - "properties": { - "byMinutes": { - "description": "Minutes to shift by; negative is earlier.", - "maximum": 9007199254740991, - "minimum": -9007199254740991, - "type": "integer" - }, - "id": { - "type": "string" - }, - "occurrenceDate": { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - "op": { - "const": "shift", - "type": "string" - }, - "scope": { - "enum": [ - "all", - "future", - "this" - ], - "type": "string" - } - }, - "required": [ - "op", - "id", - "byMinutes" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "kind": { + "description": "\"blocking\" (default) cannot overlap others; \"non-blocking\" is an overlay (e.g. a fasting band or an away/OOO marker) that may overlap and never conflicts; \"reference\" is something the user wants to SEE but isn't doing (e.g. a kid's training they drop off at) — non-blocking, and don't move, delete, or schedule work into it unless asked.", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "op": { + "const": "create", + "type": "string" + }, + "recurrence": { + "description": "How the event repeats: a preset (daily, weekdays, weekly, biweekly, monthly, yearly) or a raw RRULE (e.g. \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"). Omit for a one-off.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Inclusive end date for the repeat, \"YYYY-MM-DD\" (that day is the last occurrence). Only meaningful with `recurrence`; ignored for a one-off.", + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "date", + "start", + "end", + "name" + ], + "type": "object" + }, + { + "properties": { + "activityTypeId": { + "type": "string" + }, + "activityTypeName": { + "description": "Activity type by name instead of id.", + "type": "string" + }, + "areaId": { + "type": "string" + }, + "areaName": { + "description": "Area by name instead of id (case/accent-insensitive).", + "type": "string" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "end": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "endNextDay": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "kind": { + "description": "Change the event kind: \"blocking\", \"non-blocking\", or \"reference\" (see-only — non-blocking, don't schedule work into it).", + "enum": [ + "blocking", + "non-blocking", + "reference" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "notes": { + "maxLength": 2000, + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "update", + "type": "string" + }, + "recurrence": { + "description": "New recurrence (preset or RRULE); set to \"none\" to stop repeating.", + "type": "string" + }, + "recurrenceEnd": { + "description": "Set or replace the repeat end date, \"YYYY-MM-DD\" (inclusive), or \"none\" to make it open-ended. Carried across a frequency change. One-off: ignored.", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + }, + "syncTo": { + "description": "Set by the dial widget's “Sync to” picker — the calendar id to publish this (dial-only) event to. The user picks it in the editor; leave it unset, a created/edited event already follows the user's default calendar.", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "date": { + "description": "New date, ISO \"YYYY-MM-DD\".", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "move", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + }, + "start": { + "description": "New start time, 24-hour \"HH:MM\".", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" + } + }, + "required": [ + "op", + "id" + ], + "type": "object" + }, + { + "properties": { + "byMinutes": { + "description": "Minutes to shift by; negative is earlier.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "id": { + "type": "string" + }, + "occurrenceDate": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "op": { + "const": "shift", + "type": "string" + }, + "scope": { + "enum": [ + "all", + "future", + "this" + ], + "type": "string" + } + }, + "required": [ + "op", + "id", + "byMinutes" + ], + "type": "object" + } +]
3 tool updates
- Changed
delete_events1 field changed- added
Input schema / properties / ops / items / defaultAdded value: +{ + "op": "__invalid__" +}
- Changed
schedule1 field changed- added
Input schema / properties / requests / items / properties / autoCommitBestAdded value: +{ + "description": "Flexible requests only (an `earliest`/`latest` window, or neither — NOT an exact `start`). When true, immediately book the top-ranked slot instead of returning `options` + a commitToken. Use for routine one-shot bookings (\"block 2h this afternoon\") to skip the confirm_schedule round-trip; leave off (the default) when slots are scarce/contested and you want to review options first.", + "type": "boolean" +}
- Changed
write_events1 field changed- added
Input schema / properties / ops / items / defaultAdded value: +{ + "op": "__invalid__" +}
1 tool update
- Added
get_weather
1 tool update
- Changed
schedule6 fields changed- added
Input schema / properties / requests / items / properties / dateAdded value: +{ + "description": "Day to place on, ISO \"YYYY-MM-DD\" (you resolve \"tomorrow\" etc.).", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" +} - added
Input schema / properties / requests / items / properties / earliestAdded value: +{ + "description": "Lower bound of an \"HH:MM\" window to search within; omit `start` to use a window.", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" +} - added
Input schema / properties / requests / items / properties / latestAdded value: +{ + "description": "Upper bound of the \"HH:MM\" search window.", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" +} - added
Input schema / properties / requests / items / properties / startAdded value: +{ + "description": "Exact 24-hour \"HH:MM\" start; given ⇒ place there (alternatives proposed on a conflict).", + "pattern": "^([01]?\\d|2[0-3]):[0-5]\\d$", + "type": "string" +} - removed
Input schema / properties / requests / items / properties / whenRemoved value: -{ - "description": "When, e.g. \"tomorrow morning\", \"next monday at 3pm\", \"2026-06-04T15:30\", \"2026-06-01\".", - "type": "string" -} - changed
Input schema / properties / requests / items / requiredPrevious value: -[ - "name", - "duration", - "when" -]New value: +[ + "name", + "duration", + "date" +]
Related MCP Connectors
ADHD system of record for agents: tasks, goals, loops, calendar, focus stats.
- DoneThatOAuthai.donethat
Privacy-first work tracking with summaries, reports, coaching, and AI-ready long-term memory.
Brain dump, routines, task planning, focus, and instant thought retrieval
N-of-1 health experiments in your AI assistant: Oura/RescueTime data, protocols, workouts.
Related MCP Servers
- FlicenseBqualityDmaintenanceA productivity coaching assistant designed for ADHD support that provides intelligent task management, goal tracking, and personalized recommendations. It utilizes a persistent memory system to learn user patterns and preferences, helping to reduce decision paralysis through actionable suggestions.281-
- AlicenseNot gradedqualityDmaintenanceDescription: Voice-first planning app. Dictate voice notes on iOS/Apple Watch, AI creates tasks and events. 21 MCP tools for notes, tasks, events, and reports.18 npmMIT
- FlicenseNot gradedqualityDmaintenanceA privacy-first, local-first MCP server that provides 15 ADHD/second-brain tools for capturing, prioritizing, and resurfacing tasks with context from calendar, mail, and messages.1-
- FlicenseBqualityDmaintenanceAn ADHD-friendly productivity system that uses AI to provide frictionless capture of tasks and ideas through natural language input, with automatic context detection and intelligent routing to appropriate project trackers. Eliminates cognitive overhead by working with ADHD thinking patterns rather than against them.311-
Glama MCP Gateway
Add one secure layer between your agents and this server.