For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navigation principale

Créez un serveur MCP

Ajoutez des données en temps réel et des outils aux actions contrôlées à votre plugin.

Ajoutez un serveur MCP lorsqu’un cas d’usage de votre plugin nécessite des données en temps réel, une authentification, des actions contrôlées ou du code qui s’exécute sur une infrastructure que vous exploitez. Le serveur définit les outils accessibles à ChatGPT et à Codex. Il n’a pas besoin de renvoyer une interface personnalisée.

Partez des objectifs pris en charge dans votre inventaire des cas d’usage. Chaque outil doit contribuer à atteindre un objectif utilisateur clairement identifiable et n’exposer que les données et les actions nécessaires à cet objectif.

Commencez par créer les outils. Une fois le serveur fonctionnel sans interface personnalisée, vous pouvez ajouter une interface au serveur MCP pour les workflows qui nécessitent une interaction visuelle.

Choisissez un kit de développement logiciel MCP

Les kits de développement logiciel officiels fournissent des utilitaires pour les schémas, une structure de base pour le serveur et un transport HTTP en streaming :

Installez le SDK adapté à la stack de votre serveur :

# TypeScript
npm install @modelcontextprotocol/sdk zod

# Python
pip install mcp

Créez le serveur

Créez un serveur MCP avec un nom et une version stables :

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({
  name: "acme-projects",
  version: "1.0.0",
});

Les serveurs MCP peuvent également renvoyer un champ instructions lors de l’initialisation. ChatGPT et Codex utilisent ces instructions en complément des métadonnées des outils.

Utilisez les instructions du serveur pour les consignes communes aux outils, comme les séquences d’appels obligatoires ou les limites de débit partagées. Placez les informations les plus importantes dans les 512 premiers caractères. Ne répétez pas la description de chaque outil et ne cherchez pas à modifier la personnalité du modèle.

const server = new McpServer(
  { name: "acme-projects", version: "1.0.0" },
  {
    instructions:
      "Before updating a project, call get_project to confirm its ID and current status.",
  }
);

Définissez les outils à partir des objectifs des utilisateurs

Créez un outil pour chaque action distincte que le plugin doit prendre en charge. Privilégiez des opérations ciblées telles que list_projects, get_project et update_project plutôt qu’un seul outil proposant de nombreux modes sans rapport entre eux.

Chaque outil doit disposer des éléments suivants :

  • Un nom qui exprime l’action et un titre compréhensible par l’utilisateur.
  • Une description qui explique quand l’utiliser.
  • Un schéma d’entrée explicite.
  • Un schéma de sortie lorsque l’outil renvoie des données structurées.
  • Des annotations de sécurité exactes.
  • Un gestionnaire qui autorise la requête et exécute l’opération.

Le modèle utilise ces métadonnées pour décider s’il doit appeler l’outil et comment le faire. Considérez les noms, les descriptions, les schémas et les annotations comme faisant partie du comportement du plugin visible par l’utilisateur.

import { z } from "zod";

server.registerTool(
  "list_projects",
  {
    title: "List projects",
    description:
      "Use this when the user wants to find or review projects in their Acme workspace.",
    inputSchema: {
      status: z.enum(["active", "archived"]).optional(),
    },
    outputSchema: {
      projects: z.array(
        z.object({
          id: z.string(),
          name: z.string(),
          status: z.string(),
        })
      ),
    },
    annotations: {
      readOnlyHint: true,
      openWorldHint: false,
      destructiveHint: false,
    },
  },
  async ({ status }) => {
    const projects = await listProjects({ status });

    return {
      structuredContent: { projects },
      content: [
        {
          type: "text",
          text: `Found ${projects.length} projects.`,
        },
      ],
    };
  }
);

Renvoyez des résultats utiles sans interface

Le résultat d’un outil peut inclure les éléments suivants :

  • structuredContent : des données concises que le modèle peut examiner et utiliser lors d’appels ultérieurs.
  • content : du texte ou d’autres contenus MCP qui aident le modèle à répondre à l’utilisateur.
  • _meta : des données propres au client, masquées au modèle.

Renvoyez suffisamment d’informations pour que le modèle puisse mener le workflow à son terme sans composant. Utilisez des identifiants stables dans les résultats structurés pour que les outils appelés ensuite puissent faire référence aux mêmes enregistrements.

N’incluez pas de secrets, de jetons d’accès ni de données personnelles superflues dans les résultats des outils. Considérez _meta comme un champ masqué au modèle, et non comme un substitut à l’autorisation ou au stockage sécurisé.

