Skip to main content
Skills are reusable AI agent instructions that compose tools and resources into multi-step workflows. They map to the MCP Prompts primitive and are declared in the skills key of a schema’s main export. Each skill is stored as a separate .mjs file alongside the schema.
Skills are optional. Most schemas only need tools. Add skills when your schema has tools that work together in a predictable workflow that benefits from step-by-step guidance.

When to Use Skills

Use CaseSkill Needed?
Single tool call (get price, check status)No
Multi-step workflow (fetch data, transform, report)Yes
Common combination of tools that agents should know aboutYes
Simple tool with clear descriptionNo
Skills are most valuable when:
  • Multiple tools from the schema work together in a specific sequence
  • The workflow requires context about how to interpret intermediate results
  • AI agents would benefit from structured guidance on tool composition

Schema Declaration

Skills are referenced in the main export’s skills array:
export const main = {
    namespace: 'etherscan',
    name: 'ContractExplorer',
    version: '3.0.0',
    root: 'https://api.etherscan.io',
    tools: {
        getContractAbi: { /* ... */ },
        getSourceCode: { /* ... */ }
    },
    skills: [
        {
            name: 'full-contract-audit',
            file: 'full-contract-audit.mjs',
            description: 'Retrieve ABI and source code for a comprehensive contract audit'
        }
    ]
}

Skill Reference Fields

FieldTypeRequiredDescription
namestringYesSkill identifier. Must match ^[a-z][a-z0-9-]*$ (lowercase, hyphens).
filestringYesPath to the .mjs skill file, relative to the schema. Must end in .mjs.
descriptionstringYesWhat this skill does. Visible to AI clients.

Skill File Format

Each skill is a .mjs file that exports a skill object:
const content = `
## Instructions

You are performing a comprehensive smart contract audit.

### Step 1: Retrieve ABI
Call {{tool:getContractAbi}} with the provided {{input:address}}.
Parse the ABI to identify all public functions, events, and modifiers.

### Step 2: Retrieve Source Code
Call {{tool:getSourceCode}} with the same {{input:address}}.
Analyze the Solidity source for:
- Reentrancy vulnerabilities
- Access control patterns
- Gas optimization opportunities

### Step 3: Cross-Reference
Compare the ABI with the source code to verify:
- All public functions are documented
- Event emissions match expected patterns
- Modifier usage is consistent

### Step 4: Report
Produce a Markdown report with:
- Function summary table
- Security findings (Critical / Warning / Info)
- Gas optimization suggestions
`

export const skill = {
    name: 'full-contract-audit',
    version: 'flowmcp-skill/1.0.0',
    description: 'Retrieve ABI and source code for a comprehensive contract audit.',
    requires: {
        tools: [ 'getContractAbi', 'getSourceCode' ],
        resources: [],
        external: []
    },
    input: [
        { key: 'address', type: 'string', description: 'Ethereum contract address (0x...)', required: true }
    ],
    output: 'Markdown report with ABI summary, security findings, and optimization suggestions.',
    content
}

Skill Object Fields

FieldTypeRequiredDescription
namestringYesMust match the name in the schema’s skills array entry.
versionstringYesMust be 'flowmcp-skill/1.0.0'.
descriptionstringYesWhat this skill does.
requiresobjectYesDependencies: tools, resources, and external arrays.
inputarrayNoUser-provided input parameters.
outputstringNoDescription of what the skill produces.
contentstringYesThe instruction text with placeholders.

requires Object

FieldTypeDescription
toolsstring[]Tool names from the schema that this skill uses. Must match tool names in main.tools.
resourcesstring[]Resource names from the schema that this skill uses. Must match names in main.resources.
externalstring[]External capabilities not provided by the schema (for documentation purposes).

input Array

Each input parameter:
FieldTypeDescription
keystringParameter name (camelCase). Referenced in content as {{input:key}}.
typestringMust be string, number, or boolean.
descriptionstringWhat this input parameter is for.
requiredbooleanWhether the user must provide this value.

Placeholder System

The content field supports four types of placeholders:
PlaceholderSyntaxResolves ToExample
Tool reference{{tool:name}}Tool name from requires.tools{{tool:getContractAbi}}
Resource reference{{resource:name}}Resource name from requires.resources{{resource:verifiedContracts}}
Skill reference{{skill:name}}Another skill in the same schema{{skill:quick-check}}
Input reference{{input:key}}User-provided input value{{input:address}}

