Adapter services
What you advertise in initialize decides which parts of the desktop light up. Advertise only what the device can honour: a missing capability is presented to the user as unavailable, which is far better than a method that fails when they try it.
Availability
Each desktop role is enabled by an exact service id, version and set of methods. Partial support is normal and supported — a files service without writing gives read-only Files, and a settings service without applying gives read-only Host details.
Interface
Standard roles
| Desktop role | Service | Required methods |
|---|---|---|
| Files browsing | files v1 | files.list, files.locate, files.preview |
| Opening text files | files v1 | files.readText |
| Creating, renaming, deleting | files v1 | files.makeDirectory, files.rename, files.remove (all three) |
| Moving | files v1 | files.move |
| Downloads | files v1 | files.download.open, files.download.read, files.download.finish, files.transfer.abort |
| Uploads | files v1 | files.upload.open, files.upload.write, files.upload.finish, files.transfer.abort |
| Folder transfers | files v1 | files.transfer.entry, files.directory.open, files.directory.next, files.directory.finish, files.transfer.mkdir, files.transfer.abort |
| Volumes and mounts | files v1 | files.volumes, and files.setVolumeMounted for mount controls |
| Terminal | console v1 | console.open, console.read, console.write, console.close; console.resize optional |
| Remote settings | host v1 | host.settings.read; host.settings.apply to allow changes |
Everything else you advertise is a custom service, reachable by apps that hold services.<your-id>.
Custom service naming
Identifiers are lowercase, dot-separated, at most 180 bytes, and their first segment may not be system, files, console, host, terminal or services. Every method must begin with the service id. Use something you own, such as a reversed domain: com.example.thermostat.
What partial support produces
| You omit | The desktop does |
|---|---|
files.saveText | Marks documents read-only rather than offering a save that fails |
host.settings.apply | Shows settings with This adapter provides read-only settings. |
console.resize | Reports the console as fixed-size; resize requests are refused |
files.volumes | Shows no volumes, with a notice instead of an error |
files.setVolumeMounted | Hides mount and unmount controls |
| A transfer group | Refuses that direction: Downloads are unavailable through this adapter |
Examples
Advertise a files service with reading only, plus a custom service:
async fn initialize(
&self,
configuration: Value,
_context: RequestContext,
) -> Result<Vec<ServiceDescriptor>, CallError> {
Ok(vec![
ServiceDescriptor {
id: "files".into(),
version: 1,
methods: vec![
"files.list".into(),
"files.locate".into(),
"files.preview".into(),
"files.readText".into(),
],
},
ServiceDescriptor {
id: "com.example.thermostat".into(),
version: 1,
methods: vec![
"com.example.thermostat.read".into(),
"com.example.thermostat.setTarget".into(),
],
},
])
}Refuse an operation you cannot perform, with a code that means something:
"files.remove" => Err(CallError::new("denied", "This device exposes read-only storage")),Use unavailable when the operation does not exist here, denied when it exists but is not permitted, invalid for malformed parameters, and busy when a limit is reached.
Errors
The desktop refuses an unadvertised method before your process sees it:
This adapter does not advertise the requested method
Where a role is selected but not provided, the workspace reports the capability as unsupported — This capability is not provided by the selected service — and the connection editor notes that the capability is unavailable through that connection. These are states the user can see and understand, not failures.
Lifecycle and permissions
One workspace can take its services from several adapters: files from one, a console from another, remote settings from a third. The files family — listing, text, mutations, moves and transfers — must come from a single source, because paths are only meaningful within their own provider. Console and settings may come from anywhere.
Your service catalog is fixed for the life of the connection: it is sent once, at initialize, and cannot be changed later. To offer different capabilities, have the user reconnect.
Custom service permissions are granted per service, not per method: approving services.com.example.thermostat covers every method that service advertises, so keep services focused.
Related guides
- Adapter process protocol — how these methods are called.
- Build your first adapter — templates for files, console and settings.
- Custom services — how apps call what you advertise.
- Filesystem contracts and SDK — the path and paging model behind a files service.