# Extension points — rustdesk/rustdesk

> Canonical page: https://codevetter.com/unpack/rustdesk/extension-points

# Extension points — rustdesk/rustdesk

Scanned commit c6a358afbe37c518689a6157a8e8cdbd645dcc5d (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Extension happens at five seams: (1) the Service registry — implement `Service`/`Subscriber` and register in `server::new()`; (2) ConnType — add a variant through protos + session_add dispatch + Flutter WindowType; (3) option keys — append to libs/base/src/config/keys.rs and src/lang template; (4) CLI flags — extend the args[0] chain in core_main; (5) Flutter FFI — new pub fns in flutter_ffi.rs + flutter_rust_bridge codegen. Platform code goes in src/platform/*, not shared paths.
- Service plugin point: implement `trait Service` (or reuse ServiceTmpl<T: Subscriber>) and call `server.add_service(Box::new(...))` in `new()` — video services are even added dynamically at runtime via try_add_monitor_service/try_add_primary_camera_service keyed by `get_service_name(VideoSource, idx)`. — [src/server/service.rs#L9-23](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/service.rs#L9-L23) [src/server.rs#L130-178](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L130-L178) [src/server.rs#L402-425](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server.rs#L402-L425)
- New connection type: add a ConnType in message proto (hbb_common/base protos), branch it in `session_add` (is_* bools), map it in `peer_get_sessions_count`, add a WindowType + kAppType in Flutter main.dart, and handle the login_request::Union arm in connection.rs. — [src/flutter.rs#L1279-1293](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter.rs#L1279-L1293) [src/flutter_ffi.rs#L108-123](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter_ffi.rs#L108-L123) [flutter/lib/main.dart#L64-101](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/flutter/lib/main.dart#L64-L101) [src/server/connection.rs#L2715-2761](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/connection.rs#L2715-L2761)
- Option keys: single import path `base::config::keys` re-exports hbb_common's keys plus ~100 client keys; new options are added as `pub const OPTION_*` and consumed via config::option2bool/Config::get_option — server-pushed strategies can set them remotely. — [libs/base/src/config/keys.rs#L1-10](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/libs/base/src/config/keys.rs#L1-L10) [src/core_main.rs#L892-897](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/core_main.rs#L892-L897)
- CLI extension is a linear `else if args[0] == "--x"` chain in core_main; note the pattern of gating management commands behind `platform::is_installed() && is_root()` and routing root CLI to user IPC via UserMainIpcScope/is_user_main_ipc_scope_cli_command. — [src/core_main.rs#L373-730](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/core_main.rs#L373-L730) [src/core_main.rs#L876-889](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/core_main.rs#L876-L889) [src/ipc.rs#L109-133](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/ipc.rs#L109-L133)
- IPC message extension: add variants to serde-tagged `enum Data` (and FS/DataKeyboard/etc. sub-enums); both ipc::start listener handlers and ui_cm_interface consumers must be updated; FileBlockFromCM documents the raw-bytes side-channel protocol (send message then send_raw). — [src/ipc.rs#L321-438](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/ipc.rs#L321-L438)
- Flutter FFI extension: add `pub fn` in src/flutter_ffi.rs (naming convention: session_*, main_*, peer_*; SyncReturn for sync calls) and regenerate bridge_generated via flutter_rust_bridge 1.80; events to UI go through GLOBAL_EVENT_STREAM via push_global_event(channel, json). — [src/flutter_ffi.rs#L87-100](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter_ffi.rs#L87-L100) [src/flutter.rs#L1808](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/flutter.rs#L1808)
- Localization: add keys to src/lang/template.rs + every locale file per AGENTS.md rules (en.rs only when display differs from key; it.rs always empty string); keys are the English text themselves, sentence-case. — [AGENTS.md](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/AGENTS.md) [src/lang.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/lang.rs)
- Platform seams: src/platform/{windows.rs,linux.rs,macos.rs} + per-OS subdirs implement the hooks called from shared code (install_me, is_installed, elevate_or_run_as_system, check_autostart_config...); AGENTS.md mandates putting new platform logic in these modules with thin call-site hooks. — [src/platform/mod.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/platform/mod.rs) [src/platform/linux.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/platform/linux.rs) [src/platform/windows.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/platform/windows.rs) [AGENTS.md](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/AGENTS.md)
- Codec/capture backends are cfg-gated extensions in libs/scrap (dxgi, quartz, x11, wayland, android, drm capturer) and codec EncoderCfg dispatch in video_service — adding a capture backend means a new scrap module + feature flag + service wiring. — [libs/scrap/src/lib.rs#L1-25](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/libs/scrap/src/lib.rs#L1-L25) [src/server/video_service.rs#L41-53](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/video_service.rs#L41-L53) [Cargo.toml#L30-33](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/Cargo.toml#L30-L33)
- Privacy-mode impls are pluggable per-OS under src/privacy_mode/ (win_mag, win_virtual_display, win_exclude_from_capture, win_topmost_window, macos) selected via is_current_privacy_mode_impl/PRIVACY_MODE_IMPL_* constants. — [src/privacy_mode.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/privacy_mode.rs) [src/privacy_mode/win_mag.rs](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/privacy_mode/win_mag.rs) [src/server/video_service.rs#L28-31](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/server/video_service.rs#L28-L31)
- Custom-server branding is a deployment-time extension: embed signed CustomServer JSON (host/key/api/relay) via exe filename or config string — verified against a hardcoded sign::PublicKey — rather than a plugin API. — [src/custom_server.rs#L11-44](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/src/custom_server.rs#L11-L44)
- AGENTS.md's own extension doctrine: prefer purely additive #[cfg]-gated blocks and new functions over restructuring; 'feature off must run the old code'; shared-file changes should be thin one-line hooks — this is the enforced contribution contract. — [AGENTS.md](https://github.com/rustdesk/rustdesk/blob/c6a358afbe37c518689a6157a8e8cdbd645dcc5d/AGENTS.md)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
