Skip to main content
Glama
SemaphoreUI MCP Server

SemaphoreUI MCP Server

by cloin

SemaphoreUI MCP Server

A Model Context Protocol (MCP) server that connects AI assistants to SemaphoreUI - enabling natural language control of Ansible automation.

demo

Quick Start

Prerequisites

  • Docker (or Podman)

  • A running SemaphoreUI instance with an API token

  • Claude Desktop or Claude Code (or another MCP client)

  • Node.js (for Claude Desktop only - required for mcp-remote)

1. Get a SemaphoreUI API Token

  1. Login to your SemaphoreUI instance

  2. Go to User Settings

  3. Generate a new API token

2. Run the MCP Server

docker run -d --name semaphore-mcp \
  --network host \
  -e SEMAPHORE_URL=http://localhost:3000 \
  -e SEMAPHORE_API_TOKEN=your-token-here \
  -e MCP_PORT=8500 \
  ghcr.io/cloin/semaphore-mcp:latest

Note: SEMAPHORE_URL is where the MCP server connects to SemaphoreUI. MCP_PORT is where the MCP server listens for client connections (Claude Desktop/Code). Use this port in your client configuration below.

3a. Configure Claude Desktop

Claude Desktop requires the mcp-remote proxy to connect to HTTP-based MCP servers. This requires Node.js to be installed (npx comes with npm).

Edit your config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/claude-desktop/claude_desktop_config.json

{
  "mcpServers": {
    "semaphore": {
      "command": "npx",
      "args": ["mcp-remote", "http://127.0.0.1:8500/mcp"]
    }
  }
}

3b. Configure Claude Code

Claude Code supports remote MCP servers directly:

claude mcp add --transport http semaphore http://127.0.0.1:8500/mcp

Verify it's configured:

claude mcp list

4. Test It

Restart Claude Desktop and try:

"List all projects in SemaphoreUI"

Related MCP server: semaphore-mcp-server

Docker Networking

The MCP server container needs to reach your SemaphoreUI instance.

SemaphoreUI on the same host:

Use --network host so the container can access localhost:

docker run -d --name semaphore-mcp \
  --network host \
  -e SEMAPHORE_URL=http://localhost:3000 \
  -e SEMAPHORE_API_TOKEN=your-token \
  -e MCP_PORT=8500 \
  ghcr.io/cloin/semaphore-mcp:latest

SemaphoreUI on a different host:

Use the IP or hostname directly (no --network host needed):

docker run -d --name semaphore-mcp \
  -e SEMAPHORE_URL=http://192.168.1.100:3000 \
  -e SEMAPHORE_API_TOKEN=your-token \
  -p 8500:8000 \
  ghcr.io/cloin/semaphore-mcp:latest

For more details, see Docker's networking documentation.

Configuration

Variable

Required

Default

Description

SEMAPHORE_URL

Yes

-

URL to your SemaphoreUI instance

SEMAPHORE_API_TOKEN

stdio: Yes, http: No

-

API token from SemaphoreUI. When set it is always used. With the http transport it can be omitted and supplied by each MCP client instead, see Per-client tokens

MCP_TRANSPORT

No

http

Transport mode: http or stdio

MCP_HOST

No

0.0.0.0

Host to bind to

MCP_PORT

No

8000

Port to listen on

Per-client tokens (token passthrough)

With the http transport and no SEMAPHORE_API_TOKEN, the MCP server forwards the Authorization: Bearer <token> header of each incoming MCP request to SemaphoreUI. Every client (a user, an agent, an automation) then acts with its own SemaphoreUI token and permissions, and the server needs no shared token of its own:

docker run -d --name semaphore-mcp \
  --network host \
  -e SEMAPHORE_URL=http://localhost:3000 \
  -e MCP_PORT=8500 \
  ghcr.io/cloin/semaphore-mcp:latest

Claude Code:

