Zum Inhalt springen

Tools

Tools kapseln REST API Endpoints. Jedes Tool entspricht einem HTTP-Request. Schemas sind .mjs-Dateien mit zwei benannten Exports: einem statischen main-Block und einer optionalen handlers-Factory-Funktion.

Eine Schema-Datei besteht aus zwei Teilen: dem deklarativen main Export, der beschreibt was Tools tun, und dem optionalen handlers Export, der Requests und Responses transformiert.

Der main Export ist ein statisches, JSON-serialisierbares Objekt. Keine Funktionen, keine dynamischen Werte, keine Imports.

FeldTypBeschreibung
namespacestringProvider-Bezeichner, nur Kleinbuchstaben (/^[a-z]+$/).
namestringSchema-Name in PascalCase (z.B. SmartContractExplorer).
descriptionstringWas dieses Schema tut, 1-2 Saetze.
versionstringMuss 3.\d+.\d+ entsprechen (Semver, Major muss 3 sein).
rootstringBasis-URL fuer alle Tools. Muss mit https:// beginnen (kein Trailing Slash).
toolsobjectTool-Definitionen. Keys sind camelCase Tool-Namen. Maximal 8 Tools.
FeldTypBeschreibung
docsstring[]Dokumentations-URLs des API-Providers.
tagsstring[]Kategorisierungs-Tags fuer Tool-Discovery.
requiredServerParamsstring[]Umgebungsvariablen-Namen, die zur Laufzeit benoetigt werden (z.B. API-Keys).
requiredLibrariesstring[]npm-Pakete, die von Handlern benoetigt werden.
headersobjectStandard-HTTP-Header, die auf alle Tools angewendet werden.
sharedListsobject[]Shared-List-Referenzen fuer dynamische Enum-Werte. Siehe Shared Lists.
export const main = {
namespace: 'etherscan',
name: 'SmartContractExplorer',
description: 'Explore verified smart contracts on EVM chains via Etherscan APIs',
version: '3.0.0',
root: 'https://api.etherscan.io',
docs: [ 'https://docs.etherscan.io/' ],
tags: [ 'ethereum', 'blockchain' ],
requiredServerParams: [ 'ETHERSCAN_API_KEY' ],
tools: {
// Tool-Definitionen hier
}
}

Jeder Key in tools ist der Tool-Name in camelCase. Der Tool-Name wird Teil des vollqualifizierten MCP-Tool-Namens.

FeldTypErforderlichBeschreibung
methodstringJaHTTP-Methode: GET, POST, PUT, DELETE.
pathstringJaURL-Pfad, der an root angehaengt wird. Kann {{key}}-Platzhalter enthalten.
descriptionstringJaWas dieses Tool tut. Erscheint in der MCP-Tool-Beschreibung.
parametersarrayJaEingabeparameter-Definitionen. Kann leer sein [].

Der Pfad unterstuetzt {{key}}-Platzhalter, die zur Aufrufzeit durch insert-Parameter ersetzt werden:

// Statischer Pfad
path: '/api'
// Einzelner Platzhalter
path: '/api/v1/{{address}}/transactions'
// Mehrere Platzhalter
path: '/api/v1/{{chainId}}/address/{{address}}/balances'

Jeder {{key}}-Platzhalter muss einen entsprechenden Parameter mit location: 'insert' haben.

Jeder Parameter hat zwei Bloecke: position (wohin der Wert geht) und z (wie er validiert wird).

TypBeschreibungBeispiel
string()Beliebiger String-Wert'string()'
number()Numerischer Wert'number()'
boolean()Wahr oder falsch'boolean()'
enum(A,B,C)Einer der aufgelisteten Werte'enum(mainnet,testnet)'
array()Array von Werten'array()'
MusterBeschreibungFuer User sichtbar
{{USER_PARAM}}User gibt den Wert zur Aufrufzeit anJa
{{SERVER_PARAM:KEY}}Aus Umgebungsvariable injiziertNein
Fester StringWird automatisch mit jedem Request gesendetNein
OptionBeschreibungBeispiel
min(n)Minimalwert oder -laenge'min(1)'
max(n)Maximalwert oder -laenge'max(100)'
optional()Parameter ist nicht erforderlich'optional()'
default(value)Standardwert wenn ausgelassen'default(100)'
// User-bereitgestellte Adresse mit Laengenvalidierung
{
position: { key: 'address', value: '{{USER_PARAM}}', location: 'query' },
z: { primitive: 'string()', options: [ 'min(42)', 'max(42)' ] }
}
// Fester Parameter (fuer User unsichtbar)
{
position: { key: 'module', value: 'contract', location: 'query' },
z: { primitive: 'string()', options: [] }
}
// API-Key aus Umgebung injiziert
{
position: { key: 'apikey', value: '{{SERVER_PARAM:ETHERSCAN_API_KEY}}', location: 'query' },
z: { primitive: 'string()', options: [] }
}

