Admins can now write add-in access rules that match the open document's path, for files that can't carry a sensitivity label (for example, on a network share).
- access-policies.md: a path example, the grammar and operator entries, and a rule covering how paths are compared and their limits.
- build-manifest.mjs: accepts file_path with equals | startsWith, and warns when it is used on uploaded_file, where it can never match.
docs: document the web_search disabled_features slug (0.1.11)
The add-in now enforces web_search in disabled_features: it removes the
native web_search/web_fetch server tools and the user toggle, leaving code
execution intact. Add it to the enforced-slug table with the pairing
guidance (mcp_servers for an in-network replacement search tool) and to the
build script's hint.
* manifest: recognize the available_models config key
Adds available_models to the KEYS validator (comma-separated ids or JSON
array of ids / {id,label} objects, mirroring the add-in's parser) and
documents it in manifest.md and bootstrap.md. Replaces the retired
disabled_models/additional_models pair from #294: available_models is a
single override list, so admins state the full picker rather than diffs.
No-Verification-Needed: exercised build-manifest.mjs directly against valid and invalid inputs
* bump claude-for-msft-365-install to 0.1.9
No-Verification-Needed: version bump only
* manifest: add access_policies key and guided access-policies command doc
Adds the access_policies config key — a JSON array of allow/deny
statements that supersedes disabled_features and can scope a rule to
documents by Purview sensitivity label. The build script recognizes
the key (warn-only shape check for a JSON array), manifest.md documents
it alongside disabled_features, and a new access-policies command walks
the admin through fetching label GUIDs, choosing statements, and the
matching rules to explain before shipping.
* Validate access_policies statement structure; document grammar and slugs
The build script now parses access_policies and warns on each statement
that fails the grammar — bad effect, unknown resource or identifier type,
an operator the identifier type does not support (a GUID takes only
equals | exists), an empty identifiers array, a blank action slug. These
are the shapes the add-in drops silently, so the build is the only place
they get caught; an unparseable value is fatal.
Docs: add a statement-grammar reference and the full feature-slug list to
access-policies.md, sync the disabled_features table in manifest.md with
all four slugs, add the missing access_policies field to bootstrap.md,
and fix the parent-label prefix example to include the " - " separator.
* Add read-only add-in data export; harden cache-clear scripts
Chat history, skills, MCP registrations and memory live only in browser
storage on the user's machine. Add export-addin-data.{sh,ps1} to copy them
before a rebuild, and fix the cache-clear scripts that sit next to them.
clear-addin-cache.sh matched the add-in ID case-sensitively, but Office names
the wef file with whatever casing the manifest <Id> carried. A lowercase GUID
reported "already clear" and exited 0, sending admins to the folder-wide wipe
that destroys chat history on Windows. Match case-insensitively, and make a
miss print NOT cleared and exit non-zero on both platforms.
clear-addin-cache.ps1 never parsed on Windows PowerShell 5.1: em dashes in a
BOM-less .ps1 are decoded as ANSI into mojibake containing a quote, which
terminates a string mid-file. All .ps1 files are now pure ASCII, and check.py
rejects non-ASCII bytes in a .ps1 without a UTF-8 BOM.
Also:
- export: parse the port out of WebKit's binary origin file. Dropping it made
two origins on the same host collide in one export folder, silently
overwriting the first.
- export: include localStorage, which holds settings, the inference config,
and the onboarding/terms flags.
- export: exporting nothing while --out was given now exits non-zero, so
"export then wipe" cannot treat an empty backup as success.
- export: a failed database copy no longer aborts the run; paths containing
an apostrophe work.
- export.ps1: clear the destination before Copy-Item -Recurse, which nested
instead of refreshing on a re-run; add -IncludeAll for stores whose names
compaction has hidden; scan uncompressed LevelDB files first.
- clear.ps1: require a GUID for -Id, since Remove-Item -Path expands wildcards;
escape value names for Remove-ItemProperty.
- clear.sh: scan Outlook too, and guard flags that take a value.
- Document why replacing or reinstalling a manifest never moves the data.
Verified on macOS against live add-in data, and on a Windows host against
Windows PowerShell 5.1.
* Export Windows localStorage as the whole per-profile store
localStorage holds the settings, the inference/customer config, and the
onboarding + terms-accepted flags -- none of it in IndexedDB -- so an export
without it left a rebuilt machine re-doing onboarding.
Chromium keeps one LevelDB per profile shared by every origin, so it cannot be
filtered down to one add-in. Copy it whole rather than drop it, once per Office
account, beside that account's origin folders. It therefore also contains other
origins' settings: the size is printed on every run including the argument-less
preview, the help text says so plainly, and the folder can simply be deleted
from the export if a data policy forbids it.
- Copy to a scratch name and swap only on success. Deleting the destination
first meant a locked LOCK file (Office still running) left the export with
neither the new copy nor the previous good one. A failure is now counted and
reported as INCOMPLETE with a non-zero exit, matching the macOS script.
- Drive the copy off the unique profile list instead of the per-store loop, so
a profile whose only store fails the origin-name parse keeps its settings.
- Report in list mode too, matching macOS -- the argument-less run is
advertised as printing what it found.
- .SYNOPSIS/.DESCRIPTION no longer claim only Claude's data is copied.
- Correct the export-data doc: the export tree is relabelled for readability,
not a path mirror, so it cannot be copied back verbatim.
Verified on a Windows host against Windows PowerShell 5.1: copied once per
profile, flat on re-run, real LevelDB contents present, disclosed in list mode
without writing anything.
* manifest: add gateway_auth_source=entra param + Entra app registration docs (incl. GCC High)
- build-manifest.mjs: recognize gateway_auth_source; require entra_scope (→ graph_client_id, entra_sso=1); warn if paired with gateway_token; drop stale 'graph_client_id is Outlook-only' note
- manifest.md: new 'Use the Entra token as your gateway credential' section with a consolidated Entra app registration checklist (SPA redirect URI, Expose an API, admin consent, v2 tokens, gateway-side validation) and a GCC High/DoD subsection (portal.azure.us, .us issuer/JWKS)
* manifest.md: list both NAA redirect URIs (brk-multihub + https fallback)
The checklist only listed the https://.../msal-redirect.html SPA fallback. Desktop Office and Outlook web use the NAA broker, which requires brk-multihub://pivot.claude.ai registered as SPA — without it sign-in fails with AADSTS50011. Both are needed: brk-multihub for NAA, https for the Excel/Word/PPT Office-Web fallback where the NAA bridge isn't injected. Also pointed the earlier 'Bring your own Entra app' prose at the checklist instead of duplicating (incompletely).
* Split Entra app registration into commands/entra-app.md
manifest.md now documents what the params do; entra-app.md documents how to register the app (redirect URIs, per-use-case permissions table, admin consent, token version, backend validation, GCC-High/DoD, troubleshooting). Linked from every manifest.md section that needs your own app: graph_client_id, entra_scope, gateway_auth_source, sovereign clouds.
* docs(claude-for-msft-365-install): sovereign-cloud support via graph_cloud enum
The Outlook add-in now supports GCC-High, DoD, and 21Vianet tenants via a
single graph_cloud manifest parameter (global | us-gov-high | us-gov-dod |
china) that maps to fixed Graph + Entra endpoint pairs — no admin-supplied
URLs. Teach the install plugin about it:
- commands/manifest.md: per-tenant graph_cloud table; DoD must always set it
(shares an authority host with GCC High); non-global clouds require a BYO
graph_client_id; the enum also governs Word/Excel/PowerPoint Entra SSO.
- scripts/build-manifest.mjs: register graph_cloud and hard-fail on
unrecognized values or a non-global cloud without graph_client_id,
mirroring the add-in's load-time checks so admins see the error at build
time instead of an AADSTS code after deployment. Param building extracted
into an exported buildParams() for testability.
- scripts/build-manifest.test.mjs: node:test suite — default query string
unchanged, all enum values accepted, bad values and the removed URL params
rejected.
- .github/workflows/plugin-validate.yml: run the test suite on every PR.
* Drop manifest script tests — graph_cloud validation is two inline checks
The marketplace loader rejected 9 of 20 plugins on sync:
- 29 vertical-plugin SKILL.md sources had no YAML frontmatter — the
skill name/description sat in the body as a bare `description:` line
after the `# Title` H1. Synthesized proper `--- name/description ---`
frontmatter (name = skill dir, description = the existing body text),
matching the loading skills (e.g. fund-admin/accrual-schedule). Agent
bundles re-synced via scripts/sync-agent-skills.py (12 copies).
- 4 hooks/hooks.json were `[]`; the loader requires a JSON object.
Changed to `{ "hooks": {} }` — the form investment-banking already
uses and that synced clean.
- partner-built/spglobal defined the `spglobal` MCP server both inline
in plugin.json and in .mcp.json (identical). Dropped the inline copy;
.mcp.json is the canonical location.
scripts/check.py: OK — 80 files, 0 issues.
Co-authored-by: Jake Marsh <jakemarsh@anthropic.com>
* fix(ci): cache claude binary dir, not just the dangling symlink
~/.local/bin/claude is a symlink into ~/.local/share/claude/versions/<v>.
Caching only the symlink restored a dangling link on a cache hit, so
`claude` failed with exit 127. Cache the versioned dir too and bump the
cache key (-v2) to discard the broken saved entry.
* docs(claude-for-msft-365-install): add update + bootstrap sections, debug command row
fix(plugins): hooks.json must be {"hooks": {}} not []; add plugin-validate CI
The empty-array hooks.json in private-equity, financial-analysis,
equity-research and wealth-management caused those plugins to fail to
load ("Hook load failed: expected object, received array"). Replace [] with
the minimal valid {"hooks": {}} object in all four.
Add a plugin-validate workflow that runs the official `claude plugin
validate` over the marketplace manifest and every plugin on each PR and
push, so a malformed manifest fails CI instead of reaching users. The
CLI is installed from the official binary channel and cached, keyed on a
pinned version, so a warm cache skips the download entirely.
* feat(repo): plugin version-bump hook + CI backstop, fix install docs/remote
* docs(claude-in-office): add Wef registry + wef-folder sideload (Windows + macOS) for local debugging
* ci: use actions/checkout@v4 instead of pinned SHA
* docs(claude-in-office): scope sideload cleanup to the specific manifest, not the wef folder
* docs(claude-in-office): scope cache-clear to wef contents with guards, not rm -rf of caches/wef dirs
* docs(claude-in-office): target cache-clear by add-in Id, leave other add-ins in wef untouched
* feat(claude-in-office): add clear-addin-cache scripts (mac/win), ID-targeted, dry-run by default
* fix(claude-in-office): Windows sideload cleanup is registry-based, ID-first; direct edits (no office-addin-dev-settings); document deployed-cache caveat
* docs(claude-in-office): clarify surgical per-ID deletion of local/sideloaded manifests is safe; MS warning applies only to the deployed cache
* feat(claude-in-office): add sideload-addin scripts (mac/win), ID-derived, dry-run by default; debug.md points to script pair
* feat(claude-in-office): sideload installs directly (drop dry-run); dry-run stays only on destructive clear-addin-cache
* docs(claude-in-office): make the post-clear app restart an explicit step, not a buried line
The add-in now accepts entra_scope as a comma/whitespace-separated list and
no longer requires a URI-shaped value (Entra validates scope syntax, not the
build script). Update the docs and the build-manifest validation to match:
- build-manifest.mjs: entra_scope pattern relaxed to any non-blank string;
the graph_client_id pairing check is unchanged.
- manifest.md: document the multi-scope list syntax and the same-resource
constraint; clarify the build script enforces the pairing, not the format.
- bootstrap.md: note scp is a space-delimited list with multiple scopes.
- debug.md: add a Silent SSO / Entra token failures troubleshooting section
(AADSTS50194, entra_scope-without-graph_client_id, silent-then-popup).
build-manifest.mjs now takes a host argument (office | outlook). The
outlook host fetches manifest-outlook-3p.xml, which uses Microsoft's
MailApp schema and cannot share a file with the TaskPaneApp manifest
Excel/Word/PowerPoint use.
- URL_SLOTS regexes are now /g so all three Outlook taskpane URL entries
(FormSettings + V1_0 + V1_1 Resources) receive the config params, not
just the first match.
- New graph_client_id key for orgs that bring their own Entra app for
Microsoft Graph instead of consenting to Anthropic's multi-tenant app.
- aws_* keys with the outlook host fail fast: Bedrock is not currently
supported for Outlook.
- consent.md gains the Outlook Graph admin-consent URL (Mail.ReadWrite,
Calendars.Read, People.Read, User.Read, offline_access) and the
own-Entra-app alternative.
- manifest.md and setup.md document the host arg, the per-host file
split, and route admins to the consent step before generating the
Outlook manifest.
- Move verticals from repo root into plugins/vertical-plugins/ and partner
plugins into plugins/partner-built/
- Add 10 named, self-contained agent plugins under plugins/agent-plugins/
(Pitch Agent, Market Researcher, Earnings Reviewer, Model Builder,
Meeting Prep, GL Reconciler, Month-End Closer, Statement Auditor,
Valuation Reviewer, KYC Screener) — each bundles its own skills so it
installs standalone
- Add managed-agent-cookbooks/ (one per agent) with subagent isolation
and steering examples for /v1/agents deployment
- Add fund-admin and operations verticals so the finance-ops/onboarding
agents ship real domain skills
- Add scripts/ (check.py manifest lint, sync-agent-skills.py,
deploy-managed-agent.sh, orchestrate.py reference loop,
test-cookbooks.sh)
- Add .github/workflows/secret-scan.yml (gitleaks + internal-ref grep)
- Tighten agent tool grants to declared MCPs only — no Bash, WebFetch,
or undeclared mcp__* references in any agent
- Add not-investment-advice disclaimer to README
- Rename claude-in-office to claude-for-msft-365-install (content
unchanged)
Adds the new `otlp_resource_attributes` key (comma-separated k=v, same
format as OTEL_RESOURCE_ATTRIBUTES) to:
- build-manifest.mjs KEYS validator
- manifest.md / bootstrap.md telemetry sections
- update-user-attrs.md key table
Paired with anthropics/office-agent OA-336.
JSON object of extra HTTP headers the add-in attaches to every request
it sends to the configured gateway. Lets enterprise gateways receive
accounting or routing tags without a header-injecting proxy in front.
- build-manifest.mjs: KEYS validator entry
- manifest.md / bootstrap.md / update-user-attrs.md: documented with
example and reserved-header list
Adds examples/python-bootstrap/: a ~80-line FastAPI reference for the
bootstrap endpoint. Validates the Entra ID token, reads oid/groups from
claims, parses X-Claude-User-Agent for the Office host, and returns
skills + mcp_servers via a first-match RULES table in config.py.
Includes mint_dev_token.py (loopback-only RS256 dev tokens),
get_tenant_id.py, requirements.txt, and README.
Also documents the X-Claude-User-Agent request header and recommended
CORS preflight (Allow-Headers: Authorization, X-Claude-User-Agent, *)
in commands/bootstrap.md.
Add azure_resource_name and azure_api_key to the build-manifest KEYS
table so admins can bake Foundry config into the add-in manifest.
Document the Foundry path in setup.md and the keys table in manifest.md.
Adds gateway_api_format (anthropic | bedrock | vertex) to the config key
set so admins can deploy against gateways exposing Bedrock InvokeModel
or Vertex rawPredict pass-through routes instead of /v1/messages.
- build-manifest.mjs: KEYS entry with /^(anthropic|bedrock|vertex)$/
- setup.md: gateway wizard asks for API format; vertex => also capture
gcp_project_id + gcp_region; Step 6 smoke test now has three
format-specific curls (path + body shape differ per format)
- manifest.md / update-user-attrs.md / bootstrap.md: docs for the key
Adds mcp_servers to the recognized KEYS table so admins can bake an
org-wide MCP server list into the manifest URL. Documents the key in
commands/manifest.md alongside the other cross-cutting keys, with a
shell-quoted example and a pointer to bootstrap.md for the full schema
and per-user delivery.
Adds a new section to the /debug skill covering how to attach browser
devtools to the add-in WebView on both platforms. The macOS recipe
includes the three-gate sequence (defaults write, Safari Develop menu,
Sonoma Privacy & Security allowlist) plus the gotcha that Office updates
silently reset the defaults-write flag. Windows covers both WebView2
(right-click or Edge DevTools Preview) and the IE11/Trident legacy path
via IEChooser.exe.
Also adds a triage table row so admins asking 'how do I see the console'
route here directly.
Adds bootstrap_expires_at to the bootstrap endpoint response example
and explains it enables proactive config refresh — the add-in re-calls
the endpoint before expiry. Epoch seconds or milliseconds, auto-detected.
Explains the x-api-key vs Authorization: Bearer choice in the Gateway
section of setup.md, adds the key to manifest.md's per-cloud table, and
updates the Step 6 smoke-test curl with the alternate header form.
Adds gateway_auth_header to the KEYS table so admins can configure
which header carries the gateway token. Accepts "x-api-key" (default)
or "authorization" (sends Authorization: Bearer <token>).
Pairs with add-in support for the same key in CustomerConfig.
Consent is only required when entra_sso=1 (Bedrock or per-user config).
Gateway and Vertex with org-wide config skip it. Updates setup.md flow
and consent.md to reflect this.
Migrated from anthropics/office-agent. Provides /setup, /manifest, /consent,
/update-user-attrs, and /debug commands for M365 admins provisioning the
Claude Office add-in with direct cloud access (Vertex AI, Bedrock, or an
LLM gateway).