Przejdź do głównej zawartości

Tworzenie serwera MCP

Tworzenie serwera MCP w projekcie Speedwave polega na implementacji wyizolowanej usługi (workera) wystawiającej możliwości danej platformy (np. GitLab, Slack lub system operacyjny) w postaci narzędzi protokołu Model Context Protocol (MCP). Claude komunikuje się wyłącznie z centralnym węzłem Tool Gateway, który przekazuje wywołania JSON-RPC przez wewnętrzny mostek sieciowy Dockera (http://mcp-{nazwa}:{port}) do wskazanego kontenera.

Pakiet mcp-servers/gitlab stanowi kanoniczną implementację referencyjną.

Wszystkie serwery MCP muszą importować bibliotekę @speedwave/mcp-shared, zamiast powielać logikę obsługi protokołu HTTP:

  • bootWorker: Zestandaryzowany cykl życia i inicjalizacji serwera.
  • Tool: Definicja interfejsu TypeScript ze schematami JSON Schema.
  • withClientValidation / withResultValidation: Strażnicy wykonania dla stanu braku konfiguracji lub błędów API.
  • sanitize: Narzędzie do usuwania danych wrażliwych ze strumieni logów.

Punkt wejściowy serwera definiujemy za pomocą funkcji bootWorker():

mcp-servers/gitlab/src/index.ts
import { bootWorker, ts, makeStandardHealthCheck } from '@speedwave/mcp-shared';
import { initializeGitLabClient, type GitLabClient } from './client.js';
import { createToolDefinitions } from './tools/index.js';
bootWorker<GitLabClient>({
serverName: 'mcp-gitlab',
version: '1.0.0',
displayName: 'GitLab',
authTokenEnv: 'MCP_GITLAB_AUTH_TOKEN',
host: '0.0.0.0',
initClient: initializeGitLabClient,
makeTools: (client) => createToolDefinitions(client),
makeHealthCheck: (client) => makeStandardHealthCheck(client),
}).catch((error) => {
console.error(`${ts()} Błąd inicjalizacji workera:`, error);
process.exit(1);
});

Funkcja bootWorker automatycznie zarządza przydziałem portu PORT, walidacją tokenów autoryzacyjnych oraz ponawianiem prób połączenia.

Kontener workera montuje wyłącznie własne tokeny w katalogu /tokens/ w trybie tylko do odczytu (zobacz Zarządzanie danymi uwierzytelniającymi):

  • Folder/tokens/
    • token Token dostępu API
    • host_url Opcjonalny adres własnej instancji

W przypadku braku plików lub błędnych poświadczeń klient powinien przyjąć wartość null. Narzędzia zwrócą czytelny komunikat o braku konfiguracji bez powodowania awarii kontenera.

Narzędzia deklarujemy jako obiekty zgodne z interfejsem Tool:

mcp-servers/gitlab/src/tools/branch-tools.ts
import { Tool, READ_ONLY_ANNOTATIONS } from '@speedwave/mcp-shared';
export const listBranchesTool: Tool = {
name: 'listBranches',
description: 'Lista gałęzi w projekcie',
annotations: READ_ONLY_ANNOTATIONS,
_meta: { deferLoading: true },
keywords: ['gitlab', 'branches', 'list', 'git', 'refs'],
example: 'const branches = await gitlab.listBranches({ project_id: "speedwave/core" })',
inputSchema: {
type: 'object',
properties: {
project_id: { type: ['string', 'number'], description: 'ID lub ścieżka projektu' },
search: { type: 'string', description: 'Wyszukiwanie po nazwie gałęzi' },
limit: { type: 'number', description: 'Maksymalna liczba wyników (domyślnie 20)' },
},
required: ['project_id'],
},
};

Adnotacje narzędzia określają poziom bezpieczeństwa operacji:

Stała adnotacjireadOnlyHintdestructiveHintPrzeznaczenie
READ_ONLY_ANNOTATIONStruefalseOdczyt danych (listBranches, getIssue).
WRITE_ANNOTATIONSfalsefalseTworzenie i modyfikacja zasobów (createBranch).
DESTRUCTIVE_ANNOTATIONSfalsetrueNieodwracalne operacje usuwania (deleteBranch).

Narzędzia łączymy z ich implementacjami w fabrykach modułów (createBranchTools(client)):

  • Używaj withClientValidation, gdy funkcje rzucają wyjątki API.
  • Używaj withResultValidation, gdy funkcje zwracają ustrukturyzowane obiekty { success, data, error }.
  • Filtruj komunikaty diagnostyczne funkcją sanitize(dane), zapobiegając wyciekom tokenów do logów.

Testy narzędzi realizujemy w środowisku Vitest poprzez wywołanie fabryk narzędzi z zamockowanym klientem API:

  • Walidacja poprawności metadanych (nazwy, opisy, adnotacje, schematy).
  • Testy ścieżki poprawnej z zamockowanymi odpowiedziami klienta.
  • Weryfikacja odrzucania błędnych lub brakujących parametrów.
  • Testy propagacji błędów i obsługi niezainicjalizowanego klienta.

Uruchamiaj testy poleceniem make test-mcp i sprawdzaj wskaźniki pokrycia za pomocą make coverage-mcp.