MCP Hub
Back to servers

odoo-rust-mcp

Odoo MCP Server - Model Context Protocol server for Odoo ERP integration. Supports Odoo 14-19+ with JSON-RPC and REST API.

Stars
3
Updated
Jan 24, 2026
Validated
Feb 10, 2026

odoo-rust-mcp

CI Release codecov GitHub release License: AGPL-3.0 Homebrew Debian/Ubuntu Docker Kubernetes Helm

Rust implementation of an Odoo MCP server (Model Context Protocol), supporting:

  • Odoo 19+: JSON-2 External API (/json/2/...) with API key authentication
  • Odoo < 19: JSON-RPC (/jsonrpc) with username/password authentication

Features

  • MCP over stdio (Cursor / Claude Desktop style)
  • MCP over Streamable HTTP (Cursor remote transport)
  • MCP over SSE (legacy HTTP+SSE transport)
  • MCP over WebSocket (standalone server; not used by Cursor)
  • Multi-instance support via ODOO_INSTANCES
  • Optional cleanup tools gated behind ODOO_ENABLE_CLEANUP_TOOLS=true

Repository layout

  • rust-mcp/: the Rust MCP server implementation (Cargo workspace root)

Requirements

  • Rust toolchain (cargo)
  • Odoo instance:
    • Odoo 19+: Requires External JSON-2 API and API keys
    • Odoo < 19: Works with standard JSON-RPC endpoint (username/password)

Notes: For Odoo 19+, access to JSON-2 external API is only available on Custom plans. For Odoo < 19, the standard JSON-RPC endpoint is used which is available on all editions.

Configuration (environment variables)

Multi-instance (recommended)

Option A: JSON file (recommended for readability)

Create ~/.config/odoo-rust-mcp/instances.json:

{
  "production": {
    "url": "https://mycompany.example.com",
    "db": "mycompany",
    "apiKey": "YOUR_API_KEY"
  },
  "staging": {
    "url": "https://staging.mycompany.example.com",
    "apiKey": "YOUR_API_KEY"
  },
  "legacy": {
    "url": "https://legacy.mycompany.example.com",
    "db": "legacy_db",
    "version": "18",
    "username": "admin",
    "password": "admin_password"
  }
}

Then in ~/.config/odoo-rust-mcp/env:

ODOO_INSTANCES_JSON=/path/to/instances.json

Option B: Inline JSON (single line)

Set ODOO_INSTANCES directly in env file (must be single line):

ODOO_INSTANCES={"production":{"url":"https://mycompany.example.com","apiKey":"xxx"},"staging":{"url":"https://staging.example.com","apiKey":"yyy"}}

Instance configuration fields:

FieldRequiredDescription
urlYesOdoo server URL
dbOdoo < 19Database name (required for legacy, optional for 19+)
apiKeyOdoo 19+API key for authentication
versionNoOdoo version (e.g., "17", "18"). If < 19, uses username/password
usernameOdoo < 19Username for JSON-RPC authentication
passwordOdoo < 19Password for JSON-RPC authentication

