Skip to main content
Glama
fatemeh-mohseni-AI

Odoo 17 Project Management MCP

README.md
# Odoo 17 Project Management MCP

A security-focused, remotely accessible Model Context Protocol server for managing work in the
official **Odoo 17 Project** application. The primary runtime is a long-lived, authenticated
**Streamable HTTP** service. It supports self-hosted and Docker-based Odoo through the documented
XML-RPC external API.

> Status: alpha (`0.2.1`). Test against a staging Odoo database before enabling production writes.

[راهنمای فارسی](README.fa.md) · [Installation](docs/INSTALLATION.md) ·
[Technical architecture](docs/TECHNICAL.md) · [Tool catalog](docs/TOOLS.md) ·
[Security](docs/SECURITY.md)

## Architecture

```mermaid
flowchart LR
    A["Codex"] -->|"HTTPS + Bearer token"| B["MCP Streamable HTTP"]
    B -->|"XML-RPC"| C["Odoo 17 Project"]
```

Default endpoints:

- MCP: `http://SERVER_IP:31080/mcp`
- unauthenticated liveness check: `http://SERVER_IP:31080/health`

`/mcp` requires `Authorization: Bearer <MCP_AUTH_TOKEN>`. Missing credentials return HTTP 401 and
an invalid token returns HTTP 403. `stdio` remains available only as an explicitly selected legacy
transport.

## What it supports

| Area | Capabilities |
|---|---|
| Access boundary | Mandatory project-ID allowlist; optional assignee allowlist; indirect records are re-checked |
| Projects | List, read, create (feature-gated), and update planning settings |
| Board columns | List, create, reorder and edit project-scoped task stages |
| Tasks | Compact stage-filtered search, full single-task read, create, update, move, archive/unarchive and protected hard-delete |
| Planning | Assignees, estimates, deadlines, priority, workload, dependencies and blockers |
| Structure | Subtasks and milestones |
| Classification | Project tags and task tag assignment |
| Collaboration | Task chatter comments as the configured service account |
| Status | Independent Kanban stage and Odoo task-state changes |
| Time tracking | Official Timesheets integration when `hr_timesheet` is installed |

There is deliberately **no generic `execute_kw`, model, domain, field or method tool**. The MCP
cannot be converted into unrestricted access to the rest of Odoo.

For large projects, call `list_project_stages` once and then use
`list_tasks(project_id=..., stage_name="In Progress", limit=25, offset=0)`. The stage filter runs
inside Odoo, not after retrieval. List results exclude descriptions, dependency arrays and audit
timestamps; use `get_task(task_id)` only for a selected task's full details.

## Quick start — Docker Compose (recommended)

```bash
git clone https://github.com/fatemeh-mohseni-AI/Odoo17-Project_management-MCP.git
cd Odoo17-Project_management-MCP
cp .env.example .env
openssl rand -hex 32
```

Copy the generated token into `MCP_AUTH_TOKEN` and configure the Odoo service account and approved
database IDs in `.env`:

```dotenv
ODOO_URL=http://odoo17-test:8069
ODOO_DB=mcp_test
ODOO_USERNAME=ai-project-service@example.com
ODOO_API_KEY=replace-with-an-odoo-api-key
ODOO_ALLOWED_PROJECT_IDS=12
ODOO_ALLOWED_ASSIGNEE_USER_IDS=7,19

MCP_TRANSPORT=streamable-http
MCP_HOST=0.0.0.0
MCP_PORT=31080
MCP_AUTH_TOKEN=replace-with-the-generated-token
MCP_PUBLISH_HOST=0.0.0.0
```

Attach the MCP container to the Odoo Docker network and start the persistent service:

```bash
export ODOO_DOCKER_NETWORK=odoo17_mcp_test_net
chmod 600 .env
docker compose up -d --build
docker compose ps
curl http://127.0.0.1:31080/health
```

Connect Codex from another machine:

```bash
export ODOO_MCP_TOKEN='the-same-value-as-MCP_AUTH_TOKEN'
```

```toml
[mcp_servers.odoo_project]
url = "http://SERVER_IP:31080/mcp"
bearer_token_env_var = "ODOO_MCP_TOKEN"
enabled = true
required = true
startup_timeout_sec = 30
tool_timeout_sec = 120
default_tools_approval_mode = "writes"

[mcp_servers.odoo_project.tools.delete_task]
approval_mode = "prompt"

[mcp_servers.odoo_project.tools.delete_timesheet]
approval_mode = "prompt"
```

Use direct HTTP only on a trusted private network/VPN. For traffic crossing an untrusted network,
terminate HTTPS in a reverse proxy; an example is provided in
[`deploy/nginx.conf.example`](deploy/nginx.conf.example).

See the [installation guide](docs/INSTALLATION.md) for ID discovery, firewall/TLS guidance, local
Python installation, troubleshooting, and the optional legacy stdio mode.

## Safe defaults

- Streamable HTTP is the default transport and cannot start without a bearer token of at least 32
  characters.
- An empty project allowlist stops normal operation unless creation-only bootstrap is explicitly
  enabled.
- Project creation and permanent deletion are off by default.
- Hard deletion additionally requires an exact record-specific confirmation phrase.
- Credentials are never returned by tools or written to audit logs.
- Global stages and stages shared with a disallowed project are read-only through this MCP.

The MCP allowlist is a second boundary, not a replacement for Odoo ACLs and record rules. Use a
dedicated least-privilege Odoo account restricted to the same projects.

## Compatibility

- Odoo major version: **17 only**
- Odoo deployment: self-hosted package or Docker, reachable over HTTP(S)
- Default MCP transport: Streamable HTTP on `/mcp`
- Optional legacy transport: stdio with `MCP_TRANSPORT=stdio`
- MCP SDK: official Python SDK `2.x`
- Timesheets: official `hr_timesheet` feature required

## Development

```bash
make install
make lint
make test
make build
```

See [CONTRIBUTING.md](CONTRIBUTING.md). Licensed under the [MIT License](LICENSE).

TDQS

B3.3/5.0

Scored across 32 tools

Disambiguation4/5

Most tools have clear resource+action boundaries (list/get/create/update/delete), and descriptions explicitly disambiguate potentially similar pairs like task state vs. Kanban stage and archive vs. delete. The main residual ambiguity is between the generic update_task and specialized mutators such as move_task_to_stage, set_task_state, and set_task_tags.

Naming Consistency5/5

Tool names consistently follow a snake_case verb_noun pattern: get_, list_, create_, update_, delete_, set_, move_, archive_, add_, and check_. Minor outliers like check_odoo_connection are still predictable and do not break the overall pattern.

Tool Count2/5

With 32 tools, the surface is substantially above the 3-15 well-scoped range and falls into the 25+ 'too many' band. While the Odoo project-management domain is broad, the large number of specialized mutators and lifecycle operations creates meaningful selection overhead for an agent.

Completeness3/5

Core task and timesheet CRUD is well covered, and projects, stages, tags, and milestones have read/create/update support. However, there are notable lifecycle gaps: no delete or archive for projects, stages, tags, or milestones, and no way to read or delete task comments.

Maintenance

ActivityMaintained
ResponsivenessNo issues