Guide for contributors and developers who want to work on the Windmill MCP Server project.
- Node.js 18+ and npm
- Docker and Docker Compose (for local testing)
- Git
# Clone the repository
git clone https://github.com/rothnic/windmill-mcp.git
cd windmill-mcp
# Install dependencies
npm install
# Generate the MCP server
npm run generateFor testing, start a local Windmill instance:
# Start Windmill with development configuration
npm run docker:dev
# Output shows:
# ✅ Windmill ready at http://localhost:8000
# Superadmin secret: test-super-secret
# Default workspace: adminsOther Docker commands:
npm run docker:logs # View logs
npm run docker:down # Stop (keeps data)
npm run docker:clean # Clean everything (removes data)# Using the runtime loader (recommended)
node src/runtime/index.js
# With specific Windmill version
WINDMILL_VERSION=1.520.1 node src/runtime/index.js
# With local Windmill
WINDMILL_BASE_URL=http://localhost:8000 \
WINDMILL_API_TOKEN=test-super-secret \
node src/runtime/index.js
# Direct execution (bypass version management)
WINDMILL_BASE_URL=http://localhost:8000 \
WINDMILL_API_TOKEN=test-super-secret \
npm run dev# Run all tests
npm test
# Unit tests only
npm run test:unit
# E2E tests with local Windmill
E2E_WINDMILL_URL=http://localhost:8000 \
E2E_WINDMILL_TOKEN=test-super-secret \
E2E_WORKSPACE=admins \
npm run test:e2e
# Full E2E cycle (starts/stops Windmill automatically)
npm run test:e2e:full
# Watch mode for development
npm run test:watch
# Coverage report
npm run test:coverageSee Testing Guide for comprehensive testing documentation.
Test the MCP server interactively:
# With local Windmill
WINDMILL_BASE_URL=http://localhost:8000 \
WINDMILL_API_TOKEN=test-super-secret \
npx @modelcontextprotocol/inspector node build/dist/index.jsThis opens a web interface where you can:
- Browse all available tools
- Test tool invocations
- Debug responses
windmill-mcp/
├── src/
│ ├── generator/ # Generation scripts
│ │ ├── generate.js # Main generation orchestrator
│ │ ├── fetch-spec.js # OpenAPI spec fetching
│ │ └── config.json # Generator configuration
│ ├── overrides/ # Custom modifications
│ │ ├── apply-overrides.js
│ │ └── add-tool-namespaces.js
│ └── runtime/ # Runtime loader
│ └── index.js # Version management and loading
├── build/ # Generated code (gitignored)
│ ├── src/ # Generated TypeScript
│ └── dist/ # Compiled JavaScript
├── cache/ # Cached specs (gitignored)
├── tests/ # Test suite
│ ├── unit/ # Unit tests
│ ├── e2e/ # End-to-end tests
│ ├── docker/ # Docker setup for tests
│ └── utils/ # Test utilities
├── docs/ # Documentation
│ ├── guides/ # User guides
│ ├── development/ # Developer docs
│ ├── reference/ # Technical references
│ └── planning/ # Project planning
└── scripts/ # Utility scripts
Committed to Git:
src/- All source code including generator, overrides, and runtimetests/- Test suitedocs/- Documentationscripts/- Utility scripts
Generated/Temporary (gitignored):
build/- Generated MCP server codecache/- Cached OpenAPI specificationsnode_modules/- Dependencies
The npm run generate command executes a complete workflow:
-
Pre-generation (
pregeneratehook):- Fetches latest OpenAPI spec from Windmill
- Caches spec in
cache/directory
-
Generation:
- Runs openapi-mcp-generator
- Creates TypeScript MCP server in
build/src/
-
Post-generation (
postgeneratehook):- Adds tool namespaces for better organization
- Applies custom overrides from
src/overrides/ - Installs dependencies in
build/ - Compiles TypeScript to JavaScript in
build/dist/ - Generates tool documentation in
docs/reference/generated-tools.md
If you need to run steps individually:
# Fetch OpenAPI spec only
npm run fetch-spec
# Apply overrides only
npm run apply-overrides
# Build generated code only
npm run build:generated
# Generate tool documentation
npm run generate-tool-listCustom modifications are stored in src/overrides/ and persist across regenerations:
- Create a file in
src/overrides/matching the structure of generated code - Add your customizations
- Run
npm run generateto regenerate with overrides applied
Example:
# Override structure matches build structure
src/overrides/
└── src/
└── index.ts # Overrides build/src/index.tsSee Generator Guide for detailed information.
-
Create a feature branch:
git checkout -b feature/your-feature-name
-
Make changes:
- Prefer overrides for generated code modifications
- Add tests for new functionality
- Update documentation
-
Run tests locally:
npm test npm run validate -
Commit changes:
git add . git commit -m "Description of changes"
-
Push and create PR:
git push origin feature/your-feature-name
Before committing:
# Lint code
npm run lint
# Check file structure
npm run lint:structure
# Format code
npm run format
# Validate everything
npm run validatePull requests automatically run:
- ✅ Unit Tests (required)
- ✅ Build Verification (required)
- ℹ️ E2E Tests (informational)
PRs cannot be merged until required checks pass.
# Set specific version
export WINDMILL_VERSION=1.520.1
node src/runtime/index.js
# Or generate for specific version
WINDMILL_VERSION=1.520.1 npm run generate# View generated TypeScript
cat build/src/index.ts | less
# Check compiled JavaScript
cat build/dist/index.js | less
# Test tool directly
node -e "require('./build/dist/index.js')"- Create test file in
tests/unit/ortests/e2e/ - Follow existing test patterns
- Use mock utilities from
tests/utils/mocks.js - Run tests:
npm test
See Testing Guide for details.
When making changes:
- Update relevant documentation in
docs/ - Keep README.md high-level (details go in guides)
- Update CHANGELOG.md for notable changes
- Run documentation validation:
npm run docs:validate
Create a .env file for local development (not committed):
# Windmill Instance
WINDMILL_BASE_URL=http://localhost:8000
WINDMILL_API_TOKEN=test-super-secret
# Optional: Specific version
WINDMILL_VERSION=1.520.1
# Testing
E2E_WINDMILL_URL=http://localhost:8000
E2E_WINDMILL_TOKEN=test-super-secret
E2E_WORKSPACE=adminsSee Troubleshooting Guide for common issues.
Build fails after pulling changes:
rm -rf build/ cache/ node_modules/
npm install
npm run generateTests fail unexpectedly:
# Clean Docker state
npm run docker:clean
npm run docker:dev
npm testOverride conflicts:
npm run validate-overrides- Review Contributing Guidelines
- Check GitHub Issues
- Join Windmill Discord
- Generator Guide - Understanding the generation system
- Testing Guide - Comprehensive testing documentation
- Architecture - System architecture overview
- Contributing Guidelines - Contribution workflow