Skip to main content
Glama
mjucius

Cozi MCP Server

by mjucius

Cozi MCP Server

An unofficial Model Context Protocol server that lets AI assistants like Claude read and update your Cozi Family Organizer lists and calendar.

Each user runs their own instance against their own Cozi account. Your credentials are stored in your MCP client's secure config (Claude Desktop's OS keychain or your local environment) and never leave your machine — the author of this server has no access to your data.

Install

Download the latest .mcpb from the Releases page and double-click to install in Claude Desktop. You'll be prompted for your Cozi username and password — they're stored securely in your OS keychain.

This path requires no Node, npm, or Python install on your machine.

2. npx (any other MCP client)

Add this to your Claude Desktop claude_desktop_config.json (or any other MCP client config file):

{
  "mcpServers": {
    "cozi": {
      "command": "npx",
      "args": ["-y", "@mjucius/cozi-mcp"],
      "env": {
        "COZI_USERNAME": "you@example.com",
        "COZI_PASSWORD": "your-password",
        "COZI_READ_ONLY": "true"
      }
    }
  }
}

Requires Node 20+. The package will be downloaded on first run.

Set COZI_READ_ONLY=true to expose only read operations. In read-only mode, the server registers family_members, get_lists, get_list_items, get_calendar, search_calendar, and today; tools that create, update, or delete Cozi data are hidden from MCP clients. Omit the variable, or set it to any value other than 1, true, yes, or on, for the default read-write tool surface.

Related MCP server: AnyList MCP Server

Troubleshooting

Tools fail with "Authentication failed" even after I corrected my password

COZI_USERNAME and COZI_PASSWORD are read once, when the server process starts. Editing them in your MCP client's settings updates the stored config but does not reach a server that is already running — it keeps presenting the old credentials until it is respawned.

Fully quit and relaunch your MCP client (on macOS, Cmd-Q rather than closing the window). Reloading, reconnecting, or toggling the extension off and on is usually not enough.

How do I tell which version is actually running?

The running server advertises its version in the MCP handshake; your client displays it (Claude Desktop: Settings > Extensions). That is independent of what is in your working tree — installing an MCPB installs whatever is inside the .mcpb file, which is only as current as the last npm run bundle:mcpb. Build the bundle immediately before installing it, or install from a GitHub release.

Repeated failures start returning "Too many failed login attempts"

Five consecutive failed authentications for a username trigger an exponential backoff, capped at 15 minutes; the message states the remaining wait. The counter lives in process memory, so restarting the client clears it.

Trust and Security

Cozi has no OAuth — username/password authentication is the only way the API supports. This server handles that fact honestly:

  • Per-user, by architecture. Each user runs their own instance against their own Cozi account. There is no shared backend, no proxy, no multi-tenant database. The author of this server never sees anyone's credentials or data.

  • Credentials live only in your MCP client's secure config. Claude Desktop stores them in your OS keychain. The npx path reads them from environment variables you set yourself. Nothing is logged, written to disk by this server, or sent anywhere except https://rest.cozi.com.

  • API surface is constrained. This server only contacts rest.cozi.com for the same endpoints the Cozi web app uses (auth, lists, calendar, family members). The full request/response code lives in src/cozi/ — about 500 lines of TypeScript you can audit yourself.

  • Open source, MIT licensed. Pin a specific version (@mjucius/cozi-mcp@2.0.0) if you want a stable target, or fork the repo and run your own build if you want zero supply-chain trust.

Security & trust model

This is a single-user server by design. The Cozi credential holder is the principal — there is no separate per-caller authentication gate, because each user runs their own instance against their own Cozi account. Concretely:

  • stdio (npx / MCPB) trusts the local user. Whoever can launch the process and read the configured COZI_USERNAME / COZI_PASSWORD (or the OS keychain entry) is treated as the account owner. The trust boundary is your machine and its user account.

  • No multi-tenancy. Each user configures their own instance with their own Cozi account. There is no shared backend, no tenant isolation to breach, and no per-caller authentication beyond possession of valid Cozi credentials — which is the same access model as the Cozi web app itself.

Two defensive measures narrow the blast radius of that model:

  • Time-bounded credential cache. Authenticated clients are cached only for a bounded lifetime, so a rotated or revoked Cozi password stops working rather than being honored indefinitely from a stale cached session.

  • Failed-login rate limiting. Repeated failed authentication attempts are rate-limited to blunt credential-guessing against the Cozi endpoint.

Tools

The server exposes 15 tools by default, or 6 read-only tools when COZI_READ_ONLY=true (or the MCPB read-only setting) is enabled. Returns are slim dicts with null/empty fields omitted.

Family

  • family_members() → [{id, name, color?}] — call this first to get attendee IDs for appointments.

Lists

  • get_lists(list_type?) → [{id, title, type, item_count, completed_count}] — list_type is optional, 'shopping' or 'todo'.

  • get_list_items(list_id, include_completed=false) → [{id, text, status, position?, header?}] — header: true marks a section heading (e.g. "PRODUCE"), not an item.

  • create_list(name, list_type) → {id, title, type}.

  • rename_list(list_id, title) → {id, title, type} — the items stay as they are.

  • delete_list(list_id) → boolean.

create_list, rename_list and delete_list are hidden in read-only mode.

Items

  • add_item(list_id, text, position=0) → {id, text}.

  • update_item(list_id, item_id, text?, completed?) → {id, text, status} — pass either or both. Non-atomic when both are passed: the text is updated first, then the status.

  • remove_items(list_id, item_ids) → boolean.

All item tools are hidden in read-only mode.

