Cutover Mcp Public — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Cutover Mcp Public (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
An MCP server for interacting with the Cutover API, powered by FastMCP.
The server exposes 43 tools over MCP, grouped into 13 categories.
| Group | Description |
|---|---|
runbooks | Create, read, update, and control the lifecycle of runbooks and templates |
runbook_types | List, fetch, and query runbook types |
tasks | Read, add, update, and progress (start/complete/skip/delete) tasks within a runbook |
task_types | Look up task types |
streams | Create, read, update, and delete streams and substreams within a runbook |
workspaces | List, search, fetch, and create workspaces |
teams | Look up teams associated with a runbook |
users | Look up and search for users |
custom_fields | Discover custom fields and their metadata/valid options, and create, update and archive field definitions and groups |
folders | List folders within a workspace |
comments | Post and read comments on a runbook or task |
activities | Read a runbook's activity trail |
action_logs | Read the platform audit log |
#### Runbooks
<details>
<summary>list_runbooks - List all runbooks in a specific workspace</summary>
workspace_id: The unique identifier for the workspace (string, required)is_template: Filter by template status — false excludes templates, true shows only templates (boolean, optional)archived: Filter by archived status — false excludes archived runbooks, true shows only archived (boolean, optional)source_runbook_id: Filter to only runbooks created from this template ID (string, optional)folder_id: Filter to only runbooks in this folder ID (string, optional)extra_params: Additional query parameters to pass to the API, e.g. {"stage": "active"} (object, optional)</details>
<details>
<summary>get_runbook_by_id - Fetch details for a specific runbook by its ID</summary>
runbook_id: The unique identifier for the runbook (string, required)</details>
<details>
<summary>create_runbook - Create a new runbook in a workspace, or as a copy of an existing runbook/template</summary>
name: The name of the new runbook (string, required)workspace_id: The workspace to create the runbook in — required unless copy_source_runbook_id is passed (string, optional)description: Description for the runbook (string, optional)status: RAG status — off, red, amber, green (string, optional)is_template: Whether the runbook is a template (boolean, optional)template_type: off, default, or snippet (string, optional)rto: Recovery Time Objective in seconds (integer, optional)timezone: IANA timezone name (string, optional)runbook_type_id: Runbook type to associate (string, optional)rto_start_task / rto_end_task: Start/end task IDs for the RTO/RTA feature (string, optional)folder_id: Folder to place the runbook in — defaults to the workspace's default location (string, optional)custom_field_values: Custom field values to set, including runbook dashboard fields — see Custom Fields (array of object, optional)master_template: Whether this runbook can generate app-specific templates — requires is_template=true, and the API rejects it otherwise; on rejection, surface it rather than silently setting is_template=true (boolean, optional)start_scheduled: ISO 8601 timestamp, or the literal "now", to schedule the start (string, optional)end_scheduled: ISO 8601 timestamp for the scheduled end — must be omitted if start_scheduled isn't set (string, optional)auto_start: Whether to auto-start once start_scheduled is reached (runs live, comms on) (boolean, optional)copy_source_runbook_id: ID of an existing runbook/template to copy from (string, optional)copy_tasks / copy_teams / copy_users: What to include in the copy — each defaults to true; teams copied without members unless copy_users is also true (boolean, optional)shift_fixed_times: When copying, recalculate fixed task times relative to the new runbook's start (boolean, optional)</details>
<details>
<summary>update_runbook - Update a specific runbook's fields</summary>
runbook_id: The unique identifier for the runbook (string, required)name / description: New name/description (string, optional)status: RAG status — off, red, amber, green (string, optional)is_template: Whether the runbook is a template (boolean, optional)rto: Recovery Time Objective in seconds (integer, optional)timezone: IANA timezone name (string, optional)rto_start_task / rto_end_task: Start/end task IDs for the RTO/RTA feature (string, optional)custom_field_values: Custom field values to update, including runbook dashboard fields — see Custom Fields (array of object, optional)folder_id: Folder to move the runbook to (string, optional)master_template: Requires is_template=true; the API rejects it on a non-template runbook — surface the rejection instead of auto-flipping is_template (boolean, optional)start_scheduled / end_scheduled: ISO 8601 timestamps (or "now" for start) to (re)schedule the runbook (string, optional)auto_start: Whether to auto-start once start_scheduled is reached (boolean, optional)</details>
<details>
<summary>manage_runbook - Start, cancel, pause, or resume a runbook</summary>
runbook_id: The unique identifier for the runbook (string, required)action: start, cancel, pause, or resume — the only supported actions (string, required)comms: off, test, on — start only (string, optional, default "off")disable_task_notify: Disable task start notifications — start only (boolean, optional)run_type: live or rehearsal — start only (string, optional, default "rehearsal")rebaseline: Recalculate all planned times based on current time — start only (boolean, optional)shift_fixed_times: Shift fixed-time tasks relative to current time — start only (boolean, optional)validation_level: warning or error — start only (string, optional, default "error")message: Note attached to the action — cancel/pause/resume only (string, optional)notify: Notify users about the action — cancel/pause/resume only (boolean, optional)</details>
<details>
<summary>get_runbook_template_copies - Get all runbooks created from a specific runbook template</summary>
runbook_id: The template runbook ID to find copies of (string, required)</details>
#### Runbook Types
<details>
<summary>list_runbook_types - List all runbook types in the instance</summary>
_No parameters._
</details>
<details>
<summary>get_runbook_type_by_id - Fetch details for a specific runbook type by its ID</summary>
runbook_type_id: The unique identifier for the runbook type (string, required)</details>
<details>
<summary>query_runbook_types - Find runbook types matching text and/or capability flags</summary>
query: Case-insensitive text matched against the runbook type name, key, and description (string, optional)incident: Filter by whether the type is for incidents (boolean, optional)enable_rto: Filter by whether the type supports the RTO/RTA feature (boolean, optional)dynamic: Filter by whether the type is dynamic (boolean, optional)ai_create_enabled: Filter by whether AI-assisted creation is enabled for the type (boolean, optional)include_archived: Include archived runbook types; archived types are excluded by default (boolean, optional)include_disabled: Include disabled runbook types; disabled types are excluded by default (boolean, optional)</details>
#### Tasks
<details>
<summary>get_runbook_tasks - Fetch tasks for a specific runbook, with optional filtering and sorting</summary>
runbook_id: The unique identifier for the runbook (string, required)forecast: Return all tasks with computed timing (start_display/end_display) and dependency graph fields, overriding pagination/filters (boolean, optional)fields_task: Specific task fields to return, e.g. ["name", "stage"] (array of string, optional)stage: Filter by stage — default, startable, in_progress, complete (array of string, optional)stream_id: Filter to tasks in these stream IDs (array of string, optional)completion_type: complete_normal, complete_skipped, complete_abandoned, complete_auto (string, optional)task_type_id: Filter to tasks of these task type IDs (array of string, optional)level: Filter by task level (string, optional)search_term: Match against task name (string, optional)has_comments: Only return tasks that have comments (boolean, optional)runbook_team_id: Filter to tasks assigned to these runbook team IDs (array of string, optional)user_id: Filter to tasks assigned to these user IDs (array of string, optional)source_runbook_id: Filter to tasks originating from these source runbook IDs (array of string, optional)sort: Sort field, e.g. start_planned or -start_planned for descending (string, optional)</details>
<details>
<summary>add_task_to_runbook - Add a new task to an existing runbook</summary>
runbook_id: The runbook to add the task to (string, required)name: Task name (string, required)description: Task description (string, optional)task_type_id: Task type to associate (string, optional)stream_id: Stream (or substream) to assign the task to (string, optional)predecessors: Task IDs that are predecessors to this task (array of string, optional)duration: Planned duration in seconds (integer, optional)task_links: Links to other resources — link_type="runbook" links to a template runbook (target must be a template with ≥1 task and the task's task_type_id must be the tenant's linked type, or the link is silently dropped); link_type="snippet" attaches snippets (array of object, optional)message: Message body for an Email/SMS/Call task, or initial prompt for an agentic task (string, optional)recipients: Recipients for a comms task (array of object, optional)assignees: Assignees to add — only users/teams already participating on the runbook are honored, others are silently ignored (array of object, optional)custom_field_values: Custom field values to set — see Custom Fields (array of object, optional)start_fixed / end_fixed: ISO 8601 timestamps fixing start/end (string, optional)level: level_1, level_2, or level_3 (string, optional, default level_3)auto_start: Start automatically once predecessors complete (boolean, optional)auto_finish: Complete automatically once started (boolean, optional)</details>
<details>
<summary>update_runbook_task - Update an existing task (dependencies, description, stream, duration, etc.)</summary>
runbook_id / task_id: The runbook and task to update (string, required)name / description: New name/description (string, optional)predecessors: Task IDs that are predecessors to this task (array of string, optional)task_type_id: Task type to associate (string, optional)stream_id: Stream (or substream) to assign the task to (string, optional)duration: Planned duration in seconds (integer, optional)custom_field_values: Custom field values to update — see Custom Fields (array of object, optional)assignees: Assignees to add — only existing runbook participants are honored; additive by default (array of object, optional)delete_excluded_assignees: When true, replaces the full assignee list with only those provided instead of adding to it (boolean, optional, default false)task_links: Replaces the task's links entirely — pass an empty list to clear all links (array of object, optional)message: Message body for an Email/SMS/Call task, or initial prompt for an agentic task (string, optional)recipients: Recipients for a comms task (array of object, optional)start_fixed / end_fixed: ISO 8601 timestamps fixing start/end (string, optional)level: level_1, level_2, or level_3 (string, optional)auto_start / auto_finish: Auto-start on predecessor completion / auto-finish on start (boolean, optional)</details>
<details>
<summary>start_task - Start a specific task in a runbook</summary>
runbook_id / task_id: The runbook and task to start (string, required)</details>
<details>
<summary>complete_task - Complete a specific task in a runbook</summary>
runbook_id / task_id: The runbook and task to complete (string, required)</details>
<details>
<summary>skip_task - Skip a specific task in a runbook</summary>
runbook_id / task_id: The runbook and task to skip (string, required)comment: Reason for skipping — required by the API and posted as a runbook comment (string, required)</details>
<details>
<summary>delete_task - Delete a single task from a runbook</summary>
runbook_id / task_id: The runbook and task to delete (string, required)</details>
#### Task Types
<details>
<summary>list_task_types - List all task types</summary>
_No parameters._
</details>
#### Streams
<details>
<summary>list_streams - List all streams for a runbook, including substreams</summary>
runbook_id: The runbook to list streams for (string, required)forecast: Include computed forecast fields (start_display, end_display, etc.) (boolean, optional)</details>
<details>
<summary>get_stream - Get details of a specific stream or substream</summary>
runbook_id / stream_id: The runbook and stream to fetch (string, required)</details>
<details>
<summary>create_stream - Create a new stream or substream in a runbook</summary>
runbook_id: The runbook to create the stream in (string, required)name: Stream name (string, required)description: Stream description (string, optional)color: CSS-friendly color, e.g. #f0f0f0 or rgb(0,0,0) (string, optional)parent_stream_id: Parent stream ID, if creating a substream (string, optional)</details>
<details>
<summary>update_stream - Update an existing stream in a runbook</summary>
runbook_id / stream_id: The runbook and stream to update (string, required)name / description / color: New values (string, optional)</details>
<details>
<summary>delete_stream - Delete a stream from a runbook</summary>
runbook_id / stream_id: The runbook and stream to delete (string, required)</details>
#### Workspaces
<details>
<summary>list_workspaces - List all workspaces</summary>
limit: Maximum workspaces to return (integer, optional, default 50)offset: Number of workspaces to skip (integer, optional, default 0)</details>
<details>
<summary>query_workspaces - Search for workspaces by name or query string</summary>
query: Search string (string, required)</details>
<details>
<summary>get_workspace_by_id - Fetch details for a specific workspace by its ID</summary>
workspace_id: The unique identifier for the workspace (string, required)</details>
<details>
<summary>create_workspace - Create a new account/workspace</summary>
name: Workspace/account name (string, required)key: Shortened version of the name (string, required)description: Workspace/account description (string, optional)</details>
#### Teams
<details>
<summary>get_runbook_teams - Get all teams associated with a runbook</summary>
runbook_id: The runbook to fetch teams for (string, required)</details>
#### Users
<details>
<summary>get_user - Get user details by user ID</summary>
user_id: The user ID to fetch (string, required)</details>
<details>
<summary>search_users - Search for users by name or email (fuzzy match)</summary>
query: Search string — name or email, partial match (string, required)</details>
#### Custom Fields
The runbook and task tools accept custom_field_values as a list of {"custom_field_id": "123", "value": ...} entries, where the id comes from list_custom_fields. A field's internal name can be used in place of the id, but its display_name cannot. Each value is a string, or a list of strings for multi-select fields. Malformed entries are rejected before any request is sent to Cutover.
<details>
<summary>list_custom_fields - List all available custom fields, to discover fields that may not have values yet</summary>
workspace_id: Filter to a workspace — omit to return fields from all accessible workspaces (string, optional)include_global: When workspace_id is set, also include globally available fields alongside the workspace's own (boolean, optional, default true)scope: task, runbook, or all (string, optional, default "all") — runbook also covers dashboard fields on the runbook homepage, PIR and Incident Review</details>
<details>
<summary>get_custom_field - Get a custom field's metadata including its type, valid options, group and constraints</summary>
custom_field_id: The custom field to retrieve (string, required)</details>
The tools below change field definitions (the Custom Fields admin page), not the values on a runbook or task. They need the Custom Fields Admin or Global Admin role.
<details>
<summary>create_custom_field - Create a custom field definition</summary>
name: The field's name (string, required). The API sets the UI label to the same valuefield_type: text, textarea, select_menu, radiobox, checkboxes, datetime or user_select (string, required)apply_to: runbook_add_edit, runbook_edit, runbook_page, task_add_edit, task_edit, task_start or task_end (string, required)workspace_id: The workspace that owns the field (string, required unless global_field is true)global_field: Create the field for every workspace (boolean, optional, default false)field_options: Option names — required for select_menu, radiobox and checkboxes, rejected otherwise (array of string, optional)required, allow_field_creation, display_list, display_search, display_table: Field settings (boolean, optional)default_value: The value a new runbook or task starts with (string, optional)custom_field_group_id: The group to show the field in (string, optional)task_type_ids, runbook_type_ids: Limit the field to these task or runbook types (array of string, optional)</details>
<details>
<summary>update_custom_field - Update a custom field definition</summary>
custom_field_id: The field to update (string, required)name: The new name (string, optional)add_field_options: Option names to add to a select_menu, radiobox or checkboxes field; existing options are kept, and other field types are rejected (array of string, optional)required, allow_field_creation, display_list, display_search, display_table: Field settings (boolean, optional)default_value: The value a new runbook or task starts with (string, optional)custom_field_group_id: Move the field to this group, or "" to take it out of its group; omitted, the field stays in its current group (string, optional)task_type_ids, runbook_type_ids: Replace the constraints of that type; the other type is kept, and an empty list is rejected because the API cannot clear them (array of string, optional)</details>
<details>
<summary>archive_custom_field - Archive a custom field definition</summary>
custom_field_id: The field to archive (string, required)</details>
<details>
<summary>list_custom_field_groups - List custom field groups</summary>
Takes no parameters. Archived groups are not returned; the API does not list them.
</details>
<details>
<summary>create_custom_field_group - Create a custom field group</summary>
name: The group's name (string, required)</details>
<details>
<summary>update_custom_field_group - Rename a custom field group</summary>
custom_field_group_id: The group to rename (string, required)name: The new name (string, required)</details>
<details>
<summary>archive_custom_field_group - Archive a custom field group</summary>
custom_field_group_id: The group to archive (string, required)</details>
#### Folders
<details>
<summary>list_folders - List all folders in a specific workspace</summary>
workspace_id: The workspace to list folders for (string, required)</details>
#### Comments
<details>
<summary>add_comment - Post a comment on a runbook, optionally attached to a specific task</summary>
runbook_id: The runbook to comment on (string, required)content: Comment text — a limited set of HTML tags is supported (e.g. <p>, <b>, <ul>, <code>); markdown is not rendered and disallowed tags are stripped (string, required)task_id: Task to attach the comment to — omit to post at runbook level (string, optional)</details>
<details>
<summary>get_comments - List the comments on a runbook, optionally filtered to a specific task</summary>
runbook_id: The runbook to read comments from (string, required)task_id: Return only the comments attached to this task — omit for every comment on the runbook, including runbook-level ones (string, optional)</details>
#### Activities
<details>
<summary>get_activities - Get activities for an incident runbook, to track recent actions and events</summary>
runbook_id: The runbook to retrieve activities for (string, required)created_after / created_before: ISO 8601 date bounds (string, optional)</details>
#### Action Logs
<details>
<summary>get_action_logs - Retrieve action logs (audit logs), paginated</summary>
runbook_id / user_id / workspace_id: Filter by runbook, user, or workspace (string, optional)created_after / created_before: ISO 8601 date bounds (string, optional)max_pages: Maximum pages to fetch — response flags truncated: true if more remain (integer, optional, default 10)</details>
This includes both read and write tools — see Security & Responsible Use for how to scope access appropriately.
To set up the project, ensure you have the required dependencies installed. For macOS users, you can install uv using Homebrew:
brew install uvThis project requires Python 3.13+ — uv installs and manages the right interpreter automatically, so you don't need to install Python separately.
.env.example to .env and fill in your Cutover API credentials — see Environment Configuration below. uv sync uv run python src/cutover_mcp/server.py uv run pytestFor most instances, one URL and a token:
CUTOVER_CORE_URL=https://your-instance.cutover.com
CUTOVER_API_TOKEN=MY_TOKEN_VALUECUTOVER_CORE_URL is your Cutover instance URL, the one you open in the browser. The API host (CUTOVER_BASE_URL) defaults to https://api.cutover.net, which serves every shared production instance, so leave it unset unless your instance has its own API host (single-tenant deployments, typically https://api.your-instance.cutover.com). The default only applies to Cutover-hosted instance URLs; for any other instance URL the server asks you to set CUTOVER_BASE_URL rather than guess. If a call fails with an authorization error the message says how to override it; ask your Cutover contact if you are unsure which applies.
| Variable | Required | Notes |
|---|---|---|
CUTOVER_CORE_URL | Yes | Your Cutover instance URL, e.g. https://your-instance.cutover.com. Sent as the Core-Url header so the API routes to your instance. |
CUTOVER_API_TOKEN | Yes | See Generating an API Token below. |
CUTOVER_BASE_URL | No | The Cutover API host. Defaults to https://api.cutover.net. Set it only for an instance with its own API host, e.g. https://api.your-instance.cutover.com. |
There are two ways to generate a token:
The MCP server adds no security model of its own — it authenticates to the Cutover API as a single user app token over HTTPS and inherits exactly that user's permissions. Scope the token correctly and use the write tools deliberately:
create_runbook, manage_runbook, delete_task, start_task, …) and does not enforce read-only itself. For query-only use cases, omit roles that grant create/update/delete/manage — least privilege is configured in Cutover, not the client..env* is git-ignored and excluded from Docker images). If a token is compromised, revoke it immediately in Cutover's Access Management — the MCP server holds no independent session, so revoking the token fully cuts off access, and a scoped role confines any impact to that use case.src/cutover_mcp/ - Main packageclients/ - API clientresources/ - Resource definitions (MCP endpoints)tools/ - Tool logicserver.py - FastMCP server entrypointtests/ - TestsserverInfo.version and from GET /health when running over HTTP.If you want to use VS Code with GitHub Copilot to call out to this MCP server, you can use mcp.json.example.
mcp.json.example to .vscode/mcp.json (create the .vscode/ directory if not already present)Users/YOUR-USER-NAME/... example path to point at your working directory instead (the example uses a macOS-style path — adjust the format for Windows if needed)cutover-mcp to see its full list of tools. MCP tools only run in Agent mode — switch the mode dropdown from Ask to Agent if nothing happens.If you'd rather use Claude Desktop instead of an IDE, you can set that up:
claude_desktop_config.json.example to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS path shown; on Windows, use %APPDATA%\Claude\claude_desktop_config.json).command and args paths in that file to point at your repo's .venv/bin/python and src/cutover_mcp/server.py.cutover-mcp should be listed there along with its tools. If it isn't, check Settings → Developer for its connection status and logs.This will allow Claude Desktop to connect to your MCP server.
Docker is optional — the server runs fine without it (see Setup). Use this if you want a self-contained way to run it instead of managing a venv.
From the repository root, build the image:
docker build -t cutover-mcp ..env is excluded from the build via .dockerignore, so the image isn't tied to any environment or credential — never bake .env into an image you build, push, or share.
Pass your .env file in at run time instead, with --env-file:
docker run -i --rm --env-file .env cutover-mcpYou can configure your MCP server to use the Docker container instead of the venv. The root key differs by client: VS Code (mcp.json) uses servers; Claude Desktop (claude_desktop_config.json) uses mcpServers.
VS Code (.vscode/mcp.json):
{
"servers": {
"cutover-mcp": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--env-file",
"/path/to/your/repo/.env",
"cutover-mcp"
]
}
}
}Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"cutover-mcp": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--env-file",
"/path/to/your/repo/.env",
"cutover-mcp"
]
}
}
}To use Docker in the example configuration files (mcp.json.example and claude_desktop_config.json.example), replace the existing commands with the Docker-based commands shown in the "Docker Usage" section above.
Open up the .vscode/mcp.json file. Hover above the name of the server i.e. 'cutover-mcp'. You should have the option to start the server.
Ensure you aren't running the server independently in another terminal. Close and re-open VS Code, and if that doesn't work, restart your machine.
Alternatively, you can use the following approach to start the server:
View -> Command Palette -> MCP: List Servers -> your mcp server -> start/restart/stop server.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.