claude mcp add --transport http semaphore http://127.0.0.1:8500/mcp \
  --header "Authorization: Bearer your-token-here"

Claude Desktop (mcp-remote passes headers with --header; the value is read from an environment variable because Claude Desktop does not handle spaces in args well):

{
  "mcpServers": {
    "semaphore": {
      "command": "npx",
      "args": ["mcp-remote", "http://127.0.0.1:8500/mcp", "--header", "Authorization:${AUTH_HEADER}"],
      "env": {
        "AUTH_HEADER": "Bearer your-token-here"
      }
    }
  }
}

Rules:

  • If SEMAPHORE_API_TOKEN is set, it is always used and tokens sent by clients are ignored. The operator decides which mode the server runs in.

  • Without SEMAPHORE_API_TOKEN, each request uses the client's header; a request without one reaches SemaphoreUI unauthenticated and gets 401.

  • The stdio transport carries no HTTP headers, so it always needs SEMAPHORE_API_TOKEN.

  • The server does not validate forwarded tokens; it relays them. Expose it over TLS (a reverse proxy) or keep it on localhost, and treat it as trusted only as far as SemaphoreUI itself is.

What You Can Do

Once connected, you can interact with SemaphoreUI through natural conversation:

Run automation:

"Run the database backup playbook on production"

Monitor tasks:

"Show me all failed tasks from the last hour and analyze the errors"

Manage infrastructure:

"Create a new staging environment with APP_ENV=staging"

Troubleshoot:

"Get the output from task 42 and tell me why it failed"

Available Tools

Projects: list_projects, get_project, create_project, update_project, delete_project

Project backups: backup_project, restore_project_backup, validate_project_backup, summarize_project_backup, clone_project

Project users: get_project_role, list_project_users, add_project_user, update_project_user, remove_project_user

Views: list_views, get_view, create_view, update_view, delete_view

Templates: list_templates, get_template, create_template, update_template, delete_template

Schedules: list_schedules, list_template_schedules, get_schedule, create_schedule, update_schedule, set_schedule_active, delete_schedule, validate_schedule_cron_format

Tasks: list_tasks, get_task, run_task, stop_task, get_task_raw_output, filter_tasks, bulk_stop_tasks

Analysis: analyze_task_failure, bulk_analyze_failures, get_latest_failed_task

Events: list_events, get_last_events, list_project_events, summarize_project_activity

Environments: list_environments, get_environment, create_environment, update_environment, delete_environment

Inventory: list_inventory, get_inventory, create_inventory, update_inventory, delete_inventory

Repositories: list_repositories, get_repository, create_repository, update_repository, delete_repository

Access keys: list_access_keys, get_access_key, create_access_key, update_access_key, delete_access_key

Troubleshooting

Container won't start or exits immediately:

docker logs semaphore-mcp

Can't connect to SemaphoreUI from container:

  • If SemaphoreUI is on localhost, use --network host

  • Check that the URL is reachable from inside the container

  • Verify the API token is correct

Claude Desktop not seeing the MCP server:

  • Ensure the container is running: docker ps

  • Check the port is accessible: curl http://127.0.0.1:8500/mcp

  • Restart Claude Desktop after config changes

Enable debug logging:

docker run -d --name semaphore-mcp \
  --network host \
  -e SEMAPHORE_URL=http://localhost:3000 \
  -e SEMAPHORE_API_TOKEN=your-token \
  -e MCP_PORT=8500 \
  -e MCP_LOG_LEVEL=DEBUG \
  ghcr.io/cloin/semaphore-mcp:latest

Development

For local development and contributing, see DEVELOPMENT.md.

For testing documentation (unit tests, E2E tests, CI/CD), see TESTING.md.

Resources

License

This project is licensed under the GNU Affero General Public License v3.0 - see the LICENSE file for details.

Note: Versions prior to 1.0.0 were released under the MIT License.

Available Tools

69 tools
add_project_userA

Link a user to a project with a role.

