Skip to main content
Glama

qod-ppm-odoo-mcp

MCP server for the QOD PPM Odoo plugin.

Exposes the plugin's buttons, wizards, and workflow transitions as MCP tools — the things a generic Odoo CRUD server can't express.

Design

This server is intentionally thin. It does not reimplement Odoo CRUD. Run it alongside a generic Odoo MCP (e.g. ivnvxd/mcp-server-odoo):

Need

Use

Create/read/update/delete portfolios, programs, projects, tasks, risks, ...

Generic Odoo MCP (create_record, search_records, ...)

Transition workflow state (submit, approve, achieve, close, ...)

This server

Run a wizard (status report, CR reject, budget export, ...)

This server

Domain rules (P×I matrix move with validation, ...)

This server

Put simply: if there's a button in the Odoo UI that does something non-trivial when clicked, it's a tool here. CRUD wraps fields; this wraps buttons.

Related MCP server: Odoo MCP Server

Install

pip install qod-ppm-odoo-mcp

Or from source:

git clone https://github.com/wethti/qod-ppm-odoo-mcp
cd qod-ppm-odoo-mcp
pip install -e .

Configure

Create a service user in Odoo and give it the PPM groups you need (group_ppm_admin or scoped alternatives). Generate an API key from the user's preferences page. Then set:

export ODOO_URL="https://your-odoo.example.com"
export ODOO_DB="your_db_name"
export ODOO_USERNAME="ppm-service@example.com"
export ODOO_API_KEY="…"   # preferred
# or ODOO_PASSWORD="…"

A .env.example is included.

Run

stdio (default) — for Claude Desktop / Claude Code / anything that spawns an MCP server as a subprocess:

qod-ppm-mcp

Streamable HTTP — for remote access (another VPS, an agent host, etc.):

export QOD_PPM_MCP_TRANSPORT=http
export QOD_PPM_MCP_HOST=0.0.0.0
export QOD_PPM_MCP_PORT=8765
qod-ppm-mcp

Put a reverse proxy with TLS + auth in front if exposed to the internet.

Claude Code / Claude Desktop config

Add to ~/.claude.json (Claude Code) or claude_desktop_config.json:

{
  "mcpServers": {
    "qod-ppm": {
      "command": "qod-ppm-mcp",
      "env": {
        "ODOO_URL": "https://your-odoo.example.com",
        "ODOO_DB": "your_db_name",
        "ODOO_USERNAME": "ppm-service@example.com",
        "ODOO_API_KEY": "…"
      }
    },
    "odoo": {
      "command": "uvx",
      "args": ["mcp-server-odoo"],
      "env": {
        "ODOO_URL": "https://your-odoo.example.com",
        "ODOO_DB": "your_db_name",
        "ODOO_USERNAME": "ppm-service@example.com",
        "ODOO_API_KEY": "…"
      }
    }
  }
}

Both servers point to the same Odoo. Claude sees tools namespaced as mcp__qod-ppm__* (workflow actions) and mcp__odoo__* (generic CRUD).

Tool reference

Call ppm_list_action_tools to get the current list at runtime. Groups:

Milestones (ppm.milestone)

  • ppm_milestone_start / achieve / miss / cancel / reopen

Status Reports (ppm.status.report + wizard)

  • ppm_status_report_generate(project_id, period?, commentary?) — runs the wizard, auto-fills RAG/budget/risks/milestones, creates report

  • ppm_status_report_publish(report_id)

  • ppm_status_report_reset_draft(report_id)

  • ppm_status_report_print_url(report_id) — returns the PDF action

Change Requests (ppm.change.request + reject wizard)

  • ppm_change_request_submit / start_review / approve / reset_draft

  • ppm_change_request_reject(cr_id, reason) — runs the reject wizard

Risks (ppm.risk)

  • Workflow: ppm_risk_start_analysis / start_mitigation / start_monitoring / mark_occurred / close / reopen

  • ppm_risk_move_in_matrix(risk_id, probability, impact) — probability and impact are integers 1–5; server recomputes score and level

Issues (risks flagged as issue_type)

  • ppm_issue_assign / start / resolve / escalate

