Skip to main content
Glama
The-TechX

odoo-mcp

by The-TechX

odoo-mcp

CI

A generic Model Context Protocol (MCP) server for integrating MCP clients with Odoo.

Status

Active development. The server exposes generic Odoo read/write primitives with deployment guardrails, structured errors, and observability.

Related MCP server: Odoo MCP Server

Requirements

  • Node.js 22+

  • npm

  • Docker + Docker Compose (optional)

Local development

npm ci
npm run check
npm start

For development without building first:

npm run dev

The server supports MCP over stdio (default) and stateless Streamable HTTP. Odoo tools are registered from the configured connection and policy.

Docker

cp .env.example .env
# edit .env with your Odoo URL and API key
docker compose build
docker compose run --rm odoo-mcp

Compose passes all supported Odoo and guardrail settings into the container. ODOO_URL and ODOO_API_KEY are required; Compose fails fast when either is missing. Optional empty values are treated as unset. Because the transport is stdio, docker compose run --rm odoo-mcp is the intended interactive container entrypoint rather than a background daemon with a restart policy.

Project structure

src/
  config/          # environment and deployment policy
  observability/   # structured logging
  odoo/            # JSON-2 client and read/write services
  tools/           # MCP tool registration and schemas
  index.ts         # process entrypoint / stdio transport
  server.ts        # MCP server factory
test/              # unit tests

Development approach

Changes are developed PR by PR. Every pull request documents its scope, tests, and Definition of Done. Odoo-specific business logic does not belong in this bootstrap layer.

License

MIT

Odoo connection

The client layer targets Odoo's JSON-2 external API (/json/2/<model>/<method>), introduced for Odoo 19. Authentication uses an Odoo API key as a bearer token. X-Odoo-Database is sent only when ODOO_DATABASE is configured.

Copy .env.example and provide the connection values for your Odoo instance. Credentials are read from the environment and are never stored in source code.

Read-only MCP tools

The first MCP surface is intentionally read-only and generic:

  • odoo_search_read — searches and reads records from any model available to the configured Odoo user.

  • odoo_fields_get — inspects model field metadata.

Both tools are annotated as read-only and rely on Odoo itself for ACLs and record rules. The MCP server does not bypass or duplicate Odoo authorization.

Write MCP tools

Generic write operations are exposed separately from reads:

  • odoo_create — creates a record.

  • odoo_write — updates one or more records.

  • odoo_unlink — permanently deletes one or more records and is explicitly marked destructive.

Inputs are validated before reaching Odoo: record id lists must be non-empty and bounded, and create/update values cannot be empty. Odoo ACLs and record rules remain authoritative for every mutation.

Guardrails

odoo-mcp adds deployment-level guardrails without replacing Odoo authorization. Odoo ACLs and record rules are still the final authority for every request.

The server starts in read-only mode by default. Set ODOO_MCP_MODE=read-write to expose effective mutation capability. Optional exact-name model allow/deny lists can further reduce the models reachable through this MCP instance; deny rules take precedence over allow rules.

ODOO_MCP_MODE=read-only
ODOO_MCP_ALLOW_MODELS=res.partner,sale.order
ODOO_MCP_DENY_MODELS=res.users,ir.config_parameter

These controls are intentionally coarse deployment constraints, not a duplicate RBAC system. Use Odoo users, groups, ACLs, and record rules for business authorization.

Observability and errors

Odoo requests emit structured JSON logs to stderr with a request id, model, method, outcome, HTTP status when available, and duration. Request parameters, API keys, authorization headers, and response bodies are intentionally excluded from logs.

Transport failures are classified as http, timeout, or network errors. Timeouts and network failures do not invent an HTTP status code when no HTTP response was received. The generated request id is also forwarded to Odoo as X-Request-ID for correlation where upstream infrastructure preserves it.

Container releases

Published GitHub Releases produce a versioned OCI image in GitHub Container Registry. For release v0.1.0, consumers can pin ghcr.io/<owner>/odoo-mcp:0.1.0; the workflow also publishes the corresponding minor tag and latest. Pin a version (or digest) for deployments where reproducibility matters.

The publish workflow authenticates with the repository-scoped GITHUB_TOKEN; no registry password or personal access token is stored in the repository. Publishing is release-driven, so ordinary pushes to main never publish a container image.