Args: project_id: ID of the project user_id: ID of the user to link role: Project role: owner, manager, task_runner, or guest

Returns: Empty dict on success

Inputs: role (required), user_id (required), project_id (required). Returns: object

analyze_task_failureA

Analyze a failed task for LLM processing, gathering comprehensive failure context.

Args: project_id: ID of the project task_id: ID of the task to analyze

Returns: Comprehensive failure analysis data including task details, template context, and outputs

Inputs: task_id (required), project_id (required). Returns: object

backup_projectA

Export a Semaphore project backup.

Args: project_id: ID of the project to back up

Returns: Backup payload and a resource summary.

Inputs: project_id (required). Returns: object

bulk_analyze_failuresA

Analyze multiple failed tasks to identify patterns and common issues.

Args: project_id: ID of the project limit: Maximum number of failed tasks to analyze (default: 10)

Returns: Analysis of multiple failed tasks with pattern detection

Inputs: project_id (required), limit. Returns: object

bulk_stop_tasksA

Stop multiple tasks with confirmation.

Args: project_id: ID of the project task_ids: List of task IDs to stop confirm: Set to True to execute the bulk stop operation

Returns: Confirmation details or bulk stop results

Inputs: task_ids (required), project_id (required), confirm. Returns: object

clone_projectA

Clone a project by backing it up and restoring it with a new name.

Args: project_id: ID of the source project name: Name for the cloned project validate: Validate backup payload before restore

Returns: Source project ID, created clone, and backup summary.

Inputs: name (required), project_id (required), validate. Returns: object

create_access_keyA

Create a new access key.

Args: project_id: ID of the project name: Name for the access key key_type: Type of key - one of: - "none": For public repositories (no credentials needed) - "ssh": For SSH key authentication - "login_password": For username/password authentication login: Username (for ssh or login_password types) password: Password (for login_password type) private_key: Private key content (for ssh type)

Returns: Created access key details

Inputs: name (required), key_type (required), project_id (required), login, +2 more. Returns: object

create_environmentB

Create a new environment.

Args: project_id: ID of the project name: Environment name env_data: Environment variables as key-value pairs

Returns: Created environment details

Inputs: name (required), env_data (required), project_id (required). Returns: object

create_inventoryA

Create a new inventory item.

Args: project_id: ID of the project name: Inventory name inventory_data: Inventory content (for "static") or file path on the Semaphore server (for "file") inventory_type: Semaphore inventory type, such as "static", "static-yaml", or "file". Defaults to "static".

Returns: Created inventory item details

Inputs: name (required), project_id (required), inventory_data (required), inventory_type. Returns: object

create_projectA

Create a new project.

Args: name: Project name alert: Enable alerts (default: False) alert_chat: Chat channel for alerts (optional) max_parallel_tasks: Maximum parallel tasks, 0 = unlimited (default: 0) project_type: Project type (optional) demo: Create demo resources (default: False)

Returns: Created project details

Inputs: name (required), demo, alert, alert_chat, +2 more. Returns: object

create_repositoryC

Create a new repository.

Args: project_id: ID of the project name: Repository name git_url: Git repository URL git_branch: Git branch to use ssh_key_id: SSH key ID for authentication

Returns: Created repository details

Inputs: name (required), git_url (required), git_branch (required), project_id (required), +1 more. Returns: object

create_scheduleC

Create a new schedule.

Args: project_id: ID of the project template_id: ID of the template to run name: Schedule name cron_format: Cron expression for recurring schedules active: Whether the schedule is enabled schedule_type: Schedule type: "" for cron, or "run_at" for one-time runs run_at: RFC3339 timestamp for one-time schedules task_params: Optional task parameters to pass when the schedule runs delete_after_run: Delete the one-time schedule after it runs repository_id: Optional repository ID for commit-check schedules

Returns: Created schedule details

Inputs: name (required), project_id (required), template_id (required), active, +6 more. Returns: object

