agentCLAWHUBUnverified

drivethru-odoo

Talk to an Odoo ERP through its `drivethru_mcp` MCP server — discover the available Odoo tools at runtime and call them to look up eBay products/inventory, push eBay orders and read tracking, run the Accounts Payable PO→vendor-bill flow, review documents in the Documents app against their purchase orders and fix incorrect PO line pricing (the "check the Purchasing folder against the POs" / vendor-invoice pricing-review workflow, filing each document into Matched or Questions), schedule MRP production batches, drive vendor replenishment purchasing (run the replenishment report → curate lines → add to a PO → hand style/color/size/qty to the vendor's purchasing skill → write pricing + confirmation back and confirm the PO), and retrieve internal SOPs / best practices / policies from the Knowledge base scoped to the asking person's permissions. Use whenever the user needs to read from or write to Odoo, especially when you are answering a person inside an Odoo Discuss conversation.

OpenClaw

Rank

62

Safety

84

Downloads

2.0k

Updated

Oct 9, 2026

Version

0.9.4

Source

CLAWHUB

About

What it does, and when to use it.

Capability contract not published. No trust telemetry is available yet. 2K downloads reported by the source. Last updated 10/9/2026.

Avoid when

  • Contract metadata is missing or unavailable for deterministic execution.

Risk flags: missing_or_unavailable_contract, trust_data_unavailable, schema_references_missing

Public facts

Every fact links back to the source it came from.

Vendor
Clawhubvendor · observed Oct 9, 2026
Protocol compatibility
OpenClawcompatibility · observed Oct 9, 2026
Adoption signal
2K downloadsadoption · observed Oct 9, 2026
Latest release
0.9.4release · observed Sep 17, 2026
Handshake status
UNKNOWNsecurity

Install and run

Setup complexity: low.

clawhub skill install s17fq291581evd78xzn1930b0n87bfny:drivethru-odoo
  1. Install using `clawhub skill install s17fq291581evd78xzn1930b0n87bfny:drivethru-odoo` in an isolated environment before connecting it to live workloads.
  2. No published capability contract is available yet, so validate auth and request/response behavior manually.
  3. Review the upstream CLAWHUB listing at https://clawhub.ai/zmtucker/drivethru-odoo before using production credentials.

Contract: missing

curl -s "https://www.xpersona.co/api/v1/agents/clawhub-zmtucker-drivethru-odoo/snapshot"

Documentation

CLAWHUB

152,121 characters of source documentation, loaded on request.

Extracted files

5 files captured from the source.

SKILL.md

---
name: drivethru-odoo
description: Talk to an Odoo ERP through its `drivethru_mcp` MCP server — discover the available Odoo tools at runtime and call them to look up eBay products/inventory, push eBay orders and read tracking, run the Accounts Payable PO→vendor-bill flow, review documents in the Documents app against their purchase orders and fix incorrect PO line pricing (the "check the Purchasing folder against the POs" / vendor-invoice pricing-review workflow, filing each document into Matched or Questions), schedule MRP production batches, drive vendor replenishment purchasing (run the replenishment report → curate lines → add to a PO → hand style/color/size/qty to the vendor's purchasing skill → write pricing + confirmation back and confirm the PO), and retrieve internal SOPs / best practices / policies from the Knowledge base scoped to the asking person's permissions. Use whenever the user needs to read from or write to Odoo, especially when you are answering a person inside an Odoo Discuss conversation.
version: 0.9.4
emoji: 🏭
homepage: https://www.odoo.com
metadata:
  openclaw:
    requires:
      env: [ODOO_MCP_URL, ODOO_MCP_TOKEN]
      bins: [python3]
    primaryEnv: ODOO_MCP_TOKEN
    envVars:
      ODOO_MCP_URL:
        required: true
        description: >
          Full URL of the Odoo MCP endpoint, e.g.
          `https://odoo.example.com/drivethru_mcp/v1` (note the path — this is
          the MCP server exposed by the `drivethru_mcp` Odoo module, not the
          Odoo base URL).
      ODOO_MCP_TOKEN:
        required: true
        description: >
          The `drivethru.mcp_key` value from the Odoo `drivethru_mcp` module,
          sent as `Authorization: Bearer`. Treat as a secret; never paste into
          chat.
    install:
      uv:
        - mcp>=1.9.0
        - pypdf>=4.0   # local PDF text extraction for the PO pricing-review intake (scripts/po_docs.py)
---

# Odoo Drive Thru MCP integration

This skill gives you the Odoo **`drivethru_mcp`** MCP server — the curated Odoo
tool surface (`documents_*`, `ap_*`, `po_*`, `mfg_*`, `production_*`,
`replenish_*`, `knowledge_*`, `ebay_*`, `docs_*`) exposed over Streamable-HTTP.
`ODOO_MCP_URL` and `ODOO_MCP_TOKEN` are already configured for this agent.
**Never tell the user you can't reach Odoo, that you "don't have the tools in
this thread," or cite the web instead — either call a tool, or state the exact
tool call you attempted and the error it returned.**

## How you call Odoo (runtime-aware — read this first)

There are two ways the `drivethru_mcp` tools reach you. Work out which you have,
in this order:

1. **Native / callable MCP tools — preferred, no shell needed.** If the Odoo
   tools are attached to you as native tools, **call them directly** — e.g.
   `documents_list_folders {"name": "Purchasing"}`. This is how a chat agent
   (an Odoo Discuss bot, etc.) uses Odoo; it does **not** need a shell.
   - They may be **deferred / lazy-loaded**: if your runtime hides tools

_meta.json

{
  "ownerId": "kn715tnf30wegyr6mdbfa17avd87bjr6",
  "slug": "drivethru-odoo",
  "version": "0.9.4",
  "publishedAt": 1789682303073
}

references/agent_api_endpoints.md

# Odoo `agent_api` endpoint surface

All endpoints are served by the Odoo `agent_api` addon, authenticated with the
`X-Agent-API-Key` header. Responses are JSON. The client unwraps a top-level
`{"success": true, "data": {...}}` envelope when present and raises on
`success: false` or non-2xx status.

Base URL = `ODOO_URL` (no trailing slash). All paths below are relative to it.

## Sales / eBay — `scripts/sales.py`

| Method | Path                                              | Action         |
| ------ | ------------------------------------------------- | -------------- |
| GET    | `/agent_api/v1/ebay/products`                     | `list-products` |
| GET    | `/agent_api/v1/ebay/inventory?skus=A,B`           | `inventory`    |
| POST   | `/agent_api/v1/ebay/orders`                       | `create-order` |
| GET    | `/agent_api/v1/ebay/orders/<odoo_order_id>/tracking` | `tracking`  |

### Product shape (from `list-products`)

```json
{
  "sku": "ABC-1", "title": "...", "description": "...", "brand": "...",
  "mpn": "...", "condition": "NEW", "category_id": "...",
  "images": ["https://..."], "aspects": {"Color": ["Navy"]},
  "cost": 12.50, "quantity": 7, "weight_oz": 6.0,
  "package_length_in": 0, "package_width_in": 0, "package_height_in": 0
}
```

### Order-create payload (POST body built by `create-order`)

The `create-order` action accepts an eBay order object and maps it to:

```json
{
  "ebay_order_id": "...", "ebay_legacy_order_id": "...", "creation_date": "...",
  "buyer_username": "...", "buyer_email": "...", "currency": "USD",
  "subtotal": 0.0, "tax": 0.0, "shipping": 0.0, "total": 0.0,
  "line_items": [
    {"line_item_id": "...", "sku": "...", "title": "...", "quantity": 1,
     "unit_price": 0.0, "line_total": 0.0, "tax": 0.0}
  ],
  "shipping_address": {"name": "...", "address_line_1": "...", "address_line_2": "...",
     "city": "...", "state": "...", "postal_code": "...", "country": "US",
     "phone": "...", "email": "..."},
  "billing_address": { ... }
}
```

Response: `{odoo_order_id, odoo_order_name, already_existed, confirmed,
partner_id, shipping_partner_id, invoice_partner_id, confirm_error}`.
`already_existed: true` ⇒ idempotent skip (Odoo already had this eBay order).

### Tracking response

`{"shipped": true|false, "tracking": {"carrier", "tracking_number",
"shipped_date"} | null}`. `tracking` is null until the order ships.

## Accounts Payable — `scripts/ap.py`

| Method | Path                                              | Action            |
| ------ | ------------------------------------------------- | ----------------- |
| GET    | `/agent_api/v1/ap/purchase_orders`                | `search-pos`      |
| GET    | `/agent_api/v1/ap/purchase_orders/<po_id>`        | `get-po`          |
| PUT    | `/agent_api/v1/ap/purchase_orders/<po_id>/lines`  | `update-po-lines` |
| POST   | `/agent_api/v1/ap/invoices`                       | `create-bill`     |
| GET    | `/agent_api/v1/ap/invoices/<bill_id>`             | `ge

references/po_pricing_review.md

# Document-driven PO pricing review (batch)

The pattern behind *"go through every document in the Purchasing folder, check
its pricing against the purchase order, fix any line that's wrong, mark the PO
checked, and file the document."* This runs many times a day over 5–50+
documents, so the whole design is built to (a) keep the model's context window
small no matter how many documents there are, and (b) leave the Purchasing
inbox empty when it's done — every document ends up in **Matched** or
**Questions**.

Read `docs_get {"slug": "documents"}` and `docs_get {"slug": "invoices"}` for
the underlying tool semantics; this file is the operating procedure.

## The efficiency rule: extract text out-of-context, once

`documents_get` returns each file's bytes as **base64**, and reading a PDF
through a multimodal reader adds a **page image** on top. Both are enormous
next to the ~300–600 characters of text that actually matter per document. Do
that per file across a folder and the context window fills with base64 and
renders — the single biggest cost in a multi-document run.

**So do not loop `documents_get` (or a PDF reader) over the folder.** Use the
intake helper, which fetches every file, decodes and extracts the text
**locally**, and returns compact JSON — text only, no base64, no image:

```bash
python3 scripts/po_docs.py extract '{"folder": "Purchasing"}'
```

Returns `{"folder", "count", "documents": [{document_id, name, mimetype,
text, chars, needs_vision, open_activities}]}`. One call = the whole folder as
plain text. Read that; work from it.

- **`needs_vision: true`** on a document means the text pass came up empty (a
  scanned/image-only PDF or an image file). Only for those, fall back to
  `documents_get {"document_id"}` and read the bytes with a vision-capable
  reader — never for the whole folder.
- If the helper can't run (no shell, or `ODOO_MCP_URL`/`ODOO_MCP_TOKEN` unset),
  fall back to `documents_get` **one document at a time**, extract what you
  need, and don't carry the base64 forward. Never fetch the whole folder's
  bytes into context at once.

## Reading a document (per file)

Extract from the document's **text**, not its filename:

- **PO number** — the authoritative PO# is *inside* the document. Filenames can
  carry the vendor's order number instead (e.g. a file named
  `Order Acknowledgement 48482500.pdf` whose real PO is `P13183` in the body).
  Search Odoo on the PO# you read from the text.
- **Line items** — item/style, color, size, quantity, and **unit price** per
  line. Vendor size upcharges are normal (base sizes one price; 2XL/3XL/4XL
  higher) — that's correct pricing, not an error.
- **Totals are a cross-check, not the source of truth.** A shipment
  acknowledgement is often **one box of a multi-shipment order**, so its total
  is legitimately less than the PO total — the missing lines ship later. Match
  **line by line**, and treat a total gap that's fully explained by un-shipped
  lines as *not* a discrepancy.

references/production_scheduling.md

# Production scheduling (MRP) data model

The production actions in `scripts/production.py` map the
`/agent_api/v1/production/*` surface of the Production Scheduling Agent
Integration Schematic.

## Entities

| Entity                   | Odoo model              | Meaning                                            |
| ------------------------ | ----------------------- | -------------------------------------------------- |
| **Production batch**     | `mrp.production.batch`  | A batch of MOs sharing a machine and time slot.    |
| **Workcenter**           | `mrp.workcenter`        | A machine, e.g. "Manual Press A".                  |
| **Production center**    | `production.center`     | An area grouping machines, e.g. "Screen Print Floor". |
| **Decoration method**    | `decoration.method`     | A process type, e.g. "Screen Print", "Embroidery". |

## The writable scheduling fields

Each batch is scheduled by writing any subset of:

| Field                     | Meaning                                              |
| ------------------------- | ---------------------------------------------------- |
| `sequence`                | **Run order** — the batch's rank in the queue, and the primary scheduling decision. Rank a whole queue with `production_set_run_order`. |
| `manual_sequence`         | A manufacturing manager pinned this batch by hand; agent `sequence` writes skip it. |
| `primary_workcenter_id`   | Machine assignment.                                  |
| `production_center_id`    | Derived from the workcenter if omitted.              |
| `date_planned_start`      | ISO 8601 (UTC). Optional — a refinement on the run order, not a substitute for it. |
| `date_planned_finished`   | Auto-computed from start + Σ MO `duration_expected` unless set explicitly. |

## Event dates only lead when they're near

An `event_date` that is late or within `event_horizon_days` (default 5) sets
`event_imminent` and outranks everything else in the queue. A **distant** event
date does not: past the horizon a batch is ordered by its *governing deadline*
— the earlier of its event and ship dates — so a far-off event gives way to a
sooner ship date instead of jumping the queue.

## Art readiness tiers the queue

`production_schedule_queue` does not rank on dates alone. A batch whose decals
aren't printed (`print_decals_status` = `no` / `partial` / `sample`) or whose
artwork isn't ready (`art_status` != `done`) can't run, so it is **deferred
below runnable work** — until it's due within `art_release_days` (default 3),
when `art_at_risk` flips true and it is **expedited to the top**.

A top-ranked batch with `art_ready: false` is a call to chase the art, not a
job to schedule; `art_blockers` names what's missing. The
`drivethru-production-scheduler` skill covers this in full.

The server applies writes in safe order: run order → `production_center_id` →
`primary_workcenter_id` (derives center if omitted) → `date_planned_start`
(auto-computes finish) → `date_planned_
Github ReposUpdated 3h agoRank 70

AionUi

Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!

MCPOPENCLAW
Github ReposUpdated 6mo agoRank 70

activepieces

AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents

OPENCLAW
Github ReposUpdated 6mo agoRank 70

cherry-studio

AI productivity studio with smart chat, autonomous agents, and 300+ assistants.

MCPOPENCLAW
Github ReposUpdated 7mo agoRank 70

CopilotKit

The Frontend for Agents & Generative UI. React + Angular

OPENCLAW

Machine-readable data

The same record, as JSON, for agents and crawlers.

{
  "facts": [
    {
      "factKey": "vendor",
      "category": "vendor",
      "label": "Vendor",
      "value": "Clawhub",
      "href": "https://clawhub.ai/zmtucker/skills/drivethru-odoo",
      "sourceUrl": "https://clawhub.ai/zmtucker/skills/drivethru-odoo",
      "sourceType": "profile",
      "confidence": "medium",
      "observedAt": "2026-10-09T20:33:23.739Z",
      "isPublic": true
    },
    {
      "factKey": "protocols",
      "category": "compatibility",
      "label": "Protocol compatibility",
      "value": "OpenClaw",
      "href": "https://www.xpersona.co/api/v1/agents/clawhub-zmtucker-drivethru-odoo/contract",
      "sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-zmtucker-drivethru-odoo/contract",
      "sourceType": "contract",
      "confidence": "medium",
      "observedAt": "2026-10-09T20:33:23.739Z",
      "isPublic": true
    },
    {
      "factKey": "traction",
      "category": "adoption",
      "label": "Adoption signal",
      "value": "2K downloads",
      "href": "https://clawhub.ai/zmtucker/drivethru-odoo",
      "sourceUrl": "https://clawhub.ai/zmtucker/drivethru-odoo",
      "sourceType": "profile",
      "confidence": "medium",
      "observedAt": "2026-10-09T20:33:23.739Z",
      "isPublic": true
    },
    {
      "factKey": "latest_release",
      "category": "release",
      "label": "Latest release",
      "value": "0.9.4",
      "href": "https://clawhub.ai/zmtucker/drivethru-odoo",
      "sourceUrl": "https://clawhub.ai/zmtucker/drivethru-odoo",
      "sourceType": "release",
      "confidence": "medium",
      "observedAt": "2026-09-17T21:58:23.073Z",
      "isPublic": true
    },
    {
      "factKey": "handshake_status",
      "category": "security",
      "label": "Handshake status",
      "value": "UNKNOWN",
      "href": "https://www.xpersona.co/api/v1/agents/clawhub-zmtucker-drivethru-odoo/trust",
      "sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-zmtucker-drivethru-odoo/trust",
      "sourceType": "trust",
      "confidence": "medium",
      "observedAt": null,
      "isPublic": true
    }
  ],
  "events": [
    {
      "eventType": "release",
      "title": "Release 0.9.4",
      "description": "drivethru-odoo 0.9.4 - Updated documentation in SKILL.md for clarity and precision. - Incremented version number to 0.9.4.",
      "href": "https://clawhub.ai/zmtucker/drivethru-odoo",
      "sourceUrl": "https://clawhub.ai/zmtucker/drivethru-odoo",
      "sourceType": "release",
      "confidence": "medium",
      "observedAt": "2026-09-17T21:58:23.073Z",
      "isPublic": true
    }
  ]
}

Record generated Oct 9, 2026.

Sponsored

Ads related to drivethru-odoo and adjacent AI workflows.