ms365-mcp
ms365-mcp
小型ローカルモデル向けにサイズ調整されたMicrosoft 365 MCPサーバー。
ほとんどのMCPサーバーは、大きなコンテキストウィンドウを持つフロンティアモデル向けに構築されており、ベンダーAPIが提供するすべてを公開して、モデルに整理させる方式を取っています。Microsoft 365のリファレンスサーバーは、MicrosoftのGraph OpenAPI仕様から生成された326個のツールを公開しています。
しかし、これは8kコンテキストの8Bモデルには機能しません。ツールリスト全体がシステムプロンプトに収まり、モデルは25個を超えたあたりからランダムに選択し始めます。このサーバーは逆のアプローチを取ります:
手書きの14個のツール。上限は20個に固定されています。ツールリストは予算であり、機能リストではありません。
小型モデル向けに書かれた説明。APIメタデータから流用したものではありません。
下書き優先。 他の人に送信できるツールは正確に1つだけであり、受信者ではなく下書きIDを受け取り、破壊的と注釈付けされています。
すべてのツールが自身の効果を宣言します。MCPの
readOnlyHintおよびdestructiveHint注釈を通じて、ホストがツール名から推測することなく分類できるようにします。
Edge Harness向けに構築されており、任意のMCPクライアントで利用できます。
ステータス
初期段階。まだ使用できません。 計画は10コミットです。完全な順序と各決定の根拠についてはdocs/PLAN.mdを参照してください。
スキャフォールド、ライセンス、CI | 完了 |
stdio上のMCPプロトコル | 完了 |
14ツールのサーフェス | 宣言済み、ハンドラーはスタブ |
サインイン | 未開始 |
Microsoft Graph | 未開始 |
Related MCP server: google-nice-mcp
ツールサーフェスの確認
--list-toolsは何も起動せず、アカウントも不要なので、「ホストには何が提供されるのか?」という問いに、何も配線される前に答えます:
.venv/bin/python -m ms365_mcp --list-tools機械可読なバージョンには--jsonを追加します。
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 (!)今日のハンドラーはスタブです。呼び出しは、ツールが宣言されているが実装されていないと述べる文を返します。サーフェスは、構築される前に意図的に固定されています。ツール名、説明、効果クラスは、ホストが分類し、モデルがプロンプトで参照するものであり、後で変更するのはコストがかかるからです。
Edge Harnessからの使用
ハーネスはこのサーバーをstdio上のサブプロセスとして起動するため、独自のインタープリターで実行され、ホストと依存関係を共有しません。これは偶然ではありません。ハーネスにはmcp/というローカルパッケージがあり、PyPI上の公式SDKもmcpと呼ばれているため、このサーバーをハーネスのvirtualenvにインストールすると、ハーネス自身のパッケージをシャドウしてしまいます。
そこでのレジストリエントリはms365-ownであり、Agent Labの実行オプションでCheckを押すと、すべてのツールがその効果クラスとともにリストされます。14個すべてがdeclaredとして分類されます。つまり、ハーネスはツール名から推測するのではなく、このサーバーの注釈からそれらを取得しており、エントリにオーバーライドは不要です。
ハーネスのデフォルトの下書きモードでは、send_draftは保留され、他の13個が利用可能であるため、実行が人に到達することはありません。
セキュリティ
このリポジトリは公開されており、いかなる種類の資格情報も保持していません。
認証にはMicrosoftデバイスコードフローを使用します。結果のトークンキャッシュは、オペレーティングシステムの設定ディレクトリに所有者のみの権限で書き込まれ、このリポジトリやその作業ツリーには決して書き込まれません。.gitignoreはとにかくトークンとキャッシュのファイル名をカバーし、pre-commitフックはステージングされた変更を資格情報の形をした文字列についてスキャンするため、コミットするにはうっかりではなく意図的な努力が必要です。
# pragma: allowlist secretで終わる行はフックによってスキップされます。これは、このリポジトリ自身のテストが偽の資格情報を含むことができるように存在しており、--no-verifyではできない、レビューアーが差分で見ることができるマーカーを残します。証明可能に偽のデータにのみ使用してください。
開発
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest -qクローンごとに一度、シークレットスキャンフックを有効にします:
git config core.hooksPath .githooksライセンス
MIT。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.
14 tool updates
v0.1.0- First observed
cancel_event - First observed
create_draft - First observed
create_event - First observed
find_free_time - First observed
get_event - First observed
get_message - First observed
list_events - First observed
list_folders - First observed
list_messages - First observed
reply_draft - First observed
resolve_person - First observed
send_draft - First observed
update_event - First observed
whoami
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