Local Development Workflow
Bellwether is designed to integrate seamlessly into your local MCP server development workflow. Test your server during development, catch behavioral drift before deployment, and maintain documentation as your server evolves.
Why Test Locally?
| Approach | Pros | Cons |
|---|---|---|
| Test locally | Catch drift before deployment, faster iteration, no deployment costs | Requires local setup |
| Wait for production | Always tests "real" environment | Drift reaches production first, slower feedback |
Testing locally allows you to:
- Shift-left testing - Catch behavioral regressions before they're deployed
- Fast iteration - No waiting for deployments between tests
- CI/CD integration - Gate deployments on drift detection
- Free testing - Use check mode or Ollama for completely free testing
Quick Start
# 1. Initialize configuration
bellwether init "node ./src/mcp-server.js"
# 2. Run test
bellwether check
# 3. Save baseline
bellwether baseline save
# 4. Watch for changes (uses watch settings from bellwether.yaml)
bellwether watch
Running Against Local Servers
Stdio Transport (Default)
The most common way to test locally is using stdio transport, where Bellwether spawns your server as a subprocess:
# Node.js server
bellwether init "node ./src/mcp-server.js"
bellwether check
# Python server
bellwether init "python ./mcp_server.py"
bellwether check
# TypeScript (via ts-node or tsx)
bellwether init "npx tsx ./src/server.ts"
bellwether check
# Any executable
bellwether init "./my-server-binary --config ./config.json"
bellwether check
Bellwether communicates with your server via stdin/stdout using JSON-RPC 2.0.
Localhost HTTP Servers
If your server runs as an HTTP service locally, configure the server transport in bellwether.yaml:
server:
transport: sse
url: http://localhost:3000/mcp
Or for streamable HTTP:
server:
transport: streamable-http
url: http://localhost:8000/mcp
# sessionId: "server-issued-session-id"
# headers:
# Authorization: "Bearer ${MCP_SERVER_TOKEN}"
Development Workflow
1. Initialize Configuration
First, create your configuration file:
# Default check mode (free, fast)
bellwether init "node ./src/mcp-server.js"
# Or explore mode with Ollama (free)
bellwether init --preset local "node ./src/mcp-server.js"
2. Create Initial Baseline
After your server is working, create a baseline to track future changes:
# Run test first
bellwether check
# Save baseline
bellwether baseline save
This saves bellwether-baseline.json with:
- Tool signatures and schemas
- Observed behavior documentation
- Security findings
- Performance metrics
3. Develop with Watch Mode
Run watch mode in a terminal while developing:
bellwether watch
Configure watch settings in bellwether.yaml:
watch:
path: "./src"
interval: 5000
extensions: [".ts", ".js", ".json"]
Watch mode:
- Runs an initial test on startup
- Monitors
./srcfor file changes - Re-tests when files change
- Shows diffs from previous test
Example output:
[watch] Initial test starting...
[watch] Test complete. Watching ./src for changes...
[watch] File changed: src/tools/read.ts
[watch] Re-running test...
Changes detected:
+ read_file now handles symlinks
~ error message format changed for ENOENT
[watch] Test complete. Watching for changes...
4. Compare Against Baseline
Before committing, verify your changes against the baseline:
bellwether check
bellwether baseline compare ./bellwether-baseline.json
This shows:
- Breaking changes - Schema changes, removed tools
- Warnings - Behavioral changes to investigate
- Info - Documentation-only changes
5. Update Baseline for Intentional Changes
When changes are intentional (new features, bug fixes):
# Review the changes
bellwether check
bellwether baseline compare ./bellwether-baseline.json
# Update baseline if changes are correct
bellwether baseline save --force
# Commit updated baseline and generated contract docs
git add .bellwether/bellwether-baseline.json CONTRACT.md
git commit -m "Update baseline: added symlink support"
Using Ollama for Free Local Testing
For completely free LLM-powered testing during development, use Ollama:
# Install Ollama (macOS)
brew install ollama
# Start Ollama server
ollama serve
# Pull a model
ollama pull qwen3:8b
# Initialize with local preset
bellwether init --preset local "node ./src/mcp-server.js"
# Run test (free!)
bellwether check
The generated bellwether.yaml will be configured for Ollama:
llm:
provider: ollama
model: "" # Uses qwen3:8b by default
ollama:
baseUrl: "http://localhost:11434"
Custom Test Scenarios
For deterministic testing without LLM costs, define custom scenarios in bellwether-tests.yaml:
version: "1"
description: Custom test scenarios
scenarios:
- tool: read_file
description: "Read existing file"
category: happy_path
args:
path: "/tmp/test.txt"
assertions:
- path: content
condition: exists
- tool: read_file
description: "Read missing file"
category: error_handling
args:
path: "/nonexistent"
assertions:
- path: error
condition: exists
Configure in bellwether.yaml to use scenarios only:
scenarios:
path: "./bellwether-tests.yaml"
only: true # Skip LLM tests, run only scenarios
Then run:
bellwether check
CI/CD Integration
Add drift detection to your CI pipeline:
# .github/workflows/bellwether.yml
name: MCP Server Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run Bellwether Test
run: npx @dotsetlabs/bellwether check
- name: Check for Drift
run: npx @dotsetlabs/bellwether baseline compare ./bellwether-baseline.json --fail-on-drift
Two Commands
Choose the right command for your workflow:
Check Command (Default)
- Cost: Free
- Speed: Fast (seconds)
- Use case: CI/CD, quick checks, schema verification, drift detection
bellwether check "node ./src/mcp-server.js" # Free, deterministic
Explore Command
- Cost: Free with Ollama, ~$0.01-0.15 with API
- Speed: Slower (minutes)
- Use case: Deep exploration, documentation generation, security audits
bellwether init --preset local "node ./src/mcp-server.js" # Free with Ollama
bellwether explore # Generates AGENTS.md documentation
Environment Variables
Bellwether filters sensitive environment variables before spawning your server to prevent credential leaks. Variables matching these patterns are removed:
*_API_KEY,*_SECRET,*_TOKEN,*_PASSWORDAWS_*,AZURE_*,GCP_*OPENAI_*,ANTHROPIC_*
Your server receives a clean environment without these sensitive values.
Troubleshooting
Server Startup Issues
If your server takes time to start (common with npx), increase timeout in config:
server:
command: "npx your-server"
timeout: 60000 # 60 seconds
Server Crashes
Check the test output for error details. Enable debug logging:
logging:
level: debug
verbose: true
Watch Mode Not Detecting Changes
Ensure you've configured the right directory in bellwether.yaml:
watch:
path: "./src" # Directory to watch
extensions:
- ".ts"
- ".js"
- ".json"
See Also
- watch - Watch mode CLI reference
- check - Test CLI reference
- baseline - Baseline management
- Drift Detection - Understanding drift detection
- Custom Scenarios - Deterministic testing
- CI/CD Integration - Pipeline setup