Skip to content

MCP Tools Reference

Chronary exposes 21 MCP tools. Each tool maps to one or more REST API endpoints but is designed for natural-language invocation by AI agents.


Register your agent (AI assistant, human participant, or resource) with Chronary, creating a Chronary identity it can use to own calendars, events, and webhooks. The agent itself already exists in your system — this gives it a Chronary record.

| Parameter | Type | Required | Description | |---|---|---|---| | name | string | Yes | Display name for the agent | | type | enum: ai, human, resource | Yes | Agent type — ai for bots, human for people, resource for rooms/equipment | | description | string | No | Optional description of the agent’s purpose |

User: “Register an AI agent for my customer support team”

Tool call:

{
"name": "create_agent",
"arguments": {
"name": "Customer Support Agent",
"type": "ai",
"description": "Handles scheduling for customer support calls"
}
}

Response:

{
"id": "agt_a1b2c3d4",
"name": "Customer Support Agent",
"type": "ai",
"description": "Handles scheduling for customer support calls",
"status": "active",
"created_at": "2026-04-04T10:00:00Z"
}

List agents in your organization with optional filtering.

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | type | enum: ai, human, resource | No | — | Filter by agent type | | status | enum: active, paused, decommissioned | No | — | Filter by status | | limit | number (1–200) | No | 50 | Maximum results to return | | offset | number | No | 0 | Pagination offset |

User: “Show me all my active AI agents”

Tool call:

{
"name": "list_agents",
"arguments": {
"type": "ai",
"status": "active"
}
}

Response:

{
"data": [
{
"id": "agt_a1b2c3d4",
"name": "Customer Support Agent",
"type": "ai",
"status": "active"
},
{
"id": "agt_e5f6g7h8",
"name": "Sales Agent",
"type": "ai",
"status": "active"
}
],
"total": 2,
"limit": 50,
"offset": 0
}

Create a calendar. Calendars can belong to a specific agent or exist at the organization level.

| Parameter | Type | Required | Description | |---|---|---|---| | name | string | Yes | Calendar display name | | agent_id | string | No | Agent to own this calendar. Omit for an org-level calendar. | | timezone | string (IANA) | Yes | Calendar timezone, e.g. America/New_York, Europe/London, UTC |

User: “Create a calendar for my sales agent in New York timezone”

Tool call:

{
"name": "create_calendar",
"arguments": {
"name": "Sales Calendar",
"agent_id": "agt_e5f6g7h8",
"timezone": "America/New_York"
}
}

Response:

{
"id": "cal_x1y2z3",
"name": "Sales Calendar",
"agent_id": "agt_e5f6g7h8",
"timezone": "America/New_York",
"ical_url": "https://api.chronary.ai/ical/abc123.ics",
"created_at": "2026-04-04T10:05:00Z"
}

Create an event on a calendar.

| Parameter | Type | Required | Description | |---|---|---|---| | calendar_id | string | Yes | Target calendar ID (cal_ prefix) | | title | string | Yes | Event title | | start_time | string (ISO 8601) | Yes | Event start time, e.g. 2026-04-07T14:00:00Z | | end_time | string (ISO 8601) | Yes | Event end time | | description | string | No | Event description or notes | | all_day | boolean | No | Set to true for all-day events |

User: “Schedule a 30-minute demo call for next Monday at 2pm UTC”

Tool call:

{
"name": "create_event",
"arguments": {
"calendar_id": "cal_x1y2z3",
"title": "Demo Call",
"start_time": "2026-04-07T14:00:00Z",
"end_time": "2026-04-07T14:30:00Z",
"description": "Product demo for prospective client"
}
}

Response:

{
"id": "evt_m1n2o3",
"calendar_id": "cal_x1y2z3",
"title": "Demo Call",
"start_time": "2026-04-07T14:00:00Z",
"end_time": "2026-04-07T14:30:00Z",
"description": "Product demo for prospective client",
"status": "confirmed",
"created_at": "2026-04-04T10:10:00Z"
}

List events on a calendar with optional time-range filtering.

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | calendar_id | string | Yes | — | Calendar ID to query | | start_after | string (ISO 8601) | No | — | Only events starting after this time | | start_before | string (ISO 8601) | No | — | Only events starting before this time | | limit | number (1–200) | No | 50 | Maximum results to return | | offset | number | No | 0 | Pagination offset |

User: “What meetings do I have next week?”

Tool call:

{
"name": "list_events",
"arguments": {
"calendar_id": "cal_x1y2z3",
"start_after": "2026-04-06T00:00:00Z",
"start_before": "2026-04-13T00:00:00Z"
}
}

