Skip to content

power

get_power_state reads the device's current high-level power state (adb shell dumpsys power), deliberately minimal — wakefulness and, when reported, interactive state only. wake_device turns a sleeping screen back on by injecting the WAKEUP key (adb shell input keyevent WAKEUP); it's idempotent and does not dismiss keyguard. reboot_device requests a reboot into the normal system image (adb reboot); it's destructive (denied unless ADB_AUTOMATION_ALLOW_DESTRUCTIVE=1) and returns as soon as the request is accepted, so pair it with wait_for_device_state. Shutdown, sleep, and reboot-to-bootloader/recovery aren't implemented yet.

adb_automation_mcp.modules.power.tools

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

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

get_power_state(ctx: Context, serial: str) -> PowerState async

Get the device's current high-level power state: adb shell dumpsys power.

dumpsys power's full output is large and full of unstable implementation detail, so this deliberately extracts only two fields: wakefulness (the device's core sleep/wake state) and, when present, whether it's currently interactive. Nothing else from the dump is parsed or exposed. Power-related control (reboot, shutdown, sleep, wake) isn't implemented yet.

Parameters:

Name Type Description Default
serial str

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

required

Returns:

Type Description
PowerState

The serial, wakefulness (the raw value dumpsys reports, e.g. "Awake", "Asleep", "Dreaming", "Dozing"), and interactive (True/ False when dumpsys reports it, None when that specific field isn't present in this dump — see Error handling).

Error handling

An unknown serial or unresponsive adb binary raises DEVICE_NOT_FOUND/ADB_UNAVAILABLE. dumpsys running but producing output with no recognizable wakefulness field at all (e.g. the power service isn't registered, or the dump format is otherwise unrecognizable) raises POWER_STATE_UNAVAILABLE — distinct from interactive simply being absent, which is returned as data (interactive=None), not raised. A permission rejection raises PERMISSION_DENIED; any other failure raises a generic BACKEND_ERROR.

Example

Called with serial="emulator-5554". A typical response:

{
  "status": "success",
  "message": "Awake on emulator-5554.",
  "data": {
    "serial": "emulator-5554",
    "wakefulness": "Awake",
    "interactive": true
  },
  "error": null
}
Source code in src/adb_automation_mcp/modules/power/tools.py
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
@category("read")
async def get_power_state(ctx: Context, serial: str) -> PowerState:
    """Get the device's current high-level power state: `adb shell dumpsys power`.

    `dumpsys power`'s full output is large and full of unstable
    implementation detail, so this deliberately extracts only two fields:
    wakefulness (the device's core sleep/wake state) and, when present,
    whether it's currently interactive. Nothing else from the dump is
    parsed or exposed. Power-related control (reboot, shutdown, sleep,
    wake) isn't implemented yet.

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

    Returns:
        The serial, wakefulness (the raw value dumpsys reports, e.g.
        "Awake", "Asleep", "Dreaming", "Dozing"), and interactive (True/
        False when dumpsys reports it, None when that specific field isn't
        present in this dump — see Error handling).

    Error handling:
        An unknown serial or unresponsive adb binary raises
        DEVICE_NOT_FOUND/ADB_UNAVAILABLE. dumpsys running but producing
        output with no recognizable wakefulness field at all (e.g. the
        power service isn't registered, or the dump format is otherwise
        unrecognizable) raises POWER_STATE_UNAVAILABLE — distinct from
        interactive simply being absent, which is returned as data
        (interactive=None), not raised. A permission rejection raises
        PERMISSION_DENIED; any other failure raises a generic
        BACKEND_ERROR.

    Example:
        Called with serial="emulator-5554". A typical response:

        ```json
        {
          "status": "success",
          "message": "Awake on emulator-5554.",
          "data": {
            "serial": "emulator-5554",
            "wakefulness": "Awake",
            "interactive": true
          },
          "error": null
        }
        ```
    """
    services = cast("dict[str, object]", ctx.lifespan_context["services"])
    power = cast(PowerService, services["power"])
    return await power.get_power_state(serial)

reboot_device(ctx: Context, serial: str) -> RebootResult async

Reboot a device into its normal system image: adb -s serial reboot.

Categorized destructive (denied by default) because it interrupts everything running on the device and takes it offline for the length of a boot. adb returns the instant the request is delivered — well before the device is back — so a successful result means only that the request was accepted. The device will disappear from adb immediately; chain wait_for_device_state(serial, state="device") to block until it's back online before continuing automation. Rebooting into bootloader/recovery isn't implemented here.

Parameters:

Name Type Description Default
serial str

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

required

Returns:

Type Description
RebootResult

The serial, mode ("system"), accepted (always true when this returns without error — adb took the request), and adb's raw output (normally empty).

Error handling

An unknown serial raises DEVICE_NOT_FOUND; an unresponsive adb binary raises ADB_UNAVAILABLE. Any other non-zero exit raises BACKEND_ERROR. The device going offline right after this call is expected and is not reported as an error.

Example

Called with serial="emulator-5554". A typical response:

{
  "status": "success",
  "message": "Reboot request accepted for emulator-5554; it will drop off adb until it finishes booting.",
  "data": {
    "serial": "emulator-5554",
    "mode": "system",
    "accepted": true,
    "output": ""
  },
  "error": null
}
Source code in src/adb_automation_mcp/modules/power/tools.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
@category("destructive")
async def reboot_device(ctx: Context, serial: str) -> RebootResult:
    """Reboot a device into its normal system image: `adb -s serial reboot`.

    Categorized destructive (denied by default) because it interrupts
    everything running on the device and takes it offline for the length of
    a boot. adb returns the instant the request is delivered — well before
    the device is back — so a successful result means only that the request
    was accepted. The device will disappear from adb immediately; chain
    wait_for_device_state(serial, state="device") to block until it's back
    online before continuing automation. Rebooting into bootloader/recovery
    isn't implemented here.

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

    Returns:
        The serial, mode ("system"), accepted (always true when this
        returns without error — adb took the request), and adb's raw output
        (normally empty).

    Error handling:
        An unknown serial raises DEVICE_NOT_FOUND; an unresponsive adb
        binary raises ADB_UNAVAILABLE. Any other non-zero exit raises
        BACKEND_ERROR. The device going offline right after this call is
        expected and is not reported as an error.

    Example:
        Called with serial="emulator-5554". A typical response:

        ```json
        {
          "status": "success",
          "message": "Reboot request accepted for emulator-5554; it will drop off adb until it finishes booting.",
          "data": {
            "serial": "emulator-5554",
            "mode": "system",
            "accepted": true,
            "output": ""
          },
          "error": null
        }
        ```
    """
    services = cast("dict[str, object]", ctx.lifespan_context["services"])
    power = cast(PowerService, services["power"])
    return await power.reboot_device(serial)

wake_device(ctx: Context, serial: str) -> WakeResult async

Wake a sleeping device's screen: adb shell input keyevent WAKEUP.

Injects the WAKEUP power key so a device whose display has gone to sleep becomes interactive again — handy right before a screenshot or a sequence of UI taps. This does not unlock a locked keyguard; it only turns the screen back on. WAKEUP is idempotent: running it against an already-awake device is a harmless no-op, so this tool never fails just because the device was already awake. Putting the device back to sleep isn't implemented here.

Parameters:

Name Type Description Default
serial str

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

required

Returns:

Type Description
WakeResult

The serial, the keycode that was sent ("WAKEUP"), and accepted (always true when this returns without error — input produces no output, so success is read from its exit code). Chain get_power_state to confirm wakefulness afterwards if you need an independent check.

Error handling

An unknown serial raises DEVICE_NOT_FOUND; an unresponsive adb binary raises ADB_UNAVAILABLE. A rejection of the key injection raises PERMISSION_DENIED; any other non-zero exit raises BACKEND_ERROR.

Example

Called with serial="emulator-5554". A typical response:

{
  "status": "success",
  "message": "Sent WAKEUP to emulator-5554; the screen should be awake.",
  "data": {
    "serial": "emulator-5554",
    "keycode": "WAKEUP",
    "accepted": true
  },
  "error": null
}
Source code in src/adb_automation_mcp/modules/power/tools.py
 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
111
112
113
114
115
116
117
118
119
120
@category("write")
async def wake_device(ctx: Context, serial: str) -> WakeResult:
    """Wake a sleeping device's screen: `adb shell input keyevent WAKEUP`.

    Injects the WAKEUP power key so a device whose display has gone to
    sleep becomes interactive again — handy right before a screenshot or a
    sequence of UI taps. This does not unlock a locked keyguard; it only
    turns the screen back on. WAKEUP is idempotent: running it against an
    already-awake device is a harmless no-op, so this tool never fails just
    because the device was already awake. Putting the device back to sleep
    isn't implemented here.

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

    Returns:
        The serial, the keycode that was sent ("WAKEUP"), and accepted
        (always true when this returns without error — `input` produces no
        output, so success is read from its exit code). Chain
        get_power_state to confirm wakefulness afterwards if you need an
        independent check.

    Error handling:
        An unknown serial raises DEVICE_NOT_FOUND; an unresponsive adb
        binary raises ADB_UNAVAILABLE. A rejection of the key injection
        raises PERMISSION_DENIED; any other non-zero exit raises
        BACKEND_ERROR.

    Example:
        Called with serial="emulator-5554". A typical response:

        ```json
        {
          "status": "success",
          "message": "Sent WAKEUP to emulator-5554; the screen should be awake.",
          "data": {
            "serial": "emulator-5554",
            "keycode": "WAKEUP",
            "accepted": true
          },
          "error": null
        }
        ```
    """
    services = cast("dict[str, object]", ctx.lifespan_context["services"])
    power = cast(PowerService, services["power"])
    return await power.wake_device(serial)