# Contributing to MCP Server for Odoo Thanks for your interest in contributing! Whether it's a bug report, new feature, documentation improvement, or test coverage — all contributions are welcome. ## Development Setup ### Prerequisites - Python 3.10 or higher - [uv](https://docs.astral.sh/uv/) package manager ### Getting Started 1. Fork and clone the repository: ```bash git clone https://github.com//mcp-server-odoo.git cd mcp-server-odoo ``` 2. Install in development mode: ```bash uv pip install -e ".[dev]" ``` 3. *(Optional)* Create a `.env` file for integration tests: ```env ODOO_URL=http://localhost:8069 ODOO_USER=admin ODOO_PASSWORD=admin ODOO_DB=demo ODOO_YOLO=true ``` ## Running Tests The project has three test tiers. Unit tests require no external services — integration tests auto-skip when Odoo is unavailable. ```bash # Unit tests (no Odoo needed) uv run pytest -m "not yolo and not mcp" --cov # YOLO integration tests (vanilla Odoo, no MCP module) uv run pytest -m "yolo" -v # MCP integration tests (Odoo + MCP module installed) uv run pytest -m "mcp" -v # All tests uv run pytest --cov # Single test by name uv run pytest -k "test_search_records" -v ``` ## Code Style The project uses [Ruff](https://docs.astral.sh/ruff/) for formatting and linting, and [ty](https://github.com/astral-sh/ty) for type checking. Run all checks before submitting: ```bash uv run ruff check . && uv run ruff format --check . && uv run ty check . ``` Key settings: - **Line length**: 100 - **Lint rules**: E, F, I, N, W, B, Q - **Python target**: 3.10 To auto-fix formatting: `uv run ruff format .` ## Commit Messages This project uses [Conventional Commits](https://www.conventionalcommits.org/). Use lowercase, imperative mood, no trailing period. **Format**: `: ` | Type | Purpose | |------|---------| | `feat` | New feature | | `fix` | Bug fix | | `refactor` | Code change that neither fixes a bug nor adds a feature | | `docs` | Documentation only | | `ci` | CI/CD changes | | `chore` | Dependency updates, tooling | **Examples**: ``` feat: add multi-language support via ODOO_LOCALE fix: handle models without name field in create_record refactor: rename test markers — integration→mcp, e2e→yolo ``` For non-trivial changes, add a body explaining **why**: ``` fix: use password auth for MCP integration tests in CI Remove fake ODOO_API_KEY from CI env vars — it caused Access Denied errors because Odoo rejected the dummy key at the XML-RPC dispatch level. Tests now use password-only auth which works with use_api_keys=False. ``` ## Pull Request Process 1. **Fork** the repository and create a branch from `dev` 2. **Keep it focused** — one logical change per PR 3. **Add tests** for new functionality 4. **Update** `CHANGELOG.md` under the `[Unreleased]` section using [Keep a Changelog](https://keepachangelog.com/) format 5. **Run checks** locally — CI runs lint, unit tests, and integration tests 6. **Open a PR** targeting the `dev` branch 7. **Describe** what changed and why in the PR description ## Reporting Issues ### Bug Reports Please include: - Steps to reproduce the issue - Expected vs actual behavior - Odoo version and mode (standard or YOLO) - MCP server version (`python -m mcp_server_odoo --version`) - Relevant error messages or logs ### Feature Requests Describe the use case and motivation. Explain how the feature would benefit users of the MCP server. ## Project Architecture A quick orientation for navigating the codebase: ``` __main__.py → OdooConfig → OdooMCPServer → OdooConnection → FastMCP ``` | Module | Responsibility | |--------|---------------| | `server.py` | Orchestrates startup, registers handlers on FastMCP | | `config.py` | `OdooConfig` dataclass from env vars, singleton via `get_config()` | | `odoo_connection.py` | XML-RPC proxies, auth, CRUD convenience methods, caching | | `tools.py` | MCP tool handlers (search, get, create, update, delete, list) | | `resources.py` | MCP resource handlers with URI patterns | | `schemas.py` | Pydantic models for structured tool return types | | `access_control.py` | Model permission checks | | `formatters.py` | LLM-friendly hierarchical text output | | `performance.py` | Connection pooling, record/field caching | | `error_handling.py` | Centralized error types and handler | | `error_sanitizer.py` | Strips sensitive data from error messages | The server operates in two modes: **Standard** (requires the Odoo MCP module with `/mcp/` endpoints) and **YOLO** (connects directly to `/xmlrpc/` endpoints, no module needed). ## License By contributing, you agree that your contributions will be licensed under the [Mozilla Public License 2.0](LICENSE).