Response:

{
"data": [
{
"id": "evt_m1n2o3",
"title": "Demo Call",
"start_time": "2026-04-07T14:00:00Z",
"end_time": "2026-04-07T14:30:00Z",
"status": "confirmed"
},
{
"id": "evt_p4q5r6",
"title": "Team Standup",
"start_time": "2026-04-08T09:00:00Z",
"end_time": "2026-04-08T09:15:00Z",
"status": "confirmed"
}
],
"total": 2,
"limit": 50,
"offset": 0
}

Cancel an event. The event is marked as cancelled rather than deleted, preserving history.

| Parameter | Type | Required | Description | |---|---|---|---| | event_id | string | Yes | Event to cancel (evt_ prefix) | | calendar_id | string | No | Calendar the event belongs to. Optional — if omitted, the calendar is resolved from the event (matching the behavior of confirm_event / release_event). Provide it to fail fast on cross-calendar typos. |

User: “Cancel my demo call on Monday”

Tool call:

{
"name": "cancel_event",
"arguments": {
"calendar_id": "cal_x1y2z3",
"event_id": "evt_m1n2o3"
}
}

Response:

{
"id": "evt_m1n2o3",
"title": "Demo Call",
"status": "cancelled",
"cancelled_at": "2026-04-04T11:00:00Z"
}

Promote a held event to a confirmed booking. The event must currently have status="hold" and its hold_expires_at must not have passed. After confirmation, event.started and event.ended lifecycle webhooks fire at the scheduled times.

| Parameter | Type | Required | Description | |---|---|---|---| | event_id | string | Yes | Event ID of the hold to confirm (evt_ prefix) |

User: “Lock in the 2 pm demo slot I placed a hold on”

Tool call:

{
"name": "confirm_event",
"arguments": {
"event_id": "evt_h1a2b3c4"
}
}

Response:

{
"id": "evt_h1a2b3c4",
"status": "confirmed",
"hold_expires_at": null,
"start_time": "2026-04-05T14:00:00Z",
"end_time": "2026-04-05T14:30:00Z"
}

Manually release a held event before its hold_expires_at. The event must currently have status="hold". Frees the slot for other agents to book.

| Parameter | Type | Required | Description | |---|---|---|---| | event_id | string | Yes | Event ID of the hold to release (evt_ prefix) |

User: “Never mind, release that 2 pm hold”

Tool call:

{
"name": "release_event",
"arguments": {
"event_id": "evt_h1a2b3c4"
}
}

Response:

{
"released": true,
"id": "evt_h1a2b3c4"
}

Query available time slots for a single agent across all their calendars.

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | agent_id | string | Yes | — | Agent to check availability for | | start | string (ISO 8601) | Yes¹ | — | Start of the query window. Alias: start_time. | | end | string (ISO 8601) | Yes¹ | — | End of the query window. Alias: end_time. | | slot_duration | enum: 15m, 30m, 45m, 1h, 2h | No | 30m | Duration of each available slot | | include_busy | boolean | No | false | Include busy periods in the response |

¹ Use either start/end (canonical — matches the availability service) or start_time/end_time (aliases — match the REST events schema). Mixing forms is allowed; the canonical name wins.

User: “When is my support agent free tomorrow afternoon for a 1-hour meeting?”

Tool call:

{
"name": "get_availability",
"arguments": {
"agent_id": "agt_a1b2c3d4",
"start": "2026-04-05T12:00:00Z",
"end": "2026-04-05T18:00:00Z",
"slot_duration": "1h"
}
}

Response:

{
"agent_id": "agt_a1b2c3d4",
"slots": [
{ "start": "2026-04-05T12:00:00Z", "end": "2026-04-05T13:00:00Z" },
{ "start": "2026-04-05T13:00:00Z", "end": "2026-04-05T14:00:00Z" },
{ "start": "2026-04-05T15:00:00Z", "end": "2026-04-05T16:00:00Z" },
{ "start": "2026-04-05T16:00:00Z", "end": "2026-04-05T17:00:00Z" }
]
}

Find overlapping free slots across multiple agents — ideal for scheduling group meetings.

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | agents | array of strings | Yes¹ | — | Agent IDs to check (minimum 2). Alias: agent_ids. | | start | string (ISO 8601) | Yes¹ | — | Start of the query window. Alias: start_time. | | end | string (ISO 8601) | Yes¹ | — | End of the query window. Alias: end_time. | | slot_duration | enum: 15m, 30m, 45m, 1h, 2h | No | 30m | Duration of each slot | | calendars | array of strings | No | — | Limit to specific calendars (default: all calendars for each agent) | | include_busy | boolean | No | false | Include per-agent busy periods |

