> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OneDrive

> Mount Microsoft OneDrive or SharePoint document libraries as a Mirage filesystem with async access, versioning, and shell commands.

The OneDrive resource mounts a Microsoft OneDrive (or SharePoint document
library) at some prefix such as `/onedrive/`. All operations involve network
I/O to Microsoft Graph. Files are served as raw bytes (no Office filetype
conversion). Uses aiohttp for async Graph access.

Compatible with: personal OneDrive, OneDrive for Business, and SharePoint
document libraries (driveItems on Microsoft Graph v1.0).

For credential setup (tokens, drive ids, app vs delegated auth), see the
[OneDrive Setup](/home/setup/onedrive) guide.

## Config

```python theme={null}
import os

from mirage import MountMode, Workspace
from mirage.resource.onedrive import OneDriveResource, OneDriveConfig

config = OneDriveConfig(
    access_token=os.environ["MS_GRAPH_DRIVE_TOKEN"],
    # Optional:
    # drive_id="b!...",        # target a specific drive (required for app-only tokens)
    # site_id="contoso.sharepoint.com,...",  # use a SharePoint site's default drive
    # key_prefix="Documents/",  # mount a sub-folder as the root
    # timeout=30,
)

resource = OneDriveResource(config)
ws = Workspace({"/onedrive": resource}, mode=MountMode.WRITE)
```

`OneDriveResource(config)` takes an `OneDriveConfig` object with a Microsoft
Graph bearer token and optional drive/site targeting. Both `READ` and `WRITE`
modes are supported.

### Config Reference

| Field          | Required | Description                                                            |
| -------------- | -------- | ---------------------------------------------------------------------- |
| `access_token` | Yes      | Microsoft Graph OAuth2 bearer token                                    |
| `drive_id`     | No       | Target a specific drive. Required for app-only tokens (no `/me/drive`) |
| `site_id`      | No       | Resolve a SharePoint site's default drive instead of `/me/drive`       |
| `key_prefix`   | No       | Mount a sub-folder of the drive as the root                            |
| `timeout`      | No       | Request timeout in seconds (default `30`)                              |

Drive resolution order: `drive_id`, then the `site_id` site's default drive,
then `/me/drive`.

## Filesystem Layout

The OneDrive resource maps Graph driveItems (path-addressed) to virtual paths
under the mount prefix. Folders are real driveItems, so the tree matches what
you see in OneDrive.

For example, if the drive contains:

```text theme={null}
Documents/file.txt
Documents/config.json
Reports/q1.csv
Reports/q2.csv
```

Then mounting at `/onedrive/` exposes:

```text theme={null}
/onedrive/
  Documents/
    file.txt
    config.json
  Reports/
    q1.csv
    q2.csv
```

Path mapping: virtual `/onedrive/Documents/file.txt` maps to the driveItem at
`/root:/Documents/file.txt`.

## Versioning and Snapshots

OneDrive keeps per-file version history. The resource exposes it the same way
the S3 backend does:

* **Fingerprint** is the driveItem `cTag`, so normal reads and `stat` reflect
  the current content without extra Graph calls.
* **Snapshots** pin each path to a Graph driveItem version id. Replaying a
  snapshot reads `/versions/{id}/content`, giving time-travel to the exact
  bytes captured at snapshot time.
* **Restore** writes a previous version back as the current one.

This makes the OneDrive resource `SUPPORTS_SNAPSHOT = True`.

## Cache

The OneDrive resource caches directory listings via `IndexCacheStore` to reduce
repeated Graph calls during traversal.

## Example

```python theme={null}
import asyncio
import os

from mirage import MountMode, Workspace
from mirage.resource.onedrive import OneDriveResource, OneDriveConfig

config = OneDriveConfig(
    access_token=os.environ["MS_GRAPH_DRIVE_TOKEN"],
    drive_id=os.environ.get("MS_GRAPH_DRIVE_ID") or None,
)

resource = OneDriveResource(config)


async def main() -> None:
    ws = Workspace({"/onedrive/": resource}, mode=MountMode.WRITE)

    r = await ws.execute("ls /onedrive/")
    print(await r.stdout_str())

    await ws.execute("echo 'hello from mirage' > /onedrive/note.txt")

    r = await ws.execute("cat /onedrive/note.txt")
    print(await r.stdout_str())

    r = await ws.execute("stat /onedrive/note.txt")
    print(await r.stdout_str())

    r = await ws.execute("tree /onedrive/")
    print(await r.stdout_str())


if __name__ == "__main__":
    asyncio.run(main())
```

A runnable version lives at `examples/python/onedrive/onedrive.py`.

## Shell Commands

The OneDrive resource supports the full set of shell commands since it operates
on real file content (text, binary, JSON, CSV, etc.). Large files benefit from
range reads to avoid downloading entire items.

### Read Commands

| Command         | Notes                                      |
| --------------- | ------------------------------------------ |
| `cat`           | Read file content                          |
| `head` / `tail` | First/last N lines                         |
| `grep` / `rg`   | Pattern search (file or directory level)   |
| `jq`            | Query JSON fields                          |
| `wc`            | Line/word/byte counts                      |
| `stat`          | File metadata (name, size, type, modified) |
| `find`          | Recursive search with `-name`, `-maxdepth` |
| `tree`          | Directory tree view                        |
| `nl`            | Number lines                               |
| `du`            | Disk usage summary                         |
| `file`          | Detect file type                           |
| `strings`       | Extract printable strings from binary      |
| `xxd`           | Hex dump                                   |
| `md5`           | MD5 checksum                               |
| `sha256sum`     | SHA-256 checksum                           |

### File Operations

| Command | Notes                                 |
| ------- | ------------------------------------- |
| `cp`    | Copy files                            |
| `mv`    | Move/rename files                     |
| `rm`    | Remove files                          |
| `mkdir` | Create directories                    |
| `touch` | Create empty file or update timestamp |
| `tee`   | Write stdin to file and stdout        |

### Path Utilities

| Command    | Notes                     |
| ---------- | ------------------------- |
| `basename` | Strip directory from path |
| `dirname`  | Strip filename from path  |
| `realpath` | Resolve path              |
| `ls`       | List directory contents   |

## Use Cases

* **AI agents accessing org documents**: Mount OneDrive/SharePoint for agents to read and process files
* **Versioned document workflows**: Snapshot and replay exact file states over time
* **Sandboxed access**: Restrict agent operations to a specific drive and sub-folder via `key_prefix`
* **FUSE mounting**: Expose a OneDrive through a virtual FUSE mount for external tools

## Scoping a resource to a folder

Pass `key_prefix: str | None = None` to `OneDriveConfig` to transparently scope
every operation to a sub-folder of the drive:

```python theme={null}
OneDriveResource(OneDriveConfig(
    access_token=token,
    drive_id=drive_id,
    key_prefix=f"users/{user_id}/",
))
```

When set, every read/write/list/stat/copy/rename/delete operation is scoped to
that sub-folder. Agents see clean paths like `/data/notes.md`; the underlying
driveItem is `users/{user_id}/data/notes.md`. Useful for multi-tenant systems.

**Normalization:** leading slashes are stripped and a trailing slash is added
automatically. Both `None` and an empty string are treated as "no prefix."
