| Crates.io | rclone-sdk |
| lib.rs | rclone-sdk |
| version | 1.72.1 |
| created_at | 2025-11-15 23:02:48.176545+00 |
| updated_at | 2026-01-21 18:21:22.315448+00 |
| description | Full OpenAPI-based client for the Rclone RC API. |
| homepage | https://rcloneui.com |
| repository | https://github.com/rclone-ui/rclone-sdk |
| max_upload_size | |
| id | 1934918 |
| size | 514,651 |
Full OpenAPI-based client for the Rclone RC API
Built on top of rclone-openapi (by yours truly) · Works with Vanilla Fetch · React Query · SWR · Rust
cargo add rclone-sdk
[dependencies]
rclone-sdk = "1.72"
tokio = { version = "1", features = ["full"] }
use rclone_sdk::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new("http://localhost:5572");
// Get rclone version info
let version = client.core_version(None, None).await?;
let v = version.into_inner();
println!("Rclone {} on {}/{}", v.version, v.os, v.arch);
// List all configured remotes
let remotes = client.config_listremotes(None, None).await?;
println!("Remotes: {:?}", remotes.into_inner().remotes);
// Get storage info for a remote
let about = client.operations_about(None, None, "gdrive:").await?;
let info = about.into_inner();
println!("Storage: {} / {} bytes used", info.used, info.total);
Ok(())
}
npm install rclone-sdk
import createRCDClient from 'rclone-sdk'
const rcd = createRCDClient({ baseUrl: 'http://localhost:5572' })
// List all configured remotes
const { data: remotes } = await rcd.POST('/config/listremotes')
console.log(remotes?.remotes) // ['gdrive', 'dropbox', 's3']
// List files in a remote
const { data: files } = await rcd.POST('/operations/list', {
body: { fs: 'gdrive:', remote: 'Documents' }
})
console.log(files?.list)
// Get storage info for a remote
const { data: about } = await rcd.POST('/operations/about', {
body: { fs: 'gdrive:' }
})
console.log(`Used: ${about?.used} / ${about?.total}`)
import createRCDQueryClient from 'rclone-sdk/query'
const rq = createRCDQueryClient({ baseUrl: 'http://localhost:5572' })
function RemotesList() {
const { data, isLoading, error } = rq.useQuery('post', '/config/listremotes')
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return (
<ul>
{data?.remotes?.map(remote => (
<li key={remote}>{remote}</li>
))}
</ul>
)
}
function StorageInfo({ remote }: { remote: string }) {
const { data } = rq.useQuery('post', '/operations/about', {
body: { fs: `${remote}:` }
})
return <span>{data?.used} / {data?.total} bytes</span>
}
import createRCDSWR from 'rclone-sdk/swr'
const swr = createRCDSWR({ baseUrl: 'http://localhost:5572' })
function RemotesList() {
const { data, error, isLoading } = swr.useQuery('post', '/config/listremotes')
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return (
<ul>
{data?.remotes?.map(remote => (
<li key={remote}>{remote}</li>
))}
</ul>
)
}
function FileList({ remote, path }: { remote: string; path: string }) {
const { data } = swr.useQuery('post', '/operations/list', {
body: { fs: `${remote}:`, remote: path }
})
return (
<ul>
{data?.list?.map(item => (
<li key={item.Path}>
{item.IsDir ? '📁' : '📄'} {item.Name}
</li>
))}
</ul>
)
}
Even though the client supports all HTTP methods, rclone expects everything as a POST request.
If you want to wrap the client to only send POST requests and throw errors automatically, here's a quick snippet (adjust to taste):
import createRCDClient, {
type OpenApiMethodResponse,
type OpenApiClient,
type OpenApiClientPathsWithMethod,
type OpenApiMaybeOptionalInit,
type OpenApiRequiredKeysOf,
type RCDClient,
} from 'rclone-sdk'
type ClientPaths<T> = T extends OpenApiClient<infer P, any> ? P : never
type Paths = ClientPaths<RCDClient>
type InitParam<Init> = OpenApiRequiredKeysOf<Init> extends never
? [(Init & { [key: string]: unknown })?]
: [Init & { [key: string]: unknown }]
export default async function rclone<
Path extends OpenApiClientPathsWithMethod<RCDClient, 'post'>,
Init extends OpenApiMaybeOptionalInit<Paths[Path], 'post'> = OpenApiMaybeOptionalInit<
Paths[Path],
'post'
>,
>(
path: Path,
...init: InitParam<Init>
): Promise<OpenApiMethodResponse<RCDClient, 'post', Path, Init>> {
const client = createRCDClient({ baseUrl: 'http://localhost:5572' })
const result = await client.POST(
path,
...(init as InitParam<OpenApiMaybeOptionalInit<Paths[Path], 'post'>>)
)
if (result?.error) {
const message =
typeof result.error === 'string' ? result.error : JSON.stringify(result.error)
throw new Error(message)
}
const data = result.data as { error?: unknown } | undefined
if (data?.error) {
const message = typeof data.error === 'string' ? data.error : JSON.stringify(data.error)
throw new Error(message)
}
if (!result.response.ok) {
throw new Error(`${result.response.status} ${result.response.statusText}`)
}
return result.data as OpenApiMethodResponse<typeof client, 'post', Path, Init>
}
Now you'll be able to
rclone('config/listremotes') directlyerror field manually)Contributions = welcome! Just make sure to check if the PR isn't a better fit for the rclone-openapi repo.