¹ agents/start/end are the canonical names. agent_ids/start_time/end_time are accepted as aliases for clients written against the REST/scheduling-proposal naming. The canonical name wins if both are supplied.

User: “Find a 30-minute slot next week where both my sales agent and support agent are free”

Tool call:

{
"name": "find_meeting_time",
"arguments": {
"agents": ["agt_a1b2c3d4", "agt_e5f6g7h8"],
"start": "2026-04-06T09:00:00Z",
"end": "2026-04-10T17:00:00Z",
"slot_duration": "30m"
}
}

Response:

{
"agents": ["agt_a1b2c3d4", "agt_e5f6g7h8"],
"slots": [
{ "start": "2026-04-06T10:00:00Z", "end": "2026-04-06T10:30:00Z" },
{ "start": "2026-04-06T11:00:00Z", "end": "2026-04-06T11:30:00Z" },
{ "start": "2026-04-07T09:00:00Z", "end": "2026-04-07T09:30:00Z" },
{ "start": "2026-04-07T15:00:00Z", "end": "2026-04-07T15:30:00Z" }
]
}

Subscribe an agent’s calendar to an external iCal feed. Chronary will periodically sync events from the external URL into the agent’s calendar.

| Parameter | Type | Required | Description | |---|---|---|---| | agent_id | string | Yes | Agent that owns the target calendar | | calendar_id | string | Yes | Calendar to subscribe to the external feed. Must be agent-owned. | | url | string (HTTPS) | Yes | URL of the external .ics feed | | label | string | No | Display label for this subscription |

User: “Subscribe my sales agent’s calendar to our company holiday calendar”

Tool call:

{
"name": "subscribe_ical",
"arguments": {
"agent_id": "agt_e5f6g7h8",
"calendar_id": "cal_x1y2z3",
"url": "https://company.example.com/holidays.ics",
"label": "Company Holidays"
}
}

Response:

{
"id": "sub_k1l2m3",
"agent_id": "agt_e5f6g7h8",
"calendar_id": "cal_x1y2z3",
"url": "https://company.example.com/holidays.ics",
"label": "Company Holidays",
"status": "active",
"last_synced_at": null,
"created_at": "2026-04-04T10:15:00Z"
}

Fetch a calendar’s temporal context in one call — the current event, next upcoming event, recent past events, a short upcoming window, and the owning agent’s agent_status. Use this to answer “what is this agent doing right now?” without issuing multiple list_events queries.

| Parameter | Type | Required | Description | |---|---|---|---| | calendar_id | string | Yes | Calendar to inspect |

User: “What is the support agent up to right now?”

Tool call:

{
"name": "get_calendar_context",
"arguments": { "calendar_id": "cal_x1y2z3" }
}

Response (shape follows the REST /v1/calendars/:id/context response):

{
"calendar_id": "cal_x1y2z3",
"now": "2026-04-24T14:30:00.000Z",
"agent_status": "working",
"current_event": { "id": "evt_a1", "title": "Customer call", "end_time": "2026-04-24T15:00:00Z" },
"next_event": { "id": "evt_a2", "start_time": "2026-04-24T15:30:00Z" },
"recent_events": [],
"upcoming": []
}

Send a set of candidate time slots to one or more participant agents so they can accept, decline, or counter-propose. Once every participant responds, the system auto-resolves to the highest-scoring slot (or cancels if all decline). Requires an org-level API key. Pro plan only.

| Parameter | Type | Required | Description | |---|---|---|---| | title | string | Yes | Short description of the meeting | | description | string | No | Longer context / agenda | | organizer_agent_id | string | Yes | Agent proposing the meeting | | participant_agent_ids | string[] | Yes | Invited agents (1–50) | | calendar_id | string | Yes | Calendar the resolved event lands on | | slots | array | Yes | Candidate time slots (1–20). Each: { start_time, end_time, weight?, calendar_id? } | | expires_at | string (ISO-8601) | No | Auto-cancel cutoff if unresolved |

Fires proposal.created on the webhook stream.


List scheduling proposals for the current org. Filter by status or organizer agent, and page through results with limit and offset. Requires an org-level API key. Pro plan only.

| Parameter | Type | Required | Description | |---|---|---|---| | status | pending|confirmed|expired|cancelled | No | Filter proposals by lifecycle state | | organizer_agent_id | string | No | Filter to proposals created by one agent | | limit | integer | No | Page size, 1-200. Default 50 | | offset | integer | No | Page offset. Default 0 |


