DEV Community

Cover image for MCP Server erstellen: KI Agenten mit API Testing Fähigkeiten ausstatten
Emre Demir
Emre Demir

Posted on • Originally published at apidog.com

MCP Server erstellen: KI Agenten mit API Testing Fähigkeiten ausstatten

TL;DR

Erstellen Sie einen MCP-Server mit TypeScript, der drei Tools bereitstellt: run_test, validate_schema und list_environments. Konfigurieren Sie ihn in ~/.claude/settings.json für Claude Code oder .cursor/mcp.json für Cursor. Damit können KI-Agenten Apidog-Tests ausführen, OpenAPI-Schemas validieren und Umgebungen abrufen – alles direkt aus der Chat-Oberfläche. Der vollständige Quellcode umfasst etwa 150 Zeilen und verwendet das Paket @modelcontextprotocol/sdk.

Teste Apidog noch heute

Erstellen Sie einen MCP-Server, mit dem Claude Code, Cursor und andere KI-Agenten Apidog-API-Tests ausführen, Schemas validieren und Antworten vergleichen können – direkt im Chat-Workflow.

💡 Szenario: Ihr KI-Agent hat einen API-Endpunkt geschrieben. Statt Code zu kopieren, Apidog manuell zu öffnen und Tests einzurichten, rufen Sie einfach ein Tool auf und erhalten sofort die Ergebnisse.

Das ermöglicht das Model Context Protocol (MCP). MCP bietet KI-Agenten eine standardisierte Schnittstelle zu externen Tools. Mit dem Apidog-MCP-Server können Ihre Agenten API-Tests durchführen, Schemas validieren und Umgebungen abfragen – ohne Kontextwechsel.

Was ist MCP?

MCP (Model Context Protocol) ist ein Protokoll, das KI-Agenten Zugriff auf externe Tools und Datenquellen gibt. Es funktioniert wie ein Plugin-System, das in Claude Code, Cursor und anderen MCP-kompatiblen Clients einsetzbar ist.

Ein MCP-Server stellt Tools (Funktionen, die der Agent aufrufen kann) und Ressourcen (Daten, die der Agent lesen kann) bereit. Ihr Apidog-MCP-Server liefert Tools für API-Tests.

┌─────────────────┐         ┌──────────────────┐         ┌─────────────┐
│  KI-Agent       │         │  MCP-Server      │         │  Apidog     │
│  (Claude Code)  │◄───────►│  (Ihr Code)      │◄───────►│  API        │
└─────────────────┘   JSON  └──────────────────┘  HTTP   └─────────────┘
Enter fullscreen mode Exit fullscreen mode

Schritt 1: Projekt einrichten

Erstellen Sie ein neues TypeScript-Projekt:

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

Legen Sie die tsconfig.json an:

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

Ergänzen Sie das Build-Skript in Ihrer package.json:

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}
Enter fullscreen mode Exit fullscreen mode

Schritt 2: MCP-Server-Gerüst erstellen

Erstellen Sie die Datei 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-Test-Tools für KI-Agenten"
});

// Tools werden hier definiert

const transport = new StdioServerTransport();
await server.connect(transport);
Enter fullscreen mode Exit fullscreen mode

Dieses Gerüst initialisiert den MCP-Server und verbindet ihn über Stdio – so kommunizieren Agent und Server via Standard-I/O.

Schritt 3: Tool run_test definieren

Fügen Sie in src/index.ts das erste Tool hinzu:

