Làm chủ dữ liệu Odoo với MCP kết nối OpenCode

Nội dung

    Sự bùng nổ của các AI Agent và các trình soạn thảo mã nguồn tích hợp AI (AI-powered IDE) đang thay đổi hoàn toàn cách chúng ta làm việc với các hệ thống ERP phức tạp như Odoo. Thay vì phải chuyển đổi qua lại giữa hàng chục tab trình duyệt để tra cứu ID khách hàng, kiểm tra trạng thái đơn hàng hay xem cấu trúc model, tại sao chúng ta không đưa trực tiếp dữ liệu đó vào “não bộ” của AI?

    Hôm nay, tôi sẽ hướng dẫn các bạn cách xây dựng và triển khai một MCP Server cho Odoo, sử dụng mã nguồn mở mcp-odoo và kết nối nó với OpenCode – một môi trường làm việc AI thế hệ mới.

    1. MCP (Model Context Protocol) là gì?

    MCP là một giao thức mở được giới thiệu bởi Anthropic, cho phép các mô hình ngôn ngữ lớn (LLM) kết nối an toàn với các nguồn dữ liệu và công cụ địa phương hoặc từ xa. Bản thân cụm từ “Giao thức ngữ cảnh mô hình” nghe giống như một cụm từ được nghĩ ra trong một cuộc họp ủy ban. Ogilvy sẽ gọi đó là rào cản đối với việc áp dụng – thuật ngữ chuyên ngành khiến người bình thường cảm thấy ngu ngốc. Ông có một câu nói: “Bạn không nói chuyện với người khác. Bạn đang nói chuyện với chính mình.”

    Hãy giải thích quy trình trong vòng chưa đến 5 từ, tôi sẽ đợi.

    Vậy chúng ta sẽ thay đổi MCP thành cái gì?

    Đại loại như…

    “Một cầu nối tiêu chuẩn giữa ý tưởng và thành quả của bạn.”

    Đối với các nhà phát triển Odoo, MCP đóng vai trò là “thông dịch viên”:

    • Giúp AI hiểu được cấu trúc dữ liệu của Odoo thông qua XML-RPC.

    • Cho phép AI thực hiện các hành động như tìm kiếm, đọc, và thậm chí là ghi dữ liệu vào ERP ngay từ giao diện chat.

    Ứng cử viên hàng đầu số 1 — CRM

    Phần mềm CRM thật phiền phức. Nó yêu cầu bạn phải nhấp chuột và nhập rất nhiều thông tin, như tên khách hàng, ngày tháng, nội dung cuộc trò chuyện.

    Giờ đây, với tính năng kết nối này, tất cả những gì bạn cần làm là ghi âm giọng nói của mình rồi dán vào đoạn chat, sau đó hồ sơ CRM của bạn sẽ được cập nhật tự động.

    Lợi ích chính ở đây là cầu nối này rất thông minh, trong trường hợp này nó biết cách điều hướng hệ thống CRM thay mặt bạn.

    Nếu bạn nói Michael đến từ Flatwood Architects, hệ thống sẽ hiểu rằng cần phải liên hệ với Flatwood Architects, và nếu công ty đó chưa tồn tại, nó sẽ tạo một công ty mới có tên như vậy. Và nếu Michael không phải là người liên hệ hiện có, hệ thống cần phải tạo thêm thông tin về anh ấy.

    Ứng cử viên hàng đầu số 2 — Đơn đặt hàng

    Tôi sẽ đưa ra một ví dụ thực tế từ thời còn làm kỹ sư xây dựng. Khi phân lô đất, bạn thường phải kiểm tra áp lực nước. Chúng tôi sẽ đặt hàng kiểm tra này thay mặt bạn và lập đơn đặt hàng.

    Trước khi có MCP, tôi sẽ phải:

    • Tạo đơn đặt hàng
    • Thêm thông tin chi tiết của nhà thầu
    • Thêm thông tin chi tiết về trang web
    • Tạo hóa đơn
    • Tăng giá bán và cộng thêm đơn đặt hàng vào chi phí với mức lợi nhuận 15%.
    • Sau đó hãy gửi nó đi.

    Giờ đây, nhờ có cầu MCP, tôi có thể làm được điều đó.

    • Chụp ảnh đơn đặt hàng.
    • Hãy để Claude thực hiện tất cả các bước trên thay mặt tôi.

    2. Giới thiệu dự án mcp-odoo

    Trong bài viết này, chúng ta sẽ sử dụng project mcp-odoo. Đây là một implementation tinh gọn, sử dụng Python để lộ ra các “Tools” cần thiết cho AI như:

    • search_read: Tìm kiếm và đọc bản ghi với các bộ lọc (domain).

    • get_model_fields: Tra cứu metadata của các trường trong một model (cực kỳ hữu ích cho dev khi cần viết code Odoo).

    • execute_kw: Thực thi các hàm Odoo tùy chỉnh.

    3. Hướng dẫn cài đặt chi tiết

    Bước 1: Chuẩn bị môi trường

    Đảm bảo bạn đã cài đặt Python 3.10 trở lên. Tôi khuyến khích sử dụng uv để quản lý package nhanh chóng hơn.

    # Clone project từ GitHub
    git clone //github.com/tuanle96/mcp-odoo.git
    cd mcp-odoo
    
    # Tạo môi trường ảo và cài đặt dependencies
    python -m venv .venv
    source .venv/bin/activate  # Trên Windows: .venv\Scripts\activate
    pip install -r requirements.txt
    

    Bước 2: Cấu hình kết nối Odoo

    Tạo file .env trong thư mục gốc của project (dựa trên file .env.example) và điền thông tin instance Odoo của bạn:

    Đoạn mã

    ODOO_URL=//your-odoo-instance.com
    ODOO_DB=your_database_name
    ODOO_USER=your_email_or_username
    ODOO_PASSWORD=your_api_key_or_password
    

    Lưu ý: Nên sử dụng API Key thay vì mật khẩu đăng nhập thông thường để đảm bảo tính bảo mật. Xem tham khảo

    4. Kết nối vào OpenCode AI

    OpenCode hỗ trợ tích hợp MCP Server để mở rộng khả năng của trợ lý AI tích hợp sẵn. Theo tài liệu từ OpenCode MCP Servers, bạn cần cấu hình file JSON để OpenCode biết cách khởi động server của bạn.

    Cấu hình file config.json

    Tùy vào hệ điều hành, file cấu hình của bạn thường nằm ở:

    • macOS: ~/Library/Application Support/OpenCode/config.json

    • Windows: %APPDATA%\OpenCode\config.json

    Thêm đoạn cấu hình sau vào mục mcpServers:

    JSON

    {
      "mcpServers": {
        "odoo": {
          "command": "python",
          "args": [
            "/path/to/your/mcp-odoo/main.py"
          ],
          "env": {
            "ODOO_URL": "//your-odoo-instance.com",
            "ODOO_DB": "your_db",
            "ODOO_USER": "your_user",
            "ODOO_PASSWORD": "your_password"
          }
        }
      }
    }
    

    (Thay thế /path/to/your/mcp-odoo/main.py bằng đường dẫn tuyệt đối đến file thực thi trên máy bạn).

    5. Trải nghiệm thực tế: AI Agent “hiểu” Odoo

    Sau khi cấu hình thành công, bạn có thể mở OpenCode và bắt đầu đặt những câu hỏi như:

    1. Tra cứu kỹ thuật: “Hãy liệt kê các fields của model sale.order và cho tôi biết field nào dùng để lưu tổng tiền.”

    2. Truy vấn dữ liệu: “Tìm trong Odoo 5 khách hàng gần nhất có địa chỉ tại TP.HCM.”

    3. Hỗ trợ lập trình: “Dựa trên dữ liệu thực tế từ Odoo, hãy viết cho tôi một hàm Python để tính tỷ lệ chuyển đổi từ Lead sang Opportunity trong tháng này.”

    Lúc này, OpenCode sẽ không còn trả lời dựa trên phỏng đoán. Nó sẽ gọi đến mcp-odoo, thực hiện RPC call đến Odoo, nhận dữ liệu thực tế và phân tích cho bạn.

    6. Tại sao đây là tương lai của Odoo Development?

    Việc sử dụng mcp-odoo kết hợp với các IDE như OpenCode mang lại 3 lợi ích cốt lõi:

    • Giảm thiểu ngữ cảnh (Context Switching): Bạn không cần rời khỏi trình soạn thảo code để check dữ liệu trong ERP.

    • Chính xác tuyệt đối: AI làm việc với dữ liệu thật, schema thật của instance Odoo bạn đang dev, tránh tình trạng “hallucination” (ảo giác) về tên field hay logic nghiệp vụ.

    • Tự động hóa báo cáo: Khả năng truy vấn nhanh giúp bạn tổng hợp dữ liệu hoặc kiểm tra lỗi logic cực kỳ nhanh chóng.

    MCP không chỉ là một giao thức kỹ thuật, nó là cầu nối để biến AI thành một cộng sự thực thụ trong doanh nghiệp. Hy vọng qua bài viết này, các bạn sẽ tự xây dựng được máy chủ MCP đầu tiên cho riêng mình.

    Nâng cấp Odoo MCP Server: Từ Tra cứu đơn giản đến Quản trị hệ thống toàn diện

    Nếu bạn đã cài đặt thành công mcp-odoo cơ bản, bạn đã thấy sự tiện lợi khi AI có thể đọc dữ liệu. Nhưng để AI thực sự trở thành một “Odoo Consultant” hay “Developer” ảo, nó cần nhiều quyền năng hơn: tạo mới bản ghi, chỉnh sửa lỗi dữ liệu, hay thậm chí là hiểu cấu trúc của các module tùy chỉnh (custom modules).

    Trong bài viết này, chúng ta sẽ mở rộng mã nguồn dựa trên project tuanle96/mcp-odoo để hỗ trợ đầy đủ bộ công cụ nâng cao.

    1. Kiến trúc mở rộng với FastMCP

    Chúng ta sẽ sử dụng decorator @mcp.tool() để định nghĩa các hàm mới. Mỗi hàm này sẽ đóng vai trò là một “kỹ năng” mà OpenCode AI có thể gọi khi cần.

    Cấu trúc mã nguồn nâng cao

    Python

    import os
    import xmlrpc.client
    from mcp.server.fastmcp import FastMCP
    from typing import List, Dict, Any, Optional
    
    mcp = FastMCP("Odoo-Advanced-Connector")
    
    # --- Helper kết nối Odoo ---
    def get_odoo_client():
        url = os.getenv("ODOO_URL")
        db = os.getenv("ODOO_DB")
        username = os.getenv("ODOO_USER")
        password = os.getenv("ODOO_PASSWORD")
        
        common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
        uid = common.authenticate(db, username, password, {})
        models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
        
        return db, uid, password, models
    
    # --- Bộ Công Cụ Nâng Cao ---
    
    @mcp.tool()
    async def search_records(model: str, domain: List = [], fields: List[str] = [], limit: int = 10, offset: int = 0, order: str = "") -> List[Dict]:
        """Tìm kiếm bản ghi nâng cao với filter, limit và sắp xếp."""
        db, uid, pw, models = get_odoo_client()
        return models.execute_kw(db, uid, pw, model, 'search_read', [domain], {
            'fields': fields, 'limit': limit, 'offset': offset, 'order': order
        })
    
    @mcp.tool()
    async def create_record(model: str, values: Dict[str, Any]) -> int:
        """Tạo bản ghi mới. Trả về ID của bản ghi vừa tạo."""
        db, uid, pw, models = get_odoo_client()
        return models.execute_kw(db, uid, pw, model, 'create', [values])
    
    @mcp.tool()
    async def update_record(model: str, res_id: int, values: Dict[str, Any]) -> bool:
        """Cập nhật bản ghi hiện có theo ID."""
        db, uid, pw, models = get_odoo_client()
        return models.execute_kw(db, uid, pw, model, 'write', [[res_id], values])
    
    @mcp.tool()
    async def delete_record(model: str, res_id: int) -> bool:
        """Xóa một bản ghi khỏi hệ thống."""
        db, uid, pw, models = get_odoo_client()
        return models.execute_kw(db, uid, pw, model, 'unlink', [[res_id]])
    
    @mcp.tool()
    async def model_introspection(model: str) -> Dict:
        """Khám phá cấu trúc (fields) của một model bất kỳ."""
        db, uid, pw, models = get_odoo_client()
        return models.execute_kw(db, uid, pw, model, 'fields_get', [], {
            'attributes': ['string', 'help', 'type', 'relation']
        })
    
    @mcp.tool()
    async def list_models() -> List[str]:
        """Liệt kê toàn bộ các model có trong hệ thống Odoo."""
        db, uid, pw, models = get_odoo_client()
        records = models.execute_kw(db, uid, pw, 'ir.model', 'search_read', [[]], {'fields': ['model']})
        return [r['model'] for r in records]
    
    @mcp.tool()
    async def execute_method(model: str, method: str, res_ids: List[int], args: List = []) -> Any:
        """Gọi các hàm logic tùy chỉnh (ví dụ: action_confirm, button_immediate_install)."""
        db, uid, pw, models = get_odoo_client()
        return models.execute_kw(db, uid, pw, model, method, [res_ids] + args)
    

    2. Các điểm sáng kỹ thuật bạn cần lưu ý

    Tại sao cần model_introspection?

    AI không phải lúc nào cũng biết model sale.order của bạn có những field custom nào (ví dụ: x_delivery_date). Bằng cách cung cấp công cụ model_introspection, khi bạn hỏi: “Làm sao để lọc các đơn hàng theo ngày giao?”, OpenCode sẽ tự động gọi hàm này để xem danh sách field trước khi thực hiện lệnh search.

    Sức mạnh của execute_method

    Đây là “nút bấm vạn năng”. Bạn có thể yêu cầu AI:

    • “Hãy xác nhận (confirm) toàn bộ các đơn hàng báo giá của khách hàng A.”

    • AI sẽ tìm IDs của đơn hàng, sau đó gọi execute_method với method action_confirm.

    An toàn dữ liệu

    Vì các công cụ create, update, delete có khả năng thay đổi dữ liệu thật, hãy đảm bảo:

    1. Sử dụng Odoo API Key của một user có quyền hạn hạn chế (Internal User thay vì Super Admin).

    2. Kiểm tra log của MCP Server thường xuyên để biết AI đang thực hiện tác vụ gì.

    3. Cập nhật vào OpenCode

    Đừng quên cập nhật lại đường dẫn file Python trong cấu hình của OpenCode (hoặc Claude Desktop) để kích hoạt các công cụ mới:

    JSON

    "odoo-pro": {
      "command": "python",
      "args": ["/đường/dẫn/đến/file/vừa/cập/nhật.py"],
      "env": {
        "ODOO_URL": "...",
        "ODOO_DB": "...",
        "ODOO_USER": "...",
        "ODOO_PASSWORD": "..."
      }
    }
    

    4. Kịch bản ứng dụng thực tế

    Với bộ công cụ này, bạn có thể thực hiện các workflow cực kỳ phức tạp ngay trong cửa sổ chat của OpenCode:

    User: “Kiểm tra xem model hr.employee có trường nào liên quan đến ‘Social Media’ không. Nếu có, hãy cập nhật link LinkedIn cho nhân viên ‘Nguyễn Văn A’ thành ‘linkedin.com/in/nva‘.”

    AI sẽ tự thực hiện:

    1. Gọi model_introspection('hr.employee') để tìm field phù hợp.

    2. Gọi search_records để tìm ID của nhân viên “Nguyễn Văn A”.

    3. Gọi update_record để cập nhật dữ liệu.

    Kết luận

    Việc trang bị đầy đủ bộ công cụ CRUD và Introspection biến MCP Server thành một trợ lý đắc lực cho cả developer lẫn người dùng cuối. Bạn không còn phải nhớ tên kỹ thuật của các field hay thao tác thủ công trên giao diện web nữa.

    Hãy thử nghiệm với mã nguồn trên và cho mình biết bạn đã tự động hóa được tác vụ Odoo nào thú vị nhất nhé!

    Để lại một bình luận

    Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

    Chat with us
    Hello! How can I help you today?