Importez des skills depuis le serveur MCP

Configurez le serveur MCP pour qu’il fournisse des skills si vous souhaitez versionner et déployer leurs instructions et leurs fichiers complémentaires avec le serveur. Lors de la soumission du plugin, Analyser les outils importe un instantané statique de ces skills dans le brouillon.

OpenAI prend actuellement en charge un sous-ensemble limité et statique du projet d’extension Skills SEP-2640. Cette proposition ne fait pas encore partie de la spécification MCP stable.

Déclarez io.modelcontextprotocol/skills parmi les capacités du serveur annoncées lors de l’initialisation :

{
  "capabilities": {
    "extensions": {
      "io.modelcontextprotocol/skills": {}
    }
  }
}

La déclaration doit se trouver sous capabilities.extensions. OpenAI ne reconnaît pas l’ancienne déclaration experimental.

Listez les skills et leurs ressources

Prenez en charge la méthode paginée skills/list. Chaque entrée doit inclure les éléments suivants :

  • Un champ uri qui pointe vers le fichier SKILL.md du skill.
  • Un champ frontmatter contenant toutes les entrées issues de l’analyse de l’en-tête de métadonnées de SKILL.md. Incluez les entrées name et description.
  • Une liste resources complète contenant SKILL.md et tous les fichiers complémentaires.
  • Une empreinte SHA-256 pour chaque ressource, au format sha256:<64 lowercase hexadecimal characters>.

Utilisez la convention d’URI skill://. Le répertoire contenant SKILL.md doit porter le même nom que le skill. Par exemple :

{
  "skills": [
    {
      "uri": "skill://dice-roller/tabletop-dice/SKILL.md",
      "frontmatter": {
        "name": "tabletop-dice",
        "description": "Roll one or more dice and report each result and the total."
      },
      "resources": [
        {
          "uri": "skill://dice-roller/tabletop-dice/SKILL.md",
          "digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
        },
        {
          "uri": "skill://dice-roller/tabletop-dice/references/notation.md",
          "digest": "sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
        }
      ]
    }
  ],
  "nextCursor": "optional-next-page-cursor"
}

Les exemples d’empreintes illustrent le format requis. Pour une ressource textuelle, calculez le hachage des octets UTF-8 de content.text. Pour une ressource blob, décodez le contenu base64 de content.blob, puis calculez le hachage des octets décodés.

Prenez également en charge skills/get pour chaque URI répertorié pointant vers un fichier SKILL.md. Renvoyez un objet skill ayant la même structure complète que les entrées de skills/list.

Utilisez les paramètres de requête suivants :

  • Pour la première requête skills/list, acceptez un objet vide ({}).
  • Pour chaque requête skills/list suivante, acceptez le curseur renvoyé, par exemple { "cursor": "next-page-cursor" }.
  • Pour skills/get, acceptez l’URI du catalogue, par exemple { "uri": "skill://dice-roller/tabletop-dice/SKILL.md" }.

Renvoyez toutes les ressources répertoriées

Prenez en charge resources/read pour chaque URI du manifeste. Renvoyez exactement un élément de contenu dont l’URI correspond à la requête. OpenAI accepte du texte UTF-8 ou un blob encodé en base64.

Lors de l’importation, OpenAI vérifie que :

  • OpenAI peut récupérer chaque ressource répertoriée et vérifier son empreinte.
  • L’en-tête de métadonnées du fichier SKILL.md récupéré correspond exactement à l’entrée du catalogue.
  • Les chemins des ressources sont sûrs, uniques et ne présentent aucun conflit de normalisation.
  • Le skill complet respecte les limites d’importation.

L’importateur accepte jusqu’à cinq skills aux noms uniques, répartis sur 10 pages de catalogue. Chaque skill peut contenir jusqu’à 100 fichiers, avec les limites de taille suivantes :

ContenuLimite
SKILL.md256 KiB
Chaque fichier complémentaire1 MiB
Toutes les ressources d’un skill5 MiB
Archives de skills générées lors d’une analyse8 MiB

La limite de taille cumulée des archives inclut les données supplémentaires liées au format ZIP.

Si une entrée échoue à la validation ou dépasse une limite, Analyser les outils renvoie toujours les outils du serveur, mais ne met pas à jour les skills importées dans le brouillon. Corrigez le serveur et relancez l’analyse.

