Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion claude-for-msft-365-install/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "claude-for-msft-365-install",
"description": "Provision direct cloud access (Vertex AI, Bedrock, or LLM gateway) for the Claude Office add-in. Generates the customized add-in manifest, walks through Azure admin consent, and writes per-user config via Microsoft Graph extension attributes.",
"version": "0.1.6",
"version": "0.1.7",
"author": {
"name": "Anthropic",
"email": "support@anthropic.com"
Expand Down
11 changes: 11 additions & 0 deletions claude-for-msft-365-install/commands/bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,17 @@ layer.
"disabled_features": ["skills.authoring"]
```

### `available_models`

A JSON array of the model ids the 3P picker offers this user, replacing the
built-in catalog. Same semantics as the [manifest key](manifest.md#model-picker);
bootstrap is the per-user layer, and the highest-precedence channel, so
rotations here propagate without re-login.

```json
"available_models": ["claude-opus-4-5", "<id-your-gateway-serves>"]
```

### `bootstrap_expires_at`

Epoch timestamp (seconds or milliseconds — auto-detected) for when this
Expand Down
32 changes: 32 additions & 0 deletions claude-for-msft-365-install/commands/manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,38 @@ Unknown slugs are ignored (forward-compatible). Setting it here applies one
policy org-wide; per-user policy belongs in [bootstrap](bootstrap.md#disabled_features)
(JSON array) or extension attrs (comma-separated).

## Model picker

On 3P deployments the picker is built from a model catalog baked into the
add-in. `available_models` replaces that catalog with your own list:

```bash
available_models='claude-opus-4-5,<id-your-gateway-serves>'
```

Set it and the picker offers exactly those ids, in that order — the first is
the default your users land on. Leave it unset and the built-in catalog
applies. There is no separate "hide this one" key: to drop a model, leave it
out of the list. Accepts a comma list or a JSON array
(`'["claude-opus-4-5"]'`).

Matching is case-insensitive, and a canonical id also covers the provider
forms of the same model — `claude-opus-4-5` selects
`us.anthropic.claude-opus-4-5-20251101-v1:0` and `claude-opus-4-5@20251101`
too. An id the catalog doesn't know is offered as you wrote it, which is how
you reach a model your gateway serves that this build predates — so a typo
shows up in the picker and fails on use rather than being silently dropped.
A list that matches nothing offerable is ignored entirely: an empty picker
isn't recoverable in the UI.

Note this pins you to the list. New models we ship won't appear until you add
them — which is usually what you want, since your gateway has to provision
each model anyway.

In **Outlook** the list may only narrow, never extend: the mail safety gate
pins that surface to a vetted model, so ids outside the built-in catalog are
never offered there.

## Version

M365 Admin Center caches by `<Id>` + `<Version>` — re-upload with the same
Expand Down
1 change: 1 addition & 0 deletions claude-for-msft-365-install/commands/update-user-attrs.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ over manifest params, so whatever's here wins. All values are 256 chars max.
| `google_client_id` `google_client_secret` | Different OAuth client per team (uncommon) |
| `aws_role_arn` `aws_region` | Different Bedrock roles by team |
| `otlp_endpoint` `otlp_headers` `otlp_resource_attributes` | Route telemetry to a team-specific OTEL collector / tag spans with team-level resource attributes |
| `available_models` | Different teams see different models in the 3P picker (comma-separated ids; see [manifest](manifest.md#model-picker)) |

## One user

Expand Down
10 changes: 10 additions & 0 deletions claude-for-msft-365-install/scripts/build-manifest.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const URL_SLOTS = [/(<SourceLocation\s+DefaultValue=")([^"]+)(")/g, /(id="Taskpa
// (your infra may look different). `secret` keys warn louder: the manifest is an
// org-wide file and its URL can land in deploy logs; per-user secrets typically go
// in Azure extension attributes instead.
// A JSON array (["a","b"]) or a comma list (a,b) of model ids.
const MODEL_ID_LIST = /^(\[.*\]|[\w.:@-]+(\s*,\s*[\w.:@-]+)*)$/;

const KEYS = {
gcp_project_id: { pattern: /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/, hint: "GCP project ID" },
gcp_region: { pattern: /./, hint: "GCP region, e.g. us-east5 or global" },
Expand Down Expand Up @@ -85,6 +88,13 @@ const KEYS = {
pattern: /^[\w.]+(,[\w.]+)*$/,
hint: "comma-separated feature slugs to lock for users, e.g. skills.authoring",
},
// Model ids carry . : @ - (us.anthropic.claude-opus-4-5-20251101-v1:0,
// claude-opus-4-5@20251101), so this can't reuse disabled_features' slug pattern.
// Accepts a JSON array or a comma list; the add-in preserves id case.
available_models: {
pattern: MODEL_ID_LIST,
hint: 'the models the picker offers, replacing the built-in catalog, e.g. claude-opus-4-5 or ["claude-opus-4-5"] — 3P gateway/Bedrock/Vertex only',
},
};

const NEEDS_ENTRA = ["aws_role_arn", "graph_client_id", "entra_scope", "gateway_auth_source"];
Expand Down
Loading