{
  "tools": [
    {
      "name": "addMeetingParticipants",
      "description": "Add meeting participants. Use this when the user wants to invite people to an existing meeting; do not re-add the caller.\n\nAdds one or more participants to an existing meeting the caller's workspace\nowns; the `{id}` path parameter is the meeting id from v1CreateMeeting. The\nbody `participants` array is required. Adding a participant who is already on\nthe meeting is a no-op for that entry rather than an error. Supports an\noptional `Idempotency-Key` header: supply a client-generated printable-ASCII\nkey (max 255 chars) and the API replays the original `2xx` response for\nidentical repeats, returning `Idempotent-Replayed: true` on replays. Without\na key, blind retries could double-add newly-supplied people.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "Idempotency-Key": {
            "type": "string",
            "description": "Optional client-generated idempotency key (max 255 printable ASCII). Repeat requests with the same key replay the original 2xx response."
          },
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "guest_email": {
                  "type": "string",
                  "format": "email",
                  "example": "guest@example.com"
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "EDITOR",
                    "VIEWER"
                  ],
                  "example": "VIEWER"
                },
                "user_id": {
                  "type": "string",
                  "format": "uuid",
                  "example": "123e4567-e89b-12d3-a456-426614174003"
                }
              },
              "required": [
                "role"
              ]
            }
          }
        },
        "required": [
          "id",
          "participants"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "POST",
        "path": "/v1/meetings/{id}/participants"
      }
    },
    {
      "name": "createActionItem",
      "description": "Create action item. Use this when the user wants to add a follow-up task to a meeting.\n\nCreates an action item inside a meeting the caller can access; requires the\n`meetings:write` scope. Both `meeting_id` (from v1ListMeetings/v1CreateMeeting)\nand `title` are required — a missing or unknown meeting id returns 404, not a\nvalidation 400. `status` is optional and, when set, must be one of\n`needs_review`, `accepted`, `in_progress`, `blocked`, `completed`, `cancelled`;\nomit it to accept the server default. The 201 body returns the created item\nincluding its `id`, which you then pass to v1UpdateActionItem or\nv1DeleteActionItem. Supports an optional `Idempotency-Key` header: supply a\nclient-generated printable-ASCII key (max 255 chars) and the API replays the\noriginal `2xx` response for identical repeats, returning `Idempotent-Replayed:\ntrue` on replays. Without a key, blind retries can create duplicates.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "Idempotency-Key": {
            "type": "string",
            "description": "Optional client-generated idempotency key (max 255 printable ASCII). Repeat requests with the same key replay the original 2xx response."
          },
          "description": {
            "type": "string",
            "example": "Send proposal by Friday"
          },
          "due_date": {
            "type": "string",
            "example": "2026-01-15"
          },
          "meeting_id": {
            "type": "string",
            "example": "019abc12-def3-7000-8000-000000000002"
          },
          "status": {
            "type": "string",
            "enum": [
              "needs_review",
              "accepted",
              "in_progress",
              "blocked",
              "completed",
              "cancelled"
            ],
            "example": "needs_review"
          },
          "title": {
            "type": "string",
            "example": "Follow up with client"
          }
        },
        "required": [
          "meeting_id",
          "title"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "POST",
        "path": "/v1/action-items"
      }
    },
    {
      "name": "createAgendaItem",
      "description": "Create agenda item. Use this when the user wants to add an agenda item to a meeting.\n\nCreates an agenda item attached to a meeting in the caller's workspace;\nrequires the `meetings:write` scope. `meeting_id`, `title`, and `item_type`\nare all required — an unknown meeting id returns 404. A 409 means the target\nmeeting has already ended, so agenda items can no longer be added; this is a\nterminal state for that meeting rather than something to retry — do not loop on\nthe request. The 201 body returns the created item including its `id` for\nfollow-up updates. Supports an optional `Idempotency-Key` header: supply a\nclient-generated printable-ASCII key (max 255 chars) and the API replays the\noriginal `2xx` response for identical repeats, returning `Idempotent-Replayed:\ntrue` on replays. Without a key, blind retries can double-add an item.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "Idempotency-Key": {
            "type": "string",
            "description": "Optional client-generated idempotency key (max 255 printable ASCII). Repeat requests with the same key replay the original 2xx response."
          },
          "description": {
            "type": "string",
            "example": "Review the Q3 roadmap"
          },
          "item_type": {
            "type": "string",
            "example": "DISCUSSION"
          },
          "meeting_id": {
            "type": "string",
            "example": "019abc12-def3-7000-8000-000000000002"
          },
          "presenters": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "restricted_to_leads": {
            "type": "boolean",
            "example": false
          },
          "sequence": {
            "type": "string",
            "example": "a0"
          },
          "time_allocation_minutes": {
            "type": "number",
            "example": 15
          },
          "title": {
            "type": "string",
            "example": "Q3 roadmap review"
          }
        },
        "required": [
          "item_type",
          "meeting_id",
          "title"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "POST",
        "path": "/v1/agenda-items"
      }
    },
    {
      "name": "createMeeting",
      "description": "Create a meeting. Use this when the user wants to start a new meeting; the caller is added as owner automatically.\n\nCreates a meeting owned by the authenticated user; the caller is automatically\nadded as the owner participant, so do not re-add yourself via\nv1AddMeetingParticipants. Only `title` is required — `start_time`/`end_time`\nare ISO-8601 and optional (set `is_instant: true` for an ad-hoc meeting that\nstarts now). The 201 body returns the created meeting including its `id`; use\nthat id for follow-up calls (participants, agenda, context).\nSupports an optional `Idempotency-Key` header: supply a client-generated\nprintable-ASCII key (max 255 chars) and the API replays the original `2xx`\nresponse for identical repeats, returning `Idempotent-Replayed: true` on\nreplays. Without a key, retries can create duplicate meetings.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "Idempotency-Key": {
            "type": "string",
            "description": "Optional client-generated idempotency key (max 255 printable ASCII). Repeat requests with the same key replay the original 2xx response."
          },
          "detail_level": {
            "type": "string",
            "enum": [
              "BULLET_POINTS",
              "STANDARD",
              "VERBATIM"
            ],
            "example": "STANDARD"
          },
          "end_time": {
            "type": "string",
            "example": "2023-01-01T11:00:00Z"
          },
          "is_instant": {
            "type": "boolean",
            "example": false
          },
          "start_time": {
            "type": "string",
            "example": "2023-01-01T10:00:00Z"
          },
          "template_id": {
            "type": "string",
            "example": "123e4567-e89b-12d3-a456-426614174004"
          },
          "title": {
            "type": "string",
            "example": "Weekly Team Sync"
          }
        },
        "required": [
          "title"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "POST",
        "path": "/v1/meetings"
      }
    },
    {
      "name": "deleteActionItem",
      "description": "Delete action item. Use this when the user wants to remove a follow-up task.\n\nDeletes an action item the caller can access, keyed by the `{id}` from\nv1ListActionItems or v1CreateActionItem; requires the `meetings:write` scope.\nThis is a soft delete, so the item stops appearing in lists and reads but is\nnot physically purged. Returns 204 No Content on success — there is no body to\nparse. Deleting an unknown id or one outside the caller's workspace returns\n404. Because the operation is effectively idempotent (a second delete of the\nsame id simply 404s rather than corrupting state), retries after a network\nerror are safe.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Action Item ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "DELETE",
        "path": "/v1/action-items/{id}"
      }
    },
    {
      "name": "deleteAgendaItem",
      "description": "Delete agenda item. Use this when the user wants to remove an agenda item from a meeting.\n\nDeletes an agenda item in the caller's workspace, keyed by the `{id}` from\nv1ListAgendaItems; requires the `meetings:write` scope. Returns 204 No Content\non success with\nno body. Deleting an unknown id or one outside the caller's workspace returns\n404. The operation is effectively idempotent — a repeat delete of the same id\nsimply 404s — so retries after a network error are safe.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Agenda item ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "DELETE",
        "path": "/v1/agenda-items/{id}"
      }
    },
    {
      "name": "deleteMeeting",
      "description": "Delete a meeting. Use this when the user wants to remove a meeting they own.\n\nSoft-deletes a meeting owned by the authenticated user, keyed by the `{id}`\nfrom v1CreateMeeting/v1ListMeetings; requires the `meetings:write` scope. This\nis owner-scoped: only the meeting owner may delete it, so a caller who is\nmerely a participant gets 403, and an unknown id gets 404. Deleting a meeting\nremoves it (and stops it surfacing in lists/reads) but does not physically\npurge the underlying record. Returns 204 No Content on success. The operation is effectively\nidempotent (a repeat delete 404s), so retries after a network error are safe.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Meeting ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "DELETE",
        "path": "/v1/meetings/{id}"
      }
    },
    {
      "name": "deleteMeetingContext",
      "description": "Delete meeting context. Use this when the user wants to remove a document from a meeting.\n\nSoft-deletes a single meeting context document, keyed by the meeting `{id}` and\nthe `{context_id}` from v1ListMeetingContext; requires the `meetings:write`\nscope. The document stops surfacing in lists and reads but is not physically\npurged. Returns 204 No Content on success with no body. Deleting an unknown id,\nor one outside the caller's workspace, returns 404. The operation is\neffectively idempotent (a repeat delete 404s), so retries after a network error\nare safe.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "context_id": {
            "type": "string",
            "description": "Context ID"
          },
          "id": {
            "type": "string",
            "description": "Meeting ID"
          }
        },
        "required": [
          "context_id",
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "DELETE",
        "path": "/v1/meetings/{id}/context/{context_id}"
      }
    },
    {
      "name": "deleteUserToken",
      "description": "Delete user access token. Use this when the user wants to revoke a personal access token.\n\nPermanently deletes a user access token by its `{id}` (the token id from\nv1ListUserTokens, NOT the secret token value itself). This is destructive and\nirreversible: any integration or automation still authenticating with that token\nwill start receiving 401s immediately, so confirm the token is unused before\ndeleting. Deleting an already-deleted or unknown id returns 404. Returns 204 No\nContent on success — there is no body to parse.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Token ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "DELETE",
        "path": "/v1/user/tokens/{id}"
      }
    },
    {
      "name": "downloadMeetingContextContent",
      "description": "Download meeting context content. Use this when the user wants to fetch the file content of a meeting document.\n\nStreams the raw file content of a single meeting context document, keyed by the\nmeeting `{id}` and the `{context_id}` from v1ListMeetingContext; requires the\n`meetings:read` scope. The 200 response body is the file bytes themselves (a\nstreamed download), not a JSON envelope — read it as a byte stream and rely on\nthe response headers for content type, not on JSON parsing. Use\nv1GetMeetingContext first if you only need metadata. Returns 404 if either id\nis unknown or the document belongs to another workspace's meeting.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "context_id": {
            "type": "string",
            "description": "Context ID"
          },
          "id": {
            "type": "string",
            "description": "Meeting ID"
          }
        },
        "required": [
          "context_id",
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/{id}/context/{context_id}/content"
      }
    },
    {
      "name": "getActionItem",
      "description": "Get action item. Use this when the user wants details of a specific action item.\n\nFetches a single action item by the `{id}` returned from v1ListActionItems or\nv1CreateActionItem; requires the `meetings:read` scope. Access is user-scoped:\nthe item is only returned if the caller is its assignee or a participant in the\nparent meeting, so an id that exists but belongs to someone else's meeting\nreturns 404 rather than leaking its existence. Use this to read back a single\nitem's current `status`, `is_completed`, or `due_date` after an update instead\nof re-listing. Returns 404 if the id is unknown or not accessible to the caller.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Action Item ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/action-items/{id}"
      }
    },
    {
      "name": "getAgendaItem",
      "description": "Get agenda item. Use this when the user wants details of a specific agenda item.\n\nFetches a single agenda item by the `{id}` returned from v1ListAgendaItems or\nv1CreateAgendaItem; requires the `meetings:read` scope. The item is only\nreturned when it is attached to a meeting the caller's workspace owns —\nbacklog (meeting-less) items and items in other workspaces are cloaked as 404.\nUse this to read back an agenda item's current `status`, `title`, or\n`time_allocation_minutes` after an update instead of re-listing. Returns 404 if\nthe id is unknown or not accessible to the caller.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Agenda item ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/agenda-items/{id}"
      }
    },
    {
      "name": "getCalendarEvent",
      "description": "Get calendar event. Use this when the user wants details of a specific calendar event.\n\nFetches a single calendar event for the authenticated user, keyed by the `{id}`\nfrom v1ListCalendarEvents; requires the `meetings:read` scope. Use it to read\nthe full detail of an event you already discovered via the list call. Returns\n404 if the id is unknown or the event does not belong to the caller.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Calendar Event ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/calendar/events/{id}"
      }
    },
    {
      "name": "getMe",
      "description": "Get current user identity. Use this when the user wants to know who they are or their workspace context.\n\nReturns the authenticated user's public identity and the workspace context\ncarried by the current credential. Use this to resolve the caller's user id,\nemail, workspace id, workspace role, and plan before invoking operations that\nrequire those identifiers. The endpoint requires authentication but no\nresource scope, and repeated calls do not change state.",
      "inputSchema": {
        "type": "object"
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/me"
      }
    },
    {
      "name": "getMeeting",
      "description": "Get meeting by ID. Use this when the user wants full details of a specific meeting; summary notes require a paid plan.\n\nFetches a single meeting the caller's workspace owns, keyed by the `{id}`\nreturned from v1CreateMeeting. Use this to read back a meeting's current\n`status` after creating or updating it. Two fields are conditional: `summary_notes`\nis present whenever the meeting has an AI summary — PRO+ callers receive the\nfull text while FREE-tier callers receive a truncated preview (the first 200\ncharacters followed by an upgrade note); it is null only when no summary\nexists yet (not an error), and a non-empty `redirect_to_meeting_id` means this\nmeeting was merged into another — follow that id for the canonical record.\nReturns 404 if the id is unknown or belongs to another workspace.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Meeting ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/{id}"
      }
    },
    {
      "name": "getMeetingContext",
      "description": "Get meeting context. Use this when the user wants metadata for a specific meeting document.\n\nFetches the metadata (title, source format, type, timestamps) for a single\nmeeting context document, keyed by the meeting `{id}` and the `{context_id}`\nfrom v1ListMeetingContext; requires the `meetings:read` scope. This returns\nmetadata only — to retrieve the actual file bytes use\nv1DownloadMeetingContextContent. Returns 404 if either id is unknown or the\ndocument belongs to another workspace's meeting.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "context_id": {
            "type": "string",
            "description": "Context ID"
          },
          "id": {
            "type": "string",
            "description": "Meeting ID"
          }
        },
        "required": [
          "context_id",
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/{id}/context/{context_id}"
      }
    },
    {
      "name": "listActionItems",
      "description": "List action items. Use this when the user wants to view follow-up actions assigned to them.\n\nLists action items assigned to the authenticated user within their workspace;\nrequires the `meetings:read` scope. This is a per-user assignment view, not a\nworkspace-wide dump — items assigned to other members are not returned.\nUse `meeting_id` to restrict results to one meeting and `status` to restrict\nresults to a lifecycle state; the filters can be combined.\nPaginate with `limit` and `offset` query params (limit is clamped to 1–100);\nthe response envelope carries the filtered `total` so you can detect when to\nstop rather than fetching everything at once. Use this to discover action-item\nids before calling v1UpdateActionItem or v1DeleteActionItem.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Maximum items per page (1-100)"
          },
          "meeting_id": {
            "type": "string",
            "description": "Filter by meeting ID"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip"
          },
          "status": {
            "type": "string",
            "description": "Filter by status"
          }
        }
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/action-items"
      }
    },
    {
      "name": "listAgendaItems",
      "description": "List agenda items. Use this when the user wants to view the agenda items for a meeting.\n\nLists agenda items accessible to the authenticated user within their\nworkspace; requires the `meetings:read` scope. Use `meeting_id` to restrict\nresults to one meeting while preserving meeting participation and\nrestricted-to-leads access rules. Paginate with `limit` and `offset` query\nparams (limit is clamped to 1–100); the response envelope carries the\nfiltered `total` so you can page deterministically. Use this to read the\ncurrent ordering (`sequence`) before inserting a new item with\nv1CreateAgendaItem or reordering with v1UpdateAgendaItem, and to discover\nagenda-item ids for update/delete calls.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Maximum items per page (1-100)"
          },
          "meeting_id": {
            "type": "string",
            "description": "Filter by meeting ID"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip"
          }
        }
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/agenda-items"
      }
    },
    {
      "name": "listCalendarEvents",
      "description": "List calendar events. Use this when the user wants to view calendar events in a specified time range.\n\nLists the authenticated user's calendar events within a time window; requires\nthe `meetings:read` scope. Both `start_date` and `end_date` query params are\nrequired (ISO-8601) and bound the window — omitting either returns 400.\nPaginate with `limit` and `offset` (limit clamped to 1–100) and use\n`direction` to control ordering. Each event's `id` is what you pass to\nv1GetCalendarEvent. This reflects the user's connected calendar, so an empty\nresult usually means no events in range rather than an error.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "direction": {
            "type": "string",
            "description": "Sort direction: asc or desc (default: asc)"
          },
          "end_date": {
            "type": "string",
            "description": "End time in RFC3339 format"
          },
          "limit": {
            "type": "integer",
            "description": "Number of results per page (default 25, max 100)"
          },
          "offset": {
            "type": "integer",
            "description": "Pagination offset (default 0)"
          },
          "start_date": {
            "type": "string",
            "description": "Start time in RFC3339 format"
          }
        },
        "required": [
          "end_date",
          "start_date"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/calendar/events"
      }
    },
    {
      "name": "listMeetingContacts",
      "description": "Search workspace contacts for meeting invitations.\n\nSearches the workspace contacts associated with the meeting's workspace. Pass\nthe meeting `id` from v1CreateMeeting/v1GetMeeting as the path parameter and\nan optional `q` query for name/email substring matching. Results are intended\nas suggestions when the user wants to invite participants to a meeting; the\nreturned `email` can be supplied to v1AddMeetingParticipants as `guest_email`.\nDoes not expose whether a contact corresponds to a registered user account.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "limit": {
            "type": "integer",
            "description": "Maximum number of items per page (1-100, default 20)"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip (default 0)"
          },
          "q": {
            "type": "string",
            "description": "Search query matched against name or email"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": false
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/{id}/contacts"
      }
    },
    {
      "name": "listMeetingContext",
      "description": "List meeting contexts. Use this when the user wants to see documents attached to a meeting.\n\nLists the context documents attached to a meeting (`{id}`) with pagination;\nrequires the `meetings:read` scope. Returns every context document for the\nmeeting regardless of how it was added (user-uploaded or ingested from an\nintegration), so use it as the discovery call before reading metadata with\nv1GetMeetingContext or fetching bytes with v1DownloadMeetingContextContent.\nPaginate with `limit` and `offset` (limit clamped to 1–100) and read `total`\nfrom the envelope. Returns 404 if the meeting id is unknown or belongs to\nanother workspace. Each item's `id` is the `context_id` used by the per-context\nendpoints.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "limit": {
            "type": "integer",
            "description": "Maximum number of items to return (1-100)"
          },
          "offset": {
            "type": "integer",
            "description": "Offset for pagination"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/{id}/context"
      }
    },
    {
      "name": "listMeetingParticipants",
      "description": "List meeting participants. Use this when the user wants to see who is in a meeting.\n\nLists the participants of a specific meeting the caller can access, keyed by\nthe `{id}` from v1CreateMeeting/v1ListMeetings; requires the `meetings:read`\nscope. Returns paginated results — use `limit` and `offset` (limit clamped to\n1–100) and read `total` from the envelope to page deterministically. Each item\ncarries the participant's user id, which is the value you pass to\nv1RemoveMeetingParticipant. Returns 404 if the meeting id is unknown or belongs\nto another workspace. Call this before removing a participant to confirm the\nexact user id rather than guessing.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "limit": {
            "type": "integer",
            "description": "Maximum number of items per page (1-100, default 20)"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip (default 0)"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/{id}/participants"
      }
    },
    {
      "name": "listMeetingTemplates",
      "description": "List meeting templates. Use this when the user wants to see available templates; use the returned id when creating a meeting.\n\nLists the meeting templates the caller can use, spanning system, vertical,\nworkspace, and personal (user-owned) templates. This is the discovery call for\nthe `template_id` accepted by v1CreateMeeting — templates are otherwise not\naddressable via /v1, so call this first when you want to create a meeting from\na template but don't already have its id. Reads are ungated (no paid-tier\npaywall); the `meetings:read` scope is sufficient. Paginate with `limit`\n(1-100, default 20) and `offset`; the response envelope carries `total` so you\ncan tell when to stop. Each item exposes `id`, `name`, `description`,\n`ownership_type`, and `is_active` — pass `id` straight through as\nv1CreateMeeting's `template_id`.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Maximum items per page (1-100)"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip"
          }
        }
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meeting-templates"
      }
    },
    {
      "name": "listMeetings",
      "description": "List meetings. Use this when the user wants to browse or paginate their meetings; prefer searchMeetings when they mention keyword, date, participant, or status.\n\nLists meetings in the caller's workspace, newest first. Paginate with `limit`\nand `offset` query params rather than fetching everything at once; the response\nenvelope carries `total` so you can detect when to stop. Each item is a summary\nview — use v1GetMeeting for the full record of a specific meeting. List items\nnever carry `summary_notes`; that field is only returned by the single-meeting\nread (v1GetMeeting), and even there only on paid tiers. This is the natural\ndiscovery call before acting on a meeting whose id you don't already have.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Maximum items per page (1-100, default 20)"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip (default 0)"
          }
        }
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings"
      }
    },
    {
      "name": "listUpcomingMeetings",
      "description": "List upcoming meetings. Use this when the user wants to see their soonest future meetings.\n\nLists the caller's upcoming meetings, soonest first — i.e. scheduled meetings\nwhose start time is still in the future. This is the direct answer to \"what\nmeetings do I have coming up\"; use it instead of v1ListMeetings or\nv1SearchMeetings when the user asks about their upcoming schedule. Paginate\nwith `limit`/`offset`; the response envelope carries `total`. Each item is a\nsummary — call v1GetMeeting with an item's `id` for the full record. List\nitems never carry `summary_notes`; that field is only returned by the\nsingle-meeting read (v1GetMeeting), and even there only on paid tiers.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Maximum items per page (1-100, default 20)"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip (default 0)"
          }
        }
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/upcoming"
      }
    },
    {
      "name": "listUserTokens",
      "description": "List user access tokens. Use this when the user wants to view their non-revoked personal access tokens.\n\nLists the caller's own non-revoked personal access tokens; any authenticated\nuser may call it for their own tokens (no special scope or role required).\nEach entry exposes only a masked prefix plus scopes and timestamps — the full\nsecret token value is never returned, so this cannot recover a lost token.\nRevoked tokens are excluded. Paginate with `limit` and `offset` (limit clamped\nto 1–100). Each token's `id` is the value you pass to v1DeleteUserToken — it is\nNOT the secret token string.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Limit"
          },
          "offset": {
            "type": "integer",
            "description": "Offset"
          }
        }
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/user/tokens"
      }
    },
    {
      "name": "meetingTranscript",
      "description": "Get the transcript of a meeting. Use this when the user asks for the transcript, meeting transcript, SRT/captions, or recording transcript; requires Elite plan.\n\nUse this tool whenever the user asks for a meeting transcript, transcript export, SRT file, recording transcript, or to read the transcript from a meeting.\n\nDownloads a meeting transcript as an SRT file. This operation requires the\nELITE plan; lower tiers receive HTTP 402. The response is binary\n`application/x-subrip` content with a download filename in the\n`Content-Disposition` header, not a JSON envelope. The optional `format`\nquery parameter defaults to `srt`, which is currently the only supported\nformat.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "format": {
            "type": "string",
            "description": "Output format (default: srt)"
          },
          "id": {
            "type": "string",
            "description": "Meeting ID"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/{id}/transcript/export"
      }
    },
    {
      "name": "removeMeetingParticipant",
      "description": "Remove meeting participant. Use this when the user wants to remove someone from a meeting.\n\nRemoves a participant, identified by their user id (`{userId}`), from a meeting\nowned by the caller's workspace (`{id}`); requires the `meetings:write` scope.\nThe `{userId}` is the participant user id from v1ListMeetingParticipants, NOT a\nparticipant-row id.\nReturns 204 No Content on success. Removing someone who is not on the meeting,\nor an unknown meeting, returns 404. The operation is effectively idempotent (a\nrepeat removal 404s), so retries after a network error are safe.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "userId": {
            "type": "string",
            "description": "User ID"
          }
        },
        "required": [
          "id",
          "userId"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "DELETE",
        "path": "/v1/meetings/{id}/participants/{userId}"
      }
    },
    {
      "name": "revokeOAuthToken",
      "description": "Revoke OAuth token. Use this when the user wants to invalidate an access or refresh token.\n\nRevokes a first-party OAuth token (RFC 7009). Revoking a refresh token also\ninvalidates its entire rotation chain, so this is destructive: the client will\nneed to re-run v1ExchangeOAuthToken to obtain new credentials afterward. Per the\nspec it always returns 200 — even for an unknown or already-revoked token — so\ndo not treat 200 as proof the specific token existed. Pass `token_type_hint`\nwhen known to speed lookup. Treat the token you submit as a secret: never log it\nor echo it into tool arguments. Because the operation is idempotent (repeat\nrevocations are safe no-ops), retries are fine.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "Token to revoke"
          },
          "token_type_hint": {
            "type": "string",
            "description": "access_token or refresh_token"
          }
        },
        "required": [
          "token"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "POST",
        "path": "/v1/oauth/revoke"
      }
    },
    {
      "name": "searchMeetings",
      "description": "Search meetings by keyword/title/topic/date/participant/status. Use this when the user wants to find meetings matching specific filters.\n\nSearches meetings the caller participates in using a curated set of filters:\n`q` (case-insensitive substring over the meeting title and email alias — not\ntranscript or recap content), a start-time window (`start_time_from` /\n`start_time_to`, ISO 8601 with a required timezone), `status` (only\n`scheduled` or `completed`), `title_contains`, `participant_emails` (comma\nseparated), and `has_action_items`. All filters are optional and combine with\nAND. Visibility matches v1ListMeetings (meetings the caller participates in),\nso you never pass a workspace id. Paginate with `limit`/`offset`; the\nenvelope's `total` tells you when to stop. Prefer this over v1ListMeetings when\nyou already know something about the meeting (a keyword, a date, a participant)\nand want to narrow down rather than page through everything. Search results\nnever carry `summary_notes`; that field is only returned by the single-meeting\nread (v1GetMeeting), and even there only on paid tiers.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "has_action_items": {
            "type": "boolean",
            "description": "Restrict to meetings that do (true) or do not (false) have action items"
          },
          "limit": {
            "type": "integer",
            "description": "Maximum items per page (1-100, default 20)"
          },
          "offset": {
            "type": "integer",
            "description": "Number of items to skip (default 0)"
          },
          "participant_emails": {
            "type": "string",
            "description": "Comma-separated participant email addresses to filter by"
          },
          "q": {
            "type": "string",
            "description": "Free-text query matched (case-insensitive substring) against the meeting title and email alias"
          },
          "start_time_from": {
            "type": "string",
            "description": "Inclusive lower bound on start time (ISO 8601 with timezone)"
          },
          "start_time_to": {
            "type": "string",
            "description": "Inclusive upper bound on start time (ISO 8601 with timezone)"
          },
          "status": {
            "type": "string",
            "description": "Filter by meeting status"
          },
          "title_contains": {
            "type": "string",
            "description": "Case-insensitive substring match against the meeting title"
          }
        }
      },
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "GET",
        "path": "/v1/meetings/search"
      }
    },
    {
      "name": "updateActionItem",
      "description": "Update action item. Use this when the user wants to change a follow-up action's status or details.\n\nPartial update (PATCH) of an action item — send only the fields you want to\nchange; omitted fields are left untouched. `status` drives a state machine, so\nset it explicitly to move an item forward rather than inferring from\n`is_completed`. This endpoint does NOT honor `Idempotency-Key` (see the\n`missing_idempotency_key` flag): a blind retry after a network error can apply\nthe same change twice, so re-read with v1GetMeeting/list before retrying if you\nare unsure the first call landed. Returns 404 for an unknown id or one outside\nthe caller's workspace.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "example": "Updated description"
          },
          "due_date": {
            "type": "string",
            "example": "2026-01-15"
          },
          "id": {
            "type": "string",
            "description": "Action Item ID"
          },
          "is_completed": {
            "type": "boolean",
            "example": true
          },
          "status": {
            "type": "string",
            "enum": [
              "needs_review",
              "accepted",
              "in_progress",
              "blocked",
              "completed",
              "cancelled"
            ],
            "example": "accepted"
          },
          "title": {
            "type": "string",
            "example": "Follow up with client"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false
      },
      "x-contio-http": {
        "method": "PATCH",
        "path": "/v1/action-items/{id}"
      }
    },
    {
      "name": "updateAgendaItem",
      "description": "Update agenda item. Use this when the user wants to modify an agenda item in a meeting.\n\nPartial update (PATCH) of an agenda item in the caller's workspace — send only\nthe fields you want to change; omitted fields are left untouched. Requires the\n`meetings:write` scope and the `{id}` from v1ListAgendaItems. Returns 404 for\nan unknown id or one\noutside the caller's workspace. This endpoint does NOT honor `Idempotency-Key`\n(see the `missing_idempotency_key` flag): if you are unsure a call landed after\na network error, re-read with v1ListAgendaItems before retrying rather than\nreapplying blindly.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "example": "Review the roadmap"
          },
          "id": {
            "type": "string",
            "description": "Agenda item ID"
          },
          "item_type": {
            "type": "string",
            "example": "DISCUSSION"
          },
          "presenters": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "restricted_to_leads": {
            "type": "boolean",
            "example": false
          },
          "sequence": {
            "type": "string",
            "example": "a0"
          },
          "status": {
            "type": "string",
            "example": "ACTIVE"
          },
          "time_allocation_minutes": {
            "type": "number",
            "example": 15
          },
          "title": {
            "type": "string",
            "example": "Q3 roadmap review"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false
      },
      "x-contio-http": {
        "method": "PATCH",
        "path": "/v1/agenda-items/{id}"
      }
    },
    {
      "name": "updateMeeting",
      "description": "Update a meeting. Use this when the user wants to modify an existing meeting's fields.\n\nPartial update (PATCH) of a meeting the caller's workspace owns, keyed by the\n`{id}` from v1CreateMeeting — send only the fields you want to change; omitted\nfields are left untouched. Use this to rename (`title`) or reschedule\n(`start_time`/`end_time`, ISO-8601 with timezone) instead of delete-and-recreate.\nSetting `start_time` to null makes the meeting untimed; setting `end_time` to\nnull makes it open-ended. `end_time` must be after the effective start time, and\nyou cannot set `end_time` on a meeting that has no start time — including when the\nsame request clears `start_time` (null), which is rejected with 400. The body\nmust contain at least one updatable field; an empty object is rejected with 400.\nIt is idempotent-per-field: replaying the same body converges to the same state,\nso a retry after a network error is safe. The 200 body returns the full updated\nmeeting but omits `summary_notes`; fetch it separately with v1GetMeeting (where\nit is populated for PRO+ callers). Returns 404 for an unknown id or one\noutside the caller's workspace, 403 when the caller lacks edit access to the\nmeeting, and 402 when a referenced `template_id` requires a plan upgrade.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "detail_level": {
            "type": "string",
            "enum": [
              "BULLET_POINTS",
              "STANDARD",
              "VERBATIM"
            ],
            "example": "STANDARD"
          },
          "end_time": {
            "type": "string",
            "example": "2023-01-01T11:00:00Z"
          },
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "start_time": {
            "type": "string",
            "example": "2023-01-01T10:00:00Z"
          },
          "template_id": {
            "type": "string",
            "example": "123e4567-e89b-12d3-a456-426614174004"
          },
          "title": {
            "type": "string",
            "example": "Renamed Team Sync"
          }
        },
        "required": [
          "id"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "PATCH",
        "path": "/v1/meetings/{id}"
      }
    },
    {
      "name": "updateMeetingParticipantRole",
      "description": "Update meeting participant role. Use this when the user wants to change a participant's role in a meeting.\n\nChanges an existing participant's role to EDITOR or VIEWER on a meeting the\ncaller's workspace owns. Both the `{id}` (meeting id from v1CreateMeeting) and\n`{userId}` (the target participant's user id) path parameters are required, and\nthe participant must already be on the meeting — this endpoint only updates the\nrole, it does not add participants (use v1AddMeetingParticipants for that). The\nbody `role` is required and must be exactly `EDITOR` or `VIEWER`. The operation\nis idempotent in the sense that the final role is fully determined by the last\nsuccessful call, so retries converge on the requested role; note it always\nperforms the write (it does not short-circuit when the role is unchanged), so a\nredundant call still touches the participant record and may re-sync the doc.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "role": {
            "type": "string",
            "enum": [
              "EDITOR",
              "VIEWER"
            ],
            "example": "EDITOR"
          },
          "userId": {
            "type": "string",
            "description": "User ID"
          }
        },
        "required": [
          "id",
          "role",
          "userId"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true
      },
      "x-contio-http": {
        "method": "PATCH",
        "path": "/v1/meetings/{id}/participants/{userId}/role"
      }
    },
    {
      "name": "uploadMeetingContext",
      "description": "Upload meeting context. Use this when the user wants to attach a file or document to a meeting.\n\nUploads a context document to a meeting (`{id}`) as multipart form data;\nrequires the `meetings:write` scope. Required form fields are `file` and\n`source_format`; `title` and `context_type` are optional. `source_format`\nidentifies the file's format (e.g. `markdown`, `plain_text`, `json`) — an\nunsupported value returns 400. Content must be valid UTF-8 and the body is\ncapped at 4.5MB; exceeding the cap returns 413. There is also a per-meeting\ndocument cap, so very high-volume uploads can start failing with a 400 once the\nlimit is reached. The 201 body returns the created context including its `id`\nfor follow-up reads/downloads. This endpoint does NOT honor `Idempotency-Key`\n(see the `missing_idempotency_key` flag), so avoid blind retries that could\nupload the same document twice.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "context_type": {
            "type": "string",
            "description": "MIME type of the document"
          },
          "file": {
            "type": "string",
            "description": "Context document file",
            "format": "binary"
          },
          "id": {
            "type": "string",
            "description": "Meeting ID"
          },
          "source_format": {
            "type": "string",
            "description": "Source format (json, csv, tsv, xml, html, yaml, markdown, plain_text)"
          },
          "title": {
            "type": "string",
            "description": "Document title"
          }
        },
        "required": [
          "file",
          "id",
          "source_format"
        ]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false
      },
      "x-contio-http": {
        "method": "POST",
        "path": "/v1/meetings/{id}/context"
      }
    }
  ]
}
