admin-mcp
by aprezcuba24
README.md
# admin-mcp
Servidor [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) en Python para operaciones de administración Odoo. Scaffold arquitectónico basado en [ApkMCP](../ApkMCP), con **FastMCP** y transporte **Streamable HTTP**.
Incluye búsqueda de clientes conectada: **service → resource → tool**.
## Requisitos
- Python 3.11+
- Para desarrollo con [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector): Node.js **22.7.5+** y **pnpm**
## Instalación
```bash
cd AdminMCP
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[lambda]"
```
Con [uv](https://docs.astral.sh/uv/):
```bash
uv sync --all-extras
```
## Configuración
Copia `.env.example` a `.env`:
| Variable | Descripción | Default |
|----------|-------------|---------|
| `ADMIN_API_TIMEOUT` | Timeout HTTP en segundos | `30` |
| `MCP_HOST` / `MCP_PORT` / `MCP_PATH` | Bind y ruta MCP | `0.0.0.0:8001/mcp` |
### Autenticación (`auth-key`)
Cada petición HTTP al endpoint MCP debe incluir la cabecera **`auth-key`**: `Bearer` + `base64(BASE_URL|API_KEY[|database])`.
- `BASE_URL`: URL HTTPS del servidor Odoo (sin barra final), p. ej. `https://mi-empresa.onrender.com`
- `API_KEY`: clave API de un usuario bot de Odoo (scope rpc)
- `database` (opcional): nombre de la base de datos cuando el servidor tiene varias (`X-Odoo-Database`)
Generar el valor en local:
```bash
# Sin base de datos explícita
pnpm auth-key -- https://mi-empresa.onrender.com|99031c76-d288-41ea-866b-ef656f58e497
# Con base de datos (multi-DB)
pnpm auth-key -- https://mi-empresa.onrender.com|99031c76-d288-41ea-866b-ef656f58e497|mi_db
```
El servidor decodifica URL, API key y database opcional, y prepara el cliente httpx para llamadas JSON-2 a Odoo (`POST /json/2/{modelo}/{metodo}`).
## Ejecución
```bash
python -m app
# o
admin-mcp
```
Desarrollo con Inspector:
```bash
pnpm install
pnpm dev
```
Inspector usa `dev/mcp-inspector.config.json` (puerto **8001**, distinto de ApkMCP en 8000). Configura el header `auth-key` en el Inspector antes de invocar tools/resources.
## Flujo de pedido (ChatGPT)
Formato abreviado: `Pepe, arroz 2, aceite` (cliente + productos; sin cantidad → 1 unidad).
| Paso | Acción |
|------|--------|
| 1 | Usuario indica cliente y productos |
| 2 | Asistente resuelve cliente, crea carrito, añade productos, muestra carrito |
| 3 | Usuario puede añadir más productos |
| 4 | Asistente muestra carrito actualizado |
| 5 | Usuario confirma → `create_order` |
Desambiguación: si hay varios clientes o productos, se listan todos con **id** y el usuario elige por id.
Búsqueda de productos por nombre: `add_to_cart(product_search="arroz", quantity=2)` — no requiere conocer el `product_id` de antemano.
ChatGPT impone un límite de ~5000 tokens en el schema total de tools; las descripciones se mantienen breves para que el conector importe todas las tools (incluido catálogo).
## Verificar versión en ChatGPT
Tras un despliegue, el usuario puede comprobar qué build está respondiendo:
- Preguntar: *"¿Qué versión de AdminMCP tienes?"*
- El asistente invoca `read_server_info` y responde con `version`, `build_id`, `instructions_revision`, tools y prompts.
Cada respuesta de cualquier tool incluye `_server.version` y `_server.build_id`.
## Superficie MCP
| Tipo | Nombre | Descripción |
|------|--------|-------------|
| Tool | `read_customers` | Busca clientes por nombre/teléfono |
| Tool | `read_catalog_products` | Busca productos por nombre |
| Tool | `read_catalog_product` | Detalle de producto por id |
| Tool | `read_catalog_categories` | Lista categorías |
| Tool | `create_cart` | Crea carrito para un cliente |
| Tool | `add_to_cart` | Añade producto (`product_search` o `product_id`) |
| Tool | `get_cart` | Consulta carrito actual |
| Tool | `clear_cart` | Vacía carrito |
| Tool | `create_order` | Confirma pedido en Odoo |
| Tool | `read_server_info` | Versión y tools desplegadas |
| Resource | `app://customers` | Listado/búsqueda de clientes |
| Resource | `app://catalog/products` | Catálogo de productos |
| Prompt | `find_client_assistant` | Flujo de búsqueda de clientes |
| Prompt | `sales_order_assistant` | Flujo de carrito y pedidos |
## Arquitectura
```
app/
├── server/ # FastMCP, lifespan, middleware auth-key, DI, instructions
├── clients/ # OdooJson2Client (JSON-2 API oficial)
├── services/ # Lógica reutilizable (sin decoradores MCP)
├── resources/ # @mcp.resource app://...
├── tools/ # @mcp.tool acciones
│ └── tool_resources/ # read_* espejo de resources
├── prompts/ # @mcp.prompt
├── utils/ # app_key_codec, excepciones
└── cli/ # admin-mcp-auth-key
```
Registro por imports con efecto lateral en `app/server/__init__.py`.
Flujo de búsqueda de clientes:
1. `AppKeyMiddleware` decodifica `auth-key` → `AppContext`
2. Resource `app://customers` o tool `read_customers` → `services/customers.py`
### Cómo extender
1. Añadir función en `app/services/<dominio>.py`
2. Exponer `@mcp.resource` en `app/resources/<dominio>.py`
3. Espejo `read_*` en `app/tools/tool_resources/<dominio>.py`
4. Tools de acción en `app/tools/<dominio>.py`
5. Registrar módulos en los `__init__.py` correspondientes
6. Actualizar `app/server/instructions.py`
## Configuración Cursor MCP
```json
{
"mcpServers": {
"admin-mcp": {
"url": "http://127.0.0.1:8001/mcp",
"headers": {
"auth-key": "Bearer <base64(BASE_URL|API_KEY[|database])>"
}
}
}
}
```
## Tests
```bash
pnpm test
# o
pytest
```
## Despliegue (AWS Lambda)
```bash
pnpm deploy
```
Requiere credenciales AWS y `SERVERLESS_ACCESS_KEY`. El workflow `.github/workflows/main.yml` despliega en push a `main`.
## Relación con ApkMCP
AdminMCP replica la arquitectura de ApkMCP (capas, auth-key, Lambda, Inspector) con operaciones admin: clientes, catálogo, carrito y pedidos confirmados.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues