Programmatic API
Use MCP Jest programmatically in your Node.js applications and build custom testing workflows.
Installation
npm install mcp-jest
Basic Usage
import { mcpTest } from 'mcp-jest';
const config = {
name: 'My Test Suite',
server: {
command: 'node',
args: ['my-server.js']
},
tests: [
{
name: 'Test greeting',
type: 'tool',
tool: 'greet',
arguments: { name: 'World' },
expect: {
content: [
{
type: 'text',
text: 'Hello, World!'
}
]
}
}
]
};
// Run tests
const results = await mcpTest(config);
if (results.success) {
console.log('All tests passed!');
} else {
console.error('Tests failed:', results.failures);
process.exit(1);
}
Core API
mcpTest(config, options?)
Main function to run MCP tests:
interface mcpTest {
(config: MCPTestConfig, options?: TestOptions): Promise<TestResults>
}
interface TestOptions {
timeout?: number // Global timeout override
verbose?: boolean // Enable verbose output
bail?: boolean // Stop on first failure
updateSnapshots?: boolean // Update snapshots
grep?: string // Filter tests by pattern
parallel?: boolean // Run tests in parallel
maxWorkers?: number // Number of workers
reporter?: string // Reporter type
outputFile?: string // Output file path
}
interface TestResults {
success: boolean // Overall success
stats: TestStats // Test statistics
results: TestResult[] // Individual test results
failures: TestFailure[] // Failed tests
snapshots?: SnapshotResults
coverage?: CoverageResults
duration: number // Total time in ms
}
Test Results
interface TestStats {
total: number // Total tests
passed: number // Passed tests
failed: number // Failed tests
skipped: number // Skipped tests
pending: number // Pending tests
}
interface TestResult {
name: string // Test name
status: 'passed' | 'failed' | 'skipped' | 'pending'
duration: number // Test duration in ms
error?: TestError // Error if failed
output?: any // Test output
snapshot?: boolean // Has snapshot
}
interface TestFailure {
name: string // Test name
error: TestError // Error details
duration: number // Test duration
output?: any // Actual output
expected?: any // Expected output
}
interface TestError {
message: string // Error message
stack?: string // Stack trace
code?: string // Error code
details?: any // Additional details
}
Advanced Usage
Custom Test Runner
import { MCPTestRunner, MCPTestClient } from 'mcp-jest';
// Create custom test runner
const runner = new MCPTestRunner({
timeout: 30000,
retries: 2,
parallel: true,
maxWorkers: 4
});
// Add custom hooks
runner.beforeAll(async () => {
console.log('Setting up test environment...');
});
runner.afterAll(async () => {
console.log('Cleaning up test environment...');
});
runner.beforeEach(async (test) => {
console.log(`Running test: ${test.name}`);
});
runner.afterEach(async (test, result) => {
console.log(`Test ${test.name} ${result.status}`);
});
// Run tests
const results = await runner.run(config);
Direct Server Communication
import { MCPTestClient } from 'mcp-jest';
// Create client
const client = new MCPTestClient({
command: 'node',
args: ['my-server.js'],
timeout: 10000
});
try {
// Start server
await client.connect();
// Test capabilities
const capabilities = await client.getCapabilities();
console.log('Server capabilities:', capabilities);
// List tools
const tools = await client.listTools();
console.log('Available tools:', tools);
// Call tool
const result = await client.callTool('greet', { name: 'Alice' });
console.log('Tool result:', result);
// List resources
const resources = await client.listResources();
console.log('Available resources:', resources);
// Read resource
const content = await client.readResource('file://config.json');
console.log('Resource content:', content);
} finally {
// Clean up
await client.disconnect();
}
Snapshot Testing API
import { SnapshotManager } from 'mcp-jest';
// Create snapshot manager
const snapshots = new SnapshotManager({
snapshotDir: '__snapshots__',
updateSnapshots: false,
prettify: true
});
// Test with snapshot
const testResult = await client.callTool('generate-report', {
type: 'monthly'
});
// Compare with snapshot
const snapshotResult = await snapshots.compare(
'monthly-report-test',
testResult,
{
exclude: ['generatedAt', 'reportId'],
replacements: [
{
pattern: '\\d{4}-\\d{2}-\\d{2}',
replacement: 'DATE'
}
]
}
);
if (!snapshotResult.matches) {
console.log('Snapshot mismatch!');
console.log('Diff:', snapshotResult.diff);
}
Custom Matchers
import { addMatcher } from 'mcp-jest';
// Add custom email matcher
addMatcher('email', (value: any) => {
if (typeof value !== 'string') {
return { matches: false, message: 'Value must be a string' };
}
const emailRegex = /^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$/;
const matches = emailRegex.test(value);
return {
matches,
message: matches ? 'Valid email' : 'Invalid email format'
};
});
// Use in tests
const config = {
name: 'Email validation test',
server: { ... },
tests: [
{
name: 'Should return valid email',
type: 'tool',
tool: 'get-user-email',
expect: {
email: { matcher: 'email' }
}
}
]
};
Plugin Development
// Create a custom plugin
class PerformancePlugin {
constructor(config) {
this.thresholds = config.thresholds || {};
}
// Plugin hooks
beforeTest(test) {
this.startTime = Date.now();
}
afterTest(test, result) {
const duration = Date.now() - this.startTime;
const threshold = this.thresholds[test.name] || 1000;
if (duration > threshold) {
console.warn(
`⚠️ Test "${test.name}" took ${duration}ms (threshold: ${threshold}ms)`
);
}
}
// Result processing
processResults(results) {
const slowTests = results.results.filter(
result => result.duration > 1000
);
if (slowTests.length > 0) {
console.log(`🐌 ${slowTests.length} slow tests detected`);
}
}
}
// Register plugin
import { registerPlugin } from 'mcp-jest';
registerPlugin('performance', PerformancePlugin);
// Use plugin in config
const config = {
plugins: [
{
name: 'performance',
config: {
thresholds: {
'slow-operation': 5000,
'fast-operation': 100
}
}
}
],
// ... rest of config
};
Integration Examples
Express.js Middleware
import express from 'express';
import { mcpTest } from 'mcp-jest';
const app = express();
app.get('/test', async (req, res) => {
try {
const results = await mcpTest({
name: 'Health Check',
server: {
command: 'node',
args: ['server.js']
},
tests: [
{
name: 'Server health',
type: 'capabilities'
}
]
});
res.json({
healthy: results.success,
stats: results.stats,
timestamp: new Date().toISOString()
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
GitHub Actions Integration
// test-action.js
import { mcpTest } from 'mcp-jest';
import { setFailed, setOutput } from '@actions/core';
async function main() {
try {
const results = await mcpTest({
name: 'CI Test Suite',
server: {
command: process.env.SERVER_COMMAND,
args: JSON.parse(process.env.SERVER_ARGS || '[]')
},
tests: JSON.parse(process.env.TEST_CONFIG)
}, {
reporter: 'junit',
outputFile: 'test-results.xml',
bail: true
});
setOutput('test-results', JSON.stringify(results.stats));
if (!results.success) {
setFailed(`${results.stats.failed} tests failed`);
}
} catch (error) {
setFailed(error.message);
}
}
main();
🔧 Programmatic Power
The programmatic API gives you full control over MCP Jest. Build custom workflows, integrate with CI/CD, or create specialized testing tools.
Learn CI/CD Integration →