ms365-mcp
ms365-mcp
Ein Microsoft 365 MCP-Server, zugeschnitten auf kleine lokale Modelle.
Die meisten MCP-Server sind für Spitzenmodelle mit großen Kontextfenstern gebaut, daher exponieren sie alles, was die Anbieter-API bietet, und überlassen dem Modell die Auswahl. Der Referenz-Microsoft-365-Server stellt 326 Tools bereit, die aus Microsofts Graph-OpenAPI-Spezifikation generiert wurden.
Das funktioniert nicht für ein 8B-Modell bei 8k Kontext, wo die gesamte Tool-Liste im System-Prompt sitzt und das Modell irgendwo nach fünfundzwanzig Tools zufällig zu wählen beginnt. Dieser Server verfolgt den gegenteiligen Ansatz:
Vierzehn handgeschriebene Tools, mit einer harten Obergrenze von zwanzig. Die Tool-Liste ist ein Budget, keine Feature-Liste.
Beschreibungen, die für ein kleines Modell geschrieben sind, nicht aus API-Metadaten übernommen.
Draft-first. Genau ein Tool kann an eine andere Person übertragen, es nimmt eine Draft-ID statt eines Empfängers und ist als destruktiv annotiert.
Jedes Tool deklariert seine eigene Wirkung über MCP-
readOnlyHint- unddestructiveHint-Annotationen, sodass ein Host es klassifizieren kann, ohne aus dem Tool-Namen zu raten.
Gebaut für den Edge Harness und nützlich für jeden MCP-Client.
Status
Früh. Noch nicht nutzbar. Der Plan umfasst zehn Commits; siehe docs/PLAN.md für die vollständige Abfolge und die Begründung hinter jeder Entscheidung.
Gerüst, Lizenz, CI | erledigt |
MCP-Protokoll über stdio | erledigt |
Die Vierzehn-Tool-Oberfläche | deklariert, Handler sind Stubs |
Anmeldung | nicht begonnen |
Microsoft Graph | nicht begonnen |
Related MCP server: google-nice-mcp
Seeing the tool surface
--list-tools startet nichts und benötigt kein Konto, also beantwortet es die Frage „Was würde einem Host angeboten?“, bevor irgendetwas davon verdrahtet ist:
.venv/bin/python -m ms365_mcp --list-toolsFügen Sie --json für eine maschinenlesbare Version hinzu.
read whoami Return the display name, email address and timezone…
read resolve_person Look up a person by name or partial name and return…
read list_messages List messages in a mail folder, newest first, as se…
write create_draft Create a draft message. This does NOT send anything…
! write send_draft Send a draft that already exists, by its id. This r…
...
14 tools, 6 that change something, 4 marked destructive (!)Handler sind heute Stubs: Ein Aufruf gibt einen Satz zurück, der besagt, dass das Tool deklariert, aber nicht implementiert ist. Die Oberfläche wird bewusst festgelegt, bevor irgendetwas davon gebaut wird, denn die Tool-Namen, Beschreibungen und Effektklassen sind das, was ein Host klassifiziert und wogegen ein Modell gepromptet wird, und diese später zu ändern ist teuer.
Using it from the Edge Harness
Der Harness startet diesen Server als Subprozess über stdio, sodass er unter seiner eigenen Interpreter läuft und keine Abhängigkeiten mit dem Host teilt. Das ist nicht zufällig: Der Harness hat ein lokales Paket namens mcp/ und das offizielle SDK auf PyPI heißt ebenfalls mcp, sodass die Installation dieses Servers in die Virtualenv des Harness das eigene Paket des Harness überschattet.
Sein Registrierungseintrag dort ist ms365-own, und das Drücken von Check in den Agent-Lab-Laufoptionen listet jedes Tool mit seiner Effektklasse auf. Alle vierzehn klassifizieren als declared, was bedeutet, dass der Harness sie aus den Annotationen dieses Servers übernommen hat, anstatt aus Tool-Namen zu raten, und der Eintrag benötigt keine Überschreibungen.
Im Standard-Entwurfsmodus des Harness wird send_draft zurückgehalten und die anderen dreizehn sind verfügbar, sodass ein Lauf keine Person erreichen kann.
Security
Dieses Repository ist öffentlich und enthält keinerlei Anmeldeinformationen.
Die Authentifizierung verwendet den Microsoft-Gerätecode-Flow. Der resultierende Token-Cache wird in das Konfigurationsverzeichnis des Betriebssystems mit Berechtigungen nur für den Besitzer geschrieben, niemals in dieses Repository oder seinen Arbeitsbaum. .gitignore deckt Token- und Cache-Dateinamen ohnehin ab, und ein Pre-Commit-Hook scannt zum Commit vorgemerkte Änderungen auf Zeichenfolgen, die wie Anmeldeinformationen aussehen, sodass das Committen einer solchen bewusste Anstrengung erfordert und kein Ausrutscher ist.
Eine Zeile, die mit # pragma: allowlist secret endet, wird vom Hook übersprungen. Das existiert, damit die eigenen Tests dieses Repositorys gefälschte Anmeldeinformationen enthalten können, und es hinterlässt eine Markierung, die ein Prüfer im Diff sehen kann, was --no-verify nicht tut. Verwenden Sie es nur für Daten, die nachweislich gefälscht sind.
Development
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest -qAktivieren Sie den Secret-Scan-Hook einmal pro Klon:
git config core.hooksPath .githooksLicence
MIT. Siehe LICENSE.
Available Tools
14 toolscancel_eventCancel an eventADestructive
Cancel an event and notify every attendee. This CANNOT be undone. Read the event with get_event first and be sure it is the right one.
Inputs: event_id (required), message.
create_draftDraft a messageA
Create a draft message. This does NOT send anything: it leaves a draft a person can read and change. Get every recipient address from resolve_person first. Returns a draft id, which send_draft takes if the message is later approved.
Inputs: to (required), body (required), subject (required).
create_eventCreate an eventADestructive
Create a calendar event. If it has attendees, they are invited, which reaches real people, so get their addresses from resolve_person and check the slot with find_free_time first.
Inputs: end (required), start (required), subject (required), location, +1 more.
find_free_timeFind a free slotARead-only
Find open slots of a given length on a date, respecting existing events and working hours. Use this instead of reading the calendar and working out the gaps yourself, which is where arithmetic mistakes turn into double bookings.
Inputs: date (required), minutes.
get_eventRead an eventARead-only
Read one calendar event in full, including its body and the response status of each attendee, by the id list_events returned.
Inputs: event_id (required).
get_messageRead a messageARead-only
Read one message in full, including its body, by the id that list_messages returned. Read the message before replying to it or summarising it; a reply written from the subject line alone invents its own content.
Inputs: message_id (required).
list_eventsList calendar eventsARead-only
List calendar events between two dates, with subject, start, end, location, attendees and id. Dates are YYYY-MM-DD in the account's own timezone. Check the calendar before booking anything, so a new event does not land on top of an existing one.
Inputs: end_date (required), start_date (required).
list_foldersList mail foldersARead-only
List the mail folders on this account with their names and message counts. Use it when a task names a folder you have not seen, rather than guessing that it exists.
Inputs: no named parameters.
list_messagesList mailARead-only
List messages in a mail folder, newest first, as sender, subject, date and id. Bodies are not included; use get_message with an id to read one. Defaults to the inbox and to 10 messages.
Inputs: top, folder, search.
reply_draftDraft a replyA
Create a draft reply to an existing message, keeping its thread and recipients. Does NOT send. Read the message with get_message first, so the reply answers what was actually asked.
Inputs: body (required), message_id (required), reply_all.
resolve_personFind someone's addressARead-only
Look up a person by name or partial name and return their real email address. ALWAYS use this before addressing a message or inviting someone. Never type an email address you were not given. If this returns more than one person, ask which one rather than picking.
Inputs: name (required).
send_draftSend a draftADestructive
Send a draft that already exists, by its id. This reaches a real person and CANNOT be undone. There is deliberately no way to write and send in one step: create the draft, check it is right, then send it.
Inputs: draft_id (required).
update_eventChange an eventADestructive
Change the time, subject or location of an existing event. Attendees are notified. Only the fields you pass are changed. Read the event with get_event first, so you are not overwriting something you have not seen.
Inputs: event_id (required), end, start, subject, +1 more.
whoamiWho am IARead-only
Return the display name, email address and timezone of the signed-in account. Call this when the task says 'me', 'my' or 'I' and you need the actual address, rather than guessing it.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 14 tools
Each tool targets a distinct resource and action: identity, people lookup, mail read/draft/send, and calendar read/find/write. The only close pair, create_draft and reply_draft, is clearly separated by new-vs-reply intent.
Almost all tools follow a consistent verb_noun pattern (list_messages, create_draft, cancel_event). The lone exception is whoami, which is a conventional single-word command but breaks the otherwise uniform pattern.
14 tools is a well-scoped size for a mail-plus-calendar server. Each tool covers a necessary step in reading, creating, and sending mail or managing calendar events, with no redundant utilities.
Calendar coverage is complete with list/get/find/create/update/cancel, and mail covers read, draft, reply-draft, and send. Minor gaps such as updating/deleting drafts or searching messages exist, but agents can work around them with the provided tools.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
One MCP server for the services your AI needs: memory, files, Microsoft 365, kanban and more.
Hosted MCP endpoint with realistic fake data for prototyping agents. 12 tools, no setup.
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA production-ready MCP server that provides secure, delegated access to Microsoft 365 services including Email, SharePoint, OneDrive, and Calendar. It enables AI models to search messages, browse files, manage calendar events, and parse document contents using OAuth 2.1 authentication.MIT
- AlicenseAqualityDmaintenanceA read-only MCP server for Gmail and Drive with only 5 tools, designed to be friendly to small local LLMs by minimizing context usage and simplifying inputs.5MIT
- AlicenseBqualityDmaintenanceLightweight MCP server that enables AI agents to manage Microsoft Outlook email, calendar, and files using PKCE authentication with only a Client ID.46MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that exposes a Microsoft 365 mailbox via the Model Context Protocol, enabling AI assistants to search, read, and download emails and attachments, and optionally send mail.6 npmMIT