Skip to content

Repository files navigation

onedrive-cli

Cross-platform command line interface for OneDrive (Personal)

Installation

With npm:

npm install -g @lionello/onedrive-cli

That installs the command as onedrive, with onedrive-cli as an alias for it.

Or with nix-env:

nix-env -if https://github.com/lionello/onedrive-cli/archive/master.tar.gz -A package

Or from source:

git clone https://github.com/lionello/onedrive-cli.git
cd onedrive-cli
npm install
bin/onedrive login

Getting started

Sign in once, then use the drive like a filesystem:

onedrive login          # opens the Microsoft login page
onedrive df             # check the connection and storage usage
onedrive ls             # list your drive root

login opens your browser, then stores the access token it gets back in ~/.onedrive-cli-token (or $XDG_STATE_HOME if that is set). Tokens are valid for one hour, so run login again when a command reports that the token expired. Add -r for a read-only token.

Usage

usage: onedrive COMMAND [arguments]

Run onedrive help (or -h/--help) for this list at any time, and onedrive --version for the installed version. The commands are:

  • album - list, create, or edit photo albums (ls/create/add/rm)
  • cat - dumps the contents of a file to stdout
  • chmod - change sharing permissions
  • cp - copies local file(s) to OneDrive or vice-versa
  • df - shows OneDrive storage usage stats
  • find - find file(s) or folder(s) by name, optionally separated by NUL
  • grep - full-text search across the drive, listing matching paths
  • help - shows list of supported commands
  • ln - create a link to the remote item
  • login - request/store an OAuth access token
  • ls - list the contents of a folder
  • mcp - run a read-only MCP server over stdio
  • mkdir - create a remote folder
  • mv - move a local file to OneDrive or vice-versa
  • rm - delete a file or folder from OneDrive
  • sendmail - send an invitation email for editing to recipients
  • stat - dump all information for particular file(s)
  • wget - copy a remote URL to OneDrive (server side)

Examples

List the contents of the Public folder

onedrive ls Public

Grep one file

onedrive cat Documents/passwords | grep boa

Let OneDrive upload a file server side

onedrive wget http://mega.com/somehugepublicfile Documents/somehugepublicfile

Upload files recursively

find * -type f -print0 | xargs -0 -n1 -I{} onedrive cp "./{}" "Shared Favorites/{}"

Move remote files to a new folder

onedrive find 'Pictures/Camera Roll' -regex 2015 -type f -print0 | xargs -0 onedrive mv -t :/Pictures/2015/

Create an album and add photos to it
onedrive album create 'Summer 2026'
onedrive album add 'Summer 2026' 'Pictures/Camera Roll/IMG_1234.jpg'
onedrive albums                # list all albums
onedrive albums 'Summer 2026'  # list the photos in one album

Albums are OneDrive bundles: they live outside the folder hierarchy and only reference the files, so album rm removes a photo from the album without deleting the file. Deleting an album itself is not supported by the API — use the OneDrive web UI for that.

MCP server

onedrive mcp starts a read-only Model Context Protocol server over stdio, so an MCP client (Claude, etc.) can browse and read your OneDrive. It reuses the stored access token, so login first — ideally with login -r for a read-only token. The server only issues GET requests and cannot modify the drive. It exposes these tools:

  • list_onedrive_folder - list the direct children of a folder
  • search_onedrive_content - full-text search across the whole drive
  • find_onedrive_files - recursively find items by name glob
  • list_onedrive_albums - list the photo albums, or the items in one album
  • read_onedrive_file - read a file's contents as text
  • stat_onedrive_item - return full metadata for an item
  • onedrive_storage - report storage quota for the available drives

Register it with your MCP client, e.g. in claude_desktop_config.json:

{
  "mcpServers": {
    "onedrive": {
      "command": "onedrive",
      "args": ["mcp"]
    }
  }
}

FAQ

Access token was not found; 'login' first.

The onedrive utility needs an access token in order to read/write to your OneDrive storage. Run onedrive login: it opens the Microsoft login page, and after you sign in the callback page hands the token straight back to the waiting command, which saves it to ~/.onedrive-cli-token. If the browser runs on another machine (or the handover fails), the page shows the token so you can paste it at the prompt instead. Tokens are valid for 1 hour.

"An item with the same name already exists under the parent"

Currently, a copy will fail if a file with the same it already exists. Change the name of the target, or use other means to delete/rename the existing file in your OneDrive.

Invalid source name

You cannot copy folders. Specify a source file instead, or use wildcards.

Invalid target name

The target file name cannot be determined from the source path. Specify a target file name.

Use ./ or :/ path prefix for local or remote paths.

The cp command supports both local->remote as well as remote->local copy. To make it clear which path is remote and which is local, either use ./ as a prefix for the local path, or use :/ as a prefix for the remote path. Either one will suffice.

chmod: Invalid file mode

The chmod command currently only supports -w or -rw. The former tried to downgrade write shares to read-only, whereas the latter removes all shares for the given item(s). Octal modes are accepted (for example 644, 0700) as well as og-rw or g-w.

TODO

Tracked on the issue tracker, so this stays a pointer rather than a second source of truth:

  • #33 — uploads larger than 100 MiB (createUploadSession)
  • #36 — skip the transfer when the SHA1 already matches
  • #34chmod: granting write access (+w)
  • #37 — confirm the API honours gzip/deflate on downloads
  • #4, #8 — OneDrive for Business, via Microsoft Graph

DONE

Development

A Nix flake provides the package and a dev shell with all dependencies. Run nix develop (or use Direnv's use flake) for the shell, and nix build / nix run to build or run the CLI. The legacy shell.nix still works with nix-shell.

Update the dependency hash

After changing package-lock.json, refresh npmDepsHash in flake.nix:

nix run nixpkgs#prefetch-npm-deps -- package-lock.json

Regenerate the website

docs/index.html is generated from this README:

npm run readme

Releases

Packages

Used by

Contributors

Languages