Comment créer un serveur MCP pour donner aux agents IA des pouvoirs de test API

Ashley Innocent

Ashley Innocent

19 March 2026

Comment créer un serveur MCP pour donner aux agents IA des pouvoirs de test API

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Explorer Apidog Enterprise

En bref

Créez un serveur MCP avec TypeScript qui expose trois outils : run_test, validate_schema et list_environments. Configurez-le dans ~/.claude/settings.json pour Claude Code ou .cursor/mcp.json pour Cursor. Vos agents IA pourront alors exécuter des tests Apidog, valider des schémas OpenAPI et récupérer des environnements sans quitter l'interface de chat. Le code source complet fait environ 150 lignes et utilise le package @modelcontextprotocol/sdk.

Créez un serveur MCP qui permet à Claude Code, Cursor et d'autres agents IA d'exécuter des tests d'API Apidog, de valider des schémas et de comparer des réponses, le tout sans quitter leur interface de chat.

💡
Vous êtes en pleine session de codage. Votre agent IA vient de terminer la création d'un point de terminaison d'API. Au lieu de copier le code, d'ouvrir Apidog, de créer une collection de tests et d'exécuter manuellement la validation, vous voulez taper une seule commande et obtenir les résultats.
bouton

C'est ce que le Protocole de Contexte de Modèle (MCP) rend possible. Le MCP permet aux agents IA d'accéder à des outils externes via une interface standardisée. Créez un serveur MCP pour Apidog, et votre agent IA pourra exécuter des tests, valider des schémas et récupérer des environnements sans changer de contexte.

Qu'est-ce que le MCP ?

Le MCP (Protocole de Contexte de Modèle) est un protocole permettant aux agents IA d'accéder à des outils et des sources de données externes. Considérez-le comme un système de plugins qui fonctionne avec Claude Code, Cursor et d'autres clients compatibles MCP.

Un serveur MCP expose des outils (fonctions que l'agent peut appeler) et des ressources (données que l'agent peut lire). Votre serveur MCP Apidog exposera des outils pour les tests d'API.

┌─────────────────┐         ┌──────────────────┐         ┌─────────────┐
│  AI Agent       │         │  MCP Server      │         │  Apidog     │
│  (Claude Code)  │◄───────►│  (Your Code)     │◄───────►│  API        │
└─────────────────┘   JSON  └──────────────────┘  HTTP   └─────────────┘

Étape 1 : Configurer le projet

Créez un nouveau projet TypeScript :

mkdir apidog-mcp-server
cd apidog-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node

Créez tsconfig.json :

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Ajoutez un script de build à package.json :

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

Étape 2 : Créer le squelette du serveur MCP

Créez src/index.ts :

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "apidog",
  version: "1.0.0",
  description: "Apidog API testing tools for AI agents"
});

// Tools will be defined here

const transport = new StdioServerTransport();
await server.connect(transport);

Ce squelette crée un serveur MCP et le connecte au transport stdio. Le transport gère la communication entre l'agent IA et votre serveur via l'entrée/sortie standard.

Étape 3 : Définir l'outil run_test

Ajoutez le premier outil à src/index.ts :

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "apidog",
  version: "1.0.0",
  description: "Apidog API testing tools for AI agents"
});

// Tool: run_test
server.tool(
  "run_test",
  {
    projectId: z.string().describe("Apidog project ID (found in project URL)"),
    environmentId: z.string().optional().describe("Optional environment ID for test execution"),
    testSuiteId: z.string().optional().describe("Optional test suite ID to run specific suite")
  },
  async ({ projectId, environmentId, testSuiteId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Error: APIDOG_API_KEY environment variable not set"
        }]
      };
    }

    // Build API URL
    let url = `https://api.apidog.com/v1/projects/${projectId}/tests/run`;
    const params = new URLSearchParams();
    if (environmentId) params.append("environmentId", environmentId);
    if (testSuiteId) params.append("testSuiteId", testSuiteId);
    if (params.toString()) url += `?${params.toString()}`;

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${apiKey}`,
          "Content-Type": "application/json"
        }
      });

      if (!response.ok) {
        const error = await response.text();
        return {
          content: [{
            type: "text",
            text: `API Error: ${response.status} ${error}`
          }]
        };
      }

      const results = await response.json();
      return {
        content: [{
          type: "text",
          text: JSON.stringify(results, null, 2)
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `Request failed: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

La définition de l'outil comporte trois parties :

  1. Nomrun_test (les agents sélectionnent les outils par leur nom, donc rendez-le descriptif)
  2. Schéma — Validation Zod pour les paramètres avec descriptions
  3. Gestionnaire — Fonction asynchrone qui appelle l'API Apidog

Étape 4 : Ajouter l'outil validate_schema

Ajoutez la validation de schéma pour intercepter les erreurs OpenAPI avant le déploiement :

// Tool: validate_schema
server.tool(
  "validate_schema",
  {
    schema: z.object({}).describe("OpenAPI 3.x schema object to validate"),
    strict: z.boolean().optional().default(false).describe("Enable strict mode for additional checks")
  },
  async ({ schema, strict }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Error: APIDOG_API_KEY environment variable not set"
        }]
      };
    }

    try {
      const response = await fetch("https://api.apidog.com/v1/schemas/validate", {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${apiKey}`,
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ schema, strict })
      });

      const result = await response.json();

      if (!response.ok) {
        return {
          content: [{
            type: "text",
            text: `Validation failed: ${JSON.stringify(result.errors, null, 2)}`
          }]
        };
      }

      return {
        content: [{
          type: "text",
          text: result.valid
            ? "Schema is valid OpenAPI 3.x"
            : `Warnings: ${JSON.stringify(result.warnings, null, 2)}`
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `Validation failed: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

Étape 5 : Ajouter l'outil list_environments

Ajoutez un outil pour récupérer les environnements de test disponibles :

// Tool: list_environments
server.tool(
  "list_environments",
  {
    projectId: z.string().describe("Apidog project ID")
  },
  async ({ projectId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Error: APIDOG_API_KEY environment variable not set"
        }]
      };
    }

    try {
      const response = await fetch(
        `https://api.apidog.com/v1/projects/${projectId}/environments`,
        {
          headers: {
            "Authorization": `Bearer ${apiKey}`
          }
        }
      );

      if (!response.ok) {
        const error = await response.text();
        return {
          content: [{
            type: "text",
            text: `API Error: ${response.status} ${error}`
          }]
        };
      }

      const environments = await response.json();
      return {
        content: [{
          type: "text",
          text: environments.length === 0
            ? "No environments found for this project"
            : environments.map((e: any) =>
                `- ${e.name} (ID: ${e.id})${e.isDefault ? " [default]" : ""}`
              ).join("\n")
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `Request failed: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

Étape 6 : Compiler et tester

Compilez le serveur :

npm run build

Testez avec un client MCP simple. Créez test-client.js :

import { spawn } from "child_process";

const server = spawn("node", ["dist/index.js"], {
  env: { ...process.env, APIDOG_API_KEY: "your-api-key" }
});

server.stdout.on("data", (data) => {
  console.log(`Server output: ${data}`);
});

server.stderr.on("data", (data) => {
  console.error(`Server error: ${data}`);
});

// Send a test message
const message = {
  jsonrpc: "2.0",
  id: 1,
  method: "initialize",
  params: {
    protocolVersion: "2024-11-05",
    capabilities: {},
    clientInfo: { name: "test-client", version: "1.0.0" }
  }
};

server.stdin.write(JSON.stringify(message) + "\n");

Étape 7 : Configurer pour Claude Code

Ajoutez le serveur MCP à votre configuration Claude Code :

Créez ou modifiez ~/.claude/settings.json :

{
  "mcpServers": {
    "apidog": {
      "command": "node",
      "args": ["/absolute/path/to/apidog-mcp-server/dist/index.js"],
      "env": {
        "APIDOG_API_KEY": "your-api-key-here"
      }
    }
  }
}

Redémarrez Claude Code. Les outils Apidog devraient maintenant apparaître lorsque vous demandez de l'aide pour les tests d'API.

Utilisation dans Claude Code :

Utilisez l'outil run_test pour exécuter des tests sur mon projet Apidog.
ID du projet : proj_12345
Environnement : staging
Validez ce schéma OpenAPI par rapport aux règles Apidog :
[coller le schéma]
Listez tous les environnements pour le projet proj_12345

Étape 8 : Configurer pour Cursor

Cursor utilise une configuration MCP similaire. Créez .cursor/mcp.json dans votre projet :

{
  "mcpServers": {
    "apidog": {
      "command": "node",
      "args": ["/absolute/path/to/apidog-mcp-server/dist/index.js"],
      "env": {
        "APIDOG_API_KEY": "your-api-key-here"
      }
    }
  }
}

Utilisation dans Cursor :

@apidog run_test projectId="proj_12345" environmentId="staging"

Code source complet

Voici le fichier src/index.ts complet :

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "apidog",
  version: "1.0.0",
  description: "Apidog API testing tools for AI agents"
});

// Tool: run_test
server.tool(
  "run_test",
  {
    projectId: z.string().describe("Apidog project ID"),
    environmentId: z.string().optional().describe("Environment ID"),
    testSuiteId: z.string().optional().describe("Test suite ID")
  },
  async ({ projectId, environmentId, testSuiteId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Error: APIDOG_API_KEY not set"
        }]
      };
    }

    let url = `https://api.apidog.com/v1/projects/${projectId}/tests/run`;
    const params = new URLSearchParams();
    if (environmentId) params.append("environmentId", environmentId);
    if (testSuiteId) params.append("testSuiteId", testSuiteId);
    if (params.toString()) url += `?${params.toString()}`;

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${apiKey}`,
          "Content-Type": "application/json"
        }
      });

      const results = await response.json();
      return {
        content: [{
          type: "text",
          text: JSON.stringify(results, null, 2)
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `Request failed: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);

// Tool: validate_schema
server.tool(
  "validate_schema",
  {
    schema: z.object({}).describe("OpenAPI schema"),
    strict: z.boolean().optional().default(false)
  },
  async ({ schema, strict }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Error: APIDOG_API_KEY not set"
        }]
      };
    }

    const response = await fetch("https://api.apidog.com/v1/schemas/validate", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ schema, strict })
    });

    const result = await response.json();
    return {
      content: [{
        type: "text",
        text: result.valid
          ? "Schema is valid"
          : `Issues: ${JSON.stringify(result.errors || result.warnings, null, 2)}`
      }]
    };
  }
);

