npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@vibeflowapp/mcp-node-editor

v0.1.0

Published

MCP server for VibeFlow node parameter and content management

Readme

VibeFlow NodeEditor MCP Server

MCP server for managing node parameters, code, content, and pin data.

Features

Tools (16 total)

Parameter Management:

  • get_node_parameters - Get parameters with defaults and schema
  • update_node_parameter - Update single parameter (supports nested paths)
  • update_node_parameters - Update multiple parameters
  • reset_parameter_to_default - Reset parameter to default value
  • get_parameter_schema - Get schema for a parameter
  • validate_node - Validate node parameters

Code & Content:

  • get_node_code - Get JavaScript code (Code nodes)
  • update_node_code - Update JavaScript code
  • get_node_content - Get content (StickyNote nodes)
  • update_node_content - Update content

Pin Data:

  • pin_node_data - Pin output data to workflow
  • unpin_node_data - Remove pinned data
  • get_pinned_data - Get pinned data

Expression Evaluation:

  • evaluate_expression - Evaluate n8n expressions like {{ $json.field }}
  • validate_expression - Validate expression syntax
  • suggest_completions - Get autocomplete suggestions

Resources

  • vibeflow://node-defaults/{nodeType} - Node defaults and schema from Core API

Prompts (4 total)

  • update_code_node - Update code with natural language description
  • set_node_parameter - Set a specific parameter
  • validate_workflow_nodes - Validate all nodes in workflow
  • create_test_data - Generate and pin test data

Installation

cd /Users/ultra/xp/vibeflow/packages/mcp/node-editor
bun install
bun run build

Usage

As MCP Server (STDIO)

Development:

bun run dev

Production:

node build/index.js

Environment Variables

export CONFIG_API_URL=http://localhost:7575
export CORE_API_URL=http://localhost:7576

Claude Desktop Configuration

{
  "mcpServers": {
    "vibeflow-node-editor": {
      "command": "bun",
      "args": [
        "run",
        "/Users/ultra/xp/vibeflow/packages/mcp/node-editor/src/index.ts"
      ],
      "env": {
        "CONFIG_API_URL": "http://localhost:7575",
        "CORE_API_URL": "http://localhost:7576"
      }
    }
  }
}

Examples

Parameter Management

Get all parameters:

await callTool('get_node_parameters', {
  workflowId: 'workflow-123',
  nodeId: 'node-456'
});
// Returns: { parameters, defaults, properties }

Update single parameter:

await callTool('update_node_parameter', {
  workflowId: 'workflow-123',
  nodeId: 'node-456',
  path: 'mode',
  value: 'runOnceForAllItems'
});

Update nested parameter:

await callTool('update_node_parameter', {
  workflowId: 'workflow-123',
  nodeId: 'node-456',
  path: 'options.timeout',
  value: 30000
});

Reset to default:

await callTool('reset_parameter_to_default', {
  workflowId: 'workflow-123',
  nodeId: 'node-456',
  path: 'mode'
});

Code Management

Update code node:

await callTool('update_node_code', {
  workflowId: 'workflow-123',
  nodeId: 'code-node',
  jsCode: `
return items.map(item => ({
  json: {
    ...item.json,
    processed: true,
    timestamp: new Date().toISOString()
  }
}));
  `
});

Using prompt:

Use the "update_code_node" prompt to make the code node transform items by adding a "processed" field

Content Management

Update StickyNote:

await callTool('update_node_content', {
  workflowId: 'workflow-123',
  nodeId: 'sticky-note',
  content: `
# Important Note

This workflow processes user data:
1. Validates input
2. Enriches with external API
3. Stores in database

**TODO:** Add error handling
  `
});

Pin Data

Pin test data:

await callTool('pin_node_data', {
  workflowId: 'workflow-123',
  nodeId: 'webhook-node',
  data: [[{
    json: {
      userId: 1,
      name: 'Test User',
      email: '[email protected]'
    }
  }]]
});

Get pinned data:

await callTool('get_pinned_data', {
  workflowId: 'workflow-123'
});
// Returns all pinned data

await callTool('get_pinned_data', {
  workflowId: 'workflow-123',
  nodeId: 'webhook-node'
});
// Returns data for specific node

Expression Evaluation

Evaluate expression:

await callTool('evaluate_expression', {
  expression: '{{ $json.price * $json.quantity }}',
  context: {
    json: { price: 100, quantity: 3 }
  }
});
// Returns: { result: 300 }

Validate expression:

await callTool('validate_expression', {
  expression: '{{ $json.field }}'
});
// Returns: { valid: true }

await callTool('validate_expression', {
  expression: '{{ $json. }}'
});
// Returns: { valid: false, error: '...' }

Get suggestions:

