From Basic Tools to Workflow Customization

In the beginner phase you mastered three tools: list_devices, create_task, and get_task. But to truly integrate into your team's workflow, you need to level up to custom workflows + batch scheduling.

Step 1: Import Custom Workflow Templates

Workflows in iDeviceFarm are defined as JSON objects with this structure:

{
  "workflow_id": "my_custom_flow",
  "name": "My Custom Flow",
  "slots": [
    {"name": "platform", "type": "string", "required": true},
    {"name": "content", "type": "string", "required": true}
  ],
  "steps": [
    {"op": "launch_app", "app": "com.example.app"},
    {"op": "input", "selector": "#input-box", "value": "${content}"},
    {"op": "tap", "selector": "#submit-btn"}
  ]
}

Import via farm REST API POST /api/workflow/import with the JSON string. You can also draft and test interactively in the console, then export for reuse.

Step 2: Invoke Via run_workflow

MCP exposes a run_workflow(workflow_id, device_id, params) tool:

import httpx

def run_my_flow(device_id: str, platform: str, content: str):
    response = client.call_tool(
        "run_workflow",
        {
            "workflow_id": "my_custom_flow",
            "device_id": device_id,
            "params": {"platform": platform, "content": content}
        }
    )
    return response.task_id

Note: ${variable_name} references in the schema get replaced with your passed values at runtime. One template, many tasks.

Step 3: Batch Task Scheduling

Dispatching different tasks to multiple devices simultaneously is common. You can parallelize calls:

# Pseudocode: 5 devices running the same workflow simultaneously
devices = list_devices().result  # all online devices
for d in devices[:5]:
    run_workflow(
        workflow_id="batch_post",
        device_id=d.id,
        params={"platform": d.platform, "content": post_templates[d.index]}
    )

P1 phase will introduce a dedicated batch task scheduling endpoint to simplify this further.

Step 4: Webhook Callbacks & Result Push

Instead of polling get_task, register a webhook URL and the system pushes results when tasks complete:

# Create task with callback_url
task_id = client.create_task(
    workflow_id="my_custom_flow",
    device_id="dev_001",
    params={"content": "Hello World"},
    callback_url="https://your-server.com/webhook/mcp-result"
)

Webhook payload format:

{
  "task_id": "abc123",
  "status": "succeeded",  // or "failed"
  "started_at": "2026-09-01T14:30:00Z",
  "finished_at": "2026-09-01T14:30:45Z",
  "error_message": null,
  "logs": [{"step": 1, "op": "launch_app", "ok": true}]  // summary

Bottom line: MCP isn't a toy—it's enterprise-grade integration infrastructure. With custom workflows + webhook pushes, you embed phone operations seamlessly into CI/CD pipelines, operation dashboards, or your own platforms. Want to understand the architecture deeper? Read the architecture deep dive.