# auth.md · Acceso para agentes de ismaelbriasco.com

Este sitio expone su contenido público a agentes de IA por MCP. El acceso es
abierto: cualquier agente puede registrarse solo y empezar a usarlo, sin que
haya nadie del otro lado aprobando altas.

- Servidor MCP: `POST https://ismaelbriasco.com/mcp` (transporte Streamable HTTP)
- Authorization server: `https://ismaelbriasco.com`
- Metadata: [`/.well-known/oauth-authorization-server`](https://ismaelbriasco.com/.well-known/oauth-authorization-server)
- Recurso protegido: [`/.well-known/oauth-protected-resource`](https://ismaelbriasco.com/.well-known/oauth-protected-resource)
- Estado del servicio: [`/mcp/status`](https://ismaelbriasco.com/mcp/status)

## Qué hay adentro

Tres herramientas sobre el contenido público del sitio:

| Herramienta          | Qué hace                                                      |
| -------------------- | ------------------------------------------------------------- |
| `listar_paginas`     | Devuelve el índice de páginas con ruta, título y descripción. |
| `buscar_en_el_sitio` | Busca un texto en todas las páginas y devuelve extractos.     |
| `leer_pagina`        | Devuelve una página completa en Markdown.                     |

Y un recurso: [`llms.txt`](https://ismaelbriasco.com/llms.txt), el panorama del
sitio en una sola lectura.

## Qué NO hay

Conviene decirlo antes de que alguien lo busque. Aquí no se llega a datos de
alumnos, compras, correos, licencias ni a nada de la Academia. Esa API es otra,
usa otro sistema de identidad y no se abre a agentes. El alcance `mcp:read` es
el único que existe, y cubre exactamente lo que ya es público en el sitio.

## El flujo, de punta a punta

Cuatro pasos. El camino corto, y el que conviene por defecto, es
`client_credentials`: no hay un usuario cuyos permisos delegar, así que no hay
motivo para pasar por un navegador.

### 1. Discover

Todo arranca en la metadata del authorization server, que declara los endpoints
y un bloque `agent_auth` con esto mismo en JSON:

```bash
curl -s https://ismaelbriasco.com/.well-known/oauth-authorization-server
```

Si llegaste por un 401 del MCP, la cabecera `WWW-Authenticate` te trae el
`resource_metadata` que apunta a
[`/.well-known/oauth-protected-resource/mcp`](https://ismaelbriasco.com/.well-known/oauth-protected-resource/mcp).

### 2. Register (RFC 7591)

```bash
curl -sX POST https://ismaelbriasco.com/oauth/register \
  -H 'content-type: application/json' \
  -d '{"client_name":"Mi agente"}'
```

Devuelve `client_id` y `client_secret`. Guárdalos: el secreto no se vuelve a
mostrar y no vence. Hay un tope de 20 altas por hora por IP.

### 3. Exchange: pedir un token

```bash
curl -sX POST https://ismaelbriasco.com/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=TU_CLIENT_ID \
  -d client_secret=TU_CLIENT_SECRET
```

Devuelve un `access_token` (JWT ES256) que vive una hora. No hay refresh
tokens: cuando vence, se pide otro con las mismas credenciales.

### 4. Use

```bash
curl -sX POST https://ismaelbriasco.com/mcp \
  -H "authorization: Bearer TU_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

## Claim y Revoke: qué no hay, y por qué

La especificación Auth.md contempla dos pasos más que aquí no existen, y
conviene decirlo en vez de dejarte buscándolos.

El tipo de identidad es **anónimo**: el alta no te pide que pruebes nada.
Envías un nombre, recibes credenciales y trabajas.

**Claim** no existe. En la especificación es el endpoint donde alguien reclama
una identidad anónima y la ata a una persona real. Montarlo aquí significaría
verificar correos y guardar quién está detrás de cada agente, o sea crear datos
personales donde hoy no hay ninguno, para un servicio que solo sirve contenido
que ya es público. Se decidió no hacerlo.

**Revoke** existe, pero es de este lado y no tiene feed. Si un `client_id`
abusa, se revoca; el agente se entera porque su token deja de validar. No hay
`events_endpoint` al que suscribirse.

## Con navegador (authorization_code + PKCE)

Los clientes MCP de escritorio suelen preferir este camino. Está implementado
completo: `response_type=code`, `code_challenge_method=S256` obligatorio, y las
`redirect_uris` tienen que declararse en el alta (solo `https`, salvo
`localhost`). Aparece una pantalla que explica qué se está autorizando y con un
clic devuelve el código.

## Verificar un token sin preguntarnos

Las claves públicas están en [`/oauth/jwks.json`](https://ismaelbriasco.com/oauth/jwks.json).
Un token válido trae `iss: https://ismaelbriasco.com`,
`aud: https://ismaelbriasco.com/mcp` y `scope: mcp:read`.

## Límites y buenos modales

- Un `User-Agent` que identifique al agente ayuda cuando algo se rompe.
- El contenido se cachea diez minutos: no tiene sentido reintentar más seguido.
- Si abusas, se revoca el `client_id`, no el endpoint. Registrarse de nuevo con
  el mismo comportamiento no cambia el resultado.

## Preferencias de uso del contenido

El `robots.txt` declara Content Signals: `search=yes`, `ai-input=yes`,
`ai-train=no`. En castellano: usa este contenido para responder a alguien y
cita la fuente; no lo uses para entrenar un modelo.

## Contacto humano

Algo roto, un caso de uso que no encaja o ganas de hacer algo juntos:
[hola@ismaelbriasco.com](mailto:hola@ismaelbriasco.com).
