Skip to main content
Glama
README.md
# Odoo MCP server for OpenCode

This workspace ships a local **stdio MCP server** (`odoo_mcp`) that exposes your
self-hosted Odoo project tasks, chatter, and timesheets as ten typed tools an
agent can call directly. The same repository still contains the original
`odoo_tasks.py` CLI — unchanged behaviorally — which shares the service layer
with the MCP server.

## Prerequisites

- Python 3.10+ (workspace developed against 3.12)
- [uv](https://docs.astral.sh/uv/) on PATH (`pip install uv` if missing)

Install everything once:

```powershell
uv sync
```

## Credentials (environment variables)

| Variable | Purpose | Default |
| --- | --- | --- |
| `ODOO_URL` | Base URL of your Odoo instance | `https://odoo.geosigmoid.group` |
| `ODOO_DB` | Database name | `odoo` |
| `ODOO_USERNAME` | Your login email | required |
| `ODOO_PASSWORD` | Password **or external API key** | required |

`ODOO_URL` must be an absolute HTTPS URL so credentials are never sent over
cleartext HTTP.

An **API key is strongly recommended** over a password (Odoo: Preferences →
Account Security → New API Key): it is revocable and cannot be used for web
login. Copy `.env.example` to `.env`, fill it in, and load it into your shell,
or set the variables however you manage secrets. The MCP server and CLI helper
both auto-load a workspace-root `.env` when it is present; environment
variables already set by OpenCode or the shell take precedence. Never commit
`.env`.

**Interpolation caveat:** `opencode.json` uses `{env:VAR}` placeholders. If a
variable is missing when OpenCode starts, it becomes an **empty string**, and
every tool call will fail with a clear error naming the missing variable(s)
(`Missing required environment variables: ODOO_USERNAME, ...`) instead of
sending bad credentials anywhere. Values are never echoed to logs or results.

## Registering with OpenCode

`opencode.json` in this workspace already contains:

```jsonc
{
  "mcp": {
    "odoo": {
      "type": "local",
      "command": ["uv", "run", "python", "-m", "odoo_mcp"],
      "environment": { "...": "{env:ODOO_*} placeholders" },
      "enabled": true
    }
  }
}
```

OpenCode loads config at startup — after changing credentials or this file,
**quit and restart OpenCode** for them to take effect. The server is spawned
once per session over stdio; nothing listens on any network port.

## Tools

Mutating tools **execute immediately by default**; every one accepts a
`dry_run=true` flag that returns a preview without writing anything.

| Tool | What it does |
| --- | --- |
| `list_my_tasks` | Tasks assigned to you; filter by project, stage, state, due dates |
| `get_task` | Full detail of one task (planned/logged hours included) |
| `create_task` | Create a task in a project; optional description/priority/deadline/hours/stage; assignees default to you |
| `update_task` | Set name/description/priority/deadline/hours/state/stage; `append_description` merges text into the existing description |
| `post_task_message` | Post to a task's chatter (followers get notified) |
| `get_task_states` | Valid workflow state codes on this server + which are terminal |
| `list_stages` | Task stage ids/names for filtering |
| `list_timesheets` | Your timesheet entries; filter by task or recent days |
| `create_timesheet` | Log hours on a task (date defaults to today) |
| `update_timesheet` | Change hours/date/description/task of an entry |

State codes vary per Odoo build — call `get_task_states` first rather than
guessing; invalid states are rejected with the list of valid ones.

## Verifying the install

```powershell
uv sync                                              # deps resolve
uv run pytest tests -q                               # protocol + service suites
uv run python -m unittest discover -s tests -v       # CLI characterization suite
uv run python odoo_tasks.py --help                   # legacy CLI still intact
```

The stdio handshake itself is covered by `tests/test_stdio_smoke.py`.

TDQS

A4.1/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct resource and action: tasks (get, list, update, message, states) and timesheets (list, create, update), plus stage listing. There is no overlap or ambiguity between tool purposes.

Naming Consistency5/5

Tool names follow a consistent verb_noun pattern throughout: get_task, list_my_tasks, update_task, post_task_message, list_stages, create_timesheet, etc. Minor variation between 'get_task_states' and 'list_stages' is natural and still fits the pattern.

Tool Count5/5

With 9 tools, the set is well-scoped. Each tool serves a clear purpose within the task and timesheet domain, and the count is in the ideal range for usability.

Completeness3/5

Task and timesheet operations cover the main read/update workflows, including states, stages, and messaging. However, there are notable gaps: no create_task, no delete_task, and no delete_timesheet, which prevents full lifecycle management.

Maintenance

ActivityMaintained
ResponsivenessNo issues