一键导入
mcpgraph
Build no-code MCP servers with tools that compose and orchestrate other MCP tools, with data transformation and conditional logic.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Build no-code MCP servers with tools that compose and orchestrate other MCP tools, with data transformation and conditional logic.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Build, test, and manage mcpGraph tools using the mcpGraphToolkit MCP server. Discover MCP servers and tools, construct graph nodes with JSONata and JSON Logic, and interact with mcpGraph configurations. IMPORTANT: Always read this file before creating graph tools using mcpGraphToolkit.
Build, test, and manage mcpGraph tools using the mcpGraphToolkit MCP server. Discover MCP servers and tools, construct graph nodes with JSONata and JSON Logic, and interact with mcpGraph configurations. IMPORTANT: Always read this file before creating graph tools using mcpGraphToolkit.
| name | mcpgraph |
| description | Build no-code MCP servers with tools that compose and orchestrate other MCP tools, with data transformation and conditional logic. |
| version | 1.0.0 |
This skill teaches you how to build mcpGraph configurations - declarative YAML files that define MCP tools as directed graphs of nodes.
An mcpGraph is a declarative YAML configuration file that defines MCP (Model Context Protocol) tools as directed graphs. Each tool executes a sequence of nodes that can:
When to use mcpGraph:
Why use mcpGraph:
This skill assumes mcpGraph is installed in your local environment and available as the mcpgraph command.
To use mcpGraph as an MCP server (e.g., in Claude Desktop), add it to your MCP client configuration:
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"mcpgraph": {
"command": "mcpgraph",
"args": ["-g", "/path/to/your/config.yaml"]
}
}
}
The -g (or --graph) flag specifies the path to your YAML configuration file.
An mcpGraph configuration file is a YAML file with the following structure:
version: "1.0"
# MCP Server Metadata
server:
name: "serverName" # Required: unique identifier
version: "1.0.0" # Required: server version
title: "Display Name" # Optional: display name (defaults to name)
instructions: "..." # Optional: server usage instructions
# MCP Servers used by the graph
mcpServers:
serverName:
command: "command" # For stdio servers
args: ["arg1", "arg2"] # Command arguments
# OR for HTTP servers:
# httpServer:
# type: "streamableHttp"
# url: "https://api.example.com/mcp"
# headers:
# Authorization: "Bearer token"
# Tool Definitions for tools implemented by this graph and available as part of this MCP server
tools:
- name: "toolName"
description: "Tool description"
inputSchema:
type: "object"
properties:
paramName:
type: "string"
description: "Parameter description"
required:
- paramName
outputSchema:
type: "object"
properties:
result:
type: "string"
description: "Result description"
nodes:
# Node definitions here
The server section defines metadata for the MCP server that will expose these tools:
name (required): Unique identifier for the serverversion (required): Server version (semantic versioning)title (optional): Display name (defaults to name if not provided)instructions (optional): Instructions for using this serverThe mcpServers section defines the MCP servers that the graph will call. Each server can be:
command and args to run a command-line programtype: "streamableHttp", url, and optional headersThe tools array defines the MCP tools exposed by this server. Each tool has:
name: Tool identifierdescription: Tool descriptioninputSchema: JSON Schema defining input parameters (standard MCP tool schema)outputSchema: JSON Schema defining output structurenodes: Array of node definitions that form the execution graphA graph is a directed sequence of nodes that execute in order. Execution flow:
next fieldsNodes are connected using the next field, which specifies the ID of the next node to execute:
- id: "node1"
type: "transform"
next: "node2" # Executes node2 after node1
Switch nodes use conditions with next fields (each condition specifies its own next node), plus a top-level next field as the default:
- id: "switch_node"
type: "switch"
conditions:
- rule: { ">": [{ var: "entry.value" }, 10] }
next: "high_path"
next: "default_path" # Default case if no conditions match
During execution, each node's output is stored in the execution context. You can access node outputs using JSONata expressions:
$.node_id - Accesses the latest output of a node with ID node_id$.entry.paramName - Accesses a parameter from the entry nodeThe context is a flat structure: { "node_id": output, ... }
The entry point for a tool's graph execution. Receives tool arguments.
Properties:
id: Node identifier (typically "entry")type: "entry"next: ID of the next node to executeOutput: The tool input arguments (passed through as-is)
Example:
- id: "entry"
type: "entry"
next: "process_node"
Calls an MCP tool on an internal or external MCP server.
Properties:
id: Node identifiertype: "mcp"server: Name of the MCP server (from mcpServers section)tool: Name of the tool to call on that serverargs: Arguments to pass to the tool (can use JSONata expressions)next: ID of the next node to executeOutput: The MCP tool's response (parsed from the tool's content)
Example:
- id: "list_directory_node"
type: "mcp"
server: "filesystem"
tool: "list_directory"
args:
path:
expr: "$.entry.directory" # JSONata expression accessing entry node output
next: "count_files_node"
Applies JSONata expressions to transform data between nodes.
Properties:
id: Node identifiertype: "transform"transform.expr: JSONata expression (string)next: ID of the next node to executeOutput: The result of evaluating the JSONata expression
Expression Format:
expr: '{ "result": "value" }'|) for complex multi-line expressions to improve readabilityExample (simple):
- id: "count_files_node"
type: "transform"
transform:
expr: '{ "count": $count($split($.list_directory_node.content, "\n")) }'
next: "exit"
Example (complex):
- id: "increment_node"
type: "transform"
transform:
expr: |
$executionCount("increment_node") = 0
? { "counter": 1, "sum": 1, "target": $.entry_sum.n }
: { "counter": $nodeExecution("increment_node", -1).counter + 1, ... }
next: "check_condition"
Uses JSON Logic to conditionally route to different nodes based on data.
Properties:
id: Node identifiertype: "switch"conditions: Array of condition rules
rule: JSON Logic expression (required - all conditions must have rules)next: ID of the node to route to if this condition matchesnext: ID of the default next node (used if no conditions match)Output: The node ID of the next node that was routed to (string)
Important: var operations in JSON Logic rules are evaluated using JSONata, allowing full JSONata expression support (including history functions).
Example:
- id: "switch_node"
type: "switch"
conditions:
- rule:
">": [{ var: "entry.value" }, 10]
next: "high_path"
- rule:
">": [{ var: "entry.value" }, 0]
next: "low_path"
next: "zero_path" # Default case if no conditions match
Advanced Example with JSONata:
- id: "check_condition"
type: "switch"
conditions:
- rule:
"<": [
{ var: "$.increment_node.counter" },
{ var: "$.increment_node.target" }
]
next: "increment_node" # Loop back
next: "exit_sum" # Default: exit loop when counter >= target
Exit point that returns the final result to the MCP tool caller.
Properties:
id: Node identifier (typically "exit")type: "exit"next field - execution ends hereOutput: The output from the previous node in the execution history
Example:
- id: "exit"
type: "exit"
JSONata is used in three places in mcpGraph for data transformation and access:
var operations - Access context data in switch node conditions{ "expr": "..." } are evaluated as JSONata expressions (recursively){ "key": value }$.node_id.property$count(array), $split(string, delimiter), etc.condition ? trueValue : falseValue1. Transform Nodes:
Transform nodes use JSONata expressions in the transform.expr field to transform data:
transform:
expr: '{ "count": $count($split($.list_directory_node.content, "\n")) }'
2. MCP Tool Node Arguments:
To use a JSONata expression in an MCP node argument, wrap it in an object with an expr property:
args:
path:
expr: "$.entry.directory" # JSONata expression accessing entry node output
static: "literal/path" # Literal value (not evaluated)
count:
expr: "$count($.previous_node.items)" # JSONata expression with function
Complex nested args:
args:
path:
expr: "'downloads/' & $.entry.filename" # String concatenation
options:
recursive: true # Literal value
filter:
expr: "$.entry.filterPattern" # Nested expression
Important:
expr property are evaluated as JSONataexpr and other properties are invalid (error)expr) are passed as literals3. JSON Logic var Operations:
In switch node conditions, var operations are evaluated using JSONata:
rule:
">": [{ var: "$.increment_node.counter" }, 10]
$.node_id - Latest output of a node$.node_id.property - Property from node output$.entry.paramName - Parameter from entry nodeFor loops and accessing execution history:
$previousNode() - Get the previous node's output$previousNode(index) - Get the node that executed N steps before current$executionCount(nodeName) - Count how many times a node executed$nodeExecution(nodeName, index) - Get a specific execution (0 = first, -1 = last)$nodeExecutions(nodeName) - Get all executions as an arrayExample:
transform:
expr: |
$executionCount("increment_node") = 0
? { "counter": 1, "sum": 1, "target": $.entry_sum.n }
: {
"counter": $nodeExecution("increment_node", -1).counter + 1,
"sum": $nodeExecution("increment_node", -1).sum + $nodeExecution("increment_node", -1).counter + 1,
"target": $.entry_sum.n
}
Simple expressions: Use single-quoted strings
expr: '{ "count": $count($split($.list_directory_node.content, "\n")) }'
Complex expressions: Use block scalars (|) for readability
expr: |
$executionCount("increment_node") = 0
? { "counter": 1 }
: { "counter": $nodeExecution("increment_node", -1).counter + 1 }
JSON Logic is used in switch nodes for conditional routing. It allows complex rules as pure JSON objects.
{ ">": [a, b] }, { "<": [a, b] }, { "==": [a, b] }, etc.{ "and": [rule1, rule2] }, { "or": [rule1, rule2] }, { "!": rule }{ "var": "path" } or { "var": "$.node_id.property" }Important: var operations are evaluated using JSONata, so you can use full JSONata expressions:
{ "var": "entry.value" } - Simple property access{ "var": "$.increment_node.counter" } - JSONata expression{ "var": "$previousNode().count" } - JSONata with history functionSimple comparison:
rule:
">": [{ var: "entry.value" }, 10]
Complex condition:
rule:
and:
- ">": [{ var: "entry.price" }, 100]
- "==": [{ var: "entry.status" }, "active"]
With JSONata:
rule:
"<": [
{ var: "$.increment_node.counter" },
{ var: "$.increment_node.target" }
]
Here's a complete example that counts files in a directory:
version: "1.0"
server:
name: "fileUtils"
version: "1.0.0"
title: "File utilities"
instructions: "This server provides file utility tools for counting files and calculating total file sizes in directories."
mcpServers:
filesystem:
command: "npx"
args:
- "-y"
- "@modelcontextprotocol/server-filesystem"
- "./tests/counting"
tools:
- name: "count_files"
description: "Counts the number of files in a directory"
inputSchema:
type: "object"
properties:
directory:
type: "string"
description: "The directory path to count files in"
required:
- directory
outputSchema:
type: "object"
properties:
count:
type: "number"
description: "The number of files in the directory"
nodes:
# Entry node: Receives tool arguments
- id: "entry"
type: "entry"
next: "list_directory_node"
# List directory contents
- id: "list_directory_node"
type: "mcp"
server: "filesystem"
tool: "list_directory"
args:
path:
expr: "$.entry.directory"
next: "count_files_node"
# Transform and count files
- id: "count_files_node"
type: "transform"
transform:
expr: '{ "count": $count($split($.list_directory_node.content, "\n")) }'
next: "exit"
# Exit node: Returns the count
- id: "exit"
type: "exit"
This graph:
list_directory toollist_directory_node not node1)|) for multi-line JSONata expressionsinputSchema and outputSchema match actual data flowChain multiple MCP tool calls in sequence:
entry -> mcp_node_1 -> mcp_node_2 -> transform -> exit
Use switch nodes to route based on data:
entry -> switch_node -> [path_a | path_b] -> exit
Use switch nodes to loop back to previous nodes:
entry -> increment_node -> check_condition -> [increment_node | exit]
Transform data between nodes using JSONata:
mcp_node -> transform -> next_node