Calendar

  • today() → {date, weekday, time, timezone} — the current local time on your machine. Every tool result also ends with this as a separate line, so the assistant resolves "tomorrow" against your clock rather than its own (often UTC). Set the standard TZ env var (e.g. TZ=America/New_York) if the server runs somewhere other than your own computer.

  • get_calendar(year, month) → [{id, subject, day, all_day, start?, end?, end_day?, attendees?, location?, notes?, reminders?, kind?, read_only?, source?, recurring?, recurrence?, series_start?, series_end?, skipped_days?, covered_days?}]. day is the day the entry happens; end_day appears only on multi-day events, which Cozi lists in every month they overlap (so day may fall outside the month you asked for). A recurring series is listed once per occurrence in the month, on the days Cozi itself expands it to: each entry has the series id, its own day, series_start, and recurrence (Cozi's wording of the rule). Occurrences deleted in the Cozi app are left out and named in skipped_days. A multi-day recurring series is one entry whose covered_days lists the days it covers. kind marks non-appointments such as birthdays; read_only items (holidays, subscribed calendars, named by source) cannot be changed. reminders are minutes before the start.

  • search_calendar(query) → {appointments: [...same fields, last_day?, next_days?], more?} — Cozi's own search across months. A recurring series reports its latest past occurrence and the next ten. Cozi searches from a few years back onward, and a brand-new appointment can take a few seconds to show up.

  • create_appointment(subject, start, end, attendees?, all_day=false, notes='', location?, repeat?, reminders?, notify?) — start and end are ISO datetimes (e.g. '2026-06-15T10:00:00'). For all-day events (all_day=true) a bare date (e.g. '2026-06-15') is also accepted and end may equal start; a bare date on a timed event is an error. Put end on a later date for a multi-day event; the result reports the span as end_day. An end before start is an error. repeat makes it a series: {frequency: 'daily'|'weekly'|'monthly'|'yearly', interval?, weekdays?, monthly_by?: 'day_of_month'|'weekday', until?} (no until repeats forever). reminders are minutes before the start, e.g. [30, 1440].

  • update_appointment(appointment_id, year, month, ...) — partial update via fetch-then-merge: pass (appointment_id, year, month) plus any fields to change. Omitted fields are preserved. To switch a timed appointment to all-day pass all_day=true; to switch to timed pass new start/end. Passing end re-spans the event against its (possibly newly set) start day, so an end on a later date makes it multi-day and one on the start day collapses it back; passing start alone moves the event and keeps its length. A bare date is accepted for start/end when the event is, or is being made, all-day; on a timed event it is an error. A recurring series needs scope: 'this' changes only the occurrence on occurrence_day (Cozi stores the changed copy as its own appointment, which is returned), 'this_and_following' changes it and every later one (Cozi splits the series), 'series' changes every occurrence. repeat replaces a series' rule or turns a one-off into a series; reminders replace the existing ones ([] clears them).

  • delete_appointment(appointment_id, year, month, scope?, occurrence_day?, notify?) → boolean. Errors if the id is not on the (year, month) page. A recurring series needs scope: 'this' removes the occurrence on occurrence_day, 'this_and_following' ends the series before it, 'series' removes every occurrence. Single-occurrence deletes are read back to confirm Cozi applied them.

Holidays, subscribed calendars and birthdays are refused by update_appointment and delete_appointment. notify=true on any calendar write sends Cozi's change notification to the attendees who have notifications on (like the Cozi app's "notify" option); it is off by default.

create_appointment, update_appointment, and delete_appointment are hidden in read-only mode.

Workflow tip

When creating or updating appointments with specific attendees, call family_members() first and use those id values in the attendees arg. Calendar tools are scoped to a (year, month) page — pass the same year/month back when updating or deleting an appointment from that page.

Migration from v1 (Python)

v2.0 is a Node/TypeScript rewrite of the previous Python implementation, distributed as MCPB and npx. The runtime changed AND the tool surface was consolidated — if you have prompts written against v1, update them as follows:

v1 (Python, 14 tools)

v2 (Node, 12 tools)

get_family_members

family_members

get_lists_by_type(t)

get_lists(list_type=t)

update_item_text(...) + mark_item(...)

update_item(text?, completed?) (merged)

add_item(list_id, item_text, ...)

add_item(list_id, text, ...) (param renamed)

update_appointment(appointment_obj)

update_appointment(appointment_id, year, month, ...partial)

update_list (item reordering)

removed

delete_appointment(id)

delete_appointment(id, year, month)

get_lists returned nested items

now summary only — fetch items via get_list_items(list_id)

The legacy v1 Python source is preserved at git tag v1.0.0 for reference.

Development

Requires Node 20+ (see .nvmrc).

nvm use
npm install
npm test               # vitest, mocked at the CoziClient boundary; no credentials
npm run test:live      # live conformance suite against real Cozi (creds.env); required before a release
npm run typecheck
npm run build          # tsup → dist/
npm run dev            # local stdio dev with COZI_USERNAME / COZI_PASSWORD env vars
npm run bundle:mcpb    # produces cozi-mcp.mcpb at repo root

The repo layout:

cozi_mcp/
├── src/
│   ├── server.ts              # MCP server factory
│   ├── bin.ts                 # npx + MCPB stdio entry point
│   ├── instructions.ts
│   ├── cozi/                  # Inlined Cozi HTTP client (no separate npm package)
│   └── tools/                 # 13 MCP tools
├── tests/                     # vitest, mocks CoziClient at the boundary
├── manifest.json              # MCPB manifest (Claude Desktop)
└── package.json

The Cozi HTTP client is inlined under src/cozi/ rather than published as a separate npm package — it's small, only useful for this MCP server, and avoids the supply-chain surface area of a separate dependency. If you'd prefer the Python equivalent for your own projects, see py-cozi-client.

Acknowledgments

  • The ?apikey=coziwc|v…_production requirement on the Cozi auth endpoint was reverse-engineered from the live my.cozi.com web bundle by Wetzel402/py-cozi PR #3. Without that discovery, every login attempt from a server environment fails with a misleading 401 regardless of credential validity.

  • Built on the Model Context Protocol and its TypeScript SDK by Anthropic.

Trademark and affiliation

Cozi and the Cozi logo are trademarks of Cozi Group Inc. This project is unofficial and not affiliated with, endorsed by, or sponsored by Cozi Group Inc. Use of the Cozi API is at your own risk and subject to Cozi's Terms of Service.

