Metadata-Version: 2.4
Name: rpcclient-mcp
Version: 0.1.0
Summary: MCP server exposing rpc-project rpcclient sessions and APIs
Author: Xplo8E
Maintainer: Xplo8E
License-Expression: MIT
Project-URL: Homepage, https://github.com/Xplo8E/rpcclient-mcp
Project-URL: Repository, https://github.com/Xplo8E/rpcclient-mcp
Project-URL: Issues, https://github.com/Xplo8E/rpcclient-mcp/issues
Keywords: mcp,rpcclient,ios,automation,iphone,rpc-project
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp>=1.10.0
Requires-Dist: rpcclient==6.11.1
Provides-Extra: dev
Requires-Dist: build>=1.2.2; extra == "dev"
Requires-Dist: twine>=5.1.1; extra == "dev"
Requires-Dist: ruff>=0.6.9; extra == "dev"
Requires-Dist: mypy>=1.11.2; extra == "dev"
Dynamic: license-file

# rpcclient-mcp

MCP server for `rpcclient` targets iOS over stdio transport.

## Prerequisites

- Python 3.10+
- RPC server reachable

## Getting Started

### Install

```bash
cd rpcclient-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```

`rpcclient==6.11.1` is a package dependency, so it installs automatically with this MCP.

If you want to force local rpcclient source instead of PyPI:

```bash
export RPCCLIENT_PYTHONPATH=/absolute/path/to/rpc-project/src/rpcclient
```

### Configure your AI agent

#### Claude Code

```bash
claude mcp add --transport stdio rpcclient-mcp -- /absolute/path/to/rpcclient-mcp/.venv/bin/rpcclient-mcp
```

#### Codex CLI

```bash
codex mcp add rpcclient-mcp -- /absolute/path/to/rpcclient-mcp/.venv/bin/rpcclient-mcp
```

#### Gemini CLI

```bash
gemini mcp add --transport stdio rpcclient-mcp /absolute/path/to/rpcclient-mcp/.venv/bin/rpcclient-mcp
```

#### Codex (manual config)

Add to `~/.codex/config.toml` (or your active Codex config):

```toml
[mcp_servers.rpcclient-mcp]
command = "/absolute/path/to/rpcclient-mcp/.venv/bin/rpcclient-mcp"

[mcp_servers.rpcclient-mcp.env]
RPCCLIENT_PYTHONPATH = "/absolute/path/to/rpc-project/src/rpcclient" # optional
```

Restart your client after config changes.

## Usage

```text
ping()
rpc_connect(host="127.0.0.1", port=5910)
rpc_get_screen_context(session_id="...")
rpc_disconnect(session_id="...")
```

## Tools

### Session

```text
# health
ping()

# connection lifecycle
rpc_connect(host="127.0.0.1", port=5910, timeout=3.0)
rpc_disconnect(session_id)
rpc_reconnect(session_id)

# session inspection
rpc_list_sessions()
rpc_session_info(session_id)
```

Use these to establish, inspect, and recover sessions.  
`rpc_reconnect` is the transport recovery path and invalidates old handles.

### Generic RPC + Handles

```text
# discovery
rpc_capabilities(session_id, include_private=False)
rpc_call(session_id, path, args=None, kwargs=None, store_result=True)

# handle lifecycle
rpc_list_handles(session_id)
rpc_release_handle(session_id, handle_id)
rpc_release_all_handles(session_id)

# handle access
rpc_handle_call(session_id, handle_id, method, args=None, kwargs=None, store_result=True)
rpc_handle_get(session_id, handle_id, attr, store_result=True)
```

Use `rpc_call` for dot-path execution on the root client object.  
When `store_result=True`, non-JSON return values are materialized as handles.

### App + UI

```text
# app discovery + launch
rpc_list_apps(session_id, query="", limit=30)
rpc_launch_app(session_id, bundle_id=None, app_query=None, kill_existing=True, unlock_device=True, timeout=3.0, wait_foreground_timeout=5.0)

# context + overlay handling
rpc_get_screen_context(session_id, ensure_accessibility=True, wait_primary_bundle=None, wait_timeout=5.0, max_items=300, dedupe=True)
rpc_dismiss_overlays(session_id, timeout=4.0, max_rounds=6)

# interaction: click + type
rpc_click_label(session_id, label, exact=True, index=0, timeout=5.0, auto_scroll=True, draw_frame=False, direction="next", displayed_only=False, dismiss_overlays=True, overlay_timeout=3.0)
rpc_click_by_context(session_id, intent, min_score=0.52, timeout=5.0, auto_scroll=True, draw_frame=False, direction="next", dismiss_overlays=True, overlay_timeout=3.0)
rpc_type_text(session_id, text, target_label=None, intent=None, min_intent_score=0.35, anchor_label=None, anchor_position="before", anchor_offset=1, clear_first=False, timeout=5.0, direction="next", displayed_only=False, dismiss_overlays=True, overlay_timeout=3.0)

# gestures + focused fallback
rpc_scroll(session_id, direction="down", count=1, pause_seconds=0.25, from_x=None, from_y=None, to_x=None, to_y=None)
rpc_tap(session_id, x, y, repeat=1, pause_seconds=0.2)
rpc_type_focused_text(session_id, text, dismiss_overlays=False, overlay_timeout=2.0)
```

This is the primary automation surface: launch, read context, click, type, and gesture.  
Use `rpc_tap` + `rpc_type_focused_text` when web fields are visible but not AX-discoverable.

## Current Limitation

Safari overlay password fields are not always AX-exposed on this target.  
Manual password entry may still be required in some runs.

## License

MIT. See [LICENSE](LICENSE).
