Skip to main content
Glama

Apktool MCP Server

test.sh10.1 kB
#!/usr/bin/env bash ### # This is the test script to test the working of APKTool MCP Server. # # Prerequisites: # 1. Ensure APKTool is installed and available in PATH # 2. Have DVAC_FINAL.apk file in the current directory # 3. Start the APKTool MCP server in HTTP stream mode on port 8652 # 4. Command for step 3: `python apktool_mcp_server.py --http --port 8652` # # Usage: ./test_apktool.sh ### set -euo pipefail MCP_URL="${MCP_URL:-http://127.0.0.1:8652/mcp/}" ACCEPT_HDR="application/json, text/event-stream" CONTENT_HDR="application/json" APK_PATH="DVAC_FINAL.apk" # Helper: extract data: JSON items from SSE and drop [DONE] sse_to_json() { grep '^data: ' | sed 's/^data: //' | grep -v '^\[DONE\]$' } # 1) Initialize, capture session id header echo "== Initialize MCP Session ==" INIT_RESP_HEADERS=$(mktemp) curl -i -s -X POST "$MCP_URL" \ -H "Content-Type: $CONTENT_HDR" \ -H "Accept: $ACCEPT_HDR" \ -d '{ "jsonrpc":"2.0", "method":"initialize", "params":{ "protocolVersion":"2024-11-05", "capabilities":{}, "clientInfo":{"name":"apktool-test-automation","version":"1.0.0"} }, "id":1 }' | tee "$INIT_RESP_HEADERS" >/dev/null SESSION_ID=$(awk -F': ' 'BEGIN{IGNORECASE=1} /^mcp-session-id:/ {print $2}' "$INIT_RESP_HEADERS" | tr -d '\r') if [[ -z "${SESSION_ID:-}" ]]; then echo "Failed to obtain MCP-Session-Id header" >&2 exit 1 fi echo "Session: $SESSION_ID" # 2) Send notifications/initialized (no output expected) curl -s -X POST "$MCP_URL" \ -H "Content-Type: $CONTENT_HDR" \ -H "Accept: $ACCEPT_HDR" \ -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' >/dev/null # 3) Discover available tools echo "== Available Tools ==" TOOLS_JSON=$(curl -s -X POST "$MCP_URL" \ -H "Content-Type: $CONTENT_HDR" \ -H "Accept: $ACCEPT_HDR" \ -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":2}' \ | sse_to_json | tail -n 1) echo "$TOOLS_JSON" | jq -r '.result.tools[].name' # Helper: call a tool with JSON arguments call_tool() { local name="$1" local args_json="$2" # must be a valid JSON object string local id="${3:-1000}" curl -s -X POST "$MCP_URL" \ -H "Content-Type: $CONTENT_HDR" \ -H "Accept: $ACCEPT_HDR" \ -H "Mcp-Session-Id: $SESSION_ID" \ -d "{ \"jsonrpc\":\"2.0\", \"method\":\"tools/call\", \"params\":{ \"name\":\"$name\", \"arguments\":$args_json }, \"id\":$id }" \ | sse_to_json } echo "== Running APKTool MCP Server Tests ==" # 4) Health check echo "--- health_check ---" call_tool "health_check" '{}' 10 | jq -r '.result.content[0].text // .result // .error?.message // .' # 5) Get workspace info echo "--- get_workspace_info ---" call_tool "get_workspace_info" '{}' 11 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.workspace_info.projects[]? | {name, is_apktool_project, package_name} // .' # Check if APK file exists, if not skip decode test if [[ -f "$APK_PATH" ]]; then echo "--- decode_apk ---" APK_FULL_PATH=$(realpath "$APK_PATH" 2>/dev/null || echo "$APK_PATH") call_tool "decode_apk" "{\"apk_path\":\"$APK_FULL_PATH\",\"force\":true}" 12 | jq -r '.result.content[0].text // .result // .error?.message // .' # Wait a moment for decode to complete sleep 2 PROJECT_DIR="apktool_mcp_server_workspace/DVAC_FINAL" else echo "--- decode_apk (skipped - APK not found) ---" echo "APK file $APK_PATH not found, using existing project" # Use existing project from workspace info - check what's available PROJECT_DIR="apktool_mcp_server_workspace/DVAC-FINAL" # Note the hyphen based on workspace info fi # 7) Get decoded project directory (use existing project if decode skipped) echo "Using project directory: $PROJECT_DIR" # 8) Get manifest content echo "--- get_manifest ---" call_tool "get_manifest" "{\"project_dir\":\"$PROJECT_DIR\"}" 13 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.manifest[0:300] // .error // .' # 9) Get apktool.yml echo "--- get_apktool_yml ---" call_tool "get_apktool_yml" "{\"project_dir\":\"$PROJECT_DIR\"}" 14 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.content[0:200] // .error // .' # 10) List smali directories echo "--- list_smali_directories ---" call_tool "list_smali_directories" "{\"project_dir\":\"$PROJECT_DIR\"}" 15 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.smali_dirs[]?.name // .error // .' # 11) List smali files with pagination echo "--- list_smali_files (offset=0,count=20) ---" call_tool "list_smali_files" "{\"project_dir\":\"$PROJECT_DIR\",\"smali_dir\":\"smali\",\"offset\":0,\"count\":20}" 16 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.smali_files[]?.class_name // .error // .' | head -5 # 12) List smali files with package filter echo "--- list_smali_files (package filter: com.zin) ---" call_tool "list_smali_files" "{\"project_dir\":\"$PROJECT_DIR\",\"package_prefix\":\"com.zin\"}" 17 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.smali_files[]?.class_name // .error // .' | head -5 # 13) Get specific smali file echo "--- get_smali_file ---" call_tool "get_smali_file" "{\"project_dir\":\"$PROJECT_DIR\",\"class_name\":\"com.zin.dvac.MainActivity\"}" 18 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.content[0:300] // .error // .' # 14) List all resource types echo "--- list_resources (all types) ---" call_tool "list_resources" "{\"project_dir\":\"$PROJECT_DIR\"}" 19 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.resource_types[]?.type // .error // .' # 15) List specific resource type with pagination echo "--- list_resources (layout, offset=0,count=10) ---" call_tool "list_resources" "{\"project_dir\":\"$PROJECT_DIR\",\"resource_type\":\"layout\",\"offset\":0,\"count\":10}" 20 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.resources[]?.name // .error // .' | head -5 # 16) Get specific resource file echo "--- get_resource_file ---" call_tool "get_resource_file" "{\"project_dir\":\"$PROJECT_DIR\",\"resource_type\":\"layout\",\"resource_name\":\"activity_main.xml\"}" 21 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.content[0:200] // .error // .' # 17) Search in files echo "--- search_in_files (search for 'onCreate') ---" call_tool "search_in_files" "{\"project_dir\":\"$PROJECT_DIR\",\"search_pattern\":\"onCreate\",\"file_extensions\":[\".smali\"],\"max_results\":10}" 22 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.results[]?.file // .error // .' | head -5 # 18) Search with pagination (fix the jq syntax error) echo "--- search_in_files (with pagination, search for 'Activity') ---" call_tool "search_in_files" "{\"project_dir\":\"$PROJECT_DIR\",\"search_pattern\":\"Activity\",\"offset\":0,\"count\":5,\"case_sensitive\":false}" 23 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.results[]? | "\(.file) (\(.matches) matches)" // .error // .' | head -5 # 19) Analyze project structure echo "--- analyze_project_structure ---" call_tool "analyze_project_structure" "{\"project_dir\":\"$PROJECT_DIR\"}" 24 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.analysis | {is_valid_project, project_size, total_smali_files: .smali_analysis.total_smali_files, total_resource_files: .resource_analysis.total_resource_files} // .error // .' # 20) Clean project (with backup) echo "--- clean_project ---" call_tool "clean_project" "{\"project_dir\":\"$PROJECT_DIR\",\"backup\":true}" 25 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.cleaned_directories[]?.path // .error // "No directories to clean"' # 21) Build APK echo "--- build_apk ---" call_tool "build_apk" "{\"project_dir\":\"$PROJECT_DIR\",\"debug\":true}" 26 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.apk_path // .error // .' # 22) Example of modifying a smali file (commented out for safety) echo "--- modify_smali_file (example - commented out for safety) ---" # Uncomment the line below to test file modification call_tool "modify_smali_file" '{"project_dir":"'$PROJECT_DIR'","class_name":"com.zin.dvac.MainActivity","new_content":"# Modified smali content\n.class public Lcom/zin/dvac/MainActivity;\n.super Landroid/app/Activity;","create_backup":true}' 27 | jq -r '.result.content[0].text // .result // .error?.message // .' echo "Skipped - modify_smali_file (enable manually if needed)" # 23) Example of modifying a resource file (commented out for safety) echo "--- modify_resource_file (example - commented out for safety) ---" # Uncomment the line below to test resource modification call_tool "modify_resource_file" '{"project_dir":"'$PROJECT_DIR'","resource_type":"values","resource_name":"strings.xml","new_content":"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <string name=\"app_name\">Modified DVAC</string>\n</resources>","create_backup":true}' 28 | jq -r '.result.content[0].text // .result // .error?.message // .' echo "Skipped - modify_resource_file (enable manually if needed)" # 24) Final workspace info to see changes echo "--- get_workspace_info (final) ---" call_tool "get_workspace_info" '{}' 29 | jq -r '.result.content[0].text // .result // .error?.message // .' | jq -r '.workspace_info.projects[]? | {name, is_apktool_project, size} // .error // .' echo "== Test Completed Successfully ==" echo "Note: Some modification operations were skipped for safety." echo "To test file modifications, uncomment the relevant lines in the script." # Cleanup temp file rm -f "$INIT_RESP_HEADERS"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zinja-coder/apktool-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server