License

MIT — see LICENSE.

Contributing

PRs welcome. Please run npm test and npm run typecheck before submitting.

Available Tools

15 tools
add_itemAdd an item to a listCInspect

Add an item to a list. Returns: {id, text}.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
list_idYes
positionNo

TDQS

C2.7/5.0
Behavior2/5

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

With no annotations, the description carries the full burden, and it only discloses the return shape ({id, text}). It says nothing about duplicate handling, ordering behavior, permission requirements, or what happens on failure — all relevant for a mutation tool.

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

Conciseness4/5

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

Two short sentences with the purpose front-loaded and no filler. The return-shape line is compact and useful given there is no output schema.

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

Completeness2/5

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

For a 3-parameter mutation tool with no annotations, no output schema, and 0% schema description coverage, this definition leaves too much unspecified — parameter meaning, side effects, and failure modes are all absent.

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

Parameters2/5

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

Schema description coverage is 0% for three parameters (list_id, text, position). The description adds no parameter meaning beyond echoing 'text' and 'id' in the return value, leaving position semantics (index? insertion point?) and id format entirely undocumented.

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

Purpose4/5

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

The description names a specific verb and resource ('Add an item to a list'), so an agent immediately knows the operation. It does not distinguish itself from siblings like update_item or remove_items, which share the same list-item domain.

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

Usage Guidelines2/5

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

There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as update_item or remove_items. The agent must infer selection entirely from the tool name.

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

create_appointmentCreate a calendar appointmentAInspect

