Read-only Odoo tools over JSON-RPC: server info, model field introspection, and a restricted search_read limited to an allow list of models whose domain field names may not contain dots, so related-record traversal is not possible. A draft-create tool is registered only when allowWrite is enabled, and is limited to sale.order and project.task with the draft state enforced by the plugin.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-odoo
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:maxmilian/dsh-odoo
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
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
Links
More in this category
Tencent/WeKnora#dsh-weknora★ 33047
Four read-only tools over a WeKnora knowledge base: list knowledge bases, hybrid passage search, reassemble one document's chunks in order, and WeKnora's own cited RAG or ReAct-agent answer with a resumable session id.
superdesigndev/treg★ 4972
Tool catalog for agents: search ~2,600 external endpoints (SEO and SERP, backlinks, social, people and company enrichment, ad libraries, scraping) by the task you want done, read each one's parameters and per-call price, then call it with the credential injected server-side. Ships the skill plus an MCP row that stays disabled until TREG_TOKEN is set.
TencentCloudBase/CloudBase-AI-Toolkit#dsh-plugin★ 1136
Tencent CloudBase backend for DeepSeek Harness — scaffold and deploy full-stack apps from chat, render query results as table cards with paging, sorting and CSV export, preview a deployment on its domain, and call the CloudBase MCP toolset (`mcp__cloudbase__*`) with device-code login.
gitroomhq/postiz-agent#dsh-postiz★ 509
Connects DeepSeek Harness to Postiz over MCP: list connected social media channels, fetch per-platform posting rules, and schedule, draft, or publish posts to X, LinkedIn, Instagram, Facebook, Threads, TikTok, YouTube, Reddit, Bluesky, Mastodon, Discord, Slack, Telegram and more; adds a postiz workflow skill.
EthanYoQ/Invoice-Downloader#dsh-invoice-downloader★ 502
Local IMAP invoice download, OCR, archive, and Excel reimbursement summaries for DeepSeek Harness.
anysearch-team/anysearch-dsh★ 457
AnySearch-powered real-time web and vertical search provider for DeepSeek Harness.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.