flowmcp-core
FlowMCP is a framework for adapting existing web APIs into a standardized Model Context Protocol (MCP) interface, enabling structured, testable, and semantically consistent access for AI systems.
Documentation
FlowMCP Core
Version: 4.0.0
A comprehensive framework for adapting existing web APIs into a standardized Model Context Protocol (MCP) interface, enabling structured, testable, and semantically consistent access for AI systems. FlowMCP Core transforms any REST API into MCP-compatible tools with built-in validation, testing, and error handling.
Features
- v4 Pipeline: 16-step orchestrated load with security scan, legacy adapter, validators, library loader, selections, handlers, skills, placeholder resolution, resource DB, and prompts
- Selections (5th Primitive): First-class operator-curated tool subsets via `SelectionLoader` and `SelectionValidator`
- Grade Report: Automated A–F schema quality grading via `GradeReporter` (eval prompts + deterministic scoring)
- Placeholder Resolution: 12 placeholder types resolved against a typed catalog (tools, resources, prompts, skills, sharedLists, inputs, prefill)
- Capture Flow: Live response capture with `OutputSchemaGenerator` to auto-derive output schemas from real API responses
- One-Shot Skills: `SkillContentGenerator` renders self-contained skill content from schema + sharedLists
- Meta-Block per Tool: Every v4 tool declares `isReadOnly`, `isConcurrencySafe`, `isDestructive`, `searchHint`, `aliases`, `alwaysLoad` — generated/validated via `MetaGenerator`
- Skills-only special path: Schemas with `tools: {}` are recognised after validation and short-circuit the pipeline (steps 7–9, 11–15 skipped)
- Library Loading: Allowlisted runtime library injection through `LibraryLoader` (with `mergeAllowlist`)
- Resource Database Manager: SQLite-backed resource initialisation via `ResourceDatabaseManager`
- Security Scanner: Static scan for forbidden patterns (eval, imports) before any module is loaded
- v4-only (4.0.0): The v1/v2/legacy trees were removed — the root export and every module are v4. See Breaking change: v4-only (4.0.0)
Table of Contents
Quick Start (v4)
import * as v4 from 'flowmcp-core/v4'
const { Pipeline } = v4
// v4 Pipeline — loads, validates, and returns a result object
const result = await Pipeline
.load( {
filePath: './schemas/etherscan-io/etherscan.mjs',
listsDir: './schemas/shared/lists',
allowlist: null,
selectionFiles: [],
prefillTimeout: 1000,
fetchFn: null,
userParams: {}
} )
if( !result.status ) {
console.error( 'Pipeline failed:', result.messages )
return
}
// Result object contains all primitives:
// main, handlerMap, resourceHandlerMap, sharedLists, libraries,
// skills, selections, prompts, contentMap, prefillResults, warnings
console.log( 'Tools available:', Object.keys( result.main.tools ) )
console.log( 'Skills loaded:', Object.keys( result.skills ) )
console.log( 'Warnings:', result.warnings )Grade Report
import * as v4 from 'flowmcp-core/v4'
const { GradeReporter } = v4
const { prompts } = GradeReporter
.buildEvalPrompts( { schema: result.main, skill: null } )
const { grade, scoreSummary } = GradeReporter
.grade( {
schemaId: 'etherscan/4.0.0',
deterministicResult: { passed: true },
scores: { coverage: 90, accuracy: 85, clarity: 80 },
validatorVersion: '4.0.0'
} )
console.log( 'Grade:', grade ) // 'A' | 'B' | 'C' | 'D' | 'F'
console.log( 'Summary:', scoreSummary )v4 Public API
The v4 API is exported via `flowmcp-core/v4`. Each module is a focused, static class with a small public surface (1–3 methods per module). Internal helpers stay private.
| Module | Public Methods |
|---|---|
| `Pipeline` | `load({ filePath, listsDir, allowlist, selectionFiles, prefillTimeout, fetchFn, userParams })` |
| `MainValidator` | `validate({ main })` |
| `SelectionLoader` | `load({ filePath })` |
| `SelectionValidator` | `validate({ selection })` |
| `PlaceholderResolver` | `resolve({ content, catalog, sharedLists, inputs, prefillResults })` |
| `PrefillExecutor` | `execute({ skill, userParams, fetchFn, timeout })` |
| `MetaGenerator` | `generate({ tool })`, `generateForSchema({ tools })` |
| `GradeReporter` | `buildEvalPrompts({ schema, skill })`, `grade({ schemaId, deterministicResult, scores, validatorVersion })` |
| `OutputSchemaGenerator` | `generateFromResponse({ response, mimeType, schemaId })` |
| `SkillContentGenerator` | `generate({ schemas, sharedLists })` |
| `SkillValidator` | `validate({ skills, tools, resources })` |
| `AgentManifestValidator` | `validate({ manifest })` |
| `IdResolver` | `resolve({ reference, catalog })` |
| `LibraryLoader` | `load({ requiredLibraries, allowlist })`, `getDefaultAllowlist()`, `mergeAllowlist({ extraAllowlist })` |
| `ResourceDatabaseManager` | `initialize({ resources, schemaRef, schemaDir })` |
Pipeline.load() Return Shape
{
status: true, // Boolean — overall success
messages: [], // Error messages when status === false
main, // The validated v4 `main` object
handlerMap: {}, // Per-tool handler functions
resourceHandlerMap: {}, // Per-resource handler functions
sharedLists: {}, // Resolved shared lists
libraries: {}, // Loaded libraries (allowlist-filtered)
skills: {}, // Skills with resolved content
selections: {}, // Loaded selection files
prompts: {}, // Loaded prompts
contentMap: null, // Map produced by SkillContentGenerator
prefillResults: null, // Map produced by PrefillExecutor
warnings: [] // Non-fatal warnings
}Skills-only special path
When `Object.keys( main.tools ).length === 0` the pipeline takes a special path after step 6: HandlerFactory, SelectionLoader, PrefillExecutor, PlaceholderResolver, ResourceValidator, and PromptLoader are all skipped. `handlerMap` and `resourceHandlerMap` return `{}`. Note: `main.skills` is forbidden in v4 — use the top-level `skills` export instead. The special path therefore returns `skills: {}` for v4 schemas.
v4 Schema Structure
A v4 schema declares `export const main` with `version: '4.0.0'` and (optionally) `export const handlers` as a factory. Every entry under `tools` must carry a complete `meta` block.
Required Fields
| Key | Type | Description |
|---|---|---|
| `namespace` | string | Unique namespace, regex `^[a-z][a-z0-9-]*$` |
| `name` | string | Human-readable display name |
| `description` | string | Short summary of the API |
| `version` | string | Must equal `'4.0.0'` |
| `root` | string | Base URL for the API |
| `tools` | object | Map of tool definitions (may be empty for Skills-only schemas) |
Required `meta` Fields per Tool
| Field | Type | Notes |
|---|---|---|
| `isReadOnly` | boolean | True for GET / read-only access |
| `isConcurrencySafe` | boolean | Defaults to `isReadOnly` |
| `isDestructive` | boolean | Defaults to `!isReadOnly` |
| `searchHint` | string | Short hint for tool search |
| `aliases` | string[] | Alternative tool names |
| `alwaysLoad` | boolean | Force-load even when filtered |
Use `MetaGenerator.generateForSchema({ tools })` to derive an initial `meta` block via heuristics.
Example v4 Schema
export const main = {
namespace: 'etherscan',
name: 'Etherscan',
description: 'Etherscan REST API.',
version: '4.0.0',
docs: [ 'https://docs.etherscan.io' ],
tags: [ 'evm', 'blockchain' ],
root: 'https://api.etherscan.io',
requiredServerParams: [ 'API_KEY' ],
tools: {
getBalance: {
method: 'GET',
path: '/api?module=account&action=balance',
description: 'Return the balance for an address.',
parameters: [],
meta: {
isReadOnly: true,
isConcurrencySafe: true,
isDestructive: false,
searchHint: 'fetch ETH balance for an address',
aliases: [],
alwaysLoad: false
},
tests: [
{ _description: 'happy path' }
]
}
}
}
export const handlers = ( { sharedLists, libraries } ) => ( {
getBalance: {
postRequest: async ( { response } ) => {
return { response: { balance: response[ 'result' ] } }
}
}
} )
// Skills, resources, and prompts are top-level exports — never nested in main
export const skills = {
'lookup-balance': {
version: 'flowmcp/4.0.0',
type: 'namespace',
whenToUse: 'When the user wants to lookup an ETH balance.',
content: 'Use {{tool:etherscan/getBalance}} with the parameter address.'
}
}Breaking change: v4-only (4.0.0)
4.0.0 removes the v1, v2, and legacy trees. The package is now v4-only:
- The `exports` map carries just two entries — `.` (the v4 surface, incl. the `FlowMCP` facade) and `./v4` (an alias kept for one release, then removed). The `./v1`, `./v2`, and `./legacy` subpaths no longer exist.
- Removed v1/v2 methods such as `.activateServerTools`, `.filterArrayOfSchemas`, `.getArgvParameters`, and `.prepareActivations` are gone from the public surface. Build MCP servers with `FlowMCP.loadSchema()` + `FlowMCP.prepareServerTool()` instead (see Quick Start and the Server Integration guide).
- SHA-pinned installs keep working. Consumers that pin by commit hash (`github:FlowMCP/flowmcp-core#`) are unaffected — the old commits stay reachable in the Git history. Breakage only occurs on a pin bump, for docs readers, or for unpinned installs. Pin bumps must migrate to the v4 API.
- Convert v1/v2/v3 schema files to v4 with the explicit `flowmcp migrate` converter. The v1 method-by-method reference is preserved in the Git history.
See the CHANGELOG for the full 4.0.0 breaking notice.
> MCP SDK removed. The unused `@modelcontextprotocol/sdk` dependency was dropped from `flowmcp-core`. Core builds MCP tools in-process via `FlowMCP.loadSchema()` + `FlowMCP.prepareServerTool()` (no SDK needed to prepare tools — the consumer wires them into its own `McpServer`). For a ready-made MCP server, use `mcp-agent-server`.
Error Handling
The v4 Pipeline collects all errors and warnings in the result object — it never throws on validation failure. Inspect `status`, `messages`, and `warnings` to react.
const result = await Pipeline.load( { filePath: './schemas/etherscan.mjs' } )
if( !result.status ) {
result.messages
.forEach( ( msg ) => { console.error( '- ' + msg ) } )
return
}
result.warnings
.forEach( ( w ) => { console.warn( '! ' + w ) } )Error categories
1. SEC* — SecurityScanner findings (forbidden patterns, imports, eval)
2. VAL* — MainValidator (schema shape, meta-block, version)
3. SEL* — SelectionLoader / SelectionValidator
4. SKILL* — SkillLoader / SkillValidator (incl. missing tool references)
5. PIPE-WARN / PIPE-INFO — non-fatal pipeline notices
Testing & Validation
Run the v4 test suite from the repository root:
npm test
npm run test:coverage:srcSchema authors should pair each tool with a `tests` array carrying at least one `_description` entry. The v4 pipeline keeps test definitions in `main.tools[name].tests` — they are not removed during validation.
Performance & Optimization
- The pipeline is async and runs independent steps concurrently where possible (selections, prefill, library loading).
- `SecurityScanner` and `SchemaLoader` use static analysis and dynamic import — no eval, no spawned processes.
- Heuristic helpers (`MetaGenerator.generateForSchema`, `OutputSchemaGenerator.generateFromResponse`) avoid recomputation by caching per-tool / per-response.
- The Skills-only special path short-circuits the pipeline, keeping load times minimal for browser-automation schemas.
Documentation
For additional documentation and examples:
- **FlowMCP Specification v4.0.0** — Complete specification (current)
- **MIGRATION.md** — Historical v1 → v2 upgrade guide (both trees removed in 4.0.0; kept for reference). Migrate schema files to v4 with `flowmcp migrate`.
- tests/unit/v4/ — Reference test suite for the v4 pipeline and modules
License & Terms of Services
FlowMCP Core is MIT-licensed. The MIT license covers the schema validation, agent manifest loading, and tool execution code in this repository.
Schemas loaded via FlowMCP access third-party APIs, each with their own Terms of Services. Schemas may include an optional `meta.termsOfService` field with the provider's ToS URL and the date we last verified the link. We do not classify or interpret these Terms of Services. Users are solely responsible for reviewing each API provider's terms before use.
FlowMCP makes no representation about ToS compliance, data licensing, or fitness for any purpose. See DISCLAIMER.md for details.
License
MIT
Frequently asked questions
What is flowmcp-core?
flowmcp-core is FlowMCP is a framework for adapting existing web APIs into a standardized Model Context Protocol (MCP) interface, enabling structured, testable, and semantically consistent access for AI systems.
How do I install flowmcp-core?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is flowmcp-core open source?
Yes — it is hosted on GitHub at https://github.com/FlowMCP/flowMCP.
Related MCP tools
🔥 Official Firecrawl MCP Server - Adds powerful web scraping and search to Cursor, Claude and any other LLM clients. JavaScript-based implementation.
A model context protocol server to work with JetBrains IDEs: IntelliJ, PyCharm, WebStorm, etc. Also, works with Android Studio
A server that integrates Linear's project management system with the Model Context Protocol (MCP) to allow LLMs to interact with Linear.
The all-in-one Desktop & Docker AI application with built-in RAG, AI agents, No-code agent builder, MCP compatibility, and more.
CTTF: MCP integration between Cursor and Figma, allowing Cursor Agentic AI to communicate with Figma for reading designs and modifying them programmatically.
This is MCP server for Claude that gives it terminal control, file system search and diff file editing capabilities JavaScript-based implementation.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP