AI & Agents

LlamaIndex OneDrive Reader: Querying Documents in RAG Pipelines

The LlamaIndex OneDrive reader extracts documents and metadata from Microsoft accounts for vector indexing, but direct Graph API synchronization introduces throttling and memory bottlenecks on large archives. In production retrieval pipelines, teams either configure custom Azure Entra ID app credentials with backoff handlers or bridge OneDrive folders into indexed remote workspaces. This guide explains how to configure OneDriveReader and implement efficient search patterns.

Derek Labian 11 min read Updated
Indexing documents in intelligent workspaces eliminates client-side traversal and API rate limit bottlenecks.

How the LlamaIndex OneDrive Reader Connects to Microsoft Graph

Ingesting enterprise documents from Microsoft OneDrive directly into an in-memory retrieval pipeline creates an immediate architectural conflict: LlamaIndex must recursively traverse nested folder hierarchies and download binary streams over the Microsoft Graph API, triggering per-user rate limits and memory spikes before embedding even starts. The bottleneck in production RAG systems is rarely the vector store or the embedding model; it is the latency and throttling penalties incurred while pulling unindexed corporate archives across HTTP connections.

The LlamaIndex OneDrive reader (OneDriveReader) is a data connector that extracts files and metadata from Microsoft OneDrive accounts into LlamaIndex Document nodes for vector indexing. It acts as an extraction bridge between Microsoft 365 file storage and downstream ingestion pipelines, translating remote cloud files into parsed text blocks formatted for semantic embedding models.

Under the hood, OneDriveReader coordinates calls to the Microsoft Graph REST API endpoints (/v1.0/me/drive/items for personal user drives or /v1.0/drives/{drive-id}/items for organization drives). When your ingestion job calls load_data(), the reader initiates a multi-phase extraction sequence:

  1. Hierarchy Enumeration: The connector recursively queries child folder items, parsing paging tokens (@odata.nextLink) across large directories to build an in-memory file catalog.
  2. Content Streaming: For every eligible file matching configured MIME types, the connector makes a separate HTTP GET request to the /content endpoint to stream the binary payload.
  3. Local Format Extraction: The reader buffers raw bytes in memory and uses local format parsers to unpack plain text from PDF documents, Microsoft Word files (.docx), PowerPoint presentations (.pptx), and plain text files.
  4. Document Node Generation: The reader wraps the resulting text strings into LlamaIndex Document objects, attaching Microsoft Graph file metadata such as file_name, file_id, created_date_time, last_modified_date_time, and web_url.

While this direct extraction pattern works for prototype scripts and small file sets, production document repositories expose critical limitations. Most technical tutorials omit the steep latency penalties of pulling entire document archives into memory. Because OneDriveReader is an in-memory reader, fetching hundreds of multi-megabyte PDFs over standard HTTP connections monopolizes execution workers, exhausts container memory limits, and locks up pipeline processes during initial batch loads. Teams evaluating a dedicated OneDrive alternative often seek architectures that separate file persistence from active agent indexing.

How to Configure Microsoft Entra ID Credentials for Ingestion

Before initializing OneDriveReader in Python, you must create and configure an application registration in Microsoft Entra ID (formerly Azure Active Directory). Microsoft Graph protects all OneDrive file storage behind OAuth 2.0 authorization, requiring specific tenant scopes and client credentials.

