# onedrive-cli Cross-platform command line interface for OneDrive (Personal) ## Installation With `npm`: ```sh npm install -g @lionello/onedrive-cli ``` That installs the command as `onedrive`, with `onedrive-cli` as an alias for it. Or with `nix-env`: ```sh nix-env -if https://github.com/lionello/onedrive-cli/archive/master.tar.gz -A package ``` Or from source: ```sh 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: ```sh 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](https://modelcontextprotocol.io) 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 ```sh 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](https://learn.microsoft.com/onedrive/developer/rest-api/api/drive_list_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](https://modelcontextprotocol.io) 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`: ```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](https://github.com/lionello/onedrive-cli/blob/master/docs/oauthcallbackhandler.html) 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](https://github.com/lionello/onedrive-cli/issues), so this stays a pointer rather than a second source of truth: - [#33](https://github.com/lionello/onedrive-cli/issues/33) — uploads larger than 100 MiB (`createUploadSession`) - [#36](https://github.com/lionello/onedrive-cli/issues/36) — skip the transfer when the SHA1 already matches - [#34](https://github.com/lionello/onedrive-cli/issues/34) — `chmod`: granting write access (`+w`) - [#37](https://github.com/lionello/onedrive-cli/issues/37) — confirm the API honours gzip/deflate on downloads - [#4](https://github.com/lionello/onedrive-cli/issues/4), [#8](https://github.com/lionello/onedrive-cli/issues/8) — OneDrive for Business, via Microsoft Graph ## DONE - Read-only [MCP](https://modelcontextprotocol.io) server (`onedrive mcp`) - Photo albums via bundles (`onedrive album`) - Full-text search across the drive (`onedrive grep`) - Capture the OAuth token over a loopback listener instead of copy-paste - Delete files and folders (`onedrive rm`) - Get the sharing link for a file (`onedrive ln`) - Register with NPM ([@lionello/onedrive-cli](https://www.npmjs.com/package/@lionello/onedrive-cli)) - Fixed OAuth redirect on Safari (https://bugs.webkit.org/show_bug.cgi?id=24175) - Use XDG path spec for token file (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) - Using `async`/`await` ## Development A [Nix](https://nixos.org) flake provides the package and a dev shell with all dependencies. Run `nix develop` (or use [Direnv](https://direnv.net)'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`: ```sh nix run nixpkgs#prefetch-npm-deps -- package-lock.json ``` ### Regenerate the website `docs/index.html` is generated from this README: ```sh npm run readme ```