Repository navigation
Releases
v0.2.7
Fixes the CI failure on Windows.
The server.json validator added in v0.2.6 printed Japanese and crashed on Windows consoles using cp1252 — the same bug already fixed in the smoke test and the login script, reintroduced in a new file. UTF-8 console handling now lives in one module that takes effect on import, so a new script cannot forget it.
The published container image and registry entry were unaffected. The validator is a development and CI script; it is not part of the server. Only the CI badge was red.
No change to any tool. 80 unit tests plus the stdio smoke test, green on Linux, macOS and Windows against Python 3.10 and 3.13.
v0.2.6
This release is now listed in the official MCP Registry as io.github.ma2no4413/outlook-mcp, and a container image is published to GHCR on every version tag.
Installing from the container image
docker run -i --rm \
-e OUTLOOK_CLIENT_ID=<your-id> \
-v outlook-mcp-token:/app/data \
-e OUTLOOK_TOKEN_CACHE=/app/data/token_cache.json \
ghcr.io/ma2no4413/outlook-mcp:0.2.6Running the Python source directly is still the simpler path for everyday use — see the README.
What changed
server.jsondeclares the server, its OCI package and its four environment variables, with the token cache marked as secret.- The
Dockerfilecarries anio.modelcontextprotocol.server.namelabel. The registry verifies image ownership by matching that label against the name inserver.json. - A GitHub Actions workflow pushes the image to GHCR and publishes to the registry on each
v*tag, authenticating to GHCR withGITHUB_TOKENand to the registry with OIDC. No repository secrets are involved. validate_server_json.pyruns in CI. Publishing only happens after a tag is pushed, so a rejectedserver.jsonmeans deleting the tag and starting over — which is exactly what happened on the first attempt here, when the description exceeded the registry's 100-character limit. The validator also checks that the Dockerfile label, the image tag,server.jsonandoutlook_server.__version__all agree, since those drifting apart had caused repeated version mismatches.
No change to any tool. 80 unit tests plus the stdio smoke test.
v0.2.5
Corrects the destructive annotation on mark_read_by_search.
Glama's tool evaluation flagged that its "destructive, irreversible behavior" contradicted destructiveHint=false. The annotation was wrong.
The tool rewrites the read state of up to 25,000 messages, and read/unread is the information about what has not been looked at yet. Once cleared in bulk, what was outstanding is gone. The tool never returns message IDs, so there is no way to reconstruct which messages were unread beforehand. It is now annotated destructive, so MCP clients that distinguish the two will prompt before running it.
mark_messages_read (the 25-message version) stays non-destructive on purpose: the caller holds the IDs it just marked, so read=False restores them. The distinction is recoverability, not the operation.
No behavioural change in the server itself. Documentation and tool tables updated to match. 80 unit tests plus the stdio smoke test.
v0.2.4
Improves the create_folder tool definition, prompted by Glama's tool evaluation (it was the only tool scoring below A).
create_foldernow documents its actual behaviour, verified against a live mailbox: creating a folder whose name already exists under the same parent fails with a 409 rather than producing a duplicate, and a missing parent is an error rather than being created implicitly.- The description now also covers the required permission, the effect of
OUTLOOK_READONLY, and when to reach formove_folderorrename_folderinstead. create_foldernow rejects/in a folder name. It previously accepted it and created a single folder literally nameda/b, which is not a hierarchy and makes later path-based lookups ambiguous.rename_folderalready refused it;create_folderdid not.
No change to any other tool. 80 unit tests plus the stdio smoke test.
v0.2.3
v0.2.2
v0.2.1
v0.2.0
First public release.
An MCP server for restructuring and triaging a large Outlook / Hotmail mailbox through Microsoft Graph. 19 tools.
Highlights
move_folderrelocates an entire folder subtree in a single API call. Messages are not moved, so their IDs stay valid and any inbox rules pointing at that folder keep working.- Bulk move and bulk mark-read, batched through
/$batchwith per-item status checks, defaulting to a dry run that only reports a count. - Inbox rules as first-class tools, including rules authored in the Outlook web UI, whose condition format differs from the API's.
- Drafts and reply drafts. There is no send tool and
Mail.Sendis never requested, so the server cannot email on your behalf. - Deletion only ever means Deleted Items.
OUTLOOK_READONLY=truedisables every write tool at once.
Requirements
Two delegated permissions: Mail.ReadWrite and MailboxSettings.ReadWrite. Works with personal Hotmail / Outlook.com accounts as well as work and school accounts.
Setup is split so that the only manual step is the Azure app registration — see docs/AZURE.en.md. Everything else can be handed to Claude Code with docs/SETUP-FOR-CLAUDE.md.
Testing
Tested on Linux, macOS and Windows against Python 3.10 and 3.13. 78 unit tests plus a stdio smoke test, neither of which connects to Microsoft Graph or needs credentials. The Docker image is built and introspected in CI on every push.
Full test inventory and evidence: docs/TEST.md (Japanese).