Zum Inhalt springen

Schema erstellen

Docs > Guides

Diese Anleitung fuehrt dich durch die Erstellung von FlowMCP v4.1.0 Schemas. Ein Schema ist eine .mjs-Datei, die beschreibt, wie man mit einer REST-API interagiert — welche Endpunkte existieren, welche Parameter sie akzeptieren und wie Antworten transformiert werden sollen.

Bevor du ein Schema erstellst, brauchst du:

  • Die API-Dokumentation des Services, den du wrappen moechtest
  • Einen API-Schluessel, falls der Service Authentifizierung erfordert
  • Node.js 18+ installiert
  • FlowMCP CLI installiert:

Install via GitHub:

npm install -g github:FlowMCP/flowmcp-cli

FlowMCP packages are not published to NPM. They are installed directly from GitHub.

  1. Namespace waehlen und Endpunkte identifizieren

    Waehle einen eindeutigen Namespace fuer dein Schema und liste die API-Endpunkte auf, die du bereitstellen moechtest.

    Der Namespace wird Teil des Tool-Namens: namespace_toolName. Halte ihn kurz und wiedererkennbar (z.B. coingecko, etherscan, defillama).

    // Namespace: "myapi"
    // Zu wrappende Endpunkte:
    // GET /api/v1/status -> ping
    // GET /api/v1/data/:id -> getData
  2. Den main-Export erstellen

    Jedes Schema exportiert ein main-Objekt mit der API-Definition:

    export const main = {
    namespace: 'myapi',
    name: 'MyAPI',
    description: 'Access data from MyAPI service',
    version: '4.1.0',
    docs: [ 'https://docs.myapi.com' ],
    tags: [ 'data', 'utility' ],
    root: 'https://api.myapi.com/v1',
    requiredServerParams: [ 'MYAPI_KEY' ],
    requiredLibraries: [],
    headers: {},
    tools: {
    ping: {
    method: 'GET',
    path: '/status',
    description: 'Check if MyAPI is online',
    parameters: [],
    output: {
    mimeType: 'application/json',
    schema: {
    type: 'object',
    properties: {
    status: { type: 'string', description: 'Server status' }
    }
    }
    }
    },
    getData: {
    method: 'GET',
    path: '/data/{{id}}',
    description: 'Get data record by ID',
    parameters: [
    {
    position: { key: 'id', value: '{{USER_PARAM}}', location: 'insert' },
    z: { primitive: 'string()', options: [ 'min(1)' ] }
    },
    {
    position: { key: 'apikey', value: '{{SERVER_PARAM:MYAPI_KEY}}', location: 'query' },
    z: { primitive: 'string()', options: [] }
    }
    ],
    output: {
    mimeType: 'application/json',
    schema: {
    type: 'object',
    properties: {
    id: { type: 'string' },
    value: { type: 'number' }
    }
    }
    }
    }
    }
    }
  3. Output-Schemas hinzufuegen

    Jedes Tool kann seine Antwortstruktur im output-Feld deklarieren. Das teilt KI-Clients mit, was sie erwarten koennen:

    output: {
    mimeType: 'application/json',
    schema: {
    type: 'object',
    properties: {
    name: { type: 'string', description: 'Protocol name' },
    tvl: { type: 'number', description: 'Total value locked in USD' }
    }
    }
    }
  4. Handler hinzufuegen (optional)

    Wenn die rohe API-Antwort transformiert werden muss, fuege einen handlers-Export hinzu. Dies ist eine Factory-Funktion, die Shared Lists und Libraries erhaelt:

    export const handlers = ( { sharedLists, libraries } ) => ( {
    getData: {
    postRequest: async ( { response } ) => {
    const { id, rawValue, metadata } = response
    const simplified = {
    id,
    value: rawValue / 100,
    source: metadata.provider
    }
    return { response: simplified }
    }
    }
    } )

    Handler unterstuetzen zwei Hooks pro Tool:

    • preRequest — Request vor dem Senden modifizieren
    • postRequest — Antwort transformieren, bevor sie den KI-Client erreicht
  5. Mit CLI validieren

    Das Schema durch die Validierungs-Pipeline laufen lassen:

    Terminal-Fenster
    flowmcp validate ./my-schema.mjs

    Der Validator prueft Regeln zu Struktur, Sicherheit und Korrektheit.

  6. Mit CLI testen

    Live-API-Aufrufe ausfuehren, um zu pruefen, ob das Schema funktioniert:

    Terminal-Fenster
    flowmcp test single ./my-schema.mjs
    flowmcp test single ./my-schema.mjs --route getData

