Générer des plugins pour Copilot Cowork

Microsoft Copilot Cowork prend en charge l’extensibilité grâce aux packages d’application M365, le même mécanisme de distribution utilisé par les applications Teams, les agents Copilot et les compléments Office. Vous pouvez étendre le Cowork avec :

  • Compétences : Flux de travail basés sur des invites qui enseignent à Cowork une nouvelle expertise dans le domaine, comme l’analyse financière, la recherche juridique ou les flux de travail RH.
  • Connecteurs : serveurs distants qui donnent à Cowork l’accès à des sources de données externes et à des API.

Les deux sont empaquetés ensemble dans un package d’application Microsoft 365 standard et distribués via Microsoft 365 App Store.

Importante

Les barrières aux informations (IB) Microsoft Purview ne sont actuellement pas prises en charge pour la gestion et le partage des plug-ins ou des compétences. Dans les locataires où IB est activé, les téléchargements de fichiers de connaissances incorporés sont bloqués au niveau du locataire. Cela empêche le chargement ou la publication des plug-ins et des compétences concernés.

Ce que vous allez créer

Un plugin Cowork est un .zip package contenant :

my-extension.zip
├── manifest.json          # M365 Unified App Manifest (v1.28)
├── color.png              # 192×192 full-color app icon
├── outline.png            # 32×32 outline icon
└── skills/                # Agent Skills (SKILL.md files)
    ├── skill-one/
    │   ├── SKILL.md
    │   └── references/    # Optional deep-dive docs
    └── skill-two/
        └── SKILL.md

Les compétences utilisent la norme ouverte Agent Skills : le même format pris en charge par Claude Code, Visual Studio Code Copilot, Gemini CLI, Cursor, JetBrains Junie, et 30+ autres outils IA.

Choisissez votre point de départ

Point de départ Chemin Délai avant le premier colis
J’ai un plug-in Claude Code ou Cursor existant Importer ~5 minutes
Je pars de zéro Générer à partir de zéro ~30 minutes

Importer un plug-in existant

Si vous disposez déjà d’un plug-in Claude Code ou Cursor avec des compétences et des serveurs MCP, l’interface de ligne de commande Microsoft 365 Agents Toolkit (atk) l’importe directement. L’interface de ligne de commande s’exécute sous Windows, macOS et Linux.

  1. Installez l’interface de ligne de commande (nécessite la version 1.1.12 ou ultérieure) :

    npm install -g @microsoft/m365agentstoolkit-cli
    
  2. Vérifiez la version :

    atk --version
    
  3. Importez votre plug-in :

    atk import openplugin --path ./my-claude-plugin --output ./my-plugin-project \
      --privacy-url https://contoso.com/privacy \
      --terms-url https://contoso.com/terms
    

La commande lit le répertoire (ou ) et skills/ de .claude-plugin/plugin.json votre plug-in, puis génère un projet Agents Toolkit contenant appPackage/manifest.json, vos compétences et les .mcp.jsonicônes générées..cursor-plugin/plugin.json

Vous devez inclure --privacy-url et --terms-url parce que les manifestes de plug-in n’ont pas de champs équivalents, et le manifeste Microsoft 365 exige les deux.

Remarque

atk import openpluginLocalise un manifeste de plug-in dans un répertoire préfixé par un point —.claude-plugin/plugin.json, , ou .plugin/plugin.json—à côté d’un .mcp.json.cursor-plugin/plugin.json. La spécification des plug-ins d’agent 1.0.0 place le manifeste à un niveau plugin.json supérieur et la configuration MCP à mcp.json. Pour importer un plug-in qui respecte la mise en .plugin/plugin.json page 1.0.0, déplacez son manifeste et renommez-le mcp.json en .mcp.json.

Empaquetez le résultat dans un fichier téléchargeable .zip:

cd my-plugin-project
atk package --manifest-file ./appPackage/manifest.json \
  --output-package-file ./appPackage/build/appPackage.zip \
  --output-folder ./appPackage/build

Remarque

atk import openplugin génère un devPreview manifeste. Les exemples de manifeste ailleurs dans cet article ciblent le schéma v1.28. Si vous publiez via un canal qui nécessite la v1.28, mettez à jour manifestVersion et $schema dans le appPackage/manifest.json, et ajoutez la propriété à chaque connecteur comme décrit dans la mcpToolDescriptionsection Décrire les outils de votre connecteur.

Données importées