Continuous integration

Every pull request and push to main runs the same lint, test, TypeScript build, Compose validation, and Docker image build used during local development. CI uses placeholder connection values only for configuration/build validation and does not connect to an Odoo instance.

Streamable HTTP

For a long-running network endpoint, select the HTTP transport explicitly:

MCP_TRANSPORT=http
MCP_HTTP_HOST=0.0.0.0
MCP_HTTP_PORT=3000
MCP_HTTP_ALLOWED_HOSTS=mcp.example.com,localhost

The MCP endpoint is POST /mcp. HTTP mode is stateless: each request receives a fresh MCP server/transport pair and no MCP session state is stored by odoo-mcp. GET /mcp and DELETE /mcp return 405.

The server uses the MCP SDK's Express helper so host validation can be applied. When binding beyond localhost, configure MCP_HTTP_ALLOWED_HOSTS for the hostnames that are expected to reach the service.

HTTP authentication has two modes: MCP_AUTH_MODE=oauth (default) and MCP_AUTH_MODE=none. OAuth mode makes odoo-mcp an OAuth Resource Server: an external OIDC provider such as Keycloak issues JWT access tokens, while odoo-mcp validates signature, issuer, resource audience, expiration, and required scopes using mcp-auth. Configure MCP_AUTH_ISSUER, MCP_AUTH_RESOURCE (the public MCP URL, also the required JWT aud), and optional MCP_AUTH_REQUIRED_SCOPES. none is an explicit opt-out intended only for trusted/private networks.

OAuth discovery metadata is published according to RFC 9728 and points MCP clients to the external Authorization Server. odoo-mcp does not implement login, authorization-code, token, refresh-token, or client-registration endpoints itself.

The Docker Compose file publishes MCP_HTTP_PORT; with MCP_TRANSPORT=http it can run as a normal long-running container using docker compose up -d.

MCP protocol compatibility

odoo-mcp uses the MCP TypeScript SDK v2 packages. The HTTP entrypoint is built with createMcpHandler(), which serves the current 2026-07-28 stateless protocol and retains the SDK's stateless compatibility path for 2025-era clients. stdio uses the v2 serveStdio() entrypoint.

The transport layer depends on the official split packages (@modelcontextprotocol/server and @modelcontextprotocol/node) rather than the legacy monolithic v1 SDK package.

Live Odoo integration test

The unit suite does not require an Odoo server. A separate opt-in integration suite can validate the real Odoo 19 JSON-2 contract:

ODOO_TEST_URL=https://odoo.example.com \
ODOO_TEST_API_KEY=replace-with-a-short-lived-api-key \
ODOO_TEST_DATABASE=your-database \
npm run test:integration

The live test uses only generic res.partner operations: it inspects fields, creates a uniquely named temporary record, verifies search_read, updates it, verifies the update, deletes it, and verifies cleanup. Cleanup also runs from afterAll if an assertion fails after record creation. Use a dedicated test database or short-lived API key whenever possible.

For a completely disposable real-Odoo run, Docker can provision Odoo 19 and PostgreSQL automatically:

npm run test:integration:docker

The disposable integration suite also connects with the official MCP v2 client over Streamable HTTP, authenticates with Bearer auth, discovers the generic tools, and exercises a create/read/write/delete round trip through MCP into Odoo.

That command initializes a fresh database, seeds a fixed credential that exists only inside the disposable test database, runs the same JSON-2 integration suite, and removes the containers and volumes afterward. It never needs credentials from a real Odoo deployment.

Available Tools

5 tools
odoo_createA

Create a record in an Odoo model using the configured Odoo user permissions.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesTechnical Odoo model name, for example res.partner
valuesYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds the useful context that creation happens 'using the configured Odoo user permissions,' which signals an authorization dependency. However, it does not disclose other behavioral traits such as immediate persistence, possible side effects, or return behavior. Annotations already indicate non-read-only and non-idempotent, so the description contributes only modestly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear, front-loaded sentence with no filler. Every word contributes either to the core action or to the permission context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should explain the return value or result of the create operation, but it does not. It also omits error cases, required fields, and the relationship to the update/write operation. A mutation tool with minimal annotations needs more operational context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50% since only 'model' has a description; 'values' has none. The description does not compensate by explaining that 'values' should be a mapping of Odoo field names to field values for the new record, leaving the agent to infer the key parameter's meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Create a record in an Odoo model.' This clearly communicates the tool's core operation and distinguishes it from sibling tools like odoo_write (update), odoo_search_read, and odoo_unlink.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The verb 'create' implies the tool is for adding new records rather than updating, reading, or deleting them, but the description gives no explicit when-to-use guidance, prerequisites, or alternatives. Usage is inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