// Tool: run_test
server.tool(
  "run_test",
  {
    projectId: z.string().describe("Apidog Projekt-ID (zu finden in der Projekt-URL)"),
    environmentId: z.string().optional().describe("Optionale Umgebungs-ID für die Testausführung"),
    testSuiteId: z.string().optional().describe("Optionale Testsuiten-ID zur Ausführung einer spezifischen Suite")
  },
  async ({ projectId, environmentId, testSuiteId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Fehler: Umgebungsvariable APIDOG_API_KEY ist nicht gesetzt"
        }]
      };
    }

    // API-URL zusammenbauen
    let url = `https://api.apidog.com/v1/projects/${projectId}/tests/run?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation`;
    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-Fehler: ${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: `Anfrage fehlgeschlagen: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);
Enter fullscreen mode Exit fullscreen mode

Tool-Aufbau:

  1. Name (run_test)
  2. Parameter-Schema (mit Zod)
  3. Handler-Funktion, die die Apidog-API aufruft

Schritt 4: Tool validate_schema hinzufügen

Fügen Sie die Schema-Validierung hinzu:

// Tool: validate_schema
server.tool(
  "validate_schema",
  {
    schema: z.object({}).describe("OpenAPI 3.x Schema-Objekt zur Validierung"),
    strict: z.boolean().optional().default(false).describe("Strengen Modus für zusätzliche Prüfungen aktivieren")
  },
  async ({ schema, strict }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Fehler: Umgebungsvariable APIDOG_API_KEY ist nicht gesetzt"
        }]
      };
    }

    try {
      const response = await fetch("https://api.apidog.com/v1/schemas/validate?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation", {
        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: `Validierung fehlgeschlagen: ${JSON.stringify(result.errors, null, 2)}`
          }]
        };
      }

      return {
        content: [{
          type: "text",
          text: result.valid
            ? "Schema ist gültiges OpenAPI 3.x"
            : `Warnungen: ${JSON.stringify(result.warnings, null, 2)}`
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `Validierung fehlgeschlagen: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);
Enter fullscreen mode Exit fullscreen mode

Schritt 5: Tool list_environments hinzufügen

Fügen Sie ein Tool hinzu, um Umgebungen abzurufen:

// Tool: list_environments
server.tool(
  "list_environments",
  {
    projectId: z.string().describe("Apidog Projekt-ID")
  },
  async ({ projectId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Fehler: Umgebungsvariable APIDOG_API_KEY ist nicht gesetzt"
        }]
      };
    }

    try {
      const response = await fetch(
        `https://api.apidog.com/v1/projects/${projectId}/environments?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation`,
        {
          headers: {
            "Authorization": `Bearer ${apiKey}`
          }
        }
      );

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

      const environments = await response.json();
      return {
        content: [{
          type: "text",
          text: environments.length === 0
            ? "Keine Umgebungen für dieses Projekt gefunden"
            : environments.map((e: any) =>
                `- ${e.name} (ID: ${e.id})${e.isDefault ? " [Standard]" : ""}`
              ).join("\n")
        }]
      };
    } catch (error) {
      return {
        content: [{
          type: "text",
          text: `Anfrage fehlgeschlagen: ${error instanceof Error ? error.message : String(error)}`
        }]
      };
    }
  }
);
Enter fullscreen mode Exit fullscreen mode

Schritt 6: Build und Test

Server bauen:

npm run build
Enter fullscreen mode Exit fullscreen mode

