maxmilian/dsh-odoo
Read-only Odoo tools for DeepSeek Harness, with an opt-in restricted draft-create tool.
Project Overview项目介绍
dsh-odoo is a read-only DeepSeek Harness plugin for the Odoo external API. It connects via JSON-RPC 2.0 to the /jsonrpc endpoint and lets an agent query fourteen allow-listed models such as contacts, sales orders, invoices, project tasks, leads, and stock. One opt-in tool can create a strictly limited draft record. Use it when an agent must inspect Odoo data without altering server state. Caveat: only Odoo 18 on a directly reachable Docker image was verified; reverse proxies, Odoo Online, and Odoo.sh remain untested.
dsh-odoo 是一款面向 Odoo 外部 API 的只读 DeepSeek Harness 插件,通过 JSON-RPC 2.0 连接 /jsonrpc 端点,让智能体查询合作伙伴、销售订单、发票、项目任务、线索、库存等 14 个白名单模型。仅在显式开启 allowWrite 时注册一个受限的草稿创建工具。适用于需要安全检视 Odoo 业务数据又不修改服务器状态的场景。注意:仅在 Odoo 18 Docker 镜像上做过实测,反向代理后、Odoo Online 与 Odoo.sh 尚未验证。
请帮我了解并安装插件:【dsh-odoo】【https://github.com/maxmilian/dsh-odoo】
Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。
Or use CLI install (for developers)或使用命令行安装(适合开发者)
CLI Install命令行安装
dsh plugin --profile web add github:maxmilian/dsh-odoo
把 maxmilian/dsh-odoo 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
dsh-odoo
dsh-odoo is a free, open-source, read-only DeepSeek Harness plugin for the Odoo external API.
It lets an agent inspect Odoo business data — contacts, quotations, sales orders, invoices,
project tasks, leads, stock — without changing Odoo state. One opt-in tool can create a
strictly limited draft record, and it is not even registered unless you enable it.
✅ Verified against Odoo 18 on 2026-08-27 — the official
odoo:18image reportingserver_version18.0-20260817. Most compatibility assumptions were checked on a live server; the results, and what is still unverified, are indocs/live-verification.md: only Odoo 18 was tested (8–17 and 19 were not), and only a Docker image reached directly — behind a reverse proxy, Odoo Online and Odoo.sh remain untested. The plugin speaks JSON-RPC only and needs/jsonrpcto be reachable (see Transport). When something breaks, please report the Odoo version and serie, how it is deployed (Odoo Online, Odoo.sh, self-hosted, container, and which reverse proxy sits in front), and the full output ofodoo_server_info.
Tools
| Tool | Purpose |
|---|---|
odoo_server_info |
Read the server version and the authenticated user id. |
odoo_describe_model |
List the queryable fields of one allow-listed model. |
odoo_search_read |
Run a restricted search_read on one allow-listed model. |
odoo_create_draft |
Create one draft record. Requires allowWrite: true; otherwise it is never registered. |
Transport
This plugin speaks JSON-RPC 2.0 to POST {baseUrl}/jsonrpc, so your Odoo server must expose
that endpoint (it is provided by the web module). If the endpoint is missing, redirected, or
intercepted by a proxy, every tool fails with a TRANSPORT_UNSUPPORTED error that says so.
XML-RPC is not implemented.
Model availability
The 14 allow-listed models are not guaranteed to exist on every Odoo. Only the base models
are always present; the rest come from business modules a stock Odoo does not install.
| Module | Allow-listed models | Installed by default |
|---|---|---|
base |
res.partner, res.users, res.company |
yes |
product |
product.product, product.template |
no |
sale / sale_management |
sale.order, sale.order.line |
no |
purchase |
purchase.order |
no |
account |
account.move, account.move.line |
no |
project |
project.project, project.task |
no |
crm |
crm.lead |
no |
stock |
stock.quant |
no |
On a stock Odoo 18 with no business modules, querying sale.order fails with
ODOO_VALIDATION_ERROR carrying the upstream reason Object sale.order doesn't exist. Call
odoo_describe_model first to confirm a model is available on your instance.
Requirements
- DeepSeek Harness with compatible
@deepseek-ai/dsh-toolsAPIs - Node.js 22.19 or newer in the 22.x line, or Node.js 24 or newer
- Bun 1.3.5 or newer when installing from GitHub source or developing locally
- An Odoo URL, database name, login, and API key (or password) with access to the models you query
Configuration
Environment variables are recommended so credentials do not appear in a profile patch:
export ODOO_URL='https://odoo.example.com'
export ODOO_DB='production'
export ODOO_USERNAME='integration@example.com'
export ODOO_API_KEY='your-api-key'
Plugin config takes precedence over environment variables:
| Config | Environment fallback | Default |
|---|---|---|
baseUrl |
ODOO_URL |
required |
db |
ODOO_DB |
required |
username |
ODOO_USERNAME |
required |
apiKey |
ODOO_API_KEY |
required |
companyId |
ODOO_COMPANY_ID |
unset |
allowWrite |
none (deliberately) | false |
locale |
none | en (en / zh-TW / zh-CN / ja) |
defaultLimit |
none | 20 (1–100) |
requestTimeoutMs |
none | 30000 (1–300000) |
maxResponseBytes |
none | 1000000 (1–52428800) |
Credentials are only required when a tool actually runs: installing the plugin without filling
them in does not break profile loading. locale switches tool and parameter descriptions;
tool names and error messages always stay in English.
Safety
- Read-only by default. No
write,unlink, or workflow actions exist in this release. - Model allow list. Queries are limited to 14 standard models:
res.partner,res.users,res.company,product.product,product.template,sale.order,sale.order.line,purchase.order,account.move,account.move.line,project.project,project.task,crm.lead,stock.quant. - No relational traversal. Domain field names may not contain dots. To filter by a related
record, query the related model first and then filter with
('partner_id','in',[ids]). This keeps the allow list an actual capability boundary instead of a suggestion. - No binary fields. Fields whose Odoo type is
binaryare rejected, and default field sets never include one. - Bounded responses. Default fields per model,
limit≤ 100,offset + limit≤ 10000, single string values truncated at 2000 characters, and a hard byte cap on every response. - Only non-archived records are returned; the
active_testcontext is not exposed. - Draft creation is opt-in and fixed.
sale.orderis always created withstate=draft;project.taskmay not specifystateorstage_id, so Odoo applies its own default stage. Only an allow-listed subset of fields is accepted, and one-to-many commands are rejected.
Non-goals for 0.1
- No business wrapper tools (
list_customers,list_quotations, …). They depend on field assumptions that cannot be verified without a live Odoo, and a wrong assumption returns an empty result instead of an error — the worst failure mode for an agent. Deferred to 0.2. - No updates, deletions, or workflow transitions; no attachments or report generation.
- No XML-RPC transport, no model discovery, no multi-database switching, no cursor pagination.
Development
bun install
bun run lint
bun run typecheck
bun run test
bun run build
scripts/smoke-odoo.sh runs a manual end-to-end check against a real server; it is deliberately
excluded from CI.
License
MIT
PerryLink/dsh-auto-review
PerryLink/dsh-mcp-panel
Vithrive/Deepseek-Harness-for-VS-Code
fb0sh/dsh-pentester
shaokeyibb/dsh-plugin-product-subagents
lusblead/dsh-Kingdom