# Tokens and scopes

An agent never holds power of its own: it acts **with the named token it was given**,
and that token carries the same rules as any token created by hand from
*Settings › Connections and agents › Advanced access*.

## Read and write

A token carries one or two scopes: `read` and `write`.

- **`read`** allows reading — every `GET`, and write calls passed in simulation
  (`dry_run`). This is the scope for an agent you only want to trust with reading a
  schedule, a progress report, an export.
- **`write`** is required for everything else — every tool that places a block, moves a
  row, replies to a comment. A read-only token attempting one of these tools receives an
  explicit refusal (`SCOPE_INSUFFICIENT`), not a silent success.

A named token born from a `POST /oauth/authorize` carries the scopes the client requested
at the time of authorization (the consent form displays them) — Claude Code generally
requests both.

## One token per client

Every OAuth client that registers (Claude Code, Claude Desktop should it go through this
door, another agent) gets its own token, named after it — "MCP · Claude Code",
"MCP · `<client name>`". It isn't a shared token: two different agents have two different
tokens, two different rows under *Settings › Connections and agents › Connected applications*, and two different attributions
in the schedule's log ("Claude (you)", or "Claude (Anne)" if the token acts on behalf of
a user other than the instance's owner).

Duration: **thirty days**, with an automatic refresh valid for **ninety days** — a
single-use refresh, replaced by a fresh pair on every use; the access token's secret
changes, but it stays **the same named token** (the same identifier, the same row in
preferences) as long as the client keeps refreshing on time.

## Revocation

- From *Settings › Connections and agents › Connected applications*: revoking a named token cuts it off immediately, **and
  closes any live `/mcp` session it carried on the spot** — its streams, its resource
  subscriptions included. An agent attempting a call at the same moment gets a 401, not
  a lingering session.
- Through the OAuth protocol itself: `POST /oauth/revoke` (RFC 7009) revokes an access
  token, or a whole family of refreshes at once — the point Claude Code uses to log out
  cleanly.
- A **replayed** token (an authorization code or a refresh presented twice) is treated as
  a probable theft: the whole family of tokens descending from it is revoked instantly.

## What an agent can do, and what it can't

An agent can do everything the 101 tools cover: build, modify, analyze, share, publish,
export and import **schedules** — and, since `0.22.0`, post or read their own
**absences** (`list_absences`, `add_absence`, `remove_absence`, `get_schedule_risks`).
That's deliberately broad — it's the product.

An agent **cannot**:

- **manage tokens** (`/api/v1/me/tokens`) or screen sessions (`/api/v1/me/sessions`) —
  an MCP client doesn't create its own tokens, nor anyone else's;
- **change the password, unlink Google, or write to the profile**
  (`/api/v1/me/password`, `/api/v1/me/google`, `PUT /api/v1/me`) — these routes are
  reserved for a user session (the screen's cookie), refused to any named token with a
  refusal that says so explicitly ("tokens are managed with the screen's token, not with
  a named token");
- **export or delete the account itself, or change who you are.** This isn't a
  restriction bolted on after the fact: among the 101 tools, none touches the account's
  **settings** (password, profile, Google, export, deletion) — those stay reserved for a
  user session, as above. Only your **absences** (since `0.22.0`) are a piece of personal
  data a tool can post or read, because an agent should be able to say "I'm out" the way
  you would yourself — never another account's, and never a medical reason (the schema
  refuses it). The right to export and erase the **whole** account (GDPR) stays with the
  person; it isn't a capability delegated to an agent acting on their behalf, even with a
  `write` token.

*(A note of caution for this repository: the account export and deletion API routes,
added in sprint 16, aren't present in the branch lineage this guide is written from —
see the sprint's closing notes for what that means about the state of `docs/agents/`.
The absence of any dedicated account-related MCP tool, on the other hand, is verifiable
in the current catalog regardless of that point.)*

## An embedded view is not a named token

In an MCP Apps host, the [embedded view](vue-embarquee.md) (`show_schedule`) has **no
token of its own**: it reads and writes through the host, under the connector's named
token (or OAuth). For a client that does not render MCP Apps (Claude Code),
`show_schedule` returns an address carrying a token valid **for one hour**, capped to the
displayed schedule and to the role of whoever requested it, **read-only unless
`editable: true`** — a mechanism distinct from this page's named tokens, never visible nor
revocable from *Settings › Connections and agents › Connected applications*. Under that token, the member list carries no e-mail
address and the agenda no absence reason. It expires on its own; nothing more to remember
here.
