Communitygithub.com

sincekmori/asana-gate

Betreiben von Asana über asana-gate, die Policy-Gateway, die eine deklarative YAML-Policy vor die Asana REST API für KI-Agenten schaltet, als MCP-Tools (asana_*) und die asana-gate Kommandozeile.

Was ist asana-gate?

asana-gate ist eine Policy-Gateway-Schicht, die vor der Asana REST API sitzt und den Zugriff für KI-Agenten über eine zentrale YAML-Policy steuert. Diese Policy definiert pro Scope (Workspace, Team, Portfolio, Projekt, Abschnitt, Aufgabe), welche Aktionen ein Agent ausführen darf und wie seine Anfragen geformt werden. Die Gateway erzwingt diese Regeln bei jeder Anfrage, unabhängig davon, ob sie als MCP-Tool-Aufruf oder über den `asana-gate` Befehl eingeht. Das Tool bietet über 40 MCP-Tools für die Asana-Interaktion (z.B. Aufgaben erstellen/aktualisieren/löschen, Kommentare, Projekte, Portfolios) sowie drei generische Tools (`asana_create_tasks`, `asana_update_tasks`, `asana_request`), um Batch-Operationen und beliebige API-Aufrufe durchzuführen. Die Antworten der Gateway enthalten immer `allowed_actions`, die anzeigen, welche Aktionen für ein Objekt erlaubt sind. Verweigerungen werden als HTTP-ähnliche Fehler mit dem Präfix `asana-gate:` zurückgegeben, was sie klar von Asana-eigenen Fehlern unterscheidet. Die Policy unterstützt auch Constraint-Prüfungen, Rate Limits und menschliche Bestätigungen für kritische Aktionen.

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

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht asana-gate?

asana-gate ist eine Policy-Gateway vor der Asana REST API. Eine YAML-Policy legt pro Scope (Workspace, Team, Portfolio, Projekt, Abschnitt, Aufgabe) fest, welche Aktionen ein Agent durchführen darf und wie seine Anfragen geformt werden; die Gateway erzwingt dies bei jeder Anfrage, unabhängig davon, ob sie als MCP-Tool-Aufruf oder als asana-gate Befehl eingeht. Alles, was Sie darüber sehen oder tun können, wird durch diese Policy entschieden, nicht durch Asana: Objekte, die die Policy verbirgt, existieren für Sie nicht, und Verweigerungen kommen als HTTP-ähnliche Fehler zurück, deren Nachricht mit asana-gate: beginnt.

Lesen Sie zuerst die Antworten der Gateway

Jedes von der Gateway zurückgegebene Objekt enthält allowed_actions: die <Resource>:<Verb>-Aktionen, die die Policy aktuell darauf erlaubt, wie task:update oder story:create. Überprüfen Sie es vor dem Schreiben, denn eine nicht darin enthaltene Aktion wird verweigert: Planen Sie basierend auf dem, was aufgeführt ist, anstatt es zu versuchen und zu scheitern.

AntwortBedeutungWas zu tun ist
404 <Typ>: Keine erkannte ID: <gid>Das Objekt existiert nicht oder die Policy verbirgt es; die Gateway macht die beiden bewusst ununterscheidbar (derselbe 404, den Asana sendet)Wiederholen Sie nicht oder versuchen Sie andere gids. Sagen Sie, das Objekt ist unter der Policy nicht sichtbar; sein Besitzer kann asana-gate explain <gid> ausführen, um zu sehen, welche Regel es verbirgt
403 asana-gate: <Aktion> ist für <Typ> <gid> nicht erlaubtDas Objekt ist sichtbar, aber die Policy erlaubt diese Aktion dort nichtMelden Sie es und bieten Sie eine Aktion aus allowed_actions an; die Erweiterung der Policy ist Sache des Besitzers
403 asana-gate: Das Aktualisieren von <Resource>.<Mitglied> ist hier nicht erlaubt (erlaubte Felder: …)Die Aktualisierung betraf ein Mitglied außerhalb der fields-Whitelist der RegelSenden Sie es nur mit den erlaubten Mitgliedern erneut
400 asana-gate: Die <Resource> erfüllt die Policy nicht: …Eine Einschränkung der Policy: ein erforderliches Mitglied fehlt oder wurde gelöscht, ein Präfix oder Format ist falsch, ein Wert ist nicht erlaubt, ein Mitglied ist verbotenKorrigieren Sie die Anfrage genau wie in der Nachricht beschrieben und senden Sie sie erneut
428 asana-gate: <Aktion> benötigt die Bestätigung einer PersonDie Policy möchte, dass ein Mensch diese Aktion genehmigtAntworten Sie über MCP auf die Abfrage, die der Client zeigt; führen Sie von einer Shell aus den Befehl mit --yes erneut aus
429 asana-gate: <Aktion> ist auf N pro <Zeitraum> begrenztEin von der Policy für diese Aktion in diesem Scope festgelegtes Rate-LimitWarten Sie, bis der Zeitraum abgelaufen ist; wiederholen Sie es nicht in einer Schleife

