An AI assistant talks to SAQ through the MCP server with a token. Before configuring the client, decide whose token it holds, because that decides what the assistant sees and how its actions are attributed.
Agent account or personal token?
| Agent account key | Personal token | |
|---|---|---|
| Attribution | Actions show the agent's name (for example claude@acme) |
Actions show the person's name, marked as done through a token on their behalf |
| Project access | Member of every project, including future ones; Member role | Exactly what the person can see; can be narrowed to named projects |
| Inbox | With the triage scope | With the triage scope, workspace users only |
| Who creates it | Owner or Admin, under Settings → Members → Agent accounts | The person, under Account → API tokens |
| MFA | None: the agent never logs in | Owners and Admins need two-factor authentication at minting; forced-SSO domains need an SSO session |
Personal queue (get_context_pack.mine, /my) |
The agent's own, usually empty | The person's |
| Seats | Free | The person's existing seat |
| Lifecycle | One live key; Rotate replaces it | Expires or is revoked; revoked automatically on role change |
Use an agent account for a shared assistant that works across the workspace (triage, summaries, drafting comments) and must be recognisable as a bot. Use a personal token when the assistant acts as one person, for example a developer's Claude Code session that logs that developer's own time. Time logged through an agent key belongs to the agent, not to a person.
Scopes to grant
- read for summaries, search, boards, timesheets, and the documentation tools.
- write to create and update tickets, comment, link, and log time.
- triage only if the assistant should read and route the shared Inbox.
Start with read, add write once you trust the prompts, and keep triage for assistants that are meant to handle incoming email. Set an address restriction if the assistant runs from a fixed address.
Configure the client
Copy the snippet from Settings → Channels → MCP setup and replace saq_YOUR_TOKEN. For Claude Code:
{
"mcpServers": {
"saq": {
"type": "http",
"url": "https://saq.no/mcp",
"headers": { "Authorization": "Bearer saq_YOUR_TOKEN" }
}
}
}
Cursor uses the same object without "type". Any other MCP client that supports Streamable HTTP with a static header works the same way; see Connect an MCP client for the transport details.
First calls
list_docs, thensearch_docswith a question such as "who can close a period": the assistant learns how SAQ behaves from this documentation instead of guessing. These tools work with any token.get_context_pack: one snapshot of assigned, overdue, due-soon, blocked, stale, and unbilled tickets, the current period's time, and bank balances.search_ticketswithproject,stateCategory: "open", orqto find work, thenget_ticketfor details.add_commentwith an explicitaudience(stafffor notes only workspace users should read) andlog_timewith a ticket, date, and minutes when the assistant is allowed to write.
Aliases keep prompts readable: project keys, kind and state keys, and email addresses resolve inside the workspace; me refers to the token's owner.
Safety limits
- The assistant cannot close periods, run or void billing, delete or archive tickets, grant viewers, change workspace settings, or manage members and tokens, whatever its scopes:
close_periodandcreate_billing_runare always refused, and those routes are not open to tokens. - Everything it creates carries
source: "mcp", so people can tell assistant output from human input in the timeline. - Comments it writes are visible to the audience it chooses;
sharedreaches client users. Tell the assistant which audience to use. - It sees only what its token's owner sees, and every request re-checks memberships and project grants.
- Rate limits apply per token (120 requests per minute) and per workspace plan; a chatty assistant shares the plan budget with every other integration.
Rotation and revocation
Rotate an agent's key on Settings → Members (Rotate): the old key stops working immediately and the new one keeps the same name, scopes, address restriction, and expiry. Revoke a personal token under Account → API tokens, or any token under Settings → API tokens as an Owner or Admin. Update the client configuration with the new secret; nothing else changes.