From 5823ebefb7f1df118f89ad79eab0b16f02379329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=88=AC=EB=A6=B0?= Date: Sun, 13 Sep 2026 23:31:43 +0900 Subject: [PATCH 1/2] docs: improve English README and add i18n navigation --- README.md | 347 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 201 insertions(+), 146 deletions(-) diff --git a/README.md b/README.md index 01f923b..2dedfe0 100644 --- a/README.md +++ b/README.md @@ -1,195 +1,250 @@ +
+ # rish-mcp +**Give AI assistants secure, self-hosted MCP access to your Android device's `adb shell` — without root, Shizuku, or a permanently attached PC.** + [![CI](https://github.com/turin-dev/rish-mcp/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/turin-dev/rish-mcp/actions/workflows/ci.yml) [![CodeQL](https://github.com/turin-dev/rish-mcp/actions/workflows/codeql.yml/badge.svg?branch=master)](https://github.com/turin-dev/rish-mcp/actions/workflows/codeql.yml) +[![npm](https://img.shields.io/npm/v/rish-mcp-setup?logo=npm)](https://www.npmjs.com/package/rish-mcp-setup) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -Expose an Android device's own shell (uid 2000, like `adb shell`) to AIs as an -**MCP tool** — without VPN, adb-from-a-PC-forever, or sshd. The device holds a -single **outbound** WebSocket to a relay on a public hostname you control; AIs -call the relay's MCP endpoint. +**English** · [한국어](README.ko.md) -``` - 상시 WS (일반 기기) -┌─────────┐ MCP ┌──────────────────┐ ◀───────────────── ┌──────────────┐ -│ AI │──HTTPS─▶│ Go relay + MCP │ │ Android 앱 │ -│(Claude) │ ◀───────│ 서버 │──FCM 웨이크업──────▶│ (저사양 기기) │ -└─────────┘ └──────────────────┘ (Google FCM 경유) └──────────────┘ - │ - │ 버전/체크섬 조회, APK 배포 - ▼ - ┌──────────────────┐ - │ 공식 버전 서버 │ (별도 바이너리/컨테이너, 무토큰) - └──────────────────┘ -``` +
-> **This is a from-scratch rewrite in progress.** The previous Shizuku + -> Node/TS implementation lives under [`before/`](before/) for reference. See -> [`plan.md`](plan.md) for why it was rebuilt and [`docs/DESIGN.md`](docs/DESIGN.md) -> for the current architecture and what's actually implemented vs. still -> pending — read that before assuming anything below is production-ready. +> [!WARNING] +> **The rewrite is still in preview.** The Go relay and Android agent are usable for controlled testing, but the current Android rewrite has not completed the real-device stable-release gates. Read [Release channels](docs/RELEASES.md) before treating it as production-ready. > [!CAUTION] -> GitHub releases `v0.2.0` through `v0.5.0` contain the legacy Shizuku-based -> application. They are not compatible release artifacts for this rewrite. -> A signed rewrite preview is available as `agent-v0.1.0`, but it has not yet -> passed the real-device stable-release gates. Use it only for controlled -> testing; see [Release channels](docs/RELEASES.md) for the exact acceptance -> boundary and promotion gates. - -## Why rewrite - -The old agent depended on [Shizuku](https://shizuku.rikka.app/) — a separate -app the user had to install, understand, and grant permission to, which also -meant devices that didn't support or know about Shizuku couldn't use rish-mcp -at all. See [`plan.md`](plan.md) for the full rationale (Shizuku dependency, -Wear OS performance, server code quality, no official version endpoint). - -## What's different this time - -- **No Shizuku.** The Android app pairs with its own `adbd` directly — - wireless-debugging pairing on Android 11+, a PC+`adb tcpip` bridge below - that. See [`docs/DESIGN.md` §3.1](docs/DESIGN.md#31-셸-접근-페어링-shizuku-대체). -- **Go relay**, not Node/TS — same MCP tool contracts (`run_shell`, - `list_devices`), same WS relay protocol, same OAuth model, rewritten for - concurrency/memory efficiency and a single static binary. -- **Hybrid connection model** (planned): normal phones/tablets keep an - always-on WebSocket; low-spec devices (Wear OS) are meant to move to an - FCM-wake + short session model instead. **Not implemented yet** — it needs - a Firebase project this repo doesn't have configured. Every device - currently uses the always-on path. - -## Status - -| Piece | State | -|---|---| -| Go relay (`server/cmd/relay`) — MCP tools, WS relay, static bearer + OAuth | ✅ built, tested | -| Official version server (`server/cmd/publicserver`) | ✅ built, tested | -| Android `AdbShellClient` (ADB pairing, shell exec) | ✅ built, tested (unit-testable parts only — no device to pair against in this environment) | -| `ConnectionManager` / `AgentService` / `MainActivity` (pairing UI) | ✅ built, compiles — **not verified against a real device** | -| Low-spec hybrid connection + FCM wake | ⛔ blocked — needs a Firebase project (see `docs/DESIGN.md` §7) | -| Docker packaging for the Go binaries | ✅ `server/Dockerfile` (`--target relay` / `--target publicserver`) | -| docker-compose / reverse-proxy deploy config | ✅ `docker-compose.yml` (Traefik/Dokploy) | -| Signed rewrite APK | 🧪 `agent-v0.1.0` preview published — stable promotion pending real-device gates | - -## Components - -- `server/cmd/relay` — Go. Streamable-HTTP **MCP server** (`run_shell`, - `list_devices`) + **WS relay** the Android device connects to. Static - bearer or OAuth for AIs, shared token for the device. -- `server/cmd/publicserver` — Go. Separate, secret-free binary: reports the - current agent version and serves the APK. No route to the relay. -- `app/` — Android (Kotlin). One installable APK: pairs with the device's own - `adbd` to run commands as shell uid, a foreground service holds the - outbound WS, auto-starts on boot. - -## Quick start: relay server and MCP client - -The npm package deliberately handles only server/client setup. It does not -download, build, install, or update the Android APK. +> GitHub releases `v0.2.0` through `v0.5.0` belong to the legacy Shizuku-based implementation. The rewrite uses the separate `agent-v*` release channel. The current signed preview is `agent-v0.1.0`. + +## What is rish-mcp? + +rish-mcp exposes an Android device's own shell (`uid 2000`, equivalent to `adb shell`) as MCP tools for AI clients. + +The Android agent opens an **outbound-only WebSocket** to a relay you control. AI clients connect to that relay through **MCP over Streamable HTTP** and authenticate with a bearer token. The device does not need to accept inbound Internet connections, so the setup works behind NAT/CGNAT. + +```text + outbound WebSocket +┌──────────────┐ MCP/HTTPS ┌──────────────────────┐ ◀────────────────── ┌──────────────┐ +│ AI client │ ────────────▶ │ Go relay + MCP │ │ Android agent│ +│ Claude, etc. │ ◀──────────── │ server/cmd/relay │ ── shell command ─▶ │ adb shell │ +└──────────────┘ └──────────────────────┘ ◀── result/output ── └──────────────┘ + │ + │ version metadata / APK + ▼ + ┌──────────────────────┐ + │ Public version server│ + │ server/cmd/publicserver + └──────────────────────┘ +``` + +The previous Node/TypeScript + Shizuku implementation is kept under [`before/`](before/) for reference. See [`plan.md`](plan.md) for the rewrite rationale and [`docs/DESIGN.md`](docs/DESIGN.md) for the architecture. + +## Highlights + +- **No root and no Shizuku** — the Android app talks directly to the device's own `adbd`. +- **MCP-native** — exposes `list_devices` and `run_shell` through a remote Streamable HTTP MCP endpoint. +- **Outbound-only agent connection** — no inbound port needs to be opened on the phone. +- **Self-hosted relay** — keep shell-access credentials and command traffic on infrastructure you control. +- **Go relay** — compact deployment, straightforward concurrency, and a single server binary per target. +- **Android Kotlin agent** — wireless-debugging pairing on Android 11+, with an `adb tcpip` fallback for older devices. +- **Separate public update service** — release metadata/APK serving stays outside the shell-access trust boundary. + +## Project status + +| Component | Status | +| --- | --- | +| Go relay (`server/cmd/relay`) — MCP, WebSocket relay, bearer auth + OAuth | ✅ Built and tested | +| Public version server (`server/cmd/publicserver`) | ✅ Built and tested | +| Android `AdbShellClient` — pairing and shell execution | ✅ Built; unit-testable parts tested | +| Android UI/service — `MainActivity`, `AgentService`, `ConnectionManager` | 🧪 Builds successfully; real-device validation still in progress | +| Signed rewrite APK | 🧪 `agent-v0.1.0` preview available | +| Docker packaging / Compose deployment | ✅ Available | +| Low-spec hybrid mode + FCM wake | ⛔ Planned; requires Firebase configuration | + +## Quick start + +### 1. Set up the relay + +The easiest path is the npm setup utility. Docker is required for the server action. ```bash -# interactive menu: install relay server or create MCP client config +# interactive setup npx rish-mcp-setup -# non-interactive relay install/update +# or install/update the relay non-interactively npx rish-mcp-setup --yes --action server +``` + +The installer creates or reuses `AI_TOKEN` and `DEVICE_TOKEN`, stores them under `~/.config/rish-mcp/relay.env`, and runs the `rish-mcp-relay` container. + +For reverse-proxy, Compose, and manual deployment options, see [`docs/USAGE.md`](docs/USAGE.md). + +### 2. Install and pair the Android agent + +Use a signed `agent-v*` artifact from [GitHub Releases](https://github.com/turin-dev/rish-mcp/releases) and follow the release notes. + +On **Android 11+**, enable **Developer options → Wireless debugging → Pair device with pairing code**, then enter the pairing information in the rish-mcp app. On older Android versions, use the documented PC-assisted `adb tcpip` flow. + +Detailed pairing instructions are in [`docs/USAGE.md`](docs/USAGE.md#3-pair-the-android-agent). + +### 3. Connect an MCP client -# non-interactive MCP client config +Create a client configuration automatically: + +```bash npx rish-mcp-setup --yes --action client \ --url https://mcp.example.com/mcp \ --token "$AI_TOKEN" ``` -The server action requires Docker. The client action writes a standard -`mcpServers` entry under `~/.config/rish-mcp/client.json`. Android agent -artifacts are distributed separately through the signed `agent-v*` GitHub -release channel; local Android builds remain documented below. +Or configure a compatible MCP client manually: -See [`cli/README.md`](cli/README.md) for all npm setup options. +```json +{ + "mcpServers": { + "phone": { + "type": "http", + "url": "https://mcp.example.com/mcp", + "headers": { + "Authorization": "Bearer " + } + } + } +} +``` -## Build +For Claude CLI, the equivalent setup is: ```bash -# server (both binaries) -cd server && go build ./... && go test ./... +claude mcp add --transport http phone https://mcp.example.com/mcp \ + --header "Authorization: Bearer " +``` + +> [!IMPORTANT] +> Put the bearer token in the `Authorization` header. Do not place access tokens in URLs or query strings. + +## MCP tools -# server Docker images +### `list_devices()` + +Lists connected Android devices, including connection metadata such as agent version, connection age, and pending command count. + +### `run_shell({ cmd, deviceId?, timeoutMs? })` + +Runs a command as Android shell uid (`2000`) and returns stdout, stderr, exit code, and timing information. `deviceId` is only required when more than one device is connected. + +```text +run_shell({ "cmd": "getprop ro.product.model" }) +``` + +See [`docs/USAGE.md`](docs/USAGE.md#5-tool-reference) for the full tool contract. + +## Repository layout + +```text +app/ Android Kotlin agent +server/cmd/relay/ MCP + WebSocket relay +server/cmd/publicserver/ Public version/APK server +cli/ rish-mcp-setup npm package +docs/ Design, usage, and release documentation +before/ Legacy Shizuku + Node/TypeScript implementation +``` + +## Build from source + +### Go servers + +```bash +cd server +go build ./... +go test ./... +``` + +### Server containers + +```bash docker build --target relay -t rishmcp-relay server docker build --target publicserver -t rishmcp-public server +``` + +### Android debug build + +From the repository root: -# Android unit tests + debug APK (run from the repository root) +```bash docker build -t rishmcp-android-build -f app/Dockerfile.build app + docker run --rm -v "$PWD/app:/work" -w /work rishmcp-android-build \ gradle --no-daemon testDebugUnitTest assembleDebug -# output: app/app/build/outputs/apk/debug/app-debug.apk ``` -Official signed rewrite APKs are built by the tag-driven -[Android release workflow](.github/workflows/release.yml) from strict -`agent-vMAJOR.MINOR.PATCH` tags. The workflow verifies tag/version metadata, -builds and tests the release APK, signs it with the repository's official -key, verifies the signature, publishes a SHA-256 checksum, and creates a -GitHub **prerelease**. Do not promote that prerelease to stable until the -real-device acceptance gates in [`docs/RELEASES.md`](docs/RELEASES.md) are -recorded. +Debug APK output: + +```text +app/app/build/outputs/apk/debug/app-debug.apk +``` + +Official signed builds are produced by the tag-driven [Android release workflow](.github/workflows/release.yml) using strict `agent-vMAJOR.MINOR.PATCH` tags. -## Deploy +## Deployment -For a Dokploy host with an external Traefik network, copy `.env.example` to -`.env`, set the two hostnames and generate `AI_TOKEN`/`DEVICE_TOKEN`, then run: +A Compose configuration for Traefik/Dokploy is included: ```bash cp .env.example .env -# edit .env and replace both secrets +# Edit MCP_HOST / PUBLIC_MCP_HOST and replace both secrets. openssl rand -hex 32 -docker network create dokploy-network # once, if it does not exist +docker network create dokploy-network # once, if needed docker compose up -d --build curl -fsS "https://${MCP_HOST}/healthz" ``` -`docker-compose.yml` keeps the trust boundary explicit: the relay receives -shell-access secrets and serves MCP/agent traffic, while the separate -publicserver serves only release metadata and the APK. For all variables and -manual Docker deployment, see [`docs/USAGE.md`](docs/USAGE.md). +The relay receives shell-access secrets and device traffic. The separate public server receives no relay token and only serves release metadata and the APK. -## Use from an AI (MCP client) +See [`docs/USAGE.md`](docs/USAGE.md) for environment variables, OAuth, reverse-proxy settings, and troubleshooting. -Same tool surface as before — this part of the contract didn't change: +## Security model -```json -{ - "mcpServers": { - "phone": { - "type": "http", - "url": "https://mcp.example.com/mcp", - "headers": { "Authorization": "Bearer " } - } - } -} -``` +> [!WARNING] +> `AI_TOKEN` effectively grants remote `adb shell` access to connected devices. Treat it like an SSH private key or other high-value credential. + +- Commands run as **shell uid 2000**, not root. +- The Android agent initiates the connection to the relay; it does not expose an inbound shell service. +- Use **HTTPS/WSS** in real deployments. +- Keep `AI_TOKEN` and `DEVICE_TOKEN` secret and rotate them if they may have leaked. +- Scope is intentionally **single-user / owner-operated**, not a multi-tenant remote-device platform. + +Please report vulnerabilities privately as described in [`SECURITY.md`](SECURITY.md). + +## Release channels + +| Channel | Meaning | +| --- | --- | +| `agent-v*` | Current Android rewrite artifacts | +| `v0.2.0`–`v0.5.0` | Legacy Shizuku application; incompatible with the rewrite | +| npm `rish-mcp-setup` | Relay/client setup utility only; it does **not** install the Android APK | + +Promotion requirements and signing details live in [`docs/RELEASES.md`](docs/RELEASES.md). + +## Documentation + +| Document | Contents | +| --- | --- | +| [`docs/USAGE.md`](docs/USAGE.md) | Deployment, pairing, MCP tools, OAuth, protocol details, troubleshooting | +| [`docs/DESIGN.md`](docs/DESIGN.md) | Current architecture and implementation boundaries | +| [`docs/RELEASES.md`](docs/RELEASES.md) | Release channels, signing, and promotion gates | +| [`plan.md`](plan.md) | Rewrite rationale and project direction | +| [`cli/README.md`](cli/README.md) | `rish-mcp-setup` CLI reference | +| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Contribution guide | + +## Contributing + +Issues and pull requests are welcome. Please read [`CONTRIBUTING.md`](CONTRIBUTING.md) before contributing. + +## License -- `list_devices()` — connected devices, agent version, connection age, and - pending-command count. -- `run_shell({cmd, deviceId?, timeoutMs?})` — run a command as shell uid; - returns stdout, stderr, exit code. - -Full tool reference, OAuth flow, and the WS relay protocol are documented in -[`docs/USAGE.md`](docs/USAGE.md). - -## Security notes - -- `AI_TOKEN` is a master key for shell access to the device. Treat it like an - SSH private key. -- The Android device only trusts the relay it dials; it never accepts - inbound connections. -- No root is required or used — shell access is uid 2000, same ceiling as - `adb shell`. -- Scope is the **owner's own device** for personal automation, same as - before — see `plan.md`'s explicit "multi-tenant 아님" non-goal. - -Please report vulnerabilities privately as described in -[`SECURITY.md`](SECURITY.md). Contributions are welcome under the -[`MIT License`](LICENSE); see [`CONTRIBUTING.md`](CONTRIBUTING.md) before -opening a pull request. +rish-mcp is licensed under the [MIT License](LICENSE). From c6d1912079580abbc9ac10ccae486d95198c8107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=88=AC=EB=A6=B0?= Date: Sun, 13 Sep 2026 23:32:22 +0900 Subject: [PATCH 2/2] docs: add Korean README --- README.ko.md | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 README.ko.md diff --git a/README.ko.md b/README.ko.md new file mode 100644 index 0000000..04ce820 --- /dev/null +++ b/README.ko.md @@ -0,0 +1,250 @@ +
+ +# rish-mcp + +**루트, Shizuku, 상시 연결된 PC 없이 AI가 내 Android 기기의 `adb shell`을 MCP로 사용할 수 있게 해주는 셀프호스팅 도구입니다.** + +[![CI](https://github.com/turin-dev/rish-mcp/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/turin-dev/rish-mcp/actions/workflows/ci.yml) +[![CodeQL](https://github.com/turin-dev/rish-mcp/actions/workflows/codeql.yml/badge.svg?branch=master)](https://github.com/turin-dev/rish-mcp/actions/workflows/codeql.yml) +[![npm](https://img.shields.io/npm/v/rish-mcp-setup?logo=npm)](https://www.npmjs.com/package/rish-mcp-setup) +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) + +[English](README.md) · **한국어** + +
+ +> [!WARNING] +> **현재 리라이트 버전은 프리뷰 단계입니다.** Go 릴레이와 Android 에이전트는 제한된 테스트에 사용할 수 있지만, Android 리라이트는 아직 실제 기기 기준의 안정 릴리스 검증을 모두 통과하지 않았습니다. 운영 환경에 사용하기 전에 [릴리스 채널](docs/RELEASES.md)을 확인하세요. + +> [!CAUTION] +> GitHub 릴리스 `v0.2.0`~`v0.5.0`은 예전 Shizuku 기반 구현입니다. 현재 리라이트는 별도의 `agent-v*` 릴리스 채널을 사용하며, 현재 서명된 프리뷰는 `agent-v0.1.0`입니다. + +## rish-mcp란? + +rish-mcp는 Android 기기 자체의 셸(`uid 2000`, `adb shell`과 같은 권한 수준)을 AI 클라이언트가 사용할 수 있는 MCP 도구로 노출합니다. + +Android 에이전트는 사용자가 관리하는 릴레이 서버로 **아웃바운드 WebSocket** 연결을 생성합니다. AI 클라이언트는 **Streamable HTTP 기반 MCP**로 릴레이에 접속하고 Bearer 토큰으로 인증합니다. 기기가 인터넷에서 들어오는 연결을 직접 받을 필요가 없어 NAT/CGNAT 환경에서도 사용할 수 있습니다. + +```text + 아웃바운드 WebSocket +┌──────────────┐ MCP/HTTPS ┌──────────────────────┐ ◀────────────────── ┌──────────────┐ +│ AI 클라이언트 │ ────────────▶ │ Go 릴레이 + MCP │ │ Android 에이전트│ +│ Claude 등 │ ◀──────────── │ server/cmd/relay │ ─── 셸 명령 실행 ──▶ │ adb shell │ +└──────────────┘ └──────────────────────┘ ◀── 실행 결과 반환 ── └──────────────┘ + │ + │ 버전 정보 / APK + ▼ + ┌──────────────────────┐ + │ 공개 버전 서버 │ + │ server/cmd/publicserver + └──────────────────────┘ +``` + +이전 Node/TypeScript + Shizuku 구현은 참고용으로 [`before/`](before/)에 남아 있습니다. 리라이트 이유는 [`plan.md`](plan.md), 현재 아키텍처는 [`docs/DESIGN.md`](docs/DESIGN.md)를 참고하세요. + +## 주요 특징 + +- **루트와 Shizuku가 필요 없음** — Android 앱이 기기 자신의 `adbd`와 직접 통신합니다. +- **MCP 네이티브** — 원격 Streamable HTTP MCP 엔드포인트에서 `list_devices`, `run_shell`을 제공합니다. +- **기기 측 아웃바운드 연결만 사용** — 휴대폰에 외부 공개 포트를 열 필요가 없습니다. +- **셀프호스팅 릴레이** — 셸 접근 자격 증명과 명령 트래픽을 직접 관리하는 인프라에 둘 수 있습니다. +- **Go 릴레이** — 배포가 간단하고 서버 바이너리가 작으며 동시성 처리가 명확합니다. +- **Kotlin Android 에이전트** — Android 11+ 무선 디버깅 페어링을 지원하고, 구형 Android는 `adb tcpip` 방식으로 연결할 수 있습니다. +- **공개 업데이트 서비스 분리** — 버전 정보/APK 제공 기능을 셸 접근 권한이 있는 릴레이와 분리합니다. + +## 프로젝트 상태 + +| 구성 요소 | 상태 | +| --- | --- | +| Go 릴레이 (`server/cmd/relay`) — MCP, WebSocket 릴레이, Bearer 인증 + OAuth | ✅ 빌드 및 테스트 완료 | +| 공개 버전 서버 (`server/cmd/publicserver`) | ✅ 빌드 및 테스트 완료 | +| Android `AdbShellClient` — 페어링 및 셸 실행 | ✅ 빌드 완료, 단위 테스트 가능한 부분 테스트 완료 | +| Android UI/서비스 — `MainActivity`, `AgentService`, `ConnectionManager` | 🧪 빌드 성공, 실제 기기 검증 진행 중 | +| 서명된 리라이트 APK | 🧪 `agent-v0.1.0` 프리뷰 제공 중 | +| Docker 패키징 / Compose 배포 | ✅ 제공됨 | +| 저사양 하이브리드 모드 + FCM 웨이크업 | ⛔ 계획 단계, Firebase 설정 필요 | + +## 빠른 시작 + +### 1. 릴레이 설정 + +가장 쉬운 방법은 npm 설정 도구를 사용하는 것입니다. 서버 설치 작업에는 Docker가 필요합니다. + +```bash +# 대화형 설정 +npx rish-mcp-setup + +# 또는 비대화형으로 릴레이 설치/업데이트 +npx rish-mcp-setup --yes --action server +``` + +설치 도구는 `AI_TOKEN`과 `DEVICE_TOKEN`을 생성하거나 기존 값을 재사용하고, `~/.config/rish-mcp/relay.env`에 저장한 뒤 `rish-mcp-relay` 컨테이너를 실행합니다. + +리버스 프록시, Docker Compose, 수동 배포 방법은 [`docs/USAGE.md`](docs/USAGE.md)를 참고하세요. + +### 2. Android 에이전트 설치 및 페어링 + +[GitHub Releases](https://github.com/turin-dev/rish-mcp/releases)의 서명된 `agent-v*` 아티팩트를 사용하고 해당 릴리스 노트를 따라 설치하세요. + +**Android 11+**에서는 **개발자 옵션 → 무선 디버깅 → 페어링 코드로 기기 페어링**을 켠 뒤 rish-mcp 앱에 페어링 정보를 입력합니다. 구형 Android는 문서에 설명된 PC 보조 `adb tcpip` 방식을 사용합니다. + +상세 절차는 [`docs/USAGE.md`](docs/USAGE.md#3-pair-the-android-agent)를 참고하세요. + +### 3. MCP 클라이언트 연결 + +클라이언트 설정을 자동 생성할 수 있습니다. + +```bash +npx rish-mcp-setup --yes --action client \ + --url https://mcp.example.com/mcp \ + --token "$AI_TOKEN" +``` + +또는 호환되는 MCP 클라이언트에 직접 설정할 수 있습니다. + +```json +{ + "mcpServers": { + "phone": { + "type": "http", + "url": "https://mcp.example.com/mcp", + "headers": { + "Authorization": "Bearer " + } + } + } +} +``` + +Claude CLI에서는 다음과 같이 추가할 수 있습니다. + +```bash +claude mcp add --transport http phone https://mcp.example.com/mcp \ + --header "Authorization: Bearer " +``` + +> [!IMPORTANT] +> Bearer 토큰은 `Authorization` 헤더에 넣으세요. URL이나 쿼리 문자열에 접근 토큰을 넣지 마세요. + +## MCP 도구 + +### `list_devices()` + +연결된 Android 기기 목록을 반환합니다. 에이전트 버전, 연결 시간, 대기 중인 명령 수 등의 연결 정보도 포함합니다. + +### `run_shell({ cmd, deviceId?, timeoutMs? })` + +Android shell uid(`2000`) 권한으로 명령을 실행하고 stdout, stderr, 종료 코드, 실행 시간 정보를 반환합니다. 여러 기기가 동시에 연결된 경우에만 `deviceId`가 필요합니다. + +```text +run_shell({ "cmd": "getprop ro.product.model" }) +``` + +전체 도구 계약은 [`docs/USAGE.md`](docs/USAGE.md#5-tool-reference)를 참고하세요. + +## 저장소 구조 + +```text +app/ Android Kotlin 에이전트 +server/cmd/relay/ MCP + WebSocket 릴레이 +server/cmd/publicserver/ 공개 버전/APK 서버 +cli/ rish-mcp-setup npm 패키지 +docs/ 설계, 사용법, 릴리스 문서 +before/ 레거시 Shizuku + Node/TypeScript 구현 +``` + +## 소스에서 빌드 + +### Go 서버 + +```bash +cd server +go build ./... +go test ./... +``` + +### 서버 컨테이너 + +```bash +docker build --target relay -t rishmcp-relay server +docker build --target publicserver -t rishmcp-public server +``` + +### Android 디버그 빌드 + +저장소 루트에서 실행합니다. + +```bash +docker build -t rishmcp-android-build -f app/Dockerfile.build app + +docker run --rm -v "$PWD/app:/work" -w /work rishmcp-android-build \ + gradle --no-daemon testDebugUnitTest assembleDebug +``` + +디버그 APK 출력 경로: + +```text +app/app/build/outputs/apk/debug/app-debug.apk +``` + +공식 서명 빌드는 엄격한 `agent-vMAJOR.MINOR.PATCH` 태그를 사용하는 [Android 릴리스 워크플로](.github/workflows/release.yml)에서 생성됩니다. + +## 배포 + +Traefik/Dokploy용 Compose 설정이 포함되어 있습니다. + +```bash +cp .env.example .env +# MCP_HOST / PUBLIC_MCP_HOST를 수정하고 두 비밀값을 교체하세요. +openssl rand -hex 32 + +docker network create dokploy-network # 필요한 경우 한 번만 +docker compose up -d --build +curl -fsS "https://${MCP_HOST}/healthz" +``` + +릴레이는 셸 접근 비밀값과 기기 트래픽을 처리합니다. 별도의 공개 서버는 릴레이 토큰을 받지 않으며 릴리스 메타데이터와 APK만 제공합니다. + +환경 변수, OAuth, 리버스 프록시 설정, 문제 해결은 [`docs/USAGE.md`](docs/USAGE.md)를 참고하세요. + +## 보안 모델 + +> [!WARNING] +> `AI_TOKEN`은 연결된 기기에 원격 `adb shell` 접근 권한을 제공하는 것과 사실상 같습니다. SSH 개인 키와 비슷한 수준의 고가치 자격 증명으로 취급하세요. + +- 명령은 root가 아니라 **shell uid 2000**으로 실행됩니다. +- Android 에이전트가 릴레이에 먼저 연결하며, 기기에 인바운드 셸 서비스를 열지 않습니다. +- 실제 배포에서는 **HTTPS/WSS**를 사용하세요. +- `AI_TOKEN`, `DEVICE_TOKEN`은 외부에 노출하지 말고 유출 가능성이 있으면 교체하세요. +- 범위는 의도적으로 **단일 사용자 / 기기 소유자 운영**이며 멀티테넌트 원격 기기 플랫폼을 목표로 하지 않습니다. + +취약점은 [`SECURITY.md`](SECURITY.md)의 안내에 따라 비공개로 제보해 주세요. + +## 릴리스 채널 + +| 채널 | 의미 | +| --- | --- | +| `agent-v*` | 현재 Android 리라이트 아티팩트 | +| `v0.2.0`–`v0.5.0` | 레거시 Shizuku 앱, 현재 리라이트와 호환되지 않음 | +| npm `rish-mcp-setup` | 릴레이/클라이언트 설정 전용. Android APK는 설치하지 않음 | + +승격 조건과 서명 세부 정보는 [`docs/RELEASES.md`](docs/RELEASES.md)에 있습니다. + +## 문서 + +| 문서 | 내용 | +| --- | --- | +| [`docs/USAGE.md`](docs/USAGE.md) | 배포, 페어링, MCP 도구, OAuth, 프로토콜, 문제 해결 | +| [`docs/DESIGN.md`](docs/DESIGN.md) | 현재 아키텍처와 구현 범위 | +| [`docs/RELEASES.md`](docs/RELEASES.md) | 릴리스 채널, 서명, 승격 조건 | +| [`plan.md`](plan.md) | 리라이트 이유와 프로젝트 방향 | +| [`cli/README.md`](cli/README.md) | `rish-mcp-setup` CLI 레퍼런스 | +| [`CONTRIBUTING.md`](CONTRIBUTING.md) | 기여 가이드 | + +## 기여 + +이슈와 Pull Request를 환영합니다. 기여 전 [`CONTRIBUTING.md`](CONTRIBUTING.md)를 읽어 주세요. + +## 라이선스 + +rish-mcp는 [MIT License](LICENSE)로 배포됩니다.