create_templateB

Create a new template.

Args: project_id: ID of the project name: Template name playbook: Playbook file path (e.g., "playbook.yml") inventory_id: Inventory ID repository_id: Repository ID environment_id: Environment ID description: Template description (optional) arguments: Extra arguments as JSON string (optional) allow_override_args_in_task: Allow overriding arguments in task (default: False) suppress_success_alerts: Suppress success alerts (default: False) app: Application type (default: "ansible") git_branch: Git branch to use (optional) survey_vars: Survey variables for prompting (optional) vaults: Vault configurations (optional) template_type: Template type - "", "build", or "deploy" (optional) start_version: Start version (optional) build_template_id: Build template ID for deploy templates (optional) autorun: Enable autorun (default: False) view_id: View ID (optional) task_params: App-specific task parameters (optional). For Ansible templates: - allow_override_limit: Allow task-level --limit override (required for run_task limit) - allow_override_inventory: Allow task-level inventory override - allow_override_tags: Allow task-level --tags override - allow_override_skip_tags: Allow task-level --skip-tags override - limit: Default limit (list of hosts/groups) - tags: Default tags (list) - skip_tags: Default skip tags (list) allow_parallel_tasks: Allow several tasks of this template to run at once (default: False) allow_override_branch_in_task: Allow overriding the git branch in task (default: False) runner_tag: Runner tag (optional)

Returns: Created template details

Inputs: name (required), playbook (required), project_id (required), inventory_id (required), +19 more. Returns: object

create_viewC

Create a new view.

Args: project_id: ID of the project title: View title position: View ordering position

Returns: Created view details

Inputs: title (required), project_id (required), position. Returns: object

delete_access_keyB

Delete an access key by ID.

Args: project_id: ID of the project key_id: ID of the access key to delete

Returns: Empty dict on success

Inputs: key_id (required), project_id (required). Returns: object

delete_environmentC

Delete an environment.

Args: project_id: ID of the project environment_id: ID of the environment to delete

Returns: Deletion result

Inputs: project_id (required), environment_id (required). Returns: object

delete_inventoryB

Delete an inventory item.

Args: project_id: ID of the project inventory_id: ID of the inventory item to delete

Returns: Deletion result

Inputs: project_id (required), inventory_id (required). Returns: object

delete_projectB

Delete a project.

Args: project_id: ID of the project to delete

Returns: Empty dict on success

Inputs: project_id (required). Returns: object

delete_repositoryC

Delete a repository.

Args: project_id: ID of the project repository_id: ID of the repository to delete

Returns: Deletion result

Inputs: project_id (required), repository_id (required). Returns: object

delete_scheduleC

Delete a schedule.

Args: project_id: ID of the project schedule_id: ID of the schedule to delete

Returns: Empty dict on success

Inputs: project_id (required), schedule_id (required). Returns: object

delete_templateC

Delete a template.

Args: project_id: ID of the project template_id: ID of the template to delete

Returns: Empty dict on success

Inputs: project_id (required), template_id (required). Returns: object

delete_viewB

Delete a view.

Args: project_id: ID of the project view_id: ID of the view to delete

Returns: Empty dict on success

Inputs: view_id (required), project_id (required). Returns: object

filter_tasksB

Filter tasks by multiple criteria with bulk operation support.

Args: project_id: ID of the project status: List of statuses to filter by (e.g., ['success', 'error']) limit: Maximum number of tasks to return use_last_tasks: Use efficient last 200 tasks endpoint

Returns: Filtered tasks with statistics

Inputs: project_id (required), limit, status, use_last_tasks. Returns: object

get_access_keyB

Get an access key by ID.

Args: project_id: ID of the project key_id: ID of the access key

Returns: Access key details

Inputs: key_id (required), project_id (required). Returns: object

get_environmentA

Get details of a specific environment.

Args: project_id: ID of the project environment_id: ID of the environment to fetch

Returns: Environment details