Parameter definieren, wie Benutzereingaben und Server-Credentials auf API-Requests abgebildet werden. Jeder Parameter hat eine position, die steuert, wohin er geht:

An die URL als ?key=value angehaengt:

{
position: { key: 'symbol', value: '{{USER_PARAM}}', location: 'query' },
z: { primitive: 'string()', options: [ 'min(1)' ] }
}
// GET /api/data?symbol=BTC

In den URL-Pfad eingesetzt:

{
position: { key: 'userId', value: '{{USER_PARAM}}', location: 'insert' },
z: { primitive: 'string()', options: [ 'min(1)' ] }
}
// path: '/users/{{userId}}' -> /users/abc123

Im Request-Body fuer POST/PUT-Requests gesendet:

{
position: { key: 'query', value: '{{USER_PARAM}}', location: 'body' },
z: { primitive: 'string()', options: [] }
}

Aus Umgebungsvariablen injiziert. Niemals dem KI-Client zugaenglich:

{
position: { key: 'apikey', value: '{{SERVER_PARAM:ETHERSCAN_API_KEY}}', location: 'query' },
z: { primitive: 'string()', options: [] }
}

Jeder Parameter enthaelt ein z-Feld, das Validierungsregeln definiert:

// String mit Mindestlaenge
z: { primitive: 'string()', options: [ 'min(1)' ] }
// Zahl mit Mindestwert
z: { primitive: 'number()', options: [ 'min(1)' ] }
// Enum aus fester Liste
z: { primitive: 'enum(["bitcoin","ethereum","solana"])', options: [] }
// Enum aus Shared-List-Feld
z: { primitive: 'enum({{evmChains:etherscanAlias}})', options: [] }
// Optionaler String
z: { primitive: 'string()', options: [ 'optional()' ] }

Schemas koennen Shared Lists fuer wiederverwendbare Wert-Aufzaehlungen wie Chain-IDs oder Token-Symbole referenzieren:

// In main:
sharedLists: [
{
ref: 'evmChains',
version: '1.0.0',
filter: { key: 'etherscanAlias', exists: true }
}
],
// In einem Parameter:
z: { primitive: 'enum({{evmChains:etherscanAlias}})', options: [] }

Die {{evmChains:etherscanAlias}}-Syntax interpoliert das etherscanAlias-Feld aus allen Eintraegen der evmChains Shared List, die den Filter bestehen. Dies generiert ein Enum wie enum(["ETH","POLYGON","ARBITRUM","OPTIMISM","BASE","BSC"]).

Grosse API-Antworten auf die Felder reduzieren, die der KI-Client braucht:

export const handlers = ( { sharedLists, libraries } ) => ( {
getProtocols: {
postRequest: async ( { response } ) => {
const items = response
.filter( ( item ) => item.tvl > 0 )
.map( ( item ) => {
const { name, slug, tvl, chain, category } = item
return { name, slug, tvl, chain, category }
} )
return { response: items }
}
}
} )

Request-Parameter vor dem API-Aufruf modifizieren:

export const handlers = ( { sharedLists, libraries } ) => ( {
getData: {
preRequest: async ( { params } ) => {
const { symbol } = params
const normalized = symbol.toUpperCase()
return { params: { ...params, symbol: normalized } }
}
}
} )