En resumen
Crea un servidor MCP con TypeScript que exponga tres herramientas: run_test, validate_schema y list_environments. Configúralo en ~/.claude/settings.json para Claude Code o .cursor/mcp.json para Cursor. Tus agentes de IA podrán entonces ejecutar pruebas de Apidog, validar esquemas OpenAPI y obtener entornos sin salir de la interfaz de chat. El código fuente completo tiene unas 150 líneas y utiliza el paquete @modelcontextprotocol/sdk.
Crea un servidor MCP que permita a Claude Code, Cursor y otros agentes de IA ejecutar pruebas de API de Apidog, validar esquemas y comparar respuestas, todo sin salir de su interfaz de chat.
Eso es lo que permite el Protocolo de Contexto del Modelo (MCP). MCP permite a los agentes de IA acceder a herramientas externas a través de una interfaz estandarizada. Construye un servidor MCP para Apidog, y tu agente de IA podrá ejecutar pruebas, validar esquemas y obtener entornos sin cambiar de contexto.
¿Qué es MCP?
MCP (Model Context Protocol) es un protocolo para que los agentes de IA accedan a herramientas y fuentes de datos externas. Piensa en ello como un sistema de complementos que funciona en Claude Code, Cursor y otros clientes compatibles con MCP.
Un servidor MCP expone herramientas (funciones que el agente puede llamar) y recursos (datos que el agente puede leer). Tu servidor MCP de Apidog expondrá herramientas para las pruebas de API.
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ Agente de IA │ │ Servidor MCP │ │ Apidog │
│ (Claude Code) │◄───────►│ (Tu Código) │◄───────►│ API │
└─────────────────┘ JSON └──────────────────┘ HTTP └─────────────┘
Paso 1: Configurar el proyecto
Crea un nuevo proyecto TypeScript:
mkdir apidog-mcp-server
cd apidog-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
Crea 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"]
}
Añade un script de construcción a package.json:
{
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
}
Paso 2: Crear el esqueleto del servidor MCP
Crea 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);
Este esqueleto crea un servidor MCP y lo conecta al transporte stdio. El transporte gestiona la comunicación entre el agente de IA y tu servidor a través de la entrada/salida estándar.
Paso 3: Definir la herramienta run_test
Añade la primera herramienta a 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 definición de la herramienta tiene tres partes:
- Nombre —
run_test(los agentes seleccionan herramientas por nombre, así que hazlo descriptivo) - Esquema — Validación Zod para parámetros con descripciones
- Manejador — Función asíncrona que llama a la API de Apidog
Paso 4: Añadir la herramienta validate_schema
Añade la validación de esquemas para detectar errores de OpenAPI antes del despliegue:
// 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)}`
}]
};
}
}
);
Paso 5: Añadir la herramienta list_environments
Añade una herramienta para obtener los entornos de prueba 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)}`
}]
};
}
}
);
Paso 6: Construir y probar
Construye el servidor:
npm run build
Prueba con un cliente MCP simple. Crea 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");
Paso 7: Configurar para Claude Code
Añade el servidor MCP a tu configuración de Claude Code:
Crea o edita ~/.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"
}
}
}
}
Reinicia Claude Code. Las herramientas de Apidog deberían aparecer ahora cuando pidas ayuda para pruebas de API.
Uso en Claude Code:
Usa la herramienta run_test para ejecutar pruebas en mi proyecto Apidog.
ID del proyecto: proj_12345
Entorno: staging
Valida este esquema OpenAPI según las reglas de Apidog:
[pegar esquema]
Lista todos los entornos para el proyecto proj_12345
Paso 8: Configurar para Cursor
Cursor utiliza una configuración MCP similar. Crea .cursor/mcp.json en tu proyecto:
{
"mcpServers": {
"apidog": {
"command": "node",
"args": ["/absolute/path/to/apidog-mcp-server/dist/index.js"],
"env": {
"APIDOG_API_KEY": "your-api-key-here"
}
}
}
}
Uso en Cursor:
@apidog run_test projectId="proj_12345" environmentId="staging"
Código fuente completo
Aquí está el archivo completo 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"),
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);
Lo que has construido
| Componente | Propósito |
|---|---|
| Servidor MCP | Conecta agentes de IA a la API de Apidog |
run_test |
Ejecutar colecciones de pruebas programáticamente |
validate_schema |
Detectar errores de OpenAPI antes del despliegue |
list_environments |
Descubrir entornos de prueba disponibles |
| Validación Zod | Manejo de parámetros con seguridad de tipos |
| Transporte Stdio | Funciona con Claude Code, Cursor, cualquier cliente MCP |
Próximos pasos
Extiende el servidor:
- Añade la herramienta
compare_responsespara comparar resultados de pruebas entre entornos - Añade
get_test_historypara obtener el historial de ejecuciones de pruebas - Añade
trigger_mock_serverpara iniciar/detener puntos finales simulados
Consideraciones para producción:
- Añade lógica de reintentos para solicitudes de red inestables
- Implementa limitación de velocidad para evitar el estrangulamiento de la API
- Añade registro para depurar llamadas a herramientas fallidas
- Almacena las claves API en una bóveda segura en lugar de variables de entorno
Comparte con tu equipo:
- Publica en npm como
@tu-organizacion/apidog-mcp-server - Documenta las variables de entorno requeridas
- Incluye ejemplos de configuraciones MCP para clientes comunes
Solución de problemas comunes
El servidor MCP no carga en Claude Code:
- Verifica que la ruta en
~/.claude/settings.jsonsea absoluta (no relativa) - Comprueba que
nodeesté en tu PATH:which node - Asegúrate de que existe el archivo
dist/index.jsconstruido:ls -la dist/ - Busca errores en los registros MCP de Claude Code
Las herramientas no aparecen después de la configuración:
- Reinicia Claude Code completamente (cierra y vuelve a abrir)
- Ejecuta
npm run buildpara asegurar que TypeScript esté compilado - Verifica que las tres herramientas estén definidas antes de
server.connect() - Asegúrate de que el servidor se inicia sin errores:
node dist/index.js
Las solicitudes a la API fallan con 401:
- Confirma que
APIDOG_API_KEYesté configurada - Verifica que no haya espacios adicionales o comillas alrededor del valor de la clave
- Asegúrate de que tu cuenta de Apidog tenga el acceso a la API habilitado
- Prueba la clave manualmente:
curl -H "Authorization: Bearer $APIDOG_API_KEY" https://api.apidog.com/v1/user
Errores de validación de Zod:
- Asegúrate de que los nombres de los parámetros coincidan exactamente con el esquema
- Verifica que se proporcionen los campos obligatorios (sin errores tipográficos en
projectId) - Asegúrate de que los campos opcionales usen
.optional()en el esquema - Lee el mensaje de error completo — Zod te dirá qué campo falló
Errores de compilación de TypeScript:
- Ejecuta
npm installpara asegurar que todas las dependencias estén instaladas - Verifica la versión de TypeScript:
npx tsc --version(debe ser 5.x) - Limpia y reconstruye:
rm -rf dist && npm run build - Busca inconsistencias de tipos en las respuestas de fetch (añade aserciones de tipo
as)
Probando tu servidor MCP localmente
Antes de desplegar en producción, prueba tu servidor localmente:
Pruebas manuales con stdio:
# Inicia el servidor
node dist/index.js
# En otra terminal, envía un mensaje de prueba
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js
Salida esperada:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{ "name": "run_test", "description": "...", "inputSchema": {...} },
{ "name": "validate_schema", "description": "...", "inputSchema": {...} },
{ "name": "list_environments", "description": "...", "inputSchema": {...} }
]
}
}
Prueba una llamada a una herramienta:
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_environments","arguments":{"projectId":"your-project-id"}}}' | node dist/index.js
Tus agentes de IA ahora tienen acceso directo a las capacidades de prueba de Apidog. No más copiar y pegar entre el chat y el navegador. No más ejecuciones manuales de pruebas. Escribe un comando, obtén los resultados.
Ese es el poder de MCP: extiende tus agentes de IA con herramientas específicas del dominio y déjalos hacer lo que se supone que deben hacer: ayudarte a lanzar más rápido.
Puntos clave
- Los servidores MCP conectan agentes de IA a APIs externas — Construye una vez, usa en Claude Code, Cursor y cualquier cliente compatible con MCP
- Tres herramientas cubren la mayoría de las necesidades de pruebas de API —
run_testpara ejecución,validate_schemapara validación de OpenAPI,list_environmentspara descubrimiento - La validación Zod previene parámetros incorrectos — Las definiciones de herramientas con seguridad de tipos detectan errores antes de las llamadas a la API
- La configuración es específica de la herramienta — Claude Code usa
~/.claude/settings.json, Cursor usa.cursor/mcp.json - La producción requiere manejo de errores — Añade lógica de reintentos, limitación de velocidad y almacenamiento seguro de claves antes de desplegar
Preguntas frecuentes
¿Qué es MCP en IA?MCP (Model Context Protocol) es un protocolo estandarizado que permite a los agentes de IA acceder a herramientas y fuentes de datos externas. Piensa en ello como un sistema de complementos para agentes de IA.
¿Cómo creo un servidor MCP para Apidog?Instala @modelcontextprotocol/sdk, define herramientas con validación Zod, implementa manejadores que llamen a la API de Apidog y conéctate a través de StdioServerTransport.
¿Puedo usar esto con Cursor?Sí. Añade la configuración del servidor MCP a .cursor/mcp.json en la raíz de tu proyecto. El mismo servidor funciona con Claude Code, Cursor y otros clientes MCP.
¿Qué herramientas debo exponer?Comienza con run_test para ejecutar colecciones de pruebas, validate_schema para la validación de OpenAPI y list_environments para obtener los entornos disponibles.
¿El servidor MCP de Apidog está listo para producción?El código del tutorial es un punto de partida. Añade lógica de reintentos, limitación de velocidad, manejo de errores adecuado y almacenamiento seguro de claves API antes de usarlo en producción.
¿Necesito una clave API de Apidog?Sí. Establece APIDOG_API_KEY como una variable de entorno. El servidor la lee en tiempo de ejecución para autenticar las solicitudes a la API.
¿Puedo compartir este servidor MCP con mi equipo?Sí. Publica en npm como un paquete privado, documenta las variables de entorno requeridas e incluye ejemplos de configuraciones MCP.