Les skills importées depuis MCP sont des instantanés pris lors de la soumission, et non des ressources chargées dynamiquement à l’exécution. Après avoir modifié une skill, relancez Analyser les outils , vérifiez les skills importées et soumettez une nouvelle version du plugin. Consultez Soumettez des plugins pour connaître la procédure complète.

Authentifiez et autorisez les requêtes

Ajoutez une authentification lorsqu’un outil lit des données privées ou agit pour le compte d’un utilisateur. Faites respecter les autorisations dans le serveur MCP à chaque requête ; ne vous fiez jamais au modèle pour déterminer si un utilisateur dispose d’un accès.

Consultez Authentifiez les utilisateurs pour en savoir plus sur la découverte OAuth, les schémas de sécurité et les demandes d’autorisation.

Pour faciliter l’utilisation de plusieurs comptes, exposez un outil de profil en lecture seule qui nécessite une authentification et marquez-le avec _meta["openai/profile"]: true. OpenAI utilise les informations du profil pour identifier les comptes connectés de manière cohérente et aider les utilisateurs à les distinguer. Déterminez le profil à partir des informations d’authentification validées de la requête et limitez chaque appel d’outil au périmètre associé à ces informations d’authentification. Les utilisateurs peuvent connecter plusieurs comptes sans outil de profil. Consultez Prendre en charge plusieurs comptes pour découvrir le schéma et l’exemple d’implémentation.

Annotations des outils et élicitation

Définissez les annotations en fonction du comportement réel :

  • readOnlyHint : true uniquement lorsque l’outil ne peut pas modifier l’état.
  • destructiveHint : true lorsqu’un outil peut avoir des effets irréversibles ou difficiles à annuler.
  • openWorldHint : true lorsqu’un outil accède à l’Internet public ou à des entités externes sans périmètre délimité, y compris par des actions en lecture seule telles que la recherche web. Un outil limité au périmètre d’un compte privé ou d’un espace de travail peut définir cette valeur sur false, même si le service est hébergé à l’extérieur.

Les annotations aident ChatGPT et Codex à adopter un comportement approprié en matière de confirmation et de sécurité. Elles ne remplacent pas les mécanismes d’autorisation, de validation ou de confirmation sur votre serveur.

Utilisez l’élicitation MCP lorsque le serveur a besoin d’informations structurées qui n’ont pas été fournies lors de l’appel initial de l’outil. Limitez l’élicitation aux informations que l’utilisateur peut raisonnablement fournir. Ne l’utilisez pas pour recueillir des secrets ou contourner l’authentification habituelle.

Compatibilité avec les connaissances de l’entreprise

Les connaissances de l’entreprise peuvent utiliser les outils en lecture seule de votre serveur MCP. Pour qu’un plugin puisse servir de source de connaissances de l’entreprise, implémentez les schémas d’entrée standard des outils search et fetch, et annotez les autres outils en lecture seule avec readOnlyHint: true.

Renvoyez des URL absolues que l’utilisateur peut ouvrir pour les sources que le modèle doit citer. Conservez les identifiants internes des documents dans le champ id du résultat. Pour connaître les schémas et les structures de résultats requis, consultez Créez des serveurs MCP pour ChatGPT et les intégrations API.

Exécutez et testez en local

Exposez un point de terminaison HTTP prenant en charge la diffusion en continu, généralement à l’adresse /mcp, puis inspectez-le avec MCP Inspector :

npx @modelcontextprotocol/inspector

Dans l’interface d’Inspector, sélectionnez Streamable HTTP et saisissez http://localhost:3000/mcp.

Utilisez l’inspecteur pour effectuer les vérifications suivantes :

  1. Confirmez que l’initialisation réussit.
  2. Examinez les instructions du serveur et la liste des outils annoncés.
  3. Appelez chaque outil avec des entrées représentatives et des entrées non valides.
  4. Vérifiez les schémas, les résultats, les erreurs et les annotations.
  5. Confirmez que les autorisations sont appliquées aux données privées et aux actions d’écriture.

Connectez ensuite le serveur à ChatGPT en mode développeur et exécutez les requêtes directes, indirectes, limites et hors périmètre de votre inventaire de cas d’usage.

Déployez le point de terminaison

Pour soumettre un plugin destiné au public, déployez le serveur MCP sur un point de terminaison HTTPS stable et accessible publiquement. Le Tunnel MCP sécurisé permet de connecter un serveur MCP privé en mode développeur, mais ne répond pas aux exigences de soumission d’un plugin destiné au public.

