Skip to content

Latest commit

 

History

History
229 lines (176 loc) · 13.1 KB

File metadata and controls

229 lines (176 loc) · 13.1 KB

Tool & prompt catalog

Public HTML catalog (hosted 46-tool contract, 2026-09-18): https://erpipe.com/tools

Source of truth in code:

Surface Count Where
Core phase tools (PHASE1…PHASE4) 27 @erpipe/core (packages/core)
Prompts 7 CLOUD_V1_PROMPTS
MCP resources 5 CLOUD_V1_RESOURCES
Hosted workspace MCP 46 tools ALL_TOOLS in erpipe-cloud agent/constants.ts
Self-host example 28 tools (27 phase + ping) @erpipe/worker-selfhost

Python parity contracts still pin the original D14 23-tool names; TypeScript adds model_facts, read_attachment, render_report, and get_current_context on the core phase lists (CLOUD_V1_TOOL_COUNT = 27).

Hosted extras (not in OSS self-host): multi-instance + lifecycle + Odoo event pull + HITL status + per-user memory + named verbs + ping on the cloud agent:

27 phase
+ ping
+ list_instances, search_across_instances, aggregate_across_instances, accounting_health_across_instances
+ create_instance, update_instance, rotate_instance_credentials, update_instance_cloudflare_access, delete_instance
+ preflight_odoo_capability, execute_approved_odoo_capability
+ get_write_approval_status
+ list_odoo_events, ack_odoo_event
+ remember_episode, recall_memory, forget_memory
+ execute_named_verb
= 46

Every Odoo-bound hosted tool requires an explicit instance key (list_instances to discover). Lifecycle tools require OAuth scope erpipe:write.

Tools — core phases (27)

Phase 1 — read / health (7)

Tool Purpose
search_records Query or domain search. Omit fields. Default limit 10, max 50. Prefer native JSON arrays for domain, e.g. [["id","in",[101,102]]]. Valid JSON strings and {conditions:[{field,operator,value}]} remain supported. Malformed JSON returns VALIDATION_ERROR, retryable:false and a correction hint before any search RPC; correct the filter before retrying. Empty query+domain is rejected (EMPTY_SEARCH).
model_facts Model intent snapshot (search / write / domain / overview)
read_record Read records by id
build_domain Build Odoo domain from structured input
list_models List accessible models
get_model_fields Field metadata for a model
health_check Connection + surface sanity

Phase 2 — diagnose / smart read (10)

Tool Purpose
aggregate_records Aggregations over a domain
search_employee HR employee search helpers
search_holidays Leave / holiday search helpers
get_odoo_profile Instance profile snapshot (includes installed modules by default)
get_current_context Timezone, active company, and allowed companies only — no module list. Uses context_get, then a user-record fallback when Odoo omits company keys (Odoo 19+).
schema_catalog Schema browsing helpers (fan-out + cache metrics on hosted)
diagnose_odoo_call Diagnose a failed model call
diagnose_access Access / ACL diagnosis
inspect_model_relationships Relational graph for a model
read_attachment Read ir.attachment payload (bounded)

Phase 3 — gated writes (5)

Tool Purpose
preview_write Preview create/write/unlink + approval token
validate_write Validate values against field policy
execute_approved_write Execute only with a valid approval token (may return outcome=pending while HITL waits)
chatter_post Post a chatter message
execute_method Non-CRUD method only. Not search_read/search_count/read (use search_records/read_record) and not create/write/unlink (use preview_write).

Writes require host policy. Prefer preview → validate → execute. On hosted product: connection writes_enabled defaults OFF; owner HITL / write_mode and journal gates still apply. When execute_approved_write returns HITL_APPROVAL_REQUIRED, that is a short wait (not failure, not a chat end): keep the approval object, tell the owner to Approve (typically ~30 seconds via dashboard / push / email), sleep 5–10s then poll get_write_approval_status (or retry execute with the same approval). After ~30–45s if still pending, tell the user it remains in Approvals.

Hosted policy refuses unlink before owner approval (UNLINK_DENIED). Core and the self-host example can execute a validated deletion when their write policy permits it; enabling hosted Writes does not enable deletion.

Phase 4 — reports (5)

Tool Purpose
generate_json2_payload Build JSON-2 style payloads; set target_version: "20.0" for the Odoo 20 read_group signature
upgrade_risk_report Upgrade risk analysis report
fit_gap_report Fit/gap workshop report
business_pack_report Business pack summary report
render_report Download a bounded PDF through the optional matching ERPipe Bridge; document permissions remain in force

Tools — hosted additions (18) and shared ping

Common

Tool Purpose
ping Lightweight liveness / agent identity

HITL approval (hosted)

Tool Purpose
get_write_approval_status Poll a write approval by approval_request_id while waiting for owner Approve (sleep 5–10s between polls; cap ~30–45s)

Named verbs (hosted)

Tool Purpose
execute_named_verb Run a dashboard-named execute_method alias. Reuses the method allowlist. Not HITL. Server actions are forbidden.

Multi-instance (read-only fleet)

Tool Purpose
list_instances List workspace Odoo instances + status. Best-effort tz / companies (context_status); never fails the list.
search_across_instances Fan-out search (≤10 targets, concurrency 4). Same empty-filter reject and per-instance cap 50 as search_records.
aggregate_across_instances Fan-out aggregates with attribution
accounting_health_across_instances Receivables-style health across instances

There are no cross-instance write tools.

Instance lifecycle (require erpipe:write)