Listen (Projekte, Aufgaben, Suche, Typeahead, Ereignisse) werden still herausgefiltert: versteckte Objekte sind einfach nicht vorhanden, es wird nicht angegeben, wie viele entfernt wurden, und eine Seite enthält next_page.offset, um mit offset fortzufahren. Asanas eigene Fehler werden unverändert durchgelassen, ohne das Präfix asana-gate:: ein 402 bedeutet, dass dem Workspace-Plan die Funktion fehlt (Suche, benutzerdefinierte Felder, Portfolios und Ziele benötigen einen kostenpflichtigen Plan), ein einfacher 400 ist Asanas Ablehnung des Bodys, ein einfacher 403 ist die eigene Berechtigung des Tokens (Audit-Log-Ereignisse, Workspace-Ereignisse und Organisationsexporte benötigen ein Servicekonto auf Enterprise-Stufe; die Early-Access-Agents-Endpunkte benötigen das Flag ai_teammate_actors in den Einstellungen von asana.enable). Achten Sie auf das Präfix: Damit hat die Policy entschieden, ohne hat Asana entschieden.

Arbeiten über MCP

Der Server stellt die kuratierten Tools bereit, die die Policy jemals erlauben könnte, plus drei generische:

  • asana_create_tasks und asana_update_tasks akzeptieren bis zu 50 Aufgaben auf einmal und antworten mit einem status_code und body pro Aufgabe, in der Reihenfolge; einige können fehlschlagen, während andere erfolgreich sind.
  • asana_request ruft jede beliebige Asana REST-Operation (method, path unter /api/1.0, query, body als data-Objekt) durch dieselbe Policy auf; ein POST /batch darüber akzeptiert bis zu 50 Aktionen.
  • asana_operations listet die Operationen mit der Policy-Aktion auf, die jede benötigt; asana_allowed_actions sagt Ihnen, was Sie mit einem Objekt tun dürfen.
