MCP Scopes
Les scopes, c'est le système de permissions fine pour les tokens MCP. Chaque tool déclare quels scopes il exige. Un token n'a accès qu'aux tools dont tous les scopes requis sont dans son array
scopes. C'est l'équivalent OAuth d'un "scope" — pensé pour limiter le rayon d'action d'un agent LLM.
Concept
Trackily expose 42 scopes organisés par domaine, en paires :read / :write (avec quelques exceptions pour les domaines purement read-only ou les meta-actions).
Le contrat est strict :
- Un tool déclare ses scopes (
scopes: [S.CAMPAIGNS_WRITE]) dans sonregisterTool. - À l'appel, le serveur vérifie que tous les scopes requis sont dans
tokenRow.scopes. Sinon, code d'erreur-32002Forbidden, audit log avec event_typeauth_fail. - Si un tool requiert plusieurs scopes (ex:
bind_landing_to_email_listnécessiteemail:writeETlandings:write), le token doit avoir les deux.
L'enforcement se fait dans autopilot.js:hasScope() :
function hasScope(tokenRow, required) {
if (!Array.isArray(required) || !required.length) return true;
const granted = Array.isArray(tokenRow?.scopes) ? tokenRow.scopes : [];
return required.every(s => granted.includes(s));
}
La liste complète
Reads + writes par domaine
| Scope | Rôle |
|---|---|
stats:read |
Lecture des stats agrégées (dashboard, KPIs, time series) |
campaigns:read |
Lecture des campagnes (list, get, search) |
campaigns:write |
Mutation des campagnes (create, update, pause, resume, duplicate, cost) |
offers:read |
Lecture des offres |
offers:write |
Mutation des offres (create, update, pause, resume, payout) |
landings:read |
Lecture des landings |
landings:write |
Mutation des landings (create, update, import, link to campaign, translate, A/B variants) |
sources:read |
Lecture des sources de trafic (Kadam, Meta, TikTok, custom) |
sources:write |
Mutation côté ad networks : pause/resume campagnes externes, update budget/bid |
networks:read |
Lecture des affiliate networks (Everflow, MaxBounty, etc.) |
networks:write |
Mutation des networks (rare — généralement réservé à admin) |
flows:read |
Lecture des flows (routing landings + offers) |
flows:write |
Mutation des flows |
automizer:read |
Lecture des règles Automizer |
automizer:write |
Mutation : create / update / delete / pause / resume rules |
reports:read |
Lecture des rapports groupés (par campaign, par source, par offer…) |
ai:generate |
Appels AI coûteux (génération landings, descriptions produits, traductions, compliance, etc.) |
settings:read |
Lecture des settings (config publique sans secrets) |
settings:write |
Mutation des settings — dangereux, réservé à admin |
Domaine e-commerce externe (Shopify, WooCommerce)
| Scope | Rôle |
|---|---|
stores:read |
Lecture des stores connectés |
stores:write |
Mutation : test_store_connection, etc. |
products:read |
Lecture des produits |
products:write |
Mutation : create/update/delete products + variants + images + metafields, sync from Shopify |
orders:read |
Lecture des orders externes (Shopify) ET native |
orders:write |
Mutation : fulfill, refund, cancel, tags, notes, mark as paid |
checkouts:read |
Lecture des abandoned checkouts |
customers:read |
Lecture des clients |
customers:write |
Mutation : create / update customers |
analytics:read |
Lecture des analytics e-commerce (revenue, conversion, best-selling) |
inventory:read |
Lecture des niveaux de stock |
inventory:write |
Mutation des niveaux de stock |
collections:read |
Lecture des collections produit |
collections:write |
Mutation : create / update / delete collections, add/remove product to collection |
discounts:read |
Lecture des codes promo |
discounts:write |
Mutation : create / delete codes, create price rules |
marketing:read |
Lecture marketing assets (script tags, webhooks) |
marketing:write |
Mutation : create / delete script tags + webhooks |
content:read |
Lecture pages CMS + articles |
content:write |
Mutation : create / update / delete pages + articles, metafields, SEO audit |
Domaine email
| Scope | Rôle |
|---|---|
email:read |
Lecture lists, subscribers, sequences, sends, suppression, smtp |
email:write |
Mutation : create lists / sequences / steps, enroll, unsubscribe, suppression, triggers, send test |
Les 4 presets
Pour éviter à l'opérateur d'avoir à cocher 42 cases, l'UI propose des presets one-click. Ils sont définis dans autopilot.js:SCOPE_PRESETS.
read_only
22 scopes, tous les :read du système. Aucune mutation possible. Cas d'usage : agent de lecture (résumé de la semaine, monitoring, dashboard).
stats:read · campaigns:read · offers:read · landings:read · sources:read ·
networks:read · flows:read · automizer:read · reports:read · settings:read ·
stores:read · products:read · orders:read · checkouts:read · customers:read ·
analytics:read · inventory:read · collections:read · discounts:read ·
marketing:read · content:read · email:read
operator
40 scopes, le preset le plus utilisé. Toutes les operations day-to-day, sauf settings:write (qui peut casser la config critique) et networks:write (qui touche aux paramètres des réseaux affiliate — rare). ai:generate est inclus pour permettre la génération AI de landings/descriptions.
C'est le bon défaut pour un Claude Desktop d'opérateur principal.
full
41 scopes, équivalent à admin moins settings:write. Donne tout, sauf le pouvoir de casser irréversiblement la config. À utiliser pour un agent puissant mais sécurisé.
admin
42 scopes, tous. Y compris settings:write. À réserver à un seul token "break-glass" pour les opérations one-off de maintenance, et stocké en coffre.
Tableau de correspondance preset → scopes
| Scope | read_only |
operator |
full |
admin |
|---|---|---|---|---|
stats:read |
OK | OK | OK | OK |
campaigns:read |
OK | OK | OK | OK |
campaigns:write |
— | OK | OK | OK |
offers:read |
OK | OK | OK | OK |
offers:write |
— | OK | OK | OK |
landings:read |
OK | OK | OK | OK |
landings:write |
— | OK | OK | OK |
sources:read |
OK | OK | OK | OK |
sources:write |
— | OK | OK | OK |
networks:read |
OK | OK | OK | OK |
networks:write |
— | — | OK | OK |
flows:read |
OK | OK | OK | OK |
flows:write |
— | OK | OK | OK |
automizer:read |
OK | OK | OK | OK |
automizer:write |
— | OK | OK | OK |
reports:read |
OK | OK | OK | OK |
ai:generate |
— | OK | OK | OK |
settings:read |
OK | OK | OK | OK |
settings:write |
— | — | — | OK |
stores:read |
OK | OK | OK | OK |
stores:write |
— | OK | OK | OK |
products:read |
OK | OK | OK | OK |
products:write |
— | OK | OK | OK |
orders:read |
OK | OK | OK | OK |
orders:write |
— | OK | OK | OK |
checkouts:read |
OK | OK | OK | OK |
customers:read |
OK | OK | OK | OK |
customers:write |
— | OK | OK | OK |
analytics:read |
OK | OK | OK | OK |
inventory:read |
OK | OK | OK | OK |
inventory:write |
— | OK | OK | OK |
collections:read |
OK | OK | OK | OK |
collections:write |
— | OK | OK | OK |
discounts:read |
OK | OK | OK | OK |
discounts:write |
— | OK | OK | OK |
marketing:read |
OK | OK | OK | OK |
marketing:write |
— | OK | OK | OK |
content:read |
OK | OK | OK | OK |
content:write |
— | OK | OK | OK |
email:read |
OK | OK | OK | OK |
email:write |
— | OK | OK | OK |
Composition multi-scope
Quelques tools demandent plusieurs scopes :
| Tool | Scopes requis | Pourquoi |
|---|---|---|
bind_landing_to_email_list |
email:write + landings:write |
mute une landing pour pointer une liste |
create_email_smtp_server |
email:write + settings:write |
un SMTP impacte tout l'instance, traité comme un setting |
assign_cloaking_workflow_to_campaign |
automizer:write (workflow) + campaigns:write |
mute la campagne pour pointer un workflow |
set_inventory_level |
inventory:write + products:read |
modifie le stock après lookup du produit |
Si un token n'a qu'un des scopes requis, l'appel est refusé avec la liste complète des scopes manquants dans error.data.required.
Choisir un preset
Arbre de décision rapide :
Tu veux qu'un agent fasse...
... du reporting / monitoring uniquement
→ read_only
... des opérations day-to-day (pause, scale, create campaign, send emails)
→ operator
... du day-to-day + des modifications de réseaux affiliés
→ full
... touch settings critiques (clés API, secrets, perms users)
→ admin (à n'utiliser QUE pour ce token-là, jamais en partage)
Custom (cocher à la main)
L'UI te permet de cocher les scopes individuellement plutôt que d'utiliser un preset. Utile pour :
- Un agent dédié à la commerce uniquement :
stores:read/write,products:read/write,orders:read/write,customers:read/write,analytics:read,inventory:read/write,discounts:read/write,collections:read/write,content:read/write. - Un agent dédié à l'email :
email:read,email:write,landings:read(pour les binds),campaigns:read(pour les conversion triggers). - Un agent dédié au reporting financier :
stats:read,analytics:read,reports:read,orders:read,customers:read.
Un token avec un scope minimal est plus sûr — moins de surface d'attaque si exfiltré, moins de risque qu'un LLM hallucinant fasse n'importe quoi.
Évolutions
Les scopes sont versionnés implicitement via la liste ALL_SCOPES. Quand on ajoute un nouveau domaine (genre automations:read/write pour Phase 14), on ajoute des scopes, on n'en supprime ni n'en renomme jamais (back-compat tokens existants).
Les SCOPE_PRESETS sont recalculés à chaque release pour inclure les nouveaux scopes appropriés. Un token créé avec preset operator en 2024 ne reçoit PAS automatiquement les nouveaux scopes — il faut l'éditer ou le recréer.
Erreurs courantes
Missing scope for X+ token créé avecoperator— vérifie que le tool n'exige passettings:writeounetworks:write. Si oui, passe enfullouadmin(rare).- Agent qui peut lire mais pas écrire alors que je voulais l'inverse — preset
read_onlyau lieu deoperator. Édite le token, change le preset. - Tool qui marche en local mais pas en prod — token de prod avec un scope manquant. Compare les deux tokens.
- Audit log plein de
auth_fail"Missing scope" — l'agent essaie d'appeler des tools hors de son scope. Soit limite le system prompt de l'agent, soit étend les scopes.
Voir aussi
- Tokens — comment créer un token avec un scope donné
- Tier System — l'autre couche de défense pour les destructives
- Tools Reference — voir le scope requis de chaque tool