← odooconsole.com

OdooConsole MCP reference — one endpoint, every instance

How to connect Claude, Cursor, ChatGPT or any MCP client to an Odoo instance hosted on OdooConsole. The MCP server is open source; see also pricing and the blog.

Every connector points at https://mcp.odooconsole.com/mcp. What a token carries decides what it reaches: a token for all instances reaches every instance's ERP on your account — choosing which per call — plus the provisioning tools; a token for one instance reaches only that instance's ERP; a token for the account reaches the provisioning tools alone. Adding an instance issues no new hostname and needs no change in your client — and an all-instances connector reaches it the moment it exists, with nothing to re-authorise.

Connecting a client

Point any MCP client at https://mcp.odooconsole.com/mcp. It will get a 401 carrying a WWW-Authenticate header that names the metadata document below, discover the authorization server from there, register itself, and send you to a consent screen. Nothing has to be configured by hand.

  1. DiscoverGET /.well-known/oauth-protected-resource names https://auth.odooconsole.com as the authorization server.
  2. Register — clients that support Dynamic Client Registration (RFC 7591) POST /oauth2/register there. No pre-shared client id.
  3. Authorize — the standard authorization-code flow with PKCE. You sign in to OdooConsole and pick, on the consent screen, what this connector may reach: All instances & account (the default — every instance you own, plus provisioning), a single instance, or Manage my instances for the account tools alone.
  4. Call — send the access token as Authorization: Bearer <token> on every request.

The choice is part of the grant, not a setting in the client. A single-instance connector authorised for acme cannot see beta, and re-authorising is the only way to point it elsewhere. An all-instances connector names the instance in each call (see the instance argument below) and reaches every instance you own, including ones created after it was authorised.

The kinds of grant

Grant Scopes Reaches
All instances & account odoo:*, instances:* Every instance's ERP on the account — named per call via the instance argument — and the provisioning tools. The default consent choice.
One instance odoo:read, odoo:write That instance's ERP data — records, models, views. Takes no instance argument; the grant fixes it.
The account instances:read, instances:write Create, restart, inspect and delete instances. No route to any instance's data.

The scope families stay separable: a single-instance connector holds only odoo:* and can never provision, and an account-only connector holds only instances:* and can never read a record — so text injected into an Odoo record cannot reach a provisioning tool. The all-instances grant deliberately holds both, for one agent that manages the account and works inside its instances; grant the narrower kinds when a connector should see less.

Tools

tools/list is authoritative — what follows is what a token of each kind sees today.

With instances:*

Tool Writes What it does
list_instances Every instance on the account, with state
instance_status State plus live container health
instance_logs Recent log lines; source is odoo or sidecar
create_instance yes Provisions an instance (Odoo 19) and returns its admin password once
restart_instance yes Restarts the containers; the database is untouched
delete_instance yes Permanent. confirm_name must repeat the instance name

With odoo:*

odoo_search_read, odoo_search_count, odoo_export, odoo_list_models, odoo_get_fields, odoo_model_info, odoo_get_view, odoo_connection_info, odoo_doctor are available to any token with odoo:read.

odoo_create, odoo_update, odoo_delete, odoo_execute, odoo_set_default, odoo_modify_action additionally require odoo:write. A read-only grant refuses them before the request reaches Odoo.

The instance argument. Under an all-instances grant, every odoo_* tool takes instance as its first argument — the name of the instance to act on, which must be one you own; an unknown or unowned name is refused the same way a missing one is. Under a single-instance grant the tools take no instance argument; the grant fixes it.

Installing modules. odoo_execute runs a model method, so it installs and uninstalls Odoo modules: call it on ir.module.module with button_immediate_install (or button_immediate_uninstall) and the module's record id. This needs odoo:write.

The connector authenticates to Odoo as a dedicated account with the rights to manage that instance's configuration, so Odoo's own access rules still apply on top of the scope — but a token's scope, not the account, is the outer gate: a read-only grant never reaches a write tool.

Isolation

The endpoint is shared; the instances are not. Each instance runs its MCP server inside its own network namespace with no route to any other instance, and that server independently re-checks that the token names the instance it serves before answering. A routing mistake fails closed at the destination rather than handing one instance's data to another. An all-instances token carries no single-instance claim; the shared router resolves the instance named in each call, refuses any your account does not own, and forwards to that instance's own server — so the same per-instance scope check, audit trail and network isolation apply exactly as they do to a single-instance connector.