ToolKommandozeileWas es tut
asana_search_tasksasana-gate task searchVolltext- und gefilterte Aufgabensuche im Workspace (Asana Search API; nur kostenpflichtige Pläne). Ergebnisse sind auf Aufgaben beschränkt, die die Policy sichtbar macht.
asana_list_tasksasana-gate task listListet Aufgaben in einem Projekt, einem Abschnitt, mit einem Tag oder einem Benutzer zugewiesen (eines von Projekt, Abschnitt, Tag oder Zugewiesener ist erforderlich). Jede Aufgabe enthält allowed_actions.
asana_get_taskasana-gate task get <task_gid>Liest eine Aufgabe mit ihren vollständigen Feldern und allowed_actions.
asana_create_taskasana-gate task createErstellt eine Aufgabe in einem oder mehreren Projekten (optional in einem Abschnitt), unter einer übergeordneten Aufgabe oder ohne Startpunkt im Workspace.
asana_update_taskasana-gate task update <task_gid>Aktualisiert Felder einer Aufgabe. Abschließen benötigt task:complete, Zuweisen benötigt task:assign; andere Felder benötigen task:update (möglicherweise auf eine Whitelist beschränkt).
asana_create_tasksasana-gate task create-manyErstellt bis zu 50 Aufgaben in einem Aufruf, jede wie asana_create_task es tun würde. Das Ergebnis enthält einen status_code und body pro Aufgabe, in der Reihenfolge; Asana kann einige fehlschlagen lassen, während andere erfolgreich sind. Eine Policy-Ablehnung einer Aufgabe lehnt den gesamten Aufruf ab, bevor etwas ausgeführt wird, und ihre Nachricht nennt die Aufgabe (actions[i]).
asana_update_tasksasana-gate task update-manyAktualisiert bis zu 50 Aufgaben in einem Aufruf, jede wie asana_update_task es tun würde. Das Ergebnis enthält einen status_code und body pro Aufgabe, in der Reihenfolge; Asana kann einige fehlschlagen lassen, während andere erfolgreich sind. Eine Policy-Ablehnung einer Aufgabe lehnt den gesamten Aufruf ab, bevor etwas ausgeführt wird, und ihre Nachricht nennt die Aufgabe (actions[i]).
asana_delete_taskasana-gate task delete <task_gid>Löscht eine Aufgabe (sie wird in Asana in den Papierkorb verschoben).
asana_list_subtasksasana-gate task subtasks <task_gid>Listet die direkten Unteraufgaben einer Aufgabe auf.
asana_create_subtask—Erstellt eine Unteraufgabe unter einer Aufgabe; sie erbt den Scope des übergeordneten Elements, es sei denn, Projekte werden angegeben.
asana_set_task_parentasana-gate task set-parent <task_gid>Macht eine Aufgabe zu einer Unteraufgabe einer anderen (oder zu einer Aufgabe der obersten Ebene mit parent null).
asana_add_task_to_projectasana-gate task add-project <task_gid>Fügt eine Aufgabe in ein Projekt ein, optional in einen Abschnitt.
asana_remove_task_from_projectasana-gate task remove-project <task_gid>Entfernt eine Aufgabe aus einem ihrer Projekte.
asana_move_task_to_sectionasana-gate task move <task_gid>Verschiebt eine Aufgabe in einen Abschnitt eines Projekts, zu dem sie gehört (benötigt task:move an beiden Enden).
asana_add_tag_to_taskasana-gate task tag <task_gid>Wendet einen Tag auf eine Aufgabe an (benötigt tag:apply im Scope der Aufgabe).
asana_remove_tag_from_taskasana-gate task untag <task_gid>Entfernt einen Tag von einer Aufgabe (benötigt tag:apply im Scope der Aufgabe).
asana_add_task_dependenciesasana-gate task add-dependencies <task_gid>Markiert Aufgaben, von denen diese Aufgabe abhängt; jede referenzierte Aufgabe muss sichtbar sein.
asana_remove_task_dependenciesasana-gate task remove-dependencies <task_gid>Entfernt Abhängigkeiten einer Aufgabe.
asana_list_task_storiesasana-gate task comments <task_gid>Listet die Kommentare und Aktivitäten (Stories) einer Aufgabe auf.
asana_create_commentasana-gate task comment <task_gid>Fügt einer Aufgabe einen Kommentar (Story) hinzu.
asana_update_story—Aktualisiert den Text eines Kommentars (Story).
asana_delete_story—Löscht einen Kommentar (Story).
asana_get_story—Ruft einen einzelnen Kommentar (Story) ab.
asana_list_projectsasana-gate project listListet Projekte im Workspace auf, die die Policy sichtbar macht.
asana_get_projectasana-gate project get <project_gid>Ruft ein Projekt mit seinen vollständigen Feldern und allowed_actions ab.
asana_create_projectasana-gate project createErstellt ein Projekt.
asana_update_projectasana-gate project update <project_gid>Aktualisiert die Felder eines Projekts (benötigt project:update).
asana_delete_projectasana-gate project delete <project_gid>Löscht ein Projekt.
asana_get_project_section—Ruft einen einzelnen Abschnitt in einem Projekt ab.
asana_list_project_sectionsasana-gate project sections <project_gid>Listet die Abschnitte eines Projekts auf.
asana_create_sectionasana-gate project create-section <project_gid>Erstellt einen neuen Abschnitt in einem Projekt.
asana_update_sectionasana-gate project update-section <section_gid>Aktualisiert den Namen eines Abschnitts.
asana_delete_sectionasana-gate project delete-section <section_gid>Löscht einen Abschnitt (Aufgaben darin werden nicht gelöscht).
asana_get_task_count_for_project—Gibt die Anzahl der Aufgaben in einem Projekt zurück.
asana_list_teamsasana-gate team listListet Teams im Workspace auf.
asana_get_teamasana-gate team get <team_gid>Ruft ein Team mit allowed_actions ab.
asana_list_team_usersasana-gate team users <team_gid>Listet Benutzer in einem Team auf.
asana_list_portfoliosasana-gate portfolio listListet Portfolios im Workspace auf.
asana_get_portfolioasana-gate portfolio get <portfolio_gid>Ruft ein Portfolio mit allowed_actions ab.
asana_create_portfolioasana-gate portfolio createErstellt ein Portfolio.
asana_update_portfolioasana-gate portfolio update <portfolio_gid>Aktualisiert die Felder eines Portfolios.
asana_add_items_to_portfolioasana-gate portfolio add-items <portfolio_gid>Fügt Projekte zu einem Portfolio hinzu.
asana_remove_items_from_portfolioasana-gate portfolio remove-items <portfolio_gid>Entfernt Projekte aus einem Portfolio.
asana_list_portfolio_itemsasana-gate portfolio items <portfolio_gid>Listet die Elemente (Projekte) eines Portfolios auf.
asana_get_userasana-gate user get <user_gid>Ruft einen Benutzer ab.
asana_get_workspaceasana-gate workspace get <workspace_gid>Ruft den Workspace ab.
asana_list_workspacesasana-gate workspace listListet die Workspaces des authentifizierten Tokens auf.
asana_list_custom_fieldsasana-gate custom-field listListet benutzerdefinierte Felder im Workspace auf.
asana_get_custom_fieldasana-gate custom-field get <gid>Ruft ein benutzerdefiniertes Feld ab.
asana_search_projectsasana-gate project searchFührt eine Volltextsuche nach Projekten durch.
asana_search_objectsasana-gate object searchFührt eine asana-übergreifende Suche nach Objekten durch (Asana Search API; kostenpflichtige Pläne).
asana_get_goalasana-gate goal get <goal_gid>Ruft ein Ziel ab.
asana_list_goalsasana-gate goal listListet Ziele im Workspace auf.
asana_get_goal_metricasana-gate goal metric <goal_gid>Ruft eine Metrik eines Ziels ab.
asana_get_goal_metric_current_value-Ruft den aktuellen Wert einer Zielmetrik ab.
asana_list_goal_linksasana-gate goal links <goal_gid>Listet die Verknüpfungen eines Ziels auf.
asana_get_workspace_membershipasana-gate workspace membership <workspace_gid>Ruft die Mitgliedschaft des authentifizierten Benutzers im Workspace ab.
asana_get_membership-Ruft die Mitgliedschaft eines Benutzers in einem Projekt/Portfolio/Team ab.
asana_get_enum_option-Ruft eine einzelne Aufzählungsoption eines benutzerdefinierten Feldes ab.
asana_insert_enum_option-Fügt eine Aufzählungsoption in ein benutzerdefiniertes Feld eines Aufzählungstyps ein.
asana_rulesasana-gate rulesGibt die Policy im YAML-Format zurück (der Policy-String, den asana-gate liest).
asana_allowed_actionsasana-gate allowed-actions <Typ> <gid>Gibt die erlaubten Aktionen für ein einzelnes Objekt zurück.
asana_operations-Listet alle Operationen auf, die asana_request annehmen kann, mit der Policy-Aktion, die jede benötigt.
asana_request-Führt einen beliebigen REST-Aufruf durch die Policy aus.
asana_batch-Führt bis zu 50 Aktionen über einen einzigen POST /batch-Aufruf aus. Ergebnis ist ein Array von Antworten in derselben Reihenfolge wie die Eingabe. Fehlgeschlagene Aktionen enthalten ein error-Objekt.

