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
MCP Conductor provides both YAML-based declarative testing and programmatic testing for MCP servers with advanced pattern matching capabilities.
๐ Documentation
- ๐ Installation
- โก Quick Start Guide
- ๐ YAML Testing
- ๐ป Programmatic Testing
- ๐ Pattern Matching
- ๐๏ธ Examples
- ๐ ๏ธ API Reference
- ๐ง Troubleshooting
โก 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
- ๐ Installation
- โก Quick Start Guide
- ๐ YAML Testing
- ๐ป Programmatic Testing
- ๐ Pattern Matching
- ๐๏ธ Examples
- ๐ ๏ธ API Reference
- ๐ง Troubleshooting
๐ 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