.mjs files with two named exports: a static main block and an optional handlers factory function.
This page focuses on practical tool creation. See Schema Format for the full specification and Parameters for parameter details.
Schema Structure
A schema file has two parts: the declarativemain export that describes what tools do, and the optional handlers export that transforms requests and responses.
The main Export
The main export is a static, JSON-serializable object. No functions, no dynamic values, no imports.
Required Fields
| Field | Type | Description |
|---|---|---|
namespace | string | Provider identifier, lowercase letters only (/^[a-z]+$/). |
name | string | Schema name in PascalCase (e.g. SmartContractExplorer). |
description | string | What this schema does, 1-2 sentences. |
version | string | Must match 3.\d+.\d+ (semver, major must be 3). |
root | string | Base URL for all tools. Must start with https:// (no trailing slash). |
tools | object | Tool definitions. Keys are camelCase tool names. Maximum 8 tools. |
Optional Fields
| Field | Type | Description |
|---|---|---|
docs | string[] | Documentation URLs for the API provider. |
tags | string[] | Categorization tags for tool discovery. |
requiredServerParams | string[] | Environment variable names needed at runtime (e.g. API keys). |
requiredLibraries | string[] | npm packages needed by handlers. |
headers | object | Default HTTP headers applied to all tools. |
sharedLists | object[] | Shared list references for dynamic enum values. See Shared Lists. |
Tool Definition
Each key intools is the tool name in camelCase. The tool name becomes part of the fully qualified MCP tool name.
Tool Fields
| Field | Type | Required | Description |
|---|---|---|---|
method | string | Yes | HTTP method: GET, POST, PUT, DELETE. |
path | string | Yes | URL path appended to root. May contain {{key}} placeholders. |
description | string | Yes | What this tool does. Appears in the MCP tool description. |
parameters | array | Yes | Input parameter definitions. Can be empty []. |
Path Templates
The path supports{{key}} placeholders that are replaced by insert parameters at call-time:
{{key}} placeholder must have a corresponding parameter with location: 'insert'.
Parameters
Each parameter has two blocks:position (where the value goes) and z (how it is validated).
Parameter Types
| Type | Description | Example |
|---|---|---|
string() | Any string value | 'string()' |
number() | Numeric value | 'number()' |
boolean() | True or false | 'boolean()' |
enum(A,B,C) | One of the listed values | 'enum(mainnet,testnet)' |
array() | Array of values | 'array()' |
Value Sources
| Pattern | Description | Visible to User |
|---|---|---|
{{USER_PARAM}} | User provides the value at call-time | Yes |
{{SERVER_PARAM:KEY}} | Injected from environment variable | No |
| Fixed string | Sent automatically with every request | No |
Validation Options
| Option | Description | Example |
|---|---|---|
min(n) | Minimum value or length | 'min(1)' |
max(n) | Maximum value or length | 'max(100)' |
optional() | Parameter is not required | 'optional()' |
default(value) | Default when omitted | 'default(100)' |
Handlers
The optionalhandlers export is a factory function that receives injected dependencies and returns handler objects per tool.
Injected Dependencies
| Parameter | Type | Description |
|---|---|---|
sharedLists | object | Resolved shared list data, keyed by list name. Read-only (deep-frozen). |
libraries | object | Loaded npm packages from requiredLibraries, keyed by package name. |
Handler Types
| Handler | When | Input | Must Return |
|---|---|---|---|
preRequest | Before the API call | { struct, payload } | { struct, payload } |
postRequest | After the API call | { response, struct, payload } | { response } |
Handler Rules
- Handlers are optional. Tools without handlers make direct API calls.
- Zero import statements. All dependencies come through the factory function.
- No restricted globals.
fetch,fs,process,evalare forbidden. - Return shape must match.
preRequestreturns{ struct, payload }.postRequestreturns{ response }.
Complete Example
A full Etherscan schema with two tools, API key injection, and apostRequest handler:
Constraints
| Constraint | Value | Rationale |
|---|---|---|
| Max tools per schema | 8 | Keeps schemas focused. Split large APIs into multiple schema files. |
| Version major | 3 | Must match 3.\d+.\d+. |
| Namespace pattern | ^[a-z]+$ | Letters only. No numbers, hyphens, or underscores. |
| Root URL protocol | https:// | HTTP is not allowed. |
| Root URL trailing slash | Forbidden | root must not end with /. |
| Schema file imports | Zero | All dependencies are injected via the handlers factory. |