Inputs: project_id (required), environment_id (required). Returns: object

get_inventoryB

Get details of a specific inventory item.

Args: project_id: ID of the project inventory_id: ID of the inventory item to fetch

Returns: Inventory item details

Inputs: project_id (required), inventory_id (required). Returns: object

get_last_eventsA

List the last global events visible to the current user.

Semaphore returns the last 200 events. The optional limit trims that response further on the MCP side.

Args: limit: Return only the most recent N events; 0 returns all returned events

Returns: Dictionary containing the list of events

Inputs: limit. Returns: object

get_latest_failed_taskB

Get the most recent failed task for a project.

Args: project_id: ID of the project

Returns: The most recent failed task or a message if no failed tasks are found

Inputs: project_id (required). Returns: object

get_projectA

Get details of a specific project.

Args: project_id: ID of the project to fetch

Returns: Project details

Inputs: project_id (required). Returns: object

get_project_roleA

Get the current user's role and permissions for a project.

Args: project_id: ID of the project

Returns: Role and permissions for the current user

Inputs: project_id (required). Returns: object

get_repositoryB

Get details of a specific repository.

Args: project_id: ID of the project repository_id: ID of the repository to fetch

Returns: Repository details

Inputs: project_id (required), repository_id (required). Returns: object

get_scheduleA

Get details of a specific schedule.

Args: project_id: ID of the project schedule_id: ID of the schedule to fetch

Returns: Schedule details

Inputs: project_id (required), schedule_id (required). Returns: object

get_taskB

Get details of a specific task.

Args: project_id: ID of the project task_id: ID of the task to fetch

Returns: Task details

Inputs: task_id (required), project_id (required). Returns: object

get_task_raw_outputA

Get raw output from a completed task for LLM analysis.

Args: project_id: ID of the project task_id: ID of the task

Returns: Raw task output as plain text

Inputs: task_id (required), project_id (required). Returns: result

get_templateB

Get details of a specific template.

Args: project_id: ID of the project template_id: ID of the template to fetch

Returns: Template details

Inputs: project_id (required), template_id (required). Returns: object

get_viewB

Get details of a specific view.

Args: project_id: ID of the project view_id: ID of the view to fetch

Returns: View details

Inputs: view_id (required), project_id (required). Returns: object

get_waiting_tasksA

Get all tasks in waiting state for bulk operations.

Args: project_id: ID of the project

Returns: List of waiting tasks with bulk operation guidance

Inputs: project_id (required). Returns: object

list_access_keysA

List all access keys for a project.

Args: project_id: ID of the project key_type: Optional key type filter ("none", "ssh", or "login_password") sort: Sort field ("name" or "type") order: Sort order ("asc" or "desc")

Returns: Dictionary containing list of access keys

Inputs: project_id (required), sort, order, key_type. Returns: object

list_environmentsA

List all environments for a project.

Args: project_id: ID of the project

Returns: A list of environments for the project

Inputs: project_id (required). Returns: object

list_eventsA

List global events visible to the current user.

Args: limit: Return only the most recent N events; 0 returns all events

Returns: Dictionary containing the list of events

Inputs: limit. Returns: object

list_inventoryA

List all inventory items for a project.

Args: project_id: ID of the project

Returns: A list of inventory items for the project

Inputs: project_id (required). Returns: object

list_project_eventsA

List events related to a project.

Args: project_id: ID of the project limit: Return only the most recent N events; 0 returns all events

Returns: Dictionary containing the list of project events

Inputs: project_id (required), limit. Returns: object

list_projectsA

List all projects in SemaphoreUI.

Returns: A dictionary containing the list of projects.

Inputs: no named parameters. Returns: object

list_project_usersA

List users linked to a project.

Args: project_id: ID of the project sort: Field to sort by: name, username, email, or role order: Sort order: asc or desc

Returns: Dictionary containing the list of project users

Inputs: project_id (required), sort, order. Returns: object

