io.github.minhhq-a1/odoo-pulse
PYPI · ODOO-PULSE · SCANNED SEP 20
An AI business analyst for Odoo ERP (18+) — one-call reports with verdicts, over MCP
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
- 0 of 29 dependencies flagged as unhealthy. View diagnostics → Pass
Provenance & Transparency48
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 46 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability68
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 5578 tokens (~179/item across 31 items; 31 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management80
- Stability observed for 24 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage71
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 0% of tool parameters carry a description.Fail
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety75
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 0 of 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "delete_records" implies "delete" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
- An AI judge read all 32 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the io.github.minhhq-a1/odoo-pulse MCP server?
io.github.minhhq-a1/odoo-pulse runs locally as a PyPI package, launched with uvx odoo-pulse. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
pypi · odoo-pulse
claude mcp add minhhq-a1-odoo-pulse -- uvx odoo-pulse
{
"mcpServers": {
"minhhq-a1-odoo-pulse": {
"command": "uvx",
"args": [
"odoo-pulse"
]
}
}
} {
"servers": {
"minhhq-a1-odoo-pulse": {
"command": "uvx",
"args": [
"odoo-pulse"
]
}
}
} codex mcp add minhhq-a1-odoo-pulse -- uvx odoo-pulse
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"minhhq-a1-odoo-pulse": {
"type": "local",
"command": [
"uvx",
"odoo-pulse"
],
"enabled": true
}
}
} openclaw mcp add minhhq-a1-odoo-pulse --command uvx --arg odoo-pulse
mcp_servers:
minhhq-a1-odoo-pulse:
command: "uvx"
args: ["odoo-pulse"] {
"McpServers": {
"minhhq-a1-odoo-pulse": {
"Transport": "stdio",
"Command": "uvx",
"Arguments": [
"odoo-pulse"
]
}
}
} assistant mcp add minhhq-a1-odoo-pulse -t stdio -c uvx -a odoo-pulse
{
"mcpServers": {
"minhhq-a1-odoo-pulse": {
"command": "uvx",
"args": [
"odoo-pulse"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 20 Sept 26 −3
- Stability: pass → 0.80 functional
- 19 Sept 26 0
- Stability: 0.97 → pass security
- 18 Sept 26 +16
- Malware scan: unverified → pass ▲ security
- 17 Sept 26 −15
- Malware scan: pass → unverified ▼ security
- 16 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 87 to 90. That category is still filling its 30-day observation window: 26 days of observed history at the previous scan, 27 at this one. The score rises as the window fills, whether or not the server changes.
- 15 Sept 26 +15
- Malware scan: unverified → pass ▲ security
- 14 Sept 26 −14
- Malware scan: pass → unverified ▼ security
- 13 Sept 26 −3
- Stability: pass → 0.80 functional
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 20 Sept 2026 · Analysed pypi/odoo-pulse@1.9.1
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | pypi |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | hatchling.build |
Background: Why install scripts are a supply-chain risk →
Dependencies 29 packages
| Packages resolved | 29 |
|---|---|
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
absence_overview ~164
Report who is off and where coverage is thin, in one call. Composes approved hr.leave records overlapping the next `days` days, pending approval requests, and per-department headcount into an absence calendar, coverage-risk flags (share of a department off at some point in the window >= coverage_threshold), and a verdict. Args: days: Look-ahead window in days (default 14). coverage_threshold: Department share off in the window that counts as a coverage risk (default 0.3). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh).
| Name | Type | Req | Description |
|---|---|---|---|
| coverage_threshold | number | – | – |
| days | integer | – | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
aggregate_records ~212
Group and aggregate records server-side (one call instead of pulling rows). Args: model: Technical model name, e.g. 'sale.order'. group_by: One or more fields to group on. A field may carry a granularity, e.g. 'date_order:month'. measures: 'field:agg' specs. Bare 'field' means sum. Allowed aggregators: sum, avg, min, max, count, count_distinct. Omit to count records. domain: Odoo search domain (list of triplets). Defaults to all records. limit: Max groups (capped by ODOO_MAX_RECORDS). offset: Pagination offset over groups. order: Sort spec, e.g. 'amount_total desc'.
| Name | Type | Req | Description |
|---|---|---|---|
| domain | – | – | – |
| group_by | array | yes | – |
| limit | – | – | – |
| measures | – | – | – |
| model | string | yes | – |
| offset | integer | – | – |
| order | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
business_pulse ~141
One-call company briefing: sales, leads, receivables, tasks, absences. The morning-standup view of the whole company: yesterday's confirmed revenue and new leads, overdue customer invoices, tasks past deadline, and who is off today. Sections are independent — if an app is not installed, its section reports available=false and the rest still renders. Args: timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). company: Optional company name (ilike) or id; scopes every section.
| Name | Type | Req | Description |
|---|---|---|---|
| company | – | – | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
confirm_sale_order ~37
Confirm a quotation into a sales order (sale.order action_confirm).
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| order_id | integer | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_contact ~84
Create a contact (res.partner). Preview unless confirm=True. Use extra_values to set fields this helper doesn't model (e.g. {"vat": ...}).
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| – | – | – | |
| extra_values | – | – | – |
| is_company | boolean | – | – |
| name | string | yes | – |
| parent_id | – | – | – |
| phone | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_lead ~95
Create a CRM lead/opportunity (crm.lead). Preview unless confirm=True. Use extra_values to set fields this helper doesn't model, including custom mandatory fields (e.g. {"presales_id": 5}).
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| contact_name | – | – | – |
| description | – | – | – |
| – | – | – | |
| extra_values | – | – | – |
| name | string | yes | – |
| phone | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_record ~89
Create one record. Returns a preview unless confirm=True. Args: model: Odoo model name (must be in ODOO_WRITABLE_MODELS). values: Field -> value mapping for the new record. confirm: Set True to actually create; otherwise a dry-run preview.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| model | string | yes | – |
| values | object | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
create_task ~107
Create a project task (project.task). Preview unless confirm=True. Use list_projects to find the project_id first. Use extra_values to set fields this helper doesn't model (e.g. {"tag_ids": [(6, 0, [1])]}).
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| date_deadline | – | – | – |
| description | – | – | – |
| extra_values | – | – | – |
| name | string | yes | – |
| project_id | integer | yes | – |
| user_id | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
delete_records ~100
Delete one or more records. Returns a preview unless confirm=True. Deletes also require ODOO_ALLOW_DELETE=true on the server. Args: model: Odoo model name (must be in ODOO_WRITABLE_MODELS). ids: Record ids to delete. confirm: Set True to actually delete; otherwise a dry-run preview.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| ids | array | yes | – |
| model | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
get_model_fields ~67
Inspect the schema of an Odoo model. Returns each field's label, type, help text, requiredness and relation. Pass `fields` to limit the result to specific field names. Example model: 'res.partner'.
| Name | Type | Req | Description |
|---|---|---|---|
| fields | – | – | – |
| model | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
inventory_risk ~210
Report stock at risk — shortages and dead stock — in one call. Shortages are storable products with negative forecasted quantity (demand exceeds supply). Dead stock is on-hand product with no done stock move in dead_stock_days, valued at standard_price. The dead-stock check is a bounded heuristic: when the recently-moved product list hits the 200-group cap, a risk flags that the list may over-count. Args: dead_stock_days: No-movement window for dead stock (default 90). top_n: Rows listed per breakdown section (default 10). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). company: Optional company id or name; scopes stock quantities via allowed_company_ids context and dead-stock moves via company_id.
| Name | Type | Req | Description |
|---|---|---|---|
| company | – | – | – |
| dead_stock_days | integer | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
list_models ~55
List Odoo models (technical name + label). Optionally filter by a case-insensitive substring matched against the model name or label, e.g. 'sale', 'res.partner', 'invoice'.
| Name | Type | Req | Description |
|---|---|---|---|
| name_filter | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
odoo_version ~20
Check connectivity and return the Odoo server version info.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
pipeline_review ~359
Report the health of the CRM pipeline, in one call. Composes open crm.lead opportunities into totals (count, expected and probability-weighted revenue), stalled deals (no stage change in stalled_days), close-date buckets, per-stage / per-salesperson breakdowns, the recent win rate, and a rule-based verdict. Args: salesperson: Optional filter on user_id.name (ilike). team: Optional filter on team_id.name (ilike). stalled_days: Days without a stage change before a deal counts as stalled (default 14). lookahead_days: Days ahead that count as "closing soon" (default 30). win_rate_days: Look-back window for the won/lost ratio (default 90). top_n: Max stalled deals listed in the breakdown (default 5). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). company: Optional company name (ilike) or id; scopes every count and total to that company. stalled_pct_at_risk: Stalled share (%) at which the verdict drops to at_risk (default 25). stalled_pct_off_track: Stalled share (%) at which the verdict drops to off_track (default 50).
| Name | Type | Req | Description |
|---|---|---|---|
| company | – | – | – |
| lookahead_days | integer | – | – |
| salesperson | – | – | – |
| stalled_days | integer | – | – |
| stalled_pct_at_risk | number | – | – |
| stalled_pct_off_track | number | – | – |
| team | – | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| win_rate_days | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
portfolio_health ~203
Portfolio overview: one row per project, joined by id server-side. Replaces the project_status_report + project_profitability pair the overview tab used to call and join BY NAME in JS (which broke on duplicate project names). Returns raw signals only — the client computes its own health score from user-configured thresholds. Args: manager: Optional project-manager filter (user_id.name ilike). customer: Optional customer filter (partner_id.name ilike). include_on_hold: Keep on_hold projects (default True). include_done: Keep done projects (default False). lookahead_days: "due soon" window for derived health (default 7). timezone_offset: UTC offset for dates (default 7).
| Name | Type | Req | Description |
|---|---|---|---|
| customer | – | – | – |
| include_done | boolean | – | – |
| include_on_hold | boolean | – | – |
| lookahead_days | integer | – | – |
| manager | – | – | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
procurement_watch ~228
Report purchasing health — late receipts and stale RFQs — in one call. Composes confirmed purchase orders into open value, receipts past their planned date, per-vendor open spend, plus a count of quotation requests (draft/sent) older than rfq_stale_days, and a rule-based verdict. Args: late_grace_days: Days past date_planned before a receipt counts as late (default 0). rfq_stale_days: Age in days after which a draft/sent RFQ counts as stale (default 7). top_n: Rows in the late-receipts / top-vendors lists (default 5). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). company: Optional company name (ilike) or id to scope the report.
| Name | Type | Req | Description |
|---|---|---|---|
| company | – | – | – |
| late_grace_days | integer | – | – |
| rfq_stale_days | integer | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
production_health ~189
Report manufacturing health — late starts and stuck orders — in one call. Composes open mrp.production orders (confirmed / progress / to_close) into a by-state backlog, orders that should have started but haven't (confirmed with date_start in the past), orders running longer than stuck_days, and a rule-based verdict. Args: stuck_days: Days an order may run (progress/to_close) before it counts as stuck (default 14). top_n: Rows in the behind-start / stuck lists (default 5). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). company: Optional company name (ilike) or id to scope the report.
| Name | Type | Req | Description |
|---|---|---|---|
| company | – | – | – |
| stuck_days | integer | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
project_budget ~327
Report planned vs actual budget per project, line by line. Reads the Budgets app (budget.line on Odoo 18+, else crossovered.budget.lines) and matches lines to active projects by a line-level project_id m2o when the instance has one, else through the project's analytic account. Amounts are absolute company-currency sums; server-computed practical/theoretical amounts are used as-is. Also compares each project's total analytic cost against the practical amounts booked on its budget lines, flagging spend the budget does not capture. When the filter matches exactly one project the report gains a per-line breakdown. No date filters: budget lines carry their own period. Args: project: Optional project-name filter (name ilike). Exactly one match switches on the per-line breakdown. manager: Optional project-manager filter (user_id.name ilike). customer: Optional customer filter (partner_id.name ilike). top_n: Rows in the per-line breakdown (default 10). burn_pct_at_risk: Burn %% >= this -> at_risk (default 80). burn_pct_off_track: Burn %% >= this -> off_track (default 100). timezone_offset: UTC offset for "today" (default 7).
| Name | Type | Req | Description |
|---|---|---|---|
| burn_pct_at_risk | number | – | – |
| burn_pct_off_track | number | – | – |
| customer | – | – | – |
| manager | – | – | – |
| project | – | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
project_dashboard ~360
Everything the project-detail page needs, in one call. Replaces ~12 separate calls (status, profitability, milestones, weekly hours, budgets, budget lines, cost breakdowns, delivery by month). Use `include` to re-fetch only what changed: checkbox toggles -> ["hours", "delivery_monthly"]; budget chip changes -> ["budget_detail", "delivery_monthly"]. Sections fail soft: a broken section lands in "errors" while the rest return. Args: project_id: project.project id. only_closed_stages / closed_stage_names / single_assignee_only: sub-task filters, as in project_subtask_hours; they shape the "hours" and "delivery_monthly" sections. budget_ids: crossovered.budget / budget.analytic ids to select. OMIT (null) for ALL budgets of the project; pass [] for NO selection (budget_detail then shows all-time cost only). These two states are different on purpose — do not send [] to mean "all". include: Subset of ["core", "hours", "budgets", "budget_detail", "delivery_monthly"]; omitted = all. "core" covers project, milestones, finance and weekly_logged. lookahead_days: "due soon" window for derived health (default 7). timezone_offset: UTC offset for dates (default 7).
| Name | Type | Req | Description |
|---|---|---|---|
| budget_ids | – | – | – |
| closed_stage_names | – | – | – |
| include | – | – | – |
| lookahead_days | integer | – | – |
| only_closed_stages | boolean | – | – |
| project_id | integer | yes | – |
| single_assignee_only | boolean | – | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
project_profitability ~365
Report delivery hours, money and budget burn per project in one call. Composes active project.project records (filtered by name / manager / customer) with timesheet hours (account.analytic.line grouped by project), analytic cost/revenue (grouped by analytic account) and the Budgets app when installed, into a per-project burn verdict (off_track / at_risk / on_track). When the filter matches exactly one project the report gains per-employee and per-task breakdowns. Args: project: Optional project-name filter (name ilike). Exactly one match switches on the drill-down breakdowns. manager: Optional project-manager filter (user_id.name ilike). customer: Optional customer filter (partner_id.name ilike). date_from: Optional YYYY-MM-DD lower bound on logged hours and analytic amounts. Allocated hours and budgets stay lifetime totals, so ANY date filter disables the burn verdicts (verdict "n/a", burn percentages null). date_to: Optional YYYY-MM-DD upper bound (same caveat). top_n: Rows in the drill-down breakdowns (default 5). burn_pct_at_risk: Worst burn %% >= this -> at_risk (default 80). burn_pct_off_track: Worst burn %% >= this -> off_track (default 100). timezone_offset: UTC offset for "today" (default 7).
| Name | Type | Req | Description |
|---|---|---|---|
| burn_pct_at_risk | number | – | – |
| burn_pct_off_track | number | – | – |
| customer | – | – | – |
| date_from | – | – | – |
| date_to | – | – | – |
| manager | – | – | – |
| project | – | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
project_status_report ~278
Report which projects are in trouble, across a portfolio, in one call. Composes project.project records (filtered by manager / customer / name) with their project.milestone rows into a per-project derived health verdict (off_track / at_risk / on_track) driven by overdue-or-unreached milestones and the project end date. Surfaces the PM's declared status alongside, flags projects declared healthier than the data (divergence), and ranks by risk. Args: manager: Optional project-manager filter (user_id.name ilike). customer: Optional customer filter (partner_id.name ilike). project: Optional project-name filter (name ilike) to narrow the set. include_on_hold: Keep projects whose declared status is on_hold (default True). include_done: Keep projects whose declared status is done (default False). lookahead_days: Days ahead that count as "due soon" for at_risk (default 7). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh).
| Name | Type | Req | Description |
|---|---|---|---|
| customer | – | – | – |
| include_done | boolean | – | – |
| include_on_hold | boolean | – | – |
| lookahead_days | integer | – | – |
| manager | – | – | – |
| project | – | – | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
project_subtask_hours ~354
Total sub-task hours for one project, filtered server-side, in ONE call. Sums delivery/allocated/effective hours over the project's sub-tasks (project.task with parent_id set). Use this instead of paginating project.task through search_read — especially for the "exactly one assignee" condition, which Odoo domains cannot express. Args: project_id: project.project id (int, not name). only_closed_stages: Count only tasks whose stage name is in closed_stage_names (default False). Cancelled tasks DO count toward delivery hours (business decision 2026-07-15). closed_stage_names: Stage names treated as closed (default ["Done", "Cancelled", "Delivered"]). single_assignee_only: Count only tasks with exactly 1 user in user_ids (default False). group_by_month: Also bucket by local-time month of date_end; tasks without date_end are excluded from the buckets and summarised under "no_date_end" (default False). periods: Optional list of {"date_from": "YYYY-MM-DD", "date_to": "YYYY-MM-DD"} ranges applied to date_end, OR-combined (matching per-budget-period filtering, not a union). Empty/omitted = no date filter. timezone_offset: UTC offset for dates (default 7).
| Name | Type | Req | Description |
|---|---|---|---|
| closed_stage_names | – | – | – |
| group_by_month | boolean | – | – |
| only_closed_stages | boolean | – | – |
| periods | – | – | – |
| project_id | integer | yes | – |
| single_assignee_only | boolean | – | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
read_attachment ~107
Read an ir.attachment: metadata always, base64 content when small enough. Binary attachments under ODOO_MAX_ATTACHMENT_BYTES are returned with their base64 `datas`; larger ones return metadata plus a warning. URL-type attachments return the link, never binary data. Args: attachment_id: The ir.attachment id. include_data: When False, return metadata only (no base64 fetch).
| Name | Type | Req | Description |
|---|---|---|---|
| attachment_id | integer | yes | – |
| include_data | boolean | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
read_records ~42
Fetch specific records by their ids. Pass `fields` to limit columns.
| Name | Type | Req | Description |
|---|---|---|---|
| fields | – | – | – |
| ids | array | yes | – |
| model | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
receivables_health ~232
Report AR/AP aging and who owes what, in one call. Composes open posted invoices and vendor bills into standard aging buckets (not_due / 1-30 / 31-60 / 61-90 / 90+), the share of receivables overdue, the top overdue customers, and a verdict. Args: top_n: Rows in the top-overdue-customers list (default 5). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). company: Optional company name (ilike) or id to scope the report. overdue_pct_at_risk: Overdue AR share (%) that drops the verdict to at_risk (default 25). overdue_pct_off_track: Overdue AR share (%) that drops the verdict to off_track (default 50).
| Name | Type | Req | Description |
|---|---|---|---|
| company | – | – | – |
| overdue_pct_at_risk | number | – | – |
| overdue_pct_off_track | number | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
sales_snapshot ~283
Report how sales are going versus the previous period, in one call. Composes confirmed sale.order records over the last two periods into revenue/order deltas, top customers, top products (server-side aggregate over order lines), a stale-quotation count, and a growing / steady / declining verdict. Args: period_days: Length of the comparison window in days (default 7). stale_quote_days: Age in days after which a draft/sent quotation counts as stale (default 7). top_n: Rows in the top-customers / top-products lists (default 5). timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). growth_threshold_pct: Delta (%) beyond which the verdict is growing / declining (default 10). company: Optional company name (ilike) or id to scope the report. trend_weeks: Weeks of history bucketed into the weekly_revenue trend series; 0 disables the extra query (default 8).
| Name | Type | Req | Description |
|---|---|---|---|
| company | – | – | – |
| growth_threshold_pct | number | – | – |
| period_days | integer | – | – |
| stale_quote_days | integer | – | – |
| timezone_offset | integer | – | – |
| top_n | integer | – | – |
| trend_weeks | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
search_count ~32
Count records in a model matching an Odoo domain filter.
| Name | Type | Req | Description |
|---|---|---|---|
| domain | – | – | – |
| model | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
search_read ~181
Query records from an Odoo model. Args: model: Technical model name, e.g. 'sale.order', 'res.partner'. domain: Odoo search domain as a list of triplets, e.g. [["state", "=", "sale"], ["amount_total", ">", 1000]]. Use 'and'/'|' operators as Odoo expects. Defaults to all records. fields: Field names to return. Omit to let Odoo decide (can be large). limit: Max records (capped by ODOO_MAX_RECORDS). offset: Pagination offset. order: Sort spec, e.g. 'date_order desc'.
| Name | Type | Req | Description |
|---|---|---|---|
| domain | – | – | – |
| fields | – | – | – |
| limit | – | – | – |
| model | string | yes | – |
| offset | integer | – | – |
| order | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
standup_digest ~203
Generate a daily standup digest for a project. Fetches all active subtasks (parent_id != False, stage not in exclude_stages, exactly 1 assigned user) and categorises them by deadline into OVERDUE / TODAY / UPCOMING / NO DEADLINE sections. Returns a plain-text digest ready to paste or send as an email body. Args: project: Project name (ilike match, e.g. "The Body Shop"). exclude_stages: Stage names to treat as closed. Defaults to ["Done", "Cancelled", "Delivered"]. lookahead_days: Days ahead to include in UPCOMING (default 7). timezone_offset: UTC offset in hours for "today" (default 7 = Asia/Ho_Chi_Minh).
| Name | Type | Req | Description |
|---|---|---|---|
| exclude_stages | – | – | – |
| lookahead_days | integer | – | – |
| project | string | yes | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
team_workload ~286
Report who is over- or under-loaded, in one call. Composes the open project.task records in scope into a per-assignee load (open count plus overdue / due-soon / high-priority / no-deadline tallies), flags overloaded members and unassigned work, and returns a rule-based verdict. Done tasks carry no current load and are excluded. Args: project: Optional project-name filter (ilike). exclude_stages: Stage names dropped from scope. Default ["Cancelled"]. done_stages: Stage names treated as completed. Default ["Done", "Delivered"]. lookahead_days: Days ahead that count as "due soon" (default 7). overload_threshold: Open-task count above which a member is flagged "overloaded" (default 8). Sign-off point with the workflow owner. timezone_offset: UTC offset for "today" (default 7 = Asia/Ho_Chi_Minh). subtasks_only: Count only subtasks (parent_id != False), the team's unit of work. Default True.
| Name | Type | Req | Description |
|---|---|---|---|
| done_stages | – | – | – |
| exclude_stages | – | – | – |
| lookahead_days | integer | – | – |
| overload_threshold | integer | – | – |
| project | – | – | – |
| subtasks_only | boolean | – | – |
| timezone_offset | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
update_records ~104
Update one or more records. Returns a preview unless confirm=True. Args: model: Odoo model name (must be in ODOO_WRITABLE_MODELS). ids: Record ids to update. values: Field -> value mapping to write. confirm: Set True to actually write; otherwise a dry-run preview.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| ids | array | yes | – |
| model | string | yes | – |
| values | object | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | string | yes | – |
No examples provided.
What is the io.github.minhhq-a1/odoo-pulse MCP server?
io.github.minhhq-a1/odoo-pulse is an MCP server listed in the public MCP registry as io.github.minhhq-a1/odoo-pulse. An AI business analyst for Odoo ERP (18+), one-call reports with verdicts, over MCP. This page covers its PyPI package (odoo-pulse).
Is the io.github.minhhq-a1/odoo-pulse MCP server safe to use?
io.github.minhhq-a1/odoo-pulse scores 77 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the io.github.minhhq-a1/odoo-pulse MCP server expose?
io.github.minhhq-a1/odoo-pulse exposes 31 tools: odoo_version, list_models, get_model_fields, search_read, search_count, and 26 more. Their descriptions and schemas cost roughly 5,514 tokens of context every time the server is loaded.
Is the io.github.minhhq-a1/odoo-pulse MCP server still maintained?
io.github.minhhq-a1/odoo-pulse is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the io.github.minhhq-a1/odoo-pulse MCP server under?
io.github.minhhq-a1/odoo-pulse declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.