aidoo-mcp 0.1.0__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.
- aidoo_mcp-0.1.0/.github/workflows/ci.yml +33 -0
- aidoo_mcp-0.1.0/.gitignore +15 -0
- aidoo_mcp-0.1.0/CHANGELOG.md +16 -0
- aidoo_mcp-0.1.0/CONTRIBUTING.md +29 -0
- aidoo_mcp-0.1.0/LICENSE +21 -0
- aidoo_mcp-0.1.0/PKG-INFO +250 -0
- aidoo_mcp-0.1.0/PUBLISHING.md +79 -0
- aidoo_mcp-0.1.0/README.md +203 -0
- aidoo_mcp-0.1.0/SECURITY.md +24 -0
- aidoo_mcp-0.1.0/pyproject.toml +59 -0
- aidoo_mcp-0.1.0/server.json +22 -0
- aidoo_mcp-0.1.0/src/aidoo_mcp/__init__.py +2 -0
- aidoo_mcp-0.1.0/src/aidoo_mcp/__main__.py +4 -0
- aidoo_mcp-0.1.0/src/aidoo_mcp/cli.py +156 -0
- aidoo_mcp-0.1.0/src/aidoo_mcp/config.py +138 -0
- aidoo_mcp-0.1.0/src/aidoo_mcp/proxy.py +44 -0
- aidoo_mcp-0.1.0/src/aidoo_mcp/transport.py +94 -0
- aidoo_mcp-0.1.0/tests/test_cli.py +24 -0
- aidoo_mcp-0.1.0/tests/test_config.py +112 -0
- aidoo_mcp-0.1.0/tests/test_proxy.py +51 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v5
|
|
22
|
+
|
|
23
|
+
- name: Install
|
|
24
|
+
run: uv sync --python ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Lint
|
|
27
|
+
run: uv run ruff check .
|
|
28
|
+
|
|
29
|
+
- name: Check formatting
|
|
30
|
+
run: uv run ruff format --check .
|
|
31
|
+
|
|
32
|
+
- name: Test
|
|
33
|
+
run: uv run pytest -q
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-09-22
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- stdio bridge to the hosted Aidoo MCP server, with bearer authentication
|
|
12
|
+
- streamable HTTP and SSE upstream transports, selected automatically from the URL
|
|
13
|
+
- `--check` command that verifies the endpoint, the handshake and the API key
|
|
14
|
+
- configuration through `AIDOO_API_KEY`, `AIDOO_MCP_URL`, `AIDOO_MCP_TRANSPORT`
|
|
15
|
+
and `AIDOO_MCP_TIMEOUT`, each overridable on the command line
|
|
16
|
+
- retries with backoff while the session is being established
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Issues and pull requests are welcome.
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/eantoniomota/aidoo-mcp.git
|
|
9
|
+
cd aidoo-mcp
|
|
10
|
+
uv sync
|
|
11
|
+
uv run pytest
|
|
12
|
+
uv run ruff check .
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Ground rules
|
|
16
|
+
|
|
17
|
+
- Keep the bridge transparent. It relays protocol messages and must not interpret,
|
|
18
|
+
rewrite or cache them. Tool behaviour belongs to the Aidoo server.
|
|
19
|
+
- Every change that touches configuration or the relay comes with a test.
|
|
20
|
+
- Run `ruff check .` and `ruff format .` before opening a pull request.
|
|
21
|
+
- Never commit an API key, a log containing one, or a real Odoo hostname.
|
|
22
|
+
|
|
23
|
+
## Reporting a bug
|
|
24
|
+
|
|
25
|
+
Include your Python version, the output of `aidoo-mcp --check`, the name of your MCP
|
|
26
|
+
client, and the relevant lines from its MCP log. Redact your API key.
|
|
27
|
+
|
|
28
|
+
For anything related to the Aidoo platform itself rather than this bridge, use the
|
|
29
|
+
support channels at [aidoo.ai](https://aidoo.ai/contact).
|
aidoo_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aidoo
|
|
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.
|
aidoo_mcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: aidoo-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Connect any MCP client to your Odoo ERP through Aidoo
|
|
5
|
+
Project-URL: Homepage, https://aidoo.ai
|
|
6
|
+
Project-URL: Documentation, https://aidoo.ai/docs
|
|
7
|
+
Project-URL: Source, https://github.com/eantoniomota/aidoo-mcp
|
|
8
|
+
Project-URL: Issues, https://github.com/eantoniomota/aidoo-mcp/issues
|
|
9
|
+
Author-email: Aidoo <support@aidoo.ai>
|
|
10
|
+
License: MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 Aidoo
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Keywords: aidoo,erp,mcp,model-context-protocol,odoo
|
|
33
|
+
Classifier: Development Status :: 4 - Beta
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
41
|
+
Classifier: Topic :: Office/Business
|
|
42
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
43
|
+
Requires-Python: >=3.10
|
|
44
|
+
Requires-Dist: anyio>=4.5
|
|
45
|
+
Requires-Dist: mcp>=1.9
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
|
|
48
|
+
# aidoo-mcp
|
|
49
|
+
|
|
50
|
+
Connect any MCP client to your Odoo ERP through [Aidoo](https://aidoo.ai).
|
|
51
|
+
|
|
52
|
+
`aidoo-mcp` is a small stdio bridge. It takes an Aidoo API key, opens an authenticated
|
|
53
|
+
session against the hosted Aidoo MCP server, and relays the Model Context Protocol
|
|
54
|
+
messages in both directions. Your assistant then queries, creates and updates Odoo
|
|
55
|
+
records in plain language, under the permissions carried by the key.
|
|
56
|
+
|
|
57
|
+
[](https://pypi.org/project/aidoo-mcp/)
|
|
58
|
+
[](https://pypi.org/project/aidoo-mcp/)
|
|
59
|
+
[](LICENSE)
|
|
60
|
+
|
|
61
|
+
## Why a bridge
|
|
62
|
+
|
|
63
|
+
The Aidoo MCP server is hosted at `https://mcp.aidoo.ai`, and clients that support
|
|
64
|
+
remote connectors with OAuth or custom headers can reach it directly, with nothing to
|
|
65
|
+
install. Many MCP clients still speak stdio only, or offer no way to set an
|
|
66
|
+
`Authorization` header. This bridge fills that gap: one command, no local server,
|
|
67
|
+
no Odoo credentials on your machine.
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
MCP client <--stdio--> aidoo-mcp <--HTTPS--> Aidoo <--XML-RPC--> Odoo
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The bridge is transparent. It never rewrites payloads, so every tool your workspace
|
|
74
|
+
exposes is available the moment Aidoo ships it, with no update needed here.
|
|
75
|
+
|
|
76
|
+
## Requirements
|
|
77
|
+
|
|
78
|
+
- Python 3.10 or newer
|
|
79
|
+
- An [Aidoo account](https://app.aidoo.ai/register) with an Odoo connection
|
|
80
|
+
- An Aidoo API key, prefixed `aid_live_`, created from the API keys page of your workspace
|
|
81
|
+
|
|
82
|
+
## Install
|
|
83
|
+
|
|
84
|
+
Run it without installing anything, with [uv](https://docs.astral.sh/uv/):
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uvx aidoo-mcp --check
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or install it:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pipx install aidoo-mcp
|
|
94
|
+
# or
|
|
95
|
+
pip install aidoo-mcp
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Check your setup
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
export AIDOO_API_KEY=aid_live_your_key_here
|
|
102
|
+
aidoo-mcp --check
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The command verifies that the endpoint answers, performs the MCP handshake and prints
|
|
106
|
+
the tools your key grants:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
[aidoo-mcp] https://mcp.aidoo.ai/health is reachable
|
|
110
|
+
[aidoo-mcp] authenticated with https://mcp.aidoo.ai/mcp (transport=http, key=aid_live_...cdef)
|
|
111
|
+
[aidoo-mcp] 8 tools available: aidoo_context, aidoo_create, aidoo_print, aidoo_query, ...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Configure your client
|
|
115
|
+
|
|
116
|
+
### Claude Desktop
|
|
117
|
+
|
|
118
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS,
|
|
119
|
+
`%APPDATA%\Claude\claude_desktop_config.json` on Windows:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"mcpServers": {
|
|
124
|
+
"aidoo": {
|
|
125
|
+
"command": "uvx",
|
|
126
|
+
"args": ["aidoo-mcp"],
|
|
127
|
+
"env": { "AIDOO_API_KEY": "aid_live_your_key_here" }
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Cursor
|
|
134
|
+
|
|
135
|
+
`~/.cursor/mcp.json`:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"aidoo": {
|
|
141
|
+
"command": "uvx",
|
|
142
|
+
"args": ["aidoo-mcp"],
|
|
143
|
+
"env": { "AIDOO_API_KEY": "aid_live_your_key_here" }
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Windsurf
|
|
150
|
+
|
|
151
|
+
`~/.codeium/windsurf/mcp_config.json`, same block as Cursor.
|
|
152
|
+
|
|
153
|
+
### VS Code
|
|
154
|
+
|
|
155
|
+
`.vscode/mcp.json` in your workspace:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"servers": {
|
|
160
|
+
"aidoo": {
|
|
161
|
+
"type": "stdio",
|
|
162
|
+
"command": "uvx",
|
|
163
|
+
"args": ["aidoo-mcp"],
|
|
164
|
+
"env": { "AIDOO_API_KEY": "aid_live_your_key_here" }
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Any other stdio client
|
|
171
|
+
|
|
172
|
+
Point it at the `aidoo-mcp` executable and pass the key through the environment. If the
|
|
173
|
+
client cannot set environment variables, use the flag instead:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
aidoo-mcp --api-key aid_live_your_key_here
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Cursor, Windsurf and any client that does accept custom headers can also skip the
|
|
180
|
+
bridge entirely and target `https://mcp.aidoo.ai/sse` with an `Authorization` header.
|
|
181
|
+
See the [Aidoo documentation](https://aidoo.ai/docs).
|
|
182
|
+
|
|
183
|
+
## Usage
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
aidoo-mcp [--api-key KEY] [--url URL] [--transport {http,sse}]
|
|
187
|
+
[--timeout SECONDS] [--retries N] [--check] [--quiet]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
| Option | Environment variable | Default |
|
|
191
|
+
| --- | --- | --- |
|
|
192
|
+
| `--api-key` | `AIDOO_API_KEY` | required |
|
|
193
|
+
| `--url` | `AIDOO_MCP_URL` | `https://mcp.aidoo.ai/mcp` |
|
|
194
|
+
| `--transport` | `AIDOO_MCP_TRANSPORT` | inferred from the URL path |
|
|
195
|
+
| `--timeout` | `AIDOO_MCP_TIMEOUT` | `60` |
|
|
196
|
+
| `--retries` | | `3` |
|
|
197
|
+
|
|
198
|
+
Logs go to stderr, so they never interfere with the protocol stream on stdout. Exit
|
|
199
|
+
code `2` means a configuration problem, `1` a connection that could not be established.
|
|
200
|
+
|
|
201
|
+
## Ask your assistant
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
List the five quotations I sent last week that are still pending.
|
|
205
|
+
Create a contact for Martin Dupont at Dupont SA, martin@dupont.fr.
|
|
206
|
+
Generate the PDF of invoice INV/2026/0042.
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Security
|
|
210
|
+
|
|
211
|
+
- The key is read from the environment or the command line and sent as a bearer token
|
|
212
|
+
over HTTPS. It is masked in every log line.
|
|
213
|
+
- Odoo credentials stay in Aidoo. The bridge never sees them, and never talks to Odoo.
|
|
214
|
+
- Each key carries its own permissions, and every call runs under the Odoo access
|
|
215
|
+
rules of the linked user. Grant only what the assistant needs.
|
|
216
|
+
- Use one key per person, never a shared key, and revoke it from the dashboard if in doubt.
|
|
217
|
+
- Report a vulnerability privately: see [SECURITY.md](SECURITY.md).
|
|
218
|
+
|
|
219
|
+
## Troubleshooting
|
|
220
|
+
|
|
221
|
+
**`No API key found`** The `AIDOO_API_KEY` variable did not reach the process. Client
|
|
222
|
+
configuration files often ignore your shell profile, so set the key in the `env` block
|
|
223
|
+
shown above.
|
|
224
|
+
|
|
225
|
+
**Handshake fails with 401** The key was revoked, or its MCP permissions are disabled.
|
|
226
|
+
Check it on the API keys page of your workspace.
|
|
227
|
+
|
|
228
|
+
**The tool list is shorter than expected** Tools follow the permissions of the key.
|
|
229
|
+
Grant the missing ones, then restart your client.
|
|
230
|
+
|
|
231
|
+
**Nothing happens in the client** Restart the client completely after editing its
|
|
232
|
+
configuration, then look at its MCP logs. `aidoo-mcp --check` tells you within seconds
|
|
233
|
+
whether the problem is on your side or ours.
|
|
234
|
+
|
|
235
|
+
**A corporate network blocks the connection** The bridge needs outbound HTTPS on port
|
|
236
|
+
443 to `mcp.aidoo.ai`. Try `--transport sse` if an intermediate proxy mishandles
|
|
237
|
+
streamable HTTP.
|
|
238
|
+
|
|
239
|
+
## Development
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
uv sync
|
|
243
|
+
uv run pytest
|
|
244
|
+
uv run ruff check .
|
|
245
|
+
uv run ruff format --check .
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Publishing to the MCP Registry
|
|
2
|
+
|
|
3
|
+
`server.json` describes the Aidoo server for the [official MCP Registry](https://registry.modelcontextprotocol.io).
|
|
4
|
+
The registry stores metadata only, and the entry is what makes Aidoo discoverable from
|
|
5
|
+
the clients and directories that read the registry.
|
|
6
|
+
|
|
7
|
+
The server is published as **`ai.aidoo/aidoo`**, the reverse DNS form of `aidoo.ai`.
|
|
8
|
+
That namespace is proven with a TXT record on the apex of the domain, signed by
|
|
9
|
+
`key.pem`. The key never leaves the machine and is excluded from the repository: keep
|
|
10
|
+
it in the password manager, because regenerating it means changing the DNS record.
|
|
11
|
+
|
|
12
|
+
## Every release
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
mcp-publisher validate
|
|
16
|
+
mcp-publisher login dns --domain aidoo.ai \
|
|
17
|
+
--private-key "$(openssl pkey -in key.pem -noout -text | grep -A3 priv | tail -n +2 | tr -d ' :\n')"
|
|
18
|
+
mcp-publisher publish
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Bump `version` in `server.json` first: the registry rejects a version that already
|
|
22
|
+
exists. On macOS the system `openssl` is LibreSSL and cannot read Ed25519 keys, so use
|
|
23
|
+
`/opt/homebrew/opt/openssl@3/bin/openssl`.
|
|
24
|
+
|
|
25
|
+
## The DNS record
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
aidoo.ai. IN TXT "v=MCPv1; k=ed25519; p=<public key>"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
It sits on the **apex**, next to the SPF and Google records, never under a selector such
|
|
32
|
+
as `_mcp-auth`. Regenerate the value with:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Retiring an entry
|
|
39
|
+
|
|
40
|
+
A remote URL belongs to a single server entry, so republishing under a different name
|
|
41
|
+
fails with `remote URL ... is already used` until the previous entry is retired:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
mcp-publisher login github
|
|
45
|
+
mcp-publisher status --status deleted --all-versions <old server name>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Adding the PyPI package
|
|
49
|
+
|
|
50
|
+
Once `aidoo-mcp` is on PyPI, add a `packages` block so clients can install the bridge
|
|
51
|
+
from the registry entry. PyPI ownership is proven through the package metadata, so
|
|
52
|
+
`pyproject.toml` needs this before the release that follows:
|
|
53
|
+
|
|
54
|
+
```toml
|
|
55
|
+
[project]
|
|
56
|
+
keywords = ["mcp-name:ai.aidoo/aidoo"]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Then add to `server.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
"packages": [
|
|
63
|
+
{
|
|
64
|
+
"registryType": "pypi",
|
|
65
|
+
"identifier": "aidoo-mcp",
|
|
66
|
+
"version": "0.1.0",
|
|
67
|
+
"transport": { "type": "stdio" },
|
|
68
|
+
"environmentVariables": [
|
|
69
|
+
{
|
|
70
|
+
"name": "AIDOO_API_KEY",
|
|
71
|
+
"description": "Aidoo API key, prefixed aid_live_",
|
|
72
|
+
"isRequired": true,
|
|
73
|
+
"isSecret": true,
|
|
74
|
+
"format": "string"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
```
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# aidoo-mcp
|
|
2
|
+
|
|
3
|
+
Connect any MCP client to your Odoo ERP through [Aidoo](https://aidoo.ai).
|
|
4
|
+
|
|
5
|
+
`aidoo-mcp` is a small stdio bridge. It takes an Aidoo API key, opens an authenticated
|
|
6
|
+
session against the hosted Aidoo MCP server, and relays the Model Context Protocol
|
|
7
|
+
messages in both directions. Your assistant then queries, creates and updates Odoo
|
|
8
|
+
records in plain language, under the permissions carried by the key.
|
|
9
|
+
|
|
10
|
+
[](https://pypi.org/project/aidoo-mcp/)
|
|
11
|
+
[](https://pypi.org/project/aidoo-mcp/)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
|
|
14
|
+
## Why a bridge
|
|
15
|
+
|
|
16
|
+
The Aidoo MCP server is hosted at `https://mcp.aidoo.ai`, and clients that support
|
|
17
|
+
remote connectors with OAuth or custom headers can reach it directly, with nothing to
|
|
18
|
+
install. Many MCP clients still speak stdio only, or offer no way to set an
|
|
19
|
+
`Authorization` header. This bridge fills that gap: one command, no local server,
|
|
20
|
+
no Odoo credentials on your machine.
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
MCP client <--stdio--> aidoo-mcp <--HTTPS--> Aidoo <--XML-RPC--> Odoo
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The bridge is transparent. It never rewrites payloads, so every tool your workspace
|
|
27
|
+
exposes is available the moment Aidoo ships it, with no update needed here.
|
|
28
|
+
|
|
29
|
+
## Requirements
|
|
30
|
+
|
|
31
|
+
- Python 3.10 or newer
|
|
32
|
+
- An [Aidoo account](https://app.aidoo.ai/register) with an Odoo connection
|
|
33
|
+
- An Aidoo API key, prefixed `aid_live_`, created from the API keys page of your workspace
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
Run it without installing anything, with [uv](https://docs.astral.sh/uv/):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
uvx aidoo-mcp --check
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or install it:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pipx install aidoo-mcp
|
|
47
|
+
# or
|
|
48
|
+
pip install aidoo-mcp
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Check your setup
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
export AIDOO_API_KEY=aid_live_your_key_here
|
|
55
|
+
aidoo-mcp --check
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The command verifies that the endpoint answers, performs the MCP handshake and prints
|
|
59
|
+
the tools your key grants:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
[aidoo-mcp] https://mcp.aidoo.ai/health is reachable
|
|
63
|
+
[aidoo-mcp] authenticated with https://mcp.aidoo.ai/mcp (transport=http, key=aid_live_...cdef)
|
|
64
|
+
[aidoo-mcp] 8 tools available: aidoo_context, aidoo_create, aidoo_print, aidoo_query, ...
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Configure your client
|
|
68
|
+
|
|
69
|
+
### Claude Desktop
|
|
70
|
+
|
|
71
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS,
|
|
72
|
+
`%APPDATA%\Claude\claude_desktop_config.json` on Windows:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"aidoo": {
|
|
78
|
+
"command": "uvx",
|
|
79
|
+
"args": ["aidoo-mcp"],
|
|
80
|
+
"env": { "AIDOO_API_KEY": "aid_live_your_key_here" }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Cursor
|
|
87
|
+
|
|
88
|
+
`~/.cursor/mcp.json`:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"aidoo": {
|
|
94
|
+
"command": "uvx",
|
|
95
|
+
"args": ["aidoo-mcp"],
|
|
96
|
+
"env": { "AIDOO_API_KEY": "aid_live_your_key_here" }
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Windsurf
|
|
103
|
+
|
|
104
|
+
`~/.codeium/windsurf/mcp_config.json`, same block as Cursor.
|
|
105
|
+
|
|
106
|
+
### VS Code
|
|
107
|
+
|
|
108
|
+
`.vscode/mcp.json` in your workspace:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"servers": {
|
|
113
|
+
"aidoo": {
|
|
114
|
+
"type": "stdio",
|
|
115
|
+
"command": "uvx",
|
|
116
|
+
"args": ["aidoo-mcp"],
|
|
117
|
+
"env": { "AIDOO_API_KEY": "aid_live_your_key_here" }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Any other stdio client
|
|
124
|
+
|
|
125
|
+
Point it at the `aidoo-mcp` executable and pass the key through the environment. If the
|
|
126
|
+
client cannot set environment variables, use the flag instead:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
aidoo-mcp --api-key aid_live_your_key_here
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Cursor, Windsurf and any client that does accept custom headers can also skip the
|
|
133
|
+
bridge entirely and target `https://mcp.aidoo.ai/sse` with an `Authorization` header.
|
|
134
|
+
See the [Aidoo documentation](https://aidoo.ai/docs).
|
|
135
|
+
|
|
136
|
+
## Usage
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
aidoo-mcp [--api-key KEY] [--url URL] [--transport {http,sse}]
|
|
140
|
+
[--timeout SECONDS] [--retries N] [--check] [--quiet]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
| Option | Environment variable | Default |
|
|
144
|
+
| --- | --- | --- |
|
|
145
|
+
| `--api-key` | `AIDOO_API_KEY` | required |
|
|
146
|
+
| `--url` | `AIDOO_MCP_URL` | `https://mcp.aidoo.ai/mcp` |
|
|
147
|
+
| `--transport` | `AIDOO_MCP_TRANSPORT` | inferred from the URL path |
|
|
148
|
+
| `--timeout` | `AIDOO_MCP_TIMEOUT` | `60` |
|
|
149
|
+
| `--retries` | | `3` |
|
|
150
|
+
|
|
151
|
+
Logs go to stderr, so they never interfere with the protocol stream on stdout. Exit
|
|
152
|
+
code `2` means a configuration problem, `1` a connection that could not be established.
|
|
153
|
+
|
|
154
|
+
## Ask your assistant
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
List the five quotations I sent last week that are still pending.
|
|
158
|
+
Create a contact for Martin Dupont at Dupont SA, martin@dupont.fr.
|
|
159
|
+
Generate the PDF of invoice INV/2026/0042.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Security
|
|
163
|
+
|
|
164
|
+
- The key is read from the environment or the command line and sent as a bearer token
|
|
165
|
+
over HTTPS. It is masked in every log line.
|
|
166
|
+
- Odoo credentials stay in Aidoo. The bridge never sees them, and never talks to Odoo.
|
|
167
|
+
- Each key carries its own permissions, and every call runs under the Odoo access
|
|
168
|
+
rules of the linked user. Grant only what the assistant needs.
|
|
169
|
+
- Use one key per person, never a shared key, and revoke it from the dashboard if in doubt.
|
|
170
|
+
- Report a vulnerability privately: see [SECURITY.md](SECURITY.md).
|
|
171
|
+
|
|
172
|
+
## Troubleshooting
|
|
173
|
+
|
|
174
|
+
**`No API key found`** The `AIDOO_API_KEY` variable did not reach the process. Client
|
|
175
|
+
configuration files often ignore your shell profile, so set the key in the `env` block
|
|
176
|
+
shown above.
|
|
177
|
+
|
|
178
|
+
**Handshake fails with 401** The key was revoked, or its MCP permissions are disabled.
|
|
179
|
+
Check it on the API keys page of your workspace.
|
|
180
|
+
|
|
181
|
+
**The tool list is shorter than expected** Tools follow the permissions of the key.
|
|
182
|
+
Grant the missing ones, then restart your client.
|
|
183
|
+
|
|
184
|
+
**Nothing happens in the client** Restart the client completely after editing its
|
|
185
|
+
configuration, then look at its MCP logs. `aidoo-mcp --check` tells you within seconds
|
|
186
|
+
whether the problem is on your side or ours.
|
|
187
|
+
|
|
188
|
+
**A corporate network blocks the connection** The bridge needs outbound HTTPS on port
|
|
189
|
+
443 to `mcp.aidoo.ai`. Try `--transport sse` if an intermediate proxy mishandles
|
|
190
|
+
streamable HTTP.
|
|
191
|
+
|
|
192
|
+
## Development
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
uv sync
|
|
196
|
+
uv run pytest
|
|
197
|
+
uv run ruff check .
|
|
198
|
+
uv run ruff format --check .
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
Report vulnerabilities privately to **security@aidoo.ai**. Do not open a public issue.
|
|
6
|
+
|
|
7
|
+
Include the affected version, the steps to reproduce, and the impact you observed. You
|
|
8
|
+
will get an acknowledgement within three business days, and a fix or a mitigation plan
|
|
9
|
+
within thirty days for confirmed issues.
|
|
10
|
+
|
|
11
|
+
## Scope
|
|
12
|
+
|
|
13
|
+
This repository contains the stdio bridge only. It holds no Odoo credentials and stores
|
|
14
|
+
nothing on disk. Reports about the hosted Aidoo platform are equally welcome at the same
|
|
15
|
+
address.
|
|
16
|
+
|
|
17
|
+
## Handling your API key
|
|
18
|
+
|
|
19
|
+
- The key is read from `AIDOO_API_KEY` or `--api-key`, sent as a bearer token over HTTPS,
|
|
20
|
+
and masked in every log line the bridge writes.
|
|
21
|
+
- Prefer the environment over the command line: process arguments are visible to other
|
|
22
|
+
local processes.
|
|
23
|
+
- Use one key per person, and revoke it from the Aidoo dashboard as soon as it leaks.
|
|
24
|
+
- Grant each key the narrowest set of permissions that still does the job.
|