How a weekend idea turned into a personal copilot that reads my calendar, triages my inbox, and summarizes my Teams meeting transcripts — all running in a browser tab.
Like most engineering leads, I live inside Outlook and Microsoft Teams. My day is a stream of meetings, transcripts, follow-ups, and emails that all demand attention at once. Teams records the transcripts, Outlook holds the actions, and my brain is the fragile integration layer in between.
So I asked myself a simple question: what if I built my own workspace on top of Microsoft 365 — one that pulls everything I care about into a single screen and puts AI on top of it?
The result is Orbit: a personal workspace app that is literally one HTML file. No backend. No database. No server to maintain. It's hosted free on GitHub Pages, signs me in with my corporate Microsoft account, and talks directly to Microsoft Graph and my own Azure OpenAI deployment — entirely from the browser.
What Orbit does
A live "Today's Rail." My calendar rendered as a vertical timeline with a pulsing now marker that moves through the day. One glance tells me where I am, what's next, and how packed the afternoon looks. Clicking any block opens the meeting's details.
Transcript intelligence. This is the feature that started it all. I pick any Teams meeting from the last two weeks, and Orbit resolves the online meeting through Graph, pulls the VTT transcript, and parses it into clean speaker-labelled dialogue. Then the AI buttons kick in: Summarize gives me discussion points, decisions, and open risks. Action points extracts real commitments grouped by owner. Draft follow-up writes the recap email I used to spend twenty minutes composing after every review call.
Inbox triage. Unread mail on the dashboard, a reading pane, and one-click AI summaries plus reply drafts for any message.
A context-aware copilot. A chat tab that already knows my day — today's agenda, my unread inbox, my role — so I can ask things like "what should I prioritise today?" or "draft a status update based on today's meetings" and get answers grounded in my actual workday.
A daily briefing button. One click every morning: the day in one line, top three priorities, meetings that need prep, and emails waiting on a reply. It's the chief-of-staff I didn't know I could script.
The architecture (or the lack of it)
The most satisfying part of this project is what it doesn't have.
There is no backend. The entire application — UI, auth, Graph calls, transcript parsing, AI orchestration — lives in a single static HTML file. The browser does everything:
- Authentication uses MSAL.js with the auth code + PKCE flow. It's genuine corporate SSO — same account, same MFA, popup once, silent token renewal after. Tokens live in session storage and vanish when the tab closes.
-
Data comes straight from Microsoft Graph:
calendarViewfor the timeline, mail folders for the inbox,onlineMeetingsand the transcripts endpoint for meeting content, presence for the live status dot. - AI is pluggable. I point it at my own Azure OpenAI GPT-4o-mini deployment, so corporate data never leaves our tenant's boundary. The setup page also supports the Anthropic API for personal use.
- Configuration — client ID, tenant ID, AI endpoint — is entered on the login page itself and remembered locally in the browser. The public repository contains zero secrets; anyone reading the code sees an empty shell.
Because everything is delegated permissions, the security model is beautifully simple: Orbit can only ever see what I can already see. If a colleague opened my URL and signed in, they'd get their mailbox, their calendar — never mine. There's nothing shared to leak because there's nothing stored anywhere.
The bumps along the way (so you don't hit them)
No project ships without a few humbling moments.
The CDN that didn't exist. My first deployment greeted me with msal is not defined. The script tag pointed at cdnjs — which, it turns out, doesn't host msal-browser at all. Only Microsoft's CDN, jsDelivr and unpkg do. The fix was a one-line swap to jsDelivr with an unpkg fallback. Lesson: verify your CDN actually serves the library before blaming your code.
GitHub Pages and the 404. Publishing the repo isn't enough — Pages looks for index.html at the root. Either use the full file path in the URL or rename the file. And whatever URL you settle on must exactly match the SPA redirect URI in your app registration, trailing slash and all.
The admin consent maze. This one deserves its own paragraph. My tenant, like most enterprises, disables user self-consent. That means the "Admin consent required: No" column in the Entra portal is misleading — it shows Microsoft's default, not your organization's policy. Even innocent read-only scopes like Calendars.Read triggered the dreaded "Need admin approval" wall. And consent matching is literal: having Mail.ReadWrite granted doesn't cover a request for Mail.Read — the exact scope string must be consented. The fix is adding each delegated permission the app requests and clicking Grant admin consent so every row shows a green tick.
Designing for consent friction. Knowing that OnlineMeetingTranscript.Read.All needs admin consent, I built the app to request it lazily — only when someone actually clicks "Load transcript." Login and ninety percent of the app work with just the basic read scopes. Incremental consent is a genuinely underrated pattern for personal tooling in enterprise tenants.
What I learned
The browser is a legitimate application platform for enterprise tooling. With MSAL, Graph, and a static host, a single HTML file can deliver what would traditionally be a full-stack project with a server, a token store, and an ops burden. For personal productivity tools, zero-backend is not a compromise — it's the superior architecture: the smallest possible attack surface and nothing to maintain.
Microsoft Graph is deeper than most people realize. Everyone knows it does mail and calendar. Fewer people know you can resolve a Teams meeting from its join link and pull the full transcript as VTT — which turns every recorded meeting into raw material for AI.
AI is most valuable when it sits inside your workflow, not beside it. I already had access to chatbots. The difference here is context: the model receives my actual transcript, my actual inbox, my actual agenda. The output isn't generic advice — it's my follow-up email, my action register, my morning briefing.
Enterprise identity is where side projects go to be humbled. The code took an evening. Understanding redirect URIs, SPA platforms, consent policies, and scope matching took just as long. If you build anything on Entra, budget time for identity — it is the project.
What's next
Orbit is a foundation, and the roadmap writes itself: an action-point ledger that tracks commitments across meetings and flags the ones that keep slipping; a weekly digest that reads all my transcripts and drafts my Friday status update; one-click sending of follow-up emails via Graph; a PWA manifest so it installs on my phone like a native app; and — since I already run Azure Translator for our internal platforms — multilingual transcript summaries.
But even in its first version, Orbit has changed the shape of my day. The twenty minutes after every meeting that used to go into writing minutes now takes one click. The morning inbox scan takes one button. My calendar finally looks like time instead of a list.
One HTML file. One weekend. One orbit.
If you live in Outlook and Teams and have ever wished your tools understood your day — build your own. The APIs are all there waiting. Happy to share notes if you're attempting something similar.
Top comments (0)