onedrive
README.md
# 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`.
<!-- readme-only:start -->
## 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`
<!-- readme-only:end -->
## 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
```
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessNo issues