odoo_fields_getA
Read-onlyIdempotent

Inspect field metadata for an Odoo model using fields_get.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelYesTechnical Odoo model name, for example res.partner
attributesNoField metadata attributes to return

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description reinforces the read-only nature with 'Inspect' but adds no further behavioral details such as auth requirements, return shape, or edge cases. With annotations present, this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence: verb, resource, and method. It has no filler or redundant elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple introspection tool with two well-described parameters and strong annotations. The description plus schema provide everything needed for correct invocation: the model name is required, attributes are optional, and the operation is read-only and non-destructive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: both 'model' and 'attributes' have meaningful descriptions. The tool description does not add parameter-level detail, but the schema already carries that burden, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Inspect' and a clear resource 'field metadata for an Odoo model', and it names the underlying method fields_get. This clearly distinguishes it from sibling tools that operate on records (odoo_search_read, odoo_create, odoo_write, odoo_unlink).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the tool's context clear: it is for inspecting metadata, not for reading or modifying records. It does not explicitly list alternatives or exclusion conditions, but the purpose is sufficiently clear that an agent can route to it correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

odoo_search_readA
Read-onlyIdempotent

Search and read records from any Odoo model using the permissions of the configured Odoo API user.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
modelYesTechnical Odoo model name, for example res.partner
orderNo
domainNoOdoo search domain
fieldsNo
offsetNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey readOnly, idempotent, and non-destructive behavior. The description adds useful context about results being scoped by the configured API user's permissions, but it does not disclose pagination behavior, return shape, or error/access boundary behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. Every clause carries meaning: search, read, any Odoo model, and permission scoping.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with six parameters, no output schema, and low schema coverage, this description is too sparse. It omits crucial operational details such as domain format, field list behavior, pagination through limit/offset, ordering, and what the returned records look like.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 33% schema description coverage, the description needed to compensate for limit, order, fields, and offset semantics, but it does not mention any of them. It only reinforces the model parameter and the general search/read purpose, leaving most parameters under-explained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Search and read') and a clear resource ('records from any Odoo model'). It naturally differentiates from sibling tools: create/write/unlink are mutations, and fields_get targets field metadata rather than records.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The read-only phrasing provides clear context for when to use this tool instead of the mutation siblings. However, it does not explicitly contrast with odoo_fields_get or state exclusion conditions, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

odoo_writeB
Idempotent

Update one or more Odoo records using the configured Odoo user permissions.

