# Conectá tu app a cliply

> Permití que los entrenadores autoricen tu app a leer sus datos de cliply por MCP y OAuth 2.1.

Source: https://cliply.video/developers/connect-your-app
Updated: 2026-11-04

Tu app puede leer los datos de cliply de un entrenador igual que Claude y ChatGPT: por el servidor MCP de cliply, con la autorización del propio entrenador. No necesitás una API key nuestra ni pedirnos que te registremos. Tu app se registra sola, el entrenador la aprueba y llamás a las tools con el token que recibís.

Tu app recibe datos en JSON: partidos, tags, hechos, estadísticas, secuencias, jugadores e ids de clips. Nunca recibe video. El video se reproduce en cliply, y cada id de clip se convierte en un link que abre el workbench de cliply en esa jugada.

## De un vistazo

| Qué | Valor |
| --- | --- |
| Servidor MCP | `https://cliply.video/api/mcp` (Streamable HTTP, sin estado) |
| Metadata del servidor de autorización | `https://cliply.video/.well-known/oauth-authorization-server/api/auth` |
| Metadata del recurso protegido | `https://cliply.video/.well-known/oauth-protected-resource/api/mcp` |
| Registro de clientes | `POST https://cliply.video/api/auth/oauth2/register` (abierto, RFC 7591) |
| Autorización | `https://cliply.video/api/auth/oauth2/authorize` |
| Token | `https://cliply.video/api/auth/oauth2/token` |
| Revocación | `https://cliply.video/api/auth/oauth2/revoke` |
| Grants | `authorization_code`, `refresh_token` |
| PKCE | obligatorio, `S256` |
| Scopes | `cliply:read`, `cliply:write` (opcional), `offline_access` |

## Inicio rápido con el SDK de MCP

Los SDKs oficiales de MCP traen un cliente que descubre los endpoints, registra tu app y resuelve el flujo OAuth. En TypeScript (`@modelcontextprotocol/sdk`):

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

// authProvider implements OAuthClientProvider: it stores the client
// registration, the PKCE verifier and the tokens per coach, and redirects
// the coach's browser to the authorize URL.
const transport = new StreamableHTTPClientTransport(
  new URL("https://cliply.video/api/mcp"),
  { authProvider },
);
const client = new Client({ name: "your-app", version: "1.0.0" });
await client.connect(transport);

const { tools } = await client.listTools();
const result = await client.callTool({
  name: "list_matches",
  arguments: {},
});
```

De tu lado queda: un botón **Conectar cliply**, una ruta de callback, guardar los tokens de cada entrenador y el provider de arriba. El resto de esta página explica lo que hace el SDK, para los equipos que arman el flujo a mano.

## El flujo OAuth, paso a paso

### 1. Descubrir

`GET https://cliply.video/.well-known/oauth-protected-resource/api/mcp` nombra al servidor de autorización, y su documento de metadata lista todos los endpoints de la tabla de arriba. Un `401` de `/api/mcp` trae el mismo puntero en el header `WWW-Authenticate`.

### 2. Registrar tu app (una vez)

```http
POST https://cliply.video/api/auth/oauth2/register
Content-Type: application/json

{
  "client_name": "Your App",
  "redirect_uris": ["https://yourapp.example/cliply/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}
```

Guardá el `client_id` que recibís y usá el mismo para todos los entrenadores. No te registres de nuevo por cada uno. El registro tiene límite de frecuencia.

### 3. Mandar al entrenador a cliply

Cuando el entrenador elige **Conectar cliply**, redirigí su browser a:

```text
https://cliply.video/api/auth/oauth2/authorize
  ?response_type=code
  &client_id=<client_id>
  &redirect_uri=https://yourapp.example/cliply/callback
  &scope=cliply:read cliply:write offline_access
  &code_challenge=<S256 challenge>
  &code_challenge_method=S256
  &state=<random>
  &resource=https://cliply.video/api/mcp
```

De este paso se encarga cliply. El entrenador inicia sesión (o crea una cuenta y una organización), elige la organización que va a leer la conexión y aprueba.

### 4. Canjear el código

cliply vuelve a tu `redirect_uri` con `code` y tu `state`. Comprobá que `state` coincida con el que mandaste y canjeá el código:

```http
POST https://cliply.video/api/auth/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=<code>
&redirect_uri=https://yourapp.example/cliply/callback
&client_id=<client_id>
&code_verifier=<PKCE verifier>
&resource=https://cliply.video/api/mcp
```

La respuesta trae un `access_token` y, si pediste `offline_access`, un `refresh_token`. Guardá los dos asociados al entrenador.

### 5. Renovar

Cuando vence el access token, pedí uno nuevo con `grant_type=refresh_token`, tu `client_id` y el refresh token. El entrenador no ve este paso. Guardá el refresh token que devuelve la respuesta: puede ser distinto del que mandaste.