Policy schreiben und verwalten

Eine asana-gate-Policy ist eine einfache YAML-Datei, die definiert, worauf ein Agent zugreifen darf. Sie wird durch Umgebungsvariablen oder Befehlszeilenargumente geladen.

Schnellstart

# Aktuelle Policy anzeigen (das ist alles, was verfügbar ist)
asana-gate rules

# Policy aus einer Datei laden
export ASANA_GATE_POLICY=$(cat /pfad/zu/policy.yaml)
# oder
asana-gate --policy policy.yaml task search

Policy-Referenz

Eine Policy-Datei hat einen scopes-Eintrag. Jeder Schlüssel identifiziert ein Objekt, auf das die Regeln angewendet werden:

scopes:
  workspace:
    - where: gid == "<workspace_gid>"
      allow: "*"
      deny: ["*:delete", "*:batch", "*:search", "*:create"]
    - where: gid == "<workspace_gid>"
      allow: ["task:create", "task:update", "project:create", "story:create"]
  project:
    - where: gid == "<project_gid>"
      allow: "*"
      deny: ["task:delete"]

Policy-Elemente:

  • where: Ein Filter, der Objekte anhand ihrer Felder (gid, name, resource_type, parent.gid, members, followers) mithilfe von ==, !=, in und has-Operatoren auswählt.
  • allow: Aktionen, die erlaubt sind ("*" für alle, oder eine Liste).
  • deny: Aktionen, die verboten sind ("*" für alle, oder eine Liste; überschreibt allow).
  • fields: (optional) Auf eine Liste von Feldern beschränken, die aktualisiert werden dürfen.
  • constraints: (optional) Erzwingt Regeln auf dem Objekt: erfordert must, verbietet forbidden, schreibt prefix vor, erzwingt eine format-Regex, setzt allow_on_clear-Verhalten oder verlangt eine menschliche confirmation.

