Package-level declarations

Types

Link copied to clipboard

screencap -p [-d <display>] — captures the screen as a PNG and writes it to stdout. With a privileged shell backend this works without MediaProjection consent (no yellow status-bar indicator, no prompt). Distinct from screenshot.capture_screen (MediaProjection) and accessibility.take_screenshot_via_a11y (Accessibility-API consent).

Link copied to clipboard

pm clear <pkg> — wipe an app's data and cache directories (equivalent to Settings > Apps > Storage > Clear data). Success is detected by "Success" in stdout.

Link copied to clipboard

pm disable-user --user 0 <pkg> — disable a system or user app for the primary user without uninstalling it (hides it from the launcher, stops background activity). Reversible via EnableAppTool. Idempotent. Success is detected by "disabled-user" in stdout.

Link copied to clipboard

pm enable <pkg> — re-enable a previously disabled app (the inverse of DisableAppTool). Idempotent. Success is detected by "enabled" in stdout.

Link copied to clipboard

am force-stop <pkg> — terminate all of an app's processes (equivalent to Settings > Apps > Force stop). The command is silent on success, so this tool trusts the exit code rather than scanning stdout.

Link copied to clipboard

Foreground activity/window from dumpsys window mCurrentFocus and dumpsys window mFocusedApp. This is the standard way to get the foreground package on devices where Accessibility isn't enabled — it's what the LLM-agent should call when it just needs "what app is on top right now" without driving the UI. Read-only; takes no parameters.

Link copied to clipboard
class GrantPermissionTool(shell: ShellBackend, policy: ShellPolicy = ShellPolicy.RECOMMENDED) : McpTool

pm grant <pkg> <perm> — grant a runtime permission to an app without the user prompt. Idempotent. The permission must be one the app declared in its manifest. Treated as failure if the command exits non-zero or writes to stderr (not declared / not a runtime permission / etc.). Note pm grant also grants development-protection permissions such as WRITE_SECURE_SETTINGS; permissions in ShellPolicy.deniedPermissions are refused with denied_by_policy.

Link copied to clipboard

pm install [-r] <path> — silently install an APK from a local file path, with no user prompt. The path must be absolute, end in .apk, and contain no .. segments (so it can't be mistaken for a pm option); beyond that the host is trusted to vet it — there is no storage sandbox here (the ShellBackend is the privilege boundary), and ANY readable APK can be installed, including ones that request dangerous permissions. Success is detected by "Success" in stdout.

Link copied to clipboard

dumpsys package <pkg> parsed for the app's permissions. Read-only. Scans the requested permissions:, install permissions:, and runtime permissions: sections of the dumpsys output (see parseDumpsysPermissions) and merges them by name; it does NOT classify by protection level.

Link copied to clipboard

am set-inactive <pkg> true — flag an app as idle so the system applies aggressive Doze restrictions immediately rather than waiting for natural idle accumulation (useful for testing Doze behaviour). Idempotent. Treated as a command failure on non-zero exit or non-empty stderr.

Link copied to clipboard

ShellBackend that's always unavailable. Useful as a fallback in the "use root if available, Shizuku otherwise" dispatch pattern documented in docs/SHELL.md — when neither backend is reachable on the current device, every tool errors with shell_unavailable: NoOp so the LLM sees a structured failure instead of unexpected behaviour.

Link copied to clipboard
class PutGlobalSettingTool(shell: ShellBackend, policy: ShellPolicy = ShellPolicy.RECOMMENDED) : McpTool

settings put global <key> <value> — write a Settings.Global value (e.g. airplane_mode_on, wifi_on). Idempotent. Delegates to putSetting; treated as failure on non-zero exit or non-empty stderr.

Link copied to clipboard
class PutSecureSettingTool(shell: ShellBackend, policy: ShellPolicy = ShellPolicy.RECOMMENDED) : McpTool

settings put secure <key> <value> — write a Settings.Secure value, which most apps cannot do without privileged shell access. Idempotent. Delegates to putSetting; treated as failure on non-zero exit or non-empty stderr.

Link copied to clipboard
class PutSystemSettingTool(shell: ShellBackend, policy: ShellPolicy = ShellPolicy.RECOMMENDED) : McpTool

settings put system <key> <value> — write a Settings.System value (e.g. screen_brightness, screen_off_timeout). Idempotent. Delegates to putSetting; treated as failure on non-zero exit or non-empty stderr.

Link copied to clipboard

pm revoke <pkg> <perm> — revoke a runtime permission from an app. Idempotent. Treated as failure if the command exits non-zero or writes to stderr.

Link copied to clipboard

Escape hatch — run an arbitrary shell command via the backend.

Link copied to clipboard

am set-standby-bucket <pkg> <bucket> — set the app's standby bucket, which controls how aggressively the system throttles its background work. Idempotent. The bucket value is lowercased and validated against VALID_BUCKETS (active / working_set / frequent / rare / restricted) before issuing the command; an unknown bucket fails with invalid_args. Treated as a command failure on non-zero exit or non-empty stderr.

Link copied to clipboard

Process-global allowlist for run_shell. The host sets a set of command prefixes (e.g. "pm list packages", "dumpsys battery", "settings get global") at startup; the tool refuses any command whose argv doesn't start with one of them.

Link copied to clipboard
interface ShellBackend

Abstraction over a privileged shell-command pipeline.

Link copied to clipboard
sealed class ShellException : Exception

Infrastructure failure — the backend itself couldn't run a process. Distinct from a non-zero exit code returned by the spawned process.

Link copied to clipboard
data class ShellPolicy(val deniedSettingKeys: Set<String> = emptySet(), val deniedPermissions: Set<String> = emptySet())

Optional host-side denylist for the dedicated shell tools. Passed to ShellTools.all (and the ShizukuTools / RootTools providers); the LLM cannot change it.

Link copied to clipboard
data class ShellResult(val exitCode: Int, val stdoutBytes: ByteArray, val stderr: String, val outputTruncated: Boolean = false)

Result of a shell invocation. exitCode == 0 is the success convention; tools test it explicitly because some commands return non-zero on success (e.g. pm grant for an unknown permission).

Link copied to clipboard
object ShellTools

Factory for the shell-based tool set. Backend modules (:droid-mcp-shizuku, :droid-mcp-root) call all with their concrete ShellBackend and expose the resulting list under a module-specific provider (ShizukuTools, RootTools).

Link copied to clipboard

pm uninstall [-k] <pkg> — silently uninstall an app by package name, no user prompt. Success is detected by "Success" in stdout.