Skip to main content
Glama
Odoo 17 Project Management MCP

Odoo 17 Project Management MCP

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.

راهنمای فارسی · Installation · Technical architecture · Tool catalog · Security

Architecture

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.

Related MCP server: OdooSurface MCP

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.

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:

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:

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:

export ODOO_MCP_TOKEN='the-same-value-as-MCP_AUTH_TOKEN'
[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.

See the installation guide 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

make install
make lint
make test
make build

Development Notes

This repository is maintained as part of an ongoing development and learning process.

See CONTRIBUTING.md. Licensed under the MIT License.

Available Tools

32 tools
add_task_commentA

Post a comment to an allowed task's Odoo chatter as the configured service account.

Inputs: body (required), task_id (required). Returns: object

archive_taskA
Idempotent

Archive or unarchive a task; this is the preferred reversible alternative to deletion.

Inputs: task_id (required), archived. Returns: object

check_odoo_connectionA
Read-only

Check Odoo 17 authentication, optional capabilities, policy, and model permissions.

Inputs: no named parameters. Returns: object

create_projectA

Create and policy-register a project when ODOO_ALLOW_PROJECT_CREATION is enabled.

Inputs: name (required), date_end, date_start, task_label, +4 more. Returns: object

create_project_milestoneA

Create a milestone when milestones are enabled on the allowed project.

Inputs: name (required), project_id (required), deadline. Returns: object

create_project_stageC

Create a Kanban column scoped to exactly one allowed project.

Inputs: name (required), project_id (required), fold, sequence, +1 more. Returns: object

create_project_tagB

Create an Odoo tag scoped to one allowed project.

Inputs: name (required), project_id (required), color. Returns: object

create_subtaskA

Create a subtask in the same allowed project as its verified parent task.

Inputs: name (required), parent_task_id (required), tag_ids, deadline, +5 more. Returns: object

create_taskC

Create a task with description, assignees, estimate, stage, tags, parent and blockers.

Inputs: name (required), project_id (required), tag_ids, deadline, +8 more. Returns: object

create_timesheetB

Log time on an allowed task using the official Timesheets feature.

Inputs: hours (required), task_id (required), description (required), user_id, +1 more. Returns: object

delete_taskA
Destructive

Permanently delete a task. Requires hard-delete config and confirmation 'DELETE TASK '.

Inputs: task_id (required), confirmation (required). Returns: object

delete_timesheetB
Destructive

Permanently delete time. Requires hard-delete config and 'DELETE TIMESHEET '.

Inputs: line_id (required), confirmation (required). Returns: object

get_projectA
Read-only

Read one allowed Odoo project and its planning settings.

Inputs: project_id (required). Returns: object

get_project_boardB
Read-only

Return a planning snapshot grouped by Backlog/In Progress/etc. Kanban columns.

Inputs: project_id (required), limit, include_archived. Returns: object

get_project_workloadA
Read-only

Summarize active task counts and estimated-hour shares by assignee for planning.

Inputs: project_id (required). Returns: object

get_taskA
Read-only

Read one task after resolving and checking its real Odoo project.

Inputs: task_id (required). Returns: object

list_allowed_projectsA
Read-only

List only projects in the configured MCP allowlist.

Inputs: no named parameters. Returns: result

list_assignable_usersA
Read-only

Resolve active internal Odoo users that this MCP may assign to tasks/timesheets.

Inputs: limit, query. Returns: result

list_project_milestonesA
Read-only

List milestones for one allowed project.

Inputs: project_id (required). Returns: result

list_project_stagesA
Read-only

List Kanban columns (task stages) available to an allowed project.

Inputs: project_id (required). Returns: result

list_project_tagsA
Read-only

List global and project-specific task tags available to an allowed project.

Inputs: project_id (required). Returns: result

list_tasksB
Read-only

Search tasks, always restricted to allowed projects, with bounded pagination.

Inputs: limit, query, offset, tag_id, +6 more. Returns: result

list_task_statesA
Read-only

List live Odoo 17 task state keys; task state is separate from the Kanban stage.

Inputs: no named parameters. Returns: result

list_timesheetsA
Read-only

List official Odoo Timesheets entries, restricted to an allowed project/task.

Inputs: project_id (required), limit, date_to, task_id, +2 more. Returns: result

move_task_to_stageA
Idempotent

Move a task to an allowed Kanban column after validating task and stage projects.

Inputs: task_id (required), stage_id (required). Returns: object

set_task_stateA
Idempotent

Set a task's Odoo state using a key returned by list_task_states.

Inputs: state (required), task_id (required). Returns: object

set_task_tagsA
Idempotent

Replace a task's complete tag set with validated global/project tags.

Inputs: tag_ids (required), task_id (required). Returns: object

update_projectA
Idempotent

Update explicitly supplied planning fields on an allowed project.

Inputs: project_id (required), name, date_end, date_start, +8 more. Returns: object

update_project_milestoneA
Idempotent

Update the name, deadline, or reached flag of an allowed-project milestone.

Inputs: milestone_id (required), name, deadline, is_reached, +1 more. Returns: object

update_project_stageA
Idempotent

Edit a project-scoped stage; global or cross-policy stages are intentionally read-only.

Inputs: stage_id (required), project_id (required), fold, name, +3 more. Returns: object

update_taskB
Idempotent

Update only supplied fields on an allowed task; explicit clear flags avoid accidental erasure.

Inputs: task_id (required), name, tag_ids, deadline, +15 more. Returns: object

update_timesheetA
Idempotent

Update supplied fields on a verified allowed-project timesheet entry.

Inputs: line_id (required), hours, user_id, work_date, +1 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    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

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to interact with Odoo ERP systems through XML-RPC communication. Provides access to Odoo models, records, methods, and data structures for comprehensive ERP integration.
      2
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI agents to interact with Odoo ERP as the authenticated user, with tools for discovery, planning, and mutations bounded by user permissions.
      36
      65 npm
      2
      Apache 2.0
    • A
      license
      Not graded
      quality
      D
      maintenance
      Connects AI agents in Cursor to an Odoo instance, enabling natural language management of projects, epics, tasks, and milestones with tags and priorities.
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      Enables authenticated team members to manage Odoo projects, tasks, timesheets, and milestones through Claude, with per-user token-based authentication.
      -