Skip to content

Your own AI assistant (MCP)

Round Robin runs a remote Model Context Protocol (MCP) server. Connect an assistant that supports remote MCP servers, such as Claude, and it answers questions like “who is on duty for PAYMENTS right now?” from live data in your workspace. With your permission and your confirmation, it can also create rotations, change who is on them and set their schedules.

You need: an MCP client that supports remote servers and OAuth, and a Slack account in a workspace with Round Robin installed.

Property Value
URL https://api.roundrobinbot.eu/mcp
Transport Streamable HTTP
Authentication OAuth 2.1 (sign in with the same account you use for the dashboard)

The steps depend on your MCP client. The flow is standard OAuth:

  1. Add a remote MCP server in your client, with the URL https://api.roundrobinbot.eu/mcp.
  2. The client finds the authorization server on its own (RFC 9728 protected-resource metadata) and registers itself. Dynamic client registration is supported, so you need no client ID.
  3. Your browser opens a Round Robin sign-in page. Sign in with the same account you use for the dashboard.
  4. Approve the access. The client receives a token, and the tools appear.

In Claude Code, for example:

Terminal window
claude mcp add --transport http round-robin https://api.roundrobinbot.eu/mcp

Then run /mcp inside Claude Code to sign in.

The connection acts as you, in the Slack workspace you signed in from. A tool never takes a workspace as input, so a prompt cannot point the assistant at another workspace’s data.

The rotations it sees are the ones you can see in the dashboard:

Workspace Rotations the assistant sees
Free plan Every rotation.
Pro, as an admin or owner Every rotation, private ones included.
Pro, anybody else Every public rotation, plus each private rotation you are on (directly or through a user group) or own.

A rotation you cannot see answers exactly like one that does not exist.

Tool Input What it returns
who_is_on_call Rotation code (for example PAYMENTS) Who is on duty now, with when their cover stops, and who is up next, with when their turn ends. Also the rotation’s channels, its on-duty user group, whether it is enabled, and whether you are on it.
list_my_rotations None Every rotation you can see, sorted by name. Each has its name, code, enabled state, who is on duty now, its on-duty group, and youAreMember.
get_rotation_schedule Rotation code, entry count (default 10, at most 100) The upcoming duty, earliest first, up to six months ahead. Each entry has the person (ID and name), the turn, and when the stretch starts and ends.
get_rotation_coverage Rotation code The rotation’s coverage. Each window with its hours, its time zone, whether it is open now, how often it hands over, and its next hand-over. Each lane in each window, with its list, who holds it, when their cover stops and when their turn ends.
list_my_teams Count (default 50) The Slack workspaces you belong to.
get_user_info Slack user ID Display name, real name, handle, email (if visible), and whether it is a bot.
get_group_info Slack user group ID The group’s @handle, name, and description.
get_channel_info Slack channel ID The channel’s name and whether it is private.

Results carry readable names beside the Slack IDs, so the assistant rarely needs the lookup tools.

The read tools carry the standard MCP read-only and idempotent annotations. Assistants that honour them, such as Slack AI and Claude, run them without asking for confirmation.

The rotation tools take the rotation’s short code, the same code you use with slash commands in Slack. The whole code must match, in any case: payments finds PAYMENTS, and PAY finds nothing. list_my_rotations is the easiest way for an assistant to learn the codes.

What the assistant gets What it means
found: false, with the codes you can see listed in message No rotation you can see has that code. A blank code finds nothing either. Ask again with one of the listed codes.
found: true and empty entries from get_rotation_schedule The rotation has no duty in the next six months.
found: false from a lookup tool The Slack ID is unknown.

An empty onCallNow does not by itself mean nobody is covering. For a rotation linked to PagerDuty or Jira Service Management, read externalAssignments: it lists participants not mapped to a Slack user, empty slots, how fresh the data is, and the next change (nextChange). On those rotations upNext is empty.

get_rotation_coverage on a linked rotation lists only the lanes and windows where the provider has somebody assigned. Its windows have no name and no hours, because the provider sets the hours.

Every end time is UTC. A cover end is null while the holder is not covering: their window is shut, or they are waiting. When cover resumes is the window’s opensAtUtc in get_rotation_coverage.

Tool Field What it says
who_is_on_call onCallNow[].coveredUntilUtc When this person’s cover stops: the window closing, or the turn ending if that comes first. Null while nothing bounds it, or while the holder is not covering.
who_is_on_call upNext[].turnEndsUtc When this person’s turn ends: the next hand-over to somebody else. Null where nothing hands the turn over.
get_rotation_schedule entries[].untilUtc When this stretch ends: the window closing, or the turn ending if that comes first.
get_rotation_coverage cells[].coveredUntilUtc When the holder’s cover stops: the window closing, or the turn ending if that comes first. Null while the holder is not covering, or while nothing bounds it.
get_rotation_coverage cells[].turnEndsUtc When the holder’s turn ends: the next hand-over to somebody else. Later than coveredUntilUtc when the window closes first. Null where nothing hands the turn over.

