Schema erstellen
Diese Anleitung fuehrt dich durch die Erstellung von FlowMCP v3.0.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.
Voraussetzungen
Abschnitt betitelt „Voraussetzungen“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 (
npm install -g github:FlowMCP/flowmcp-cli)
Erstellungsprozess
Abschnitt betitelt „Erstellungsprozess“-
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 -
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: '3.0.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' }}}}}}} -
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' }}}} -
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 } = responseconst simplified = {id,value: rawValue / 100,source: metadata.provider}return { response: simplified }}}} )Handler unterstuetzen zwei Hooks pro Tool:
preRequest— Request vor dem Senden modifizierenpostRequest— Antwort transformieren, bevor sie den KI-Client erreicht
-
Mit CLI validieren
Das Schema durch die Validierungs-Pipeline laufen lassen:
Terminal-Fenster flowmcp validate ./my-schema.mjsDer Validator prueft Regeln zu Struktur, Sicherheit und Korrektheit.
-
Mit CLI testen
Live-API-Aufrufe ausfuehren, um zu pruefen, ob das Schema funktioniert:
Terminal-Fenster flowmcp test single ./my-schema.mjsflowmcp test single ./my-schema.mjs --route getData
Parameter-Muster
Abschnitt betitelt „Parameter-Muster“Parameter definieren, wie Benutzereingaben und Server-Credentials auf API-Requests abgebildet werden. Jeder Parameter hat eine position, die steuert, wohin er geht:
Query-Parameter
Abschnitt betitelt „Query-Parameter“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=BTCPfad-Parameter (insert)
Abschnitt betitelt „Pfad-Parameter (insert)“In den URL-Pfad eingesetzt:
{ position: { key: 'userId', value: '{{USER_PARAM}}', location: 'insert' }, z: { primitive: 'string()', options: [ 'min(1)' ] }}// path: '/users/{{userId}}' -> /users/abc123Body-Parameter
Abschnitt betitelt „Body-Parameter“Im Request-Body fuer POST/PUT-Requests gesendet:
{ position: { key: 'query', value: '{{USER_PARAM}}', location: 'body' }, z: { primitive: 'string()', options: [] }}Server-Parameter
Abschnitt betitelt „Server-Parameter“Aus Umgebungsvariablen injiziert. Niemals dem KI-Client zugaenglich:
{ position: { key: 'apikey', value: '{{SERVER_PARAM:ETHERSCAN_API_KEY}}', location: 'query' }, z: { primitive: 'string()', options: [] }}Zod-Validierung
Abschnitt betitelt „Zod-Validierung“Jeder Parameter enthaelt ein z-Feld, das Validierungsregeln definiert:
// String mit Mindestlaengez: { primitive: 'string()', options: [ 'min(1)' ] }
// Zahl mit Mindestwertz: { primitive: 'number()', options: [ 'min(1)' ] }
// Enum aus fester Listez: { primitive: 'enum(["bitcoin","ethereum","solana"])', options: [] }
// Enum aus Shared-List-Feldz: { primitive: 'enum({{evmChains:etherscanAlias}})', options: [] }
// Optionaler Stringz: { primitive: 'string()', options: [ 'optional()' ] }Shared-List-Referenzen
Abschnitt betitelt „Shared-List-Referenzen“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"]).
Handler-Muster
Abschnitt betitelt „Handler-Muster“Antwort-Filterung
Abschnitt betitelt „Antwort-Filterung“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 } } }} )Pre-Request-Modifikation
Abschnitt betitelt „Pre-Request-Modifikation“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 } } } }} )