The permission model creates substantial confusion for engineering teams because Microsoft distinguishes between Delegated permissions and Application permissions:

  • Delegated Permissions (Files.Read, Files.Read.All, User.Read): The application accesses OneDrive on behalf of a signed-in human user. This mode requires an interactive browser prompt and a redirect URI (such as https://localhost under Mobile and Desktop applications). Delegated access works well for interactive developer utilities, but it fails in unattended background workers, scheduled cron jobs, and cloud containers where no human is present to complete interactive OAuth logins.
  • Application Permissions (Files.Read.All): The application authenticates silently as a background service principal using the OAuth 2.0 client credentials grant. This is the required architecture for automated ingestion pipelines. However, Files.Read.All grants the service principal broad read access across every user OneDrive and SharePoint document library in the entire Microsoft 365 tenant.

Because Application permissions grant tenant-wide data access, Microsoft Entra ID requires explicit Microsoft 365 Global Administrator consent. Without administrator consent, authentication attempts fail immediately with an AADSTS65001: The user or administrator has not consented to use the application exception.

Account types also alter the authentication structure:

  • OneDrive for Business / Microsoft 365: Uses your organization's specific Microsoft Entra Directory (Tenant) ID (a standard UUID format) and supports Application permissions with client secrets.
  • Personal OneDrive: Uses the generic string consumers as the tenant ID. Microsoft does not support application permissions or client secret authentication on personal OneDrive accounts; personal accounts must use interactive delegated authentication.

Once your Entra ID application registration is complete and admin consent is granted, install the dedicated reader package from PyPI into your Python environment. You can then instantiate OneDriveReader and parse documents into retrieval-ready nodes:

import os
from llama_index.readers.microsoft_onedrive import OneDriveReader
from llama_index.core.node_parser import SentenceSplitter

### Initialize reader with Entra ID application credentials
reader = OneDriveReader(
    client_id=os.environ["AZURE_CLIENT_ID"],
    tenant_id=os.environ["AZURE_TENANT_ID"],
    client_secret=os.environ["AZURE_CLIENT_SECRET"],
)

### Target specific folders and restrict MIME types to prevent memory exhaustion
documents = reader.load_data(
    folder_path="KnowledgeBase/Engineering",
    recursive=True,
    mime_types=[
        "application/pdf",
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        "text/plain",
    ],
)

### Chunk extracted documents into retrieval-ready nodes
parser = SentenceSplitter(chunk_size=512, chunk_overlap=64)
nodes = parser.get_nodes_from_documents(documents)
print(f"Extracted {len(documents)} documents into {len(nodes)} indexed text nodes.")

Limiting mime_types is essential. Attempting to parse unindexed media files, executables, or unsupported disk archives causes reader exceptions and wastes network bandwidth.

Why Microsoft Graph Throttling Blocks Ingestion Pipelines

The primary operational challenge when running OneDriveReader against active enterprise directories is Microsoft Graph API throttling. Ingestion pipelines that attempt to load thousands of documents sequentially or in parallel workers quickly hit service protection boundaries.

OneDrive Graph API endpoints enforce request rate limits per user account that trigger exponential backoff on bulk ingestion. Microsoft does not publish static request-per-minute ceilings because throttling thresholds are dynamic; limits scale according to resource consumption units, overall tenant activity, and concurrent connection counts.

When an ingestion script exceeds these dynamic limits, Microsoft Graph halts execution and responds with HTTP status code 429 Too Many Requests (or occasionally 503 Server Too Busy). Critically, the response includes a Retry-After HTTP header specifying the exact duration in seconds that your application must wait before retrying:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 28

Ignoring the Retry-After header and continuing to hammer Microsoft Graph endpoints prolongs the throttling window and can temporarily suspend API access for the entire application principal across the tenant. As detailed in the official Microsoft Graph throttling documentation, backing off requests using the specified delay is mandatory to recover from throttling because resource tracking continues while a client is being throttled.

To handle these failures in custom Python extraction scripts, you must implement retry handlers that inspect the Retry-After header and apply exponential backoff with randomized jitter:

import time
import random
import requests

def fetch_graph_item_with_backoff(url: str, headers: dict, max_retries: int = 5):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)
        
        if response.status_code == 200:
            return response.json()
        
        if response.status_code in (429, 503):
            ### Respect Microsoft Graph Retry-After header if present
            retry_after = response.headers.get("Retry-After")
            if retry_after:
                wait_time = int(retry_after)
            else:
                ### Exponential backoff with jitter fallback
                wait_time = (2 ** attempt) + random.uniform(0.5, 1.5)
            
            time.sleep(wait_time)
            continue
        
        response.raise_for_status()
    
    raise RuntimeError(f"Max retries exceeded for endpoint: {url}")

Beyond HTTP throttling, direct bulk extraction creates an architectural synchronization deficit. OneDriveReader does not maintain a state database of previously parsed files. Running an ingestion pipeline on a nightly schedule re-traverses the entire folder hierarchy, re-downloads all files, and re-embeds text that has not changed. While Microsoft Graph provides a Delta Query API (/delta) to track additions and modifications, wiring custom delta synchronization into LlamaIndex requires writing and maintaining an external state tracking layer.

