Skip to content

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 roleServiceRequired methods
Files browsingfiles v1files.list, files.locate, files.preview
Opening text filesfiles v1files.readText
Creating, renaming, deletingfiles v1files.makeDirectory, files.rename, files.remove (all three)
Movingfiles v1files.move
Downloadsfiles v1files.download.open, files.download.read, files.download.finish, files.transfer.abort
Uploadsfiles v1files.upload.open, files.upload.write, files.upload.finish, files.transfer.abort
Folder transfersfiles v1files.transfer.entry, files.directory.open, files.directory.next, files.directory.finish, files.transfer.mkdir, files.transfer.abort
Volumes and mountsfiles v1files.volumes, and files.setVolumeMounted for mount controls
Terminalconsole v1console.open, console.read, console.write, console.close; console.resize optional
Remote settingshost v1host.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 omitThe desktop does
files.saveTextMarks documents read-only rather than offering a save that fails
host.settings.applyShows settings with This adapter provides read-only settings.
console.resizeReports the console as fixed-size; resize requests are refused
files.volumesShows no volumes, with a notice instead of an error
files.setVolumeMountedHides mount and unmount controls
A transfer groupRefuses that direction: Downloads are unavailable through this adapter

Examples

Advertise a files service with reading only, plus a custom service:

rust
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:

rust
"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.

ShellCanvas documentation