Skip to main content

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"

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.

Metadata

Release files for semaphore-mcp 1.0.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for semaphore-mcp 1.0.6
File Size Uploaded Provenance Actions
semaphore_mcp-1.0.6.tar.gz 71.6 kB With provenance Details for semaphore_mcp-1.0.6.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for semaphore-mcp 1.0.6
File Interpreter ABI Platform Actions
semaphore_mcp-1.0.6-py3-none-any.whl Python 3 none any Details for semaphore_mcp-1.0.6-py3-none-any.whl

Total release size: 126.9 kB

Release files / semaphore_mcp-1.0.6.tar.gz

Download URL semaphore_mcp-1.0.6.tar.gz
Size 71.6 kB
Tags Source
SHA-256 checksum
How to use checksums
faffb4c4243a390118413b976a3ad974736d1e4fb36386abe6c6ac5afc10b451
BLAKE2b-256 checksum
How to use checksums
f5691a64371128cde8a8eef405b38e5f34fa7d6ac81ffcb48077559fbdb9cec7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / semaphore_mcp-1.0.6-py3-none-any.whl

Download URL semaphore_mcp-1.0.6-py3-none-any.whl
Size 55.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cb65a8ee6480ece5fbe1cc3f1ab92691f2f07647d769d17247f39bf95b5f58de
BLAKE2b-256 checksum
How to use checksums
c89371843f1394473668f3dc85db48403c09b56983aa0b23335e38ef48219597
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Security for semaphore-mcp 1.0.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for semaphore_mcp-1.0.6.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page