Skip to main content
Glama
CONTRIBUTING.mdβ€’18.4 kB
# Contributing to MCP WordPress Server Welcome to the MCP WordPress Server project! This document provides comprehensive guidelines for contributing to this WordPress Model Context Protocol (MCP) server implementation. ## πŸ“‹ Table of Contents - [Getting Started](#-getting-started) - [Development Workflow](#-development-workflow) - [Code Quality Standards](#-code-quality-standards) - [Testing Requirements](#-testing-requirements) - [Coverage Standards](#-coverage-standards) - [TypeScript Guidelines](#-typescript-guidelines) - [Logging Guidelines](#-logging-guidelines) - [Security Guidelines](#-security-guidelines) - [Performance Guidelines](#-performance-guidelines) - [Documentation Standards](#-documentation-standards) - [Pull Request Process](#-pull-request-process) ## πŸš€ Getting Started ### Prerequisites - **Node.js**: Version 18 or higher - **npm**: Version 8 or higher - **TypeScript**: Version 5.0 or higher - **WordPress**: Access to a WordPress site for testing - **Git**: Version 2.30 or higher ### Initial Setup ```bash # Clone the repository git clone https://github.com/docdyhr/mcp-wordpress.git cd mcp-wordpress # Install dependencies npm ci # Set up configuration cp .env.example .env # Edit .env with your WordPress credentials # Run initial health check npm run health ``` ### Development Environment ```bash # Start development mode npm run dev # Run tests in watch mode npm run test:watch # Enable debug logging DEBUG=true npm run dev ``` ## πŸ”„ Development Workflow ### Branch Strategy We follow a **feature branch workflow** with strict branch protection on `main`: ```bash # Create feature branch from main git checkout main git pull origin main git checkout -b feature/your-feature-name # Work on your feature # Make atomic commits with conventional commit messages # Push and create PR git push -u origin feature/your-feature-name gh pr create --title "feat: description" --body "Detailed description" ``` ### Commit Message Standards We use **Conventional Commits** for automated versioning and changelog generation: ```bash # Format: type(scope): description feat(tools): add new WordPress custom fields tool fix(auth): resolve app password authentication issue chore(deps): update dependencies to latest versions docs(readme): improve installation instructions test(posts): add comprehensive post tool unit tests ``` **Types:** - `feat`: New features - `fix`: Bug fixes - `chore`: Maintenance tasks - `docs`: Documentation changes - `test`: Adding or updating tests - `refactor`: Code refactoring - `perf`: Performance improvements - `security`: Security improvements ## πŸ—οΈ Code Quality Standards ### ESLint Configuration We maintain **strict ESLint compliance**: ```bash # Check for linting errors npm run lint # Auto-fix linting issues npm run lint:fix # Ensure zero violations before committing ``` **Key Rules:** - No unused variables (use `_` prefix for intentionally unused) - Strict TypeScript types (no `any` types allowed) - Consistent import/export patterns - Proper error handling requirements ### Code Formatting We use **Prettier** for consistent code formatting: ```bash # Format all code npm run format # Automatic formatting on commit via husky hooks ``` ## βœ… Testing Requirements ### Test Categories All contributions must include tests based on the following hierarchy: #### 1. Unit Tests (Required) - **Coverage Target**: β‰₯50% for new components - **Focus**: Individual functions, classes, and modules - **Location**: `tests/unit/` ```typescript // Example unit test structure describe("WordPressClient", () => { describe("authentication", () => { it("should authenticate with app password", async () => { // Test implementation }); it("should handle authentication failures gracefully", async () => { // Test implementation }); }); }); ``` #### 2. Integration Tests (Required for API changes) - **Focus**: Component interactions and API integrations - **Location**: `tests/integration/` - **WordPress Integration**: Use mock/live dual-mode testing #### 3. Security Tests (Required for security-related changes) - **Coverage**: 40/40 tests must pass - **Focus**: Input validation, SQL injection prevention, XSS protection - **Location**: `tests/security/` #### 4. Performance Tests (Required for performance-related changes) - **Coverage**: 8/8 tests must pass - **Focus**: Response times, memory usage, cache efficiency - **Location**: `tests/performance/` ### Test Execution ```bash # Run all tests npm test # Run specific test categories npm run test:unit npm run test:integration npm run test:security npm run test:performance # Run tests with coverage npm run test:coverage # Run tests in watch mode during development npm run test:watch ``` ### Test Writing Standards ```typescript // Use descriptive test names it("should create post with featured media and return management links", async () => { // Arrange const postData = { title: "Test Post", content: "<p>Test content</p>", featured_media: 42, }; // Act const result = await postTool.createPost(postData); // Assert expect(result.id).toBeDefined(); expect(result.featured_media).toBe(42); expect(result._links.self).toBeDefined(); }); // Test error conditions it("should throw validation error for missing required title", async () => { await expect(postTool.createPost({})).rejects.toThrow(/title.*required/i); }); // Test edge cases it("should handle empty post content gracefully", async () => { const result = await postTool.createPost({ title: "Test", content: "" }); expect(result.content.rendered).toBe(""); }); ``` ## πŸ“Š Coverage Standards ### Coverage Thresholds We enforce **incremental coverage improvement** to maintain code quality: #### Global Thresholds (Minimum) ```json { "lines": 30, "branches": 25, "functions": 28, "statements": 29 } ``` #### Incremental Coverage Rule - **No regression allowed**: Coverage cannot decrease by >1% in any metric - **New code target**: β‰₯50% coverage for new components - **Improvement goal**: Gradual increase toward 80% total coverage #### Component-Specific Requirements **High-Priority Components** (β‰₯50% coverage required): - `src/client/` - WordPress API client - `src/tools/` - MCP tool implementations - `src/security/` - Security utilities - `src/utils/` - Core utilities **Moderate-Priority Components** (β‰₯30% coverage): - `src/config/` - Configuration management - `src/cache/` - Caching system - `src/server/` - MCP server implementation ### Coverage Validation ```bash # Check coverage npm run test:coverage # Validate coverage thresholds npm run coverage:check # Generate detailed coverage report npm run coverage:report ``` ## πŸ“˜ TypeScript Guidelines ### Type Safety Requirements We enforce **strict TypeScript compliance** with zero tolerance for type violations: #### Prohibited Patterns ```typescript // ❌ NEVER use explicit 'any' function badFunction(data: any): any { return data.whatever; } // ❌ NEVER bypass type checking const result = (data as any).someProperty; // ❌ NEVER ignore TypeScript errors // @ts-ignore const unsafeOperation = riskyFunction(); ``` #### Required Patterns ```typescript // βœ… Define proper interfaces interface WordPressPost { id: number; title: { rendered: string; }; content: { rendered: string; }; status: "publish" | "draft" | "pending" | "private"; featured_media?: number | undefined; } // βœ… Use proper type guards function isWordPressPost(obj: unknown): obj is WordPressPost { return typeof obj === "object" && obj !== null && "id" in obj && "title" in obj; } // βœ… Handle optional properties correctly interface ToolParams { title: string; content?: string | undefined; // Explicit undefined for exactOptionalPropertyTypes } ``` #### Type Definition Standards - **All exports**: Must have explicit type definitions - **Function parameters**: Must be properly typed - **Return types**: Must be explicitly declared - **Error types**: Must extend proper error classes ```typescript // βœ… Proper function typing export async function createPost(params: CreatePostParams): Promise<WordPressPost> { // Implementation } // βœ… Proper error typing export class WordPressApiError extends Error { constructor( message: string, public statusCode: number, public response?: unknown, ) { super(message); this.name = "WordPressApiError"; } } ``` ## πŸ“ Logging Guidelines ### Structured Logging Requirements We use **centralized structured logging** for all components: #### Required Logger Usage ```typescript // βœ… ALWAYS use LoggerFactory import { LoggerFactory } from "../utils/logger.js"; // Create component-specific loggers const apiLogger = LoggerFactory.api("site1"); const toolLogger = LoggerFactory.tool("wp_create_post", "site2"); const cacheLogger = LoggerFactory.cache(); const securityLogger = LoggerFactory.security(); ``` #### Prohibited Logging Patterns ```typescript // ❌ NEVER use console.log directly console.log("Debug info:", data); // ❌ NEVER use generic console methods console.error("Error occurred"); console.warn("Warning message"); // ❌ NEVER log sensitive data without sanitization logger.info("User credentials", { username, password }); ``` #### Required Logging Patterns ```typescript // βœ… Use appropriate log levels logger.debug("Processing request", { endpoint: "/wp/v2/posts" }); logger.info("Post created successfully", { postId: 123, title: "Post Title" }); logger.warn("Cache miss detected", { key: "posts:123", reason: "expired" }); logger.error("API request failed", { statusCode: 401, endpoint: "/wp/v2/posts" }); // βœ… Use timing for performance monitoring const result = await logger.time("Database query", async () => { return await database.query(sql); }); // βœ… Sensitive data is automatically sanitized logger.info("Authentication attempt", { username: "testuser", password: "secret123", // Automatically becomes [REDACTED:9chars] token: "abc123def", // Automatically becomes [REDACTED:9chars] }); // βœ… Use contextual logging const requestLogger = logger.child({ requestId: uuid(), userId: "user123" }); requestLogger.info("Processing user request"); ``` #### Log Level Guidelines - **trace**: Detailed debugging (disabled in production) - **debug**: Development debugging (disabled in production) - **info**: General operational information - **warn**: Warning conditions that don't stop operation - **error**: Error conditions that may stop operation - **fatal**: Critical errors that stop the application ## πŸ”’ Security Guidelines ### Security Requirements All code must follow **defensive security practices**: #### Input Validation ```typescript // βœ… Validate all inputs function validatePostData(data: unknown): CreatePostParams { const schema = z.object({ title: z.string().min(1).max(200), content: z.string().optional(), status: z.enum(["publish", "draft", "pending", "private"]).optional(), }); return schema.parse(data); } // βœ… Sanitize HTML content import { sanitizeHtml } from "../security/sanitization.js"; const safeContent = sanitizeHtml(userContent, { allowedTags: ["p", "br", "strong", "em"], allowedAttributes: {}, }); ``` #### Authentication Security ```typescript // βœ… Secure credential handling class AuthenticationManager { private credentials: Map<string, SiteCredentials> = new Map(); setCredentials(siteId: string, credentials: SiteCredentials): void { // Credentials are never logged this.logger.info("Credentials updated", { siteId }); this.credentials.set(siteId, credentials); } } // βœ… Secure API communication const response = await fetch(url, { headers: { Authorization: `Bearer ${token}`, "User-Agent": "MCP-WordPress/2.4.0", "Content-Type": "application/json", }, // Always use HTTPS in production }); ``` #### SQL Injection Prevention ```typescript // βœ… Use parameterized queries const query = ` SELECT * FROM posts WHERE status = ? AND author_id = ? `; const results = await db.query(query, [status, authorId]); // ❌ NEVER use string concatenation const badQuery = `SELECT * FROM posts WHERE status = '${status}'`; ``` ### Required Security Tests All security-related changes must include: 1. **Input validation tests** 2. **XSS prevention tests** 3. **SQL injection prevention tests** 4. **Authentication bypass tests** 5. **Authorization tests** ## ⚑ Performance Guidelines ### Performance Requirements Code must meet **performance standards**: #### Response Time Targets - **API calls**: <500ms average - **Cache operations**: <50ms - **Tool execution**: <2000ms - **Database queries**: <200ms #### Memory Usage Guidelines - **Memory leaks**: Zero tolerance - **Memory usage**: <80% of available memory - **Cache size**: Configurable limits with LRU eviction #### Performance Testing ```typescript // βœ… Include performance tests for critical paths describe("Performance Tests", () => { it("should create post within 2 seconds", async () => { const start = Date.now(); await postTool.createPost(testData); const duration = Date.now() - start; expect(duration).toBeLessThan(2000); }); it("should handle 100 concurrent requests", async () => { const promises = Array(100) .fill(null) .map(() => postTool.listPosts({ per_page: 10 })); await expect(Promise.all(promises)).resolves.toBeDefined(); }); }); ``` ## πŸ“š Documentation Standards ### Code Documentation - **JSDoc comments**: Required for all public APIs - **Type annotations**: Required for all exports - **Usage examples**: Required for tools and utilities ````typescript /** * Creates a new WordPress post with comprehensive validation * * @param params - Post creation parameters * @param params.title - Post title (required) * @param params.content - Post content in HTML format * @param params.status - Publishing status * @returns Promise resolving to created post with metadata * * @example * ```typescript * const post = await createPost({ * title: 'My New Post', * content: '<p>Hello World!</p>', * status: 'publish' * }); * console.log(`Created post with ID: ${post.id}`); * ``` */ export async function createPost(params: CreatePostParams): Promise<WordPressPost> { // Implementation } ```` ### README Updates - Update feature lists for new capabilities - Add usage examples for new tools - Update installation instructions if needed ## πŸ”„ Pull Request Process ### PR Requirements Checklist Before submitting a pull request, ensure: #### Code Quality - [ ] All tests pass (`npm test`) - [ ] ESLint compliance (`npm run lint`) - [ ] TypeScript compilation (`npm run build`) - [ ] Code formatted (`npm run format`) #### Testing - [ ] Unit tests for new functionality (β‰₯50% coverage) - [ ] Integration tests for API changes - [ ] Security tests for security-related changes - [ ] Performance tests for performance-related changes #### Coverage - [ ] No coverage regression (>1% decrease) - [ ] New code meets coverage targets - [ ] Coverage report generated (`npm run test:coverage`) #### Documentation - [ ] JSDoc comments for public APIs - [ ] README updated if needed - [ ] CLAUDE.md updated for significant changes - [ ] Commit messages follow conventional format ### PR Template ```markdown ## Description Brief description of changes and motivation. ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that causes existing functionality to change) - [ ] Documentation update ## Testing - [ ] Unit tests added/updated - [ ] Integration tests added/updated - [ ] Security tests added/updated (if applicable) - [ ] Performance tests added/updated (if applicable) - [ ] All tests pass ## Coverage - [ ] Coverage maintained or improved - [ ] New code meets β‰₯50% coverage target - [ ] No regression in coverage metrics ## Security - [ ] Input validation implemented - [ ] No sensitive data exposed in logs - [ ] Authentication/authorization properly handled - [ ] Security tests pass ## Performance - [ ] Performance impact assessed - [ ] No memory leaks introduced - [ ] Response times within targets - [ ] Performance tests pass (if applicable) ## Documentation - [ ] Code documented with JSDoc - [ ] README updated (if applicable) - [ ] Usage examples provided ``` ### Review Process 1. **Automated Checks**: All CI/CD checks must pass 2. **Code Review**: At least one maintainer review required 3. **Security Review**: Required for security-related changes 4. **Performance Review**: Required for performance-related changes 5. **Merge**: Squash and merge after approval ### Branch Protection The `main` branch has strict protection rules: - βœ… Pull requests required - βœ… Status checks must pass - βœ… No direct pushes allowed - βœ… No merge commits allowed - βœ… Branch must be up to date ## πŸ†˜ Getting Help ### Resources - **Documentation**: [Project README](README.md) - **Development Guide**: [CLAUDE.md](CLAUDE.md) - **Testing Guide**: [TESTING_GUIDELINES.md](TESTING_GUIDELINES.md) - **Coverage Strategy**: [COVERAGE_STRATEGY.md](COVERAGE_STRATEGY.md) ### Support Channels - **GitHub Issues**: For bug reports and feature requests - **GitHub Discussions**: For questions and community discussion - **Code Review**: Through pull request comments ### Common Issues - **TypeScript errors**: Check `exactOptionalPropertyTypes` compliance - **Test failures**: Ensure proper mocking and async handling - **Coverage issues**: Add tests for uncovered branches - **Linting errors**: Run `npm run lint:fix` for auto-fixes --- ## 🎯 Summary This project maintains **high standards** for code quality, testing, and security. By following these guidelines, you help ensure that the MCP WordPress Server remains: - βœ… **Reliable**: Comprehensive testing and quality gates - βœ… **Secure**: Defense-in-depth security practices - βœ… **Performant**: Optimized for speed and efficiency - βœ… **Maintainable**: Clean, well-documented, type-safe code - βœ… **Professional**: Industry-standard development practices **Thank you for contributing to making WordPress management better for everyone!** πŸš€

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/docdyhr/mcp-wordpress'

If you have feedback or need assistance with the MCP directory API, please join our Discord server