The @gleanwork/mcp-server-tester CLI provides interactive commands to help you get started quickly and generate eval datasets.
- init - Initialize Project
- generate - Generate Eval Dataset
- login - OAuth Authentication
- token - Export Tokens for CI/CD
Create a complete project structure with configuration, tests, and example datasets.
npx mcp-server-tester init [options]-n, --name <name>- Project name-d, --dir <directory>- Target directory (default: ".")-h, --help- Display help
Running init without options starts an interactive setup:
npx mcp-server-tester init
? Project name: my-mcp-tests
? MCP transport type: stdio (local server process)
? Server command (for stdio): node server.js
? Install dependencies now? Yes
✓ Project initialized successfully!
Next steps:
cd my-mcp-tests
npm testThe init command creates:
my-mcp-tests/
├── playwright.config.ts # Playwright config with MCP setup
├── tests/
│ └── mcp.spec.ts # Example test file
├── data/
│ └── example-dataset.json # Sample eval dataset
├── package.json # Dependencies and scripts
└── tsconfig.json # TypeScript configuration
playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
projects: [
{
name: 'mcp-local',
use: {
mcpConfig: {
transport: 'stdio',
command: 'node',
args: ['server.js'],
},
},
},
],
});tests/mcp.spec.ts:
import { test, expect } from '@gleanwork/mcp-server-tester/fixtures/mcp';
test('lists tools', async ({ mcp }) => {
const tools = await mcp.listTools();
expect(tools.length).toBeGreaterThan(0);
});data/example-dataset.json:
{
"name": "example-evals",
"cases": [
{
"id": "example-1",
"toolName": "example_tool",
"args": { "input": "test" }
}
]
}Interactively create eval datasets by connecting to your MCP server and generating test cases.
npx mcp-server-tester generate [options]-c, --config <path>- Path to MCP config JSON file-o, --output <path>- Output dataset path (default: "data/dataset.json")-s, --snapshot- Use Playwright snapshot testing for all cases-h, --help- Display help
Use --snapshot to create datasets that use Playwright's built-in snapshot testing:
npx mcp-server-tester generate --snapshot -o data/snapshot-tests.jsonThis sets expect.snapshot: "<case-id>" for each case. When you run tests:
- First run: Playwright captures snapshots to
__snapshots__/folder - Subsequent runs: Compares responses against captured snapshots
- Update snapshots: Run
npx playwright test --update-snapshotswhen server behavior changes
This is ideal for regression testing - capture known-good responses once, then verify they don't change unexpectedly.
The generate command guides you through creating test cases:
npx mcp-server-tester generate
# Step 1: Connect to MCP server
? MCP transport type: stdio
? Server command: node server.js
✓ Connected to MCP server
✓ Found 3 tools
# Step 2: Select tool and provide arguments
? Select tool to test: get_weather
? Tool arguments (JSON): { "city": "London" }
✓ Tool called successfully
# Step 3: Preview response
Response preview:
{
"city": "London",
"temperature": 20,
"conditions": "Sunny"
}
# Step 4: Auto-suggested expectations
Suggested expectations:
Text contains:
- "London"
- "temperature"
Regex patterns:
- \d+
# Step 5: Configure test case
? Test case ID: weather-london
? Add text contains expectations? Yes
? Add regex expectations? Yes
✓ Added test case "weather-london"
# Step 6: Continue or finish
? Add another test case? No
✓ Dataset saved to data/dataset.jsonThe generator connects to your actual MCP server to:
- List available tools
- Call tools with your arguments
- Show real responses
Based on the response format, the generator suggests:
- Text Contains - Key phrases and values from the response
- Regex Patterns - Format patterns (dates, numbers, etc.)
See the actual tool response before creating expectations:
Response preview:
## Weather Report
**City:** London
**Temperature:** 20°C
**Conditions:** Sunny
**Updated:** 2025-01-22
The generator can append to existing dataset files:
npx mcp-server-tester generate -o data/existing.json
✓ Found existing dataset with 5 cases
? Add new test cases? YesFor complex MCP configurations, use a JSON config file:
mcp-config.json:
{
"transport": "stdio",
"command": "node",
"args": ["server.js"],
"env": {
"NODE_ENV": "test"
}
}Then generate with:
npx mcp-server-tester generate -c mcp-config.jsonThe generated dataset is a JSON file:
{
"name": "generated-dataset",
"cases": [
{
"id": "weather-london",
"toolName": "get_weather",
"args": { "city": "London" },
"expect": {
"containsText": ["London", "temperature"],
"matchesPattern": ["\\d+"]
}
}
]
}- Descriptive IDs - Use clear, unique test case IDs (e.g.,
weather-london,search-auth) - Representative Cases - Generate cases that cover different scenarios
- Review Suggestions - The auto-suggested expectations are starting points; review and refine them
- Version Control - Commit generated datasets to track test evolution
- Organize by Feature - Create separate datasets for different tool categories
# Generate dataset for a weather service
npx mcp-server-tester generate -o data/weather-tests.json
# Test case 1: Sunny day
? Tool: get_weather
? Args: { "city": "London" }
? ID: weather-sunny
✓ Added
# Test case 2: Rainy day
? Add another? Yes
? Tool: get_weather
? Args: { "city": "Seattle" }
? ID: weather-rainy
✓ Added
# Test case 3: Invalid city
? Add another? Yes
? Tool: get_weather
? Args: { "city": "InvalidCity123" }
? ID: weather-invalid
✓ Added
✓ Dataset saved with 3 casesIf the generator can't connect to your MCP server:
✗ Failed to connect to MCP server
Error: Command not found: node server.js
Solutions:
- Verify the command is correct
- Check that the server script exists
- Ensure all dependencies are installed
- Try using absolute paths
If a tool call fails:
✗ Tool call failed
Error: Required parameter 'city' missing
Solutions:
- Check the tool's expected argument schema
- Use valid JSON for arguments
- Review tool documentation
- Test with simpler arguments first
Authenticate with MCP servers that require OAuth. Tokens are cached locally and automatically refreshed when expired.
npx mcp-server-tester login <server-url> [options]<server-url>- (required) The MCP server URL to authenticate with
--force- Force re-authentication even if a valid token exists--state-dir <dir>- Custom directory for token storage--scopes <scopes>- Comma-separated list of scopes to request (default: all from server metadata)-h, --help- Display help
# Authenticate with an MCP server (opens browser for OAuth flow)
npx mcp-server-tester login https://api.example.com/mcp
# Output:
# Authenticating with https://api.example.com/mcp...
# Authentication successful!
# Token expires: 1/15/2025, 3:30:00 PM
# Tokens stored in: ~/.local/state/mcp-tests/api-example-com-mcp/If you need fresh credentials or your tokens are corrupted:
npx mcp-server-tester login https://api.example.com/mcp --force
# Output:
# Clearing existing credentials...
# Authenticating with https://api.example.com/mcp...
# Authentication successful!By default, the CLI requests all scopes advertised by the server's OAuth metadata. To request specific scopes:
npx mcp-server-tester login https://api.example.com/mcp --scopes read,write
# Output:
# Authenticating with https://api.example.com/mcp...
# Authentication successful!
# Scopes: read, write
# Token expires: 1/15/2025, 3:30:00 PMThis is useful when:
- You only need a subset of available scopes
- The server requires explicit scope selection
- You want to test with minimal permissions
Tokens are stored locally in a secure directory:
| Platform | Default Location |
|---|---|
| Linux | $XDG_STATE_HOME/mcp-tests/<server-key>/ or ~/.local/state/mcp-tests/<server-key>/ |
| macOS | ~/.local/state/mcp-tests/<server-key>/ |
| Windows | %LOCALAPPDATA%\mcp-tests\<server-key>\ |
Security:
- Directory permissions:
0700(owner only) - File permissions:
0600(owner read/write only) - Files stored:
tokens.json,client.json,server.json
Use --state-dir to override the storage location:
npx mcp-server-tester login https://api.example.com/mcp --state-dir ./my-tokensFor automated testing in CI, tokens can be provided via environment variables instead of running the interactive login flow.
# Run login locally
npx mcp-server-tester login https://api.example.com/mcp
# Find your tokens
cat ~/.local/state/mcp-tests/<server-key>/tokens.jsonCopy the access_token and refresh_token values to your CI provider's secrets.
GitHub Actions:
# .github/workflows/mcp-tests.yml
jobs:
test:
runs-on: ubuntu-latest
env:
MCP_ACCESS_TOKEN: ${{ secrets.MCP_ACCESS_TOKEN }}
MCP_REFRESH_TOKEN: ${{ secrets.MCP_REFRESH_TOKEN }}
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright testInstead of environment variables, you can inject tokens in your test setup:
// globalSetup.ts
import { injectTokens } from '@gleanwork/mcp-server-tester';
export default async function globalSetup() {
await injectTokens('https://api.example.com/mcp', {
accessToken: process.env.MCP_ACCESS_TOKEN!,
tokenType: 'Bearer',
});
}You can also use the OAuth client directly in code:
import { CLIOAuthClient } from '@gleanwork/mcp-server-tester';
const client = new CLIOAuthClient({
mcpServerUrl: 'https://api.example.com/mcp',
});
// Get a valid access token (cached, refreshed, or new)
const result = await client.getAccessToken();
console.log(`Token: ${result.accessToken}`);
console.log(`Expires: ${new Date(result.expiresAt!).toLocaleString()}`);If the OAuth browser window doesn't open automatically:
- Check the terminal for a URL to open manually
- Ensure you have a default browser configured
- Try running with
--forceto clear any stale state
# Clear and re-authenticate
npx mcp-server-tester login https://api.example.com/mcp --forceEnsure the environment variables are named correctly:
MCP_ACCESS_TOKEN- The access tokenMCP_REFRESH_TOKEN- The refresh token (optional, for token refresh)
Export stored OAuth tokens in formats suitable for CI/CD environments like GitHub Actions.
npx mcp-server-tester token <server-url> [options]<server-url>- (required) The MCP server URL to get tokens for
-f, --format <format>- Output format:env,json, orgh(default:env)--state-dir <dir>- Custom directory for token storage-h, --help- Display help
Outputs tokens as shell-compatible environment variable assignments:
npx mcp-server-tester token https://api.example.com/mcp
# Output:
MCP_ACCESS_TOKEN=eyJhbGciOiJSUzI1NiIs...
MCP_REFRESH_TOKEN=dGhpcyBpcyBhIHJlZnJl...
MCP_TOKEN_TYPE=Bearer
MCP_TOKEN_EXPIRES_AT=1736956200000Use with eval to set environment variables:
eval $(npx mcp-server-tester token https://api.example.com/mcp)Outputs tokens as a JSON object:
npx mcp-server-tester token https://api.example.com/mcp --format json
# Output:
{
"MCP_ACCESS_TOKEN": "eyJhbGciOiJSUzI1NiIs...",
"MCP_REFRESH_TOKEN": "dGhpcyBpcyBhIHJlZnJl...",
"MCP_TOKEN_TYPE": "Bearer",
"MCP_TOKEN_EXPIRES_AT": 1736956200000
}Outputs ready-to-paste GitHub CLI commands for setting repository secrets:
npx mcp-server-tester token https://api.example.com/mcp --format gh
# Output:
# Run these commands to set GitHub Actions secrets:
gh secret set MCP_ACCESS_TOKEN --body "eyJhbGciOiJSUzI1NiIs..."
gh secret set MCP_REFRESH_TOKEN --body "dGhpcyBpcyBhIHJlZnJl..."
gh secret set MCP_TOKEN_TYPE --body "Bearer"
gh secret set MCP_TOKEN_EXPIRES_AT --body "1736956200000"-
Authenticate locally:
npx mcp-server-tester login https://api.example.com/mcp
-
Export tokens for GitHub:
npx mcp-server-tester token https://api.example.com/mcp --format gh
-
Run the output commands (or copy/paste each secret manually):
gh secret set MCP_ACCESS_TOKEN --body "..." gh secret set MCP_REFRESH_TOKEN --body "..." gh secret set MCP_TOKEN_TYPE --body "Bearer" gh secret set MCP_TOKEN_EXPIRES_AT --body "..."
-
Configure your workflow:
# .github/workflows/mcp-tests.yml jobs: test: runs-on: ubuntu-latest env: MCP_ACCESS_TOKEN: ${{ secrets.MCP_ACCESS_TOKEN }} MCP_REFRESH_TOKEN: ${{ secrets.MCP_REFRESH_TOKEN }} MCP_TOKEN_TYPE: ${{ secrets.MCP_TOKEN_TYPE }} MCP_TOKEN_EXPIRES_AT: ${{ secrets.MCP_TOKEN_EXPIRES_AT }} steps: - uses: actions/checkout@v4 - run: npm ci - run: npx playwright test
If no tokens are found for the specified server:
npx mcp-server-tester token https://api.example.com/mcp
# Output (to stderr):
# No tokens found for https://api.example.com/mcp
#
# Expected location: ~/.local/state/mcp-tests/api.example.com_mcp/tokens.json
#
# Run 'mcp-server-tester login https://api.example.com/mcp' to authenticate first.- See the Quick Start Guide for using generated datasets
- Check the Expectations Guide for customizing validations
- Explore Examples for real-world dataset patterns