Minimaler Test-Client (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-Ausgabe: ${data}`);
});

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

// Sende Testnachricht
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");
Enter fullscreen mode Exit fullscreen mode

Schritt 7: Für Claude Code konfigurieren

Bearbeiten oder erstellen Sie ~/.claude/settings.json:

{
  "mcpServers": {
    "apidog": {
      "command": "node",
      "args": ["/absoluter/pfad/zu/apidog-mcp-server/dist/index.js"],
      "env": {
        "APIDOG_API_KEY": "Ihr-API-Schlüssel-hier"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Starten Sie Claude Code neu. Die Apidog-Tools sollten verfügbar sein.

Beispiel-Nutzung:

Verwenden Sie das run_test-Tool, um Tests in meinem Apidog-Projekt auszuführen.
Projekt-ID: proj_12345
Umgebung: staging
Enter fullscreen mode Exit fullscreen mode
Validieren Sie dieses OpenAPI-Schema anhand der Apidog-Regeln:
[Schema hier einfügen]
Enter fullscreen mode Exit fullscreen mode
Listen Sie alle Umgebungen für das Projekt proj_12345 auf
Enter fullscreen mode Exit fullscreen mode

Schritt 8: Für Cursor konfigurieren

Erstellen Sie .cursor/mcp.json im Projektverzeichnis:

{
  "mcpServers": {
    "apidog": {
      "command": "node",
      "args": ["/absoluter/pfad/zu/apidog-mcp-server/dist/index.js"],
      "env": {
        "APIDOG_API_KEY": "Ihr-API-Schlüssel-hier"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Beispiel-Nutzung in Cursor:

@apidog run_test projectId="proj_12345" environmentId="staging"
Enter fullscreen mode Exit fullscreen mode

Vollständiger Quellcode

Hier die komplette 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-Test-Tools für KI-Agenten"
});

// Tool: run_test
server.tool(
  "run_test",
  {
    projectId: z.string().describe("Apidog Projekt-ID"),
    environmentId: z.string().optional().describe("Umgebungs-ID"),
    testSuiteId: z.string().optional().describe("Testsuiten-ID")
  },
  async ({ projectId, environmentId, testSuiteId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Fehler: APIDOG_API_KEY ist nicht gesetzt"
        }]
      };
    }

    let url = `https://api.apidog.com/v1/projects/${projectId}/tests/run?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation`;
    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: `Anfrage fehlgeschlagen: ${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: "Fehler: APIDOG_API_KEY ist nicht gesetzt"
        }]
      };
    }

    const response = await fetch("https://api.apidog.com/v1/schemas/validate?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation", {
      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 ist gültig"
          : `Probleme: ${JSON.stringify(result.errors || result.warnings, null, 2)}`
      }]
    };
  }
);

// Tool: list_environments
server.tool(
  "list_environments",
  {
    projectId: z.string().describe("Apidog Projekt-ID")
  },
  async ({ projectId }) => {
    const apiKey = process.env.APIDOG_API_KEY;
    if (!apiKey) {
      return {
        content: [{
          type: "text",
          text: "Fehler: APIDOG_API_KEY ist nicht gesetzt"
        }]
      };
    }

    const response = await fetch(
      `https://api.apidog.com/v1/projects/${projectId}/environments?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation`,
      {
        headers: { "Authorization": `Bearer ${apiKey}` }
      }
    );

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

const transport = new StdioServerTransport();
await server.connect(transport);
Enter fullscreen mode Exit fullscreen mode

Was Sie erstellt haben

Komponente Zweck
MCP-Server Verbindet KI-Agenten mit der Apidog-API
run_test Testsammlungen programmatisch ausführen
validate_schema OpenAPI-Fehler vor der Bereitstellung abfangen
list_environments Verfügbare Testumgebungen entdecken
Zod-Validierung Typsichere Parameterbehandlung
Stdio-Transport Funktioniert mit Claude Code, Cursor, jedem MCP-Client

Nächste Schritte

Erweitern Sie den Server:

  • Fügen Sie das compare_responses-Tool hinzu, um Testergebnisse zwischen Umgebungen zu vergleichen.
  • Implementieren Sie get_test_history für die Historie von Testläufen.
  • Erstellen Sie trigger_mock_server, um Mock-Endpunkte zu verwalten.

Produktionsreife erhöhen:

  • Wiederholungslogik für Netzwerkfehler implementieren.
  • Ratenbegrenzung gegen API-Throttling einbauen.
  • Logging für Fehlerdiagnose ergänzen.
  • API-Schlüssel in einem sicheren Tresor speichern.

Teilen im Team:

  • Veröffentlichen Sie das Paket (z.B. als @your-org/apidog-mcp-server).
  • Dokumentieren Sie Umgebungsvariablen & Beispielkonfigurationen für verschiedene Clients.

Behebung häufiger Probleme

MCP-Server lädt nicht in Claude Code:

  • Absoluter Pfad in ~/.claude/settings.json verwenden.
  • Prüfen, ob node im PATH ist: which node
  • Sicherstellen, dass dist/index.js nach Build existiert.
  • Fehler in MCP-Logs von Claude Code prüfen.

Tools erscheinen nicht:

  • Claude Code komplett neu starten.
  • Mit npm run build sicherstellen, dass alles kompiliert ist.
  • Tools müssen vor server.connect() definiert sein.
  • Server direkt starten: node dist/index.js zur Fehlersuche.

