JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q64088F
  • License MIT

A Node.js testing library for Model Context Protocol (MCP) servers

Package Exports

  • mcp-conductor
  • mcp-conductor/src/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (mcp-conductor) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

MCP Conductor

A comprehensive Node.js testing library for Model Context Protocol (MCP) servers

Node.js License: MIT

MCP Conductor provides both YAML-based declarative testing and programmatic testing for MCP servers with advanced pattern matching capabilities.

๐Ÿ“– Documentation

๐Ÿ“š Complete Documentation

โšก Quick Start

# Install globally
npm install -g mcp-conductor

# Initialize in your MCP project
npx mcp-conductor init

# The init command creates:
# - conductor.config.json (configured from package.json)
# - test/mcp/ or tests/mcp/ directory (based on existing project structure)
# - AGENTS.md (AI agent guide) in the test directory
# - Installs mcp-conductor as a dev dependency

# Customize your config (optional)
# Edit conductor.config.json to match your server setup

# Write your first test
cat > tests/mcp/my-server.test.mcp.yml << 'EOF'  # or test/mcp/ depending on your project
description: "Basic test"
tests:
  - it: "should list tools"
    request:
      jsonrpc: "2.0"
      id: "1"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "1"
        result:
          tools: "match:type:array"
EOF

# Run tests (after init, you can use npx or npm script)
npx mcp-conductor "test*/mcp/**/*.test.mcp.yml"  # Matches both test/ and tests/

# Or add to package.json scripts:
# "scripts": { "test:mcp": "mcp-conductor \"./test*/mcp/**/*.test.mcp.yml\"" }
# Then run: npm run test:mcp

Manual Setup (Alternative)

# Create config manually
echo '{"name":"My Server","command":"node","args":["./server.js"]}' > conductor.config.json

# Write test
cat > test.yml << 'EOF'
description: "Basic test"
tests:
  - it: "should list tools"
    request:
      jsonrpc: "2.0"
      id: "1"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "1"
        result:
          tools: "match:type:array"
EOF

# Run test
conductor test.yml --config conductor.config.json

โœจ Key Features

  • ๐ŸŽฏ Declarative YAML Testing - Simple, readable test definitions
  • ๐Ÿ’ป Programmatic API - JavaScript/TypeScript integration with any test framework
  • ๐Ÿ”„ Automatic MCP Protocol - Handles handshakes and JSON-RPC messaging
  • ๐Ÿงช Advanced Pattern Matching - 11+ verified pattern types with robust validation
  • ๐Ÿ“Š Rich Reporting - Detailed diffs and colored output
  • ๐Ÿ›ก๏ธ Robust Communication - Reliable stdio transport handling

๐Ÿ“– Documentation

๐Ÿ“š Complete Documentation

๐Ÿš€ Testing Approaches

YAML Declarative Testing

description: "Calculator tests"
tests:
  - it: "should add numbers"
    request:
      jsonrpc: "2.0"
      id: "calc-1"
      method: "tools/call"
      params:
        name: "calculator"
        arguments: { a: 15, b: 27 }
    expect:
      response:
        jsonrpc: "2.0"
        id: "calc-1"
        result:
          content:
            - type: "text"
              text: "match:Result: \\d+"

Programmatic Testing

import { test, before, after, assert } from 'node:test';
import { connect } from 'mcp-conductor';

let client;
before(async () => { 
  client = await connect('./conductor.config.json'); 
});
after(async () => { 
  await client?.disconnect(); 
});

test('should list available tools', async () => {
  const tools = await client.listTools();
  assert.ok(Array.isArray(tools));
  assert.ok(tools.length > 0);
  
  // Verify tool structure
  tools.forEach(tool => {
    assert.ok(tool.name, 'Tool should have name');
    assert.ok(tool.description, 'Tool should have description');
    assert.ok(tool.inputSchema, 'Tool should have input schema');
  });
});

test('should execute calculator tool', async () => {
  const result = await client.callTool('calculator', { 
    operation: 'add', a: 15, b: 27 
  });
  
  assert.equal(result.isError, false);
  assert.equal(result.content[0].type, 'text');
  assert.equal(result.content[0].text, 'Result: 42');
});

test('should handle tool errors gracefully', async () => {
  try {
    await client.callTool('nonexistent_tool', {});
    assert.fail('Should have thrown an error');
  } catch (error) {
    assert.ok(error.message.includes('Failed to call tool'));
  }
});

๐Ÿƒโ€โ™‚๏ธ Running Tests

# YAML tests with various options
conductor "tests/**/*.test.mcp.yml" --config config.json

# Verbose output with test hierarchy
conductor "tests/*.yml" --config config.json --verbose

# Debug mode with detailed MCP communication
conductor "tests/*.yml" --config config.json --debug

# Timing information for performance analysis
conductor "tests/*.yml" --config config.json --timing

# JSON output for CI/automation systems  
conductor "tests/*.yml" --config config.json --json

# Quiet mode (minimal output)
conductor "tests/*.yml" --config config.json --quiet

# Combine multiple options
conductor "tests/*.yml" --config config.json --verbose --timing --debug

# Programmatic tests  
node --test tests/**/*.programmatic.test.js

# Example tests (included)
npm run test:examples

๐Ÿค Contributing

Contributions welcome! See our Contributing Guide for details.

# Development setup
git clone https://github.com/taurgis/mcp-conductor.git
cd mcp-conductor
npm install

# Run all tests
npm test

๐Ÿ“œ License

MIT License - see LICENSE file for details.


๐Ÿ“š View Complete Documentation | ๐Ÿ› Report Issues | โญ Star on GitHub