Zurück zum Journal
6 Min. Lesezeit

Standardisierung von KI-Integrationen mit dem Model Context Protocol (MCP)

Ein praktischer Leitfaden zur Entwicklung und Absicherung benutzerdefinierter MCP-Server, um Unternehmensdaten sicher für KI-Entwickler-Agenten freizugeben.

AI AgentsMCPNode.jsEnterprise ArchitectureAPI Security
Standardisierung von KI-Integrationen mit dem Model Context Protocol (MCP)

Die Anbindung großer Sprachmodelle (LLMs) an interne Datenquellen und Systeme war in der Vergangenheit eine fragmentierte Ad-hoc-Angelegenheit. Jedes KI-Entwicklungsprojekt beginnt meist mit dem Schreiben benutzerdefinierter API-Wrapper, dem Zuordnen von JSON-Schemas oder dem Schreiben proprietärer Integrationslogik innerhalb der Orchestrator-Laufzeiten zur Steuerung von Tool-Aufrufen.

Wenn Sie von OpenAI zu Anthropic wechseln oder Ihre Entwickler von einer KI-gestützten IDE zu einer anderen migrieren, müssen Sie oft die gesamte Integrationsschicht neu schreiben.

Diese Reibung ist der Grund, warum das Model Context Protocol (MCP), ein von Anthropic initiierter offener Standard, schnell an Bedeutung gewonnen hat. Ähnlich wie das Language Server Protocol (LSP) die Kommunikation zwischen Compilern und Code-Editoren standardisiert hat, vereinheitlicht MCP die Art und Weise, wie KI-Modelle mit Datenquellen und Entwickler-Tools interagieren.

Hier ist ein praktischer Leitfaden für den Aufbau, die Strukturierung und die Absicherung eines benutzerdefinierten MCP-Servers, um Ihre Unternehmensdaten sicher für Ihre Entwickler-Agenten freizugeben.


Die Architektur: Entkopplung von Clients und Servern

Das zentrale Designprinzip von MCP ist die Entkopplung. Anstatt API-Integrationen direkt in einer Agenten-Laufzeit fest zu verdrahten, führt MCP eine Client-Server-Architektur ein:

[ AI Agent / IDE ] (MCP Client)
       │
       │ (JSON-RPC 2.0 over Stdio or SSE)
       ▼
[ Custom MCP Server ]
       │
       ├─► Secure Database (PostgreSQL / BigQuery)
       ├─► Internal Microservices
       └─► Local Development Tools
  • MCP-Client: Der Koordinator (z. B. Cursor, Windsurf oder ein benutzerdefinierter LangChain-Orchestrator). Er verwaltet das logische Denken des LLMs, hält den Benutzerkontext und initiiert Tool-Anfragen.
  • MCP-Server: Ein leichtgewichtiger Prozess oder Dienst, der drei Kernprimitive bereitstellt:
    1. Prompts: Wiederverwendbare Vorlagen zur Steuerung von Modellinteraktionen.
    2. Resources: Nur-Lese-Datenquellen (Dateiinhalte, Datenbankzeilen, API-Antworten).
    3. Tools: Ausführbare Funktionen, die Operationen durchführen oder externe APIs aufrufen können.

Erstellung eines benutzerdefinierten MCP-Servers in TypeScript

Lassen Sie uns einen produktionsbereiten Node.js-MCP-Server mit dem offiziellen TypeScript-SDK aufbauen. Dieser Server wird ein sicheres Tool zur Suche in internen Datenbankeinträgen (z. B. Kandidaten oder Fallstudien) mit integrierter Argumentprüfung zur Laufzeit bereitstellen.

1. Projekt-Initialisierung

Richten Sie zunächst ein TypeScript-Projekt ein und installieren Sie die erforderlichen Abhängigkeiten:

npm init -y
npm install @modelcontextprotocol/sdk zod
npm install --save-dev typescript @types/node
npx tsc --init

2. Implementierung des Servers

Nachfolgend finden Sie den Code für einen sicheren, stdio-basierten MCP-Server. Wir registrieren ein Suchwerkzeug und verwenden zod, um eine strikte Schemaüberprüfung für eingehende Payloads zu erzwingen:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";

// 1. Initialize the MCP Server
const server = new Server(
  {
    name: "enterprise-search-service",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {}, // Advertise tool capabilities to the client
    },
  }
);

// 2. Define the Search Schema using Zod
const CandidateSearchSchema = z.object({
  query: z.string().min(2),
  limit: z.number().optional().default(5),
  department: z.enum(["Engineering", "Design", "Product", "Sales"]).optional(),
});

// 3. Register Available Tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "search_candidates",
        description: "Search internal database for candidates matching specific skills and departments.",
        inputSchema: {
          type: "object",
          properties: {
            query: { type: "string", description: "Search term or required skill" },
            limit: { type: "number", description: "Maximum records to return" },
            department: { type: "string", enum: ["Engineering", "Design", "Product", "Sales"] },
          },
          required: ["query"],
        },
      },
    ],
  };
});

