stop_build
Stop a running Jenkins build by specifying server, job, and build number. Automatically checks build status and handles permission errors for reliable termination.
Instructions
Stop Jenkins build.
Intelligently handles permission errors and will automatically check build status to confirm if it has already been terminated.
Args:
server_name: Jenkins server name
job_full_name: Full job name
build_number: Build number
ctx: MCP context (for logging)
Returns:
Stop result
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| server_name | Yes | ||
| job_full_name | Yes | ||
| build_number | Yes |
Implementation Reference
- src/jenkins/tools/mcp_tools.py:191-233 (handler)MCP tool handler and registration for 'stop_build' via @mcp.tool() decorator. Creates JenkinsAPIClient and calls its stop_build method, with logging via ctx.@mcp.tool() def stop_build( server_name: str, job_full_name: str, build_number: int, ctx: Context = None ) -> StopResult: """Stop Jenkins build. Intelligently handles permission errors and will automatically check build status to confirm if it has already been terminated. Args: server_name: Jenkins server name job_full_name: Full job name build_number: Build number ctx: MCP context (for logging) Returns: Stop result """ client = JenkinsAPIClient(server_name) if ctx: ctx.log( "info", f"Stopping build #{build_number} for {job_full_name} on {server_name}", ) try: result = client.stop_build(job_full_name, build_number) if ctx: if result["status"] == "ALREADY_TERMINATED": ctx.log("info", "Build was already terminated") elif result["status"] == "STOP_REQUESTED": ctx.log("info", "Stop request sent successfully") elif result["status"] == "NOT_FOUND": ctx.log("warning", "Build not found") return result except Exception as e: if ctx: ctx.log("error", f"Failed to stop build: {e}") raise
- src/jenkins/tools/types.py:123-128 (schema)Output schema definition for StopResult, a TypedDict specifying the return type structure.class StopResult(TypedDict): """Stop build result.""" status: Literal["STOP_REQUESTED", "ALREADY_TERMINATED", "NOT_FOUND"] url: Optional[str]
- src/jenkins/tools/client.py:418-444 (helper)Core helper method in JenkinsAPIClient that performs the HTTP POST to the Jenkins stop endpoint, handles 404 and 403 responses.def stop_build(self, job_full_name: str, build_number: int) -> StopResult: """Stop build. Args: job_full_name: Full job name build_number: Build number Returns: Stop result Raises: JenkinsError: Stop failed """ job_url = self._build_job_url(job_full_name) stop_url = f"{job_url}/{build_number}/stop" response = self._make_request("POST", stop_url) if response.status_code == 404: return {"status": "NOT_FOUND", "url": None} if response.status_code == 403: # Permission error, check build status return self._handle_stop_permission_error(job_full_name, build_number) response.raise_for_status() return {"status": "STOP_REQUESTED", "url": stop_url}
- src/jenkins/tools/client.py:446-473 (helper)Helper method to handle 403 permission errors by polling the build status up to 10 times to check if already terminated.def _handle_stop_permission_error( self, job_full_name: str, build_number: int ) -> StopResult: """Handle permission error when stopping build. Args: job_full_name: Full job name build_number: Build number Returns: Stop result """ # Loop to check build status, confirm if already terminated for attempt in range(10): try: build_info = self.get_build_status(job_full_name, build_number) if not build_info.get("building", True): return {"status": "ALREADY_TERMINATED", "url": None} except (JenkinsBuildNotFoundError, JenkinsError): # Build not found or query failed, consider as terminated return {"status": "ALREADY_TERMINATED", "url": None} if attempt < 9: time.sleep(1) # Still building after 10 checks, raise permission error raise JenkinsPermissionError("stop build", f"{job_full_name}#{build_number}")