Skip to content

[ADD] ms365: read shared O365 documents (Graph Shares + text extraction)#185

Open
beorngb wants to merge 8 commits into
mainfrom
feat/ms365-shared-documents
Open

[ADD] ms365: read shared O365 documents (Graph Shares + text extraction)#185
beorngb wants to merge 8 commits into
mainfrom
feat/ms365-shared-documents

Conversation

@beorngb

@beorngb beorngb commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Extends the ms365 MCP plugin to read Office 365 documents shared with the
account
— the case the existing tools couldn't reach (they only read files by
known SharePoint site_id + file_path or the user's own OneDrive).

New tools

  • m365_read_shared(sharing_url | drive_id+item_id) — reads a shared document by
    share link (from email) or by an item from m365_list_shared. Resolves via the
    Graph Shares API (/shares/{shareId}/driveItem) or /drives/{id}/items/{id},
    then returns extracted text. Works cross-tenant with the recipient's own
    delegated token — no app in the sharer's tenant needed.
  • m365_list_shared() — lists "Shared with me" (/me/drive/sharedWithMe),
    paginated (cap 200 items / 5 pages, truncated flag), returning
    drive_id/item_id to pass to m365_read_shared.

Also

  • New plugins/ms365/extract.py: extract_text (docx/xlsx/pdf/text via
    python-docx/openpyxl/pypdf) and encode_sharing_url (Graph shareId).
  • m365_read_file/m365_read_drive_file now extract Office text on binary
    content instead of returning "Binary file" — text files still decode as before
    (utf-8-first).
  • Content read is robust: resolve item metadata → fetch the pre-authenticated
    @microsoft.graph.downloadUrl with no auth header (avoids leaking the Graph
    bearer to the storage host), streamed with a 50 MB size guard; folders and
    missing-downloadUrl items are guarded with clear errors.
  • Deps declared in the manifest and the ms365 pyproject extra.

Only the MCP-server path (server.py) is touched; the legacy in-process tag path
is untouched.

Tests — 35 unit tests (tests/unit/plugins/ms365/): extraction (all formats

  • empty/unsupported/corrupt/truncation/uppercase-ext), share-URL encoding,
    pagination, input contract, folder/size guards, error mapping. Repo-wide unit
    suite green.

Runtime prerequisite (not in this PR) — the plugin is currently unconfigured
(no Azure app client_id in its DB config), so this is not yet live-verifiable.
To enable: register/point the Azure AD app, grant the Files.Read.All delegated
permission with admin consent, re-authenticate the account(s) via the OAuth flow,
then confirm end-to-end.

Follow-ups (non-blocking)

  • m365_read_shared does not update the "current file" continuity state that
    read_file/read_drive_file feed.
  • context.py tool docs are on the legacy path and don't reach the live MCP
    system prompt (agents learn the tools from the Tool() schemas).
  • openpyxl/pypdf/python-docx are duplicated between the data and ms365
    pyproject extras (harmless).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant