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.
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 :
- Nom —
run_test(les agents sélectionnent les outils par leur nom, donc rendez-le descriptif) - Schéma — Validation Zod pour les paramètres avec descriptions
- 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 :
- Ajoutez l'outil
compare_responsespour comparer les résultats des tests entre les environnements - Ajoutez
get_test_historypour récupérer l'historique des exécutions de tests - Ajoutez
trigger_mock_serverpour démarrer/arrêter les points de terminaison fictifs
Considérations de production :
- Ajoutez une logique de réessai pour les requêtes réseau instables
- Implémentez une limitation de débit pour éviter le bridage de l'API
- Ajoutez une journalisation pour le débogage des appels d'outils échoués
- Stockez les clés API dans un coffre-fort sécurisé au lieu de variables d'environnement
Partagez avec votre équipe :
- Publiez sur npm en tant que
@your-org/apidog-mcp-server - Documentez les variables d'environnement requises
- Incluez des exemples de configurations MCP pour les clients courants
Dépannage des problèmes courants
Le serveur MCP ne se charge pas dans Claude Code :
- Vérifiez que le chemin dans
~/.claude/settings.jsonest absolu (pas relatif) - Vérifiez que
nodeest dans votre PATH :which node - Assurez-vous que le fichier
dist/index.jscompilé existe :ls -la dist/ - Recherchez les erreurs dans les journaux MCP de Claude Code
Les outils n'apparaissent pas après la configuration :
- Redémarrez complètement Claude Code (quittez et rouvrez)
- Exécutez
npm run buildpour vous assurer que TypeScript est compilé - Vérifiez que les trois outils sont définis avant
server.connect() - Vérifiez que le serveur démarre sans erreurs :
node dist/index.js
Les requêtes API échouent avec 401 :
- Confirmez que
APIDOG_API_KEYest défini dans la configuration - Vérifiez l'absence d'espaces supplémentaires ou de guillemets autour de la valeur de la clé
- Vérifiez que votre compte Apidog a l'accès API activé
- Testez la clé manuellement :
curl -H "Authorization: Bearer $APIDOG_API_KEY" https://api.apidog.com/v1/user
Erreurs de validation Zod :
- Assurez-vous que les noms des paramètres correspondent exactement au schéma
- Vérifiez que les champs obligatoires sont fournis (pas de fautes de frappe dans
projectId) - Vérifiez que les champs facultatifs utilisent
.optional()dans le schéma - Lisez le message d'erreur complet — Zod vous indique quel champ a échoué
Erreurs de compilation TypeScript :
- Exécutez
npm installpour vous assurer que toutes les dépendances sont installées - Vérifiez la version de TypeScript :
npx tsc --version(devrait être 5.x) - Nettoyez et recompilez :
rm -rf dist && npm run build - Recherchez les incompatibilités de type dans les réponses fetch (ajoutez des assertions de type
as)
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
- Les serveurs MCP connectent les agents IA aux API externes — Construisez une fois, utilisez avec Claude Code, Cursor et tout client compatible MCP
- Trois outils couvrent la plupart des besoins de test d'API —
run_testpour l'exécution,validate_schemapour la validation OpenAPI,list_environmentspour la découverte - La validation Zod empêche les mauvais paramètres — Les définitions d'outils typées et sécurisées détectent les erreurs avant les appels API
- La configuration est spécifique à l'outil — Claude Code utilise
~/.claude/settings.json, Cursor utilise.cursor/mcp.json - La production nécessite une gestion des erreurs — Ajoutez une logique de réessai, une limitation de débit et un stockage sécurisé des clés avant le déploiement
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.
