Metadata-Version: 2.4
Name: synthelium-sdk
Version: 2.5.0
Summary: SDK oficial de Aletheox + servidor MCP — gobernanza verificable de agentes de IA.
Author-email: Aletheox <directiva@aletheox.com>
License: Proprietary — Todos los derechos reservados
Project-URL: Homepage, https://api.aletheox.com
Project-URL: Documentation, https://api.aletheox.com/guide
Keywords: ai,safety,compliance,risk,governance,adversarial,mcp
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: License :: Other/Proprietary License
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27.0
Provides-Extra: mcp
Requires-Dist: mcp>=2.0.0; extra == "mcp"

# Aletheox SDK + MCP

Las **interfaces de distribución** del Core de Aletheox (motor determinista de
gobernanza para IA), extraídas del monorepo a un repo propio. Todas hablan con el
mismo Core API (`api.aletheox.com`) por HTTP; **ninguna contiene lógica de
validación ni embebe el motor** — solo transporte y serialización.

> Este repo **no** incluye el núcleo (`core/`) ni el evaluador del servidor: son
> secreto industrial y viven solo en el servidor. Aquí está lo que va del lado
> del cliente, que es seguro publicar.

## Tres vías de consumo (misma fuente de verdad)

| Vía | Para quién | Cómo |
|-----|-----------|------|
| **SDK Python** | Ingenieros (integración en backend) | `pip install .` |
| **MCP Python** | Devs que operan desde Claude Desktop | `pip install '.[mcp]'` |
| **MCP `.mcpb` (un clic)** | No-devs / clientes | doble clic al bundle, sin instalar nada |

## Contenido

```
synthelium_sdk/     SDK Python (HTTP puro), publicado en PyPI
adapters/
  contracts/        Interfaz Única — EnginePort (Protocol) + tipos + HttpEngine
  mcp_server/       Servidor MCP en Python (usa el SDK por dentro)
  tests/            Contrato + construcción del servidor con motor inyectado
mcp_ts/             Servidor MCP en TypeScript → bundle .mcpb de UN CLIC
```

La arquitectura completa (por qué el SSOT es el Core API y no un objeto en
proceso, el diagrama de inyección de dependencias, etc.) está en
[`adapters/README.md`](adapters/README.md). Pasos de instalación en
[`INSTALL.md`](INSTALL.md).

## SDK nativo en 2 líneas

```python
from synthelium_sdk import SyntheliumClient, Agent
client = SyntheliumClient(api_key="sk-synthelium-...")
report = client.run_evaluation(Agent(mi_llm), sector="banking")
```

## Crear y actualizar un proceso

Declara la intención. El servidor la hace cumplir.

```python
client.builder.create(proceso)    # NUEVO      · si el id ya existe -> 409 «ya_existe»
client.builder.update(proceso)    # EXISTENTE  · si el id no existe -> 404
client.builder.create_from_text("1. Recibir\n2. Aprobar")
```

**Por qué importa.** Hasta 2.4.0 solo existía `builder.build()`, que no mandaba intención:
el servidor creaba si el id no estaba y **sobrescribía** si estaba. Sobre un id determinista
—dos pestañas, dos procesos, un reintento— lo que ibas a crear pisaba en silencio lo que el
otro acababa de declarar. Con `create()` la colisión se ve; no se pierde nada.

### Legado

```python
client.builder.upsert(proceso)    # crear-o-actualizar, DECLARADO a propósito
```

`upsert()` es para el único caso en que eso es lo que quieres: un guion de alta idempotente,
con un id fijo y un solo escritor. No es el camino recomendado.

`builder.build()` y `builder.build_from_text()` están **DEPRECADAS** desde 2.5.0. Siguen
funcionando exactamente igual que hasta 2.4.0 —no se rompe nada— y avisan con
`DeprecationWarning`. Las dos son equivalentes a `upsert()` sin decirlo.

## MCP — dos formas

**Un clic (no-devs)** → bundle `.mcpb`: doble clic en Claude Desktop, pega la API
key en el formulario, listo. No requiere Python ni Node. Ver
[`mcp_ts/README.md`](mcp_ts/README.md).

```bash
cd mcp_ts && npm install && npm run pack   # genera aletheox.mcpb (lo hacemos nosotros)
```

**Desde código (devs)** → servidor Python en un venv aparte:

```bash
python -m venv .venv-mcp && . .venv-mcp/Scripts/activate
pip install '.[mcp]'
ALETHEOX_API_KEY=sk-synthelium-... python -m adapters.mcp_server.server
# o, tras instalar:  aletheox-mcp
```

> ⚠️ El SDK de MCP en Python arrastra un `starlette` nuevo que puede chocar con
> `fastapi` en entornos que lo tengan; por eso va en su propio venv. La vía
> `.mcpb` no tiene ese problema (Node embebido, dependencias empaquetadas).
> Detalle en [`adapters/mcp_server/README.md`](adapters/mcp_server/README.md).

## Cuando hace falta una decisión humana

Si el veredicto trae `requires_human: true`, **no ejecutes la acción** y **conserva el
`cert_id`**: identifica esa decisión concreta, no la acción en general.

Cuando una persona la autorice, vuelve a evaluar **la misma acción**:

```python
v = cli.gate("ses-1", "aplicar_descuento", process_id=pid, payload=datos)
if v["requires_human"]:
    guardar(v["cert_id"])          # detente aquí; no ejecutes
    ...                            # una persona decide en Aletheox
    v = cli.gate("ses-1", "aplicar_descuento", process_id=pid,
                 payload=datos,    # el MISMO payload
                 cert_id=guardado) # la autorización que te dieron
if v["proceed"]:
    hacer_el_trabajo()             # ejecutar sigue siendo tuyo
```

Cuatro cosas que conviene tener claras:

- **Sirve una sola vez.** Una autorización consumida no vale para un segundo intento.
- **Mismo payload.** Mismos campos y mismos valores; el orden de las claves del JSON da
  igual, el contenido no. Conserva el original en vez de reconstruirlo.
- **Si cambian los datos, es otra decisión.** Vuelve sin `cert_id` y se evaluará de cero.
- **`proceed: true` no dice que ocurriera.** Dice que Aletheox te deja continuar. Aletheox
  no reanuda ni ejecuta nada por su cuenta: el efecto es tuyo.

Si la persona **no** autoriza, la acción no se ejecuta. Volver a intentar lo mismo no es un
reintento automático: sería pedir otra decisión.

## Tests

```bash
# Python (contrato + server MCP con motor inyectado)
pip install pytest && pip install '.[mcp]'
pytest adapters/tests -q

# TypeScript (cliente MCP <-> server con motor falso, sin red)
cd mcp_ts && npm install && npm test
```

## Licencia

Propietario — Todos los derechos reservados. Aletheox.