Bypassing Bulk Extraction with Remote Workspace Indexing

For engineering teams managing large document collections, pulling entire file archives across Microsoft Graph into local memory is an inefficient way to power retrieval. The alternative architecture decouples your underlying cloud storage from the AI pipeline by pairing scheduled workspace synchronization with remote search.

In this model, your team keeps their existing file storage exactly where it lives today in OneDrive, Google Drive, Dropbox, Box, or SharePoint. Cloud Sync connects Google Drive, Dropbox, Box and OneDrive folders to a workspace, one-way or two-way, on a schedule or on demand. SharePoint document libraries synchronize directly through the OneDrive connector. Because synchronization runs on a schedule or on demand rather than requiring continuous manual downloads, your document repository updates predictably without exhausting client memory.

Once synchronized into Fast.io workspaces, workspace intelligence indexes files automatically for hybrid search. Hybrid search combines full-text keyword indexing, semantic vector matching, and search-by-metadata-value. Documents are parsed and indexed on arrival, eliminating the need to stand up separate vector databases, chunking workers, or embedding pipelines. Every search query returns matching text excerpts accompanied by source document citations.

Instead of building brittle Graph API ingestion scripts in Python, your AI agents and LlamaIndex applications query the workspace through a remote Model Context Protocol (MCP) server. Teams building agent pipelines use storage for agents to connect directly over Streamable HTTP:

  • https://mcp.fast.io/mcp/tools for Claude desktop and general applications
  • https://mcp.fast.io/mcp/code for coding agents and developer environments
  • https://mcp.fast.io/mcp/operations for custom ChatGPT and Codex connectors

Comprehensive setup instructions for each client are documented at https://mcp.fast.io/docs.

Decoupling storage from ingestion also delivers measurable latency and cost advantages. In independent performance evaluations across cloud storage connectors, Fast.io was measured the fastest and lowest cost provider tested in the published connector benchmark at https://fast.io/benchmarks/. Rather than transmitting entire raw document files over HTTP to be chunked in client RAM, an AI agent issues lightweight semantic search queries against the pre-indexed workspace, retrieving only the exact passages required to answer the prompt.

Workspaces are shared and organization-owned, supporting role-based permissions set per organization, workspace, and share. Monthly plans start with a 14-day free trial, which requires a credit card.

Plan Tier Monthly Price Included Seats Storage Allowance Monthly Credits
Starter $9.99/mo 3 seats 250 GB 100,000 credits
Business $49.99/mo 10 seats 5 TB 600,000 credits
Enterprise $199.99/mo 30 seats 25 TB 3,000,000 credits

Storage beyond plan allowances is 1.5 cents per GB a month, and extra bandwidth is 4 cents per GB. Credits meter AI operations, with overage options detailed on the Fast.io pricing page.

Vector indexing and semantic search architecture for workspace files
Fastio features

Connect OneDrive files to your AI pipelines without Graph API throttling

Sync your OneDrive folders into a shared workspace with built-in indexing and search over the remote MCP server. Monthly plans start with a 14-day free trial.

When to Choose Workspace Indexing Over Direct Ingestion

When designing a production RAG system that interfaces with enterprise storage, select your ingestion strategy based on collection scale, update frequency, and agent access patterns.

For small, static document folders (fewer than fifty files) maintained by a single user, OneDriveReader provides a quick path to extract text directly into a local LlamaIndex vector store index. When adopting this pattern, apply the following practices:

  1. Target Specific Subfolders: Never point OneDriveReader at the drive root. Narrow the folder_path or provide specific file_ids to keep the API payload small.
  2. Strict MIME Filtering: Always define mime_types explicitly. Avoid passing generic binary objects or spreadsheets with thousands of empty rows to local document parsers.
  3. Local Embedding Persistence: Save generated vector embeddings to disk using ChromaDB or a local directory index immediately after generation so you never re-download identical files after process restarts.

For enterprise teams, dynamic document libraries, and multi-agent systems, replacing bulk Graph downloads with remote workspace search resolves both throttling and memory overhead. Instead of pulling raw files, your LlamaIndex pipeline treats the workspace as an external knowledge retrieval service.

