UNPKG

@democratize-quality/mcp-server

Version:

MCP Server for democratizing quality through browser automation and comprehensive API testing capabilities

275 lines (208 loc) 6.84 kB
# Developer Guide A comprehensive guide for extending and contributing to the MCP Browser Control Server. --- ## Table of Contents - [Architecture Overview](#architecture-overview) - [Adding New Tools](#adding-new-tools) - [Tool Development Best Practices](#tool-development-best-practices) - [Configuration System](#configuration-system) - [Testing](#testing) - [Contributing](#contributing) ## Architecture Overview The MCP Browser Control Server follows a modular architecture: ``` src/ ├── tools/ │ ├── base/ │ │ ├── ToolBase.js # Base class for all tools │ │ └── ToolRegistry.js # Tool discovery and management │ ├── browser/ # Browser automation tools │ └── index.js # Tool system entry point ├── services/ │ └── browserService.js # Core browser management ├── config/ # Configuration management └── utils/ # Utility functions ``` ### Key Components 1. **ToolBase**: Abstract base class providing common functionality 2. **ToolRegistry**: Manages tool discovery, loading, and execution 3. **Configuration System**: Environment-based configuration management 4. **Browser Service**: Core browser automation functionality ## Adding New Tools ### Step 1: Create Tool File Create a new file in the appropriate category directory: ```javascript // src/tools/browser/my-new-tool.js const ToolBase = require('../base/ToolBase'); const browserService = require('../../services/browserService'); class MyNewTool extends ToolBase { static definition = { name: "browser_my_action", description: "Performs a custom browser action", input_schema: { type: "object", properties: { browserId: { type: "string", description: "Browser instance ID" }, // Add your parameters here }, required: ["browserId"] }, output_schema: { type: "object", properties: { success: { type: "boolean" }, // Add your output fields here }, required: ["success"] } }; async execute(parameters) { const { browserId } = parameters; // Your tool implementation here return { success: true }; } } module.exports = MyNewTool; ``` ### Step 2: Tool Discovery The tool will be automatically discovered and registered when the server starts. No manual registration required! ### Step 3: Add Configuration (Optional) Add tool-specific configuration in `src/config/tools/`: ```javascript // src/config/tools/browser.js module.exports = { // ... existing config browser_my_action: { timeout: 5000, retryAttempts: 3, customSetting: 'value' } }; ``` ### Step 4: Access Configuration in Tool ```javascript async execute(parameters) { const timeout = this.getConfig('timeout', 30000); const customSetting = this.getConfig('customSetting'); // Use configuration in your tool logic } ``` ## Tool Development Best Practices ### 1. Error Handling ```javascript async execute(parameters) { try { // Your logic here return result; } catch (error) { // Provide meaningful error messages throw new Error(`Failed to perform action: ${error.message}`); } } ``` ### 2. Parameter Validation Use the JSON schema in the `input_schema` for automatic validation: ```javascript static definition = { input_schema: { type: "object", properties: { url: { type: "string", pattern: "^https?://", // Regex validation description: "Must be a valid HTTP/HTTPS URL" }, timeout: { type: "number", minimum: 1000, maximum: 60000 } } } }; ``` ### 3. Logging Use consistent logging patterns: ```javascript async execute(parameters) { const toolName = this.constructor.definition.name; const enableDebug = this.config.isFeatureEnabled('enableDebugMode'); if (enableDebug) { console.error(`[${toolName}] Starting execution with:, parameters); } // Your logic here if (enableDebug) { console.error(`[${toolName}] Execution completed successfully`); } } ``` ### 4. Configuration Usage ```javascript async execute(parameters) { // Get tool-specific config with fallback const timeout = this.getConfig('timeout', 30000); const retries = this.getConfig('retryAttempts', 3); // Check feature flags if (this.config.isFeatureEnabled('enableDetailedLogging')) { // Enhanced logging } } ``` ## Configuration System ### Environment-Based Configuration - `development.js` - Development settings - `production.js` - Production optimizations - `server.js` - Server-level settings - `tools/` - Tool-specific configurations ### Environment Variable Overrides Override any configuration using environment variables: ```bash # Feature flags MCP_FEATURES_ENABLEBROWSERTOOLS=false # Tool settings MCP_TOOLS_BROWSER_TIMEOUT=60000 # Server settings MCP_SERVER_PORT=8080 ``` ## Testing ### Unit Testing Tools ```javascript // tests/tools/browser/my-tool.test.js const MyNewTool = require('../../../src/tools/browser/my-new-tool'); describe('MyNewTool', () => { let tool; beforeEach(() => { tool = new MyNewTool(); }); test('should validate required parameters', async () => { await expect(tool.run({})).rejects.toThrow('Missing required parameter'); }); test('should execute successfully with valid parameters', async () => { const result = await tool.run({ browserId: 'test-123' }); expect(result.content[0].text).toContain('success'); }); }); ``` ### Integration Testing Test tools with actual browser instances in development environment. ## Contributing 1. **Fork the repository** 2. **Create a feature branch**: `git checkout -b feature/my-new-tool` 3. **Add your tool** following the patterns above 4. **Add tests** for your tool 5. **Update documentation** by running `npm run docs:generate` 6. **Submit a pull request** ### Code Style - Use descriptive variable names - Add JSDoc comments for public methods - Follow existing patterns for consistency - Use async/await for asynchronous operations ### Commit Messages - Use conventional commit format: `feat: add new browser tool` - Include scope when relevant: `feat(browser): add scroll tool` - Use present tense: "add" not "added" --- *Generated automatically from tool definitions and code analysis*