Skip to main content
Glama
hallzyx

zero-slop-mcp-server

by hallzyx
README.md
# zero-slop-mcp-server

MCP remoto con **una tool**: `zero_slop_submit_assessment`. Recibe el análisis del harness (Claude Code), valida, calcula `total` y lo guarda en Convex `assessments` vía `evaluations.save`.

Clerk es solo la web. Esta tool se autentica con Bearer → `sha256` → `mcpTokens`. Nunca `getUserIdentity()`.

`githubUsername` es el evaluado (él mismo, o un senior). Si el senior evalúa a alguien sin fila, Convex puede crear el `developer` — la cuenta Clerk se vincula después en el onboarding.

## Setup

1. Copia `convex-dropin/mcp.ts` → `convex/mcp.ts` y `convex-dropin/evaluations.ts` → `convex/evaluations.ts`. Despliega Convex.
2. Al emitir tokens (en la web), guarda `sha256(plaintext)` en `mcpTokens.tokenHash`. No borres filas: usá `revokedAt`.
3. Copia el skill `skills/zero-slop-assessment/` al harness de Claude Code.
4. Configura env y arranca:

```bash
cp .env.example .env
npm install
npm run dev
```

- MCP: `http://127.0.0.1:3000/mcp` (Bearer obligatorio)
- Health: `http://127.0.0.1:3000/health` (sin auth)

## Cliente (Claude Code / Cursor)

```json
{
  "mcpServers": {
    "zero-slop": {
      "url": "http://127.0.0.1:3000/mcp",
      "headers": {
        "Authorization": "Bearer DEVELOPER_MCP_TOKEN"
      }
    }
  }
}
```

El LLM puntúa con el skill (`references/rubric.md`) y llama la tool. **No envía `scores.total`**: `avg(decisionUnderstanding, riskDetection)`, un decimal. `explanationQuality` se guarda y tiene feedback, no entra en el total. Cada llamada **inserta** (historial).

Sin el `skillId` correcto la tool rechaza. El agente debe buscar el skill en **dos sitios**: skills instaladas del harness, y este repo (`skills/zero-slop-assessment/SKILL.md`). Con uno alcanza. El MCP remoto no ve el disco; si no está en ninguno, te lo tiene que pedir.

## Producción (Dokploy)

Dokploy ya trae Traefik + Let's Encrypt. No uses Caddy ni publiques 80/443 en el compose.

Lo más simple: una **Application** que construye el `Dockerfile`.

1. DNS A/AAAA de `mcp.tudominio.com` al VPS de Dokploy.
2. Nueva aplicación → Git o Compose. Si es Compose, el archivo es `compose.yml` (servicio `mcp`). Compose path en Dokploy: `./compose.yml`.
3. Environment:
   - `HOST=0.0.0.0`
   - `PORT=3000`
   - `CONVEX_URL=https://….convex.cloud`
   - `ALLOWED_HOSTS=mcp.tudominio.com` (Host header; Compose also accepts `MCP_DOMAIN`)
4. Domains: host `mcp.tudominio.com`, servicio `mcp`, puerto interno **3000**, certificado Let's Encrypt.
5. Health path: `/health` (sin Bearer; ábrelo en el navegador para comprobar Traefik). MCP: `https://mcp.tudominio.com/mcp` (POST + Bearer; GET en el browser no es una página).

```json
{
  "mcpServers": {
    "zero-slop": {
      "url": "https://mcp.tudominio.com/mcp",
      "headers": {
        "Authorization": "Bearer DEVELOPER_MCP_TOKEN"
      }
    }
  }
}
```

Local sigue siendo `npm run dev`.