list_repositoriesA

List all repositories for a project.

Args: project_id: ID of the project

Returns: A list of repositories for the project

Inputs: project_id (required). Returns: object

list_schedulesB

List all schedules for a project.

Args: project_id: ID of the project

Returns: Dictionary containing list of schedules

Inputs: project_id (required). Returns: object

list_tasksA

List tasks for a project with a default limit of 5 to avoid overloading context windows.

Args: project_id: ID of the project limit: Maximum number of tasks to return (default: 5) status: Optional status filter (e.g., 'success', 'error', 'running') tags: Optional list of tags to filter by

Returns: A list of tasks for the project, limited by the specified count

Inputs: project_id (required), tags, limit, status. Returns: object

list_templatesA

List all templates for a project.

Args: project_id: ID of the project

Returns: A list of templates for the project

Inputs: project_id (required). Returns: object

list_template_schedulesA

List schedules attached to a template.

Args: project_id: ID of the project template_id: ID of the template

Returns: Dictionary containing list of template schedules

Inputs: project_id (required), template_id (required). Returns: object

list_viewsB

List all views for a project.

Args: project_id: ID of the project

Returns: Dictionary containing the list of views

Inputs: project_id (required). Returns: object

remove_project_userB

Remove a user from a project.

Args: project_id: ID of the project user_id: ID of the user to remove

Returns: Empty dict on success

Inputs: user_id (required), project_id (required). Returns: object

restore_project_backupA

Restore a Semaphore project from a backup payload.

Args: backup: Backup payload returned by backup_project project_name: Optional name override for the restored project validate: Validate payload shape and references before restore

Returns: Created project and summary of the restored backup payload.

Inputs: backup (required), validate, project_name. Returns: object

run_taskA

Run a task from a template with optional 30-second monitoring.

Args: template_id: ID of the template to run project_id: Optional project ID (if not provided, will attempt to determine from template) environment: Optional environment variables for the task as dictionary limit: Restrict execution to specific hosts/groups (Ansible --limit) dry_run: Run without making changes (Ansible --check) diff: Show differences when changing files (Ansible --diff) debug: Enable verbose debug output playbook: Override playbook file path git_branch: Override git branch to use message: Task description/message arguments: Additional CLI arguments as a JSON string or string list inventory_id: Override inventory to use follow: Enable 30-second monitoring for startup verification (default: False)

Returns: Task execution result with immediate web URLs and optional monitoring summary

Template Override Requirements: Some parameters require the template to have overrides enabled in task_params. Use create_template() or update_template() with task_params to enable:

- limit: requires task_params={"allow_override_limit": true}
- inventory_id: requires task_params={"allow_override_inventory": true}

Without these settings, the parameter will be ignored silently.

Examples: # Just start the task and get URLs result = await run_task(template_id=5)

# Start task with 30-second monitoring and get URLs
result = await run_task(template_id=5, follow=True)

# Run with limit to specific hosts (template must allow override)
result = await run_task(template_id=5, limit="webservers")

# Dry run with diff to preview changes
result = await run_task(template_id=5, dry_run=True, diff=True)

Inputs: template_id (required), diff, debug, limit, +9 more. Returns: object

set_schedule_activeA

Enable or disable a schedule.

Args: project_id: ID of the project schedule_id: ID of the schedule to update active: Whether the schedule should be active

Returns: Empty dict on success

Inputs: active (required), project_id (required), schedule_id (required). Returns: object

stop_all_template_tasksC

Stop all running tasks for a template.

Args: project_id: ID of the project template_id: ID of the template

Returns: Empty dict on success

Inputs: project_id (required), template_id (required). Returns: object

stop_taskB

Stop a running task.

Args: project_id: ID of the project task_id: ID of the task to stop

Returns: Task stop result

Inputs: task_id (required), project_id (required). Returns: object

summarize_project_activityA

Summarize recent project activity from Semaphore events.

