Skip to content

broadcasts

Sending Android intent broadcasts (adb shell am broadcast) to a connected device. Activity and service operations aren't in scope for this module.

adb_automation_mcp.modules.broadcasts.tools

Module-level, statically-introspectable tool functions for the broadcasts module.

Kept as plain top-level functions, never closures, so that documentation tooling and the registry meta-test can both introspect them directly.

send_broadcast(ctx: Context, serial: str, action: str, component: str | None = None, package: str | None = None, user_id: int | None = None, receiver_permission: str | None = None, extras: list[BroadcastExtra] | None = None) -> BroadcastResult async

Send an Android intent broadcast to a device: adb shell am broadcast.

Models the intent semantically (action/component/package/extras) rather than accepting a raw command string — see the module docs for why this server never exposes arbitrary shell arguments.

Parameters:

Name Type Description Default
serial str

The target device's adb serial (see list_connected_devices).

required
action str

The broadcast's Intent action, e.g. "android.intent.action.MY_ACTION" (-a).

required
component str | None

Restrict delivery to one explicit receiver, in "package/class" form, e.g. "com.example.app/.MyReceiver" (-n). A relative class name (starting with ".") is resolved against the package. Omit to let any registered receiver match.

None
package str | None

Restrict delivery to receivers declared by one package (-p). Can be combined with component, though component alone already implies a package.

None
user_id int | None

Send the broadcast as one specific Android user (--user, see list_users). Omit to use am's default user.

None
receiver_permission str | None

Require receivers to hold this permission to receive the broadcast, e.g. "com.example.MY_PERMISSION" (--receiver-permission). Omit to require no permission.

None
extras list[BroadcastExtra] | None

Simple scalar Intent extras to attach (--es/--ei/--el/ --ef/--ez). Array, URI, and component-name extras aren't supported.

None

Returns:

Type Description
BroadcastResult

The broadcast's completion info: the serial/action/component/ package/user_id/receiver_permission sent, the parsed result_code (and result_data/result_extras when a receiver set them), and the raw am output.

Error handling

Propagates the same way most tools do (unlike check_adb_available): if the adb binary itself can't be found or is unresponsive, or the serial doesn't match a connected device, that surfaces as an actual tool error. A malformed component string (not "package/class" shape) raises COMPONENT_NOT_FOUND; a protected action the caller isn't allowed to send raises PERMISSION_DENIED; any other ActivityManager failure raises a generic BACKEND_ERROR. A well-formed component or package that simply doesn't match any installed receiver is NOT an error — Android resolves receivers at delivery time, so that case completes normally with result_code=0.

Example

Called with serial="emulator-5554", action="android.intent.action.MY_ACTION". A typical response:

{
  "status": "success",
  "message": "Broadcast 'android.intent.action.MY_ACTION' completed on emulator-5554 (result=0).",
  "data": {
    "serial": "emulator-5554",
    "action": "android.intent.action.MY_ACTION",
    "component": null,
    "package": null,
    "user_id": null,
    "receiver_permission": null,
    "result_code": 0,
    "result_data": null,
    "result_extras": null,
    "output": "Broadcasting: Intent { act=android.intent.action.MY_ACTION }\nBroadcast completed: result=0\n"
  },
  "error": null
}
Source code in src/adb_automation_mcp/modules/broadcasts/tools.py
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
@category("write")
async def send_broadcast(
    ctx: Context,
    serial: str,
    action: str,
    component: str | None = None,
    package: str | None = None,
    user_id: int | None = None,
    receiver_permission: str | None = None,
    extras: list[BroadcastExtra] | None = None,
) -> BroadcastResult:
    """Send an Android intent broadcast to a device: `adb shell am broadcast`.

    Models the intent semantically (action/component/package/extras) rather
    than accepting a raw command string — see the module docs for why this
    server never exposes arbitrary shell arguments.

    Args:
        serial: The target device's adb serial (see list_connected_devices).
        action: The broadcast's Intent action, e.g.
            "android.intent.action.MY_ACTION" (`-a`).
        component: Restrict delivery to one explicit receiver, in
            "package/class" form, e.g. "com.example.app/.MyReceiver" (`-n`).
            A relative class name (starting with ".") is resolved against
            the package. Omit to let any registered receiver match.
        package: Restrict delivery to receivers declared by one package
            (`-p`). Can be combined with component, though component alone
            already implies a package.
        user_id: Send the broadcast as one specific Android user (`--user`,
            see list_users). Omit to use am's default user.
        receiver_permission: Require receivers to hold this permission to
            receive the broadcast, e.g. "com.example.MY_PERMISSION"
            (`--receiver-permission`). Omit to require no permission.
        extras: Simple scalar Intent extras to attach (`--es`/`--ei`/`--el`/
            `--ef`/`--ez`). Array, URI, and component-name extras aren't
            supported.

    Returns:
        The broadcast's completion info: the serial/action/component/
        package/user_id/receiver_permission sent, the parsed result_code
        (and result_data/result_extras when a receiver set them), and the
        raw am output.

    Error handling:
        Propagates the same way most tools do (unlike check_adb_available): if
        the adb binary itself can't be found or is unresponsive, or the
        serial doesn't match a connected device, that surfaces as an actual
        tool error. A malformed component string (not "package/class" shape)
        raises COMPONENT_NOT_FOUND; a protected action the caller isn't
        allowed to send raises PERMISSION_DENIED; any other ActivityManager
        failure raises a generic BACKEND_ERROR. A well-formed component or
        package that simply doesn't match any installed receiver is NOT an
        error — Android resolves receivers at delivery time, so that case
        completes normally with result_code=0.

    Example:
        Called with serial="emulator-5554",
        action="android.intent.action.MY_ACTION". A typical response:

        ```json
        {
          "status": "success",
          "message": "Broadcast 'android.intent.action.MY_ACTION' completed on emulator-5554 (result=0).",
          "data": {
            "serial": "emulator-5554",
            "action": "android.intent.action.MY_ACTION",
            "component": null,
            "package": null,
            "user_id": null,
            "receiver_permission": null,
            "result_code": 0,
            "result_data": null,
            "result_extras": null,
            "output": "Broadcasting: Intent { act=android.intent.action.MY_ACTION }\\nBroadcast completed: result=0\\n"
          },
          "error": null
        }
        ```
    """
    services = cast("dict[str, object]", ctx.lifespan_context["services"])
    broadcasts = cast(BroadcastsService, services["broadcasts"])
    return await broadcasts.send_broadcast(
        serial,
        action,
        component=component,
        package=package,
        user_id=user_id,
        receiver_permission=receiver_permission,
        extras=extras,
    )