From f2d2cf16365ce9366b8824189f64c693840f87e8 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Wed, 22 Apr 2026 22:24:55 +0100 Subject: [PATCH 1/2] Add workiq mcp server install and instructions Signed-off-by: Simon Davies --- Justfile | 72 ++++++++++++++++++++++++- docs/MCP.md | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+), 1 deletion(-) diff --git a/Justfile b/Justfile index 93fe0fa..a7b8c4a 100644 --- a/Justfile +++ b/Justfile @@ -574,6 +574,11 @@ k8s-smoke-test: # # Helper recipes to configure MCP servers for testing and examples. # These write to ~/.hyperagent/config.json (gitignored). +# +# For Work IQ (Microsoft 365), the sanctioned setup is the Microsoft-published +# stdio MCP server: +# just mcp-setup-workiq +# See the "Work IQ (Microsoft 365)" section below for prerequisites. # Set up the MCP "everything" test server (reference/test server with echo, add, etc.) [unix] @@ -677,7 +682,7 @@ mcp-show-config: if (cfg.mcpServers) { console.log('Configured MCP servers:'); for (const [name, s] of Object.entries(cfg.mcpServers)) { - console.log(' ' + name + ': ' + s.command + ' ' + (s.args || []).join(' ')); + console.log(' ' + name + ': ' + (s.command || '?') + ' ' + (s.args || []).join(' ')); } } else { console.log('No MCP servers configured.'); @@ -687,3 +692,68 @@ mcp-show-config: echo "No config file found at $CONFIG_FILE" echo "Run: just mcp-setup-everything" fi + +# ── Work IQ (Microsoft 365) ────────────────────────────────────────── +# +# Adds the Microsoft-published Work IQ MCP stdio server +# (https://github.com/microsoft/work-iq) to your HyperAgent config. +# +# The server is spawned on demand via `npx -y @microsoft/workiq@latest mcp`. +# It exposes the `ask_work_iq`, `accept_eula`, and `get_debug_link` tools, +# which speak to the Microsoft 365 Copilot Chat API on your behalf. +# +# Prerequisites: +# • Node.js 18+ (for npx) +# • A Microsoft 365 Copilot licence on the signing-in user +# • Tenant admin consent for the "Work IQ CLI" enterprise app. Admins: see +# https://github.com/microsoft/work-iq/blob/main/ADMIN-INSTRUCTIONS.md +# • Run `npx -y @microsoft/workiq@latest accept-eula` once (interactive) to +# accept the EULA before the MCP server will serve requests. +# +# Auth: the `workiq` binary performs its own Entra interactive sign-in on +# first call and caches tokens in the user's MSAL cache. HyperAgent does +# NOT need to be told about clientId/tenantId. + +# Set up the Microsoft Work IQ MCP stdio server +[unix] +mcp-setup-workiq: + #!/usr/bin/env bash + set -euo pipefail + CONFIG_DIR="$HOME/.hyperagent" + CONFIG_FILE="$CONFIG_DIR/config.json" + mkdir -p "$CONFIG_DIR" + + echo "▸ Pre-fetching @microsoft/workiq (~188 MB on first run)…" + # Primes the npx cache and downloads the platform binary so the first + # /mcp enable workiq inside HyperAgent doesn't block for minutes. + npx -y @microsoft/workiq@latest version + + echo "▸ Accepting EULA (interactive)…" + # accept-eula writes per-user acceptance state. Safe to re-run; idempotent. + npx -y @microsoft/workiq@latest accept-eula + + echo "▸ Writing MCP config entry…" + node -e " + const fs = require('fs'); + const path = '$CONFIG_FILE'; + const cfg = fs.existsSync(path) ? JSON.parse(fs.readFileSync(path, 'utf8')) : {}; + cfg.mcpServers = cfg.mcpServers || {}; + // Remove any stale HTTP Work IQ entries from previous setups + for (const k of Object.keys(cfg.mcpServers)) { + if (k.startsWith('work-iq-')) delete cfg.mcpServers[k]; + } + cfg.mcpServers.workiq = { + command: 'npx', + args: ['-y', '@microsoft/workiq@latest', 'mcp'] + }; + fs.writeFileSync(path, JSON.stringify(cfg, null, 2) + '\n'); + " + echo "" + echo "✅ Work IQ stdio MCP server ready in $CONFIG_FILE" + echo "" + echo " Next:" + echo " just start" + echo " /plugin enable mcp" + echo " /mcp enable workiq" + echo "" + echo " First tool call opens a browser for Microsoft sign-in." diff --git a/docs/MCP.md b/docs/MCP.md index 9284913..776030b 100644 --- a/docs/MCP.md +++ b/docs/MCP.md @@ -273,6 +273,153 @@ with sandboxed document generation in a single typed JavaScript handler.** --- +## Work IQ (Microsoft 365) + +Microsoft publishes a first-party stdio MCP server, +[`@microsoft/workiq`](https://github.com/microsoft/work-iq), that exposes the +Microsoft 365 Copilot Chat API as MCP tools (emails, meetings, documents, +Teams messages, people). HyperAgent spawns it like any other stdio server — +no HTTP transport, no OAuth config in HyperAgent, no per-tenant app +registration. + +### Prerequisites + +- **Node.js 18+** (for `npx`). +- **Microsoft 365 Copilot licence** on the signing-in user. +- **Tenant admin consent** for the "Work IQ CLI" enterprise application. + See the [Tenant Administrator Enablement Guide][wiq-admin] — admins can + grant consent in one click via the URL at the top of that page, or run the + published `Enable-WorkIQToolsForTenant.ps1` script for tenants where the + Work IQ Tools service principal hasn't been auto-provisioned. +- **Accept the EULA once** (interactive, in your own shell): + + ```bash + npx -y @microsoft/workiq@latest accept-eula + ``` + +[wiq-admin]: https://github.com/microsoft/work-iq/blob/main/ADMIN-INSTRUCTIONS.md + +### One-shot setup + +```bash +just mcp-setup-workiq +``` + +This writes the following entry to `~/.hyperagent/config.json`: + +```json +{ + "mcpServers": { + "workiq": { + "command": "npx", + "args": ["-y", "@microsoft/workiq@latest", "mcp"] + } + } +} +``` + +### Connecting + +``` +/plugin enable mcp +/mcp enable workiq +``` + +On the first tool call the `workiq` binary opens a browser for Microsoft +sign-in (MSAL interactive flow). Tokens are cached in the standard MSAL +cache under the user's home directory — not in `~/.hyperagent/`. Subsequent +sessions reuse the cache silently. + +### Available tools + +The Work IQ MCP server exposes three tools: + +| Tool | Purpose | +|------------------|-------------------------------------------------------------------------| +| `ask_work_iq` | Natural-language query against M365 (mail, calendar, files, Teams, people). | +| `accept_eula` | Accept the EULA from inside an agent session (alternative to the CLI). | +| `get_debug_link` | Return a support link for reporting issues. | + +Most real work happens through `ask_work_iq` with prompts like: + +- "What are my upcoming meetings this week?" +- "Summarise emails from Sarah about the budget." +- "Find documents I worked on yesterday." + +### Running in a container / AKS + +Because auth is interactive, a long-running pod can't sign in on its own. +Two options, ordered by how fragile they are: + +1. **Prime the cache locally, then mount it** — run `workiq ask -q hi` + once on a workstation, copy the MSAL token cache file(s) into a + Kubernetes Secret, mount it into the pod at the path `workiq` expects. + The refresh token will eventually expire (typically days). +2. **Device-code flow** — if `workiq` ever exposes it (check + `npx -y @microsoft/workiq mcp --help` in the version you have), run it + once inside the pod with kubectl attach, auth from another browser, let + the refresh token take over. + +At time of writing, the sanctioned path is **desktop use only**. There is +no documented service-principal / client-credentials flow for Work IQ. + +### Troubleshooting + +| Symptom | Fix | +|----------------------------------------------|-------------------------------------------------------------------------------| +| "Admin approval required" on sign-in | Tenant admin must grant consent — see [admin guide][wiq-admin]. | +| EULA prompt blocks MCP session startup | Run `npx -y @microsoft/workiq@latest accept-eula` once in an interactive shell. | +| `/mcp enable workiq` hangs | First run downloads ~188 MB of platform binaries via `npx`. Be patient. | +| "AADSTS650052" / "Access denied" on consent URL | Work IQ Tools service principal not provisioned. Run the admin PS script. | + +### Legacy HTTP + OAuth path + +Earlier iterations of this integration connected to +`agent365.svc.cloud.microsoft` directly over HTTP with an Entra app +registration per tenant. That flow still works (HyperAgent's HTTP+OAuth +transport is documented below and used by other remote MCP servers), but +the Microsoft-published stdio CLI is simpler, officially supported, and +avoids per-tenant app-registration plumbing. The old setup script is kept +for reference under [`scripts/.attic/setup-workiq-app.sh`](../scripts/.attic/setup-workiq-app.sh). + +--- + +## HTTP Transport & OAuth (generic remote MCP servers) + +HyperAgent supports remote MCP servers over HTTP with OAuth 2.0 (PKCE) for +cases where a hosted MCP endpoint requires bearer-token auth. + +Config shape: + +```json +{ + "mcpServers": { + "my-remote": { + "type": "http", + "url": "https://example.com/mcp", + "auth": { + "method": "oauth", + "clientId": "", + "tenantId": "", + "callbackPort": 8080 + } + } + } +} +``` + +On first connect HyperAgent starts a short-lived callback listener on +`http://localhost:/callback`, opens the system browser to the +authorisation endpoint advertised by the server's OAuth metadata, performs +PKCE, and persists the resulting tokens to +`~/.hyperagent/mcp-tokens/.json` (mode `0600` on Unix). + +Subsequent sessions reuse the cached token and refresh silently. Deleting +the token file forces a fresh sign-in. Tokens are **never** written to the +transcript log. + +--- + ## Debugging ### Connection states From 5d84a14cc3e8550a584a81d271af09c7e1093fbc Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Thu, 23 Apr 2026 09:46:15 +0100 Subject: [PATCH 2/2] docs(mcp): address PR #65 review comments - Bump Node.js prereq from 18+ to 22+ (HyperAgent requirement) in both docs/MCP.md and Justfile. - Drop 'Legacy HTTP + OAuth path' subsection referencing scripts/.attic/setup-workiq-app.sh (file not in this PR). - Drop 'HTTP Transport & OAuth (generic remote MCP servers)' section; the backing transport code is not in this PR either. --- Justfile | 2 +- docs/MCP.md | 49 ++----------------------------------------------- 2 files changed, 3 insertions(+), 48 deletions(-) diff --git a/Justfile b/Justfile index a7b8c4a..f71b8c9 100644 --- a/Justfile +++ b/Justfile @@ -703,7 +703,7 @@ mcp-show-config: # which speak to the Microsoft 365 Copilot Chat API on your behalf. # # Prerequisites: -# • Node.js 18+ (for npx) +# • Node.js 22+ (required by HyperAgent; also satisfies workiq's 18+ minimum) # • A Microsoft 365 Copilot licence on the signing-in user # • Tenant admin consent for the "Work IQ CLI" enterprise app. Admins: see # https://github.com/microsoft/work-iq/blob/main/ADMIN-INSTRUCTIONS.md diff --git a/docs/MCP.md b/docs/MCP.md index 776030b..27bf20f 100644 --- a/docs/MCP.md +++ b/docs/MCP.md @@ -284,7 +284,8 @@ registration. ### Prerequisites -- **Node.js 18+** (for `npx`). +- **Node.js 22+** — required by HyperAgent (`just start`); also satisfies the + Work IQ CLI's own Node.js 18+ minimum. - **Microsoft 365 Copilot licence** on the signing-in user. - **Tenant admin consent** for the "Work IQ CLI" enterprise application. See the [Tenant Administrator Enablement Guide][wiq-admin] — admins can @@ -372,52 +373,6 @@ no documented service-principal / client-credentials flow for Work IQ. | `/mcp enable workiq` hangs | First run downloads ~188 MB of platform binaries via `npx`. Be patient. | | "AADSTS650052" / "Access denied" on consent URL | Work IQ Tools service principal not provisioned. Run the admin PS script. | -### Legacy HTTP + OAuth path - -Earlier iterations of this integration connected to -`agent365.svc.cloud.microsoft` directly over HTTP with an Entra app -registration per tenant. That flow still works (HyperAgent's HTTP+OAuth -transport is documented below and used by other remote MCP servers), but -the Microsoft-published stdio CLI is simpler, officially supported, and -avoids per-tenant app-registration plumbing. The old setup script is kept -for reference under [`scripts/.attic/setup-workiq-app.sh`](../scripts/.attic/setup-workiq-app.sh). - ---- - -## HTTP Transport & OAuth (generic remote MCP servers) - -HyperAgent supports remote MCP servers over HTTP with OAuth 2.0 (PKCE) for -cases where a hosted MCP endpoint requires bearer-token auth. - -Config shape: - -```json -{ - "mcpServers": { - "my-remote": { - "type": "http", - "url": "https://example.com/mcp", - "auth": { - "method": "oauth", - "clientId": "", - "tenantId": "", - "callbackPort": 8080 - } - } - } -} -``` - -On first connect HyperAgent starts a short-lived callback listener on -`http://localhost:/callback`, opens the system browser to the -authorisation endpoint advertised by the server's OAuth metadata, performs -PKCE, and persists the resulting tokens to -`~/.hyperagent/mcp-tokens/.json` (mode `0600` on Unix). - -Subsequent sessions reuse the cached token and refresh silently. Deleting -the token file forces a fresh sign-in. Tokens are **never** written to the -transcript log. - --- ## Debugging