Here is how a LlamaIndex application queries a pre-indexed Fast.io workspace using standard HTTP requests:

import os
import requests

def query_workspace_knowledge(
    workspace_id: str,
    query_text: str,
    api_key: str,
    top_k: int = 5
) -> list[dict]:
    """
    Queries pre-indexed workspace documents via unified storage search,
    retrieving semantic matches without downloading raw files.
    """
    url = f"https://api.fast.io/current/workspace/{workspace_id}/storage/search/"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    params = {
        "search": query_text,
        "limit": top_k,
    }
    
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()
    
    results = response.json().get("results", [])
    return [
        {
            "file_name": item.get("name"),
            "snippet": item.get("snippet"),
            "score": item.get("score"),
            "file_id": item.get("id"),
        }
        for item in results
    ]

### Execute targeted semantic search against synchronized OneDrive files
matches = query_workspace_knowledge(
    workspace_id=os.environ["FASTIO_WORKSPACE_ID"],
    query_text="What are the compliance requirements for cloud data retention?",
    api_key=os.environ["FASTIO_API_KEY"],
)

for match in matches:
    print(f"[{match['file_name']}] (Score: {match['score']}): {match['snippet']}")

When structured document data is required alongside semantic text search, you can layer in Metadata Views. Metadata Views turn unstructured documents into live, queryable database spreadsheets. You describe the target fields in natural language, and AI populates typed schema columns (Text, Integer, Decimal, Boolean, Date & Time, URL, JSON) without manual regex or OCR templates.

Finally, governance is maintained automatically. The workspace tracks every change in a detailed activity log recording uploads, edits, moves, and deletions, while per-file version history preserves prior revisions during concurrent team edits. This keeps document retrieval accurate, auditable, and decoupled from client-side API throttling.

Sources

References used to verify factual claims in this guide.

  1. Microsoft Graph returns an HTTP 429 error code on throttled requests and provides a Retry-After delay header to govern client recovery.

Frequently Asked Questions

How do I configure OneDriveReader in LlamaIndex?

Install the llama-index-readers-microsoft-onedrive package, register an application in Microsoft Entra ID with Files.Read.All permissions, and instantiate OneDriveReader with your client_id, tenant_id, and client_secret. Then call reader.load_data() with a targeted folder_path and specified mime_types to extract files into LlamaIndex Document nodes.

What permissions are needed to read OneDrive files in LlamaIndex?

For unattended background pipelines, OneDriveReader requires Application permissions for Files.Read.All, which allows silent authentication using client credentials but requires Microsoft 365 tenant administrator consent. For interactive user scripts, Delegated permissions (Files.Read or Files.Read.All) can be used with an interactive browser login and localhost redirect URI.

How do I prevent Microsoft Graph throttling when loading OneDrive documents?

To avoid HTTP 429 Too Many Requests errors, inspect the Retry-After header on throttled responses, implement exponential backoff with randomized jitter, avoid aggressive multithreaded downloads, and filter by specific subfolders. For large repositories, sync folders into an indexed workspace on a schedule so agents query pre-indexed text instead of downloading raw files.

Can OneDriveReader load personal OneDrive files with a client secret?

No. Microsoft Graph does not support application permissions or client secret authentication for personal Microsoft accounts. Personal OneDrive accounts require delegated authentication with interactive browser sign-in and tenant_id set to consumers. Application permissions with client credentials flow are supported only on OneDrive for Business and Microsoft 365 enterprise tenants.

How does Fast.io Cloud Sync connect to OneDrive and SharePoint?

Cloud Sync connects Google Drive, Dropbox, Box and OneDrive folders to a workspace, one-way or two-way, on a schedule or on demand. SharePoint document libraries connect through the OneDrive connector. Once synced, workspace Intelligence Mode automatically indexes the files for hybrid full-text and semantic search, allowing agents to query context over the remote MCP server.

Related Resources

Fastio features

Connect OneDrive files to your AI pipelines without Graph API throttling

Sync your OneDrive folders into a shared workspace with built-in indexing and search over the remote MCP server. Monthly plans start with a 14-day free trial.