# Sailfish Devel MCP Host-side Model Context Protocol server for Sailfish OS development workflows. This first iteration is dependency-free: it implements MCP over stdio directly with Python's standard library and exposes typed tools around commands that are easy to get wrong during day-to-day Sailfish work. ## Scope The server currently exposes tools for: - Sailfish device access over SSH - defaultuser session-bus calls - Lipstick screenshots - touchscreen discovery and tap/swipe injection - topmost window PID lookup - process map inspection - journal log reads - RPM copy/install on a device - system and user service management - Docker/mb2 RPM builds through the local `build-sailfishos` helper - Jolla OBS result and build-log lookup through `osc` - repository status and search under the configured git root - RPM spec metadata summaries - QML translation search and Sailfish ternary translation checks The committed defaults are deliberately generic. Device tools default to the placeholder SSH target `root@device`, the Sailfish user-session bus at `/run/user/100000/dbus/user_bus_socket`, `~/git` as the local source root, and the vendored build helper at `src/sailfish_devel_mcp/vendor/build_sailfishos.py`. Put a config file at `~/.config/sailfish-devel-mcp/config.json` or pass `--config` to provide your real device and OBS settings. Device entries can also carry the preferred user, architecture, and current release label. If an installed SDK is available, set `paths.local_sdk` to its `sdk-chroot` path; builds will use it when it has a target matching the requested release and architecture, otherwise they fall back to the coderus SDK image. ## Running From a checkout: ```sh /path/to/sailfish-devel-mcp/bin/sailfish-devel-mcp ``` To inspect the effective configuration: ```sh /path/to/sailfish-devel-mcp/bin/sailfish-devel-mcp --dump-config ``` Example MCP client configuration: ```json { "mcpServers": { "sailfish-devel": { "command": "/path/to/sailfish-devel-mcp/bin/sailfish-devel-mcp" } } } ``` ## Configuration Example: ```json { "default_device": "phone", "devices": { "phone": { "ssh_target": "root@phone", "username": "defaultuser", "architecture": "aarch64", "release": "live", "user_bus_runtime_dir": "/run/user/100000", "user_bus_address": "unix:path=/run/user/100000/dbus/user_bus_socket" } }, "paths": { "git_root": "/home/you/git", "ssh_config": "/home/you/.ssh/config", "local_sdk": "/srv/mer/sdks/sfossdk/sdk-chroot", "osc_api_alias": "your-obs-alias" } } ``` ## Tool Notes The server keeps local paths scoped to the configured git root and `/tmp` for tools that read or write files. Device access still uses SSH, so the usual SSH prompts, permissions, and command failures are surfaced as tool results. Mutating tools are annotated as non-read-only: - `sailfish_device_lipstick_screenshot` - `sailfish_device_touch` - `sailfish_device_user_bus_call` - `sailfish_device_install_rpm` - `sailfish_device_restart_service` - `sailfish_build_rpm` `sailfish_device_lipstick_screenshot` defaults to `~/Pictures/Screenshots/lipstick-.png` under `/home/`, where `username` comes from the device config. Lipstick rejects screenshot save paths outside the home directory. When that directory is missing, the tool derives ownership with `stat -L`, creates `Pictures` as that owner/group with mode `775`, and creates `Pictures/Screenshots` as that owner and the `privileged` group with mode `755` when the group exists. `sailfish_device_touch` supports `discover`, `tap`, and `swipe`. Discovery prints `/proc/bus/input/devices` and can also run `evdev_trace -i` when `include_evdev_trace` is true. Tap and swipe auto-select a likely touchscreen input event device unless `input_device` is supplied. Coordinates are raw input/display coordinates, so pair this tool with a current screenshot when choosing points. `sailfish_build_rpm` can use a configured device's `architecture` and `release` as defaults when the call includes `device`. If `paths.local_sdk` is set, the build helper first checks the installed SDK targets. `live` uses the unversioned local target for the requested architecture, for example `aarch64`; a named release such as `5.0.0` uses a matching versioned local target such as `aarch64-5.0.0`. If the required target is not installed, the helper falls back to the release-specific coderus Docker SDK image. The wrapper image defaults to `sailfish-sdk-build-engine:$USER` and can be overridden with `SAILFISH_SDK_BUILD_ENGINE_IMAGE`. Read-only tools include the journal, topmost PID, process maps, OBS lookup, repo search, spec summary, and QML checks. ## Smoke Test ```sh printf '%s\n' \ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \ '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \ | /path/to/sailfish-devel-mcp/bin/sailfish-devel-mcp ``` ## Development Run tests without installing the package: ```sh PYTHONPATH=src python3 -m unittest discover -s tests ```