Skip to main content
Glama
design.md9.4 kB
# mcpGraph Design Document ## Overview This document memorializes the high-level design and tooling recommendations for mcpGraph, a product similar to n8n that surfaces an MCP interface and internally implements a directed graph of MCP server calls. The system enables filtering and reformatting data between nodes, makes routing decisions based on node output, and maintains a declarative, observable configuration without embedding a full programming language. ## Core Architecture: The Orchestrator ### Recommended Platform: TypeScript (Node.js) **Rationale:** - The MCP SDK is most mature in TypeScript - Frontend tools for visual graph editing (like React Flow) are industry standard - Strong ecosystem for both backend orchestration and frontend visualization ### Graph Execution Engine: Flowcraft **Flowcraft** is the recommended graph execution engine for orchestrating the directed graph of MCP server calls. **Why Flowcraft:** - **Workflow-Focused**: Designed specifically for workflow orchestration (similar to n8n/Zapier), making it a natural fit for tool-call-based nodes - **Control Flow**: Built-in support for conditionals (if/switch), loops, and parallelism - **Data Flow**: Designed to handle data transformation and flow between nodes, with built-in support for modifying node inputs/outputs - **Lightweight**: Dependency-free and focused on workflow execution - **Static Analysis**: Provides tools to analyze workflows, detect cycles, and catch errors before execution - **Programmatic API**: Can be used programmatically to build workflows from custom YAML configurations **Implementation Approach:** The system will define its own custom YAML format for graph definitions. The YAML will be parsed into a graph structure, which will then be used to programmatically construct Flowcraft workflows. This allows full control over the YAML schema while leveraging Flowcraft's execution engine for running the graph. ### MCP Integration - Use `@modelcontextprotocol/sdk` - The system exposes an MCP server interface - The YAML configuration defines the MCP server metadata and the tools it exposes - Each tool definition includes standard MCP tool metadata (name, description, input/output parameters) - Each tool's graph has an explicit entry node that receives tool arguments and initializes execution - Each tool's graph has an explicit exit node that returns the final result to the MCP tool caller - Execution flows through the graph from entry node to exit node ## Declarative Logic & Data Transformation To avoid embedding a full programming language while maintaining declarative, observable configurations, the system uses standardized expression engines. ### Data Reformatting: JSONata **Why JSONata:** - Declarative query and transformation language for JSON - Single string expression enables clear observability - Can log input, expression, and output to debug transformations **Resources:** [JSONata Documentation](https://jsonata.org/) **YAML Example:** ```yaml transform: expr: "$merge([payload, {'timestamp': $now()}])" ``` ### Routing Decisions: JSON Logic **Why JSON Logic:** - Allows complex rules (e.g., "if price > 100 and status == 'active'") as pure JSON objects - Declarative and observable - No embedded code execution **Resources:** [JSON Logic Documentation](https://jsonlogic.com/) **YAML Example:** ```yaml condition: and: - ">": [{ var: "price" }, 100] - "==": [{ var: "status" }, "active"] ``` ## High-Level Design: The Graph Runner The system exposes an MCP server that reads a YAML configuration file. When a tool is called on this MCP server, it executes the corresponding graph starting at the tool's entry node and continuing until the exit node is reached. ### The Workflow Lifecycle 1. **Parse**: Read the YAML configuration into a structure containing MCP server metadata, tool definitions, and the directed graph of nodes 2. **Initialize MCP Server**: Expose the MCP server with the tools defined in the configuration 3. **Tool Invocation**: When a tool is called: - Receive tool arguments from the MCP client - Start graph execution at the tool's entry node - Entry node receives tool arguments and initializes the execution context 4. **Execute Node**: - **Entry Node**: Receives tool arguments, initializes execution context, passes to next node - **Pre-transform**: Apply JSONata to the incoming data to format the tool arguments (if node is an MCP tool call) - **Call Tool**: Use the MCP SDK to `callTool` on the target server (if node is an MCP tool call) - **Post-transform**: Reformat the tool's output for the next step (if node is an MCP tool call) - **Route**: Evaluate json-logic against the current data state to decide which edge to follow next (if node is a switch/conditional) - **Observe**: Emit an event to the UI with the node_id, input_data, and output_data 5. **Exit Node**: When execution reaches the exit node, extract the final result and return it to the MCP tool caller ## Visual Tooling & Observability ### Component Recommendations | Component | Tooling Recommendation | |-----------|----------------------| | **Visual Editor** | **React Flow** - Industry standard for node-based UIs, used by companies like Stripe and Typeform. Provides customizable nodes, edges, zooming, panning, and built-in components like MiniMap and Controls. [React Flow Documentation](https://reactflow.dev/) | | **Observability** | OpenTelemetry - wrap each node execution in a "Span" to see the "Trace" of data through the graph in tools like Jaeger | ## Implementation Strategy: The YAML Standard Graph definitions should feel like Kubernetes manifests or GitHub Actions - declarative and version-controlled. ### Configuration Structure The YAML configuration centers around MCP server and tool definitions: 1. **MCP Server Metadata**: Defines the MCP server information (name, version, description) 2. **Tools**: Array of tool definitions, each containing: - Standard MCP tool metadata (name, description) - Input parameters schema (MCP tool parameter definitions) - Output schema (what the tool returns) - `entryNode`: The entry node ID where graph execution begins when this tool is called - `exitNode`: The exit node ID that returns the final result 3. **Nodes**: The directed graph of nodes that execute when tools are called. Node types include: - **`entry`**: Entry point for a tool's graph execution. Receives tool arguments and initializes execution context. - **`mcp_tool`**: Calls an MCP tool on an internal or external MCP server using `callTool` - **`transform`**: Applies JSONata expressions to transform data between nodes - **`switch`**: Uses JSON Logic to conditionally route to different nodes based on data - **`exit`**: Exit point for a tool's graph execution. Extracts and returns the final result to the MCP tool caller ### Example YAML Structure: count_files Tool This example defines a `count_files` tool that takes a directory, lists its contents using the filesystem MCP server, counts the files, and returns the count: ```yaml version: "1.0" # MCP Server Metadata server: name: "mcpGraph" version: "1.0.0" description: "MCP server that executes directed graphs of MCP tool calls" # Tool Definitions 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" entryNode: "entry_count_files" exitNode: "exit_count_files" # Graph Nodes nodes: # Entry node: Receives tool arguments - id: "entry_count_files" type: "entry" next: "list_directory_node" # List directory contents - id: "list_directory_node" type: "mcp_tool" server: "filesystem" tool: "list_directory" args: path: "$.input.directory" # JSONata reference to tool input next: "count_files_node" # Transform and count files - id: "count_files_node" type: "transform" transform: expr: | { "count": $count($split(list_directory_node, "\n")) } next: "exit_count_files" # Exit node: Returns the count - id: "exit_count_files" type: "exit" ``` ## Key Design Principles 1. **Declarative Configuration**: All logic expressed in YAML using standard expression languages (JSONata, JSON Logic) 2. **Observability**: Every transformation and decision is traceable and loggable 3. **No Embedded Code**: Avoid full programming languages to maintain clarity and safety 4. **Standard-Based**: Favor existing standards (JSONata, JSON Logic) over custom solutions 5. **Visual First**: Graph should be viewable and editable through a visual interface 6. **Execution Transparency**: Ability to observe graph execution in real-time ## System Components 1. **Executable**: Exposes an MCP server to run the graph 2. **Visual Editor**: Tools to visually view and edit the graph 3. **Execution Observer**: Ability to observe the graph as it executes 4. **Graph Runner**: Core orchestration engine that executes the directed graph (supports cycles for loops and retries)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TeamSparkAI/mcpGraph'

If you have feedback or need assistance with the MCP directory API, please join our Discord server