odoo-sh-readonly-mcp
Read-only MCP server for Odoo.sh exposing builds, environments, logs, and system status via Web API and SSH without any write capabilities.
README
odoo-sh-readonly-mcp 🔒
MCP solo lectura para Odoo.sh: builds, entornos, logs y estado del sistema — consultable por una AI sin entrar a la web.
Sin tools de escritura: no hay git push, ni shell arbitrario, ni escritura de archivos. SSH via execFile (sin shell → sin command injection) con comandos whitelisted. El smoke test de CI falla el build si alguna vez aparece una tool con nombre de escritura o sin readOnlyHint.
📑 Tabla de contenidos
- Tools
- Instalación via imagen GHCR
- Instalación local (Node)
- Configuración
- Ejemplos de uso
- Nota técnica
- Seguridad
🧰 Tools
| Tool | Fuente | Qué da |
|---|---|---|
odoo_sh_overview |
Web API | Repos + branches con stage (production/staging/dev) y último build |
odoo_sh_list_builds |
Web API | Builds recientes con status real (success/failed/testing) |
odoo_sh_model_fields |
Web API | Introspección de campos de modelos paas.* |
odoo_sh_search_read |
Web API | Query genérica read-only (whitelist paas.*) |
odoo_sh_logs |
SSH | tail de odoo.log / install.log / pip.log (+ filtro) |
odoo_sh_system_info |
SSH | Hostname, uptime, disco, memoria, versiones |
odoo_sh_databases |
SSH | DBs PostgreSQL y tamaños |
odoo_sh_status |
— | Diagnóstico de configuración (sin exponer secretos) |
🐳 Instalación via imagen GHCR (recomendado)
Cada push a main publica una imagen multi-arch (amd64/arm64) en GitHub Container Registry:
ghcr.io/ai-zar/odoo-sh-readonly-mcp:latest
1. Autenticarse contra GHCR
El repo es privado, así que la imagen también. Necesitás un PAT con scope read:packages:
echo $GITHUB_PAT | docker login ghcr.io -u TU_USUARIO --password-stdin
docker pull ghcr.io/ai-zar/odoo-sh-readonly-mcp:latest
2. Configurar el cliente MCP
Solo builds/entornos (sin SSH):
{
"mcpServers": {
"odoo-sh": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "ODOO_SH_SESSION_ID",
"-e", "ODOO_SH_PROJECT",
"ghcr.io/ai-zar/odoo-sh-readonly-mcp:latest"
],
"env": {
"ODOO_SH_SESSION_ID": "tu_session_id",
"ODOO_SH_PROJECT": "mi-proyecto"
}
}
}
}
Con SSH (logs / system / DBs) — montá la clave privada read-only:
{
"mcpServers": {
"odoo-sh": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/home/usuario/.ssh/odoo_sh:/keys/id:ro",
"-e", "ODOO_SH_SESSION_ID",
"-e", "ODOO_SH_SSH_HOST",
"-e", "ODOO_SH_SSH_USER",
"-e", "ODOO_SH_SSH_KEY_PATH",
"ghcr.io/ai-zar/odoo-sh-readonly-mcp:latest"
],
"env": {
"ODOO_SH_SESSION_ID": "tu_session_id",
"ODOO_SH_SSH_HOST": "mi-proyecto.dev.odoo.com",
"ODOO_SH_SSH_USER": "BUILD_ID",
"ODOO_SH_SSH_KEY_PATH": "/keys/id"
}
}
}
}
⚠️ En Windows usá rutas estilo
C:\\Users\\usuario\\.ssh\\odoo_sh:/keys/id:roen el-v.ODOO_SH_SSH_KEY_PATHsiempre apunta a la ruta dentro del contenedor (/keys/id).
3. Probar la imagen a mano
docker run -i --rm -e ODOO_SH_SESSION_ID=xxx \
ghcr.io/ai-zar/odoo-sh-readonly-mcp:latest
Pegá esto en stdin para ver las tools:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"cli","version":"1"}}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
💻 Instalación local (Node)
git clone https://github.com/ai-zar/odoo-sh-readonly-mcp.git
cd odoo-sh-readonly-mcp
npm install
npm run smoke # verifica que arranca y expone las 8 tools
{
"mcpServers": {
"odoo-sh": {
"command": "node",
"args": ["C:\\ruta\\absoluta\\odoo-sh-readonly-mcp\\index.js"],
"env": { "ODOO_SH_SESSION_ID": "tu_session_id" }
}
}
}
⚙️ Configuración
| Variable | Requerida | Descripción |
|---|---|---|
ODOO_SH_SESSION_ID |
✅ (web) | Cookie session_id de www.odoo.sh |
ODOO_SH_PROJECT |
❌ | Repo por defecto para filtrar |
ODOO_SH_BASE_URL |
❌ | Default https://www.odoo.sh |
ODOO_SH_SSH_HOST |
✅ (ssh) | <proyecto>.dev.odoo.com |
ODOO_SH_SSH_USER |
✅ (ssh) | BUILD_ID o nombre de branch |
ODOO_SH_SSH_KEY_PATH |
✅ (ssh) | Ruta a la clave privada |
ODOO_SH_SSH_PORT |
❌ | Default 22 |
ODOO_SH_SSH_TIMEOUT_MS |
❌ | Default 30000 |
🍪 Obtener la cookie de sesión
Odoo.sh no expone API pública; su panel web es un Odoo estándar. Se usa tu propia sesión:
- Logueate en https://www.odoo.sh
- F12 → Application → Cookies →
www.odoo.sh→ copiásession_id
La cookie expira: cuando las llamadas fallen con error de sesión, repetí el paso. Los permisos son exactamente los de tu usuario — ni más ni menos.
💬 Ejemplos de uso con AI
- "¿Cómo están los builds de staging?"
- "¿Falló algún build esta semana en main?"
- "Mostrame los últimos errores del log de producción"
- "¿Cuánto pesa la DB de producción?"
- "Listame todos los entornos y en qué commit está cada uno"
🔬 Nota técnica: modelos paas.*
Los modelos internos de Odoo.sh (paas.build, paas.branch, ...) no están documentados y sus campos pueden cambiar. Por eso:
resilientSearchRead: si un campo no existe, reintenta pidiendo todos los campos legiblesodoo_sh_model_fields: la AI puede autodescubrir el schema y después consultar con precisión viaodoo_sh_search_read
Primera vez, pedile a la AI:
"Usá
odoo_sh_model_fieldssobrepaas.buildy después listá los builds con los campos correctos"
🛡️ Seguridad
| Riesgo | Mitigación |
|---|---|
| Command injection | SSH via execFile (argv, sin shell). Comandos remotos son templates fijos; solo enteros validados y un filtro con whitelist de caracteres se interpolan |
| Escritura accidental | No existen tools de escritura. Whitelist de modelos + de métodos (search_read, read, search_count, fields_get, name_search) |
| Prompt injection → acción destructiva | Superficie de ataque = solo lectura. Lo peor que puede pasar es leer datos a los que ya tenés acceso |
| MITM en SSH | StrictHostKeyChecking=accept-new (TOFU) en vez de no |
| Secretos en la imagen | Nada hardcodeado; todo por env vars. Clave SSH se monta read-only en runtime |
| Supply chain | Imagen con attestation de provenance (actions/attest-build-provenance) firmada por GitHub |
MIT — ver LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.