Add add_remote_device tool to allow remote Frida connections - #7
Conversation
There was a problem hiding this comment.
Pull request overview
Adds MCP tools for managing remote Frida device connections so users can connect to and disconnect from Frida servers running on other hosts.
Changes:
- Introduce
add_remote_devicetool to register a remote Frida server via host/port and optional TLS/auth parameters. - Introduce
remove_remote_devicetool to unregister a previously-added remote device.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| try: | ||
| address = f"{host}:{port}" | ||
| manager = frida.get_device_manager() | ||
|
|
There was a problem hiding this comment.
address = f"{host}:{port}" will produce an invalid/ambiguous address for IPv6 hosts (e.g. fe80::1 becomes fe80::1:27042). Consider detecting IPv6 literals and formatting as [host]:port, or document that IPv6 is unsupported and validate/reject host values containing :.
| except Exception as e: | ||
| raise ValueError(f"Failed to add remote device at {host}:{port}: {str(e)}") |
There was a problem hiding this comment.
When re-raising as ValueError, consider using exception chaining (raise ValueError(...) from e) so the original Frida exception type/traceback is preserved for debugging. This is especially useful when troubleshooting remote connection failures.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7474b0a. Configure here.
| try: | ||
| addr = ipaddress.ip_address(bare) | ||
| if isinstance(addr, ipaddress.IPv6Address): | ||
| return f"[{bare}]:{port}" |
There was a problem hiding this comment.
IPv6 address not normalized, causing potential mismatch
Low Severity
_format_address parses the IPv6 address into an ipaddress.IPv6Address object (which normalizes it) but then discards the parsed result and uses the raw bare string in the output. This means equivalent IPv6 representations like 0:0:0:0:0:0:0:1 and ::1 produce different address strings. Since both add_remote_device and remove_remote_device rely on _format_address for the address key, a user who adds a device with one representation and removes it with another will get a mismatch and the removal will fail. Using str(addr) instead of bare would normalize the address to its canonical form.
Reviewed by Cursor Bugbot for commit 7474b0a. Configure here.
|
I also would like this |
…ackaging - split the 700-line cli.py into server/devices/state/tools modules with a create_server() factory and a thin STDIO entry point - fix create_simple_hook for frida 17 (Module.getGlobalExportByName instead of the removed findExportByName) and report hook status/errors instead of returning false success - add lifecycle tools: list_sessions/close_session, list_hooks/ get_hook_messages/remove_hook, with detached-signal auto-cleanup, capped message queues, and persist_timeout USB resilience - add add_remote_device/remove_remote_device with IPv6-aware addressing (upstream issue dnakov#6, based on PR dnakov#7) - USB-first default device policy with logged local fallback (upstream issue dnakov#1) - frida 17 spawn argv; attach_to_process verifies then detaches (issue dnakov#2) - Annotated-style tool parameters with real Python defaults; operational failures return structured results instead of raising - pyproject 0.2.0: ruff/mypy (strict)/ty/pytest gates, PEP 735 dependency groups, committed uv.lock, py.typed, .gitattributes - 41 unit tests with faked devices plus an env-gated live self-attach test; verified live on Android 15 (API 35): hook install/capture/teardown, interactive sessions, auto-cleanup, and failure paths
…ackaging - split the 700-line cli.py into server/devices/state/tools modules with a create_server() factory and a thin STDIO entry point - fix create_simple_hook for frida 17 (Module.getGlobalExportByName instead of the removed findExportByName) and report hook status/errors instead of returning false success - add lifecycle tools: list_sessions/close_session, list_hooks/ get_hook_messages/remove_hook, with detached-signal auto-cleanup, capped message queues, and persist_timeout USB resilience - add add_remote_device/remove_remote_device with IPv6-aware addressing (upstream issue dnakov#6, based on PR dnakov#7) - USB-first default device policy with logged local fallback (upstream issue dnakov#1) - frida 17 spawn argv; attach_to_process verifies then detaches (issue dnakov#2) - Annotated-style tool parameters with real Python defaults; operational failures return structured results instead of raising - pyproject 0.2.0: ruff/mypy (strict)/ty/pytest gates, PEP 735 dependency groups, committed uv.lock, py.typed, .gitattributes - 41 unit tests with faked devices plus an env-gated live self-attach test; verified live on Android 15 (API 35): hook install/capture/teardown, interactive sessions, auto-cleanup, and failure paths


Note
Medium Risk
Adds new network-facing capability to connect/disconnect from remote Frida servers (including optional auth/TLS parameters), which can affect connectivity and security assumptions if misused or misconfigured.
Overview
Adds MCP tools to manage remote Frida connections from the CLI:
add_remote_device(with optionalcertificate,origin,token, andkeepalive_interval) andremove_remote_device.Introduces
_format_addressusingipaddressto correctly format IPv4/hostname vs IPv6 ([addr]:port) when building the Frida remote device address, and surfaces remote device info (includingaddress) or consistentValueErrorerrors on failure.Reviewed by Cursor Bugbot for commit 7474b0a. Bugbot is set up for automated code reviews on this repo. Configure here.