Args: project_id: ID of the project limit: Number of most recent events to analyze recent_limit: Number of recent event objects to include

Returns: Counts and recent event details for project activity

Inputs: project_id (required), limit, recent_limit. Returns: object

summarize_project_backupA

Summarize the resources contained in a project backup.

Args: backup: Backup payload to summarize

Returns: Counts, names, and secret-reference indicators for the backup.

Inputs: backup (required). Returns: object

update_access_keyB

Update an existing access key.

Args: project_id: ID of the project key_id: ID of the access key name: New access key name (optional) key_type: New key type (optional) login: Username for ssh or login_password keys (optional) password: Password for login_password keys (optional) private_key: Private key for ssh keys (optional) override_secret: Force updating stored secret material (optional)

Returns: Empty dict on success

Inputs: key_id (required), project_id (required), name, login, +4 more. Returns: object

update_environmentB

Update an existing environment.

Args: project_id: ID of the project environment_id: ID of the environment to update name: Environment name (optional) env_data: Environment variables as key-value pairs (optional)

Returns: Updated environment details

Inputs: project_id (required), environment_id (required), name, env_data. Returns: object

update_inventoryB

Update an existing inventory item.

Args: project_id: ID of the project inventory_id: ID of the inventory item to update name: Inventory name (optional) inventory_data: Inventory content for "static", or file path for "file" (optional) inventory_type: Semaphore inventory type, such as "static", "static-yaml", or "file". Defaults to "static"; pass the existing type if you don't intend to change it.

Returns: Updated inventory item details

Inputs: project_id (required), inventory_id (required), name, inventory_data, +1 more. Returns: object

update_projectB

Update an existing project.

Args: project_id: ID of the project to update name: Project name (optional) alert: Enable alerts (optional) alert_chat: Chat channel for alerts (optional) max_parallel_tasks: Maximum parallel tasks (optional) project_type: Project type (optional)

Returns: Empty dict on success

Inputs: project_id (required), name, alert, alert_chat, +2 more. Returns: object

update_project_userA

Update a linked user's project role.

Args: project_id: ID of the project user_id: ID of the linked user role: Project role: owner, manager, task_runner, or guest

Returns: Empty dict on success

Inputs: role (required), user_id (required), project_id (required). Returns: object

update_repositoryB

Update an existing repository.

Args: project_id: ID of the project repository_id: ID of the repository to update name: Repository name (optional) git_url: Git repository URL (optional) git_branch: Git branch to use (optional) ssh_key_id: SSH key ID for authentication (optional)

Returns: Updated repository details

Inputs: project_id (required), repository_id (required), name, git_url, +2 more. Returns: object

update_scheduleB

Update an existing schedule.

Args: project_id: ID of the project schedule_id: ID of the schedule to update template_id: ID of the template to run name: Schedule name cron_format: Cron expression for recurring schedules active: Whether the schedule is enabled schedule_type: Schedule type: "" for cron, or "run_at" for one-time runs run_at: RFC3339 timestamp for one-time schedules task_params: Optional task parameters to pass when the schedule runs delete_after_run: Delete the one-time schedule after it runs repository_id: Optional repository ID for commit-check schedules

Returns: Updated schedule details or empty dict on success

Inputs: project_id (required), schedule_id (required), name, active, +7 more. Returns: object

update_templateA

Update an existing template.