Notes:

  • db is optional for Odoo 19+ (only needed when Host header isn't enough to select DB).
  • db is required for Odoo < 19 (legacy mode).
  • version determines authentication mode: < 19 uses username/password, >= 19 uses API key.
  • Extra fields in the JSON are ignored.
  • If an instance omits apiKey, the server will fall back to the global ODOO_API_KEY (if set).
  • If an instance omits username/password, the server will fall back to ODOO_USERNAME/ODOO_PASSWORD.

Single-instance (fallback)

Odoo 19+ (API Key):

export ODOO_URL="https://mycompany.example.com"
export ODOO_API_KEY="YOUR_API_KEY"
export ODOO_DB="mycompany"   # optional

Odoo < 19 (Username/Password):

export ODOO_URL="https://mycompany.example.com"
export ODOO_DB="mycompany"   # required for legacy
export ODOO_VERSION="18"     # triggers legacy mode
export ODOO_USERNAME="admin"
export ODOO_PASSWORD="your_password"

URL convenience: ODOO_URL may be given as localhost:8069 (it will be normalized to http://localhost:8069).

Local example (Odoo 19+)

export ODOO_URL="localhost:8069"
export ODOO_DB="v19_pos"
export ODOO_API_KEY="YOUR_API_KEY"

Local example (Odoo 18 or earlier)

export ODOO_URL="localhost:8069"
export ODOO_DB="v18_db"
export ODOO_VERSION="18"
export ODOO_USERNAME="admin"
export ODOO_PASSWORD="admin"

Tools, prompts, and server metadata via JSON (no recompile)

This server is fully declarative:

  • tools.json defines:
    • tool name / description
    • tool inputSchema (JSON Schema; must be Cursor-friendly)
    • tool op (maps tool calls to a primitive operation executed by Rust)
    • optional guards (e.g. requiresEnvTrue)
  • prompts.json defines prompt name / description / content
  • server.json defines initialize metadata (serverName, instructions, default protocol version)

Cursor schema constraints:

  • Avoid anyOf, oneOf, allOf, $ref, definitions, and \"type\": [...] (type arrays). These are rejected to prevent Cursor schema parsing issues.

Auto-reload:

  • The server watches these files and reloads them on change.
  • If a JSON file is missing at startup, the server will create it from built-in seed defaults (embedded from rust-mcp/config-defaults/*).

Editable vs seed defaults (important):

  • Edit these runtime files for day-to-day configuration:
    • rust-mcp/config/tools.json
    • rust-mcp/config/prompts.json
    • rust-mcp/config/server.json
  • Do not edit rust-mcp/config-defaults/* for normal configuration changes.
    • Those files are embedded into the binary as seed defaults (used only to auto-create missing runtime config files).
    • If you change config-defaults/*, you must rebuild the binary/image for changes to take effect.

Environment variables (optional overrides):

export MCP_TOOLS_JSON="config/tools.json"
export MCP_PROMPTS_JSON="config/prompts.json"
export MCP_SERVER_JSON="config/server.json"

Sample files are provided in:

  • rust-mcp/config/tools.json
  • rust-mcp/config/prompts.json
  • rust-mcp/config/server.json

Seed defaults (used only when files are missing):

  • rust-mcp/config-defaults/tools.json
  • rust-mcp/config-defaults/prompts.json
  • rust-mcp/config-defaults/server.json

Installation

Option 1: Homebrew (macOS/Linux) - Recommended

# Install
brew tap rachmataditiya/odoo-rust-mcp
brew install rust-mcp

# Configure (edit with your Odoo credentials)
nano ~/.config/odoo-rust-mcp/env

# Start as background service
brew services start rust-mcp

Or install directly in one command:

brew install rachmataditiya/odoo-rust-mcp/rust-mcp

What gets installed:

ComponentLocation
Binary/opt/homebrew/bin/rust-mcp
Service wrapper/opt/homebrew/bin/rust-mcp-service
User configs~/.config/odoo-rust-mcp/ (auto-created)
Service logs/opt/homebrew/var/log/rust-mcp.log

User config directory (~/.config/odoo-rust-mcp/):

├── env              # Environment variables - EDIT THIS with Odoo credentials
├── tools.json       # MCP tools definition
├── prompts.json     # MCP prompts definition  
└── server.json      # MCP server metadata

Service commands:

brew services start rust-mcp      # Start service
brew services stop rust-mcp       # Stop service
brew services restart rust-mcp    # Restart after config changes
brew services list                # Check status
tail -f /opt/homebrew/var/log/rust-mcp.log  # View logs

Service endpoint: http://127.0.0.1:8787/mcp

For Cursor/Claude Desktop/Windsurf with Homebrew:

The binary automatically loads config from ~/.config/odoo-rust-mcp/env, so you can use it directly:

{
  "mcpServers": {
    "odoo": {
      "command": "/opt/homebrew/bin/rust-mcp",
      "args": ["--transport", "stdio"]
    }
  }
}

Note: Starting from v0.2.4, the binary (rust-mcp) automatically:

  • Creates ~/.config/odoo-rust-mcp/ directory if it doesn't exist
  • Creates a default env template file
  • Loads environment variables from ~/.config/odoo-rust-mcp/env
  • Sets default MCP config paths from Homebrew share directory

This means you can use rust-mcp directly without the shell wrapper rust-mcp-service. This is especially important for MCP clients like Windsurf that don't support shell script execution.

For full Homebrew documentation, see: https://rachmataditiya.github.io/homebrew-odoo-rust-mcp/

Option 2: APT (Debian/Ubuntu)

# Add GPG key
curl -fsSL https://rachmataditiya.github.io/odoo-rust-mcp/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/rust-mcp.gpg

# Add repository
echo "deb [signed-by=/usr/share/keyrings/rust-mcp.gpg] https://rachmataditiya.github.io/odoo-rust-mcp stable main" | sudo tee /etc/apt/sources.list.d/rust-mcp.list

# Install
sudo apt update
sudo apt install rust-mcp

# Configure (edit with your Odoo credentials)
nano ~/.config/rust-mcp/env

# Start service
sudo systemctl start rust-mcp
sudo systemctl enable rust-mcp

What gets installed:

ComponentLocation
Binary/usr/bin/rust-mcp
Service wrapper/usr/bin/rust-mcp-service
Default configs/usr/share/rust-mcp/
User configs~/.config/rust-mcp/ (auto-created on install)
Systemd service/lib/systemd/system/rust-mcp.service

Service commands:

sudo systemctl start rust-mcp      # Start service
sudo systemctl stop rust-mcp       # Stop service
sudo systemctl restart rust-mcp    # Restart after config changes
sudo systemctl status rust-mcp     # Check status
journalctl -u rust-mcp -f          # View logs

Service endpoint: http://127.0.0.1:8787/mcp

Option 3: Download and install

Download the latest release for your platform from GitHub Releases:

PlatformFile
Linux x86_64rust-mcp-x86_64-unknown-linux-gnu.tar.gz
macOS x86_64rust-mcp-x86_64-apple-darwin.tar.gz
macOS ARM64 (Apple Silicon)rust-mcp-aarch64-apple-darwin.tar.gz
Windows x86_64rust-mcp-x86_64-pc-windows-msvc.zip

Extract and install:

Linux / macOS:

tar -xzf rust-mcp-<platform>.tar.gz
cd rust-mcp-<platform>
./install.sh

This installs:

  • Binary to /usr/local/bin/rust-mcp
  • Config files to /usr/local/share/odoo-rust-mcp/

To uninstall:

./install.sh uninstall

Windows (PowerShell as Administrator):

Expand-Archive rust-mcp-x86_64-pc-windows-msvc.zip -DestinationPath rust-mcp
cd rust-mcp
.\install.ps1

This installs:

  • Binary to C:\Program Files\odoo-rust-mcp\
  • Config files to C:\ProgramData\odoo-rust-mcp\
  • Adds binary to system PATH

To uninstall:

.\install.ps1 -Uninstall

Manual (without installer):

# Linux/macOS - just run directly
tar -xzf rust-mcp-<platform>.tar.gz
./rust-mcp --transport stdio

# Windows
Expand-Archive rust-mcp-x86_64-pc-windows-msvc.zip -DestinationPath .
.\rust-mcp.exe --transport stdio

The release archive includes:

  • rust-mcp (or rust-mcp.exe on Windows) - the binary
  • config/ - default configuration files (tools.json, prompts.json, server.json)
  • .env.example - example environment variables
  • install.sh (Linux/macOS) or install.ps1 (Windows) - installer script

Option 4: Build from source

cd rust-mcp
cargo build --release

Run as Background Service

The installer scripts support running the MCP server as a background service (HTTP transport on port 8787).

Linux (systemd):

./install.sh service

Commands:

  • Start: sudo systemctl start odoo-rust-mcp
  • Stop: sudo systemctl stop odoo-rust-mcp
  • Status: sudo systemctl status odoo-rust-mcp
  • Logs: sudo journalctl -u odoo-rust-mcp -f

Config: /etc/odoo-rust-mcp.env

macOS (launchd):

./install.sh service

Commands:

  • Start: launchctl load ~/Library/LaunchAgents/com.odoo.rust-mcp.plist
  • Stop: launchctl unload ~/Library/LaunchAgents/com.odoo.rust-mcp.plist
  • Logs: tail -f ~/.config/odoo-rust-mcp/stdout.log

Config: ~/.config/odoo-rust-mcp/env

Windows (Scheduled Task):

.\install.ps1 -Service

Commands (PowerShell as Admin):

  • Start: Start-ScheduledTask -TaskName OdooRustMcpService
  • Stop: Stop-ScheduledTask -TaskName OdooRustMcpService
  • Status: Get-ScheduledTask -TaskName OdooRustMcpService | Select-Object State

Config: C:\ProgramData\odoo-rust-mcp\env.ps1

Service endpoint: http://127.0.0.1:8787/mcp

To remove service only:

# Linux/macOS
./install.sh service-uninstall

# Windows
.\install.ps1 -ServiceUninstall

Run (stdio)

cd rust-mcp
./target/release/rust-mcp --transport stdio

Run (Streamable HTTP)

cd rust-mcp
./target/release/rust-mcp --transport http --listen 127.0.0.1:8787

Endpoints:

  • Streamable HTTP: http://127.0.0.1:8787/mcp
  • Legacy SSE: http://127.0.0.1:8787/sse (paired with POST /messages)

Authentication (HTTP Transport)

The HTTP transport supports Bearer token authentication as per the MCP specification.

Enable authentication:

export MCP_AUTH_TOKEN=your-secure-random-token-here

When MCP_AUTH_TOKEN is set, all HTTP requests must include the Authorization header:

Authorization: Bearer your-secure-random-token-here

Example with curl:

curl -X POST http://127.0.0.1:8787/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-secure-random-token-here" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}'

Notes:

  • If MCP_AUTH_TOKEN is not set, authentication is disabled (not recommended for production)
  • STDIO transport does not use HTTP authentication (credentials come from environment)
  • Generate a secure token: openssl rand -hex 32

Run (WebSocket / standalone server)

cd rust-mcp
./target/release/rust-mcp --transport ws --listen 127.0.0.1:8787

Run with Docker Compose

Create .env in the repo root (example in dotenv.example), then:

docker compose up --build

By default, the container runs HTTP transport and exposes http://localhost:8787/mcp.

Features:

  • Custom network mcp-network for integration with other containers (n8n, dify, etc.)
  • Health check for container orchestration
  • Volume mounts for config files
  • Support for ODOO_INSTANCES_JSON for multi-instance setup
  • Resource limits and labels for service discovery

Multi-instance configuration:

  1. Create instances.json with your Odoo instances:
{
  "production": {"url": "https://odoo.example.com", "db": "prod", "apiKey": "xxx"},
  "staging": {"url": "https://staging.example.com", "db": "staging", "apiKey": "yyy"}
}
  1. Mount and configure in .env:
ODOO_INSTANCES_JSON=/config/instances.json
  1. Uncomment the volume mount in docker-compose.yml:
volumes:
  - ./instances.json:/config/instances.json:ro

Integration with other containers:

The MCP server runs on the mcp-network network. Other containers can connect using:

# In your other service's docker-compose.yml
services:
  n8n:
    networks:
      - mcp-network
    environment:
      MCP_URL: "http://odoo-mcp:8787/mcp"

networks:
  mcp-network:
    external: true

See docker-compose.override.example.yml for more integration examples.

Run with Kubernetes

The project includes Kubernetes manifests in k8s/ for production deployments.

Quick start with raw manifests:

# Apply all manifests
kubectl apply -k k8s/

# Or apply individually
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yaml    # Edit first with your credentials!
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml   # Optional, for external access

Verify deployment:

kubectl -n odoo-mcp get pods
kubectl -n odoo-mcp logs -f deployment/odoo-mcp

Port-forward for local testing:

kubectl -n odoo-mcp port-forward svc/odoo-mcp 8787:8787
# Access: http://127.0.0.1:8787/mcp

Features:

  • Namespace isolation
  • ConfigMap for MCP configuration files
  • Secret for Odoo credentials
  • Deployment with:
    • Resource limits/requests
    • Liveness/readiness/startup probes
    • Pod anti-affinity for high availability
    • Non-root security context
  • ClusterIP Service for internal access
  • Ingress for external access with TLS
  • Kustomization for environment management

Run with Helm

For more flexible deployments, use the Helm chart in helm/odoo-rust-mcp/.

Install:

# Add your values (see helm/odoo-rust-mcp/values.yaml for all options)
cat > my-values.yaml <<EOF
odoo:
  url: "http://odoo-service:8069"
  db: "mydb"
  apiKey: "your-api-key"

mcp:
  authToken: "your-secure-token"

ingress:
  enabled: true
  hosts:
    - host: mcp.example.com
      paths:
        - path: /
          pathType: Prefix
EOF

# Install
helm install odoo-mcp ./helm/odoo-rust-mcp -f my-values.yaml -n odoo-mcp --create-namespace

Upgrade:

helm upgrade odoo-mcp ./helm/odoo-rust-mcp -f my-values.yaml -n odoo-mcp

Uninstall:

helm uninstall odoo-mcp -n odoo-mcp

Key configuration options:

ParameterDescriptionDefault
replicaCountNumber of replicas2
odoo.urlOdoo server URLhttp://odoo-service:8069
odoo.apiKeyAPI key for Odoo 19+""
odooInstances.jsonMulti-instance JSON config""
mcp.authTokenHTTP auth token (recommended)""
ingress.enabledEnable ingressfalse
autoscaling.enabledEnable HPAfalse

Production recommendations:

  1. Always set mcp.authToken for HTTP authentication
  2. Use external secrets (Vault, AWS Secrets Manager) instead of storing credentials in values.yaml
  3. Enable pod disruption budgets for zero-downtime updates
  4. Configure resource limits based on your workload
  5. Use Ingress with TLS for external access

Cleanup tools (disabled by default)

Cleanup tools are only listed and callable when enabled:

export ODOO_ENABLE_CLEANUP_TOOLS=true

Tools

Tools are defined by tools.json (authoritative). The default seed includes tools like:

  • odoo_search, odoo_search_read, odoo_read, odoo_create, odoo_update, odoo_delete
  • odoo_execute, odoo_count, odoo_workflow_action, odoo_generate_report, odoo_get_model_metadata
  • cleanup tools (odoo_database_cleanup, odoo_deep_cleanup) guarded by ODOO_ENABLE_CLEANUP_TOOLS=true

Supported op.type values (used in tools.json):

  • search, search_read, read, create, write, unlink
  • search_count, workflow_action, execute
  • generate_report, get_model_metadata
  • database_cleanup, deep_cleanup

Prompts

Prompts are defined by prompts.json (authoritative). The default seed includes:

  • odoo_common_models
  • odoo_domain_filters

Example tool calls

Tool result format (important)

Most tools return an MCP response whose content[0].text is a JSON string.

  • In the examples below, Request shows what you pass as tool arguments.
  • Decoded result shows the JSON payload after you parse content[0].text.

Search and read:

{
  "instance": "default",
  "model": "res.partner",
  "domain": [["is_company", "=", true]],
  "fields": ["name", "email"],
  "limit": 10,
  "order": "name ASC"
}

Decoded result (shape):

{
  "records": [],
  "count": 0
}

Read by ids:

{
  "instance": "default",
  "model": "res.partner",
  "ids": [1, 2, 3],
  "fields": ["id", "name", "email"]
}

Decoded result (shape):

{
  "records": []
}

Create:

{
  "instance": "default",
  "model": "res.partner",
  "values": {
    "name": "ACME Demo",
    "is_company": true
  }
}

Decoded result (shape):

{
  "id": 123,
  "success": true
}

Update:

{
  "instance": "default",
  "model": "res.partner",
  "ids": [123],
  "values": {
    "email": "demo@acme.test"
  }
}

Decoded result (shape):

{
  "success": true,
  "updated_count": 1
}

Delete:

{
  "instance": "default",
  "model": "res.partner",
  "ids": [123]
}

Decoded result (shape):

{
  "success": true,
  "deleted_count": 1
}

Search (IDs only):

{
  "instance": "default",
  "model": "res.partner",
  "domain": [["is_company", "=", true]],
  "limit": 10,
  "order": "name ASC"
}

Decoded result (shape):

{
  "ids": [1, 2, 3],
  "count": 3
}

Count:

{
  "instance": "default",
  "model": "res.partner",
  "domain": [["id", ">", 0]]
}

Decoded result (shape):

{
  "count": 18
}

Execute action/button (workflow):

{
  "instance": "default",
  "model": "sale.order",
  "ids": [42],
  "action": "action_confirm"
}

Decoded result (shape):

{
  "result": null,
  "executed_on": [42]
}

Execute arbitrary method:

{
  "instance": "default",
  "model": "res.partner",
  "method": "name_get",
  "args": [[1, 2, 3]]
}

Decoded result (shape):

{
  "result": []
}

Model metadata (fields/types):

{
  "instance": "default",
  "model": "sale.order"
}

Decoded result (shape):

{
  "model": {
    "name": "sale.order",
    "description": "Sales Order",
    "fields": {}
  }
}

Generate report (PDF as base64):

{
  "instance": "default",
  "reportName": "sale.report_saleorder",
  "ids": [42]
}

Decoded result (shape):

{
  "pdf_base64": "JVBERi0xLjQKJ...<omitted>...",
  "report_name": "sale.report_saleorder",
  "record_ids": [42]
}

Claude Desktop config example

Set your MCP server command to the built binary:

Odoo 19+ (API Key):

{
  "mcpServers": {
    "odoo-rust": {
      "command": "/absolute/path/to/odoo-rust-mcp/rust-mcp/target/release/rust-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "ODOO_INSTANCES": "{\"production\":{\"url\":\"https://mycompany.example.com\",\"db\":\"mycompany\",\"apiKey\":\"YOUR_API_KEY\"}}"
      }
    }
  }
}

Odoo < 19 (Username/Password):

{
  "mcpServers": {
    "odoo-rust": {
      "command": "/absolute/path/to/odoo-rust-mcp/rust-mcp/target/release/rust-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "ODOO_INSTANCES": "{\"legacy\":{\"url\":\"https://mycompany.example.com\",\"db\":\"mycompany\",\"version\":\"18\",\"username\":\"admin\",\"password\":\"your_password\"}}"
      }
    }
  }
}

Cursor config example

Cursor supports stdio, SSE, and Streamable HTTP transports. See Cursor docs: cursor.com/docs/context/mcp.

Cursor (recommended): stdio

Put this in ~/.cursor/mcp.json (or ${workspaceFolder}/.cursor/mcp.json):

IMPORTANT: For stdio transport, you must use absolute paths for config files because Cursor runs the binary from a different working directory.

Odoo 19+ (complete example):

{
  "mcpServers": {
    "odoo-rust-mcp": {
      "type": "stdio",
      "command": "/absolute/path/to/odoo-rust-mcp/rust-mcp/target/release/rust-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "ODOO_URL": "http://localhost:8069",
        "ODOO_DB": "mydb",
        "ODOO_API_KEY": "YOUR_API_KEY",
        "MCP_TOOLS_JSON": "/absolute/path/to/odoo-rust-mcp/config/tools.json",
        "MCP_PROMPTS_JSON": "/absolute/path/to/odoo-rust-mcp/config/prompts.json",
        "MCP_SERVER_JSON": "/absolute/path/to/odoo-rust-mcp/config/server.json"
      }
    }
  }
}

Odoo < 19 (complete example):

{
  "mcpServers": {
    "odoo-rust-mcp": {
      "type": "stdio",
      "command": "/absolute/path/to/odoo-rust-mcp/rust-mcp/target/release/rust-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "ODOO_URL": "http://localhost:8069",
        "ODOO_DB": "mydb",
        "ODOO_VERSION": "18",
        "ODOO_USERNAME": "admin",
        "ODOO_PASSWORD": "admin",
        "MCP_TOOLS_JSON": "/absolute/path/to/odoo-rust-mcp/config/tools.json",
        "MCP_PROMPTS_JSON": "/absolute/path/to/odoo-rust-mcp/config/prompts.json",
        "MCP_SERVER_JSON": "/absolute/path/to/odoo-rust-mcp/config/server.json"
      }
    }
  }
}

Using .env file:

{
  "mcpServers": {
    "odoo-rust-mcp": {
      "type": "stdio",
      "command": "/absolute/path/to/odoo-rust-mcp/rust-mcp/target/release/rust-mcp",
      "args": ["--transport", "stdio"],
      "envFile": "/absolute/path/to/odoo-rust-mcp/.env"
    }
  }
}

Note: When using envFile, ensure your .env contains absolute paths for MCP_TOOLS_JSON, MCP_PROMPTS_JSON, and MCP_SERVER_JSON.

Cursor: Streamable HTTP (remote / multi-user)

Run the server with --transport http and set:

{
  "mcpServers": {
    "odoo-rust-mcp": {
      "url": "http://127.0.0.1:8787/mcp"
    }
  }
}

With Bearer Token Authentication:

If you have MCP_AUTH_TOKEN set on the server, configure Cursor with the token in headers:

{
  "mcpServers": {
    "odoo-rust-mcp": {
      "url": "http://127.0.0.1:8787/mcp",
      "headers": {
        "Authorization": "Bearer your-secure-random-token-here"
      }
    }
  }
}

Note: Generate a secure token with openssl rand -hex 32 and set MCP_AUTH_TOKEN on the server.

Test / smoke

Run unit tests (no warnings):

cd rust-mcp
RUSTFLAGS='-Dwarnings' cargo test

There is also a small WS smoke client that can validate end-to-end MCP calls (connect → initialize → list tools → call a few tools):

cd rust-mcp
cargo run --release --bin ws_smoke_client -- \
  --url ws://127.0.0.1:8787 \
  --instance default \
  --model res.partner

Example output (local run against res.partner):

tools/list: 11 tools
- odoo_search
- odoo_search_read
- odoo_read
- odoo_create
- odoo_update
- odoo_delete
- odoo_execute
- odoo_count
- odoo_workflow_action
- odoo_generate_report
- odoo_get_model_metadata
odoo_count result: {"count":18}
odoo_search_read count: 2
odoo_search_read sample records: [{"id":46,"name":"Kasir C"},{"id":45,"name":"Kasir B"}]
prompts/list: odoo_common_models, odoo_domain_filters

Security

  • Do not commit .env or any file containing API keys/passwords.
  • Prefer using dedicated bot users with minimal access rights in Odoo for automation.

Reviews

No reviews yet

Sign in to write a review