Communitygithub.com

asana-gate

Opérez Asana via asana-gate, la passerelle de politiques qui place une politique YAML déclarative devant l'API REST d'Asana pour les agents IA, sous forme d'outils MCP (asana_*) et de la ligne de commande asana-gate.

Qu'est-ce que asana-gate ?

La compétence `asana-gate` est une passerelle de politiques qui s'interpose entre un agent IA et l'API REST d'Asana. Elle s'appuie sur un fichier de politique YAML pour définir, par périmètre (espace de travail, équipe, projet, section, tâche), les actions autorisées et les contraintes appliquées aux requêtes. L'agent peut interagir avec Asana via des outils MCP (comme `asana_create_task`, `asana_update_tasks`) ou en ligne de commande (`asana-gate task list`, `asana-gate task get`). La politique contrôle l'accès aux données : les objets masqués sont invisibles, tout refus de la politique est signalé par un message d'erreur HTTP commençant par `asana-gate:`. Les réponses incluent le champ `allowed_actions` qui liste les actions possibles sur chaque objet ; si une action n'y figure pas, elle sera refusée. La compétence est utilisable avec Claude Code, Cursor, Codex ou tout client prenant en charge MCP, et empêche les comportements imprévus de l'IA en imposant des limites de taux, des validations de format et des confirmations humaines.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sincekmori/asana-gate/tree/HEAD/skills/asana-gate

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait asana-gate ?

asana-gate est une passerelle de politiques placée devant l'API REST d'Asana. Une politique YAML définit, par périmètre (espace de travail, équipe, portfolio, projet, section, tâche), les actions qu'un agent peut entreprendre et la manière dont ses requêtes sont formatées ; la passerelle les applique à chaque requête, qu'elle arrive sous forme d'appel d'outil MCP ou de commande asana-gate. Tout ce que vous pouvez voir ou faire via asana-gate est déterminé par cette politique, pas par Asana : les objets que la politique cache n'existent pas pour vous, et les refus se présentent sous forme d'erreurs de type HTTP dont le message commence par asana-gate:.

Lisez d'abord les réponses de la passerelle

Chaque objet renvoyé par la passerelle contient allowed_actions : les actions <ressource>:<verbe> que la politique autorise sur cet objet à ce moment, comme task:update ou story:create. Vérifiez-le avant d'écrire, car une action qui en est absente sera refusée : planifiez en fonction de ce qui est listé plutôt que d'essayer et d'échouer.

RéponseSignificationQue faire
404 <type>: ID non reconnu : <gid>L'objet n'existe pas, ou la politique le cache ; la passerelle rend délibérément les deux cas indiscernables (le même 404 qu'Asana envoie)Ne réessayez pas et n'essayez pas d'autres gid. Dites que l'objet n'est pas visible selon la politique ; son propriétaire peut exécuter asana-gate explain <gid> pour voir quelle règle le cache
403 asana-gate: <action> n'est pas autorisée sur <type> <gid>L'objet est visible, mais la politique n'autorise pas cette action sur celui-ciSignalez-le et proposez une action parmi allowed_actions ; l'élargissement de la politique relève du propriétaire
403 asana-gate: la mise à jour de <ressource>.<membre> n'est pas autorisée ici (champs autorisés : …)La mise à jour a touché un membre en dehors de la liste autorisée de fields de la règleRenvoyez avec uniquement les membres autorisés
400 asana-gate: la <ressource> ne satisfait pas la politique : …Une contrainte de la politique : un membre requis est manquant ou effacé, un préfixe ou un format est incorrect, une valeur n'est pas autorisée, un membre est interditCorrigez la requête exactement comme le message l'indique et renvoyez-la
428 asana-gate: <action> nécessite la confirmation d'une personneLa politique exige qu'un humain approuve cette actionVia MCP, répondez à la sollicitation affichée par le client ; depuis un terminal, relancez avec --yes
429 asana-gate: <action> est limitée à N par <période>Un plafond de débit que la politique définit pour cette action dans ce périmètreAttendez la fin de la période ; ne bouclez pas dessus

Les listes (projets, tâches, recherche, typeahead, événements) sont filtrées silencieusement : les objets cachés sont simplement absents, rien n'indique combien ont été retirés, et une page comporte next_page.offset pour continuer avec offset. Les propres erreurs d'Asana sont transmises sans modification, sans le préfixe asana-gate: : un 402 signifie que le plan de l'espace de travail ne dispose pas de la fonctionnalité (recherche, champs personnalisés, portfolios et buts nécessitent un plan payant), un 400 simple est le rejet du corps par Asana, un 403 simple est la permission du jeton lui-même (les événements du journal d'audit, les événements d'espace de travail et les exportations d'organisation nécessitent un compte de service sur un niveau Enterprise ; les points d'accès Agents en accès anticipé nécessitent le drapeau ai_teammate_actors dans le paramètre asana.enable des réglages). Cherchez le préfixe : avec lui, la politique a décidé ; sans lui, c'est Asana qui a décidé.

Travailler via MCP

Le serveur expose les outils sélectionnés que la politique pourrait éventuellement autoriser, plus trois outils génériques :

  • asana_create_tasks et asana_update_tasks prennent jusqu'à 50 tâches à la fois et répondent avec un status_code et un body par tâche, dans l'ordre ; certaines peuvent échouer tandis que d'autres réussissent.
  • asana_request appelle n'importe quelle opération REST Asana (method, path en dessous de /api/1.0, query, body en tant qu'objet data) en passant par la même politique ; un POST /batch via cet outil accepte jusqu'à 50 actions.
  • asana_operations liste les opérations avec l'action de politique dont chacune a besoin ; asana_allowed_actions indique ce que vous pouvez faire avec un objet.