Role Assignments (ppm.role.assignment)

  • ppm_role_activate / approve_and_activate / revoke / reset_draft (each syncs the Odoo security group)

Exports (wizards → XLSX)

  • ppm_export_budget(project_id?, portfolio_id?, date_from?, date_to?, category_id?, include_closed?)

  • ppm_export_risks(project_id?, portfolio_id?, risk_level?, include_closed?)

  • ppm_export_resources(project_id?, employee_id?, department_id?, date_from?, date_to?, include_cancelled?)

All three return an ir.actions.act_url pointing at /web/content/<id>?download=true.

Client Card Projects

  • ppm_create_project_from_template(partner_id, template_id, project_name)

Introspection

  • ppm_ping() — auth + basic counts

  • ppm_list_action_tools() — self-describing tool list

Compatibility

  • Odoo 18.0 Community / Enterprise

  • QOD PPM modules: qod_ppm_core, qod_ppm_budget, qod_ppm_change_request, qod_ppm_client_card_projects, qod_ppm_dashboard, qod_ppm_resource, qod_ppm_risk, qod_ppm_roles, qod_ppm_roles_crm, qod_ppm_roles_mrp, qod_ppm_scoring, qod_ppm_status, qod_ppm_task_status

License

LGPL-3.0-or-later — matching the QOD PPM modules.

Available Tools

35 tools
ppm_change_request_approveB

Approve a Change Request under review; creates a baseline snapshot.

Inputs: cr_id (required). Returns: object

ppm_change_request_rejectB

Reject a Change Request with a required reason (runs the reject wizard).

Inputs: cr_id (required), reason (required). Returns: object

ppm_change_request_reset_draftB

Return a submitted or rejected Change Request to draft.

Inputs: cr_id (required). Returns: object

ppm_change_request_start_reviewB

Start review of a submitted Change Request.

Inputs: cr_id (required). Returns: object

ppm_change_request_submitB

Submit a draft Change Request for review; assigns a sequence number.

Inputs: cr_id (required). Returns: object

ppm_create_project_from_templateB

Clone a project template and attach it to a customer (res.partner).

Returns the new project id, name, portfolio_id, and program_id.

Inputs: partner_id (required), template_id (required), project_name (required). Returns: object

ppm_export_budgetA

Export budget lines to XLSX. Returns the download URL action.

At least one of project_id or portfolio_id is typically set; omit both to export everything visible to the service user.

Inputs: project_id, portfolio_id, date_from, date_to, +2 more. Returns: object

ppm_export_resourcesB

Export resource allocations to XLSX.

Inputs: project_id, employee_id, department_id, date_from, +2 more. Returns: object

ppm_export_risksB

Export the risk register to XLSX.

risk_level is one of 'low', 'medium', 'high', 'critical' — or omit for all.

Inputs: project_id, portfolio_id, risk_level, include_closed. Returns: object

ppm_issue_assignC

Move an issue from 'new' to 'assigned'.

Inputs: issue_id (required). Returns: object

ppm_issue_escalateC

Escalate an issue to management.

Inputs: issue_id (required). Returns: object

ppm_issue_resolveC

Resolve an issue; sets date_resolved.

Inputs: issue_id (required). Returns: object

ppm_issue_startB

Move an issue to 'in_progress'.

Inputs: issue_id (required). Returns: object

ppm_list_action_toolsA

List every PPM action/wizard tool this server exposes, with a one-line description.

Useful when Claude is deciding whether to call a custom tool or fall back to the generic Odoo MCP's update_record/search_records.

Inputs: no named parameters. Returns: result

ppm_milestone_achieveC

Mark a milestone as achieved; records today as the actual date.

Inputs: milestone_id (required). Returns: object

ppm_milestone_cancelC

Cancel a milestone.

Inputs: milestone_id (required). Returns: object

ppm_milestone_missC

Mark a milestone as missed.

Inputs: milestone_id (required). Returns: object

ppm_milestone_reopenB

Reopen a milestone back to 'planned'.

Inputs: milestone_id (required). Returns: object

ppm_milestone_startB

Transition a milestone from 'planned' to 'in_progress'.

Inputs: milestone_id (required). Returns: object

ppm_pingA