Artefact de plug-in Équivalent M365 Notes
.claude-plugin/plugin.json manifest.json Nom, description et champs de développeur mappés ; GUID généré automatiquement (UUID déterministe v5)
skills/*/SKILL.md agentSkills[] Entrées + skills/ dossier Copie textuelle - format identique
.mcp.json serveurs agentConnectors[] Entrées Type d’URL et d’authentification détectés automatiquement
color.png / outline.png Icônes dans le package Utilisé s’il est présent ; espaces réservés générés s’ils sont manquants

Importante

Pour chaque connecteur importé à partir de .mcp.json, le généré authorization.referenceId est un espace réservé dérivé du plug-in et du nom du serveur. Remplacez-le par votre ID d’inscription client OAuth actuel avant de publier. Voir Types d’authentification pris en charge.

Ce qui n’est pas converti

Les fonctionnalités suivantes du plug-in Claude ne sont pas encore prises en charge dans le manifeste Microsoft 365 :

Fonctionnalité de plug-in Claude Statut
commands/ (commandes slash) Pas encore pris en charge
agents/ (sous-agents) Pas encore pris en charge
hooks/ (gestionnaires d’événements) Pas encore pris en charge
settings.json Non applicable
bin/ (exécutables) Non applicable

Options d’importation

Option Description
--path, -p Obligatoire. Répertoire de plug-in contenant .claude-plugin/plugin.json, .cursor-plugin/plugin.jsonou .plugin/plugin.json
--output, -o Dossier de projet de destination (par défaut : ./<plugin-name>)
--privacy-url developer.privacyUrl pour le manifeste généré
--terms-url developer.termsOfUseUrl pour le manifeste généré
--website-url developer.websiteUrl. Revient à homepage, puis author.url
--app-id Remplacer l’UUID déterministe v5 généré pour le manifeste id
--default-auth-type Auto (par défaut), None, OAuthPluginVaultou ApiKeyPluginVault

Type d’authentification détection automatique :

Source Type d’authentification par défaut Reason
URL HTTPS externes OAuthPluginVault La plupart des API distantes nécessitent une authentification
localhost et URL non-HTTPS None Serveurs de développement locaux

Si la détection automatique ne correspond pas à votre configuration, utilisez-la --default-auth-type pour la remplacer.

Exporter vers un répertoire de plug-in

Pour redéplacer un projet Agents Toolkit vers un répertoire de plug-in (par exemple, pour garder un plug-in Claude Code et un package Cowork synchronisés), utilisez atk export openplugin:

atk export openplugin --path ./my-plugin-project \
  --output ./my-claude-plugin --manifest-kind claude-plugin
Option Description
--path, -p Obligatoire. Dossier du projet Agents Toolkit contenant appPackage/manifest.json
--output, -o Répertoire du plug-in de destination (par défaut : ./<plugin-name>-openplugin)
--manifest-kind open-plugin (par défaut, écrits .plugin/plugin.json) claude-pluginou cursor-plugin

L’exportation écrit un x-microsoft-365-agents-toolkit bloc dans le fichier généré plugin.json. Ce bloc contient le manifesteid, les URL des développeurs et les paramètres du connecteur, donc un aller-retour ultérieur atk import openplugin sans avoir besoin ou --terms-url à --privacy-url nouveau.

Remarque

Le x-microsoft-365-agents-toolkit bloc est spécifique à Agents Toolkit, et le type par défaut open-plugin écrit le manifeste dans .plugin/plugin.json. Plug-ins d’agent 1.0.0 utilise un niveau plugin.json supérieur et transporte les données spécifiques au client sous une extensions clé avec un espace de noms de domaine inverse, de sorte que les autres clients ignorent ce blocage plutôt que d’agir dessus. Lorsque votre cible est Code Claude ou Cursor, utilisez --manifest-kind claude-plugin ou cursor-plugin.

Version héritée : script de conversion PowerShell

Avant atk l’importation du plug-in prise en charge, la conversion utilisait un script PowerShell Windows uniquement, qui reste disponible en tant que script de conversion :

.\Convert-ClaudePluginToMOS3.ps1 -PluginPath ./my-claude-plugin -OutputPath ./output

Utilisez atk import openplugin plutôt l’option à la place. Il est multiplateforme, prend en charge les sources Cursor ainsi que Claude Code et peut exporter vers un répertoire de plugins.

Créer un plug-in à partir de zéro

Suivez ces étapes pour créer un package de plug-in à partir de zéro, en commençant par votre première compétence et en progressant jusqu’à un package complet et publiable.

Étape 1 : Créer votre première compétence

Une compétence est un dossier contenant un SKILL.md fichier. Créez la structure de dossiers suivante :

my-extension/
└── skills/
    └── contract-analysis/
        └── SKILL.md

Écrivez SKILL.md avec une matière frontmatter YAML et un corps Markdown :

---
name: contract-analysis
description: |
  Analyzes contracts for key terms, risks, and obligations.
  Use when user asks to "review this contract", "find the liability clause",
  "summarize the key terms", or "compare these two agreements".
license: MIT
metadata:
  author: Contoso Legal Tech
  version: "1.0"
---

# Contract Analysis

## What This Skill Does

Guides Cowork through systematic contract review, identifying:
- Key commercial terms (pricing, payment, renewal)
- Risk clauses (indemnification, limitation of liability, IP)
- Obligations and deadlines
- Non-standard or unusual provisions

## Workflow

1. Read the uploaded contract document
2. Extract and categorize all clauses
3. Flag risk areas with severity ratings
4. Generate a structured summary with recommendations

## Output Format

Present findings in a structured table:

| Clause | Category | Risk Level | Summary |
|--------|----------|------------|---------|
| Section 4.2-Indemnification | Risk | High | Unlimited indemnification for IP claims |
| Section 7.1-Term | Commercial | Low | 12-month auto-renewal with 30-day notice |

SKILL.md champs frontmatter

Champs obligatoires :

Field Contraintes Description
name 1-64 caractères, kebab-case Identificateur de compétence : doit correspondre exactement au nom de dossier
description 1-1 024 caractères Quand utiliser cette compétence : inclure des phrases de déclenchement

Importante

  • Le nom du dossier doit correspondre au name champ de la page d’introduction. Cette inadéquation est la cause la plus fréquente d’échecs de compétences.
  • Les champs de liste description des plug-ins ne doivent pas inclure d’appels à l’action dirigeant les utilisateurs vers des places de marché externes pour acheter des abonnements.
Chemin d’accès au dossier name champ Valide ? Pourquoi
skills/contract-analysis/SKILL.md contract-analysis Oui Correspondance du dossier et du nom
skills/contract-analysis/SKILL.md ContractAnalysis Non Le nom utilise PascalCase au lieu du dossier correspondant
skills/my-skill/SKILL.md contract-analysis Non Le dossier est my-skill mais le nom est contract-analysis

Règles de nommage (kebab-case) : Utilisez uniquement des caractères alphanumériques minuscules et des traits d’union. N’utilisez pas de traits d’union consécutifs, et n’utilisez pas de traits d’union de début ou de fin.

Exemple Valide ? Problème
bond-relative-value Oui Mettre en minuscules avec des traits d’union
fx-carry-trade Oui Mettre en minuscules avec des traits d’union
email Oui Un seul mot, aucun trait d’union n’est nécessaire
Bond_Relative_Value Non Traits de soulignement et lettres majuscules
--my-skill-- Non Traits d’union de début et de fin
my--skill Non Traits d’union consécutifs

Étape 2 : Ajouter des documents de référence (facultatif)

Pour les compétences complexes, gardez le contenu principal SKILL.md et déplacez le contenu détaillé vers des sous-répertoires. Ces fichiers supplémentaires sont des fichiers compagnes. La compétence les charge en cas de besoin.

skills/
└── contract-analysis/
    ├── SKILL.md               # Core workflow (~1,500-2,000 words ideal)
    ├── references/            # Deep-dive docs loaded on demand
    │   ├── clause-taxonomy.md
    │   └── risk-scoring.md
    └── scripts/               # Executable utilities
        └── extract-clauses.py

Limites des fichiers associés

Chaque compétence peut inclure jusqu’à 20 fichiers compagnons (tout fichier autre que SKILL.md). Les limites suivantes s’appliquent par compétence :

Limite Valeur
Nombre maximal de fichiers associés 20
Taille maximale par fichier compagnon 5 Mo
Taille totale maximale du compagnon La taille maximale d'un classeur pouvant être ouvert dans Excel Services est 10 mégaoctets.
Délai d’expiration du téléchargement (tous les compagnons) 15 secondes

Règles des fichiers associés

Les chemins d’accès des fichiers associés doivent respecter les règles suivantes :

  • Utiliser uniquement les chemins relatifs (aucun chemin absolu)
  • Pas de traversée de chemin (.. segments)
  • Pas de barres obliques inverses ni d’octets null dans les noms de fichiers
  • Aucun fichier caché (noms commençant par .)
  • Aucun nom réservé Windows (CON, PRN, AUX, NULCOM1, –, –LPT9COM9) LPT1
  • Le fichier SKILL.md lui-même n’est pas considéré comme un fichier compagnon
  • Les noms de fichiers doivent utiliser des caractères fiables : alphanumériques, traits d’union, traits de soulignement, points, espaces et !

Pour que la fenêtre contextuelle reste efficace, le système charge les compétences en trois couches :

Couche Lors du chargement Taille cible
Frontmatter (name + description) Toujours - au démarrage ~100 jetons
SKILL.md du corps Quand la compétence se déclenche Moins de 5 000 jetons (1 500 à 2 000 mots)
Références (references/) À la demande de l’agent Illimité
Scripts (scripts/) Exécuté, non chargé dans le contexte S/O

Faites référence explicitement aux sous-répertoires pour SKILL.md que l’agent sache qu’ils existent :

## Additional Resources

- **`references/clause-taxonomy.md`**-Full taxonomy of contract clause types
- **`references/risk-scoring.md`**-Risk scoring methodology and thresholds
- **`scripts/extract-clauses.py`**-Automated clause extraction utility

Étape 3 : Ajouter un connecteur (facultatif)

Si votre extension a besoin d’accéder à des données externes, ajoutez un serveur MCP distant. Cette étape est facultative. Les packages de compétences uniquement fonctionnent bien pour les flux de travail basés sur des invites.

Conseil

Si votre serveur gate la visibilité de l’outil par client ou attribue le trafic entrant, consultez Identifier le trafic Cowork vers votre serveur pour l’identité client présentée par Cowork.

Remarque

Les plugins personnalisés ne sont pas pris en charge dans le Cowork sur mobile.

Configuration requise pour les connecteurs

Conditions requises Détails
Transport HTTP diffusable en continu (HTTPS requis, TLS 1.2+)
Protocole Format de message JSON-RPC 2.0
Découverte d’outil Prise en charge tools/list de la découverte dynamique (recommandé)
Exécution de l’outil Prise en charge tools/call de l’appel
Disponibilité Disponibilité de 99,9 % Contrat de niveau de service recommandé pour les applications publiées par le Store
Temps de réponse Moins de 30 secondes par appel d’outil

Recommandations de conception d’outils

  • Un outil par action pour les petites API (moins de 15 opérations) : search_case_law, get_ruling, cite_precedent
  • Rechercher + exécuter pour les API volumineuses (50+ opérations) : search_actions + execute_action
  • Noms descriptifs : get_bond_price non getData
  • Schémas d’entrée riches : incluez une description pour chaque paramètre : c’est ce que lit l’agent
  • Sortie structurée : retourner le code JSON que l’agent peut mettre en forme pour l’utilisateur
  • Entrées de fichier : Pour accepter un fichier de l’espace de travail de l’utilisateur, déclarez le paramètre avec contentEncoding: base64. Pour en savoir plus, consultez Accepter des fichiers de l’espace de travail Cowork.

Décrire les outils de votre connecteur (mcpToolDescription)

Chaque remoteMcpServer connecteur doit inclure un mcpToolDescription objet. Sa propriété imbriquée file pointe vers un fichier JSON de description d’outil que vous empaquetez à l’intérieur de votre .zip et référencez par un chemin d’accès relatif à partir de la racine du package. Si vous omettez mcpToolDescription, le service de package rejette le chargement avec une erreur HTTP 400 :

Les propriétés obligatoires ne figurent pas dans l’objet : mcpToolDescription.

"remoteMcpServer": {
  "mcpServerUrl": "https://api.contoso.com/legal/mcp",
  "mcpToolDescription": {
    "file": "./tools/contoso-legal-tools.json"
  },
  "authorization": {
    "type": "OAuthPluginVault",
    "referenceId": "A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u"
  }
}

Le fichier référencé (par exemple, tools/contoso-legal-tools.json) décrit les outils exposés par le connecteur et doit être présent dans le package ZIP. Incluez-le avec votre manifest.json dossier et skills/ lorsque vous empaquetez le plugin.

Types d’authentification pris en charge

Type d’authentification Champs d’utilisation Expérience utilisateur
None API publiques ou anonymes, services internes Transparent - aucune invite d’authentification
OAuthPluginVault API OAuth 2.0 (recommandé pour la production) L’utilisateur termine le consentement OAuth une fois
ApiKeyPluginVault Services basés sur des clés API L’utilisateur fournit la clé une seule fois

Remarque

  • La prise en charge de l’authentification par clé API n’est pas encore disponible dans Cowork.
  • Si votre serveur MCP nécessite une clé API, utilisez OAuthPluginVault plutôt l’Enregistrement client dynamique ou exposez un point de terminaison qui accepte None.

Pour OAuthPluginVault et ApiKeyPluginVault, les referenceId points des informations d’identification stockées dans le Microsoft Enterprise Token Store - les secrets n’apparaissent jamais dans le manifeste ou les fichiers de compétences. La referenceId valeur est l’identifiant d’inscription d’un client OAuth que vous créez lors de l’inscription d’un client OAuth auprès d’Agents Toolkit.

Importante

Lors de l’inscription de votre client OAuth, définissez l’utilisation par organisation sur N’importe quelle organisation Microsoft 365 pour vous assurer que votre plug-in fonctionne sur plusieurs clients.

Authentification MCP

Pour utiliser OAuth ou ApiKey pour l’authentification, consultez Configurer l’authentification pour les plug-ins MCP et API dans les agents dans Microsoft 365 Copilot pour plus de détails sur l’installation et la configuration.

Enregistrement client dynamique

Si votre serveur MCP prend en charge l’enregistrement client dynamique (DCR), vous pouvez omettre une authentication configuration de la définition de votre connecteur, et Cowork crée automatiquement un client OAuth au nom de votre plug-in.

Vous pouvez omettre l’objet authorization , mais vous devez quand même inclure mcpToolDescription. Configurez l’URL de votre serveur MCP et la description de l’outil, et Cowork s’occupe du client OAuth :

"remoteMcpServer": {
  "mcpServerUrl": "https://api.contoso.com/legal/mcp",
  "mcpToolDescription": {
    "file": "./tools/contoso-legal-tools.json"
  }
}

Étape 4 : Créer le manifeste

Créez manifest.json dans la racine de votre package :

{
  "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.28/MicrosoftTeams.schema.json",
  "manifestVersion": "1.28",
  "version": "1.0.0",
  "id": "YOUR-GUID-HERE",
  "developer": {
    "name": "Contoso Legal Tech",
    "websiteUrl": "https://contoso.com",
    "privacyUrl": "https://contoso.com/privacy",
    "termsOfUseUrl": "https://contoso.com/terms"
  },
  "name": {
    "short": "Contoso Legal Tools",
    "full": "Contoso Legal Tools for Copilot Cowork"
  },
  "description": {
    "short": "Contract analysis, clause extraction, and legal research",
    "full": "Comprehensive legal tools for Copilot Cowork including contract analysis, clause extraction, risk assessment, and legal research capabilities."
  },
  "icons": {
    "color": "color.png",
    "outline": "outline.png"
  },
  "accentColor": "#2B579A",
  "agentSkills": [
    { "folder": "./skills/contract-analysis" }
  ]
}

Pour ajouter un connecteur, incluez agentConnectors:

{
  "agentConnectors": [
    {
      "id": "contoso-legal-api",
      "displayName": "Contoso Legal Database",
      "description": "Access to case law, statutes, and regulatory databases",
      "toolSource": {
        "remoteMcpServer": {
          "mcpServerUrl": "https://api.contoso.com/legal/mcp",
          "mcpToolDescription": {
            "file": "./tools/contoso-legal-tools.json"
          },
          "authorization": {
            "type": "OAuthPluginVault",
            "referenceId": "A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u"
          }
        }
      }
    }
  ]
}

Dans la configuration du connecteur, referenceId doit être l’ID d’inscription OAuth et mcpToolDescription.file doit pointer vers un fichier JSON de description d’outil inclus dans le package ZIP.

Importante

Le schéma de manifeste v1.28 est strict : il se place additionalProperties: false à la racine, de sorte que tout champ qui n’est pas défini dans le schéma est rejeté. Les champs valides dans les manifestes d’application Teams standard, tels que packageName, provoquent l’échec du chargement avec une erreur telle Property 'packageName' has not been defined and the schema does not allow additional properties. que Inclure uniquement les champs affichés ici.

Étape 5 : Ajouter des icônes

Créez deux icônes PNG :

Icône Taille Objectif
color.png 192×192 px Icône d’application en couleur affichée dans la liste des magasins et des applications
outline.png 32×32 px Icône de contour unicolore pour les vues compactes

Si vous n’avez pas encore d’icônes, atk import openplugin génère des espaces réservés de couleur unie. Remplacez-les avant l’envoi au magasin.

Étape 6 : Créer un package

Créez un fichier ZIP avec tout le contenu au niveau racine :

contoso-legal-tools.zip
├── manifest.json
├── color.png
├── outline.png
├── tools/
│   └── contoso-legal-tools.json   # Referenced by mcpToolDescription (connectors only)
└── skills/
    └── contract-analysis/
        ├── SKILL.md
        └── references/
            └── clause-taxonomy.md

Si votre package inclut une agentConnectors entrée, incluez le fichier JSON de description d’outil référencé par mcpToolDescription.file. Les packages de compétences uniquement n’ont pas besoin de tools/ dossier.

Windows (PowerShell) :

Compress-Archive -Path manifest.json, color.png, outline.png, tools, skills -DestinationPath contoso-legal-tools.zip

macOS/Linux :

zip -r contoso-legal-tools.zip manifest.json color.png outline.png tools/ skills/

Utilisation de Microsoft 365 Agents Toolkit

 atk package --manifest-file ./appPackage/manifest.json \
       --output-package-file ./appPackage/build/appPackage.zip \
       --output-folder ./appPackage/build

Étape 7 : Tester

Pour tester votre application, chargez votre package d’application dans Teams comme décrit dans Charger votre application dans Teams.

Pour des tests personnels, chargez une version test de l’application à l’aide de l’interface de ligne de commande Microsoft 365 Agents Toolkit :

  1. Installer @microsoft/m365agentstoolkit-cli à partir de npm:

    npm install -g @microsoft/m365agentstoolkit-cli
    
  2. Vérifiez l’installation en exécutant :

    atk --version
    
  3. Authentifiez-vous avec votre compte professionnel Microsoft 365 :

    atk auth login
    
  4. Connectez-vous à votre compte professionnel et installez le package d’agent. Remplacez le chemin d’accès au fichier par l’emplacement de votre package ZIP :

    atk install --file-path "C:/Users/myuser/myPackage.zip" --scope Personal
    

    Une installation réussie renvoie une sortie qui inclut un TitleId et AppId pour votre compte.

  5. Conservez ces ID pour une utilisation ultérieure lors de la mise à jour ou de la désinstallation.

Pour en savoir plus, consultez l’interface de ligne de commande de Microsoft 365 Agents Toolkit.

Étape 8 : Publier vers votre client

  1. Ouvrir le Centre >d’administration M365Gérer les applications>Charger une application personnalisée.
  2. Sélectionnez le bouton points de suspension (...)>Ajoutez un agent.
  3. Téléchargez votre .zip package.
  4. Plug-insCowork> sources & de compétences> ouverts. Votre plugin apparaît dans la section Découvrir .

Étape 9 : Publier pour le public

Pour les plug-ins destinés à une distribution publique, envoyez votre plug-in à l’App Store Microsoft 365 via l’Espace partenaires. Pour en savoir plus, consultez Publier des agents pour Microsoft 365 Copilot.

Tester un connecteur par rapport à un serveur MCP local

Les connecteurs nécessitent un protocole HTTPS mcpServerUrl, donc pour tester un serveur en cours d’exécution sur votre ordinateur, vous devez l’exposer sur une URL HTTPS publique. Les tunnels de développement fournissent un relais qui termine TLS pour vous.

devtunnel port create <tunnel> -p <port> --protocol http

Importante

Use --protocol http, not https. L’indicateur --protocol décrit le service local vers lequel le tunnel transfère, et non l’URL du tunnel public. La plupart des serveurs MCP locaux parlent HTTP simple, donc si vous définissez --protocol https alors que votre serveur sert HTTP, chaque requête via le tunnel renvoie une 502 erreur. Le relais termine TLS et diffuse l’URL publique via HTTPS quel que soit cet indicateur.

Résolution des problèmes

Symptôme Cause Corriger
Toutes les requêtes tunnelisées sont renvoyées 502 et le serveur local parle HTTP devtunnel port create a été exécuté avec --protocol https Recréez le port avec --protocol http
Les requêtes tunnelisées sont retournées 502 sur macOS même si le serveur local est en cours d’exécution Le serveur est lié à 0.0.0.0 (IPv4 uniquement), mais le tunnel compose localhost, qui résout en ::1 (IPv6) en premier Liez le serveur afin :: qu’il accepte les connexions IPv4 et IPv6
Le téléchargement échoue avec Required properties are missing from object: mcpToolDescription Le connecteur est manquant mcpToolDescription Ajoutez mcpToolDescription avec une file référence et empaquetez ce fichier dans le fichier ZIP
Le téléchargement échoue avec Property '<field>' has not been defined and the schema does not allow additional properties Le manifeste inclut un champ que le schéma v1.28 n’autorise pas (par exemple, packageName) Supprimer le champ ; Le schéma v1.28 utilise additionalProperties: false

Modèles d’emballage

Choisissez le modèle qui correspond à votre extension :

Compétences uniquement (pas de connecteur)

Idéal pour les flux de travail basés sur des invites, l’analyse de documents et l’aide à la rédaction.

my-skills-pack.zip
├── manifest.json          # agentSkills only, no agentConnectors
├── color.png
├── outline.png
└── skills/
    ├── skill-one/SKILL.md
    └── skill-two/SKILL.md

Compétences + connecteur de télécommande

Idéal pour l’analyse des données, les intégrations d’API et les systèmes d’entreprise.

my-data-skills.zip
├── manifest.json          # agentSkills + agentConnectors
├── color.png
├── outline.png
├── tools/                 # Tool-description file(s) for mcpToolDescription
│   └── my-connector.json
└── skills/
    ├── analysis-workflow/SKILL.md
    └── reporting-workflow/SKILL.md

Connecteur uniquement (aucune compétence personnalisée)

Utilisez cette option pour les sources de données que les compétences intégrées de Cowork peuvent déjà utiliser.

my-connector.zip
├── manifest.json          # agentConnectors only, no agentSkills
├── color.png
├── outline.png
└── tools/                 # Tool-description file(s) for mcpToolDescription
    └── my-connector.json

Plug-in Claude Code ou Cursor importé

Utilisez cette option pour les plugins existants d’autres outils d’IA qui ciblent le Cowork.

atk import openplugin --path ./claude-plugin --output ./my-plugin-project \
  --privacy-url https://contoso.com/privacy \
  --terms-url https://contoso.com/terms

Meilleures pratiques de création de compétences

Suivez ces recommandations pour créer des compétences qui s’activent de manière fiable et produisent des résultats cohérents.

Rédiger des descriptions efficaces

Le description champ détermine quand l’agent active votre compétence. Soyez précis :

# Good-specific trigger phrases, concrete scenarios
description: |
  Analyzes bond relative value using Z-spreads, ASW spreads, and butterfly analysis.
  Use when user asks to "analyze bond spreads", "compare bonds",
  "rich-cheap analysis", "relative value", or "Z-spread calculation".

# Bad-vague, no trigger phrases
description: Provides bond analytics capabilities.

Écrire des flux de travail efficaces

  • Soyez précis dans la description. Incluez des phrases de déclencheur : « À utiliser lorsque l’utilisateur demande à... Cette description est la façon dont l’agent décide de la compétence à activer.
  • Structure comme un flux de travail. Numérotez les étapes. Chaque étape doit correspondre à une action concrète (lire un fichier, appeler un outil, générer une sortie).
  • Définir le format de sortie. Afficher la structure exacte du tableau, de la liste ou du document que les utilisateurs doivent attendre. Cette définition améliore considérablement la cohérence.
  • Outils de référence par nom. Si votre compétence dépend des outils de connecteur, nommez-les explicitement : « Utiliser l’outil search_case_law pour...
  • Gardez le SKILL.md principal maigre. Déplacer des documents de référence détaillés vers le references/ sous-répertoire. Le corps des compétences devrait être le flux de travail, pas une encyclopédie.

Éviter les erreurs courantes

  • N’incorporez pas de secrets dans SKILL.md des fichiers. À utiliser agentConnectors avec l’authentification pour les informations d’identification de l’API.
  • Ne dupliquez pas les compétences intégrées. Vérifiez la liste des compétences intégrées avant de créer.
  • Ne faites pas en sorte que les compétences soient trop larges. « Tout faire avec des documents juridiques » est pire que des compétences spécifiques pour « l’analyse des contrats », « l’extraction de clauses » et la « recherche juridique ».
  • Ne codez pas en dur les chemins d’accès aux fichiers ou les commandes système. Les compétences doivent être transférables d’un environnement à l’autre.
  • Ne mettez pas tout en SKILL.md. Si votre corps dépasse ~3 000 mots, déplacez le contenu détaillé vers references/.

Règles de validation

Lorsque vous soumettez votre package, la plateforme le valide à plusieurs niveaux. Corrigez ces erreurs avant la soumission pour éviter tout rejet.

Validation au niveau du manifeste

Code Règle Severity
ASKILL-M001 folder est obligatoire sur chaque agentSkills entrée Erreur
ASKILL-M002 agentSkills La matrice peut avoir jusqu’à 20 éléments Erreur
ASKILL-M003 folder Le chemin d’accès peut compter jusqu’à 256 caractères Erreur

Validation au niveau du package

Code Règle Correctif courant Severity
ASKILL-P001 Le dossier référencé dans le manifeste existe dans ZIP Vérifiez la structure de votre ZIP Erreur
ASKILL-P002 Le dossier contient un SKILL.md fichier Ajouter manquant SKILL.md Erreur
ASKILL-P003 SKILL.md a une matière frontmatter YAML valide entre --- des délimiteurs Corriger la syntaxe YAML Erreur
ASKILL-P004 Les pages préliminaires comprennent un name champ Ajouter name: à la page d’accueil Erreur
ASKILL-P005 Les pages préliminaires comprennent un description champ Ajouter description: à la page d’accueil Erreur
ASKILL-P006 name Correspond au nom du dossier (dernier segment de chemin) Renommer le dossier ou le correctif name: Erreur
ASKILL-P007 name est kebab-case N’utilisez my-skill pas MySkill ou my_skill Erreur
ASKILL-P008 Aucune valeur dupliquée folder dans le tableau Supprimer les doublons Erreur

Validation du connecteur

Règle Severity
Chaque connecteur nécessite un id et displayName Erreur
Toutes les valeurs de connecteur id doivent être uniques dans le manifeste Erreur
Exactement l’un des plugin ou remoteMcpServer Erreur
mcpServerUrl doit être une URL HTTPS valide Erreur
mcpToolDescription obligatoire sur chaque remoteMcpServer, avec un file qui existe dans le ZIP Erreur
authorization.referenceId Obligatoire sauf si le type est None Erreur
authorization.referenceId Ne doit pas être présent lorsque le type est None Erreur

Validation du fichier compagnon

Le portail valide les fichiers associés (documents de référence, scripts et autres fichiers avec SKILL.md) au moment du chargement et de la synchronisation :

Règle Severity
Maximum 20 fichiers compagnons par compétence (à l’exception de SKILL.md) Erreur
Chaque fichier compagnon doit être inférieur ou égal à 5 Mo Erreur
Le nombre total de fichiers associés doit être inférieur ou égal à 10 Mo par compétence Erreur
Les chemins d’accès aux fichiers doivent être relatifs (pas de chemins absolus) Erreur
Aucun segment de parcours (..) Erreur
Pas de barres obliques inverses ni d’octets null dans les noms de fichiers Erreur
Aucun fichier caché (noms commençant par .) Erreur
Aucun nom réservé Windows (CON, PRN, AUX, NULCOM1, –, –LPT9COM9) LPT1 Erreur
Les noms de fichiers ne doivent utiliser que des caractères fiables (alphanumériques, traits d’union, traits de soulignement, points, espaces !, etc.) Erreur

Compatibilité multiplateforme

Les compétences utilisent la norme ouverte des compétences d’agent. Les mêmes SKILL.md fichiers fonctionnent sur plusieurs outils d’IA :

Plateforme Compatibilité
Code Claude Même format intégral SKILL.md
Projets Claude.ai Les compétences complètes peuvent être téléchargées en tant que fichiers projet
VS Code / GitHub Copilot Full-Agent compétences prises en charge en mode agent
CLI Gemini Full-Agent compétences prises en charge
JetBrains Junie Full-Agent compétences prises en charge
OpenAI Codex Full-Agent compétences prises en charge
Cursor Full-Agent compétences prises en charge

Si vous développez des compétences pour Claude Code et Cowork, commencez par la structure du plugin Claude Code - c’est le surensemble :

my-plugin/
├── .claude-plugin/
│   └── plugin.json        # Claude plugin manifest
├── skills/
│   ├── skill-one/
│   │   ├── SKILL.md       # Works in both Claude Code AND M365
│   │   └── references/
│   └── skill-two/
│       └── SKILL.md
└── .mcp.json              # MCP server config (optional)

Importez-le ensuite dans un projet M365 lorsque vous êtes prêt à le publier dans l’App Store Microsoft 365 :

atk import openplugin --path ./my-plugin --output ./my-plugin-project \
  --privacy-url https://contoso.com/privacy \
  --terms-url https://contoso.com/terms

Gestion des annotations et des confirmations MCP

Copilot Cowork lit l’objet MCP annotations standard sur les outils que tools/listvotre serveur retourne, et l’utilise pour décider si un appel d’outil nécessite la confirmation de l’utilisateur et quelle étiquette afficher sur l’invite.

Champs disponibles

Champ Type Effet
readOnlyHint bool false: confirmation requise avant l’exécution de l’outil.
destructiveHint bool true: confirmation requise avant l’exécution de l’outil.
title string Étiquette lisible affichée dans la boîte de dialogue de confirmation. Revient au nom de l’outil en cas d’absence.

Règles de confirmation

Une confirmation est requise si readOnlyHint == false ou destructiveHint == true.

Tous les outils doivent avoir des annotations de sécurité spécifiques. Les outils sans annotations sont traités comme destructeurs et nécessitent une confirmation. Pour plus d’informations, consultez la référence du schéma MCP.

Exemples MCP

Action destructrice avec une étiquette amicale :

{
  "name": "send_email",
  "description": "Send an email message.",
  "annotations": {
    "title": "Send Email",
    "destructiveHint": true
  },
  "inputSchema": { ... }
}

Lecture sûre qui s’exécute automatiquement :

{
  "name": "search_docs",
  "annotations": {
    "title": "Search Documents",
    "readOnlyHint": true
  }
}

Ce qui est disponible maintenant

  • Les outils Microsoft (Graph, Dataverse et autres) sont contrôlés par la stratégie intégrée de Cowork, indépendamment des annotations.
  • Pour les serveurs MCP non-Microsoft, la confirmation pilotée par les annotations est déployée progressivement. La définition des indices est désormais compatible en amont et des invites de confirmation apparaissent à mesure que le déploiement s’étend sans qu’aucune modification de développeur ne soit requise.

Accepter des fichiers depuis l’espace de travail Cowork

Un outil Connecteur peut prendre un fichier de la session Cowork de l’utilisateur en tant qu’entrée : un document joint par l’utilisateur, une pièce jointe à un e-mail enregistrée par Cowork ou un fichier produit par une étape antérieure. Déclarez le paramètre avec le mot clé contentEncoding: base64 de schéma JSON standard et Cowork gère le reste. Aucune extension de schéma spécifique à Microsoft n’est requise et la surface d’API de votre serveur ne change pas.

Cowork résout le fichier de l’espace de travail et l’encode en base64 avant d’appeler votre serveur, de sorte que les octets de fichier n’entrent jamais dans le contexte de l’agent. L’agent ne voit et n’émet que des chemins d’accès aux fichiers de l’espace de travail.

Remarque

Ne demandez pas à l’agent d’encoder un fichier en base64 et de coller l’objet blob dans un appel d’outil. Cela charge l’ensemble du fichier dans le contexte du modèle et dépend du modèle qui reproduit exactement l’objet blob. Il semble fonctionner sur de petits fichiers de test et échoue sur les vrais.

Déclarer un paramètre de fichier

Une propriété de chaîne avec contentEncoding: base64 est reconnue comme une entrée de fichier :

{
  "name": "analyze_contract",
  "description": "Extract key terms from a contract document.",
  "annotations": {
    "title": "Analyze Contract",
    "readOnlyHint": true
  },
  "inputSchema": {
    "type": "object",
    "properties": {
      "document": {
        "type": "string",
        "contentEncoding": "base64",
        "description": "The contract file to analyze."
      },
      "jurisdiction": {
        "type": "string",
        "description": "Two-letter country code governing the contract."
      }
    },
    "required": ["document"]
  }
}

Un tableau de telles chaînes est également reconnu, pour les outils qui acceptent plusieurs fichiers :

"attachments": {
  "type": "array",
  "items": { "type": "string", "contentEncoding": "base64" },
  "description": "Receipt images to attach to the expense line."
}

Ce que l’agent voit

Pour les paramètres de fichier déclarés au niveau supérieur de inputSchema.properties, Cowork les remplace dans le schéma face au modèle par un seul direct_attachment_file_paths tableau, le même paramètre utilisé par les outils intégrés de Cowork, de sorte que l’agent sait déjà comment le remplir. Le schéma ci-dessus est présenté à l’agent comme suit :

{
  "type": "object",
  "properties": {
    "direct_attachment_file_paths": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Workspace file paths to attach."
    },
    "jurisdiction": { "type": "string" }
  }
}

Si votre outil déclare plusieurs paramètres de fichier de niveau supérieur, ils sont tous réduits dans ce seul direct_attachment_file_paths tableau. Au moment de l’appel, Cowork réactive les fichiers résolus dans vos noms de paramètres d’origine dans l’ordre de déclaration.

Paramètres de fichier imbriqués

Un paramètre de fichier imbriqué dans un objet ou un tableau d’objets est également pris en charge et est géré différemment : au lieu d’être réduit, il est réécrit sur place dans une chaîne de chemin à son propre emplacement. Cela permet de conserver l’association entre un fichier et ses champs frères (par exemple, un reçu par ligne de dépense :

"line_items": {
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "amount": { "type": "number" },
      "receipt": { "type": "string", "contentEncoding": "base64" }
    }
  }
}

L’agent remplit un chemin d’accès à line_items[].receipt l’espace de travail, et Cowork échange chaque chemin pour le contenu base64 en place avant de transférer l’appel.

L’imbrication est traversée jusqu’à une profondeur de quatre niveaux sous le sommet de inputSchema. $ref Les pointeurs ne sont pas suivis : définissez les paramètres de fichier en ligne plutôt que derrière un $ref.

Ce que reçoit votre serveur

Votre serveur reçoit un ordinaire tools/call avec vos noms de paramètres d’origine remplis avec du contenu codé en base64 :

{
  "method": "tools/call",
  "params": {
    "name": "analyze_contract",
    "arguments": {
      "document": "JVBERi0xLjQKJcfsj6IKNSAwIG9iago8PC9MZW5...",
      "jurisdiction": "US"
    }
  }
}

Votre serveur n’a pas besoin de savoir que l’agent a utilisé une interface basée sur le chemin et les outils qui ne déclarent contentEncoding: base64 pas de paramètres ne sont pas affectés.

Limites

Limite Valeur
Files par appel d’outil 8
Taille par fichier 150 Mio
Taille totale par appel d’outil 150 Mio
Paramètres de fichier de tableau par outil 1 (combinez-le avec n’importe quel nombre de paramètres de fichier scalaire)
Profondeur d’imbrication maximale 4 niveaux sous le haut de inputSchema

Un appel qui dépasse le nombre de fichiers ou une limite de taille échoue avec une erreur d’outil et n’atteint jamais votre serveur. Dimensionnez votre API et ses délais d’expiration en gardant à l’esprit le plafond de 150 Mio : base64 gonfle la charge utile d’environ un tiers par rapport à la taille du fichier brut, et le contenu encodé est envoyé dans le corps de la requête JSON-RPC.

Recommandations

  • Décrivez le paramètre pour un lecteur humain. L’agent utilise la description pour choisir quel fichier appartient à quel paramètre. Par exemple, "The signed contract PDF to analyze" fonctionne mieux que "file".
  • Indiquez les formats que vous acceptez dans la description du paramètre. Le cowork passe par tout ce que l’utilisateur attache. Validez le type de contenu de votre côté et renvoyez une erreur d’outil claire s’il n’est pas utilisable.
  • Définissez des annotations. Un outil qui reçoit un fichier et agit dessus n’est normalement pas en lecture seule, il invite donc à la confirmation. Voir Gestion des annotations et des confirmations MCP.
  • Conserver les paramètres de fichier en ligne. Un paramètre derrière un $ref, ou imbriqué à plus de quatre niveaux, n’est pas réécrit. Votre serveur recevrait une chaîne de chemin d’accès dans laquelle il attend du contenu.
  • Déclarez au plus un paramètre de fichier de tableau par outil. Avec deux ou plus, Cowork ne peut pas savoir quel fichier appartient à quel tableau, et l’appel échoue avec une erreur d’outil. Utilisez un tableau ou plusieurs paramètres scalaires, ou une combinaison de scalaires et d’un seul tableau.
  • Attendez-vous à un nombre exact d’outils scalaires uniquement. Si votre outil déclare uniquement des paramètres de fichier scalaire, le nombre de fichiers transmis par l’agent doit correspondre au nombre déclaré. Indiquez clairement les paramètres de fichier facultatifs dans leurs descriptions afin que l’agent ne soit pas en sous-alimentation ou en suralimentation.

Remarque

Ce mécanisme est antérieur au travail d’entrée de fichier du protocole de contexte modèle, qui est en cours de normalisation par le groupe de travail sur les téléchargements de fichiers MCP. Cowork pourrait ajouter la prise en charge de la forme standardisée des entrées de fichiers déclaratifs une fois qu’il atterrit. Le contentEncoding: base64 contrat décrit ici continue de fonctionner.

Identifier le trafic Cowork vers votre serveur

Si votre serveur MCP contrôle la visibilité de l’outil par client ou si vous souhaitez attribuer le trafic qu’il reçoit, vous pouvez reconnaître les requêtes provenant de Cowork. Cowork présente une identité logicielle stable sur deux canaux :

Canal Emplacement Valeur
En-tête de demande User-Agent Chaque requête sortante que Cowork envoie à votre serveur copilot-cowork/1.0
clientInfodans la négociation MCP initialize La initialize demande uniquement { "name": "copilot-cowork", "version": "<version>" }

Correspondent sur le copilot-cowork préfixe

Faites correspondre le préfixe, en respectant la copilot-cowork casse, sur l’un ou l’autre canal. Ne correspondent pas à la chaîne exacte copilot-cowork/1.0 ou à un clientInfo.versionfichier . La version suit le contrat client-identité et devrait changer ; Une correspondance de préfixe permet à votre portail de travailler sur des bosses de version.

# Correct: case-insensitive prefix match
copilot-cowork

# Incorrect: exact match breaks when the version changes
copilot-cowork/1.0

Choisissez le bon canal pour votre portail

Les deux canaux ont des étendues différentes, donc clé sur celui qui correspond à la façon dont votre serveur applique sa porte :

  • L’en-tête User-Agent est présent sur chaque requête, y compris tools/list et tools/call. Si vous effectuez un gate ou un attribut par requête, activez cet en-tête.
  • clientInfo est envoyé uniquement lors de la initialize négociation de la main. Si vous effectuez un portail par session au moment de la connexion, vous pouvez le lire à cet endroit, mais il ne se répète pas lors des demandes ultérieures.

Ce que l’identité inclut et n’inclut pas

L’identité nomme uniquement le logiciel . C’est la même chose pour chaque utilisateur et connexion Cowork, et il ne porte jamais l’identité de l’utilisateur. L’identité de l’utilisateur reste dans le flux d’autorisation définie par la configuration de l’authentification de votre connecteur.

L’identité comprend L’identité n’inclut pas
Un nom logiciel stable (copilot-cowork) et une version de contrat N’importe quel identificateur de client, d’utilisateur, de session ou de conversation
La même valeur à chaque requête et à chaque connexion Qualificateur par connecteur

Comme il n’existe aucun qualificateur par connecteur, vous ne pouvez actuellement pas utiliser cette identité pour indiquer quel connecteur a effectué un appel ou pour séparer un plug-in Microsoft publié d’un serveur chargé de manière indépendante pointant vers la même URL. Si vous avez besoin de cette distinction, appliquez-la via la configuration d’autorisation de votre connecteur plutôt que l’identité du client.

Questions fréquentes

Puis-je utiliser les compétences du package M365 dans Claude Code ?

Oui. Les dossiers de compétences contiennent des compétences d’agent standard. Copiez-les dans n’importe .claude/skills/ quel projet Claude Code, ou exécutez atk export openplugin pour reconvertir l’ensemble du projet en un plug-in Claude Code.

Ai-je besoin d’un connecteur à distance ?

Non. Les packages de compétences uniquement fonctionnent bien pour les flux de travail basés sur des invites. Les connecteurs sont nécessaires uniquement lorsque votre compétence nécessite des données en direct provenant d’un système externe.

En quoi les compétences des plugins sont-elles différentes des compétences intégrées ?

Les compétences de plug-in apparaissent avec la source "package" dans l’API. Ils ne peuvent pas remplacer les compétences intégrées du même nom. Les packages déployés par l’Administration montrent isAdminDeployed: true

Les administrateurs informatiques peuvent-ils contrôler les plug-ins disponibles ?

Oui. Les contrôles d’administration M365 Standard s’appliquent : listes d’autorisation/blocage au niveau du locataire, déploiements gérés par l’administrateur et stratégies de conformité.

Que se passe-t-il si un plugin est révoqué ?

Lors du cycle de synchronisation suivant, les compétences et les connecteurs de ce package sont supprimés de la session de l’utilisateur. Les conversations actives ne sont pas interrompues, mais les nouvelles sessions n’ont pas les fonctionnalités du package.

Quel est le nombre maximal de compétences par package ?

Vingt (20) compétences (selon ASKILL-M002). Pour les connecteurs, la limite est de 10 par package.

Les compétences peuvent-elles référencer des outils de connecteur du même package ?

Oui, et ils devraient. Nommez explicitement les outils dans votre SKILL.md workflow (par exemple, « Utilisez l’outil search_case_law pour... »). L’agent les connecte au moment de l’exécution.

Les outils de mon plugin peuvent-ils accepter des fichiers de l’espace de travail Cowork ?

Oui. Déclarez le paramètre outil avec contentEncoding: base64, et Cowork résout le fichier d’espace de travail de l’utilisateur au contenu base64 avant d’appeler votre serveur. Le modèle transmet les chemins d’accès aux fichiers, et non le contenu des fichiers, de sorte que les fichiers volumineux ne consomment pas le contexte du modèle. Pour les détails et les limites de déclaration, en savoir plus dans Accepter des fichiers à partir de l’espace de travail Cowork.

Comment faire générer un GUID déterministe pour mon package ?

atk import openplugin utilise l’UUID v5 (basé sur SHA-1) du nom de votre plug-in. L’exécution de l’importation deux fois produit le même GUID. Pour définir le vôtre, passez .--app-id Pour l’empaquetage manuel, utilisez n’importe quel générateur GUID. Veillez à ce qu’il reste stable entre les versions.