Skip to main content
Glama
MarwanDevSpace

mcp-flutter-apk-injector

Inject Flutter runtime into APK workspace

inject_flutter_runtime_and_smali
Destructive

Inject Flutter runtime and Smali payloads into a decompiled APK workspace to embed Flutter code. Select an injection mode to match the target app's structure, enabling native Flutter execution within the host application.

Instructions

Inject a synthesized Flutter payload (lib/ and assets/) and generated Smali bootstrap classes into a decoded APK workspace. Mutates workspaceDir in-place by writing Smali classes, copying native libraries per ABI, and deploying Flutter assets; requires payloadDir containing valid Flutter binaries. Select injectionMode based on target structure: prefer activity_overlay for cached-engine screens, direct_application_hook for custom Application classes, headless_engine for background tasks, or view_tree_injection (experimental); enable nativeLibraryFallback to guard against missing ABI crashes.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
engineIdNoOptional cached FlutterEngine identifier stored in FlutterEngineCache (defaults to 'injected_flutter_engine')
payloadDirYesPath to synthesized Flutter payload directory produced by synthesize_flutter_payload containing lib/ native libraries (libflutter.so, libapp.so) and assets/
workspaceDirYesPath to decompiled APK workspace root directory produced by decompile_apk (modified in-place)
injectionModeYesInjection strategy enum: 'direct_application_hook' (hooks host Application class), 'activity_overlay' (adds overlay Activity), 'view_tree_injection' (attaches FlutterView to main Activity), 'headless_engine' (background engine without UI)
methodChannelBridgeNoOptional MethodChannel bridge config for two-way communication between target Android Smali host and injected Flutter Dart layer
attachBaseContextHookNoInject engine init into attachBaseContext(Context) as well as onCreate() for early initialization
nativeLibraryFallbackNoWrap System.loadLibrary call in defensive try-catch blocks to prevent UnsatisfiedLinkError crashes on missing ABIs

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
engineIdYesFlutterEngineCache identifier used by generated code.
warningsYesCompatibility and follow-up warnings.
copiedLibsYesNumber of copied native library files.
copiedAssetsYesNumber of copied Flutter asset files.
workspaceDirYesMutated decoded APK workspace.
injectionModeYesApplied Flutter integration mode.
methodChannelNoConfigured method-channel bridge, when requested.
modifiedFilesYesWorkspace files created or changed by the operation.
generatedClassesYesGenerated Smali class descriptors.
launchActivityNameYesResolved activity associated with the selected integration mode.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changedv0.1.3
    • addedInput schema / properties / attachBaseContextHook
      Added value: +{
      +  "description": "Inject engine init into attachBaseContext(Context) as well as onCreate() for early initialization",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / engineId / description
      Added value: +"Optional cached FlutterEngine identifier stored in FlutterEngineCache (defaults to 'injected_flutter_engine')"
    • addedInput schema / properties / injectionMode / description
      Added value: +"Injection strategy enum: 'direct_application_hook' (hooks host Application class), 'activity_overlay' (adds overlay Activity), 'view_tree_injection' (attaches FlutterView to main Activity), 'headless_engine' (background engine without UI)"
    • changedInput schema / properties / injectionMode / enum
      Previous value: -[
      -  "activity_overlay",
      -  "view_tree_injection",
      -  "headless_engine"
      -]New value: +[
      +  "activity_overlay",
      +  "view_tree_injection",
      +  "headless_engine",
      +  "direct_application_hook"
      +]
    • addedInput schema / properties / methodChannelBridge / description
      Added value: +"Optional MethodChannel bridge config for two-way communication between target Android Smali host and injected Flutter Dart layer"
    • addedInput schema / properties / methodChannelBridge / properties / channelName / description
      Added value: +"Name of two-way Flutter MethodChannel identifier for Smali<->Dart communication"
    • addedInput schema / properties / methodChannelBridge / properties / handlerClass / description
      Added value: +"Optional custom Smali handler class name to process incoming MethodChannel calls"
    • addedInput schema / properties / methodChannelBridge / properties / methodWhitelist / description
      Added value: +"Optional whitelist of method names allowed over the MethodChannel bridge"
    • addedInput schema / properties / nativeLibraryFallback
      Added value: +{
      +  "description": "Wrap System.loadLibrary call in defensive try-catch blocks to prevent UnsatisfiedLinkError crashes on missing ABIs",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / payloadDir / description
      Added value: +"Path to synthesized Flutter payload directory produced by synthesize_flutter_payload containing lib/ native libraries (libflutter.so, libapp.so) and assets/"
    • addedInput schema / properties / workspaceDir / description
      Added value: +"Path to decompiled APK workspace root directory produced by decompile_apk (modified in-place)"
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "copiedAssets": {
      +      "description": "Number of copied Flutter asset files.",
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "copiedLibs": {
      +      "description": "Number of copied native library files.",
      +      "minimum": 0,
      +      "type": "integer"
      +    },
      +    "engineId": {
      +      "description": "FlutterEngineCache identifier used by generated code.",
      +      "type": "string"
      +    },
      +    "generatedClasses": {
      +      "description": "Generated Smali class descriptors.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "injectionMode": {
      +      "description": "Applied Flutter integration mode.",
      +      "enum": [
      +        "activity_overlay",
      +        "view_tree_injection",
      +        "headless_engine",
      +        "direct_application_hook"
      +      ],
      +      "type": "string"
      +    },
      +    "launchActivityName": {
      +      "description": "Resolved activity associated with the selected integration mode.",
      +      "type": "string"
      +    },
      +    "methodChannel": {
      +      "additionalProperties": false,
      +      "description": "Configured method-channel bridge, when requested.",
      +      "properties": {
      +        "channelName": {
      +          "description": "Dart/host channel identifier.",
      +          "type": "string"
      +        },
      +        "handlerClass": {
      +          "description": "Optional generated or host-side Smali handler class.",
      +          "type": "string"
      +        },
      +        "methodWhitelist": {
      +          "description": "Optional allowed inbound method names.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "channelName"
      +      ],
      +      "type": "object"
      +    },
      +    "modifiedFiles": {
      +      "description": "Workspace files created or changed by the operation.",
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "description": {
      +            "type": "string"
      +          },
      +          "filePath": {
      +            "type": "string"
      +          },
      +          "patchType": {
      +            "enum": [
      +              "smali_insert",
      +              "smali_create",
      +              "asset_copy",
      +              "lib_copy",
      +              "manifest_edit"
      +            ],
      +            "type": "string"
      +          },
      +          "verified": {
      +            "type": "boolean"
      +          }
      +        },
      +        "required": [
      +          "filePath",
      +          "patchType",
      +          "description",
      +          "verified"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "warnings": {
      +      "description": "Compatibility and follow-up warnings.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "workspaceDir": {
      +      "description": "Mutated decoded APK workspace.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "workspaceDir",
      +    "injectionMode",
      +    "generatedClasses",
      +    "modifiedFiles",
      +    "copiedAssets",
      +    "copiedLibs",
      +    "engineId",
      +    "launchActivityName",
      +    "warnings"
      +  ],
      +  "type": "object"
      +}
  2. First observedv0.1.2

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description openly discloses that the tool mutates workspaceDir in-place, writes Smali classes, copies native libraries, and deploys assets. This aligns with the destructiveHint annotation and leaves no ambiguity about side effects. It also notes the experimental nature of view_tree_injection.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense paragraph that packs all essential information without redundancy. It flows logically from action to inputs to mode selection, and every sentence contributes to the agent's understanding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of the operation (7 parameters, nested objects, enum, destructive action), the description covers all relevant aspects: prerequisites, side effects, mode selection, fallback behavior, and configuration options. It is sufficiently complete for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides 100% coverage with descriptive text for every parameter, including nested fields like methodChannelBridge. Each parameter's purpose, defaults, and allowed values are clearly explained, leaving no ambiguity for the agent.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: injecting a synthesized Flutter payload and Smali bootstrap classes into a decompiled APK workspace. It also names the required inputs (workspaceDir and payloadDir) and distinguishes from sibling tools by referencing their outputs (decompile_apk, synthesize_flutter_payload).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance on when to use each injection mode (e.g., prefer activity_overlay for cached-engine screens, direct_application_hook for custom Application classes) and when to enable nativeLibraryFallback to protect against missing ABI crashes, directly helping the agent choose parameter values appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.