RESUMO
Crie um servidor MCP com TypeScript que exponha três ferramentas: run_test, validate_schema e list_environments. Configure-o em ~/.claude/settings.json para Claude Code ou .cursor/mcp.json para Cursor. Seus agentes de IA poderão então executar testes Apidog, validar esquemas OpenAPI e buscar ambientes sem sair da interface de bate-papo. O código-fonte completo tem cerca de 150 linhas e utiliza o pacote @modelcontextprotocol/sdk.
Crie um servidor MCP que permita a Claude Code, Cursor e outros agentes de IA executar testes de API Apidog, validar esquemas e comparar respostas, tudo sem sair da interface de bate-papo.
É isso que o Model Context Protocol (MCP) permite. O MCP permite que agentes de IA acessem ferramentas externas através de uma interface padronizada. Crie um servidor MCP para Apidog, e seu agente de IA poderá executar testes, validar esquemas e buscar ambientes sem troca de contexto.
O Que É MCP?
MCP (Model Context Protocol) é um protocolo para agentes de IA acessarem ferramentas externas e fontes de dados. Pense nele como um sistema de plugins que funciona em Claude Code, Cursor e outros clientes compatíveis com MCP.
Um servidor MCP expõe ferramentas (funções que o agente pode chamar) e recursos (dados que o agente pode ler). Seu servidor MCP Apidog exporá ferramentas para teste de API.
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ AI Agent │ │ MCP Server │ │ Apidog │
│ (Claude Code) │◄───────►│ (Your Code) │◄───────►│ API │
└─────────────────┘ JSON └──────────────────┘ HTTP └─────────────┘
Passo 1: Configure o Projeto
Crie um novo projeto TypeScript:
mkdir apidog-mcp-server
cd apidog-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
Crie 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"]
}
Adicione um script de build ao package.json:
{
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
}
Passo 2: Crie o Esqueleto do Servidor MCP
Crie 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 cria um servidor MCP e o conecta ao transporte stdio. O transporte lida com a comunicação entre o agente de IA e seu servidor através da entrada/saída padrão.
Passo 3: Defina a Ferramenta run_test
Adicione a primeira ferramenta 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);
A definição da ferramenta tem três partes:
- Nome —
run_test(os agentes selecionam as ferramentas pelo nome, então torne-o descritivo) - Esquema — Validação Zod para parâmetros com descrições
- Manipulador (Handler) — Função assíncrona que chama a API Apidog
Passo 4: Adicione a Ferramenta validate_schema
Adicione validação de esquema para capturar erros OpenAPI antes da implantação:
// 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)}`
}]
};
}
}
);
Passo 5: Adicione a Ferramenta list_environments
Adicione uma ferramenta para buscar ambientes de teste disponíveis:
// 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)}`
}]
};
}
}
);
Passo 6: Construa e Teste
Construa o servidor:
npm run build
Teste com um cliente MCP simples. Crie 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");
Passo 7: Configure para Claude Code
Adicione o servidor MCP à sua configuração do Claude Code:
Crie ou edite ~/.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"
}
}
}
}
Reinicie o Claude Code. As ferramentas Apidog devem agora aparecer quando você pedir ajuda para testes de API.
Uso no Claude Code:
Use the run_test tool to run tests on my Apidog project.
Project ID: proj_12345
Environment: staging
Validate this OpenAPI schema against Apidog rules:
[paste schema]
List all environments for project proj_12345
Passo 8: Configure para Cursor
O Cursor usa uma configuração MCP semelhante. Crie .cursor/mcp.json em seu projeto:
{
"mcpServers": {
"apidog": {
"command": "node",
"args": ["/absolute/path/to/apidog-mcp-server/dist/index.js"],
"env": {
"APIDOG_API_KEY": "your-api-key-here"
}
}
}
}
Uso no Cursor:
@apidog run_test projectId="proj_12345" environmentId="staging"
Código-Fonte Completo
Aqui está o src/index.ts completo:
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);
O Que Você Construiu
| Componente | Propósito |
|---|---|
| Servidor MCP | Conecta agentes de IA à API Apidog |
run_test |
Executa coleções de teste programaticamente |
validate_schema |
Captura erros OpenAPI antes da implantação |
list_environments |
Descobre ambientes de teste disponíveis |
| Validação Zod | Manipulação de parâmetros com segurança de tipo |
| Transporte Stdio | Funciona com Claude Code, Cursor, qualquer cliente MCP |
Próximos Passos
Estenda o servidor:
- Adicione a ferramenta
compare_responsespara comparar resultados de testes entre ambientes - Adicione
get_test_historypara buscar execuções de teste históricas - Adicione
trigger_mock_serverpara iniciar/parar endpoints mock
Considerações para Produção:
- Adicione lógica de retentativa para requisições de rede instáveis
- Implemente limitação de taxa para evitar o estrangulamento da API
- Adicione logging para depurar chamadas de ferramentas falhas
- Armazene chaves de API em um cofre seguro em vez de variáveis de ambiente
Compartilhe com sua equipe:
- Publique no npm como
@your-org/apidog-mcp-server - Documente as variáveis de ambiente necessárias
- Inclua exemplos de configurações MCP para clientes comuns
Solução de Problemas Comuns
Servidor MCP não carregando no Claude Code:
- Verifique se o caminho em
~/.claude/settings.jsoné absoluto (não relativo) - Verifique se
nodeestá no seu PATH:which node - Garanta que o
dist/index.jsconstruído exista:ls -la dist/ - Procure por erros nos logs MCP do Claude Code
Ferramentas não aparecendo após a configuração:
- Reinicie o Claude Code completamente (feche e abra novamente)
- Execute
npm run buildpara garantir que o TypeScript seja compilado - Verifique se todas as três ferramentas estão definidas antes de
server.connect() - Verifique se o servidor inicia sem erros:
node dist/index.js
Requisições de API falhando com 401:
- Confirme se
APIDOG_API_KEYestá configurado - Verifique se há espaços extras ou aspas ao redor do valor da chave
- Verifique se sua conta Apidog tem acesso à API habilitado
- Teste a chave manualmente:
curl -H "Authorization: Bearer $APIDOG_API_KEY" https://api.apidog.com/v1/user
Erros de validação Zod:
- Garanta que os nomes dos parâmetros correspondam exatamente ao esquema
- Verifique se os campos obrigatórios são fornecidos (sem erros de digitação em
projectId) - Verifique se os campos opcionais usam
.optional()no esquema - Leia a mensagem de erro completa — o Zod informa qual campo falhou
Erros de compilação TypeScript:
- Execute
npm installpara garantir que todas as dependências estejam instaladas - Verifique a versão do TypeScript:
npx tsc --version(deve ser 5.x) - Limpe e reconstrua:
rm -rf dist && npm run build - Procure por incompatibilidades de tipo nas respostas de fetch (adicione asserções de tipo
as)
Testando Seu Servidor MCP Localmente
Antes de implantar em produção, teste seu servidor localmente:
Teste manual com stdio:
# Inicie o servidor
node dist/index.js
# Em outro terminal, envie uma mensagem de teste
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js
Saída esperada:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{ "name": "run_test", "description": "...", "inputSchema": {...} },
{ "name": "validate_schema", "description": "...", "inputSchema": {...} },
{ "name": "list_environments", "description": "...", "inputSchema": {...} }
]
}
}
Teste uma chamada de ferramenta:
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_environments","arguments":{"projectId":"your-project-id"}}}' | node dist/index.js
Seus agentes de IA agora têm acesso direto às capacidades de teste do Apidog. Chega de copiar e colar entre o chat e o navegador. Chega de execuções de teste manuais. Digite um comando, receba os resultados.
Esse é o poder do MCP: estenda seus agentes de IA com ferramentas específicas do domínio e deixe-os fazer o que devem fazer — ajudá-lo a entregar mais rapidamente.
Principais Conclusões
- Servidores MCP conectam agentes de IA a APIs externas — Construa uma vez, use em Claude Code, Cursor e qualquer cliente compatível com MCP
- Três ferramentas cobrem a maioria das necessidades de teste de API —
run_testpara execução,validate_schemapara validação OpenAPI,list_environmentspara descoberta - A validação Zod previne parâmetros inválidos — Definições de ferramentas com segurança de tipo capturam erros antes das chamadas de API
- A configuração é específica da ferramenta — Claude Code usa
~/.claude/settings.json, Cursor usa.cursor/mcp.json - A produção exige tratamento de erros — Adicione lógica de retentativa, limitação de taxa e armazenamento seguro de chaves antes de implantar
Perguntas Frequentes
O que é MCP em IA?MCP (Model Context Protocol) é um protocolo padronizado que permite que agentes de IA acessem ferramentas externas e fontes de dados. Pense nele como um sistema de plugins para agentes de IA.
Como crio um servidor MCP para Apidog?Instale @modelcontextprotocol/sdk, defina ferramentas com validação Zod, implemente manipuladores que chamem a API Apidog e conecte-se via StdioServerTransport.
Posso usar isso com o Cursor?Sim. Adicione a configuração do servidor MCP a .cursor/mcp.json na raiz do seu projeto. O mesmo servidor funciona com Claude Code, Cursor e outros clientes MCP.
Quais ferramentas devo expor?Comece com run_test para executar coleções de teste, validate_schema para validação OpenAPI e list_environments para buscar ambientes disponíveis.
O servidor MCP Apidog está pronto para produção?O código do tutorial é um ponto de partida. Adicione lógica de retentativa, limitação de taxa, tratamento de erros adequado e armazenamento seguro de chaves de API antes de usar em produção.
Preciso de uma chave de API Apidog?Sim. Defina APIDOG_API_KEY como uma variável de ambiente. O servidor lê isso em tempo de execução para autenticar requisições de API.
Posso compartilhar este servidor MCP com minha equipe?Sim. Publique no npm como um pacote privado, documente as variáveis de ambiente necessárias e inclua exemplos de configurações MCP.
