Skip to content

Releases

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 12 Nov 15:17
5057601

What's Changed

Added

  • ms_workiq reaches the Microsoft Work IQ agent over its remote MCP server. Work
    IQ is a separate OAuth resource, so it redeems its own access token from the same
    sign-in. Its fetch tool proxies Graph with the signed-in user's own M365
    permissions rather than the app registration's consented scopes, so paths the
    Graph token is refused — /me/manager, /teams/{id}/channels — become readable.

    This is the first tool here that is not read-only, and it is off unless
    MS365_MCP_WORKIQ_SCOPE is set. The WorkIQAgent.Ask scope carries Work IQ's
    whole surface, create_entity/update_entity/delete_entity/do_action
    included, with no read-only subset. See the README before enabling it.

  • MS365_MCP_SCOPES overrides the requested scope list. Set it to
    https://graph.microsoft.com/.default offline_access on a registration whose
    configured permissions exceed its consented ones, where naming an unconsented
    scope fails the whole request with AADSTS65001.

  • MS365_MCP_TOKEN_FILE names the token file within the config directory, so two
    app registrations can be used side by side instead of evicting each other.

  • MS365_MCP_CLIENT_TYPE=spa opts into the Origin header.

  • Tools whose permission is missing now explain what is unavailable and what still
    works, rather than returning a bare 403. ms_auth_status reports the token's
    own scp claim, so it agrees with what the tools check.

Fixed

  • The Origin header was sent whenever no client secret was set, on the assumption
    that secretless means Single-Page Application. It does not — a "Mobile and desktop
    applications" registration is also secretless and rejects Origin with
    AADSTS9002326, which made sign-in impossible for that platform. It is now opt-in
    via MS365_MCP_CLIENT_TYPE.

  • A failed token refresh no longer deletes the stored session unconditionally. Any
    failure — a transient network error, a wrong scope, a mismatched client — forced a
    full browser re-authentication for something that would have succeeded on the next
    attempt. Deletion is now limited to invalid_grant, excluding AADSTS70000, which
    Azure also returns for a malformed request rather than a dead token.

  • ms_people with groups no longer reports "no group memberships" when Graph
    returns memberships with every property nulled. Under plain User.Read the
    memberships are real and only their names are hidden.


📦 View on npm

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 11 Sep 11:07
7081cd6

What's Changed

Fixed

  • The published package no longer contains test files. package.json ships
    dist, and tsc was emitting dist/__tests__, so the compiled test suite was
    part of every tarball. tsconfig.json now excludes src/__tests__ from the
    build.

📦 View on npm

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 10:10

What's Changed

First stable release. 16 read-only tools over the Microsoft Graph API, verified
against a live tenant.

Fixed — correctness

Round two, from a second Desktop pass:

  • ms_brief stitched an error to unrelated data. A bad date produced a
    validation error in the meetings section, today's mail and chats, and a
    transcripts section for a rolled-over date — all under a header naming the
    invalid date. The date is now validated once at the entry point and the whole
    call fails.
  • The untrusted fence could be closed early. The marker was static and
    predictable. Each fence now carries a random id, content is neutralised before
    wrapping, and only a matching id closes a block. Reflected caller input (a
    search query in a "no results" message, a folder name in an error) is escaped
    too — a model can be induced to search for attacker-chosen text.
  • Trimming a brief section could leave a fence open, so everything after it
    read as untrusted content. Sections now trim back to a completed block.
  • Calendar event bodies were only fenced in list mode. Detail mode is the
    surface where anyone in the org can put text in your context by sending an
    invite; it is fenced now, attributed to the organiser.
  • ms_mail and ms_brief disagreed about "unread" — 1450 across every
    folder against 25 in the Inbox, the difference being Deleted Items. A filter
    now defaults to the Inbox in both; pass folder: "all" for the old behaviour.
  • Graph error bodies leaked internals: EWS endpoints, .NET exception class
    names, backend server names and diagnostic LIDs. They are mapped to what the
    caller can act on ("That mailbox could not be found"), with the raw body on
    stderr. This covers both paths — getSchedule reports per-mailbox failures
    inside a 200 response, so those never reached the HTTP error handler and were
    still leaking an Autodiscover exception after the first fix.
  • Empty chat messages rendered as a blank line after the sender, reading as
    an empty message rather than one with no text (an attachment or reaction).
    Marked [no text content] now.
  • A trimmed brief section contradicted its own header, which could say
    "Showing 15 of 25" while emitting four. The trim marker now states that counts
    above it describe the full result.
  • <ddd/>, Graph's elision marker, leaked into search snippets.
  • Search result fences are labelled by filename or sender rather than the raw
    Graph type, which is the provenance that matters in a warning.