// Tool: list_environments
server.tool(
  "list_environments",
  {
    projectId: z.string().describe("Apidog project ID")
  },
  async ({ projectId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Error: APIDOG_API_KEY not set"
        }]
      };
    }

    const response = await fetch(
      `https://api.apidog.com/v1/projects/${projectId}/environments`,
      {
        headers: { "Authorization": `Bearer ${apiKey}` }
      }
    );

    const environments = await response.json();
    return {
      content: [{
        type: "text",
        text: environments.map((e: any) =>
          `- ${e.name} (${e.id})${e.isDefault ? " [default]" : ""}`
        ).join("\n")
      }]
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

Ce que vous avez construit

Composant Objectif
Serveur MCP Connecte les agents IA à l'API Apidog
run_test Exécute des collections de tests par programme
validate_schema Détecte les erreurs OpenAPI avant le déploiement
list_environments Découvre les environnements de test disponibles
Validation Zod Gestion des paramètres typée et sécurisée
Transport Stdio Fonctionne avec Claude Code, Cursor, tout client MCP

Prochaines étapes

Étendre le serveur :

Considérations de production :

Partagez avec votre équipe :

Dépannage des problèmes courants

Le serveur MCP ne se charge pas dans Claude Code :

Les outils n'apparaissent pas après la configuration :

Les requêtes API échouent avec 401 :

Erreurs de validation Zod :

Erreurs de compilation TypeScript :

Tester votre serveur MCP localement

Avant de déployer en production, testez votre serveur localement :

Test manuel avec stdio :

# Démarrez le serveur
node dist/index.js

# Dans un autre terminal, envoyez un message de test
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js

Sortie attendue :

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      { "name": "run_test", "description": "...", "inputSchema": {...} },
      { "name": "validate_schema", "description": "...", "inputSchema": {...} },
      { "name": "list_environments", "description": "...", "inputSchema": {...} }
    ]
  }
}

Testez un appel d'outil :

echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_environments","arguments":{"projectId":"your-project-id"}}}' | node dist/index.js

Vos agents IA ont désormais un accès direct aux capacités de test d'Apidog. Fini le copier-coller entre le chat et le navigateur. Fini les exécutions de tests manuelles. Tapez une commande, obtenez des résultats.

C'est la puissance du MCP : étendez vos agents IA avec des outils spécifiques à un domaine, et laissez-les faire ce qu'ils sont censés faire — vous aider à livrer plus vite.

Points clés à retenir

bouton

FAQ

Qu'est-ce que le MCP en IA ?Le MCP (Protocole de Contexte de Modèle) est un protocole standardisé qui permet aux agents IA d'accéder à des outils et des sources de données externes. Considérez-le comme un système de plugins pour les agents IA.

Comment créer un serveur MCP pour Apidog ?Installez @modelcontextprotocol/sdk, définissez des outils avec la validation Zod, implémentez des gestionnaires qui appellent l'API Apidog et connectez-vous via StdioServerTransport.

Puis-je utiliser cela avec Cursor ?Oui. Ajoutez la configuration du serveur MCP à .cursor/mcp.json à la racine de votre projet. Le même serveur fonctionne avec Claude Code, Cursor et d'autres clients MCP.

Quels outils devrais-je exposer ?Commencez par run_test pour exécuter des collections de tests, validate_schema pour la validation OpenAPI et list_environments pour récupérer les environnements disponibles.

Le serveur MCP Apidog est-il prêt pour la production ?Le code du tutoriel est un point de départ. Ajoutez une logique de réessai, une limitation de débit, une gestion appropriée des erreurs et un stockage sécurisé des clés API avant de l'utiliser en production.

Ai-je besoin d'une clé API Apidog ?Oui. Définissez APIDOG_API_KEY comme variable d'environnement. Le serveur lit cette variable lors de l'exécution pour authentifier les requêtes API.

Puis-je partager ce serveur MCP avec mon équipe ?Oui. Publiez-le sur npm en tant que package privé, documentez les variables d'environnement requises et incluez des exemples de configurations MCP.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API