// Mock database resolver
async function queryDatabase(query: string, limit: number, dept?: string) {
  // Real implementation would connect to Cloud SQL / BigQuery
  return [
    { id: 101, name: "Sarah Connor", role: "Staff Platform Engineer", tags: ["Kubernetes", "Go", "MACH"] },
    { id: 102, name: "Marcus Wright", role: "Solutions Architect", tags: ["Next.js", "React", "AI Agents"] }
  ];
}

// 4. Handle Tool Executions
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name !== "search_candidates") {
    throw new Error(`Tool ${request.params.name} not found`);
  }

  try {
    // Validate the arguments at runtime
    const args = CandidateSearchSchema.parse(request.params.arguments);

    // Fetch secure records
    const results = await queryDatabase(args.query, args.limit, args.department);

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(results, null, 2),
        },
      ],
    };
  } catch (error: any) {
    return {
      content: [
        {
          type: "text",
          text: `Error validating arguments: ${error.message}`,
        },
      ],
      isError: true,
    };
  }
});

// 5. Start Server Transport (stdio is standard for local IDE integrations)
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Enterprise Search MCP Server running on stdio");

Erhöhung der Sicherheit für den Unternehmenseinsatz

Während die Implementierung des TypeScript-Codes unkompliziert ist, erfordert die Freigabe interner Produktionsdaten für LLMs strenge Sicherheitsvorkehrungen. KI-Modelle sind anfällig für Halluzinationen, Prompt-Injections und unbeabsichtigte Tool-Ausführungsschleifen.

Hier sind die vier Säulen der MCP-Sicherheit im Unternehmen:

1. Schemaüberprüfung und Eingabebereinigung

Vertrauen Sie niemals Argumenten, die von einem LLM generiert wurden. Validieren Sie Parameter immer mit Bibliotheken wie Zod, und bereinigen Sie Strings, um Risiken für die Datenbank auszuschließen:

  • Verwenden Sie parametrisierte Abfragen oder ORMs, um SQL-Injection zu verhindern.
  • Validieren Sie Verzeichnispfade, um Directory-Traversal-Exploits zu verhindern, wenn Ihr Tool lokale Dateien liest.

2. Authentifizierung und OAuth-Kontextweiterleitung

Bei der Ausführung in einem Unternehmensnetzwerk müssen Sie die Autorisierungsstufe des Benutzers überprüfen, der den Agenten steuert.

  • Stellen Sie MCP über Server-Sent Events (SSE) anstelle von stdio bereit. Dadurch kann der MCP-Server als unabhängiger Microservice hinter einem API-Gateway ausgeführt werden.
  • Leiten Sie das Identitätstoken (JWT) des Benutzers in den Anfrage-Headern weiter, sodass Ihr MCP-Server Row-Level Security (RLS) in der Zieldatenbank durchsetzen kann.

3. Human-in-the-Loop (HITL) Freigabeprozesse

Die Freigabe von Lesewerkzeugen (wie search_candidates) ist risikoarm. Das Bereitstellen von Schreibwerkzeugen (wie update_records oder deploy_service) ist jedoch gefährlich.

  • Implementieren Sie explizite Genehmigungen für Schreibaktionen. Der MCP-Client sollte Schreibanfragen abfangen und dem Entwickler ein Diff mit den Änderungen anzeigen, die der Agent festschreiben möchte.
[ Agent Tool Request ] ──► [ Security Middleware ] ──► (Diff Check / UI Popup)
                                                             │
                  ┌──────────────────────────────────────────┘
                  ▼
         [ User Approves? ] ──(Yes)──► [ Execute Write on Server ]

4. Ratenbegrenzung und Guardrails

Agenten können in rekursive Denkschleifen geraten, in denen sie ein Tool innerhalb weniger Sekunden Dutzende Male aufrufen. Dies führt zu einer enormen Belastung der Datenbank oder zu hohen Token-Kosten.

  • Erzwingen Sie Ratenbegrenzungen (Rate Limiting) pro Sitzung.
  • Begrenzen Sie die maximale Größe der Ergebnisdaten, um einen Token-Überlauf zu verhindern.

Ausblick: Legacy-Systeme als KI-Primitive bereitstellen

Die Stärke des Model Context Protocols liegt darin, dass es ältere Softwareschnittstellen in klare, auffindbare Fähigkeiten umwandelt.

Durch die Kapselung interner Datenbanken, Bereitstellungsskripte und APIs in einer standardisierten MCP-Schicht stellen Sie sicher, dass jedes KI-Werkzeug – sei es ein Editor wie Cursor, ein Terminal-Assistent oder ein autonomer Bereitstellungsagent – sicher, vorhersehbar und ohne zusätzlichen Übersetzungsaufwand mit Ihrer Geschäftslogik interagieren kann.

Share this article