Skip to content

v6.4.1

Latest

Choose a tag to compare

@zinja-coder zinja-coder released this 06 Aug 15:56
d2dd72e

Release Notes: JADX AI MCP v6.4.1

A correctness and reliability patch release.

Four community-reported bugs, two of which spanned both the Java plugin and the Python server. Huge thanks to @LYC-Android, @mhsjzsq, @1yearning1, @darkblack1234, @zbhello, and @Merrg1n for the detailed reports.

No breaking changes. Every new parameter is optional and existing calls behave exactly as before.


Bug Fixes

rename_method could rename a method in the wrong class (#103)

On obfuscated APKs, short names like a() repeat across hundreds of classes. handleRenameMethod walked every included class and renamed the first name match it found, so the rename frequently landed on an arbitrary unrelated class silently, with a success response.
rename_method now accepts an optional class_name. When supplied, the plugin resolves that single class first and only searches within it, returning a proper 404 if the class doesn't exist or the method isn't in it. The matching logic moved into a tryRenameMethodInClass helper so the scoped and unscoped paths can't drift apart.

# Now deterministic on obfuscated APKs
await rename_method(
    method_name="a",
    new_name="decryptPayload",
    class_name="com.example.crypto.Helper",
)

Renaming a method made it unfindable afterwards (#106)

The subtle one. MethodInfo builds its shortId once, from the original method name, and never refreshes it. JavaMethod.getName(), meanwhile, reports the current alias. The moment you renamed a method, those two disagreed so any signature carrying the new name stopped matching shortId, and the method appeared to have vanished. Rename it once and you could no longer address it.

Signature matching now lives in a single MethodSignatures.matches() utility that compares against both getShortId() and the alias-aware makeSignature(true, true). A signature keeps resolving before and after a rename. Both rename_method and get_method_by_name use it, so the two tools can no longer disagree about whether a method exists.

get_resource_file returned HTTP 500 on binary resources (#105, server #59)

The handler called resFile.loadContent().getText().getCodeStr() unconditionally. For resources whose ResContainer wraps a ResourceFile rather than ICodeInfo - PNGs, fonts, arbitrary binary assets - getText() throws ClassCastException: ResourceFile cannot be cast to ICodeInfo. That surfaced as a hard HTTP 500 that aborted the tool call entirely.

Content loading and text extraction now go through safeLoadContent() and safeExtractText(), which normalize decode failures to null. Non-text resources return a structured, stable response instead of an error:

{
  "type": "resource/binary",
  "file": {
    "file_name": "res/drawable/icon.png",
    "content": "",
    "note": "Matched resource is not text-decodable by JADX"
  }
}

Nested-file lookup was also generalized: it previously only descended into resources.arsc, and now searches the subfiles of any container resource.

Codex CLI could not load the MCP server over stdio (#104, server #60)

FastMCP prints a startup banner to stdout. The stdio transport reserves stdout exclusively for MCP protocol frames, so the banner corrupted the stream and broke the initialize handshake before the client ever saw a tool.

Worth calling out: show_banner=False had already been proposed in PR #51 and was lost during merge 605429d. This was a silent regression, not a new bug. The fix restores it on the stdio path and carries an inline comment explaining exactly why it must stay, so it doesn't get dropped a third time.

Package install rejected Python 3.10–3.12 (server #63)

pyproject.toml declared requires-python = ">=3.13", a value present since the very first commit (efac9e1, beta v0.0.1) and almost certainly an unmodified uv init default rather than a deliberate constraint. It contradicted both the README badge (Python 3.10+) and the PEP 723 inline metadata in jadx_mcp_server.py, which already said >=3.10. The practical result: script mode ran fine on 3.10, but uv tool install and pip install refused for no technical reason.

Now >=3.10, verified empirically against a real CPython 3.10.18 interpreter:

Documentation

The ReadTheDocs reference pages had drifted far enough to be actively misleading, the documented rename_method signature would have failed for anyone who copied it. Five signatures were corrected against the live registered tool schemas, not transcribed by hand:

Tool Correct signature
rename_method (method_name, new_name, class_name=None, method_signature=None)
rename_variable (class_name, method_name, variable_name, new_name, reg=None, ssa=None)
search_classes_by_keyword (search_term, package='', search_in='code', offset=0, count=20)
get_method_by_name (class_name, method_name, method_signature=None)
get_xrefs_to_method (class_name, method_name, offset=0, count=20)

The pages also shed a large amount of duplicated prose and aspirational examples describing tools that were never shipped, a net −1,966 lines across 10 pages.

Issues Closed

Issue Reporter Summary
#103 @LYC-Android rename_method lacks class_name, causes wrong-class renames
#104 @zbhello Codex CLI cannot load jadx mcp
#105 @1yearning1 get_resource_file() 500 error
#106 @mhsjzsq Rename failed
server #59 @darkblack1234 ClassCastException: ResourceFile cannot cast to ICodeInfo
server #60 @Merrg1n stdio transport fails to initialize with Codex CLI

Merged Pull Requests

Plugin — #109 (fixes), #110 (version), #111 (docs) Server — #61 (fixes), #62 (version), #63 (Python floor)

Upgrading

Both components must be on 6.4.1, the class_name fix requires the server to send the parameter and the plugin to honor it.

Full Changelog: v6.4.0...v6.4.1

New Contributors

Checksum SHA256:
jadx-mcp-server-6.4.1.zip: e7cf0fa756b817cde3d3a2b6c04a6a6eb8546298eaff6a957e711fb68e53b532
jadx-ai-mcp-6.4.1.jar: df7040ee4bc724c132635e8ad906b0961829db09a35da3365cbc46a761bed983