Args: project_id: ID of the project template_id: ID of the template to update name: Template name (optional) playbook: Playbook file path (optional) inventory_id: Inventory ID (optional) repository_id: Repository ID (optional) environment_id: Environment ID (optional) description: Template description (optional) arguments: Extra arguments (optional) allow_override_args_in_task: Allow overriding arguments (optional) suppress_success_alerts: Suppress success alerts (optional) app: Application type (optional) git_branch: Git branch (optional) survey_vars: Survey variables (optional) vaults: Vault configurations (optional) template_type: Template type (optional) start_version: Start version (optional) build_template_id: Build template ID (optional) autorun: Enable autorun (optional) view_id: View ID (optional) task_params: App-specific task parameters (optional). For Ansible templates: - allow_override_limit: Allow task-level --limit override (required for run_task limit) - allow_override_inventory: Allow task-level inventory override - allow_override_tags: Allow task-level --tags override - allow_override_skip_tags: Allow task-level --skip-tags override - limit: Default limit (list of hosts/groups) - tags: Default tags (list) - skip_tags: Default skip tags (list) allow_parallel_tasks: Allow parallel tasks (optional) allow_override_branch_in_task: Allow overriding the git branch in task (optional) runner_tag: Runner tag (optional)

Fields not passed keep their current value.

Returns: Empty dict on success

Inputs: project_id (required), template_id (required), app, name, +20 more. Returns: object

update_viewC

Update an existing view.

Args: project_id: ID of the project view_id: ID of the view to update title: View title position: View ordering position

Returns: Empty dict on success

Inputs: view_id (required), project_id (required), title, position. Returns: object

validate_project_backupA

Validate a project backup before attempting restore.

Args: backup: Backup payload to inspect

Returns: Validation result, errors, warnings, and a summary.

Inputs: backup (required). Returns: object

validate_schedule_cron_formatC

Validate a cron expression for Semaphore schedules.

Args: project_id: ID of the project cron_format: Cron expression to validate

Returns: Empty dict on success

Inputs: project_id (required), cron_format (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3/5.0

    Scored across 69 tools

    Disambiguation3/5

    Most tools are clearly separated by resource (template, inventory, repository, environment, schedule, view, access key, project user), but there is notable overlap in the events/activity area: list_events, get_last_events, list_project_events, and summarize_project_activity all deal with event retrieval/analysis. Similarly, list_tasks, filter_tasks, get_latest_failed_task, and get_waiting_tasks have overlapping task-listing purposes, though their filters differ.

    Naming Consistency4/5

    The vast majority of tools follow a consistent verb_noun pattern (list_templates, create_template, update_template, delete_template, get_template). Minor deviations exist: get_last_events is not a list_* verb, summarize_project_activity and bulk_analyze_failures use different verb styles, and stop_all_template_tasks is a compound noun phrase. Overall the pattern is strong and predictable.

    Tool Count2/5

    69 tools is a very large surface for an MCP server. While SemaphoreUI is a broad product, the tool count is excessive and will likely overwhelm an agent's context and tool-selection process. Many tools are highly specialized (validate_schedule_cron_format, summarize_project_backup, get_project_role) and could be consolidated or removed.

    Completeness4/5

    The server covers CRUD for the main Semaphore resources (projects, templates, inventories, repositories, environments, schedules, views, access keys, project users) plus task execution, monitoring, failure analysis, and backup/restore. Minor gaps exist: there is no create/update for schedules' task_params in a structured way (though update_schedule exists), and there is no explicit 'get_schedule' for listing all schedules without a template (list_schedules exists but no get_schedule by ID is present—wait, get_schedule does exist). Actually, the surface is quite complete; the only notable gap is the lack of a direct 'get_all_schedules' vs 'list_schedules' distinction, and no tool for managing project-level API tokens or user management beyond project linking. Overall, the domain is well covered.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables comprehensive Ansible automation management through natural language, including playbook creation and execution, inventory management, role scaffolding, and project workflows. Supports both local inventories and full project lifecycle management with syntax validation and idempotency testing.
      30
      -
    • A
      license
      C
      quality
      C
      maintenance
      Enables AI assistants to interact with Semaphore UI for managing Ansible, Terraform, and other automation workflows through project, task, template, and inventory management.
      37
      1
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      Enables AI assistants to manage Rundeck operations including jobs, executions, projects, nodes, system management, key storage, webhooks, and ACL policies via natural language.
      50
      50 npm
      1
      Apache 2.0