Placeholder Rules

  1. {{tool:x}}x should be listed in requires.tools
  2. {{resource:x}}x should be listed in requires.resources
  3. {{skill:x}}x must reference another skill in the same schema (no circular references)
  4. {{input:x}}x should match an input[].key
Unresolved placeholders produce validation warnings (not errors), except for {{skill:x}} which must resolve.

Versioning

All skills use the version string 'flowmcp-skill/1.0.0'. This version identifies the skill format, not the skill’s content version. When the skill format changes, this version will be updated.
version: 'flowmcp-skill/1.0.0'

Constraints

ConstraintValueRationale
Max skills per schema4Skills compose tools; keep schemas focused
Skill name pattern^[a-z][a-z0-9-]*$Lowercase with hyphens
Skill file extension.mjsES module format
Versionflowmcp-skill/1.0.0Fixed for v3.0.0
ContentNon-empty stringMust contain instructions
No circular referencesVia {{skill:x}}Prevents infinite loops

Complete Example

A schema with tools, a resource, and a skill:
// etherscan-contracts.mjs
export const main = {
    namespace: 'etherscan',
    name: 'ContractExplorer',
    description: 'Explore verified smart contracts with API tools and local data',
    version: '3.0.0',
    root: 'https://api.etherscan.io',
    requiredServerParams: [ 'ETHERSCAN_API_KEY' ],
    requiredLibraries: [],
    headers: {},
    tools: {
        getContractAbi: {
            method: 'GET',
            path: '/api',
            description: 'Returns 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: 'Returns the Solidity source code of a verified 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: [] } }
            ]
        }
    },
    resources: {
        verifiedContracts: {
            description: 'Local database of verified contract metadata',
            source: 'sqlite',
            database: 'contracts.db',
            queries: {
                byAddress: {
                    description: 'Find contract metadata by address',
                    sql: 'SELECT name, compiler_version, license FROM contracts WHERE address = ?',
                    parameters: [
                        { key: 'address', type: 'string', description: 'Contract address', required: true }
                    ]
                }
            }
        }
    },
    skills: [
        {
            name: 'full-contract-audit',
            file: 'full-contract-audit.mjs',
            description: 'Comprehensive contract audit using ABI, source code, and local metadata'
        }
    ]
}
The corresponding skill file (full-contract-audit.mjs):
const content = `
## Full Contract Audit

Perform a comprehensive audit of the smart contract at {{input:address}}.

### Step 1: Quick Metadata Check
Query {{resource:verifiedContracts}} to check if the contract is in the local database.
Note the compiler version and license type.

### Step 2: Fetch Live ABI
Call {{tool:getContractAbi}} with address {{input:address}}.
Parse the ABI JSON to list all public functions and events.

### Step 3: Fetch Source Code
Call {{tool:getSourceCode}} with address {{input:address}}.
Analyze the source for common vulnerability patterns.

### Step 4: Produce Report
Generate a Markdown report containing:
- Contract identity (name, compiler, license from Step 1)
- Public interface summary (from Step 2)
- Security analysis (from Step 3)
- Overall risk assessment
`

export const skill = {
    name: 'full-contract-audit',
    version: 'flowmcp-skill/1.0.0',
    description: 'Comprehensive contract audit using ABI, source code, and local metadata.',
    requires: {
        tools: [ 'getContractAbi', 'getSourceCode' ],
        resources: [ 'verifiedContracts' ],
        external: []
    },
    input: [
        { key: 'address', type: 'string', description: 'Ethereum contract address (0x...)', required: true }
    ],
    output: 'Markdown report with contract identity, public interface, security analysis, and risk assessment.',
    content
}

Validation Rules

Skills are validated by rules SKL001-SKL025. Key rules include:
CodeRule
SKL002Maximum 4 skills per schema
SKL005Skill file must end in .mjs
SKL008skill.name must match the name in main.skills entry
SKL009Version must be 'flowmcp-skill/1.0.0'
SKL013requires.tools entries must match tool names in schema
SKL014requires.resources entries must match resource names in schema
SKL025No circular skill references via {{skill:x}} placeholders
See Validation Rules for the complete list.

Group-Level Skills vs Schema-Level Skills

FlowMCP has two types of skills:
TypeLocationFormatPurpose
Schema-level.mjs files alongside schemaexport const skill objectDistributed with the schema, composing that schema’s tools
Group-level.md files in .flowmcp/skills/Markdown with sectionsProject-specific workflows across multiple schemas
Schema-level skills (this page) are part of the schema and travel with it. Group-level skills (see Groups & Skills) are project-local and can reference tools from any schema in the group.