PatchFirst / Desarrollo
API y MCP
Lee los hallazgos de tus servidores de pago, prepara una cola de parches y solicita recálculos desde tus propias herramientas.
Un token por integración
Crea un token API personal en la sección de tokens del panel. Dale un nombre de hasta 64 caracteres, elige read o write (lectura y escritura) y una vigencia de 1 a 365 días. Confirma su creación introduciendo de nuevo la contraseña actual. Todos los tokens API se revocan tras cambiar o recuperar la contraseña. Cerrar sesión mantiene el acceso de CI y MCP. Para revocarlos todos, usa el botón independiente «Revocar todos los tokens» del panel, que muestra el motivo de revocación. Puedes tener hasta 50 tokens activos. Copia el secreto cuando aparezca: solo se muestra una vez. El servicio solo almacena un hash de verificación. Puedes listar, revocar y consultar el uso de los tokens desde el panel.
Usa HTTPS y envía el token solo en Authorization: Bearer …. Los tokens en URL se rechazan. Los ejemplos suponen que PATCHFIRST_API_TOKEN está definida en tu entorno; mantén el secreto fuera del control de versiones, capturas y registros. Las claves de lectura/escritura de flota y los tokens de agentes son credenciales independientes.
curl --fail-with-body "https://patchfirst.dev/v1/me/fleets" \
-H "Authorization: Bearer $PATCHFIRST_API_TOKEN"El token solo abarca las flotas del propietario. Una flota ajena devuelve 404, igual que una inexistente. Un token read no puede iniciar recálculos. El acceso del navegador desde otros orígenes está desactivado (CORS cerrado).
La API y MCP requieren monitorización de pago. Sin un pago válido, devuelven 402. Tras el vencimiento, el acceso al archivo solo incluye instantáneas guardadas de periodos pagados conforme a las reglas de facturación, sin datos nuevos. Los detalles de CVE requieren pago activo: de lo contrario, la API devuelve 402 y cve_details devuelve un error de pago en el resultado MCP; los datos actuales de KEV, EPSS, códigos de explotación, observaciones y menciones no están disponibles en modo archivo. Los nuevos cálculos requieren derecho vigente a monitorización, incluido el periodo de gracia aplicable; las plazas gratuitas por sí solas no dan acceso a la API.
Rutas de la API v1
URL base: https://patchfirst.dev. Sustituye {fleet} y {server} por los UUID que devuelven las rutas de listado. Todas las rutas siguientes usan un token Bearer personal.
| Método y ruta | Resultado |
|---|---|
GET /v1/me/fleets | Flotas propias: {"fleets":[{"id":"…","created_at":1792713600}]}. |
GET /v1/me/fleets/{fleet}/servers | Servidores de pago consultables: {"servers":[{"id":"…","name":"web-1","name_kind":"alias","updated_at":1792713600}]}. |
GET /v1/me/fleets/{fleet}/report | Puntuación de flota, recuentos P0–P3 e informes por servidor en assets. |
GET /v1/me/fleets/{fleet}/servers/{server}/report | Puntuación, hallazgos, CVE, versiones corregidas y recomendaciones del servidor. |
GET /v1/me/fleets/{fleet}/servers/{server}/history | {"history":[…]}: instantáneas de puntuación almacenadas. |
GET /v1/me/cves/{cve} | Registro CVE, KEV, EPSS, códigos de explotación y menciones en fuentes. ID de ejemplo: CVE-2026-12345. |
POST /v1/me/fleets/{fleet}/refresh | 202: recálculo aceptado. Requiere write y derecho a monitorización. Vuelve a leer el informe para obtener los resultados. |
curl --fail-with-body "https://patchfirst.dev/v1/me/fleets/11111111-1111-4111-8111-111111111111/report" \
-H "Authorization: Bearer $PATCHFIRST_API_TOKEN"
curl --fail-with-body -X POST "https://patchfirst.dev/v1/me/fleets/11111111-1111-4111-8111-111111111111/refresh" \
-H "Authorization: Bearer $PATCHFIRST_API_TOKEN"La gestión de tokens del panel utiliza la sesión del navegador, independiente del acceso Bearer: GET/POST /v1/account/api-tokens, DELETE /v1/account/api-tokens/{token_id} y GET /v1/account/api-tokens/{token_id}/usage. La creación acepta {"name":"acme integration","scope":"read","expires_in_days":30,"password":"CURRENT_PASSWORD"} y devuelve 201 con metadatos y el secreto token, mostrado una sola vez. Las escrituras de sesión exigen comprobaciones de solicitudes del mismo origen.
Contrato de respuestas y nombres
El documento OpenAPI define los esquemas JSON v1. Los campos existentes conservan su significado y sus tipos; los clientes deben aceptar campos adicionales. Las respuestas correctas son objetos JSON. Los listados usan matrices fleets, servers o history. Los metadatos de tokens, la creación de flotas, las actualizaciones de servidores y recorded_at del historial usan segundos Unix (UTC); computed_at de los informes usa una cadena de fecha y hora UTC o null.
Los campos score y grade dan la valoración principal de los componentes comprobados. global_score y global_grade dan la valoración global considerando el riesgo desconocido. coverage contiene los enteros checked (comprobados) y total (detectados). Estos campos figuran en informes de servidores y parques, listas de servidores e instantáneas del historial. La cobertura del parque solo suma servidores con valoración global disponible; su ponderación coincide con la principal. La letra ? indica que la valoración no está disponible. Las instantáneas antiguas pueden contener null para la valoración global.
Los campos complete, rating_complete, reasons y blind se conservan por compatibilidad y describen la cobertura. No determinan la valoración principal ni el veredicto. Cálculo de la valoración global y la cobertura →
Un informe de servidor contiene id, name, name_kind, score, grade, counts y findings. Cada hallazgo incluye priority (P0–P3), component, version instalada, fix, action recomendada y entradas CVE principales en top. fix puede estar vacío o ser null si no hay versión corregida; consulta unfixed, pro_only y action.
Los alias sin cifrar, como web-1, se devuelven con name_kind: "alias". Si los nombres están cifrados o sin definir, name_kind: "opaque" indica una etiqueta opaca. El servicio remoto no conoce los nombres cifrados y no puede descifrarlos. Nunca uses un dominio, IP, empresa o cliente como alias sin cifrar.
Errores, límites y uso
Los errores tienen la forma estable {"error":"Readable explanation","code":"machine_code"}. Usa el estado HTTP y code en la lógica del programa; la explicación puede cambiar.
| Estado | Significado |
|---|---|
| 400 | Entrada inválida, parámetros no admitidos o token en la URL. |
| 401 | Token ausente, inválido, caducado o revocado. |
| 402 | Se requiere monitorización de pago o una instantánea pagada consultable. |
| 403 | Permisos insuficientes u origen inválido; usa un token de escritura para recalcular. |
| 404 | Recurso inexistente o de otro propietario. |
| 405 | Método no admitido; MCP acepta POST. |
| 409 | Se ha alcanzado el límite de 50 tokens API personales activos. |
| 429 | Demasiadas solicitudes. Espera los segundos indicados en Retry-After antes de reintentar. |
El límite es de 120 solicitudes por minuto y cuenta, compartido entre todos sus tokens, API y MCP. El recálculo de flota tiene otro límite de 10 solicitudes por minuto y cuenta, compartido por API y MCP. El registro muestra hasta las 100 últimas solicitudes almacenadas. Las solicitudes iguales (token, método, ruta y estado) se registran como máximo una vez por minuto; se excluyen las respuestas 429. Se conservan hasta 30 días y 1000 entradas por token; una limpieza horaria elimina el exceso. El historial de puntuación devuelve hasta las 1000 entradas más recientes. Los registros de uso contienen hora, método, ruta y estado HTTP; excluyen los cuerpos de solicitud y respuesta y el secreto del token.
Conectar el MCP remoto
Destino: https://patchfirst.dev/v1/mcp. Transporte: Streamable HTTP, protocolo 2025-06-18, con el mismo token Bearer, comprobaciones de propiedad y reglas de pago. Empieza con un token de lectura. Las herramientas remotas son list_servers, server_report, fleet_report, cve_details y patch_first (qué actualizar primero). Usa refresh_fleet para iniciar un recálculo: requiere write, un UUID fleet y pago activo, y comparte el límite independiente de recálculos por cuenta.
server_report recibe UUID fleet y server; fleet_report recibe fleet; cve_details recibe cve. list_servers devuelve el UUID de flota en fleet. En list_servers y patch_first, fleet es opcional y por defecto corresponde a tu flota. Consulta los esquemas de entrada con tools/list. Los fallos de protocolo usan errores JSON-RPC; los fallos de ejecución, incluidos los límites de pago y recálculo, devuelven HTTP 200 con isError: true.
Solo se admite autenticación Bearer estática: crea un token manualmente en el panel y configúralo en tu cliente. No hay servidor de autorización OAuth ni obtención automática de tokens OAuth. Es un modo limitado de token estático; el flujo completo de autorización OAuth de la especificación MCP no está implementado. La ruta pública /.well-known/oauth-protected-resource publica la URL MCP, la documentación y el enlace de emisión de tokens del panel (token_issuance_uri). En una respuesta 401, la cabecera WWW-Authenticate: Bearer resource_metadata="…" apunta a esos metadatos. Usa un cliente que acepte un token Bearer configurado manualmente.
Claude Code
Define el token en tu entorno y añade el servidor HTTP:
claude mcp add --transport http patchfirst "https://patchfirst.dev/v1/mcp" \
--header "Authorization: Bearer $PATCHFIRST_API_TOKEN"Codex
Añade lo siguiente a ~/.codex/config.toml e inicia Codex con PATCHFIRST_API_TOKEN definida:
[mcp_servers.patchfirst]
url = "https://patchfirst.dev/v1/mcp"
bearer_token_env_var = "PATCHFIRST_API_TOKEN"Documentación oficial de OpenAI para configurar MCP en Codex.
Cursor
Añade el servidor en los ajustes MCP o en tu archivo local ~/.cursor/mcp.json. Sustituye el marcador por tu token y protege el archivo como un secreto:
{
"mcpServers": {
"patchfirst": {
"url": "https://patchfirst.dev/v1/mcp",
"headers": {"Authorization": "Bearer YOUR_API_TOKEN"}
}
}
}Ejemplo de protocolo
El servidor no mantiene estado. Envía Accept: application/json, text/event-stream y Content-Type: application/json. Inicializa primero, envía notifications/initialized y usa después tools/list o tools/call con MCP-Protocol-Version: 2025-06-18. Las notificaciones devuelven 202 sin cuerpo; no se requiere identificador de sesión del servidor. GET /v1/mcp devuelve 405 con la cabecera Allow: POST.
curl --fail-with-body "https://patchfirst.dev/v1/mcp" \
-H "Authorization: Bearer $PATCHFIRST_API_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"acme","version":"1.0"}}}'Recalcular mediante MCP
Ejemplo de tools/call para un token de escritura; sustituye el UUID de flota:
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"refresh_fleet","arguments":{"fleet":"11111111-1111-4111-8111-111111111111"}}}MCP local con descifrado de nombres
El core/mcp_server.py existente sigue disponible por stdio. Ejecuta python3 /path/to/patchfirst/core/mcp_server.py localmente con tu CLI de propietario configurada y los archivos locales de flota (PSR_FLEETS, PSR_INVENTORY). Puede recuperar nombres con tu diccionario cifrado local. El MCP remoto mantiene opacos los nombres cifrados.