Aktionen

Aktionen sind <Ressourcentyp>:<Verb>. Die Policy verwendet dieselben Aktionen für alle Scopes:

AktionBedeutung
task:createAufgabe erstellen
task:readAufgabe lesen
task:updateAufgabe aktualisieren
task:deleteAufgabe löschen
task:completeAufgabe abschließen
task:assignAufgabe zuweisen
task:moveAufgabe verschieben
task:add-projectAufgabe zu Projekt hinzufügen
task:remove-projectAufgabe aus Projekt entfernen
story:createKommentar hinzufügen
story:readKommentar lesen
story:updateKommentar bearbeiten
story:deleteKommentar löschen
project:createProjekt erstellen
project:readProjekt lesen
project:updateProjekt aktualisieren
project:deleteProjekt löschen
section:createAbschnitt erstellen
section:updateAbschnitt aktualisieren
section:deleteAbschnitt löschen
tag:applyTag anwenden/entfernen
portfolio:createPortfolio erstellen
portfolio:readPortfolio lesen
portfolio:updatePortfolio aktualisieren
portfolio:deletePortfolio löschen
portfolio:add-itemsElemente zu Portfolio hinzufügen
portfolio:remove-itemsElemente aus Portfolio entfernen
team:readTeam lesen
team:list-membersTeammitglieder auflisten
goal:readZiel lesen
custom_field:readBenutzerdefiniertes Feld lesen
custom_field:writeBenutzerdefiniertes Feld schreiben
user:readBenutzer lesen
workspace:readWorkspace lesen

Was passiert, wenn beides erlaubt und verweigert wird

Das Verhalten lautet: Standardmäßig alles verweigern, außer was erlaubt ist. Das erste passende allow gewährt eine Aktion; selbst wenn sie gewährt wurde, kann ein deny auf derselben Ebene sie widerrufen.

Fehlersuche in der Policy

# Erklären, welche Regel eine bestimmte ID verbirgt
asana-gate explain 1234567890

# Erlaubte Aktionen für ein Objekt anzeigen
asana-gate allowed-actions task 1234567890

Verwandte Skills