Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
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 requêtes 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.
Important
Cloisonnement de l’information Microsoft Purview (IB) ne sont actuellement pas pris en charge pour la gestion ou le partage des plug-ins ou des compétences. Dans les locataires où IB est activé, les chargements de fichiers de connaissances incorporés sont bloqués au niveau du tenant. Cela empêche le téléversement ou la publication des plug-ins et des compétences concernés.
Microsoft ne crée ni ne conserve d’index persistant, de graphe de connaissances (y compris Microsoft Graph) ou de base de données qui inclut le contenu ISV, que ce soit par analyse, grattage, récolte, exportation en bloc, ingestion ou toute autre méthode (via API, serveur MCP ou autre). Microsoft peut traiter temporairement le contenu ISV en fonction des besoins pour répondre à la requête en temps réel d'un utilisateur, mais ne conserve pas le contenu ISV au-delà de la durée de cette session. Sur demande écrite d’ISV, Microsoft supprime tout Contenu ISV en sa possession ou sous son contrôle dans un délai de 10 jours ouvrables et certifie cette suppression par écrit. En savoir plus sur la protection des données d’entreprise dans Microsoft Copilot et Microsoft Copilot Chat.
Ce que vous allez construire
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 Compétences de l’assistant, le même format pris en charge par Claude Code, Visual Studio Code Copilot, Gemini CLI, Cursor, JetBrains Junie et plus de 30 autres outils d’IA.
Choisir votre point de départ
Générez votre plug-in avec CLI wiqd. L’interface de ligne de commande structure le package et synchronise manifest.json vos dossiers de compétences. Il exécute également les propres règles de validation de la plateforme avant que vous ne téléchargiez, puis provisionne et partage le résultat. La CLI est en version préliminaire, de sorte que ses commandes et la sortie générée peuvent changer avant la disponibilité générale. Tout ce qu’il génère est un package d’application Microsoft 365 simple, vous pouvez donc toujours ouvrir, modifier et versionner les fichiers directement.
Assemblez le package manuellement uniquement lorsque vous ne pouvez pas installer d’outils ou lorsque vous mettez en place votre propre pipeline de packaging. Dans ce cas, la référence de format de package dans cet article est ce dont vous avez besoin : elle décrit exactement ce qui wiqd produit.
| Point de départ | Procédez comme suit | Délai avant le premier package |
|---|---|---|
| Je pars de zéro | Générer un plugin avec wiqd | environ 10 minutes |
| J’ai un plug-in Claude Code existant | Convertissez-le | environ 5 minutes |
| Je ne parviens pas à installer les outils, ou je crée moi-même mon propre package | Assembler un emballage à la main | environ 30 minutes |
Générer un plugin avec wiqd
L’interface de ligne de commande wiqd exécute le même cycle de vie que celui que vous effectuez manuellement : créer, ajouter des fonctionnalités, valider, provisionner, empaqueter et partager. Le package qu’il produit répond déjà aux règles de validation énoncées dans cet article.
Étape 1 : Installez wiqd et connectez-vous
Installez l’interface de ligne de commande wiqd en suivant le guide d’installation de wiqd, qui couvre Windows, macOS et Linux. Connectez-vous ensuite au client Microsoft 365 pour lequel vous développez, car l’approvisionnement et le partage touchent votre locataire :
wiqd auth login --interactive
Le programme d’installation enregistre également un plugin GitHub Copilot CLI, afin que vous puissiez gérer le même cycle de vie en mode conversationnel. Par exemple, vous pouvez dire : Créer un plug-in autonome appelé Triage Helper ou Valider mon plug-in. Le parcours conversationnel exécute les mêmes commandes que cette section. Utilisez les commandes directement lorsque vous écrivez un script pour un pipeline ou que vous souhaitez une automatisation reproductible et non interactive.
Étape 2 : générer la structure du plug-in et ajouter des capacités
Créez le conteneur du plug-in, puis ajoutez les capacités dont vous avez besoin, selon la combinaison de votre choix :
wiqd plugin create --name my-plugin
wiqd plugin add skill --name "Contract Analysis"
wiqd plugin add connector --name "Contoso Legal" --description "Case law and statutes over MCP" --url https://api.contoso.com/legal/mcp
add skill génère appPackage/skills/contract-analysis/SKILL.md et l’enregistre dans agentSkills[].
add connector écrit l’entrée agentConnectors[]. Les deux commandes appliquent les limites de nommage et de taille de la plateforme avant l’écriture, de sorte qu’une incompatibilité de nom de dossier ou une surlongueur id n’atteint jamais le manifeste.
Écrivez votre logique de compétence dans le SKILL.md généré. Les champs de frontmatter, le modèle de chargement progressif et les limites de fichiers associés sont les mêmes que ceux décrits à l’étape 1 : Créer votre première compétence et à l’étape 2 : Ajouter des documents de référence (facultatif).
Important
wiqd plugin create épingle le paquet à manifestVersion: "1.29", tandis que les exemples manuscrits de cet article utilisent 1.28. La différence est importante pour les connecteurs. À la version 1.28, mcpToolDescription est obligatoire et le fichier qu’il nomme doit être dans le ZIP. À la version 1.29, agentConnectors[] les entrées sont uniquement des URL et mcpToolDescription est facultatif, de sorte qu’un package généré par wiqd ne rencontre jamais cet échec de téléversement. wiqd ne génère pas encore d’authentification de connecteur automatique : configurez-la directement comme décrit dans Types d’authentification pris en charge.
Étape 3 : Valider au fur et à mesure du développement
Validez en continu au lieu d’assembler un package et d’espérer que le téléversement réussit :
wiqd plugin validate
wiqd plugin validate --mode deep
validate est la vérification statique hors ligne de la surface declarative-agent. Un plug-in de compétences uniquement ou de connecteur uniquement le réussit sans rien à vérifier, ce qui est attendu : il s’agit d’une vérification pour votre boucle de génération, pas d’une couverture complète.
validate --mode deep empaquette d’abord le plug-in, puis valide la version générée .zip par rapport à la même bibliothèque de validation d’application utilisée par le chargement. C’est là que les codes ASKILL et les règles de connecteur font surface.
Étape 4 : Provisionner, empaqueter et partager
Exécutez ces trois commandes dans l’ordre :
wiqd plugin provision
wiqd plugin package
wiqd plugin share --scope users --email you@contoso.com
Exécuter provision en premier, car il écrit le fichier d’environnement dont package dépendent les deux share et les deux. Utilisez --scope users pour partager avec les personnes que vous répertoriez, ou --scope tenant avec tous les membres de votre organisation. Quoi qu’il en soit, le plugin apparaît dans Partagé avec moi sous Cowork>Sources & compétences>. Pour le répertorier dans la section Découvrir à la place, un administrateur charge le package. Pour plus d’informations, consultez l’Étape 8 : publiez sur votre locataire. Pour supprimer ce que provision a créé, exécutez wiqd plugin delete --env local --yes.
La soumission au magasin public est toujours un processus manuel dans Espace partenaires. Pour plus d’informations, consultez l’Étape 9 : publier pour le public.
Apporter un plug-in sur un autre hébergeur
Pour utiliser vos compétences dans Claude Code, Cursor ou tout autre hôte de compétences d’assistant, exportez le projet plutôt que de copier des dossiers manuellement :
wiqd plugin export --format claude-plugin
export est défini par défaut sur --format open-plugin et accepte cursor-pluginégalement . Il écrit un répertoire non compressé sous <path>/export/<format>.
Importer un plug-in existant
Si vous disposez déjà d’un plugin Claude Code avec des compétences et des serveurs MCP, vous avez deux itinéraires de conversion. La voie que vous choisissez dépend du fait que vous prévoyez de continuer à développer le plugin ou simplement d’expédier ce que vous avez.
| Objectif | Utiliser |
|---|---|
| Continuez à développer, valider et livrer le plug-in de Microsoft 365 | wiqd plugin import |
Produire immédiatement un élément publiable .zip à partir d’un plug-in Claude existant |
Script de conversion |
Importer avec wiqd
wiqd plugin import reconnaît une source Open Plug-in, Claude plug-in ou Cursor plug-in et produit un wiqd plug-in projet à partir de celle-ci. Le plugin importé a le même cycle de vie que celui que vous avez créé avec wiqd plugin create:
wiqd plugin import --path ./my-claude-plugin --privacy-url https://contoso.com/privacy --terms-url https://contoso.com/terms
--privacy-url et --terms-url ne sont requis que lors de la première importation d’un plugin. Si le contenu source provient d’un précédent wiqd plugin export, les métadonnées aller-retour les portent déjà.
Important
Un projet importé prend en charge uniquement la partie en lecture seule du cycle de vie : wiqd plugin validate, show, et list. Il ne peut pas encore être empaqueté, approvisionné ou partagé, car l’importation ne génère pas de génération automatique des fichiers de déploiement locaux nécessaires à ces étapes. Il s’agit d’un écart suivi. Pour connaître le statut actuel, consultez la référence de la CLI activée wiqd. Si vous avez besoin d’un package publiable aujourd’hui, utilisez le script de conversion.
Convertir avec le script de conversion
Le script de conversion traduit directement un plug-in Claude en un package M365 publiable :
Installez l’interface de ligne de commande (nécessite la version 1.1.12 ou ultérieure) :
npm install -g @microsoft/m365agentstoolkit-cliVérifiez la version :
atk --versionImportez 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 les répertoires skills/ (ou .claude-plugin/plugin.json), appPackage/manifest.json et .mcp.json de votre plug-in, puis génère un projet Agents Toolkit contenant .cursor-plugin/plugin.json, vos compétences et les icônes générées.
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, .plugin/plugin.json ou .mcp.json—à côté d’un .cursor-plugin/plugin.json. La spécification Agent Plugins 1.0.0 situe le manifeste à la racine plugin.json et la configuration MCP dans mcp.json. Pour importer un plug-in qui suit la structure 1.0.0, déplacez son manifeste vers .plugin/plugin.json et renommez mcp.json en .mcp.json.
Empaquetez le résultat dans un fichier pouvant être téléversé .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 manifest devPreview. Les exemples de manifeste ailleurs dans cet article ciblent le schéma v1.28. Si vous publiez via un canal qui nécessite la version 1.28, mettez à jour manifestVersion et $schema dans le appPackage/manifest.json généré.
Éléments importés
| Artefact de plug-in | Équivalent M365 | Remarques |
|---|---|---|
.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[] éléments + skills/ dossier |
Copié textuellement - format identique |
.mcp.json serveurs |
agentConnectors[] entrées |
URL et type d’authentification détectés automatiquement |
color.png / outline.png |
Icônes du package | Utilisé s’il est présent ; substituts générés s’ils sont manquants |
Important
Pour chaque connecteur importé à partir de .mcp.json, le authorization.referenceId généré est un espace réservé dérivé du plug-in et du nom du serveur. Remplacez-le par votre ID d’inscription client OAuth réel avant de publier. Pour en savoir plus, consultez 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é du plugin Claude | Status |
|---|---|
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 |
Required. 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 |
Redéfinir l’UUID déterministe v5 généré pour le manifeste id |
--default-auth-type |
Auto (par défaut), None, OAuthPluginVaultou ApiKeyPluginVault |
Détection automatique du type d’authentification :
| 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 --default-auth-type pour la remplacer.
Ré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 |
Required. 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, écrit .plugin/plugin.json), claude-plugin, ou cursor-plugin |
L’exportation insère un bloc x-microsoft-365-agents-toolkit dans le plugin.json généré. Ce bloc contient le manifest id, les URL des développeurs et les paramètres du connecteur, donc un aller-retour ultérieur atk import openplugin peut s’effectuer sans avoir besoin de --privacy-url ou --terms-url de 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.
Agent plug-ins 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 bloc plutôt que d’agir dessus. Lorsque votre cible est Claude Code ou Cursor, utilisez --manifest-kind claude-plugin ou cursor-plugin.
Version héritée : script de conversion PowerShell
Avant que atk ne prenne en charge l’importation de plug-ins, la conversion utilisait un script PowerShell uniquement disponible sous Windows, qui reste disponible en tant que script de conversion :
.\Convert-ClaudePluginToMOS3.ps1 -PluginPath ./my-claude-plugin -OutputPath ./output
Utilisez atk import openplugin à la place. Il est multiplateforme, prend en charge les sources Cursor ainsi que Claude Code et peut exporter vers un répertoire de plugins.
Assembler un colis à la main
Cette section est la référence du format de package : elle décrit exactement ce que Générez un plug-in avec wiqd génère, champ par champ. Suivez-le de bout en bout lorsque vous ne pouvez pas installer d’outils ou que vous créez votre propre pipeline d’empaquetage. Utilisez-le comme référence lorsque vous avez besoin de comprendre ou de déboguer un package généré.
Étape 1 : créer votre première compétence
Une compétence est un dossier contenant un fichier SKILL.md. Créez la structure de dossiers suivante :
my-extension/
└── skills/
└── contract-analysis/
└── SKILL.md
Écrivez SKILL.md avec un en-tête YAML et un corps en 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 |
Champs de frontmatter SKILL.md
Champs obligatoires :
| Champ | Contraintes | Description |
|---|---|---|
name |
1 à 64 caractères, kebab-case | Identificateur de compétence - doit correspondre exactement au nom du dossier |
description |
1-1 024 caractères | Quand utiliser cette compétence : inclure des phrases déclencheurs |
Important
- Le nom du dossier doit correspondre au champ
namedu frontmatter. Cette inadéquation est la cause la plus fréquente d’échecs de compétences. - Les champs de fiche des plug-ins
descriptionne doivent pas inclure d’appels à l’action invitant les utilisateurs à se rendre sur des places de marché externes pour acheter des abonnements.
| Chemin d’accès au dossier | champ name |
Valide ? | Pourquoi |
|---|---|---|---|
skills/contract-analysis/SKILL.md |
contract-analysis |
Yes | Le dossier et le nom correspondent |
skills/contract-analysis/SKILL.md |
ContractAnalysis |
No | Le nom utilise PascalCase au lieu de correspondre au nom du dossier |
skills/my-skill/SKILL.md |
contract-analysis |
No | 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 ? | Issue |
|---|---|---|
bond-relative-value |
Yes | Minuscules avec traits d’union |
fx-carry-trade |
Yes | Minuscules avec traits d’union |
email |
Yes | Un seul mot, aucun trait d’union n’est nécessaire |
Bond_Relative_Value |
No | Traits de soulignement et lettres majuscules |
--my-skill-- |
No | Traits d’union de début et de fin |
my--skill |
No | 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 succinct et déplacez le contenu détaillé vers des sous-répertoires. Ces fichiers supplémentaires sont des fichiers compagnons. Le skill 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 enfants (tout fichier autre que SKILL.md). Les limites suivantes s’appliquent par compétence :
| Limit | Value |
|---|---|
| Nombre maximal de fichiers associés | 20 |
| Taille maximale par fichier compagnon | 5 Mo |
| Taille totale maximale de l’enfant | 10 Mo |
| Délai d’expiration du téléchargement (tous les enfants) | 15 secondes |
Règles du fichier compagnon
Les chemins d’accès des fichiers associés doivent respecter les règles suivantes :
- Utiliser uniquement des chemins relatifs (pas de chemins absolus).
- Aucune traversée de répertoire (segments
..). - Pas de barres obliques inverses ni d’octets nuls dans les noms de fichiers.
- Aucun fichier caché (noms commençant par
.). - Aucun nom réservé de Windows (
CON,PRN,AUX,NUL,COM1–LPT9,COM9–LPT1). - Le fichier
SKILL.mdlui-même ne compte pas comme un fichier associé. - Les noms de fichiers doivent utiliser des caractères de sécurité : 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 de la cible |
|---|---|---|
Frontmatter (name + description) |
Toujours - au démarrage | ~100 jetons |
Corps SKILL.md |
Lorsqu’une compétence se déclenche | Moins de 5 000 jetons (1 500 à 2 000 mots) |
Références (references/) |
À la demande de l’assistant | Unlimited |
Scripts (scripts/) |
Exécuté, non chargé dans le contexte | N/A |
Faites référence explicitement aux sous-répertoires pour SKILL.md que l’assistant 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 workflows basés sur des requêtes.
Tip
Si votre serveur contrôle la visibilité par client ou attribue une origine au trafic entrant, accédez à 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 le connecteur
| Requirement | Détails |
|---|---|
| Transport | HTTP en streaming (HTTPS requis, TLS 1.2+) |
| Protocol | Format de message JSON-RPC 2.0 |
| Découverte d’outils | Prise en charge de la découverte dynamique tools/list (recommandée) |
| Exécution de l’outil | Prise en charge tools/call de l’invocation |
| 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 |
Instructions de conception d’outil
-
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_pricepasgetData - 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)
Un remoteMcpServer connecteur peut éventuellement inclure un mcpToolDescription objet. Lorsqu’elle est fournie, sa propriété imbriquée pointe vers un fichier JSON de description d’outil que vous empaquetez à l’intérieur de votre file et référencez .zip par un chemin relatif à partir de la racine du package. Cowork découvre les outils de manière dynamique à partir de votre serveur MCP et n’utilise pas ce fichier, même lorsqu’il est présent.
"remoteMcpServer": {
"mcpServerUrl": "https://api.contoso.com/legal/mcp",
"mcpToolDescription": {
"file": "./tools/contoso-legal-tools.json"
},
"authorization": {
"type": "OAuthPluginVault",
"referenceId": "A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u"
}
}
Si vous incluez mcpToolDescription, le fichier référencé (par exemple, tools/contoso-legal-tools.json) décrit les outils que le connecteur expose et doit être présent dans le package ZIP. Incluez-le avec votre manifest.json dossier et skills/ lorsque vous empaquetez le plug-in.
Tip
Cette exigence s’applique à la version 1.28 du manifeste. Les packages que wiqd plugin create génèrent ciblent la version 1.29, dans lesquels les entrées agentConnectors[] sont uniquement des URL, mcpToolDescription est facultatif et il n’y a pas de fichier de description d’outil à oublier.
Types d’authentification pris en charge
| Type d’authentification | Quand utiliser | Expérience utilisateur |
|---|---|---|
None |
API publiques ou anonymes, services internes | Transparent - aucune requête 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 plutôt
OAuthPluginVaultou l’enregistrement dynamique du client, ou exposez un point de terminaison qui accepteNone.
Pour OAuthPluginVault et ApiKeyPluginVault, referenceId pointe vers des informations d’identification stockées dans le magasin de jetons Microsoft Enterprise - les secrets n’apparaissent jamais dans le manifeste ou les fichiers de compétences. La valeur referenceId est l’identifiant d’inscription du client OAuth que vous créez lorsque vous inscrivez un client OAuth auprès de la boîte à outils Agents.
Important
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 locataires.
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.
Inscription dynamique du client
Si votre serveur MCP prend en charge l’enregistrement client dynamique (DCR), vous pouvez omettre la configuration authentication de la définition de votre connecteur, et Cowork crée automatiquement un client OAuth au nom de votre plug-in.
Remarque
L’omission de la authentication configuration est prise en charge uniquement dans Cowork. Il n’est pas pris en charge dans le Copilot Chat. Si votre plug-in doit également fonctionner dans Copilot Chat, configurez OAuthPluginVault l’authentification comme décrit dans Types d’authentification pris en charge.
Vous pouvez omettre complètement l’objet authorization . Configurez l’URL de votre serveur MCP et Cowork s’occupe du client OAuth :
"remoteMcpServer": {
"mcpServerUrl": "https://api.contoso.com/legal/mcp"
}
Étape 4 : Créer le manifeste
Créez manifest.json à la racine de votre paquet. L’exemple utilise la version de manifest 1.28 ; wiqd plugin create épingle 1.29 à la place, où les entrées de connecteur sont URL uniquement.
{
"$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’identifiant d’enregistrement OAuth. Si vous incluez mcpToolDescription, son file doit pointer vers un fichier JSON de description d’outil inclus dans le package ZIP.
Important
Le schéma de manifeste v1.28 est strict : il définit 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 | Purpose |
|---|---|---|
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 la publication sur le magasin.
Étape 6 : package
Créez un fichier ZIP avec tout le contenu au niveau racine. (wiqd plugin package produit cette même structure après wiqd plugin provision.)
contoso-legal-tools.zip
├── manifest.json
├── color.png
├── outline.png
├── tools/
│ └── contoso-legal-tools.json # Referenced by mcpToolDescription (optional, connectors only)
└── skills/
└── contract-analysis/
├── SKILL.md
└── references/
└── clause-taxonomy.md
Si un connecteur inclut mcpToolDescription, incluez le fichier JSON de description de l’outil auquel il fait référence. Les packages qui n’utilisent pas mcpToolDescription, y compris les packages de compétences uniquement, n’ont pas besoin de dossier tools/.
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 : Test
Pour tester votre application, chargez votre package d’application dans Teams comme décrit dans Charger votre application dans Teams.
Si vous avez créé le plug-in avec wiqd, exécutez wiqd plugin provision à la place – il enregistre le plug-in avec votre locataire pour vous. Pour tester personnellement un package assemblé à la main, chargez l’application en mode hors Store à l’aide de l’interface de ligne de commande Microsoft 365 Agents Toolkit :
Installer
@microsoft/m365agentstoolkit-clià partir denpm:npm install -g @microsoft/m365agentstoolkit-cliVérifiez l’installation en exécutant :
atk --versionAuthentifiez-vous avec votre compte professionnel Microsoft 365 :
atk auth loginConnectez-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 PersonalUne installation réussie produit une sortie contenant un
TitleIdet unAppIdpour votre compte.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 locataire
Téléchargez le paquet dans le centre d’administration pour répertorier votre plug-in dans la section Découvrir, où tous les membres de votre organisation peuvent le trouver :
- Ouvrir Centre d’administration M365>Gérer les applications>Téléverser une application personnalisée.
- Sélectionnez le bouton points de suspension (...) >Ajoutez un assistant.
- Importez votre
.zippackage. - Ouvrez Cowork>>. Votre plug-in apparaît dans la section Découverte.
wiqd plugin share place le plug-in dans Partagé avec moi plutôt que Découverte. Utilisez-le pour les tests et pour un déploiement ciblé auprès de personnes spécifiques. Le chargement dans le centre d’administration est ce qui répertorie un plug-in pour la découverte.
Étape 9 : Publier publiquement
Pour les plug-ins destinés à une distribution publique, soumettez votre plug-in au magasin d’application Microsoft 365 via Espace partenaires. Pour en savoir plus, consultez la rubrique Publier des assistants pour Microsoft 365 Copilot.
Tester un connecteur sur un serveur MCP local
Les connecteurs nécessitent une connexion HTTPS mcpServerUrl. Pour tester un serveur en cours d’exécution sur votre ordinateur, vous devez l’exposer sur une URL HTTPS publique.
Dev tunnels fournissent un relais qui assure la terminaison TLS pour vous.
devtunnel port create <tunnel> -p <port> --protocol http
Important
Utilisez --protocol http, pas 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 utilisent HTTP simple. Ainsi, si vous définissez --protocol https alors que votre serveur utilise HTTP, chaque requête passant par le tunnel renvoie une erreur 502. Le relais assure la terminaison TLS et diffuse l’URL publique via HTTPS quel que soit cet indicateur.
Troubleshooting
| Symptôme | Cause | Réparer |
|---|---|---|
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 à l’aide de --protocol http |
Les requêtes tunnelisées renvoient 502 sur macOS même si le serveur local est en cours d’exécution |
Le serveur est associé à 0.0.0.0 (IPv4 uniquement), mais le tunnel se connecte à localhost, qui est d’abord résolu en ::1 (IPv6) |
Liez le serveur à :: afin qu’il accepte les connexions IPv4 et IPv6 |
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 de packaging
Choisissez le motif qui correspond à votre extension :
Compétences uniquement (pas de connecteur)
Idéal pour les flux de travail basés sur des prompts, 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 distant
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 (optional)
│ └── 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 déjà utilisables par les compétences intégrées de Cowork.
my-connector.zip
├── manifest.json # agentConnectors only, no agentSkills
├── color.png
├── outline.png
└── tools/ # Tool-description file(s) for mcpToolDescription (optional)
└── my-connector.json
Extension Claude Code ou Cursor importée
Utilisez cette option pour les plugins existants de l’écosystème Claude qui ciblent le Cowork. Pour continuer à développer le plug-in dans Microsoft 365, importez-le :
wiqd plugin import --path ./claude-plugin --privacy-url https://contoso.com/privacy --terms-url https://contoso.com/terms
Pour produire un publiable .zip à partir du plug-in tel qu’il se présente aujourd’hui, utilisez le script de conversion :
atk import openplugin --path ./claude-plugin --output ./my-plugin-project \
--privacy-url https://contoso.com/privacy \
--terms-url https://contoso.com/terms
Meilleures pratiques en matière 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 champ description détermine quand l’assistant déclenche 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.
- Structurez 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. Affichez la structure exacte du tableau, de la liste ou du document à laquelle les utilisateurs doivent s’attendre. Cette définition améliore considérablement la cohérence.
-
Outils de référence par nom. Si votre compétence dépend d’outils connecteurs, nommez-les explicitement : « Utilisez l’outil
search_case_lawpour... » -
Gardez le SKILL.md principal concis. Déplacer la documentation de référence détaillée dans le sous-répertoire
references/. Le corps de la compétence doit être le workflow, pas une encyclopédie.
Éviter les erreurs courantes
-
N’incorporez pas de secrets dans les fichiers
SKILL.md. À utiliseragentConnectorsavec 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 commencer.
- Ne définissez pas les compétences de manière trop large. « Tout faire avec des documents juridiques » est moins bon 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 dans SKILL.md. Si votre corps du texte dépasse ~3 000 mots, déplacez le contenu détaillé vers
references/.
Règles de validation
Lorsque vous envoyez votre paquet, la plateforme le valide à plusieurs niveaux. Corrigez ces erreurs avant la soumission pour éviter tout rejet.
Pour les intercepter au fur et à mesure de la génération plutôt qu’au moment de l’envoi, exécutez wiqd plugin validate --mode deep. Cette commande empaquette le plug-in et exécute ces mêmes règles localement. Pour plus d’informations, consultez l’étape 3 : valider au fur et à mesure que vous créez.
Validation au niveau du manifeste
| Code | Rule | Severity |
|---|---|---|
| ASKILL-M001 |
folder est obligatoire sur chaque entrée agentSkills |
Error |
| ASKILL-M002 |
agentSkills Le tableau peut avoir jusqu’à 20 éléments |
Error |
| ASKILL-M003 |
folder Le chemin d’accès peut compter jusqu’à 256 caractères |
Error |
Validation au niveau du paquet
| Code | Rule | Correction courante | Severity |
|---|---|---|---|
| ASKILL-P001 | Le dossier référencé dans le manifeste se trouve dans l’archive ZIP | Vérifiez la structure de votre archive ZIP | Error |
| ASKILL-P002 | Le dossier contient le fichier SKILL.md |
Ajouter un SKILL.md manquant |
Error |
| ASKILL-P003 |
SKILL.md a un front matter YAML valide, délimité par --- |
Corriger la syntaxe YAML | Error |
| ASKILL-P004 | Les pages préliminaires comprennent un champ name |
Ajouter name: au frontmatter |
Error |
| ASKILL-P005 | Les pages préliminaires comprennent un champ description |
Ajouter description: au frontmatter |
Error |
| ASKILL-P006 |
name correspond au nom du dossier (dernier segment du chemin d’accès) |
Renommer le dossier ou le correctif name: |
Error |
| ASKILL-P007 |
name est kebab-case |
Utilisez my-skill, et non MySkill ou my_skill |
Error |
| ASKILL-P008 | Aucune valeur dupliquée folder dans le tableau |
Supprimer les doublons | Error |
Validation du connecteur
| Rule | Severity |
|---|---|
Chaque connecteur nécessite un id et un displayName |
Error |
Toutes les valeurs du connecteur id doivent être uniques dans le manifeste |
Error |
Exactement l’un des plugin ou remoteMcpServer |
Error |
mcpServerUrl doit être une URL HTTPS valide |
Error |
Si mcpToolDescription est présent, son file doit exister dans le ZIP |
Error |
authorization.referenceId Obligatoire sauf si le type est None |
Error |
authorization.referenceId Ne doit pas être présent lorsque le type est None |
Error |
Validation du fichier compagnon
Le portail valide les fichiers associés (documents de référence, scripts et autres fichiers accompagnant SKILL.md) lors du chargement et de la synchronisation :
| Rule | Severity |
|---|---|
Maximum 20 fichiers enfants par compétence (à l’exception de SKILL.md) |
Error |
| Chaque fichier compagnon doit être inférieur ou égal à 5 Mo | Error |
| La taille totale des fichiers associés doit être inférieure ou égale à 10 Mo par compétence | Error |
| Les chemins d’accès aux fichiers doivent être relatifs (pas de chemins absolus) | Error |
Aucun segment de traversée de chemin (..) |
Error |
| Pas de barres obliques inverses ni d’octets null dans les noms de fichiers | Error |
Aucun fichier caché (noms commençant par .) |
Error |
Aucun nom réservé Windows (CON, PRN, AUX, NUL, COM1–LPT9, COM9–LPT1) |
Error |
Les noms de fichiers doivent utiliser des caractères de sécurité uniquement (alphanumériques, traits d’union, traits de soulignement, points, espaces et !). |
Error |
Compatibilité multiplateforme
Les compétences utilisent la norme ouverte Agent Skills. Les mêmes SKILL.md fichiers fonctionnent sur plusieurs outils d’IA :
| Platform | Compatibilité |
|---|---|
| Claude Code | Format totalement identique SKILL.md |
| Projets Claude.ai | Les compétences complètes peuvent être téléversées en tant que fichiers de projet |
| VS Code / GitHub Copilot | Compétences de l’assistant complet prises en charge en mode assistant |
| Gemini CLI | Compétences d’assistant complet prises en charge |
| JetBrains Junie | Compétences d’assistant complet prises en charge |
| OpenAI Codex | Compétences d’assistant complet prises en charge |
| Cursor | Compétences d’assistant complet prises en charge |
Si vous développez des compétences à la fois pour Claude Code et pour Copilot Cowork, créez le plug-in avec wiqd. Ensuite, exécutez wiqd plugin export --format claude-plugin pour produire la mise en page de Claude Code. Si vous préférez commencer à partir de la structure du plug-in Claude Code (c’est le sur-ensemble) la mise en page est la suivante :
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 Microsoft 365 lorsque vous êtes prêt à le publier dans l’App Store Microsoft 365, avec wiqd plugin import ou avec le script de conversion :
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 votre serveur retourne depuis tools/list, et l’utilise pour décider si un appel d’outil nécessite la confirmation de l’utilisateur et quelle étiquette afficher sur la requête.
Champs disponibles
| Champ | Catégorie | Effect |
|---|---|---|
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écifiées. 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 suggestions est désormais compatible avec les versions futures, et des requêtes 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’assistant d’encoder un fichier en base64 et de coller l’objet blob dans un appel d’outil. Cette approche charge l’ensemble du fichier dans le contexte du modèle et dépend de ce dernier qui reproduit exactement le 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’assistant 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 redistribue les fichiers résolus selon vos noms de paramètres d’origine dans l’ordre de déclaration.
Paramètres des fichiers imbriqués
L’agent prend en charge un paramètre de fichier imbriqué dans un objet ou un tableau d’objets. L’assistant gère ce paramètre différemment : au lieu de le réduire, l’assistant le réécrit en place dans une chaîne de chemin à son propre emplacement. Cette approche préserve l’association entre un fichier et ses champs frères. Par exemple, vous recevez 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’assistant remplit line_items[].receipt avec un chemin d’accès vers l’espace de travail, et Cowork échange chaque chemin contre le contenu base64 sur 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 références ne sont pas suivies : définissez les paramètres de fichier en ligne plutôt que via un $ref.
Ce que reçoit votre serveur
Votre serveur reçoit une requête 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.
Limits
| Limit | Value |
|---|---|
| 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 (combiné 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.
Recommendations
- 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. Cowork transmet 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éfinir les annotations. Un outil qui reçoit un fichier et agit dessus n’est normalement pas en lecture seule, il demande donc une confirmation. En savoir plus sur la 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 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 décompte exact sur les outils uniquement scalaires. 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 n’en fournisse pas trop ou pas assez.
Remarque
Ce mécanisme est antérieur au propre travail d’entrée de fichier Model Context Protocol, 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.
Identifiez 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 | Où il apparaît | Value |
|---|---|---|
En-tête de demande User-Agent |
Chaque requête sortante que Cowork envoie à votre serveur | copilot-cowork/1.0 |
clientInfo dans l’établissement d’une liaison MCP initialize |
La initialize demande uniquement |
{ "name": "copilot-cowork", "version": "<version>" } |
Correspondre au préfixe copilot-cowork
Faites correspondre le préfixecopilot-cowork sensible à la casse, sur l’un ou l’autre canal. Ne faites pas correspondre la chaîne exacte copilot-cowork/1.0 ou un clientInfo.version. La version suit le contrat client-identité et devrait changer ; Une correspondance de préfixe permet à votre portail de travailler sur des heurts de version.
# Correct: case-insensitive prefix match
copilot-cowork
# Incorrect: exact match breaks when the version changes
copilot-cowork/1.0
Choisissez la bonne voie pour votre passerelle
Les deux canaux ont des étendues différentes, donc clé sur celui qui correspond à la façon dont votre serveur applique sa passerelle :
- L’en-tête
User-Agentest présent sur chaque requête, y compristools/listettools/call. Si vous appliquez un contrôle ou attribuez par requête, activez cet en-tête. -
clientInfoest envoyé uniquement lors de l’établissement d’une liaisoninitialize. Si vous appliquez un contrôle par session au moment de la connexion, vous pouvez le consulter à ce moment-là, mais il n’est pas répété 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 courantes
Puis-je utiliser les compétences du package M365 dans Claude Code ?
Oui. Les dossiers de compétences contiennent des compétences d’assistant standard. Exécutez wiqd plugin export --format claude-plugin pour produire la mise en page du Claude Code, ou copiez les dossiers de .claude/skills/ compétences dans n’importe quel projet Claude Code.
Ai-je besoin d’un connecteur à distance ?
No. Les packages de compétences uniquement fonctionnent bien pour les workflows basés sur des requêtes. Les connecteurs ne sont nécessaires que 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 redéfinir les compétences intégrées du même nom. Les paquets déployés par l’administration affichent 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 paquet.
Les compétences peuvent-elles faire référence à des outils de connecteur du même paquet ?
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 d’outil avec contentEncoding: base64, et Cowork convertit le fichier d’espace de travail de l’utilisateur en 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 ?
wiqd plugin create génère et épingle l’ID d’application pour vous. Le script de conversion utilise l’UUID v5 (basé sur SHA-1) à partir du nom de votre plug-in, de sorte que l’exécution de la conversion deux fois produit le même GUID. Pour l’empaquetage manuel, utilisez n’importe quel générateur GUID. Veillez à ce qu’il reste stable d’une version à l’autre.
Quelle version de manifeste dois-je cibler ?
Ciblez la version 1.29 si vous construisez avec wiqd, qui fixe cette version pour vous. À la version 1,29, agentConnectors[] les entrées sont uniquement des URL et mcpToolDescription est facultatif. Les exemples rédigés manuellement de cet article utilisent la version 1.28, dans laquelle mcpToolDescription est requis et le fichier qu’il nomme doit être dans le ZIP.
atk import openplugin utilise l’UUID v5 (basé sur SHA-1) à partir 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, transmettez --app-id. Pour l’empaquetage manuel, utilisez n’importe quel générateur GUID. Veillez à ce qu’il reste stable d’une version à l’autre.