Der optionale handlers Export ist eine Factory-Funktion, die injizierte Abhaengigkeiten empfaengt und Handler-Objekte pro Tool zurueckgibt.

export const handlers = ( { sharedLists, libraries } ) => ({
toolName: {
preRequest: async ( { struct, payload } ) => {
// Request vor dem Senden modifizieren
return { struct, payload }
},
postRequest: async ( { response, struct, payload } ) => {
// Antwort nach dem Empfang transformieren
return { response }
}
}
})
ParameterTypBeschreibung
sharedListsobjectAufgeloeste Shared-List-Daten, nach Listennamen geschluesselt. Schreibgeschuetzt (deep-frozen).
librariesobjectGeladene npm-Pakete aus requiredLibraries, nach Paketnamen geschluesselt.
HandlerWannInputMuss zurueckgeben
preRequestVor dem API-Aufruf{ struct, payload }{ struct, payload }
postRequestNach dem API-Aufruf{ response, struct, payload }{ response }
  1. Handler sind optional. Tools ohne Handler machen direkte API-Aufrufe.
  2. Null Import-Statements. Alle Abhaengigkeiten kommen durch die Factory-Funktion.
  3. Keine eingeschraenkten Globals. fetch, fs, process, eval sind verboten.
  4. Rueckgabe-Form muss uebereinstimmen. preRequest gibt { struct, payload } zurueck. postRequest gibt { response } zurueck.

Ein vollstaendiges Etherscan-Schema mit zwei Tools, API-Key-Injektion und einem postRequest-Handler:

export const main = {
namespace: 'etherscan',
name: 'SmartContractExplorer',
description: 'Ethereum blockchain explorer API',
version: '3.0.0',
docs: [ 'https://docs.etherscan.io/' ],
tags: [ 'ethereum', 'blockchain' ],
root: 'https://api.etherscan.io',
requiredServerParams: [ 'ETHERSCAN_API_KEY' ],
headers: { 'Accept': 'application/json' },
tools: {
getContractAbi: {
method: 'GET',
path: '/api',
description: 'Get the ABI of a verified smart contract',
parameters: [
{
position: { key: 'module', value: 'contract', location: 'query' },
z: { primitive: 'string()', options: [] }
},
{
position: { key: 'action', value: 'getabi', location: 'query' },
z: { primitive: 'string()', options: [] }
},
{
position: { key: 'address', value: '{{USER_PARAM}}', location: 'query' },
z: { primitive: 'string()', options: [ 'min(42)', 'max(42)' ] }
},
{
position: { key: 'apikey', value: '{{SERVER_PARAM:ETHERSCAN_API_KEY}}', location: 'query' },
z: { primitive: 'string()', options: [] }
}
]
},
getSourceCode: {
method: 'GET',
path: '/api',
description: 'Get the Solidity source code of a verified smart contract',
parameters: [
{
position: { key: 'module', value: 'contract', location: 'query' },
z: { primitive: 'string()', options: [] }
},
{
position: { key: 'action', value: 'getsourcecode', location: 'query' },
z: { primitive: 'string()', options: [] }
},
{
position: { key: 'address', value: '{{USER_PARAM}}', location: 'query' },
z: { primitive: 'string()', options: [ 'min(42)', 'max(42)' ] }
},
{
position: { key: 'apikey', value: '{{SERVER_PARAM:ETHERSCAN_API_KEY}}', location: 'query' },
z: { primitive: 'string()', options: [] }
}
]
}
}
}
export const handlers = ( { sharedLists } ) => ({
getContractAbi: {
postRequest: async ( { response } ) => {
return { response: JSON.parse( response['result'] ) }
}
},
getSourceCode: {
postRequest: async ( { response } ) => {
const { result } = response
const [ first ] = result
const { SourceCode, ABI, ContractName, CompilerVersion, OptimizationUsed } = first
return {
response: {
contractName: ContractName,
compilerVersion: CompilerVersion,
optimizationUsed: OptimizationUsed === '1',
sourceCode: SourceCode,
abi: ABI
}
}
}
}
})
EinschraenkungWertBegruendung
Max Tools pro Schema8Haelt Schemas fokussiert. Grosse APIs auf mehrere Schema-Dateien aufteilen.
Version Major3Muss 3.\d+.\d+ entsprechen.
Namespace-Muster^[a-z]+$Nur Buchstaben. Keine Zahlen, Bindestriche oder Unterstriche.
Root-URL-Protokollhttps://HTTP ist nicht erlaubt.
Root-URL Trailing SlashVerbotenroot darf nicht mit / enden.
Schema-Datei-ImportsNullAlle Abhaengigkeiten werden via die handlers-Factory injiziert.