## Scopes y qué aprueba el entrenador

- **`cliply:read`**: lee todo lo que el entrenador ve en la organización que eligió.
- **`cliply:write`**: opcional. Permite crear colecciones y presentaciones y comentar clips. Nunca edita ni borra nada. La pantalla de autorización lo muestra como un casillero que el entrenador puede desmarcar. Si lo desmarca, el token queda en solo lectura y las tools de creación no aparecen.
- **`offline_access`**: emite un refresh token.

Cada token queda atado a **un entrenador y una organización**. Ve lo que ese entrenador ve ahí (los proyectos privados, solo si el entrenador puede abrirlos) y nunca usa otra membresía. Las cuentas de jugador no pueden autorizar. Para leer otra organización, el entrenador vuelve a conectar y la elige.

La pantalla de autorización muestra el `client_name` que registraste junto al host de tu `redirect_uri`. Registrá un nombre que los entrenadores reconozcan.

## Llamar a las tools

Cada llamada es un pedido JSON-RPC a `/api/mcp` con el token del entrenador:

```http
POST https://cliply.video/api/mcp
Authorization: Bearer <access_token>
Content-Type: application/json
Accept: application/json, text/event-stream

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"match_analysis","arguments":{"matchId":"<id>"}}}
```

El servidor no guarda estado, así que no necesitás session id. Un token revocado se rechaza en el pedido siguiente. Llamá a `tools/list` para ver el esquema actualizado de cada tool; ahí cada una trae también su input.

| Tool | Qué lee |
| --- | --- |
| `whoami` | El entrenador, la organización, su deporte y qué funciones tiene |
| `list_projects`, `list_matches` | Por dónde empezar: proyectos y partidos con sus urls |
| `match_analysis` | Un partido como hechos con F-ids, un mapa `tagMeaning` (de quién es cada acción, si es buena o mala para el equipo y su opuesta) y una línea base de partidos comparables |
| `match_report` | El informe de IA guardado de un partido, si la organización lo generó |
| `find_clips` | Clips por partido, tag, jugador o período |
| `find_sequences` | Una acción seguida de otra dentro de una ventana de tiempo, por ejemplo una recuperación que termina en entrada al área |
| `compare_matches` | Hasta 8 partidos lado a lado |
| `cliply_read` | Todo lo demás por nombre: jugadores, estadísticas de jugador, equipos, estadísticas de temporada como `team_tag_season`, eventos, alineaciones, GPS, comentarios, colecciones, vistas de links, calendario, actividad |
| `cliply_describe` | El input exacto de un nombre de `cliply_read` |
| `search`, `fetch` | Buscar entre partidos, jugadores, equipos y artículos de ayuda, y traer uno por id |
| `cliply_help_search`, `cliply_help_article`, `cliply_whats_new` | Este centro de ayuda y las notas de versión |
| `create_collection`, `create_presentation`, `comment_clip` | Solo con tokens `cliply:write` |

Algunas lecturas dependen de funciones que la organización tenga activadas, como GPS, estadísticas del banco o estadísticas de temporada. Si una está apagada, la tool lo dice en vez de devolver datos.

## Links y citas

- Los tiempos son segundos desde el inicio del video.
- Un partido se linkea con su `url`. Una jugada, con la url del partido más `?clip=<clipId>`; cualquier id de clip de cualquier lectura funciona ahí.
- Los hechos de `match_analysis` traen ids (`F1`, `F2`…). Citalos para que el entrenador pueda rastrear cada afirmación hasta el partido.
- Los links abren el workbench de cliply y piden que el entrenador tenga sesión iniciada en cliply. Para mostrarles clips a los jugadores, creá una colección con `cliply:write` y el entrenador la comparte desde cliply.
- Tu modelo lee tags, no video. Las respuestas son tan completas como el etiquetado del entrenador.

## Límites, créditos y errores

- **Límites de frecuencia:** 120 pedidos por minuto por entrenador y 300 por minuto por IP. Si te pasás, `/api/mcp` responde `429` con `Retry-After: 60`.
- **Créditos:** las lecturas por el conector no consumen créditos de cliply.
- **`401`:** falta el token, venció o fue revocado. Renovalo, o mandá al entrenador a hacer el flujo de nuevo.
- **Errores de una tool:** vuelven como un resultado normal con `isError: true` y un mensaje que tu modelo puede leer.

## Desconectar

Un entrenador desconecta tu app en cliply desde **Cuenta → Sesiones → Apps de IA**. Los propietarios y admins de la organización pueden desconectar la app de cualquier miembro desde **Configuración de la organización → General → Apps de IA**, y el registro de auditoría de la organización anota cada conexión. Tu app también puede revocar sus propios tokens en el endpoint de revocación. En todos los casos, la siguiente llamada con ese token recibe un `401`.

Para consultas, escribinos a hi@cliply.video.