Create a calendar appointment. start and end are ISO datetimes (e.g. '2026-06-15T10:00:00'). For all-day events (all_day=true) a bare date (e.g. '2026-06-15') is also accepted and end may equal start; a bare date on a timed event is an error. For a multi-day event put end on a later date — the span is preserved, and the result reports it as end_day. end before start is an error. For attendees, call family_members() first and pass those id values. For a repeating event pass repeat; start/end are then its first occurrence.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYes
notesNo
startYes
notifyNoSend Cozi's change notification to the attendees who have notifications on, like the Cozi app's 'notify' option. Off by default; only when the user asks for it.
repeatNoMake it repeat. `interval` 2 = every other day/week/month/year. Weekly: `weekdays` (e.g. ['MO','WE']; default the start's weekday, which must be included). Monthly/yearly: `monthly_by` 'day_of_month' (default, e.g. the 15th) or 'weekday' (e.g. the 2nd Tuesday; a 5th weekday means the last). `until` is the last possible day (YYYY-MM-DD); omit it to repeat forever.
all_dayNo
subjectYes
locationNo
attendeesNo
remindersNoReminder lead times in minutes before the start, e.g. [30, 1440]. [] clears them on an update.

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does disclose real behavior: which inputs are errors (bare date on timed event, end before start), that multi-day spans are preserved and reported as `end_day`, and that repeat changes the meaning of start/end. It omits permissions/auth and whether adding attendees produces side effects beyond the schema-documented `notify` flag.

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

Conciseness4/5

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

Front-loads the core action, then spends each sentence on a distinct rule (formats, all-day, multi-day, errors, attendees, repeat). Some of the repeat prose overlaps the schema's own `repeat` description, but there is little outright waste.

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

Completeness4/5

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

For a 10-param mutation tool with no annotations and no output schema, the definition covers the temporal and validation semantics an agent most needs to call it correctly. Gaps remain around non-temporal fields and the broader return shape beyond `end_day`, but nothing critical to a successful call is missing.

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

Parameters4/5

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

Schema coverage is only 30% across 10 params, so the description must compensate, and it does for the most error-prone fields: ISO formats for `start`/`end`, all_day date semantics, multi-day span rules, attendee id sourcing, and repeat start/end semantics. It leaves subject, location, notes, and reminders to the schema (which documents notify and reminders), so it is strong but not exhaustive.

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

Purpose5/5

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

Opens with a specific verb+resource ('Create a calendar appointment') that clearly separates it from update_appointment/delete_appointment, and the rest of the text is unambiguous about scope. An agent knows immediately this is the creation path for calendar entries.

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

Usage Guidelines4/5

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

Explicitly routes the agent: 'For attendees, call family_members() first and pass those id values,' and explains when repeat applies (start/end become the first occurrence). It does not state when to prefer update_appointment over re-creating, so it stops short of full alternative coverage.

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

create_listCreate a listAInspect

Create a list ('shopping' or 'todo'). Returns: {id, title, type}.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
list_typeYes

TDQS

A3.6/5.0
Behavior3/5

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

No annotations provided, so the description carries the full burden. It discloses the return structure ({id, title, type}), but does not mention side effects, validation, authorization needs, or behavior on duplicate names.

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

Conciseness5/5

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

The description is extremely concise with two front-loaded sentences and zero wasted words. Every part adds value.

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

Completeness4/5

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

Given the tool's simplicity (2 required params, no nested objects, no output schema), the description provides the essential purpose and return format. It is adequate for an AI agent to use correctly, though it could mention that 'name' is a required string.

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

Parameters3/5

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

Schema coverage is 0% (no descriptions in schema). The description adds context for the 'list_type' parameter by specifying allowed values ('shopping' or 'todo'), but the 'name' parameter is not described at all, leaving its purpose and constraints unclear.

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

Purpose5/5

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

The description clearly states the verb 'create' and the resource 'list', and specifies the two valid types ('shopping' or 'todo'). This distinguishes it from sibling tools like 'create_appointment' or 'get_lists'.

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

Usage Guidelines2/5

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

No explicit guidance on when to use this tool vs alternatives. It does not mention when not to use it or provide context for choosing between this and sibling tools like 'add_item' or 'get_lists'.

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

delete_appointmentDelete an appointmentAInspect

Delete an appointment. Returns true on success; errors if the id is not on the (year, month) page. A recurring series (recurring: true in get_calendar) needs scope: 'this' removes only the occurrence on occurrence_day, 'this_and_following' ends the series before it, 'series' removes every occurrence, past and future. Confirm a 'series' delete with the user first. Holidays, subscribed calendars and birthdays cannot be deleted.

ParametersJSON Schema
NameRequiredDescriptionDefault
yearYes
monthYes
scopeNoRequired for a recurring series: 'this' = only the occurrence on occurrence_day, 'this_and_following' = that occurrence and every later one, 'series' = every occurrence.
notifyNoSend Cozi's change notification to the attendees who have notifications on, like the Cozi app's 'notify' option. Off by default; only when the user asks for it.
appointment_idYes
occurrence_dayNoWith scope 'this' or 'this_and_following': the occurrence's `day` as get_calendar lists it.

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it states the return value (true on success), the error condition (id not on the given year/month page), the destructive reach of each scope including that 'series' removes past AND future occurrences, and a required user-confirmation step. Auth/permission requirements are not covered, which keeps it from a 5.

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

Conciseness4/5

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

Front-loaded with purpose and return behavior, then ordered into recurring semantics, safety confirmation, and exclusions. Every sentence is load-bearing, though the scope enumeration partly duplicates the schema's own enum description.

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

Completeness4/5

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

For a 6-parameter destructive tool with no annotations and no output schema, the description covers return behavior, errors, destructive scope variants, a confirmation gate, and blocked entity types. Pairing/auth prerequisites are the main omission.

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

Parameters3/5

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

Schema coverage is 50%, so the baseline is 3. The description does add real value by explaining the coupling of appointment_id with (year, month) — the id must be on that page — and by reinforcing the recurring-only requirement for scope and its link to occurrence_day. It says nothing about notify (covered by the schema) or the year/month value ranges.

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

Purpose4/5

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

Opens with a specific verb+resource ("Delete an appointment") and adds eligibility rules that distinguish it from update/create siblings by naming what delete cannot touch (holidays, subscribed calendars, birthdays). It does not explicitly name a sibling tool, but the operation is unambiguous.

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

Usage Guidelines4/5

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

Gives clear conditional guidance: scope applies to recurring series detected via `recurring: true` in get_calendar, and 'series' deletes require user confirmation first. It also implies a when-not (holidays, subscribed calendars, birthdays). No alternative tool is named for modifying rather than deleting, so it stops short of 5.

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

delete_listDelete a listCInspect

Delete a list. Returns true on success.

ParametersJSON Schema
NameRequiredDescriptionDefault
list_idYes

TDQS

C2.8/5.0
Behavior2/5

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

With no annotations, the description carries the full behavioral burden for a destructive operation. It notes the return value ('true on success') but omits irreversibility, permission requirements, and whether dependent items are also removed — critical context for a delete.

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

Conciseness5/5

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

Two short sentences, front-loaded with the action and followed by the return contract. Nothing is wasted.

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

Completeness2/5

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

For a destructive, annotation-free tool with no output schema and an undocumented required parameter, the description is too thin. It should at minimum state irreversibility and any preconditions before an agent commits to the call.

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

Parameters2/5

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

Schema description coverage is 0% and the single parameter list_id is documented only by a regex pattern. The description adds no meaning about how to obtain a list_id or what it references, so it does not compensate for the schema gap.

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

Purpose4/5

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

States a specific verb and resource ('Delete a list'), which is unambiguous against siblings like create_list or get_list_items. It does not, however, differentiate itself from other delete-style siblings (delete_appointment, remove_items) or clarify scope (e.g., whether list items go with it).

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

Usage Guidelines2/5

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

There is no guidance on when to use this tool versus alternatives such as remove_items, nor any preconditions or warnings. The agent must infer usage entirely from the name.

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

family_membersList family membersAInspect

List family members. Use the id for appointment attendees. Returns: [{id, name, color?}].

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

No annotations exist, so description must disclose behavior. It correctly states it returns a list of family members with fields {id, name, color?}, but does not specify ordering, caching, or potential empty results. Adequate for a read-only list tool.

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

Conciseness5/5

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

Two tightly crafted sentences: first states purpose, second provides usage guidance and return structure. No redundant words.

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

Completeness5/5

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

Fully sufficient for a simple parameterless tool: describes return format and actionable usage (id for attendees). No output schema exists, so the description compensates well.

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

Parameters4/5

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

No parameters in input schema, so schema coverage is 100%. Description adds no parameter info (none needed), baseline 4 for zero-parameter tools.

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

Purpose5/5

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

The verb 'List' and resource 'family members' is specific and unambiguous. It distinguishes itself from sibling list tools (e.g., get_calendar, get_lists) by naming a distinct entity.

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

Usage Guidelines4/5

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

Explicitly tells the agent to use the returned `id` for appointment attendees, providing a clear use case. Lacks explicit when-not-to-use or alternative comparisons, but sufficient for this simple tool.

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

get_calendarGet appointments for a monthAInspect

Appointments for one month. Returns: [{id, subject, day, all_day, start?, end?, end_day?, attendees?, location?, notes?, reminders?, kind?, read_only?, source?, recurring?, recurrence?, series_start?, series_end?, skipped_days?, covered_days?}]. day is the day the entry happens; end_day appears only on multi-day events, which are listed in every month they overlap, so day may fall outside the month asked for. A recurring series (recurring: true) is listed once per occurrence in the month, as Cozi itself expands it: each entry carries the series id, its own day, and series_start. Occurrences deleted in Cozi are already left out (and named in skipped_days). A multi-day recurring series is instead ONE entry whose covered_days lists every day it covers this month. kind marks items that are not plain appointments (e.g. "birthday"); read_only items (holidays, subscribed calendars, with source naming the calendar) cannot be changed. reminders are minutes before the start.

ParametersJSON Schema
NameRequiredDescriptionDefault
yearYes
monthYes

TDQS

A3.5/5.0
Behavior4/5

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

With no annotations, the description carries the full behavioral burden and does substantial work: it discloses recurrence expansion (one entry per occurrence), that deleted occurrences are omitted and listed in skipped_days, that multi-day events appear in every overlapping month, that multi-day recurring series collapse into a single covered_days entry, and that read_only items cannot be changed. It omits auth/permission requirements and error behavior, but the domain semantics are unusually well covered.

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

Conciseness4/5

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

The first sentence states the purpose and the return shape is front-loaded immediately after, which is good structure. The remainder is a dense block of field-by-field semantics; nearly all of it is load-bearing, though the long inline field list is heavier reading than necessary.

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

Completeness4/5

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

With no output schema, the description must explain return values and it does so thoroughly, covering field meanings, recurrence edge cases, and read_only/source semantics. What remains missing is the parameter format and any note on empty months or volume limits, which keeps it short of complete.

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

Parameters2/5

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

Schema description coverage is 0% for both required parameters, and the description never clarifies the year/month format (full year vs. short, timezone or locale assumptions). It only alludes to 'the month asked for', so the parameters remain largely undocumented in both schema and prose.

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

Purpose4/5

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

The description states a specific resource (appointments) and scope (one month), reinforced by the title 'Get appointments for a month', so the agent knows exactly what it retrieves. It does not, however, explicitly contrast itself with the sibling retrieval tools search_calendar or today, which the month-scoping alone only implicitly separates.

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

Usage Guidelines3/5

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

Usage is implied rather than stated: the month granularity hints at when this tool is appropriate versus search_calendar or today, and the year/month parameters reinforce the month-scoped use case. There is no explicit when-to-use or when-not-to-use guidance and no named alternative, leaving the routing decision to inference.

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

get_list_itemsGet items in a listAInspect

Items in one list. Excludes completed items by default. Returns: [{id, text, status, position?}].

ParametersJSON Schema
NameRequiredDescriptionDefault
list_idYes
include_completedNo

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It discloses the default filtering behavior (excludes completed) and the return shape, which is genuinely useful. However, it doesn't mention read-only safety, pagination, ordering, or permissions—significant omissions for a retrieval tool with zero annotation coverage.

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

Conciseness5/5

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

Three short, front-loaded clauses: scope, default behavior, return shape. No wasted words, and the most decision-relevant fact (default exclusion) is prominent.

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

Completeness3/5

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

No output schema exists, so the inline return shape is a plus. But for a 2-param tool with 0% schema coverage and no annotations, the description leaves gaps: list_id semantics, pagination, error cases, and read-only nature are unaddressed. Adequate but with clear gaps.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must compensate. It clarifies that include_completed controls the completed-item filter, which gives meaning to one parameter. But list_id is undocumented (though self-evident), and the parameter's type/default behavior isn't fully explained. Partial compensation warrants a 3.

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

Purpose4/5

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

States a clear verb+resource: retrieving items within one list. Distinguishes from get_lists (which returns lists, not items). However, it doesn't explicitly name or differentiate from sibling add_item/update_item/remove_items beyond the 'get' verb, so it falls short of a 5.

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

Usage Guidelines3/5

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

The default behavior (excludes completed items) implies context for when to use include_completed, but there's no explicit statement of when to use this vs alternatives like get_lists or update_item. Usage is implied rather than stated.

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

get_listsSummarize all listsAInspect

Summarize all lists (no items). Optionally filter by 'shopping' or 'todo'. Returns: [{id, title, type, item_count, completed_count}].

ParametersJSON Schema
NameRequiredDescriptionDefault
list_typeNo

TDQS

A4.4/5.0
Behavior4/5

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

Without annotations, the description clearly indicates it is a read-only summarization that returns specific fields and explicitly states it does not return items, disclosing key behavioral traits.

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

Conciseness5/5

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

Two sentences with no wasted words: main purpose first, then filter, then return format. Highly concise and well-structured.

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

Completeness4/5

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

The description covers return structure and filtering, which is adequate for a simple list summary tool. Minor omissions like case sensitivity or pagination do not significantly detract.

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

Parameters4/5

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

The schema has 0% description coverage, but the description adds meaning by explaining the parameter's purpose and suggesting valid filter values.

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

Purpose5/5

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

The description clearly states it summarizes all lists without items, and optionally filters by type. It distinguishes from siblings like 'get_list_items' which retrieves items of a specific list.

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

Usage Guidelines4/5

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

The description provides filtering options ('shopping' or 'todo') but does not explicitly state when to use this tool versus alternatives like 'get_list_items' for item details.

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

remove_itemsRemove items from a listCInspect

Remove items from a list. Returns true on success.

ParametersJSON Schema
NameRequiredDescriptionDefault
list_idYes
item_idsYes

TDQS

C2.9/5.0
Behavior2/5

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

No annotations are provided, so the description must carry behavioral disclosure. It only states the return value (true on success) but omits critical details such as required permissions, whether removal is reversible, and whether missing item_ids are ignored or cause errors.

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

Conciseness4/5

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

Two short, front-loaded sentences with minimal waste. The purpose is stated first, followed by the return value, which is efficient though slightly sparse.

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

Completeness2/5

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

Given the absence of annotations and no output schema, the description is incomplete. It does not cover permissions, error conditions, or parameter semantics for a mutation tool with two required parameters.

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

Parameters3/5

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

Schema description coverage is 0%, and the description does not describe the two parameters (list_id, item_ids) beyond their names. With a low coverage, the description fails to compensate for the missing parameter documentation, leaving the agent to infer meanings from names alone.

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

Purpose4/5

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

States a specific verb (Remove) and resource (items from a list), which distinguishes it from siblings like add_item and update_item. However, it does not explicitly differentiate from other removal-style siblings such as delete_list.

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

Usage Guidelines2/5

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

No indication of when to use this tool versus alternatives like update_item or delete_list, nor any prerequisites or conditions for use. The description offers no guidance on selection.

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

rename_listRename a listBInspect

Rename a list; its items stay as they are. Returns: {id, title, type}.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
list_idYes

TDQS

B3.1/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It does disclose one real behavioral trait — that list items are unaffected — and describes the return shape. However it omits permissions/auth needs, idempotency, and error behavior for a mutation tool.

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

Conciseness5/5

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

A single front-loaded sentence plus a compact return spec — every clause earns its place, no filler, and the key side-effect fact comes before the return values.

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

Completeness3/5

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

For a simple two-parameter mutation with no annotations and no output schema, the description covers purpose, the item-preservation side effect, and the return fields {id, title, type}, which is genuinely helpful. It still lacks usage guidance and parameter explanation, leaving gaps for an agent invoking it blind.

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

Parameters2/5

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

Schema description coverage is 0% for two required parameters. The description only implies the 'title' parameter via the word 'rename' and says nothing about 'list_id' (not even its id-like nature), so it fails to compensate for the undocumented schema.

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

Purpose4/5

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

States a specific verb+resource ('Rename a list') plus an important scoping fact (items stay as they are). It is unambiguous, but it does not name or contrast with any sibling (e.g., update_item vs rename_list), so the agent gets no explicit routing signal.

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

Usage Guidelines2/5

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

No when-to-use, when-not-to-use, or alternative is given. The purpose implies renaming a list's title, but nothing tells the agent when this is preferable to, say, create_list or update_item, nor any prerequisites.

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

search_calendarSearch the calendarAInspect

Find appointments by words in their subject, across months (Cozi's own search, the one in its app). Use it for "when is the dentist?" instead of paging through months. Returns: {appointments: [{...same fields as get_calendar, last_day?, next_days?}], more?}. A recurring series is one entry with last_day (latest past occurrence) and next_days (up to 10 upcoming). Cozi searches from a few years back onward, and an appointment created in the last few seconds may not be found yet; more: true means it found more than this first page, so narrow the query.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so richly: it discloses the search time horizon ('from a few years back onward'), an indexing lag ('an appointment created in the last few seconds may not be found yet'), pagination semantics ('more: true means it found more than this first page'), and how recurring series collapse into one entry with last_day/next_days.

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

Conciseness5/5

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

Front-loads purpose and usage, then return shape, then caveats, in a tight sequence. Despite covering many topics, nearly every clause adds distinct information an agent needs (field shape, pagination, staleness, recurrence).

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

Completeness5/5

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

There is no output schema, but the description supplies the return shape inline and covers the operational edge cases (indexing delay, result cap, recurrence representation) that an agent would otherwise have to discover by trial. Nothing material for correct invocation is missing.

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

Parameters4/5

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

Schema coverage is 0% for the single required 'query' parameter, so the description must compensate. It does by specifying that matching is against words 'in their subject', narrowing the semantics of an otherwise bare string param, though it does not cover case sensitivity, partial-word matching, or multi-word behavior.

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

Purpose5/5

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

States a specific verb and resource ('Find appointments by words in their subject, across months') and clarifies it is Cozi's own app-level search, which separates it from get_calendar and today. An agent can distinguish it from all siblings without opening a schema.

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

Usage Guidelines4/5

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

Gives a concrete when-to-use cue ('when is the dentist?') and an explicit alternative behavior ('instead of paging through months'), which implicitly routes to get_calendar. It does not explicitly name the sibling tool or state when-not to use it, so it falls short of a full 5.

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

todayToday's date in the user's timezoneAInspect

Current date, weekday and time on the user's machine. Returns: {date, weekday, time, timezone}. Call it before turning 'tomorrow' or 'this Saturday' into the ISO dates the calendar tools take when you have not called another Cozi tool yet; every Cozi tool result also carries this time.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

With no annotations, the description carries the full burden, and it does disclose two useful behavioral facts: the exact return tuple and the cross-tool invariant that every Cozi result also carries this timestamp (which bounds how often it must be called). It does not explicitly state that the tool is side-effect-free or discuss timezone/DST edge cases, so it falls short of a 5.

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

Conciseness5/5

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

Two tight sentences, front-loaded with what it returns and followed by the one condition that governs when to call it. Every clause earns its place; nothing is repeated from the title or schema.

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

Completeness5/5

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

There is no output schema, but the description enumerates the returned fields ({date, weekday, time, timezone}) and explains the one non-obvious interaction (other Cozi results already carry the time). For a zero-param, read-only context tool this is complete.

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

Parameters4/5

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

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline of 4 applies. The description appropriately spends no words on parameters.

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

Purpose5/5

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

States a specific resource (current date, weekday, time on the user's machine) with an explicit return shape, and its identity is unambiguous against calendar/list siblings that mutate data. An agent can tell at a glance that this is a clock/context tool, not a data access tool.

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

Usage Guidelines5/5

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

Gives an explicit trigger ('call it before turning "tomorrow" or "this Saturday" into ISO dates') and an explicit exclusion ('when you have not called another Cozi tool yet; every Cozi tool result also carries this time'). This is exactly the when/when-not guidance that prevents redundant calls.

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

update_appointmentPartial-update an appointmentAInspect

Partial-update an appointment. The Cozi PUT semantics replace ALL fields, so this tool first fetches the existing appointment from the (year, month) page and merges your changes — only fields you pass are altered. To switch a timed appointment to all-day pass all_day=true; to switch to timed pass new start/end. Passing end re-spans the event against its (possibly newly set) start day, so an end on a later date makes it multi-day and one on the start day collapses it back; passing start alone moves the event and keeps its length, and all_day=true preserves the span. A bare date (e.g. '2026-06-15') is accepted for start/end when the event is, or is being made, all-day; on a timed event it is an error. A recurring series (recurring: true in get_calendar) needs scope: 'this' changes only the occurrence on occurrence_day (Cozi stores it as its own appointment, returned here), 'this_and_following' changes it and every later one (returned as the new series), 'series' changes every occurrence and keeps the rule unless repeat replaces it. repeat also turns a one-off into a series. Holidays, subscribed calendars and birthdays cannot be changed.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNo
yearYes
monthYes
notesNo
scopeNoRequired for a recurring series: 'this' = only the occurrence on occurrence_day, 'this_and_following' = that occurrence and every later one, 'series' = every occurrence.
startNo
notifyNoSend Cozi's change notification to the attendees who have notifications on, like the Cozi app's 'notify' option. Off by default; only when the user asks for it.
repeatNoMake it repeat. `interval` 2 = every other day/week/month/year. Weekly: `weekdays` (e.g. ['MO','WE']; default the start's weekday, which must be included). Monthly/yearly: `monthly_by` 'day_of_month' (default, e.g. the 15th) or 'weekday' (e.g. the 2nd Tuesday; a 5th weekday means the last). `until` is the last possible day (YYYY-MM-DD); omit it to repeat forever.
all_dayNo
subjectNo
locationNo
attendeesNo
remindersNoReminder lead times in minutes before the start, e.g. [30, 1440]. [] clears them on an update.
appointment_idYes
occurrence_dayNoWith scope 'this' or 'this_and_following': the occurrence's `day` as get_calendar lists it.

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full behavioral burden and does so well: it discloses the underlying Cozi PUT-replace semantics and the fetch-and-merge workaround, the exact start/end re-spans and length-preservation behavior, the all_day exceptions, an explicit error condition (bare date on a timed event), and immutable entities. It even notes return behavior for scope 'this' vs 'this_and_following'.

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

Conciseness4/5

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

The purpose and merge mechanism are front-loaded, followed by parameter-specific rules in a logical order. It is dense and long, but nearly every clause conveys a distinct behavioral rule rather than restating the name or schema. Slightly heavy, yet the volume is justified by the tool's complexity.

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

Completeness4/5

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

For a 15-parameter mutation tool with no annotations and no output schema, the description is unusually complete on mutation semantics, error cases, and editability limits. The remaining gaps are secondary parameter meanings (notify, attendees, reminders) and auth/permission prerequisites, which keep it just shy of fully self-sufficient.

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

Parameters4/5

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

Schema description coverage is only 33%, so the description must compensate, and it does for the hardest parameters: start, end, all_day, scope, and repeat semantics are spelled out in detail beyond the schema. It does not explain notify, attendees, reminders, subject, location, appointment_id, year, or month, leaving several parameters undocumented in both places, so it stops short of fully closing the gap.

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

Purpose5/5

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

Opens with a specific verb+resource ('Partial-update an appointment'), immediately distinguishing it from create_appointment and delete_appointment. The first sentence also clarifies that it is a merge-update rather than a destructive replace, which is the key differentiator an agent needs. No sibling ambiguity remains.

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

Usage Guidelines4/5

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

Gives rich conditional guidance on when to use which parameters: all_day=true to make all-day, new start/end to make timed, scope required for recurring series, and explicitly states holidays/subscribed calendars/birthdays cannot be changed. However it never names sibling alternatives (e.g. create_appointment, delete_appointment) to route between tools, so it falls short of the explicit-alternatives bar.

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

update_itemUpdate an item's text and/or completionAInspect

Update an item's text and/or completion status. Pass text, completed, or both. When both are provided the text is updated first then status is updated as a separate request — these are NOT atomic. Returns: {id, text, status}.

ParametersJSON Schema
NameRequiredDescriptionDefault
textNo
item_idYes
list_idYes
completedNo

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries full burden and does real work: it discloses that a combined text+status update is executed as two sequential requests that are NOT atomic, which an agent must know to reason about partial-failure states. It also discloses the response shape {id, text, status}. It omits permission/auth requirements and error behavior, keeping it off a 5.

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

Conciseness5/5

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

Three short sentences, zero filler: purpose first, then valid parameter combinations, then the non-atomicity caveat, then the return shape. The most decision-critical constraint is placed where it cannot be missed and nothing is repeated from the schema.

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

Completeness4/5

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

For an unannotated mutation tool with no output schema and four undocumented parameters, the description supplies the two things that matter most: the non-atomic update behavior and the return shape. Remaining gaps are authorization requirements and failure semantics for a partially applied update, which an agent would still have to discover.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must compensate. It adds real meaning for `text` and `completed` (they can be supplied individually or together, with ordering semantics) but says nothing about `list_id` or `item_id` beyond their presence as required identifiers, and gives no format notes despite the id patterns. Partial compensation justifies the baseline 3.

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

Purpose4/5

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

The description opens with a specific verb+resource+scope: "Update an item's text and/or completion status", which unambiguously separates it from add_item, remove_items, and update_list-style siblings. It names the exact mutable fields rather than restating the title. It stops short of explicitly contrasting with any sibling tool, so it lands just under a 5.

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

Usage Guidelines3/5

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

"Pass `text`, `completed`, or both" tells the agent what input combinations are valid, which is useful invocation guidance. However, it never states when to prefer this tool over a delete/re-add pattern or what happens on invalid item_id, and there are no explicit exclusions. Usage is implied rather than prescribed.

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.

  1. 6 tool updatesv2.5.0
    • Changedcreate_appointment3 fields changed
      • addedInput schema / properties / notify
        Added value: +{
        +  "description": "Send Cozi's change notification to the attendees who have notifications on, like the Cozi app's 'notify' option. Off by default; only when the user asks for it.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / reminders
        Added value: +{
        +  "description": "Reminder lead times in minutes before the start, e.g. [30, 1440]. [] clears them on an update.",
        +  "items": {
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / repeat
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Make it repeat. `interval` 2 = every other day/week/month/year. Weekly: `weekdays` (e.g. ['MO','WE']; default the start's weekday, which must be included). Monthly/yearly: `monthly_by` 'day_of_month' (default, e.g. the 15th) or 'weekday' (e.g. the 2nd Tuesday; a 5th weekday means the last). `until` is the last possible day (YYYY-MM-DD); omit it to repeat forever.",
        +  "properties": {
        +    "frequency": {
        +      "enum": [
        +        "daily",
        +        "weekly",
        +        "monthly",
        +        "yearly"
        +      ],
        +      "type": "string"
        +    },
        +    "interval": {
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "monthly_by": {
        +      "enum": [
        +        "day_of_month",
        +        "weekday"
        +      ],
        +      "type": "string"
        +    },
        +    "until": {
        +      "type": "string"
        +    },
        +    "weekdays": {
        +      "items": {
        +        "enum": [
        +          "SU",
        +          "MO",
        +          "TU",
        +          "WE",
        +          "TH",
        +          "FR",
        +          "SA"
        +        ],
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "frequency"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_appointment3 fields changed
      • addedInput schema / properties / notify
        Added value: +{
        +  "description": "Send Cozi's change notification to the attendees who have notifications on, like the Cozi app's 'notify' option. Off by default; only when the user asks for it.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / occurrence_day
        Added value: +{
        +  "description": "With scope 'this' or 'this_and_following': the occurrence's `day` as get_calendar lists it.",
        +  "type": "string"
        +}
      • addedInput schema / properties / scope
        Added value: +{
        +  "description": "Required for a recurring series: 'this' = only the occurrence on occurrence_day, 'this_and_following' = that occurrence and every later one, 'series' = every occurrence.",
        +  "enum": [
        +    "this",
        +    "this_and_following",
        +    "series"
        +  ],
        +  "type": "string"
        +}
    • Addedrename_list
    • Addedsearch_calendar
    • Addedtoday
    • Changedupdate_appointment5 fields changed
      • addedInput schema / properties / notify
        Added value: +{
        +  "description": "Send Cozi's change notification to the attendees who have notifications on, like the Cozi app's 'notify' option. Off by default; only when the user asks for it.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / occurrence_day
        Added value: +{
        +  "description": "With scope 'this' or 'this_and_following': the occurrence's `day` as get_calendar lists it.",
        +  "type": "string"
        +}
      • addedInput schema / properties / reminders
        Added value: +{
        +  "description": "Reminder lead times in minutes before the start, e.g. [30, 1440]. [] clears them on an update.",
        +  "items": {
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / repeat
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Make it repeat. `interval` 2 = every other day/week/month/year. Weekly: `weekdays` (e.g. ['MO','WE']; default the start's weekday, which must be included). Monthly/yearly: `monthly_by` 'day_of_month' (default, e.g. the 15th) or 'weekday' (e.g. the 2nd Tuesday; a 5th weekday means the last). `until` is the last possible day (YYYY-MM-DD); omit it to repeat forever.",
        +  "properties": {
        +    "frequency": {
        +      "enum": [
        +        "daily",
        +        "weekly",
        +        "monthly",
        +        "yearly"
        +      ],
        +      "type": "string"
        +    },
        +    "interval": {
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "monthly_by": {
        +      "enum": [
        +        "day_of_month",
        +        "weekday"
        +      ],
        +      "type": "string"
        +    },
        +    "until": {
        +      "type": "string"
        +    },
        +    "weekdays": {
        +      "items": {
        +        "enum": [
        +          "SU",
        +          "MO",
        +          "TU",
        +          "WE",
        +          "TH",
        +          "FR",
        +          "SA"
        +        ],
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "frequency"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / properties / scope
        Added value: +{
        +  "description": "Required for a recurring series: 'this' = only the occurrence on occurrence_day, 'this_and_following' = that occurrence and every later one, 'series' = every occurrence.",
        +  "enum": [
        +    "this",
        +    "this_and_following",
        +    "series"
        +  ],
        +  "type": "string"
        +}
  2. 5 tool updatesv2.2.0
    • Changedadd_item1 field changed
      • addedInput schema / properties / list_id / pattern
        Added value: +"^[A-Za-z0-9_-]+$"
    • Changeddelete_list1 field changed
      • addedInput schema / properties / list_id / pattern
        Added value: +"^[A-Za-z0-9_-]+$"
    • Changedget_list_items1 field changed
      • addedInput schema / properties / list_id / pattern
        Added value: +"^[A-Za-z0-9_-]+$"
    • Changedremove_items2 fields changed
      • addedInput schema / properties / item_ids / items / pattern
        Added value: +"^[A-Za-z0-9_-]+$"
      • addedInput schema / properties / list_id / pattern
        Added value: +"^[A-Za-z0-9_-]+$"
    • Changedupdate_item2 fields changed
      • addedInput schema / properties / item_id / pattern
        Added value: +"^[A-Za-z0-9_-]+$"
      • addedInput schema / properties / list_id / pattern
        Added value: +"^[A-Za-z0-9_-]+$"
  3. 12 tool updatesv2.0.1
    • First observedadd_item
    • First observedcreate_appointment
    • First observedcreate_list
    • First observeddelete_appointment
    • First observeddelete_list
    • First observedfamily_members
    • First observedget_calendar
    • First observedget_list_items
    • First observedget_lists
    • First observedremove_items
    • First observedupdate_appointment
    • First observedupdate_item

TDQS

A3.7/5.0

Scored across 15 tools

Disambiguation5/5

The two domains (lists vs calendar) are cleanly separated, and within each domain every tool targets a distinct resource+action (add_item vs update_item vs remove_items, create_appointment vs update_appointment vs delete_appointment). search_calendar vs get_calendar are clearly differentiated by intent (keyword search vs month page). No two tools appear interchangeable.

Naming Consistency4/5

The set is overwhelmingly consistent snake_case verb_noun (create_list, add_item, update_appointment, delete_list, get_lists). The only deviations are the bare noun 'today' and the noun phrase 'family_members', which break the verb_noun pattern but are still clear.

Tool Count5/5

15 tools is well within the healthy range and each tool earns its place across two distinct domains (list management and calendar management). Nothing is redundant and nothing feels like filler.

Completeness4/5

Both domains have full lifecycle coverage: lists and items support create/read/update/delete, and appointments support get/search/create/update/delete including recurring-series scoping, plus family_members and today helpers. Minor gaps exist (no direct single-appointment fetch by id, no cross-list item search), but these are workable around.

Maintenance

ActivityMaintained
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to interact with AnyList for managing shopping lists, recipes, and meal planning. Users can retrieve recipe details, add ingredients to lists, and schedule meals on their AnyList calendar.
    10
    -