io.github.syncday-app/sync-day
Measured conclusion: Deep-tested. L2 outcome: tools_ok.
Free no-signup group scheduling; share a link and rank times by who's free.
| Author | io.github.syncday-app |
|---|---|
| Access | remote |
| Publisher key required | No |
| Measured state | Deep-tested |
| L1 liveness | alive |
| L1 latency | 2277 ms |
| Last measured | 2026-10-26 |
Add to your agent
Copy this into your MCP client config:
{
"mcpServers": {
"sync-day": {
"url": "https://sync.day/mcp/mcp",
"transport": "streamable-http"
}
}
}
Measured tools (8)
create_eventCreate a sync.day availability poll and get its share link. Candidate days run from startDate to endDate (inclusive; or give days instead). Each day offers candidate START times from hourFrom, every startStepMinutes, as long as start + durationMinutes <= hourTo. Returns slug, public url (share this), adminUrl and adminKey (keep private; needed for update_event / remove_participant). Example: 周六周日下午聚餐 3 小时 -> {title:'周末聚餐', startDate:'2026-09-05', endDate:'2026-09-06', hourFrom:13, hourTo:18, durationMinutes:180, startStepMinutes:60}.
Parameters:
title(required) — string — Event name, max 60 chars. e.g. 周末聚餐, Team syncstartDate(required) — string — First candidate day, YYYY-MM-DD. e.g. 2026-09-05hourFrom(required) — integer — Earliest hour of each day (0-23). e.g. 9hourTo(required) — integer — End of each day's window, exclusive (1-24), must be > hourFrom. e.g. 22durationMinutes(required) — Event length in minutes. One of 30, 60, 90, 120, 180, 240, 480.days— integer — Number of consecutive days from startDate (1-21); alternative to endDate.endDate— string — Last candidate day, inclusive, YYYY-MM-DD (same as startDate for a single day; at most 21 days). Give this or days; endDate wins when both are set.question— string — Optional prompt shown to participants, max 200 chars. e.g. 哪天晚上有空?startStepMinutes— Gap between candidate start times in minutes: 30 or 60 (default 60).
Hints: read-only no · destructive no · idempotent no · open-world no
parse_event_textread-onlyTurn a natural-language sentence (Chinese works best) into create_event input using sync.day's AI parser. Does NOT create anything; review the result, then call create_event. Example: '下周六或周日下午聚餐,大概 3 小时'.
Parameters:
text(required) — string — One sentence describing the event, max 300 chars.today— string — Reference date for relative words like 明天/下周, YYYY-MM-DD. Defaults to today in Asia/Shanghai.
Hints: read-only yes · destructive not declared · idempotent not declared · open-world yes
get_eventread-onlyRead an event: settings, every candidate start key per day (startOptions), who has answered (participants with their start keys; names may repeat), the top 10 start times by head-count (ranked), the starts EVERYONE with picks can make with their votes (voteOptions), each person's vote (votes) and decidedStart. No key needed.
Parameters:
slug(required) — string — Event slug from the URL, e.g. calm-otter-4821 (sync.day/calm-otter-4821)
Hints: read-only yes · destructive not declared · idempotent not declared · open-world no
submit_availabilitySave (or replace) one person's availability: the candidate start keys they can make, from get_event.startOptions. The person is identified by `identity`, not by name: the same identity later overwrites the same row (and can rename it), a different identity with the same name is a second participant. Keys outside the event's start options are rejected. Returns the updated ranking.
Parameters:
slug(required) — string — Event slug from the URL, e.g. calm-otter-4821 (sync.day/calm-otter-4821)identity(required) — string — Random secret for this person that you generate and keep per person, 16-256 chars (e.g. 32 hex chars; NOT a plain user id or name, since anyone who guesses it can act as them). Same identity = same participant; the server stores only a hash. Example: 3f9a1c77b2e04d5e8a61f0c9d2b7e415name(required) — string — Display name, 1-20 chars, may repeat. e.g. 小明starts(required) — array — Start keys like 2026-09-05T14:00. Empty array clears this person's picks.
Hints: read-only no · destructive no · idempotent yes · open-world no
remove_participantdestructiveOrganiser only: remove one participant by name (the oldest row with that name when it repeats), together with their vote. Requires the adminKey from create_event.
Parameters:
slug(required) — string — Event slug from the URL, e.g. calm-otter-4821 (sync.day/calm-otter-4821)name(required) — string — Exact participant name to remove.adminKey(required) — string — Organiser key returned by create_event (the ?key= part of adminUrl).
Hints: read-only no · destructive yes · idempotent yes · open-world no
update_eventOrganiser only: change any event settings (same fields and rules as create_event; omitted fields keep their current value; endDate wins over days). Existing picks are kept; those no longer valid starts are just hidden.
Parameters:
slug(required) — string — Event slug from the URL, e.g. calm-otter-4821 (sync.day/calm-otter-4821)adminKey(required) — string — Organiser key returned by create_event (the ?key= part of adminUrl).days— integer — Number of consecutive days from startDate (1-21); alternative to endDate.title— string — Event name, max 60 chars. e.g. 周末聚餐, Team synchourTo— integer — End of each day's window, exclusive (1-24), must be > hourFrom. e.g. 22endDate— string — Last candidate day, inclusive, YYYY-MM-DD (same as startDate for a single day; at most 21 days). Give this or days; endDate wins when both are set.hourFrom— integer — Earliest hour of each day (0-23). e.g. 9question— string — Optional prompt shown to participants, max 200 chars. e.g. 哪天晚上有空?startDate— string — First candidate day, YYYY-MM-DD. e.g. 2026-09-05durationMinutes— Event length in minutes. One of 30, 60, 90, 120, 180, 240, 480.startStepMinutes— Gap between candidate start times in minutes: 30 or 60 (default 60).
Hints: read-only no · destructive no · idempotent yes · open-world no
vote_timeApproval voting: set every start one person accepts (replaces their earlier approvals; an empty list clears them). The voter is the `identity` used in submit_availability and must have at least one start saved. Only keys listed in get_event.voteOptions are accepted; the error lists the current options otherwise. Rejected once the organiser decided. Example: {slug:'calm-otter-4821', identity:'3f9a1c77b2e04d5e8a61f0c9d2b7e415', starts:['2026-09-05T15:00','2026-09-06T10:00']}. `start` is shorthand for a single-item `starts`.
Parameters:
slug(required) — string — Event slug from the URL, e.g. calm-otter-4821 (sync.day/calm-otter-4821)identity(required) — string — Random secret for this person that you generate and keep per person, 16-256 chars (e.g. 32 hex chars; NOT a plain user id or name, since anyone who guesses it can act as them). Same identity = same participant; the server stores only a hash. Example: 3f9a1c77b2e04d5e8a61f0c9d2b7e415start— string — Shorthand for starts: [start]starts— array — All start keys this person accepts (from get_event.voteOptions); [] clears their approvals
Hints: read-only no · destructive no · idempotent yes · open-world no
decide_timeOrganiser only: settle on a start time (locks availability picking and voting; the page shows 已定). Pass start=null to reopen. Requires the adminKey from create_event.
Parameters:
slug(required) — string — Event slug from the URL, e.g. calm-otter-4821 (sync.day/calm-otter-4821)adminKey(required) — string — Organiser key returned by create_event (the ?key= part of adminUrl).start(required) — A candidate start key of the event (normally one of voteOptions), or null to reopen.
Hints: read-only no · destructive no · idempotent yes · open-world no
Measured by MCPYP probing. Untested fields are omitted, never estimated. Listing is always free; MCPYP never proxies calls or stores user tokens.