await callTool('suggest_completions', {
  partialExpression: '$json.',
  context: {
    json: { name: 'John', age: 30 }
  }
});
// Returns: [{ label: '$json.name', ... }, { label: '$json.age', ... }]

Validation

Validate node:

await callTool('validate_node', {
  workflowId: 'workflow-123',
  nodeId: 'node-456'
});
// Returns: {
//   valid: false,
//   errors: [{ path: 'jsCode', message: 'JavaScript Code is required', severity: 'error' }],
//   warnings: []
// }

Architecture

NodeEditor MCP Server
├── ParameterManager
│   ├── get/update/validate parameters
│   ├── reset to defaults
│   └── get schema
├── NodeManager
│   ├── code management (jsCode)
│   ├── content management (StickyNote)
│   └── pin data operations
└── ExpressionEvaluator
    ├── evaluate expressions
    ├── validate syntax
    └── suggest completions

Testing

# Run all tests
bun test

# Run with watch mode
bun test --watch

# Run specific test file
bun test tests/ParameterManager.test.ts

Test Coverage

  • ParameterManager: 7 tests
    • get/update/validate parameters
    • schema retrieval
    • reset to default
  • NodeManager: 8 tests
    • code/content get/update
    • pin/unpin/get pin data
  • ExpressionEvaluator: 18 tests
    • evaluate (plain, $json, $node, operations, nested)
    • validate (correct, unbalanced, syntax errors)
    • suggest completions
    • edge cases

Total: 33 tests, all passing ✅

Development

Adding a new parameter type

1. Add to ParameterManager:

// src/ParameterManager.ts
private validatePropertyType(property: NodeProperty, value: any): string | null {
  switch (type) {
    // ... existing cases
    case 'myNewType':
      if (!isValidMyNewType(value)) {
        return `Invalid myNewType value`;
      }
      break;
  }
}

2. Add tests:

// tests/ParameterManager.test.ts
test('should validate myNewType', async () => {
  // Test validation logic
});

3. Update schema mapping:

private mapPropertyTypeToJsonSchema(type: string): string {
  const typeMap: Record<string, string> = {
    // ... existing mappings
    myNewType: 'string',
  };
}

Adding expression functions

1. Extend ExpressionEvaluator:

// src/ExpressionEvaluator.ts
private buildEvalContext(context: EvaluationContext): Record<string, any> {
  return {
    $json: context.json || {},
    $node: this.buildNodeAccessor(...),
    // Add new function
    $myFunction: (arg: any) => {
      // Implementation
    },
  };
}

2. Add tests:

// tests/ExpressionEvaluator.test.ts
test('should evaluate $myFunction', () => {
  const result = evaluator.evaluate('{{ $myFunction("test") }}', {});
  expect(result.result).toBe(expected);
});

Best Practices

Parameter Updates

  1. Use nested paths for deep updates:

    // Good
    update_node_parameter(workflowId, nodeId, 'options.timeout', 5000)
    
    // Avoid
    get_node_parameters() → modify → update_node_parameters()
  2. Validate before update:

    const validation = await validate_node(workflowId, nodeId);
    if (!validation.valid) {
      // Handle errors
    }
  3. Use schema to understand parameters:

    const schema = await get_parameter_schema(nodeType, 'mode');
    // Check schema.enum for valid values

Code Updates

  1. Always return n8n format:

    // Correct
    return items.map(item => ({ json: {...} }));
    
    // Wrong
    return {...}; // Missing n8n wrapper
  2. Handle errors gracefully:

    try {
      // Code logic
    } catch (error) {
      return [{
        json: { error: error.message },
        pairedItem: { item: 0 }
      }];
    }
  3. Use expressions for dynamic values:

    const apiUrl = '{{ $json.endpoint }}'; // Will be evaluated

Pin Data

  1. Use for testing - pin data to skip API calls during development
  2. Format correctly - always use [[{ json: {...} }]] format
  3. Clean up - unpin when no longer needed

Troubleshooting

Common Issues

1. "Parameter not found in schema"

  • Check parameter path (case-sensitive)
  • Verify node type supports this parameter
  • Use get_parameter_schema to see available parameters

2. "Expression evaluation failed"

  • Validate syntax first: validate_expression
  • Check context has required data ($json, $node)
  • Use suggestions: suggest_completions

3. "Type mismatch"

  • Check parameter schema type
  • Use get_parameter_schema to see expected type
  • Convert value to correct type

4. "Node validation errors"

  • Required parameters missing
  • Use validate_node to see all errors
  • Fix errors one by one

Roadmap

  • [ ] Support for more parameter types (fixedCollection, etc.)
  • [ ] Advanced expression functions ($datetime, $json.parse, etc.)
  • [ ] Bulk parameter updates across multiple nodes
  • [ ] Parameter templates/presets
  • [ ] Expression macros

See Also