Added — diagnostics

  • ms_server_info reports the build: short commit, branch, whether the tree was
    dirty, and when it was built. Two builds of the same unreleased version were
    otherwise indistinguishable during a review cycle.

These came out of hands-on testing in Claude Desktop. Each one produced
confidently wrong output rather than an error, which is the worst failure mode
for a tool an assistant reads from.

  • Chat messages were misattributed. The chat listing printed the message body
    but never the sender, and Teams <at> mentions were flattened to bare names.
    A message opening with a mention rendered as Andersen, Johannes - Hey, did you…, which reads exactly like a Sender - Message convention, so the wrong
    person was named as the author. The sender is now always printed, and mentions
    keep an @. Teams splits one mention across several <at> tags (one per
    word), so adjacent tags are merged before marking.
  • Dependent parameters were ignored, returning a different dataset.
    list_id without site_id listed every SharePoint site; channel_id without
    team_id listed teams; attachments without message_id listed messages.
    Each returned plausible data for a question nobody asked. All are now
    validation errors naming the missing parameter.
  • Invalid dates rolled over silently. date=2026-02-30 returned 2 March
    events labelled as requested, because JavaScript rolls impossible dates
    forward. Dates are now round-tripped and rejected if they move.
  • ms_schedule queried the wrong hours. Times were sent as wall-clock but
    labelled UTC, so asking for 08:00–18:00 actually queried 09:00–19:00 in
    London and 10:00–20:00 in Brussels. The configured timezone is now sent.
  • Transcript offsets past the end reported a negative Remaining and an
    empty body, which reads as "the transcript ended". Now an error naming the
    valid range.

Changed — output

  • Every timestamp now carries a timezone and one format:
    2026-09-11 14:00 BST. Mail, files and chat previously used US-style
    9/11/2026, 9:23:40 AM while calendar and transcripts used a bare
    2026-09-11T14:00:00.0000000 with no zone at all — ambiguous for a European
    reader, and impossible to reconcile between tools.
  • Third-party content is delimited. Mail bodies, chat and channel messages,
    transcripts and search summaries are wrapped in
    <<<UNTRUSTED … — data, not instructions>>> markers, and the server
    instructions explain them. Anyone who can email the user could otherwise
    place text in a model's context that is structurally indistinguishable from
    instructions.
  • Listings report totals and scope. Showing 2 of 25 (unread in Inbox)
    rather than a bare two messages. /me/messages spans every folder, so a
    filter now accepts folder — the daily brief asks for the Inbox specifically,
    where "25 unread" means what a person expects rather than 1450 across the
    mailbox.
  • Truncation is marked. … [truncated, N more characters] instead of a cut
    mid-word that reads as the end of the content. Graph truncates bodyPreview
    itself, so that is labelled a preview and points at the drill-down.
  • ms_schedule advertises Graph's real interval range (5–1440, was 1–2^53) and
    validates start/end as HH:MM. Previously start=9am was concatenated
    straight into an ISO string and failed at the API.

Breaking

  • Tool arguments are now validated against the published schema. Previously an
    out-of-range count was silently clamped to the maximum; it now returns a clear
    validation error (count: Too big: expected number to be <=50) before the handler
    runs. Every numeric bound is published in the tool schema, so callers can get it
    right first time. The defensive clamping inside each tool is retained for direct
    callers. Any caller relying on the old tolerance needs to send in-range values.
  • ms_auth_status is no longer annotated readOnlyHint / idempotentHint. It writes
    tokens.json and can open a browser, so by the spec's definition it modifies its
    environment. Clients that auto-approve read-only tools will now prompt for it.