On a linked rotation, read externalAssignments.nextChange for assignments starting, ending and continuing. The public API publishes the same pair as coveredUntil and turnEnds: see when duty ends.

These tools create and change rotations. Any connected client can use them once you grant the write:rotation scope (see Permissions). A client connected with read access alone does not see them. Before running one, the assistant summarises the change and asks you to confirm.

Tool Input What it does
create_rotation Name; optional code, description, members (in rotation order), channels, lanes Creates an enabled rotation with you as owner. It has no automatic schedule, so duty moves only when somebody rotates it. Add a schedule with set_window_cadence or in the dashboard.
update_rotation Rotation code; at least one of: new name, new code, description, members, channels, lanes, enabled Changes only the fields you give. members replaces the people on the rotation’s list, and works only on a rotation with one list.
update_list Rotation code, the list (its name or id); at least one of: members, new name Replaces the people on one list, renames it, or both. The rotation’s other lists stay as they are.
set_window_cadence Rotation code; schedule type (weekly, daysOfWeek, daily, workdays), time zone, first hand-over, period; optionally which window; options for the type Sets how often one coverage window hands over, which also puts the rotation on automatic. The time zone must be a city (Europe/Rome, America/New_York) or UTC. A fixed offset such as Etc/GMT+2 is refused. Custom calendars are set in the dashboard.

Lanes are how many people hold the duty at the same time: two lanes is a primary and a secondary. A coverage window is a stretch of hours with its own time zone and its own hand-over cadence. A rotation covering Europe and Asia has two, each turning over on its own clock.

On a rotation with one window, naming it is optional. On a rotation with several, a change that names no window is refused with the window names listed, so your assistant can ask which one you meant. set_window_cadence accepts whatever get_rotation_coverage prints for a window: the name somebody gave it, or its time zone.

Add a lane or a coverage window on the rotation’s Coverage tab. An assistant reads the grid and changes a cadence, but does not reshape it.

Delete a rotation in the dashboard. To advance duty, use Rotate now in Slack or the dashboard.

People are written per list. Each lane deals from one of the rotation’s lists, and most rotations have only one.

  • One list: the assistant can use update_rotation with members, or update_list.
  • Several lists: the assistant uses update_list and names the list. get_rotation_coverage prints the list each lane deals from in each window.

members takes every Slack user ID the list should name, and replaces the people it names now. People who stay keep their place in the turn order, and newcomers join after them. People on the list through a Slack user group stay on it. Change the groups a list draws on in the dashboard or through the API.

Leave members out and the list keeps its people. To empty a list, call update_list with an empty members. update_rotation refuses an empty members.

On the Free plan, anybody in the workspace can change any rotation. On Pro, the rotation’s owners can, and so can the workspace’s admins and owners. Plan limits are enforced, and rotation codes must be unique.

A refused change comes back with created set to false and the reason in message. The rotation is left as it was, with one exception at the end of this section.

message starts with What to do
Nothing to change Give at least one field to change.
An empty members list is not an update To empty the list, use update_list. To keep the people, leave members out.
Rotation '…' draws on … lists update_rotation cannot choose a list. Call update_list with one of the lists the message names.
No list '…' on rotation '…' Use one of the lists the message names.
'…' names more than one list Two lists share that name. Use one of the ids the message gives.
Somebody named could not be found The message lists the Slack user IDs that are not in the workspace. Remove or correct them.
This workspace's plan has no room for more people in its rotations Name fewer people, take somebody off another rotation, or upgrade the workspace.
An external rotation is read-only here The rotation follows PagerDuty or Jira Service Management. Change who is on it at the provider.
No rotation with code '…' Use one of the codes the message lists.

update_rotation with members and other fields writes the members first. If the other changes are then refused, the message starts with The members were updated, but the rotation's other changes were not applied: and gives the reason. Fix the cause and ask again for the other changes alone.

OAuth scopes decide which tools a client gets. You grant them on the consent screen when you connect:

Scope Grants Required by
read:oncall Reading rotations, schedules, who is on duty, and directory lookups All read tools
write:rotation Creating and updating rotations, their lists and their hand-over cadences The management tools

With read:oncall alone, the client’s tool list holds the read tools. Add write:rotation and it also lists the management tools. Either way the assistant can change only what you could change in the dashboard, and it asks you to confirm first.

The same server answers Slack AI, Slack’s built-in assistant, so people can ask “who is on duty for PAYMENTS?” inside Slack with no client setup. It is an optional permission per workspace: see Slack AI to turn it on.