ParametersJSON Schema
NameRequiredDescriptionDefault
idsYes
modelYesTechnical Odoo model name, for example res.partner
valuesYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a non-read-only, non-destructive, idempotent operation. The description adds a small but useful behavioral note about running under the configured Odoo user permissions, but it does not disclose partial-failure behavior or outcomes when permissions are insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler. The update action and permission context are the most important information and appear first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write operation with an under-described values object, no output schema, and no return-value hints, the description is too thin. It omits important invocation context such as how ids map to records, what values accepts, and what result or failure behavior the agent should expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only the model parameter is documented in the schema, with schema description coverage at 33%. The tool description does not explain that values should be an Odoo field-value map or that ids must identify existing records, so it fails to compensate for the gaps around ids and values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Update') with a clear resource ('one or more Odoo records') and adds the scope of operating under configured permissions. It is clear but does not explicitly distinguish this from sibling tools like odoo_create or odoo_unlink, though the update semantics are inferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus the sibling alternatives odoo_create, odoo_unlink, or odoo_search_read. The description only implies existing-record updates from the word 'Update' and does not state exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updates
    • Changedodoo_create6 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "__schema0": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "number"
        +      },
        +      {
        +        "type": "boolean"
        +      },
        +      {
        +        "type": "null"
        +      },
        +      {
        +        "items": {
        +          "$ref": "#/$defs/__schema0"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "additionalProperties": {
        +          "$ref": "#/$defs/__schema0"
        +        },
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      }
        +    ]
        +  }
        +}
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / values / additionalProperties / $ref
        Added value: +"#/$defs/__schema0"
      • removedInput schema / properties / values / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  },
        -  {
        -    "items": {
        -      "$ref": "#/properties/values/additionalProperties"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "additionalProperties": {
        -      "$ref": "#/properties/values/additionalProperties"
        -    },
        -    "type": "object"
        -  }
        -]
      • addedInput schema / properties / values / propertyNames
        Added value: +{
        +  "type": "string"
        +}
    • Changedodoo_fields_get2 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedodoo_search_read6 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "__schema0": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "number"
        +      },
        +      {
        +        "type": "boolean"
        +      },
        +      {
        +        "type": "null"
        +      },
        +      {
        +        "items": {
        +          "$ref": "#/$defs/__schema0"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "additionalProperties": {
        +          "$ref": "#/$defs/__schema0"
        +        },
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      }
        +    ]
        +  }
        +}
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / domain / items / $ref
        Added value: +"#/$defs/__schema0"
      • removedInput schema / properties / domain / items / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  },
        -  {
        -    "items": {
        -      "$ref": "#/properties/domain/items"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "additionalProperties": {
        -      "$ref": "#/properties/domain/items"
        -    },
        -    "type": "object"
        -  }
        -]
      • addedInput schema / properties / offset / maximum
        Added value: +9007199254740991
    • Changedodoo_unlink3 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / ids / items / maximum
        Added value: +9007199254740991
    • Changedodoo_write7 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "__schema0": {
        +    "anyOf": [
        +      {
        +        "type": "string"
        +      },
        +      {
        +        "type": "number"
        +      },
        +      {
        +        "type": "boolean"
        +      },
        +      {
        +        "type": "null"
        +      },
        +      {
        +        "items": {
        +          "$ref": "#/$defs/__schema0"
        +        },
        +        "type": "array"
        +      },
        +      {
        +        "additionalProperties": {
        +          "$ref": "#/$defs/__schema0"
        +        },
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      }
        +    ]
        +  }
        +}
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / ids / items / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / values / additionalProperties / $ref
        Added value: +"#/$defs/__schema0"
      • removedInput schema / properties / values / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  },
        -  {
        -    "items": {
        -      "$ref": "#/properties/values/additionalProperties"
        -    },
        -    "type": "array"
        -  },
        -  {
        -    "additionalProperties": {
        -      "$ref": "#/properties/values/additionalProperties"
        -    },
        -    "type": "object"
        -  }
        -]
      • addedInput schema / properties / values / propertyNames
        Added value: +{
        +  "type": "string"
        +}
  2. 5 tool updatesv0.1.0
    • First observedodoo_create
    • First observedodoo_fields_get
    • First observedodoo_search_read
    • First observedodoo_unlink
    • First observedodoo_write

TDQS

A3.8/5.0

Scored across 5 tools

Disambiguation5/5

Each tool maps to a distinct operation: metadata inspection, create, search/read, update, and delete. There is no meaningful overlap between them.

Naming Consistency4/5

All tools share the 'odoo_' prefix, which is good. The second part is mostly a verb, though 'fields_get' and 'search_read' are compound forms while 'create', 'write', and 'unlink' are simple verbs, creating a minor inconsistency.

Tool Count5/5

Five tools is a tight, well-scoped set for a generic Odoo CRUD server. Each tool covers a fundamental operation without unnecessary bloat.

Completeness5/5

The tool set covers the full core lifecycle: read schema, create, read/search, update, and delete. For a generic Odoo model API server, these are the essential operations and no major gaps are apparent.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to interact with Odoo data using natural language to search, read, create, and update records. It acts as a secure bridge between MCP clients and Odoo instances version 17.0 through 19.0.
    11
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides read-only access to Odoo databases via OdooRPC, allowing AI assistants to query and analyze Odoo data through the MCP protocol.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A read-only MCP server that enables AI assistants to query Odoo instances via XML-RPC, supporting search, read, count, and field inspection without requiring custom modules.
    37 PyPI
    1
    Mozilla Public 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with Odoo 18 (JSON-RPC API) via MCP, supporting model exploration, CRUD operations, and secure API key authentication.
    Apache 2.0