Tool Purpose
create_instance Create instance (HTTPS preflight + auth probe)
update_instance Label / pause-resume (enabled)
rotate_instance_credentials Rotate stored credentials
update_instance_cloudflare_access Owner-only set/clear of a service-token pair. Set accepts an optional new Odoo password to recover both credentials together; otherwise preflights with the saved credential. Clear requires confirm: true and no credentials. Returns configured status only.
delete_instance Delete instance + encrypted secrets

Governance toggles (writes_enabled, write_mode, field policy, model allowlist, named verbs) stay dashboard-only.

create_instance also accepts optional access_client_id and access_client_secret together; supplying the pair requires workspace owner access. update_instance_cloudflare_access takes instance, action: "set" with both credentials, or action: "clear" with confirm: true and no credentials. Both operations require erpipe:write. Failed verification preserves the old pair. Paused instances can be configured; revoked instances cannot. No saved Client ID or secret is returned.

When both the Odoo credential and Access token have expired or changed, set may include a nonempty password containing the new Odoo password/API key. ERPipe verifies both new credentials together and stores them atomically on the existing connection. Omit password to keep the stored Odoo credential; clear rejects this field. Use protected runtime inputs, never credentials pasted into a conversation.

Optional Odoo capability approval

Tool Purpose
preflight_odoo_capability Discover and preflight a capability advertised by the optional companion addon without changing Odoo.
execute_approved_odoo_capability Execute after owner approval and a fresh capability fingerprint check.

Agent memory (per signed-in user)

Tool Purpose
recall_memory Look up similar past cases when the problem looks repeatable. Do not wait for the user to ask. Untrusted; verify live records.
remember_episode After a verified reusable fix, save a short lesson with source_event_ids. Never raw Odoo, credentials, trivia, or one-off lookups.
forget_memory Drop one saved memory after the user asks, or confirms it is wrong.

Odoo webhook pull queue

Tool Purpose
list_odoo_events List inbound webhook events for a connection
ack_odoo_event Acknowledge a handled event

Ingress: POST /hooks/{slug} with the connection webhook secret.

Prompts (7)

Prompt Purpose
diagnose_failed_odoo_call Guided diagnosis of a failed call
fit_gap_workshop Structure fit/gap from requirements
json2_migration_plan Plan XML-RPC/JSON-RPC → JSON-2 migration
safe_write_review Review create/write/unlink before execute
invoice_approval_chain Draft invoice find → validate → gated post
po_to_receipt PO / receipt / bill three-way match
customer_onboarding Dedup + gated customer create

Resources (5)

Name URI Purpose
odoo_models odoo://models List available models
odoo_model odoo://model/{model_name} Model + fields
odoo_record odoo://record/{model_name}/{record_id} One record
odoo_record_field odoo://record/{model_name}/{record_id}/{field_name} One binary field (size-capped; omitted when over the cap)
odoo_search odoo://search/{model_name}/{domain} Search with JSON domain

Transport notes

Transport Typical auth Package
XML-RPC username + password / API key as password @erpipe/odoo-xmlrpc + XmlRpcTransport
JSON-2 API key bearer Json2Transport

URL policy rejects unsafe origins (SSRF guard) before calling Odoo. Hosted product rechecks public-unicast DNS at create, session open, and per-call boundaries.

Both transports accept cfAccess: { clientId, clientSecret }. They construct only CF-Access-Client-Id and CF-Access-Client-Secret, including on authentication and version requests, and never follow redirects. The Odoo credential remains separate. Self-host uses CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET together. Configure the token in a Service Auth policy for the Odoo hostname; older hexadecimal and newer cfast_ secrets are both supported.

JSON-2 version discovery uses the public /web/webclient/version_info JSON-RPC route and validates result.server_version. A blocked or invalid probe does not fabricate a version.

Odoo 20 Community candidate

The October 1, 2026 candidate was tested on pinned Community 20.0 source using Python 3.12 and PostgreSQL 17. It is a local qualification, not a production deployment or a guarantee for Enterprise, Odoo.sh, Odoo Online or custom addons.

  • JSON-2 uses a dedicated API key with RPC scope. Record methods take args: [] and kwargs: { ids: [1, 2], ...namedParameters }; model methods take named parameters without ids. XML-RPC record methods retain args: [[1, 2]].
  • diagnose_access reads ir.access on 20 and the legacy access/rule models on older releases. Restricted users may query their records without permission to list security metadata; access_metadata.available reports that boundary.
  • search_holidays uses inclusive requested dates on 20, including day, half-day and hourly leave. Dates are not shifted by the reader's timezone.
  • read_attachment keeps its base64 datas output while reading Odoo 20's raw binary value. Binary resources also retain their bounded output. Attachment field policies treat datas and raw as the same protected content: denying either blocks both. Restrictive allow rules must explicitly permit both names; allowing only one refuses content. This also protects raw reads and writes, and metadata-only reads retain their separate field rules.
  • render_report requires the 20.0 Bridge and ordinary model, record, company and report-group permissions. Rendering runs as the RPC user in a fresh read-only transaction, bypasses stored print attachments and rolls back. Reports that write while printing are refused; field-restricted connections cannot render opaque PDFs through either the report tool or a raw method. This guard covers the audited native reports, not arbitrary custom Python that opens another cursor or causes external effects.
  • Legacy XML-RPC action_archive, action_unarchive and toggle_active are refused before sending because their native None response can fail after changing the record. Use a gated active write instead. A previous ambiguous call must be reconciled before any new write.

The 16–19 regression matrix covers native reads, schema, aggregation, resources, attachments, HR and gated writes/business methods. Companion-backed PDF is qualified on the 20.0 series; older Bridge series need their own PDF port.