Le point de terminaison de production doit :

  • Prendre en charge le transport HTTP MCP avec diffusion en continu.
  • Répondre à une URL stable, se terminant généralement par /mcp.
  • Répondre aux besoins de latence et de disponibilité des workflows du plugin.
  • Accéder aux services et aux systèmes de stockage de données nécessaires.
  • Respecter les limites d’accès définies par l’authentification et les autorisations.
  • Produire des journaux et des métriques pour les échecs d’initialisation et d’appels d’outils.

Si le serveur MCP doit rester privé, déployez un proxy HTTPS public qui transmet les requêtes MCP au serveur privé. Utilisez mTLS géré par OpenAI pour authentifier ChatGPT en tant que client MCP, et utilisez OAuth 2.1 lorsque votre plugin nécessite l’authentification des utilisateurs. Si votre réseau exige une liste d’adresses IP autorisées, utilisez les plages d’adresses IP publiées pour les connecteurs ChatGPT et mettez cette liste à jour automatiquement. Une liste d’adresses IP autorisées ne remplace pas l’authentification ni les contrôles d’autorisation.

Le point de terminaison public doit rester accessible pour la révision du plugin et la vérification du domaine. N’utilisez pas le Tunnel MCP sécurisé seul, un tunnel temporaire ou un point de terminaison local pour soumettre un plugin destiné au public.

Choisissez l’infrastructure

Vous pouvez déployer le serveur MCP sur une infrastructure serverless, conteneurisée, edge ou applicative traditionnelle. Choisissez une plateforme en fonction des critères suivants :

  • Prise en charge de l’environnement d’exécution et des dépendances.
  • Comportement des réponses diffusées en continu.
  • Latence des démarrages à froid et des requêtes.
  • Accès réseau aux services nécessaires.
  • Exigences de résidence des données et de conformité.
  • Gestion des secrets.
  • Journalisation, traçage et alertes.
  • Prise en charge du retour arrière et de la gestion des versions.

Si le serveur héberge également les ressources d’une interface facultative, déployez-les sur des origines stables autorisées par la politique de sécurité du contenu du composant.

Configurez le point de terminaison de production

Avant le déploiement :

  1. Définissez les identifiants de production dans le système de gestion des secrets de l’hôte.
  2. Configurez le serveur d’autorisation et les comportements de redirection autorisés.
  3. Appliquez des délais d’expiration et des limites de débit aux outils coûteux ou visibles à l’extérieur.
  4. Supprimez les réponses de débogage et les données personnelles inutiles.
  5. Confirmez que les journaux ne contiennent aucun jeton d’accès ni résultat d’outil sensible.

Après le déploiement, appelez le point de terminaison de production avec MCP Inspector. Vérifiez l’initialisation, les instructions du serveur, les outils, les schémas, les annotations, l’authentification, les résultats et les erreurs.

Préparez les mises à jour

Préservez la rétrocompatibilité des noms et des schémas des outils publiés. Ajoutez des champs ou des outils sans rompre les contrats existants. Si les métadonnées changent, actualisez la connexion en mode développeur et réexécutez l’ensemble des évaluations avant la soumission.

Pour l’interface facultative, versionnez les identifiants des ressources lorsque des modifications du HTML, du JavaScript ou du CSS risquent de rendre un composant en cache incompatible.

Ajoutez une interface facultative

Une fois les outils opérationnels de bout en bout, déterminez si certains cas d’usage nécessitent une interaction visuelle. Un tableau, une carte, un planning modifiable ou une vue comparative peuvent bénéficier d’une interface. Une recherche d’information, une vérification d’état ou une action en arrière-plan peuvent souvent s’en passer.

Poursuivez avec Ajouter une interface utilisateur à votre serveur MCP pour enregistrer une ressource MCP Apps et l’associer aux outils sélectionnés.

Rappels de sécurité

  • Considérez toutes les données d’entrée des outils comme non fiables.
  • Validez les paramètres et appliquez les contrôles d’autorisation sur le serveur.
  • Exigez une confirmation pour les actions d’écriture ayant des conséquences importantes.
  • N’incluez aucun secret ni aucune donnée sensible dans les métadonnées et les résultats des outils.
  • Consignez suffisamment de contexte pour analyser les échecs, sans enregistrer d’identifiants d’accès ni de données personnelles superflues.
  • Appliquez des limites de débit aux actions coûteuses ou visibles à l’extérieur.