This documentation adapts the formal specification for practical use. The full specification is maintained at github.com/FlowMCP/flowmcp-spec.
Problem
Web data sources are organized by provider — Etherscan exposes smart contract endpoints, CoinGecko exposes market data, DeFi Llama exposes TVL metrics. Each source has its own interface style, authentication scheme, URL structure, response format, and error handling. AI agents need tools organized by application domain — token prices, contract ABIs, TVL data, wallet balances. An agent answering a question about a token’s market cap should not need to know whether the answer comes from CoinGecko, CoinCap, or DeFi Llama. Manual integration per source is unsustainable at scale. With 187+ schemas across dozens of providers, the combinatorial complexity makes hand-written integrations fragile and expensive to maintain.Solution
FlowMCP introduces a schema-driven normalization layer between web data sources and AI clients. Each schema is a.mjs file that declaratively defines:
- Input parameters with Zod-based validation (type, constraints, enum values)
- URL construction rules (path templates, query parameters, body payloads)
- Response transformation (optional handlers for pre/post processing)
- Security constraints (no imports, no filesystem access, no eval)
Positioning
FlowMCP is the deterministic anchor in a system that pairs it with non-deterministic AI.| Layer | Nature | Responsibility |
|---|---|---|
| AI Client (Skills) | Non-deterministic | Decides which tool to use, how to interpret results |
| FlowMCP | Deterministic | Guarantees the tool itself behaves identically every time |
| Web Data Sources | External | Provides the raw data (uncontrolled) |
- The same input parameters always produce the same API call
- Parameter validation is enforced before any network request
- Response transformations are consistent and reproducible
- Security constraints are verified at load-time, not runtime
Terminology
| Term | Definition |
|---|---|
| Schema | A .mjs file with two named exports: main (static) and optionally handlers (factory function). Defines one or more tools. |
| Route | A single tool within a schema. Maps to one web data source endpoint. Each route has parameters, a method, a path, and optional handlers. |
| Tool | The MCP-visible unit exposed to AI clients. Fully qualified name: namespace/schemaFile::routeName. |
| Namespace | Provider identifier, lowercase letters only (e.g. etherscan, coingecko). Groups schemas by data source. |
| Handler | An async function returned by the handlers factory. Performs pre- or post-processing for a route. Receives dependencies via injection. |
| Modifier | Handler subtype: preRequest transforms input before the API call, postRequest transforms output after. |
| Shared List | A reusable, versioned value list (e.g. EVM chain identifiers) referenced by schemas and injected at load-time. |
| Group | A named collection of cherry-picked tools with an integrity hash. Used for project-level tool activation. |
| Main Export | export const main = {...} — the declarative, JSON-serializable part of a schema. Hashable for integrity verification. |
| Handlers Export | export const handlers = ({ sharedLists, libraries }) => ({...}) — factory function receiving injected dependencies. |
Design Principles
1. Deterministic over clever
Same input always produces the same API call. No randomness, no caching heuristics, no adaptive behavior inside the schema layer.2. Declare over code
Maximize themain block, minimize handlers. Every field that can be expressed declaratively must live in main. Handlers exist only for transformations that cannot be expressed as static data.
3. Inject over import
Schemas receive data through dependency injection, never import. A handler that needs EVM chain data receivessharedLists.evmChains via the factory function. Libraries are declared in requiredLibraries and injected by the runtime from an allowlist.
4. Hash over trust
Integrity verification through SHA-256 hashes. Themain block is hashable because it is pure JSON-serializable data. Groups store hashes of their member tools.
5. Constrain over permit
Security by default, explicit opt-in for capabilities. Schema files have zero import statements. The security scanner rejects schemas with forbidden patterns at load-time.Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2025-06 | Initial schema format. Flat structure with inline parameters. |
| 1.2.0 | 2025-11 | Added handlers, Zod-based parameter validation, modifier pattern. |
| 2.0.0 | 2026-02 | Two-export format (main + handlers factory). Dependency injection. Shared lists. Output schemas. Zero-import security. Groups with integrity hashes. Max routes reduced to 8. |
What Changed in v2.0.0
The v2.0.0 release restructures the schema format around a fundamental insight: the declarative parts should be separable from the executable parts. This enables:- Integrity hashing of the
mainblock without including function bodies - Security scanning of the
handlersblock as an isolated concern - Shared lists that inject reusable data at load-time instead of hardcoding enum values
- Output schemas that declare expected response shapes for downstream consumers
- Groups that compose tools across schemas with verifiable integrity
Specification Document Index
| Document | Description |
|---|---|
| Schema Format | File structure, main/handlers split, route definitions, naming conventions |
| Parameters | Position block, Z block validation, shared list interpolation, API key injection |
| Shared Lists | List format, versioning, field definitions, filtering, resolution lifecycle |
| Output Schema | Response type declarations, field mapping, validation rules |
| Security Model | Zero-import policy, library allowlist, static scan, dependency injection |
| Groups & Prompts | Cherry-pick groups, integrity hashes, prompt workflows |
| Route Tests | Test format, response capture lifecycle, output schema generation |
| Preload | Cache configuration, TTL guidelines, runtime behavior |
| Validation Rules | 79 rules across 12 categories with severity levels |
| Migration v1 to v2 | Step-by-step migration guide, backward compatibility |