Giving the AI hands
Outlook write access via the Lokka MCP server
April – May 2026 · ~3 weeks stuck · 1 breakthrough session
← carried in A talk on TDD at a Dallas AI meetup
→ carried forward Red→green test protocol
→ carried forward The runbook habit
Giving an AI agent real hands: send and draft email, write files, manage a calendar — in a sandbox Microsoft 365 account built for exactly this.
Timeline: roughly three weeks of on-and-off failure in April–early May 2026 (my recollection), one breakthrough session on May 8 (dated in my notes), then four more days to full capability by May 12 (timestamped test logs). Actual hours: unknown. The logs record sessions and dates, not effort.
What it is
The Microsoft 365 connector that ships with my AI tools is read-only. It can read email; it cannot draft or send. Lokka is a separate open-source MCP server that runs on my machine and adds the write half — email, OneDrive files, Excel cells, calendar. Every agent I've built since runs on this plumbing.
Why it mattered
Every workflow I tried to build dead-ended one step before the useful part. A resume-sorting agent that can't send an outreach email isn't an agent, it's a report. I wanted the last step.
The walls
This took three weeks, and almost none of it was about AI. It was Windows, file encoding, and Microsoft licensing.
Personal accounts don't work. The connector requires a work or school Microsoft account, and my personal one failed with no useful error. I checked the free developer program (didn't qualify) and the student route (didn't qualify), then bought the cheapest business subscription (~$6/month) and stood up a sandbox tenant. A purchase and a detour before the project could even start.
The thumb drive. I was copying the config file between two laptops on a thumb drive. Wrong versions kept overwriting right ones, so fixes I'd already made kept silently disappearing. The config file lives on the machine that runs the thing. Moving it around is how you lose work.
Plain Text vs UTF-8. Notepad saved the config as Plain Text. Claude Desktop won't load it — even with a
.jsonextension, even with perfect contents. No complaint, no error. Save As → UTF-8 fixed it.The backslash problem. JSON wants doubled backslashes in Windows paths. Windows shows single ones. Pasting a normal Windows path into the config produced a parse error on every restart.
Two Notepad tabs. After an app update, two versions of the config ended up open at once. I was saving correct fixes into the wrong tab. This one cost real time and had nothing to do with technology. A meaningful share of "the AI isn't working" is actually "my desk is a mess."
The actual wall: no hammer icon. Credentials correct. JSON correct. Encoding correct. The server even authenticated when I ran it manually from the command prompt. And still no tools appeared in Claude Desktop. No error to chase — just silence. This is where it sat for the long stretch, and it's the demoralizing kind of stuck.
What Wall 6 actually was (I only pieced this together later, from the session records): two things at once. The config file had an extra settings block that broke the parser — so the whole file was being silently ignored. And the credential I'd pasted in was Azure's Secret ID (a GUID you can see anytime) rather than the secret Value (the long random string shown exactly once). The cruelest part: my manual command-prompt test "worked" only because the server silently fell back to browser sign-in and never used the secret at all. The one piece of evidence that looked verified wasn't verifying anything.
The turn
On May 7 I went to a Dallas AI meetup and heard a talk on test-driven development and context engineering. Three things changed the next morning:
- Define success as a verifiable test before touching anything. Mine: send an email, confirm it's in Sent, confirm it lands in my Gmail. Not "does the icon appear" — that's a UI signal, not a result.
- Start a fresh conversation instead of continuing a days-long muddled one that carried every wrong assumption I'd accumulated.
- Point the agent at resources instead of spoon-feeding it my (wrong) conclusions.
With a real test defined, the agent stopped guessing and started working error-to-error. Six fixes later — clean config rebuild, the right secret, the right permission type (Application, not Delegated), a consent button that silently under-granted (fixed with a direct consent URL), a missing redirect URI, and a restart to force a fresh token — the test passed. Email sent, in Sent, received in Gmail.
The moment that changed how I think about agents: I had stored the credentials in an email in the sandbox inbox. I never told the agent where they were. It reasoned they'd probably be in the inbox, went and looked, and found them. Being told an agent "can use tools" is abstract; watching one decide to go check the mail is not. The caveat that belongs right next to that story: storing live credentials in an inbox is against normal security practice. I did it deliberately, in a throwaway sandbox with nothing real in it. It would be wrong anywhere else, and the credential got rotated afterward.
The sequel walls (May 12)
Getting write access working was Act I. Act II was migrating from app-style auth to delegated auth — signing in as me — because app-only auth structurally can't touch "my" OneDrive. Two more walls from that morning's log: adding a permission in the Azure portal does not put it on the token (the client has to request each scope at sign-in — different failure messages taught me that the hard way), and the browser sign-in roundtrip knocked the MCP server offline mid-session (the token survived; the connection didn't). Twenty-four minutes, red to green, and by that afternoon the same setup could read and write individual Excel cells and manage the calendar.
What I'd do differently
Check the account-type requirement first — Wall 1 was discoverable in five minutes of reading, and I found it by failing. Define the test before touching the config — Walls 2 through 6 were all attempts to make a UI signal appear rather than to produce a verifiable result. One config file, one machine, one open editor tab.
What carried forward
The test-first discipline born here became the protocol for everything after it — the Briefing Agent and the Attendance Dashboard were both built red-to-green from the start, and both went dramatically smoother. Fresh threads over marathons, and pointing agents at resources, became how I work generally. And the troubleshooting chain got written down as a reusable roadmap document — the first time I learned that the write-up is part of the build.