odoo-mcp 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
odoo_mcp-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lê Anh Tuấn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,245 @@
1
+ Metadata-Version: 2.2
2
+ Name: odoo-mcp
3
+ Version: 0.0.1
4
+ Summary: MCP Server for Odoo Integration
5
+ Author-email: Lê Anh Tuấn <justin.le.1105@gmail.com>
6
+ Project-URL: Homepage, https://github.com/tuanle03/mcp-odoo
7
+ Project-URL: Issues, https://github.com/tuanle03/mcp-odoo/issues
8
+ Keywords: odoo,mcp,server
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Provides-Extra: dev
17
+ Requires-Dist: black; extra == "dev"
18
+ Requires-Dist: isort; extra == "dev"
19
+ Requires-Dist: mypy; extra == "dev"
20
+ Requires-Dist: ruff; extra == "dev"
21
+ Requires-Dist: build; extra == "dev"
22
+ Requires-Dist: twine; extra == "dev"
23
+
24
+ # Odoo MCP Server
25
+
26
+ An MCP server implementation that integrates with Odoo ERP systems, enabling AI assistants to interact with Odoo data and functionality through the Model Context Protocol.
27
+
28
+ ## Features
29
+
30
+ * **Comprehensive Odoo Integration**: Full access to Odoo models, records, and methods
31
+ * **XML-RPC Communication**: Secure connection to Odoo instances via XML-RPC
32
+ * **Flexible Configuration**: Support for config files and environment variables
33
+ * **Resource Pattern System**: URI-based access to Odoo data structures
34
+ * **Error Handling**: Clear error messages for common Odoo API issues
35
+ * **Stateless Operations**: Clean request/response cycle for reliable integration
36
+
37
+ ## Tools
38
+
39
+ * **search_records**
40
+ * Search for records in any Odoo model
41
+ * Inputs:
42
+ * `model` (string): The model name (e.g., 'res.partner')
43
+ * `domain` (array): Search domain (e.g., [['is_company', '=', true]])
44
+ * `fields` (optional array): Optional fields to fetch
45
+ * `limit` (optional number): Maximum number of records to return
46
+ * Returns: Matching records with requested fields
47
+
48
+ * **read_record**
49
+ * Read details of a specific record
50
+ * Inputs:
51
+ * `model` (string): The model name (e.g., 'res.partner')
52
+ * `id` (number): The record ID
53
+ * `fields` (optional array): Optional fields to fetch
54
+ * Returns: Record data with requested fields
55
+
56
+ * **create_record**
57
+ * Create a new record in Odoo
58
+ * Inputs:
59
+ * `model` (string): The model name (e.g., 'res.partner')
60
+ * `values` (object): Dictionary of field values
61
+ * Returns: Dictionary with the new record ID
62
+
63
+ * **update_record**
64
+ * Update an existing record
65
+ * Inputs:
66
+ * `model` (string): The model name (e.g., 'res.partner')
67
+ * `id` (number): The record ID
68
+ * `values` (object): Dictionary of field values to update
69
+ * Returns: Dictionary indicating success
70
+
71
+ * **delete_record**
72
+ * Delete a record from Odoo
73
+ * Inputs:
74
+ * `model` (string): The model name (e.g., 'res.partner')
75
+ * `id` (number): The record ID
76
+ * Returns: Dictionary indicating success
77
+
78
+ * **execute_method**
79
+ * Execute a custom method on an Odoo model
80
+ * Inputs:
81
+ * `model` (string): The model name (e.g., 'res.partner')
82
+ * `method` (string): Method name to execute
83
+ * `args` (optional array): Positional arguments
84
+ * `kwargs` (optional object): Keyword arguments
85
+ * Returns: Dictionary with the method result
86
+
87
+ * **get_model_fields**
88
+ * Get field definitions for a model
89
+ * Inputs:
90
+ * `model` (string): The model name (e.g., 'res.partner')
91
+ * Returns: Dictionary with field definitions
92
+
93
+ ## Resources
94
+
95
+ * **odoo://models**
96
+ * Lists all available models in the Odoo system
97
+ * Returns: JSON array of model information
98
+
99
+ * **odoo://model/{model_name}**
100
+ * Get information about a specific model including fields
101
+ * Example: `odoo://model/res.partner`
102
+ * Returns: JSON object with model metadata and field definitions
103
+
104
+ * **odoo://record/{model_name}/{record_id}**
105
+ * Get a specific record by ID
106
+ * Example: `odoo://record/res.partner/1`
107
+ * Returns: JSON object with record data
108
+
109
+ * **odoo://search/{model_name}/{domain}**
110
+ * Search for records that match a domain
111
+ * Example: `odoo://search/res.partner/[["is_company","=",true]]`
112
+ * Returns: JSON array of matching records (limited to 10 by default)
113
+
114
+ ## Configuration
115
+
116
+ ### Odoo Connection Setup
117
+
118
+ 1. Create a configuration file named `odoo_config.json`:
119
+
120
+ ```json
121
+ {
122
+ "url": "https://your-odoo-instance.com",
123
+ "db": "your-database-name",
124
+ "username": "your-username",
125
+ "password": "your-password-or-api-key"
126
+ }
127
+ ```
128
+
129
+ 2. Alternatively, use environment variables:
130
+ * `ODOO_URL`: Your Odoo server URL
131
+ * `ODOO_DB`: Database name
132
+ * `ODOO_USERNAME`: Login username
133
+ * `ODOO_PASSWORD`: Password or API key
134
+ * `ODOO_TIMEOUT`: Connection timeout in seconds (default: 30)
135
+ * `ODOO_VERIFY_SSL`: Whether to verify SSL certificates (default: true)
136
+
137
+ ### Usage with Claude Desktop
138
+
139
+ Add this to your `claude_desktop_config.json`:
140
+
141
+ ```json
142
+ {
143
+ "mcpServers": {
144
+ "odoo": {
145
+ "command": "python",
146
+ "args": [
147
+ "-m",
148
+ "odoo_mcp"
149
+ ],
150
+ "env": {
151
+ "ODOO_URL": "https://your-odoo-instance.com",
152
+ "ODOO_DB": "your-database-name",
153
+ "ODOO_USERNAME": "your-username",
154
+ "ODOO_PASSWORD": "your-password-or-api-key"
155
+ }
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ ### Docker
162
+
163
+ ```json
164
+ {
165
+ "mcpServers": {
166
+ "odoo": {
167
+ "command": "docker",
168
+ "args": [
169
+ "run",
170
+ "-i",
171
+ "--rm",
172
+ "-e",
173
+ "ODOO_URL",
174
+ "-e",
175
+ "ODOO_DB",
176
+ "-e",
177
+ "ODOO_USERNAME",
178
+ "-e",
179
+ "ODOO_PASSWORD",
180
+ "mcp/odoo"
181
+ ],
182
+ "env": {
183
+ "ODOO_URL": "https://your-odoo-instance.com",
184
+ "ODOO_DB": "your-database-name",
185
+ "ODOO_USERNAME": "your-username",
186
+ "ODOO_PASSWORD": "your-password-or-api-key"
187
+ }
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ ## Installation
194
+
195
+ ### Python Package
196
+
197
+ ```bash
198
+ pip install odoo-mcp
199
+ ```
200
+
201
+ ### Running the Server
202
+
203
+ ```bash
204
+ # Using the installed package
205
+ odoo-mcp
206
+
207
+ # Using the MCP development tools
208
+ mcp dev odoo_mcp/server.py
209
+
210
+ # With additional dependencies
211
+ mcp dev odoo_mcp/server.py --with pandas --with numpy
212
+
213
+ # Mount local code for development
214
+ mcp dev odoo_mcp/server.py --with-editable .
215
+ ```
216
+
217
+ ## Build
218
+
219
+ Docker build:
220
+
221
+ ```bash
222
+ docker build -t mcp/odoo:latest -f Dockerfile .
223
+ ```
224
+
225
+ ## Parameter Formatting Guidelines
226
+
227
+ When using the MCP tools for Odoo, pay attention to these parameter formatting guidelines:
228
+
229
+ 1. **Domain Parameter**:
230
+ * The following domain formats are supported:
231
+ * List format: `[["field", "operator", value], ...]`
232
+ * Object format: `{"conditions": [{"field": "...", "operator": "...", "value": "..."}]}`
233
+ * JSON string of either format
234
+ * Examples:
235
+ * List format: `[["is_company", "=", true]]`
236
+ * Object format: `{"conditions": [{"field": "date_order", "operator": ">=", "value": "2025-03-01"}]}`
237
+ * Multiple conditions: `[["date_order", ">=", "2025-03-01"], ["date_order", "<=", "2025-03-31"]]`
238
+
239
+ 2. **Fields Parameter**:
240
+ * Should be an array of field names: `["name", "email", "phone"]`
241
+ * The server will try to parse string inputs as JSON
242
+
243
+ ## License
244
+
245
+ This MCP server is licensed under the MIT License.
@@ -0,0 +1,222 @@
1
+ # Odoo MCP Server
2
+
3
+ An MCP server implementation that integrates with Odoo ERP systems, enabling AI assistants to interact with Odoo data and functionality through the Model Context Protocol.
4
+
5
+ ## Features
6
+
7
+ * **Comprehensive Odoo Integration**: Full access to Odoo models, records, and methods
8
+ * **XML-RPC Communication**: Secure connection to Odoo instances via XML-RPC
9
+ * **Flexible Configuration**: Support for config files and environment variables
10
+ * **Resource Pattern System**: URI-based access to Odoo data structures
11
+ * **Error Handling**: Clear error messages for common Odoo API issues
12
+ * **Stateless Operations**: Clean request/response cycle for reliable integration
13
+
14
+ ## Tools
15
+
16
+ * **search_records**
17
+ * Search for records in any Odoo model
18
+ * Inputs:
19
+ * `model` (string): The model name (e.g., 'res.partner')
20
+ * `domain` (array): Search domain (e.g., [['is_company', '=', true]])
21
+ * `fields` (optional array): Optional fields to fetch
22
+ * `limit` (optional number): Maximum number of records to return
23
+ * Returns: Matching records with requested fields
24
+
25
+ * **read_record**
26
+ * Read details of a specific record
27
+ * Inputs:
28
+ * `model` (string): The model name (e.g., 'res.partner')
29
+ * `id` (number): The record ID
30
+ * `fields` (optional array): Optional fields to fetch
31
+ * Returns: Record data with requested fields
32
+
33
+ * **create_record**
34
+ * Create a new record in Odoo
35
+ * Inputs:
36
+ * `model` (string): The model name (e.g., 'res.partner')
37
+ * `values` (object): Dictionary of field values
38
+ * Returns: Dictionary with the new record ID
39
+
40
+ * **update_record**
41
+ * Update an existing record
42
+ * Inputs:
43
+ * `model` (string): The model name (e.g., 'res.partner')
44
+ * `id` (number): The record ID
45
+ * `values` (object): Dictionary of field values to update
46
+ * Returns: Dictionary indicating success
47
+
48
+ * **delete_record**
49
+ * Delete a record from Odoo
50
+ * Inputs:
51
+ * `model` (string): The model name (e.g., 'res.partner')
52
+ * `id` (number): The record ID
53
+ * Returns: Dictionary indicating success
54
+
55
+ * **execute_method**
56
+ * Execute a custom method on an Odoo model
57
+ * Inputs:
58
+ * `model` (string): The model name (e.g., 'res.partner')
59
+ * `method` (string): Method name to execute
60
+ * `args` (optional array): Positional arguments
61
+ * `kwargs` (optional object): Keyword arguments
62
+ * Returns: Dictionary with the method result
63
+
64
+ * **get_model_fields**
65
+ * Get field definitions for a model
66
+ * Inputs:
67
+ * `model` (string): The model name (e.g., 'res.partner')
68
+ * Returns: Dictionary with field definitions
69
+
70
+ ## Resources
71
+
72
+ * **odoo://models**
73
+ * Lists all available models in the Odoo system
74
+ * Returns: JSON array of model information
75
+
76
+ * **odoo://model/{model_name}**
77
+ * Get information about a specific model including fields
78
+ * Example: `odoo://model/res.partner`
79
+ * Returns: JSON object with model metadata and field definitions
80
+
81
+ * **odoo://record/{model_name}/{record_id}**
82
+ * Get a specific record by ID
83
+ * Example: `odoo://record/res.partner/1`
84
+ * Returns: JSON object with record data
85
+
86
+ * **odoo://search/{model_name}/{domain}**
87
+ * Search for records that match a domain
88
+ * Example: `odoo://search/res.partner/[["is_company","=",true]]`
89
+ * Returns: JSON array of matching records (limited to 10 by default)
90
+
91
+ ## Configuration
92
+
93
+ ### Odoo Connection Setup
94
+
95
+ 1. Create a configuration file named `odoo_config.json`:
96
+
97
+ ```json
98
+ {
99
+ "url": "https://your-odoo-instance.com",
100
+ "db": "your-database-name",
101
+ "username": "your-username",
102
+ "password": "your-password-or-api-key"
103
+ }
104
+ ```
105
+
106
+ 2. Alternatively, use environment variables:
107
+ * `ODOO_URL`: Your Odoo server URL
108
+ * `ODOO_DB`: Database name
109
+ * `ODOO_USERNAME`: Login username
110
+ * `ODOO_PASSWORD`: Password or API key
111
+ * `ODOO_TIMEOUT`: Connection timeout in seconds (default: 30)
112
+ * `ODOO_VERIFY_SSL`: Whether to verify SSL certificates (default: true)
113
+
114
+ ### Usage with Claude Desktop
115
+
116
+ Add this to your `claude_desktop_config.json`:
117
+
118
+ ```json
119
+ {
120
+ "mcpServers": {
121
+ "odoo": {
122
+ "command": "python",
123
+ "args": [
124
+ "-m",
125
+ "odoo_mcp"
126
+ ],
127
+ "env": {
128
+ "ODOO_URL": "https://your-odoo-instance.com",
129
+ "ODOO_DB": "your-database-name",
130
+ "ODOO_USERNAME": "your-username",
131
+ "ODOO_PASSWORD": "your-password-or-api-key"
132
+ }
133
+ }
134
+ }
135
+ }
136
+ ```
137
+
138
+ ### Docker
139
+
140
+ ```json
141
+ {
142
+ "mcpServers": {
143
+ "odoo": {
144
+ "command": "docker",
145
+ "args": [
146
+ "run",
147
+ "-i",
148
+ "--rm",
149
+ "-e",
150
+ "ODOO_URL",
151
+ "-e",
152
+ "ODOO_DB",
153
+ "-e",
154
+ "ODOO_USERNAME",
155
+ "-e",
156
+ "ODOO_PASSWORD",
157
+ "mcp/odoo"
158
+ ],
159
+ "env": {
160
+ "ODOO_URL": "https://your-odoo-instance.com",
161
+ "ODOO_DB": "your-database-name",
162
+ "ODOO_USERNAME": "your-username",
163
+ "ODOO_PASSWORD": "your-password-or-api-key"
164
+ }
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ ## Installation
171
+
172
+ ### Python Package
173
+
174
+ ```bash
175
+ pip install odoo-mcp
176
+ ```
177
+
178
+ ### Running the Server
179
+
180
+ ```bash
181
+ # Using the installed package
182
+ odoo-mcp
183
+
184
+ # Using the MCP development tools
185
+ mcp dev odoo_mcp/server.py
186
+
187
+ # With additional dependencies
188
+ mcp dev odoo_mcp/server.py --with pandas --with numpy
189
+
190
+ # Mount local code for development
191
+ mcp dev odoo_mcp/server.py --with-editable .
192
+ ```
193
+
194
+ ## Build
195
+
196
+ Docker build:
197
+
198
+ ```bash
199
+ docker build -t mcp/odoo:latest -f Dockerfile .
200
+ ```
201
+
202
+ ## Parameter Formatting Guidelines
203
+
204
+ When using the MCP tools for Odoo, pay attention to these parameter formatting guidelines:
205
+
206
+ 1. **Domain Parameter**:
207
+ * The following domain formats are supported:
208
+ * List format: `[["field", "operator", value], ...]`
209
+ * Object format: `{"conditions": [{"field": "...", "operator": "...", "value": "..."}]}`
210
+ * JSON string of either format
211
+ * Examples:
212
+ * List format: `[["is_company", "=", true]]`
213
+ * Object format: `{"conditions": [{"field": "date_order", "operator": ">=", "value": "2025-03-01"}]}`
214
+ * Multiple conditions: `[["date_order", ">=", "2025-03-01"], ["date_order", "<=", "2025-03-31"]]`
215
+
216
+ 2. **Fields Parameter**:
217
+ * Should be an array of field names: `["name", "email", "phone"]`
218
+ * The server will try to parse string inputs as JSON
219
+
220
+ ## License
221
+
222
+ This MCP server is licensed under the MIT License.
@@ -0,0 +1,56 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "odoo-mcp"
7
+ version = "0.0.1"
8
+ description = "MCP Server for Odoo Integration"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ classifiers = [
12
+ "License :: OSI Approved :: MIT License",
13
+ "Programming Language :: Python :: 3",
14
+ "Programming Language :: Python :: 3.10",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ keywords = ["odoo", "mcp", "server"]
18
+ authors = [
19
+ {name = "Lê Anh Tuấn", email = "justin.le.1105@gmail.com"}
20
+ ]
21
+
22
+ [project.urls]
23
+ Homepage = "https://github.com/tuanle03/mcp-odoo"
24
+ Issues = "https://github.com/tuanle03/mcp-odoo/issues"
25
+
26
+ [project.optional-dependencies]
27
+ dev = [
28
+ "black",
29
+ "isort",
30
+ "mypy",
31
+ "ruff",
32
+ "build",
33
+ "twine",
34
+ ]
35
+
36
+ [project.scripts]
37
+ odoo-mcp = "odoo_mcp.__main__:main"
38
+
39
+ [tool.setuptools]
40
+ package-dir = {"" = "src"}
41
+ packages = ["odoo_mcp"]
42
+
43
+ [tool.black]
44
+ line-length = 88
45
+ target-version = ["py310"]
46
+
47
+ [tool.isort]
48
+ profile = "black"
49
+ line_length = 88
50
+
51
+ [tool.mypy]
52
+ python_version = "3.10"
53
+ warn_return_any = true
54
+ warn_unused_configs = true
55
+ disallow_untyped_defs = true
56
+ disallow_incomplete_defs = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ """
2
+ Odoo MCP Server - MCP Server for Odoo Integration
3
+ """
4
+
5
+ from .server import mcp
6
+
7
+ __all__ = ["mcp"]
@@ -0,0 +1,54 @@
1
+ """
2
+ Command line entry point for the Odoo MCP Server
3
+ """
4
+ import sys
5
+ import asyncio
6
+ import traceback
7
+ import os
8
+
9
+ from .server import mcp
10
+
11
+
12
+ def main() -> int:
13
+ """
14
+ Run the MCP server
15
+ """
16
+ try:
17
+ print("=== ODOO MCP SERVER STARTING ===", file=sys.stderr)
18
+ print(f"Python version: {sys.version}", file=sys.stderr)
19
+ print("Environment variables:", file=sys.stderr)
20
+ for key, value in os.environ.items():
21
+ if key.startswith("ODOO_"):
22
+ if key == "ODOO_PASSWORD":
23
+ print(f" {key}: ***hidden***", file=sys.stderr)
24
+ else:
25
+ print(f" {key}: {value}", file=sys.stderr)
26
+
27
+ # Check if server instance has the run_stdio method
28
+ methods = [method for method in dir(mcp) if not method.startswith('_')]
29
+ print(f"Available methods on mcp object: {methods}", file=sys.stderr)
30
+
31
+ print("Starting MCP server with run() method...", file=sys.stderr)
32
+ sys.stderr.flush() # Ensure log information is written immediately
33
+
34
+ # Use the run() method directly
35
+ mcp.run()
36
+
37
+ # If execution reaches here, the server exited normally
38
+ print("MCP server stopped normally", file=sys.stderr)
39
+ return 0
40
+ except KeyboardInterrupt:
41
+ print("MCP server stopped by user", file=sys.stderr)
42
+ return 0
43
+ except Exception as e:
44
+ print(f"Error starting server: {e}", file=sys.stderr)
45
+ print("Exception details:", file=sys.stderr)
46
+ traceback.print_exc(file=sys.stderr)
47
+ print("\nServer object information:", file=sys.stderr)
48
+ print(f"MCP object type: {type(mcp)}", file=sys.stderr)
49
+ print(f"MCP object dir: {dir(mcp)}", file=sys.stderr)
50
+ return 1
51
+
52
+
53
+ if __name__ == "__main__":
54
+ sys.exit(main())