API-Anfragen schlagen mit 401 fehl:

  • Ist APIDOG_API_KEY gesetzt?
  • Keine Anführungszeichen/Whitespace im Schlüsselwert.
  • Apidog-Konto für API-Zugriff freigeschaltet?
  • Schlüssel manuell testen: curl -H "Authorization: Bearer $APIDOG_API_KEY" https://api.apidog.com/v1/user?utm_source=dev.to&utm_medium=wanda&utm_content=n8n-post-automation

Zod-Validierungsfehler:

  • Parameternamen exakt wie im Schema.
  • Pflichtfelder nicht vergessen (Tippfehler bei projectId vermeiden).
  • Optionales Feld? .optional() im Zod-Schema verwenden.
  • Die vollständige Fehlermeldung lesen – Zod gibt Details.

TypeScript-Kompilierungsfehler:

  • Mit npm install sicherstellen, dass alles installiert ist.
  • TypeScript-Version kontrollieren (npx tsc --version, sollte 5.x sein).
  • Build-Ordner löschen und neu bauen: rm -rf dist && npm run build
  • Bei Problemen mit Typen ggf. as-Zuweisungen ergänzen.

Lokales Testen Ihres MCP-Servers

Manuelles Testen per Stdio:

# Server starten
node dist/index.js

# In anderem Terminal, Tools auflisten
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js
Enter fullscreen mode Exit fullscreen mode

Erwartete Ausgabe:

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

Tool-Aufruf testen:

echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_environments","arguments":{"projectId":"Ihre-Projekt-ID"}}}' | node dist/index.js
Enter fullscreen mode Exit fullscreen mode

Ihre KI-Agenten können nun direkt Apidog-Tests und Validierungen ausführen – ohne Kontextwechsel, ohne manuelles Kopieren.

Das ist die Stärke von MCP: Erweitern Sie Ihre KI-Agenten mit domänenspezifischen Tools und automatisieren Sie Tests und Validierung nahtlos.

Wichtige Erkenntnisse

  • MCP-Server verbinden KI-Agenten mit externen APIs – Einmal aufsetzen, in Claude Code, Cursor und weiteren Clients verwenden.
  • Drei Tools decken die meisten API-Testanforderungen abrun_test, validate_schema, list_environments.
  • Zod-Validation verhindert fehlerhafte Parameter – Typsicherheit direkt im Tooling.
  • Werkzeugspezifische Konfiguration – Claude Code nutzt ~/.claude/settings.json, Cursor nutzt .cursor/mcp.json.
  • Für Produktion Fehlerbehandlung und Sicherheit beachten – Wiederholungslogik, Ratenbegrenzung, sichere Schlüsselablage.

Häufig gestellte Fragen (FAQ)

Was ist MCP in der KI?

MCP (Model Context Protocol) ist ein standardisiertes Protokoll, das KI-Agenten Zugriff auf externe Tools und Datenquellen gibt – vergleichbar mit einem Plug-in-System.

Wie erstelle ich einen MCP-Server für Apidog?

Installieren Sie @modelcontextprotocol/sdk, definieren Sie Tools mit Zod, implementieren Sie die Handler für Apidog-API-Aufrufe und verbinden Sie über StdioServerTransport.

Kann ich dies mit Cursor nutzen?

Ja – einfach die MCP-Server-Konfiguration in .cursor/mcp.json hinterlegen. Der Server funktioniert mit Claude Code, Cursor und anderen MCP-Clients.

Welche Tools sollte ich bereitstellen?

Starten Sie mit run_test (Testausführung), validate_schema (OpenAPI-Validierung) und list_environments (Umgebungen abrufen).

Ist der Apidog MCP-Server produktionsreif?

Der Code ist ein Ausgangspunkt. Ergänzen Sie Wiederholungslogik, Ratenbegrenzung, Fehlerbehandlung und sichere Schlüsselablage vor dem Produktionseinsatz.

Brauche ich einen Apidog API-Schlüssel?

Ja. Hinterlegen Sie APIDOG_API_KEY als Umgebungsvariable – der Server nutzt diesen zur Authentifizierung.

Kann ich diesen MCP-Server mit meinem Team teilen?

Ja. Veröffentlichen Sie ihn etwa als privates npm-Paket, dokumentieren Sie die Umgebungsvariablen und liefern Sie Beispiel-Konfigurationen für MCP-Clients mit.

Top comments (0)