Skip to main content
Glama

ppm_export_risks

Export a filtered risk register to XLSX. Optionally specify project, portfolio, risk level, or include closed risks.

Instructions

Export the risk register to XLSX.

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idNo
portfolio_idNo
risk_levelNo
include_closedNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The actual handler function for the 'ppm_export_risks' tool. Decorated with @mcp.tool(), it accepts optional project_id, portfolio_id, risk_level, and include_closed parameters, builds a vals dict, and delegates to _run_export_wizard('ppm.risk.export.wizard', vals).
    @mcp.tool()
    def ppm_export_risks(
        project_id: int | None = None,
        portfolio_id: int | None = None,
        risk_level: str | None = None,
        include_closed: bool = False,
    ) -> dict[str, Any]:
        """Export the risk register to XLSX.
    
        `risk_level` is one of 'low', 'medium', 'high', 'critical' — or omit for all.
        """
        vals: dict[str, Any] = {"include_closed": include_closed}
        if project_id is not None:
            vals["project_id"] = project_id
        if portfolio_id is not None:
            vals["portfolio_id"] = portfolio_id
        if risk_level:
            vals["risk_level"] = risk_level
        return _run_export_wizard("ppm.risk.export.wizard", vals)
  • The helper function _run_export_wizard that ppm_export_risks calls. It creates a wizard record via execute_kw and then calls the action_export button method on it, returning a dict with the wizard model name and the action result.
    def _run_export_wizard(
        model: str,
        values: dict[str, Any],
    ) -> dict[str, Any]:
        wizard_id = client().execute_kw(model, "create", [values])
        action = client().call_action(model, "action_export", [wizard_id])
        # action is `ir.actions.act_url` with /web/content/{attachment_id}?download=true
        return {"wizard": model, "action": action}
  • The tool registration: the @mcp.tool() decorator on line 400 registers ppm_export_risks as an MCP tool on the FastMCP instance named 'qod-ppm'.
    @mcp.tool()
  • The OdooClient helper methods (execute_kw and call_action) used by _run_export_wizard to create the wizard record and invoke the export action.
    def execute_kw(
        self,
        model: str,
        method: str,
        args: list[Any] | None = None,
        kwargs: dict[str, Any] | None = None,
    ) -> Any:
        return self._call(
            "object",
            "execute_kw",
            [self.db, self.uid, self.secret, model, method, args or [], kwargs or {}],
        )
    
    def search_read(
        self,
        model: str,
        domain: list[Any] | None = None,
        fields: list[str] | None = None,
        limit: int | None = None,
        offset: int | None = None,
        order: str | None = None,
    ) -> list[dict[str, Any]]:
        kwargs: dict[str, Any] = {}
        if fields is not None:
            kwargs["fields"] = fields
        if limit is not None:
            kwargs["limit"] = limit
        if offset is not None:
            kwargs["offset"] = offset
        if order is not None:
            kwargs["order"] = order
        return self.execute_kw(model, "search_read", [domain or []], kwargs)
    
    def read(
        self,
        model: str,
        ids: list[int],
        fields: list[str] | None = None,
    ) -> list[dict[str, Any]]:
        kwargs = {"fields": fields} if fields else {}
        return self.execute_kw(model, "read", [ids], kwargs)
    
    def call_action(self, model: str, method: str, ids: list[int]) -> Any:
        """Invoke an `action_*` button method on the given record ids."""
        return self.execute_kw(model, method, [ids])
    
    def close(self) -> None:
        self._http.close()
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are absent, so the description carries full burden. It fails to disclose whether the tool modifies data, what it returns (e.g., download link), or any permissions required. The description only states the export action without behavioral details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is brief (two sentences) and front-loaded with the main action. It is efficient but could benefit from additional context without becoming overly verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having an output schema, the description lacks context about return behavior, parameter dependencies, and when to use this tool. Given four parameters and no descriptions, the description is insufficient for an agent to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must compensate. It only explains 'risk_level' values, leaving 'project_id', 'portfolio_id', and 'include_closed' undocumented. The meaning of these parameters and their interplay is unclear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific action ('Export'), resource ('risk register'), and output format ('XLSX'). It distinguishes from sibling tools that perform other risk-related actions like closing or moving risks.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides guidance on the 'risk_level' parameter, explaining its valid values and that omission exports all. However, it does not explain when to use this tool versus other risk tools (e.g., ppm_risk_close) or provide context about prerequisites like needing a project or portfolio.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wethti/qod-ppm-odoo-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server