get_step_logs
Access raw logs for a specific build step using build ID and step ID. Get step IDs from get_build_logs. Choose file delivery for managed temp file or inline for direct log text.
Instructions
Get the raw logs for a specific build step.
Use get_build_logs first to see all step IDs, then call this to drill into a specific step.
Args: build_id: The Codemagic build ID. step_id: The step ID (from get_build_logs output). delivery: Defaults to "file" to create/update a managed temp file and return artifact metadata. Use "inline" to return log text directly.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| build_id | Yes | ||
| step_id | Yes | ||
| delivery | No | file |
Implementation Reference
- codemagic_mcp/tools/builds.py:103-123 (handler)The MCP tool handler for 'get_step_logs'. Decorated with @mcp.tool(), it accepts build_id, step_id, and delivery (inline/file). Delegates to CodemagicClient.get_step_logs or get_step_logs_file.
@mcp.tool() async def get_step_logs( build_id: str, step_id: str, delivery: Literal["inline", "file"] = "file", ) -> Any: """Get the raw logs for a specific build step. Use get_build_logs first to see all step IDs, then call this to drill into a specific step. Args: build_id: The Codemagic build ID. step_id: The step ID (from get_build_logs output). delivery: Defaults to "file" to create/update a managed temp file and return artifact metadata. Use "inline" to return log text directly. """ async with CodemagicClient() as client: if delivery == "inline": return await client.get_step_logs(build_id, step_id) if delivery == "file": return await client.get_step_logs_file(build_id, step_id) raise ValueError('delivery must be either "inline" or "file"') - codemagic_mcp/client.py:252-255 (helper)Client method that makes the HTTP GET request to Codemagic API for step logs (inline delivery). Returns raw response text.
async def get_step_logs(self, build_id: str, step_id: str) -> str: response = await self._client.get(f"/builds/{build_id}/step/{step_id}") response.raise_for_status() return response.text - codemagic_mcp/client.py:383-390 (helper)Client method that fetches the log, writes it to a managed temp file, enforces storage limits, and returns artifact metadata (file delivery).
async def get_step_logs_file(self, build_id: str, step_id: str) -> dict[str, Any]: log_text = await self.get_step_logs(build_id, step_id) self.cleanup_step_log_artifacts() destination = self._build_log_file_path(build_id, step_id) self._write_step_log_file(destination, log_text) self._enforce_step_log_limits() return self._inspect_step_log_artifact(build_id, step_id) - codemagic_mcp/tools/__init__.py:1-13 (registration)Tool registration entry point. Calls builds.register(mcp) which registers get_step_logs as an MCP tool via the @mcp.tool() decorator.
from mcp.server.fastmcp import FastMCP from codemagic_mcp.tools import apps, artifacts, builds, caches, variables, webhooks def register_all_tools(mcp: FastMCP) -> None: apps.register(mcp) builds.register(mcp) artifacts.register(mcp) caches.register(mcp) variables.register(mcp) webhooks.register(mcp) - codemagic_mcp/server.py:32-43 (registration)Server initialization: creates FastMCP instance and calls register_all_tools(mcp) which registers all tools including get_step_logs.
mcp = FastMCP( name="Codemagic MCP", instructions=( "Codemagic CI/CD REST API: manage builds, apps, artifacts, caches, variables, and webhooks.\n\n" "Destructive ops (delete_app, cancel_build, delete_cache, delete_all_caches, delete_variable, delete_webhook): confirm before executing.\n\n" "App ID resolution: (1) use explicit app_id; (2) use CODEMAGIC_DEFAULT_APP_ID if set (exposed as `default_app_id`); " "(3) call list_apps — auto-select if one result, else ask user." ), lifespan=lifespan, ) register_all_tools(mcp)