AI assistant App Password: offer 'Can view and change' (MCP write), copy-ready client setup, and the MCP switch hint #629

Open
opened 2026-10-01 11:25:47 +00:00 by kayg · 5 comments
Owner

Owner question (2026-10-01): "Why is MCP read only? I wanna try it out."

The App Password chooser's "AI assistant · MCP" preset only grants mcp: read. Write access exists only through "Custom scopes", which is not obvious.
Fix (in the #412 chooser, merging in round 5):

  • The AI assistant preset offers a clear choice: "Can view" (read) / "Can view and change" (read + write), with plain words about what "change" means ("create, edit and delete your events, notes, tasks and files; every change is logged and can be undone"). The default stays Can view, with one tap to switch.
  • After creating it, show copy-ready setup for common clients: the MCP URL (https://<host>/mcp), the auth header (Authorization: Bearer <app password>), and one-click snippets for Claude Code (claude mcp add --transport http calternal https://<host>/mcp --header "Authorization: Bearer …"), Claude Desktop / mcp.json, and ChatGPT connectors.
  • If the MCP switch in Settings → Apps is off, the chooser says so and offers to turn it on (today a disabled surface returns 403 with no hint).
    Test: e2e: create an AI-assistant password with "Can view and change" → its scopes are mcp: read, write; the setup snippets contain the right URL; with the MCP switch off, the UI offers to enable it.
## Owner question (2026-10-01): "Why is MCP read only? I wanna try it out." The App Password chooser's "AI assistant · MCP" preset only grants `mcp: read`. Write access exists only through "Custom scopes", which is not obvious. **Fix (in the #412 chooser, merging in round 5):** - The AI assistant preset offers a clear choice: **"Can view"** (read) / **"Can view and change"** (read + write), with plain words about what "change" means ("create, edit and delete your events, notes, tasks and files; every change is logged and can be undone"). The default stays **Can view**, with one tap to switch. - After creating it, show **copy-ready setup** for common clients: the MCP URL (`https://<host>/mcp`), the auth header (`Authorization: Bearer <app password>`), and one-click snippets for Claude Code (`claude mcp add --transport http calternal https://<host>/mcp --header "Authorization: Bearer …"`), Claude Desktop / mcp.json, and ChatGPT connectors. - If the **MCP switch** in Settings → Apps is off, the chooser says so and offers to turn it on (today a disabled surface returns 403 with no hint). **Test:** e2e: create an AI-assistant password with "Can view and change" → its scopes are `mcp: read, write`; the setup snippets contain the right URL; with the MCP switch off, the UI offers to enable it.
Author
Owner

Owner (2026-10-01): "the preset is stupid btw. it should allow writing!"
Decision: the AI assistant preset grants read + write by default (mcp: full). The read-only choice stays available as the alternative ("Can view").
Also found: in Custom scopes, "Write" means write WITHOUT read (AppPassword::allows matches the access exactly; only Full covers both). For a User that reads as broken. Fix the wording/model: offer "Can view" (read), "Can view and change" (full), and keep "Upload only" for file drop-style passwords. Remove bare write-only from the UI unless a protocol truly needs it (state which). Migrate existing write-only passwords to full only if that was clearly the intent; otherwise list them for the User.

**Owner (2026-10-01): "the preset is stupid btw. it should allow writing!"** Decision: the AI assistant preset grants **read + write by default** (`mcp: full`). The read-only choice stays available as the alternative ("Can view"). Also found: in Custom scopes, **"Write" means write WITHOUT read** (`AppPassword::allows` matches the access exactly; only `Full` covers both). For a User that reads as broken. Fix the wording/model: offer **"Can view"** (read), **"Can view and change"** (full), and keep "Upload only" for file drop-style passwords. Remove bare write-only from the UI unless a protocol truly needs it (state which). Migrate existing write-only passwords to full only if that was clearly the intent; otherwise list them for the User.
Author
Owner

Correction from the owner's words (2026-10-01: "the preset is stupid btw. it should allow writing!"): the AI assistant preset defaults to Can view and change (mcp read + write). "Can view" stays one tap away. Everything else in this issue stands.

Correction from the owner's words (2026-10-01: "the preset is stupid btw. it should allow writing!"): the AI assistant preset defaults to **Can view and change** (mcp read + write). "Can view" stays one tap away. Everything else in this issue stands.
Author
Owner

Starting #629 on job/app-pw-chooser. Branch base SHA: 15e17aeafc8ea160c109e62fba57f6961c39d21f (origin/dev at the current worktree base). I read the owner comments: the AI assistant preset defaults to Can view and change (mcp: full), with Can view as the alternative.

Starting #629 on `job/app-pw-chooser`. Branch base SHA: `15e17aeafc8ea160c109e62fba57f6961c39d21f` (`origin/dev` at the current worktree base). I read the owner comments: the AI assistant preset defaults to Can view and change (`mcp: full`), with Can view as the alternative.
Author
Owner

Finding: AppPasswordsGroup.svelte mapped the AI assistant preset to mcp: read and described it as unable to make changes. The chooser also exposed a bare Write grant. AppPassword::allows in crates/calternal-auth/src/store.rs grants both read and write only when the access is Full; Write alone does not include read. I am mapping “Can view and change” to mcp: full, retaining the read-only choice, and listing existing write-only credentials as “Can change only” without widening them.

Finding: `AppPasswordsGroup.svelte` mapped the AI assistant preset to `mcp: read` and described it as unable to make changes. The chooser also exposed a bare `Write` grant. `AppPassword::allows` in `crates/calternal-auth/src/store.rs` grants both read and write only when the access is `Full`; `Write` alone does not include read. I am mapping “Can view and change” to `mcp: full`, retaining the read-only choice, and listing existing write-only credentials as “Can change only” without widening them.
Author
Owner

Built

The AI assistant preset now defaults to Can view and change with MCP read and write access. Can view remains available. The chooser explains that changes are logged and can be undone. After creation, the user can copy the MCP name, URL, Authorization header, CLI setup command, or generic mcp.json. If MCP is off for the user, the UI offers to turn it on in place. Existing write-only grants display as Can change only. “Apple Devices” now uses the same section-heading role as “Automatic”.

Merged current origin/dev before final checks. Conflict resolution kept the new Notes integration in the Apple-device preset and preserved the current benchmark and calendar E2E changes.

Files

Feature files:

  • apps/docs/src/content/docs/guides/apps.md
  • apps/web/e2e/app-passwords.mjs
  • apps/web/e2e/route-perf.mjs
  • apps/web/src/routes/settings/account/AppPasswordsGroup.svelte
  • apps/web/src/routes/settings/api.svelte.ts
  • apps/web/src/routes/settings/apps/AppsSection.svelte
  • bench/run.sh

Merge conflict integration:

  • apps/web/e2e/calendar.mjs
  • bench/record.py
  • bench/test_record.py

Head

c9fa49ecece69c817c6865bd34fd39c173cf8b9b

Feature commit: 4cc807b3 — feat(app-passwords): offer full MCP assistant access.

Gates

  • cargo fmt --check: passed, no output (exit 0).
  • cargo clippy -p calternal-auth --all-targets -- -D warnings:
    Finished dev profile [unoptimized + debuginfo] target(s) in 16m 52s
  • cargo test -p calternal-auth:
    Finished test profile [unoptimized + debuginfo] target(s) in 16m 56s running 65 tests test result: ok. 65 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 37.11s running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
  • cargo clippy -p calternal-server --all-targets -- -D warnings:
    Finished dev profile [unoptimized + debuginfo] target(s) in 5m 36s
  • bun run check:
    $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
    User browser caches use userStorage; only documented device/public-link exceptions remain.
    Text sizes and UI shape values use shared role tokens.
    UI transitions and animation options use shared motion tokens or documented exceptions.
    Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/app-pw-chooser/apps/web
    Getting Svelte diagnostics...
    
    svelte-check found 0 errors and 0 warnings
    
  • bun run build: completed; adapter-static wrote the site to build.
  • cargo test -p calternal-server: interrupted with SIGINT, exit 130, after Cargo reported 4:30:55 elapsed. It has no passing test result. I stopped at the job’s time ceiling.
  • bun run test, the local MCP tools/list plus write call, adversarial probe, and benchmark were not run.

UX gaps closed

The default grant, access explanation, setup-copy controls, in-place user MCP enable action, and Apple Devices heading-role nit are implemented. The E2E script covers the requested chooser and MCP flows, but was not run, so pointer, touch, keyboard, undo propagation, and screen-reader behavior are not verified in a browser.

UX gaps left

No requested screenshots were captured or attached. The local server MCP tools/list and write call are unverified. The new benchmark profile has no run or numbers. The server test suite and web test suite remain unverified. No adversarial round was run.

Mac checks pending: capture the required macOS-emulated screenshots and review shortcut glyphs. The real macOS VM is offline per the owner rule.

Decisions

  • The owner specified full MCP access as the assistant preset default; the implementation uses that grant.
  • Existing write-only grants remain valid and are labeled “Can change only”; they are not migrated.
  • The current origin/dev Notes integration made the Apple-device preset a combined CalDAV/full and Notes/full grant, preserving the current “Sync with Your Devices” behavior. Please confirm this integration choice.
  • The chooser’s user-level MCP toggle reuses the existing setAppSurface helper and step-up flow.

No push, deploy, or issue closure was performed.

## Built The AI assistant preset now defaults to **Can view and change** with MCP read and write access. **Can view** remains available. The chooser explains that changes are logged and can be undone. After creation, the user can copy the MCP name, URL, Authorization header, CLI setup command, or generic `mcp.json`. If MCP is off for the user, the UI offers to turn it on in place. Existing write-only grants display as **Can change only**. “Apple Devices” now uses the same section-heading role as “Automatic”. Merged current `origin/dev` before final checks. Conflict resolution kept the new Notes integration in the Apple-device preset and preserved the current benchmark and calendar E2E changes. ## Files Feature files: - `apps/docs/src/content/docs/guides/apps.md` - `apps/web/e2e/app-passwords.mjs` - `apps/web/e2e/route-perf.mjs` - `apps/web/src/routes/settings/account/AppPasswordsGroup.svelte` - `apps/web/src/routes/settings/api.svelte.ts` - `apps/web/src/routes/settings/apps/AppsSection.svelte` - `bench/run.sh` Merge conflict integration: - `apps/web/e2e/calendar.mjs` - `bench/record.py` - `bench/test_record.py` ## Head `c9fa49ecece69c817c6865bd34fd39c173cf8b9b` Feature commit: `4cc807b3` — `feat(app-passwords): offer full MCP assistant access`. ## Gates - `cargo fmt --check`: passed, no output (exit 0). - `cargo clippy -p calternal-auth --all-targets -- -D warnings`: `Finished `dev` profile [unoptimized + debuginfo] target(s) in 16m 52s` - `cargo test -p calternal-auth`: `Finished `test` profile [unoptimized + debuginfo] target(s) in 16m 56s running 65 tests test result: ok. 65 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 37.11s running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s` - `cargo clippy -p calternal-server --all-targets -- -D warnings`: `Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 36s` - `bun run check`: ``` $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/app-pw-chooser/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` - `bun run build`: completed; adapter-static wrote the site to `build`. - `cargo test -p calternal-server`: interrupted with SIGINT, exit 130, after Cargo reported 4:30:55 elapsed. It has no passing test result. I stopped at the job’s time ceiling. - `bun run test`, the local MCP tools/list plus write call, adversarial probe, and benchmark were not run. ## UX gaps closed The default grant, access explanation, setup-copy controls, in-place user MCP enable action, and Apple Devices heading-role nit are implemented. The E2E script covers the requested chooser and MCP flows, but was not run, so pointer, touch, keyboard, undo propagation, and screen-reader behavior are not verified in a browser. ## UX gaps left No requested screenshots were captured or attached. The local server MCP tools/list and write call are unverified. The new benchmark profile has no run or numbers. The server test suite and web test suite remain unverified. No adversarial round was run. Mac checks pending: capture the required macOS-emulated screenshots and review shortcut glyphs. The real macOS VM is offline per the owner rule. ## Decisions - The owner specified full MCP access as the assistant preset default; the implementation uses that grant. - Existing write-only grants remain valid and are labeled “Can change only”; they are not migrated. - The current `origin/dev` Notes integration made the Apple-device preset a combined CalDAV/full and Notes/full grant, preserving the current “Sync with Your Devices” behavior. Please confirm this integration choice. - The chooser’s user-level MCP toggle reuses the existing `setAppSurface` helper and step-up flow. No push, deploy, or issue closure was performed.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#629
No description provided.