Fetch a scheduling proposal with its candidate slots and participant responses. Use this before respond_to_proposal to find a selected_slot_id. Requires an org-level API key. Pro plan only.

| Parameter | Type | Required | Description | |---|---|---|---| | proposal_id | string | Yes | Proposal to fetch |


Submit a response on behalf of one participant agent. An accept requires the slot id from the proposal; a counter can suggest alternative slots. When all participants have responded the proposal auto-resolves. Requires an org-level API key. Pro plan only.

| Parameter | Type | Required | Description | |---|---|---|---| | proposal_id | string | Yes | Proposal to respond to | | agent_id | string | Yes | Participant agent responding | | response | accept|decline|counter | Yes | Decision | | selected_slot_id | string | When accept | Slot the agent is accepting | | counter_slots | array | When counter | Alternative slots (up to 20) | | message | string | No | Optional note for the organizer |

Response includes auto_resolved: "confirmed", "cancelled", or null.


Force-resolve an open proposal using responses collected so far — picks the highest-scoring slot accepted by the most participants and creates a confirmed event. If every response was decline, the proposal is cancelled instead. Use when you want to close out a proposal without waiting for every participant. Requires an org-level API key. Pro plan only.

| Parameter | Type | Required | Description | |---|---|---|---| | proposal_id | string | Yes | Proposal to resolve |

Response is either { status: "confirmed", resolved_slot } or { status: "cancelled", reason: "all_declined" }.


Cancel an open proposal. Fires proposal.cancelled with reason: "organizer_cancelled". Requires an org-level API key. Pro plan only.

| Parameter | Type | Required | Description | |---|---|---|---| | proposal_id | string | Yes | Proposal to cancel |


Set (or replace) the availability rules on a calendar — buffer times before/after events and optional per-day working hours. Once set, every availability query on this calendar automatically applies them: busy blocks expand by the buffers, and slots outside working hours are masked. Upsert semantics — overwrites any existing rules.

| Parameter | Type | Required | Description | |---|---|---|---| | calendar_id | string | Yes | Calendar to configure | | buffer_before_minutes | integer (0–120) | No | Buffer before each event. Default 0. | | buffer_after_minutes | integer (0–120) | No | Buffer after each event. Default 0. | | working_hours | object | null | No | Per-day map { mon: { start: "09:00", end: "17:00" }, ... }. Pass null to disable the mask. | | timezone | string | No | IANA timezone used to interpret working_hours. Default UTC. |


Read the buffer times and working-hours rules configured on a calendar. Returns the rules row, or not_found if none are set.

| Parameter | Type | Required | Description | |---|---|---|---| | calendar_id | string | Yes | Calendar to read |


Remove the availability rules from a calendar, reverting to the default (no buffers, no working-hours mask). Returns the deleted row, or not_found if none were set.

| Parameter | Type | Required | Description | |---|---|---|---| | calendar_id | string | Yes | Calendar whose rules should be cleared |


| Tool | Purpose | Key parameters | |---|---|---| | create_agent | Register agent | name, type | | list_agents | List/filter agents | type, status, limit | | create_calendar | Create calendar | name, timezone, agent_id | | create_event | Schedule event | calendar_id, title, start_time, end_time | | list_events | List/filter events | calendar_id, start_after, start_before | | cancel_event | Cancel event | calendar_id, event_id | | confirm_event | Promote hold to confirmed | event_id | | release_event | Release a hold early | event_id | | get_availability | Single-agent free slots | agent_id, start, end, slot_duration | | find_meeting_time | Cross-agent free slots | agents, start, end, slot_duration | | subscribe_ical | Subscribe to external iCal | agent_id, calendar_id, url | | get_calendar_context | Current + upcoming context | calendar_id | | create_proposal | Open a multi-agent scheduling proposal | organizer_agent_id, participant_agent_ids, calendar_id, slots | | list_proposals | List scheduling proposals | status, organizer_agent_id, limit | | get_proposal | Fetch a scheduling proposal | proposal_id | | respond_to_proposal | Participant response | proposal_id, agent_id, response | | resolve_proposal | Force-resolve a pending proposal | proposal_id | | cancel_proposal | Cancel a pending proposal | proposal_id | | set_availability_rules | Configure buffers + working hours | calendar_id, buffer_before_minutes, buffer_after_minutes, working_hours | | get_availability_rules | Read configured rules | calendar_id | | clear_availability_rules | Remove rules | calendar_id |