What this guide covers
How the CoreConduit platform bridges Microsoft 365 (where nonprofit staff live) with local AI (where their data stays private). This isn't a generic Graph API tutorial — it's the actual integration pattern used to solve the MS Forms Graph API gap, connect Power Automate to local endpoints, and build automation workflows that respect data sovereignty.
Nonprofit organizations overwhelmingly use Microsoft 365. It's free or deeply discounted through Microsoft's nonprofit program, it's what staff already know, and it handles email, documents, forms, and collaboration. When CoreConduit consults with a nonprofit, M365 is almost always the starting point.
But there's a tension: M365 is a cloud platform. The CoreConduit AI stack is local — Ollama running on a Pi 5, no data leaving the building. The integration problem is: how do you get data from M365 into local AI without breaking the data sovereignty model?
The answer is a one-way bridge: data flows from M365 to local AI for processing. Results stay local. Nothing gets uploaded to Azure OpenAI, Copilot, or any third-party AI service.
Microsoft Forms is heavily used by nonprofits — volunteer sign-ups, client intake, program applications, feedback surveys. But as of May 2026, MS Forms still has no Microsoft Graph API endpoint for retrieving form responses. You cannot call GET /v1.0/me/forms/{id}/responses — it doesn't exist.
This is the API gap that shaped the entire integration architecture. Since Graph API can't pull form responses, the data has to be pushed. Power Automate is the push mechanism:
Power Automate flow triggers on "When a new response is submitted" in MS Forms. No polling, no scheduled jobs — event-driven from the M365 side.
The flow calls "Get response details" to unpack the form data into structured fields. At this point the data is in Power Automate's memory — still within the M365 tenant.
The flow sends an HTTP POST with the structured form data to a local endpoint. If the Pi 5 is on the same LAN or reachable via reverse proxy, the data arrives as JSON. If the Pi is offline, the flow queues the request or falls back to storing the response in a SharePoint list for later sync.
The local endpoint validates the payload, stores it if needed, and routes it to the appropriate AI pipeline — maybe Ollama for summarization, ChromaDB for semantic indexing, or a NEXUS agent for multi-step workflow automation. The LLM never sees the internet. The internet never sees the LLM's output.
There are two patterns depending on how your network is set up. Both are used in production at CoreConduit depending on the client.
Power Automate posts directly to the Pi on the local network.
Power Automate writes to a SharePoint list; the Pi pulls on schedule.
The local endpoint needs to accept data from Power Automate without exposing the Pi to the open internet or hard-coding credentials in Power Automate flows.
Current approach: shared secret in HTTP header. Power Automate includes a long random token in an X-API-Key header. The local endpoint (Flask or Apache mod_rewrite) validates it before accepting the payload. The token lives in the Pi's .env file and in Power Automate's environment variables — neither is in source control.
For higher-security deployments, the recommended upgrade path is mTLS (mutual TLS) where the Pi presents a client certificate and Power Automate validates it. Not yet implemented in production — the shared secret model has been sufficient for nonprofit form data, which is sensitive but not regulated (no HIPAA, no PCI).
Here's a concrete example running in production for a nonprofit client:
| Stage | System | Action |
|---|---|---|
| 1. Sign-up | MS Forms | Volunteer fills out intake form (skills, availability, background) |
| 2. Trigger | Power Automate | Form submission fires flow |
| 3. Enrich | Graph API | Flow checks if person exists in org directory; pulls manager info |
| 4. Deliver | HTTP POST | Structured volunteer record sent to local CoreConduit endpoint |
| 5. Classify | Ollama (qwen3:4b) | LLM classifies volunteer by program area, flags special skills |
| 6. Index | ChromaDB | Volunteer profile embedded and indexed for semantic search |
| 7. Respond | Outlook (Graph API) | Local service calls back to M365 to send personalized welcome email |
The key point: the volunteer's personal story, skills, and background never touch Azure OpenAI. The LLM classification happens on the Pi. Only the final email goes back through Microsoft's servers because that's where the nonprofit's email lives.
Beyond the Power Automate bridge, the CoreConduit platform uses Microsoft Graph API for these specific operations:
/v1.0/users for role-based access control in local tools.All Graph API calls originate from the Pi side (outbound), use app-only authentication (client credentials grant), and have scoped permissions — typically Sites.Read.All, User.Read.All, Calendars.Read. No admin consent for write operations unless the workflow specifically needs it (like sending email).
The philosophy
This integration exists because nonprofits don't have to choose between "use M365" and "keep your data private." The CoreConduit approach is: let M365 be M365 — the collaboration layer people already know. And let the AI be yours — running on hardware you control, processing data that never leaves your network unless you explicitly send it back. The bridge makes these two worlds interoperate without either one owning the other.
The complete system map — hardware, services, AI stack, tooling, and how everything communicates on a single Raspberry Pi 5.
Nonprofit · Privacy · CommunicationsUsing local LLMs to draft donor communications, impact reports, and grant narratives — practical workflows for the data that flows through this integration.