Verify the MCP server can authenticate to Odoo and hit the PPM models.

Returns {ok, uid, portfolios, programs, projects, risks} with counts.

Inputs: no named parameters. Returns: object

ppm_risk_closeC

Close a risk; sets date_closed.

Inputs: risk_id (required). Returns: object

ppm_risk_mark_occurredC

Mark a risk as occurred.

Inputs: risk_id (required). Returns: object

ppm_risk_move_in_matrixA

Move a risk in the P×I matrix.

Both probability and impact are integers 1–5 (matching the selection keys). The server recomputes risk_score and risk_level automatically.

Inputs: risk_id (required), probability (required), impact (required). Returns: object

ppm_risk_reopenC

Reopen a closed risk back to 'identified'.

Inputs: risk_id (required). Returns: object

ppm_risk_start_analysisB

Transition a risk from 'identified' to 'analyzing'.

Inputs: risk_id (required). Returns: object

ppm_risk_start_mitigationC

Transition a risk to 'mitigating'.

Inputs: risk_id (required). Returns: object

ppm_risk_start_monitoringC

Transition a risk to 'monitoring'.

Inputs: risk_id (required). Returns: object

ppm_role_activateB

Activate a draft role assignment (syncs the security group).

Inputs: assignment_id (required). Returns: object

ppm_role_approve_and_activateC

Approve and activate in one step.

Inputs: assignment_id (required). Returns: object

ppm_role_reset_draftC

Return a role assignment to draft.

Inputs: assignment_id (required). Returns: object

ppm_role_revokeB

Revoke a role assignment; removes the user from the security group.

Inputs: assignment_id (required). Returns: object

ppm_status_report_generateA

Run the Status Report wizard for a project.

The wizard auto-populates RAG, budget, risks, milestones from project data and creates a ppm.status.report in draft state.

Args: project_id: project.project id to report on. period: free-text period label (e.g. 'April 2026'); defaults to current month. commentary: optional commentary field.

Returns: dict with the created status report id and summary fields.

Inputs: project_id (required), period, commentary. Returns: object

ppm_status_report_print_urlA

Return the Odoo URL for the PDF render of a status report.

Odoo returns a report action; the caller fetches the PDF via that URL using the same credentials.

Inputs: report_id (required). Returns: object

ppm_status_report_publishC

Publish a draft status report.

Inputs: report_id (required). Returns: object

ppm_status_report_reset_draftB

Revert a published status report back to draft.

Inputs: report_id (required). Returns: object

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 35 tools

    Disambiguation5/5

    All tools are grouped by domain (change requests, issues, milestones, risks, roles, status reports, etc.) with distinct purposes. Each tool targets a specific action on a unique entity, making it easy for an agent to distinguish between them.

    Naming Consistency5/5

    Every tool follows the consistent pattern 'ppm_verb_noun' (e.g., ppm_change_request_approve, ppm_risk_close). The naming convention is uniform with snake_case and clear verb prefixes, ensuring predictability.

    Tool Count4/5

    35 tools is above the typical range, but the server covers a broad PPM domain with multiple entity lifecycles. Each tool addresses a specific action, and the count is justified by the scope, though slightly heavy.

    Completeness4/5

    The tool set covers key lifecycles (change requests, issues, milestones, risks, roles, status reports) and includes exports and a meta-tool. Missing create operations for some entities are mitigated by fallback to a generic Odoo MCP, but gaps exist.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      An MCP server that enables AI assistants to interact with Odoo ERP apps like Inventory, CRM, Sales, and Manufacturing. It allows users to read, create, and manage Odoo records and workflows using natural language commands.
      25
      11 npm
      1
      ISC
    • A
      license
      Not graded
      quality
      D
      maintenance
      An enterprise-grade MCP server for interacting with Odoo ERP through AI assistants, enabling guided workflows, native BI, and deep introspection.
      10
      MIT
    • A
      license
      D
      quality
      C
      maintenance
      MCP server for Odoo 18 that provides 85 tools for CRUD operations, business actions, and migration workflows, enabling natural language interaction with Odoo ERP.
      85
      5
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server integrating with Odoo ERP systems, enabling AI assistants to interact with Odoo data and functionality through tools and resources.
      MIT