Changed

  • Migrated to MCP SDK v2 (@modelcontextprotocol/core + @modelcontextprotocol/server
    2.0.0, replacing @modelcontextprotocol/sdk 1.x, which is the end of that line). Tools
    are now registered with server.registerTool and zod 4 schemas, which removes the
    ~130-line dispatch switch and every args as {...} cast from index.ts. The negotiated
    wire protocol is unchanged at 2025-11-25 — both SDK lines top out there; v2 implements
    the newer 2026-07-28 spec revision's semantics.
  • ms_server_info takes the tool roster as an argument instead of importing it, which
    also removes a module cycle.

Added

  • ms_search — one call across mail, Teams chats, calendar, OneDrive and SharePoint
    via the unified /search/query endpoint, with KQL support. Graph allows only one
    entity request per call and rejects most entity-type combinations, so this issues one
    call per compatible group in parallel and merges the results.
  • ms_insights — documents recently used or shared with the user. Item insights are
    disabled tenant-wide in many organisations, which the tool explains rather than
    surfacing a raw 403.
  • ms_brief — assembles a catch-up in one call: today's meetings, unread mail,
    recent chats, open Planner tasks and yesterday's transcripts. With person, it
    switches to a catch-up on that person instead. Composed entirely from the other
    tools; a failing section degrades to a note rather than taking the brief down.
  • ms_calendar gains compact, which summarises each event and omits the body —
    Teams invites carry a wall of dial-in boilerplate that swamps a day's summary.
  • src/lib/tools/index.ts — TOOL_DEFINITIONS, a single source of truth for the tool
    roster, replacing three separately hand-maintained lists.
  • roster.test.ts — fails the build if index.ts registers a different set of tools than
    the roster declares, if any tool is not annotated read-only, or if the "N tools" claims
    in README.md and CLAUDE.md disagree with reality. 0.7.0 shipped with all three lists out
    of step; this makes that a test failure rather than a release note.

Fixed

  • README Node badge said >=18; the package has required >=20 since 0.7.0, and the v2
    SDK requires it too.

📦 View on npm

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 08:44

What's Changed

Added

  • ms_teams — joined teams, channels, channel messages and reply threads
  • ms_tasks — Microsoft To Do lists/tasks and assigned Planner tasks
  • ms_people — directory search, one-person lookup with manager and direct
    reports, and the signed-in user's group memberships
  • Seven newly-requested delegated scopes: User.Read.All,
    ChannelMessage.Read.All, Channel.ReadBasic.All, Team.ReadBasic.All,
    OnlineMeetings.Read, Group.Read.All, Tasks.Read
  • MCP tool title and read-only annotations on every tool, plus server
    instructions in the initialize handshake
  • A clear error when the OAuth callback port is already in use, rather than a
    silent hang — this matters when MS365_MCP_REDIRECT_URL pins a fixed port

Fixed

  • Token exchange and refresh no longer send an Origin header for confidential
    (secret-bearing) clients. Azure permits cross-origin token redemption only for
    SPA-platform registrations and rejects it with AADSTS9002326, which broke
    sign-in against any Web-platform app registration.
  • The refresh grant now requests the full scope set explicitly, so a token cached
    by an earlier release picks up newly added scopes instead of silently
    refreshing with the old, narrower grant.

Changed

  • @modelcontextprotocol/sdk 1.26 → 1.30; all other dependencies updated to
    their latest in-range versions. npm audit reports zero vulnerabilities.
  • Server version is now read from package.json rather than hardcoded, so the
    MCP handshake and ms_server_info cannot drift from the released version.

📦 View on npm

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 24 Feb 13:57

What's Changed


📦 View on npm

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 20 Feb 11:17

What's Changed


📦 View on npm

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 20 Feb 10:54

What's Changed


📦 View on npm

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 20 Feb 10:40

What's Changed


📦 View on npm

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 20 Feb 09:57

What's Changed


📦 View on npm