OutilLigne de commandeCe qu'il fait
asana_search_tasksasana-gate task searchRecherche de tâches en texte intégral et par filtre dans l'espace de travail (API de recherche Asana ; plans payants uniquement). Les résultats sont limités aux tâches que la politique rend visibles.
asana_list_tasksasana-gate task listListe les tâches dans un projet, une section, avec un tag, ou assignées à un utilisateur (l'un des paramètres projet, section, tag ou assigné est requis). Chaque tâche contient allowed_actions.
asana_get_taskasana-gate task get <task_gid>Lit une tâche avec ses champs complets et allowed_actions.
asana_create_taskasana-gate task createCrée une tâche dans un ou plusieurs projets (éventuellement dans une section), sous une tâche parente, ou sans rattachement dans l'espace de travail.
asana_update_taskasana-gate task update <task_gid>Met à jour les champs d'une tâche. Compléter nécessite task:complete, assigner nécessite task:assign ; les autres champs nécessitent task:update (éventuellement limité à une liste autorisée).
asana_create_tasksasana-gate task create-manyCrée jusqu'à 50 tâches en un seul appel, chacune comme le ferait asana_create_task. Le résultat contient un status_code et un body par tâche, dans l'ordre ; Asana peut faire échouer certaines tandis que d'autres réussissent. Un refus de politique pour une tâche rejette l'ensemble de l'appel avant toute exécution, et son message nomme la tâche (actions[i]).
asana_update_tasksasana-gate task update-manyMet à jour jusqu'à 50 tâches en un seul appel, chacune comme le ferait asana_update_task. Le résultat contient un status_code et un body par tâche, dans l'ordre ; Asana peut faire échouer certaines tandis que d'autres réussissent. Un refus de politique pour une tâche rejette l'ensemble de l'appel avant toute exécution, et son message nomme la tâche (actions[i]).
asana_delete_taskasana-gate task delete <task_gid>Supprime une tâche (elle est déplacée dans la corbeille d'Asana).
asana_list_subtasksasana-gate task subtasks <task_gid>Liste les sous-tâches directes d'une tâche.
asana_create_subtask—Crée une sous-tâche sous une tâche ; elle hérite du périmètre du parent sauf si des projets sont spécifiés.
asana_set_task_parentasana-gate task set-parent <task_gid>Fait d'une tâche une sous-tâche d'une autre (ou une tâche de niveau supérieur avec un parent null).
asana_add_task_to_projectasana-gate task add-project <task_gid>Rattache une tâche à un projet, éventuellement dans une section.
asana_remove_task_from_projectasana-gate task remove-project <task_gid>Retire une tâche d'un de ses projets.
asana_move_task_to_sectionasana-gate task move <task_gid>Déplace une tâche dans une section d'un projet auquel elle appartient (nécessite task:move aux deux extrémités).
asana_add_tag_to_taskasana-gate task tag <task_gid>Applique un tag à une tâche (nécessite tag:apply dans le périmètre de la tâche).
asana_remove_tag_from_taskasana-gate task untag <task_gid>Retire un tag d'une tâche (nécessite tag:apply dans le périmètre de la tâche).
asana_add_task_dependenciesasana-gate task add-dependencies <task_gid>Marque les tâches dont cette tâche dépend ; chaque tâche référencée doit être visible.
asana_remove_task_dependenciesasana-gate task remove-dependencies <task_gid>Supprime les dépendances d'une tâche.
asana_list_task_storiesasana-gate task comments <task_gid>Liste les commentaires et l'activité (histoires) d'une tâche.
asana_create_commentasana-gate task comment <task_gid>Ajoute un commentaire (histoire) à une tâche.
asana_update_storyasana-gate task update-comment <story_gid>Met à jour le texte d'un commentaire (histoire).
asana_delete_storyasana-gate task delete-comment <story_gid>Supprime un commentaire (histoire).
asana_create_projectasana-gate project createCrée un projet dans un espace de travail ou une équipe, avec des champs et un statut de coloris parmi les options de l'équipe.
asana_update_projectasana-gate project update <project_gid>Met à jour les champs d'un projet.
asana_delete_projectasana-gate project delete <project_gid>Supprime un projet (le déplace dans la corbeille).
asana_get_projectasana-gate project get <project_gid>Lit un projet avec ses champs.
asana_list_projectsasana-gate project listListe les projets visibles dans l'espace de travail ou l'équipe (l'un d'eux doit être donné).
asana_list_project_sectionsasana-gate project sections <project_gid>Liste les sections d'un projet dans l'ordre (la première section est Nouvelle section).
asana_create_project_sectionasana-gate project add-section <project_gid>Ajoute une section à un projet.
asana_add_custom_field_to_projectasana-gate project add-custom-field <project_gid>Ajoute un champ personnalisé à un projet (pour les projets disposant de champs personnalisés ; nécessite l'action de politique project:update).
asana_get_workspaceasana-gate workspace get <workspace_gid>Lit un espace de travail.
asana_list_workspacesasana-gate workspace listListe les espaces de travail visibles.
asana_list_teamsasana-gate team listListe les équipes d'un espace de travail.
asana_get_teamasana-gate team get <team_gid>Lit une équipe.
asana_list_team_projectsasana-gate team projects <team_gid>Liste les projets d'une équipe.
asana_list_team_usersasana-gate team users <team_gid>Liste les membres d'une équipe.
asana_get_userasana-gate user get <user_gid>Lit un utilisateur.
asana_list_usersasana-gate user listListe les utilisateurs (dans un espace de travail, ou l'espace de travail par défaut).
asana_get_current_userasana-gate user meLit l'utilisateur actuel.
asana_get_portfolioasana-gate portfolio get <portfolio_gid>Lit un portfolio.
asana_list_portfoliosasana-gate portfolio listListe les portfolios visibles.
asana_list_portfolio_itemsasana-gate portfolio items <portfolio_gid>Liste les éléments d'un portfolio (projets, portfolios).
asana_get_custom_fieldasana-gate custom-field get <custom_field_gid>Lit un champ personnalisé.
asana_list_custom_fieldsasana-gate custom-field listListe les champs personnalisés dans un espace de travail ou un projet (selon l'API ; l'un ou l'autre doit être donné).
asana_get_project_briefasana-gate project brief <project_gid>Lit le briefing d'un projet.
asana_update_project_briefasana-gate project update-brief <project_gid>Met à jour le briefing d'un projet.
asana_get_sectionasana-gate section get <section_gid>Lit une section.
asana_list_task_enumsasana-gate task enumsListe les tâches enum (prédéfinies) disponibles pour les champs personnalisés de type énumération (via le point d'accès typeahead d'Asana).
asana_requestasana-gate raw <method> <path>Appelle n'importe quelle opération REST Asana via la politique (avec la possibilité d'envoyer des données --data). Avec POST /batch, jusqu'à 50 actions ; chaque élément de lot est exécuté individuellement dans la politique.
asana_operationsasana-gate operationsRenvoie la liste de toutes les opérations avec l'action de politique dont chacune a besoin.
asana_allowed_actionsasana-gate allowed-actions <type> <gid>Interroge la politique sur ce qui est autorisé sur un objet par son type et son gid (ne fait pas d'appel à l'API Asana ; la politique elle-même décide).

Travailler en ligne de commande

Tous les outils MCP sont accessibles via la commande asana-gate. La syntaxe générale est:

asana-gate <ressource> <action> [<id>] [--key value]

Les clés et valeurs de la ligne de commande correspondent aux paramètres de l'outil MCP : les clés --d'un_trait_deviennent un_trait. Les valeurs booléennes s'écrivent --flag ou --no-flag. Les listes et les objets sont des chaînes JSON.

Obtenez l'aide d'une sous-commande avec asana-gate help <commande> ou asana-gate <commande> --help. asana-gate explain <gid> interroge la politique pour savoir quelle règle s'applique à un gid : elle indique si c'est un refus (masqué) ou une autorisation. asana-gate dump-policy imprime la politique active au format YAML pour vérifier sa configuration.

Lorsqu'une action nécessite --yes (confirmation humaine), vous pouvez la passer sur la ligne de commande pour éviter la sollicitation interactive. asana-gate lui-même supporte des options globales :

OptionSignification
--asana-tokenJeton d'accès personnel Asana (remplace ASANA_TOKEN).
--policyChemin vers le fichier de politique YAML (remplace ASANA_GATE_POLICY).
--verboseImprime la correspondance détaillée des règles et la requête/réponse HTTP.
--no-colorDésactive la coloration de la sortie.
--outputFormat de sortie : text (tableaux simples, par défaut) ou json.
--versionImprime la version.
--yesConfirme toutes les actions qui nécessitent --yes dans la politique (à utiliser avec précaution).

Écrire une politique

C'est la partie cruciale : une politique est un fichier YAML qui dit, par périmètre, ce qui est autorisé et comment les requêtes sont modifiées avant d'atteindre Asana. Chaque règle contient :

  • scope: une paire clé-valeur identifiant le périmètre (par exemple workspace:"1201234567890", project:"1201234567890).
  • where: optionnel. Une condition sur les propriétés de l'objet pour que la règle s'applique (par exemple tags: ["1201234567890"]).
  • allow: liste des actions autorisées (par exemple ['task:create', 'task:update']).
  • deny: liste des actions refusées (a priorité sur allow).
  • confirm: optionnel. true pour exiger une confirmation humaine sur chaque action autorisée.
  • constraints: contraintes sur les valeurs autorisées pour certains membres, requises, préfixées, formatées, ou interdites.
  • fields: liste autorisée des champs que l'agent peut mettre à jour dans une action update ; tout champ en dehors est refusé.
  • rate: plafond de débit N/period (période parmi second, minute, hour, day).

Exemple de règle :

- scope:
    workspace: "1201234567890"
  where:
    projects: ["1201234567890"]
  allow:
  - task:create
  - task:update
  - task:move
  - story:create
  deny:
  - task:delete
  confirm: true
  constraints:
    required_members: ["name", "projects"]
    prefixes:
      name: "[DEV] "
    forbidden_members: ["due_on", "assignee"]
  rate: 50/minute

Le moteur de politique évalue les règles dans l'ordre pour chaque requête et applique la première règle correspondante ; si aucune règle ne correspond, l'action est refusée. Utilisez asana-gate explain <gid> pour déboguer quelle règle s'applique à un objet.

Configuration

  • Jeton Asana : ASANA_TOKEN (variable d'environnement) ou --asana-token.
  • Fichier de politique : ASANA_GATE_POLICY (variable d'environnement, chemin vers un fichier YAML) ou --policy.
  • Les outils MCP peuvent être configurés dans claude_desktop_config.json:
{
  "mcpServers": {
    "asana-gate": {
      "command": "npx",
      "args": ["-y", "asana-gate"]
    }
  }
}

Dépannage

  • Le 404 d'une tâche que vous venez de voir peut signifier que la politique a changé ou que le gid est incorrect.
  • Le préfixe asana-gate: dans l'erreur signifie que la politique a refusé ; sans lui, c'est Asana.
  • asana-gate dump-policy imprime la politique active.
  • asana-gate explain <gid> dit pourquoi un objet est caché ou autorisé.
  • Les paramètres régionaux de la politique ne sont pas traduits dans son mécanisme ; l'interface utilisateur peut être en anglais.

Notes de version

  • v1.0.0 : Version initiale.
  • v1.1.0 : Ajout du support MCP et de la ligne de commande.
  • v2.0.0 : Réécriture complète du moteur de politique, ajout des contraintes et du plafond de débit.

Licence

MIT

Skills associés