CONTRIBUTING.md•13.9 kB
# Contributing to Finizi B4B MCP Server
Thank you for your interest in contributing to the Finizi B4B MCP Server! This document provides guidelines and instructions for contributing to our project.
## Table of Contents
1. [Code of Conduct](#code-of-conduct)
2. [How to Contribute](#how-to-contribute)
3. [Development Setup](#development-setup)
4. [Pull Request Process](#pull-request-process)
5. [Coding Standards](#coding-standards)
6. [Testing Requirements](#testing-requirements)
7. [Documentation Requirements](#documentation-requirements)
8. [Commit Message Guidelines](#commit-message-guidelines)
9. [Issue Reporting](#issue-reporting)
10. [Community](#community)
## Code of Conduct
### Our Pledge
We pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dev@finizi.ai. All complaints will be reviewed and investigated promptly and fairly.
## How to Contribute
### Ways to Contribute
1. **Report Bugs**: Found a bug? Report it via GitHub Issues
2. **Suggest Features**: Have an idea? Open a feature request
3. **Submit Pull Requests**: Fix bugs or add features
4. **Improve Documentation**: Help make our docs better
5. **Write Tests**: Increase test coverage
6. **Review Code**: Review open pull requests
### First Time Contributors
Looking for a good first issue? Check out issues labeled with:
- `good first issue` - Simple issues perfect for beginners
- `help wanted` - Issues where we need community help
- `documentation` - Documentation improvements
### Getting Started
1. Fork the repository
2. Clone your fork locally
3. Create a new branch for your contribution
4. Make your changes
5. Submit a pull request
## Development Setup
### Prerequisites
- Python 3.11 or higher
- UV package manager
- Git
### Setting Up Your Development Environment
```bash
# Clone your fork
git clone https://github.com/YOUR_USERNAME/finizi-mcp.git
cd finizi-mcp
# Add upstream remote
git remote add upstream https://github.com/finizi/finizi-mcp.git
# Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create virtual environment
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies with dev extras
uv pip install -e ".[dev]"
# Copy environment configuration
cp .env.example .env
# Edit .env with your configuration
```
### Running the Development Server
```bash
# Run the MCP server
python run_server.py
# Or with debug logging
LOG_LEVEL=DEBUG python run_server.py
```
## Pull Request Process
### Before Submitting
1. **Update your fork**:
```bash
git fetch upstream
git checkout main
git merge upstream/main
```
2. **Create a feature branch**:
```bash
git checkout -b feature/your-feature-name
```
3. **Make your changes**:
- Write clean, maintainable code
- Follow our coding standards
- Add tests for new functionality
- Update documentation as needed
4. **Run tests**:
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=src/finizi_b4b_mcp
# Run specific tests
pytest tests/test_auth.py
```
5. **Format and lint**:
```bash
# Format code
ruff format .
# Check linting
ruff check .
# Fix auto-fixable issues
ruff check --fix .
```
### Submitting Your PR
1. **Commit your changes**:
```bash
git add .
git commit -m "feat: Add new feature" # See commit guidelines below
```
2. **Push to your fork**:
```bash
git push origin feature/your-feature-name
```
3. **Create Pull Request**:
- Go to GitHub and create a PR from your branch
- Fill out the PR template completely
- Link any related issues
- Add appropriate labels
### PR Review Process
1. **Automated Checks**: CI will run tests and linting
2. **Code Review**: Maintainers will review your code
3. **Feedback**: Address any requested changes
4. **Approval**: Once approved, your PR will be merged
### PR Template
```markdown
## Description
Brief description of what this PR does
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Checklist
- [ ] My code follows the style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have commented my code where necessary
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix/feature works
- [ ] New and existing unit tests pass locally
- [ ] Any dependent changes have been merged and published
## Testing
Describe the tests that you ran to verify your changes
## Screenshots (if applicable)
Add screenshots to help explain your changes
## Related Issues
Fixes #(issue number)
```
## Coding Standards
### Python Style Guide
We follow PEP 8 with some modifications:
- Line length: 100 characters maximum
- Use 4 spaces for indentation
- Use type hints for all function signatures
### Code Organization
```python
# Import order
import standard_library_imports
import third_party_imports
from local_application import imports
# Class definitions
class MyClass:
"""Class docstring."""
def __init__(self):
"""Constructor docstring."""
pass
async def async_method(self, param: str) -> dict:
"""
Method docstring.
Args:
param: Description of param
Returns:
Description of return value
"""
pass
# Function definitions
async def my_function(param1: str, param2: int = 10) -> dict:
"""
Function docstring.
Args:
param1: Description
param2: Description with default
Returns:
Description of return
Raises:
ValueError: When validation fails
"""
pass
```
### Naming Conventions
- **Classes**: `PascalCase` (e.g., `ApiClient`)
- **Functions/Methods**: `snake_case` (e.g., `list_entities`)
- **Constants**: `UPPER_SNAKE_CASE` (e.g., `MAX_RETRIES`)
- **Private**: Leading underscore (e.g., `_internal_method`)
### Type Hints
Always use type hints:
```python
from typing import Optional, Dict, List, Any
async def process_data(
data: List[Dict[str, Any]],
filter_key: Optional[str] = None
) -> Dict[str, Any]:
"""Process data with optional filtering."""
pass
```
### Error Handling
```python
from ..utils.errors import MCPValidationError
try:
# Risky operation
result = await api_call()
except MCPValidationError as e:
logger.error("Validation failed", error=str(e))
return {"success": False, "error": str(e)}
except Exception as e:
logger.error("Unexpected error", error=str(e))
raise
```
### Logging
Use structured logging:
```python
import structlog
logger = structlog.get_logger(__name__)
logger.info("Operation started", user_id=user_id, action="list_entities")
logger.error("Operation failed", error=str(e), user_id=user_id)
```
## Testing Requirements
### Test Coverage
- Minimum 80% overall coverage required
- New features must include tests
- Bug fixes must include regression tests
### Writing Tests
#### Test Structure
```python
import pytest
from unittest.mock import AsyncMock, patch
class TestFeature:
"""Test suite for feature."""
@pytest.fixture
def setup(self):
"""Setup test fixtures."""
return {"key": "value"}
@pytest.mark.asyncio
async def test_success_case(self, setup):
"""Test successful operation."""
# Arrange
mock_data = setup
# Act
result = await function_under_test(mock_data)
# Assert
assert result["success"] is True
@pytest.mark.asyncio
async def test_error_case(self):
"""Test error handling."""
with pytest.raises(ValueError):
await function_under_test(invalid_data)
```
#### Mocking Guidelines
```python
@patch('finizi_b4b_mcp.client.api_client.ApiClient')
async def test_with_mock(mock_client):
"""Test with mocked API client."""
mock_client.get.return_value = {"test": "data"}
result = await function_under_test()
mock_client.get.assert_called_once_with("/endpoint")
assert result == {"test": "data"}
```
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=src/finizi_b4b_mcp --cov-report=html
# Run specific test file
pytest tests/test_auth.py
# Run with verbose output
pytest -v
# Run with captured output
pytest -s
```
## Documentation Requirements
### Code Documentation
Every public function/class must have a docstring:
```python
def calculate_total(items: List[Dict[str, float]], tax_rate: float = 0.1) -> float:
"""
Calculate total price including tax.
Args:
items: List of items with 'price' key
tax_rate: Tax rate as decimal (default: 0.1 for 10%)
Returns:
Total price including tax
Example:
>>> items = [{"name": "item1", "price": 10.0}]
>>> calculate_total(items, 0.2)
12.0
"""
pass
```
### Documentation Files
When adding new features, update:
1. **README.md**: Add to feature list and examples
2. **API_MAPPING.md**: Document new API endpoints
3. **DEVELOPMENT.md**: Add development notes if needed
### API Documentation
Document new MCP tools in the following format:
```markdown
### tool_name
**Purpose**: Brief description of what the tool does
**Parameters**:
- `param1` (type, required/optional): Description
- `param2` (type, required/optional): Description
**Returns**:
```json
{
"success": true,
"data": "..."
}
```
**Example**:
```python
result = await tool_name(param1="value", param2=123)
```
```
## Commit Message Guidelines
We follow the Conventional Commits specification:
### Format
```
<type>(<scope>): <subject>
<body>
<footer>
```
### Types
- **feat**: New feature
- **fix**: Bug fix
- **docs**: Documentation changes
- **style**: Code style changes (formatting, etc.)
- **refactor**: Code refactoring
- **test**: Adding or updating tests
- **chore**: Maintenance tasks
- **perf**: Performance improvements
### Examples
```bash
# Feature
git commit -m "feat(auth): Add refresh token support"
# Bug fix
git commit -m "fix(entities): Correct pagination logic"
# Documentation
git commit -m "docs(readme): Update installation instructions"
# Multiple lines
git commit -m "feat(invoices): Add XML import functionality
- Parse XML invoice format
- Validate against schema
- Store in database
Closes #123"
```
### Scope Examples
- `auth`: Authentication related
- `entities`: Entity management
- `invoices`: Invoice management
- `vendors`: Vendor management
- `products`: Product management
- `client`: API client
- `utils`: Utilities
- `tests`: Test suite
## Issue Reporting
### Before Creating an Issue
1. **Search existing issues**: Your issue might already be reported
2. **Check documentation**: The answer might be in the docs
3. **Verify reproduction**: Ensure you can reproduce the issue
### Issue Template
```markdown
## Bug Report
### Description
Clear description of the bug
### Steps to Reproduce
1. Step one
2. Step two
3. Step three
### Expected Behavior
What you expected to happen
### Actual Behavior
What actually happened
### Environment
- OS: [e.g., Ubuntu 22.04]
- Python version: [e.g., 3.11.5]
- MCP Server version: [e.g., 1.0.0]
- B4B API version: [e.g., v1]
### Logs
```
Paste relevant logs here
```
### Additional Context
Any other context about the problem
```
### Feature Request Template
```markdown
## Feature Request
### Problem Statement
What problem does this feature solve?
### Proposed Solution
How would you like to see this implemented?
### Alternatives Considered
What other solutions have you considered?
### Additional Context
Any other context or screenshots
```
## Community
### Getting Help
- **Documentation**: Read our comprehensive docs
- **GitHub Issues**: Search or ask questions
- **Discord**: Join our community server
- **Email**: dev@finizi.ai for direct contact
### Stay Updated
- Watch the repository for updates
- Subscribe to release notifications
- Follow our blog for announcements
### Recognition
Contributors who submit accepted PRs will be:
- Added to the contributors list
- Mentioned in release notes
- Eligible for contributor badges
## License
By contributing to Finizi B4B MCP Server, you agree that your contributions will be licensed under the MIT License.
## Questions?
If you have questions about contributing, please:
1. Check this guide and other documentation
2. Search existing issues
3. Ask in our Discord community
4. Contact us at dev@finizi.ai
Thank you for contributing to Finizi B4B MCP Server!
---
**Last Updated**: October 2024
**Version**: 1.0.0