p PatchFirst

PatchFirst / Développeurs

API et MCP

Consultez les constats de vos serveurs payants, préparez une liste de correctifs prioritaires et demandez un recalcul depuis vos outils.

Un jeton par intégration

Créez un jeton API personnel dans la rubrique Jetons API du tableau de bord. Donnez-lui un nom de 64 caractères maximum, choisissez read ou write (lecture et écriture), puis définissez sa durée de validité de 1 à 365 jours. Saisissez à nouveau votre mot de passe actuel pour confirmer sa création. Tous les jetons API sont révoqués après une modification ou une récupération du mot de passe. Une simple déconnexion conserve l’accès CI et MCP. Pour révoquer tous les jetons, utilisez le bouton dédié « Révoquer tous les jetons » dans le tableau de bord. Celui-ci affiche le motif de révocation. Vous pouvez avoir jusqu’à 50 jetons actifs. Copiez le secret à son apparition : il n’est affiché qu’une fois. Le service ne conserve qu’une empreinte de vérification. Vous pouvez lister et révoquer les jetons et consulter leur utilisation depuis le tableau de bord.

Utilisez HTTPS et transmettez le jeton uniquement dans Authorization: Bearer …. Les jetons dans les URL sont refusés. Ces exemples supposent que PATCHFIRST_API_TOKEN est défini dans votre environnement ; gardez le secret hors du dépôt de code, des captures d’écran et des journaux. Les clés de lecture/écriture des parcs et les jetons d’agents existants sont des identifiants d’accès distincts.

curl --fail-with-body "https://patchfirst.dev/v1/me/fleets" \
  -H "Authorization: Bearer $PATCHFIRST_API_TOKEN"

Le jeton couvre uniquement les parcs du propriétaire. Un parc appartenant à un tiers renvoie 404, comme un parc inexistant. Un jeton read ne peut pas lancer de recalcul. L’accès depuis un navigateur d’une autre origine est désactivé (CORS fermé).

L’API et MCP nécessitent une surveillance payante. Sans paiement éligible, les requêtes renvoient 402. Après l’expiration de la surveillance, l’accès aux archives comprend uniquement les instantanés de rapports sauvegardés pendant une période précédemment payée, selon les règles de facturation, sans nouvelles données. Les détails CVE nécessitent un paiement actif : sinon, l’API renvoie 402 et cve_details renvoie une erreur de paiement dans le résultat MCP ; les données actuelles KEV, EPSS, codes d’exploitation, observations et mentions sont indisponibles en mode archive. Les nouveaux calculs nécessitent une surveillance éligible en cours, y compris son éventuel délai de grâce ; des emplacements gratuits seuls ne donnent pas accès à l’API.

Points d’accès de l’API v1

URL de base : https://patchfirst.dev. Remplacez {fleet} et {server} par les UUID renvoyés par les points d’accès de liste. Tous les points d’accès ci-dessous utilisent un jeton Bearer personnel.

API personnelle
Méthode et cheminRésultat
GET /v1/me/fleetsParcs détenus : {"fleets":[{"id":"…","created_at":1792713600}]}.
GET /v1/me/fleets/{fleet}/serversServeurs payants consultables : {"servers":[{"id":"…","name":"web-1","name_kind":"alias","updated_at":1792713600}]}.
GET /v1/me/fleets/{fleet}/reportNote du parc, nombres de P0–P3 et rapports des serveurs dans assets.
GET /v1/me/fleets/{fleet}/servers/{server}/reportNote du serveur, constats, CVE, versions corrigées et recommandations.
GET /v1/me/fleets/{fleet}/servers/{server}/history{"history":[…]} : instantanés de notes conservés.
GET /v1/me/cves/{cve}Fiche CVE, KEV, EPSS, codes d’exploitation et mentions des sources. Exemple d’identifiant : CVE-2026-12345.
POST /v1/me/fleets/{fleet}/refresh202 : recalcul accepté. Nécessite write et une surveillance éligible. Consultez de nouveau le rapport pour obtenir les résultats.
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 gestion des jetons dans le tableau de bord utilise votre session de navigateur connectée, distincte de l’accès Bearer : GET/POST /v1/account/api-tokens, DELETE /v1/account/api-tokens/{token_id}, et GET /v1/account/api-tokens/{token_id}/usage. La création accepte {"name":"acme integration","scope":"read","expires_in_days":30,"password":"CURRENT_PASSWORD"} et renvoie 201 avec les métadonnées du jeton et le secret token à affichage unique. Les écritures de session nécessitent une vérification de même origine.

Contrat des réponses et noms

Le document OpenAPI définit les schémas JSON v1. Les champs existants conservent leur sens et leurs types ; les clients doivent accepter des champs supplémentaires. Les réponses de succès sont des objets JSON. Les listes utilisent des tableaux fleets, servers ou history. Les métadonnées des jetons, la création des parcs, les mises à jour des serveurs et les valeurs d’historique recorded_at utilisent des secondes Unix (UTC) ; le champ de rapport computed_at utilise une chaîne de date et heure UTC ou null.

Les champs score et grade donnent la note principale des composants vérifiés. global_score et global_grade donnent la note globale en tenant compte du risque inconnu. coverage contient les entiers checked (vérifiés) et total (détectés). Ces champs figurent dans les rapports de serveur et de parc, les listes de serveurs et les instantanés d’historique. La couverture du parc additionne uniquement les serveurs dont la note globale est disponible ; leur pondération est celle de la note principale. La lettre ? indique une note indisponible. Les anciens instantanés peuvent contenir null pour la note globale.

Les champs complete, rating_complete, reasons et blind sont conservés pour compatibilité et décrivent la couverture. Ils ne déterminent ni la note principale ni le verdict. Calcul de la note globale et de la couverture →

Un rapport de serveur contient id, name, name_kind, score, grade, counts et findings. Chaque constat comprend priority (P0–P3), component, la version installée version, la version corrigée fix, l’action recommandée action et les entrées CVE top. fix peut être vide ou null lorsqu’aucune version corrigée n’est disponible ; vérifiez unfixed, pro_only et action.

Les alias en clair tels que web-1 sont renvoyés avec name_kind: "alias". Lorsque les noms sont chiffrés ou non définis, name_kind: "opaque" désigne une étiquette opaque. Le service distant ne connaît pas les noms de serveur chiffrés et ne peut pas les déchiffrer. N’utilisez jamais de domaine, d’IP, de nom d’entreprise ou de client comme alias en clair.

Erreurs, limites et utilisation

Les erreurs ont la structure stable {"error":"Readable explanation","code":"machine_code"}. Utilisez le statut HTTP et code pour la logique du programme ; l’explication peut changer.

Codes de statut HTTP
StatutSignification
400Entrée invalide, paramètres non pris en charge ou jeton dans l’URL.
401Jeton absent, invalide, expiré ou révoqué.
402Une surveillance payante ou un instantané payé consultable est nécessaire.
403Autorisations insuffisantes ou origine invalide ; utilisez un jeton en écriture pour actualiser.
404Ressource inexistante ou appartenant à un autre propriétaire.
405Méthode non prise en charge ; MCP accepte POST.
409La limite de 50 jetons API personnels actifs est atteinte.
429Trop de requêtes. Patientez le nombre de secondes indiqué par Retry-After avant de réessayer.

La limite est de 120 requêtes par minute et par compte, partagée entre tous ses jetons, l’API et MCP. Le recalcul d’un parc a une limite distincte de 10 requêtes par minute et par compte, commune à l’API et à MCP. Le journal affiche jusqu’aux 100 dernières requêtes conservées. Les requêtes identiques (jeton, méthode, chemin, statut) sont échantillonnées au maximum une fois par minute ; les réponses 429 sont exclues. Les enregistrements sont conservés jusqu’à 30 jours et dans la limite de 1000 par jeton ; un nettoyage horaire supprime l’excédent. L’historique des notes renvoie jusqu’aux 1000 entrées les plus récentes. Le journal contient la date, la méthode, le chemin et le statut HTTP ; les corps des requêtes et des réponses ainsi que le secret du jeton en sont exclus.

Connecter le MCP distant

Point d’accès : https://patchfirst.dev/v1/mcp. Transport : Streamable HTTP, protocole 2025-06-18, avec le même jeton Bearer, les mêmes contrôles de propriété et les mêmes règles de paiement. Commencez par un jeton en lecture. Les outils distants sont list_servers, server_report, fleet_report, cve_details et patch_first (quoi mettre à jour en premier). Utilisez refresh_fleet pour lancer un recalcul : il nécessite write, un UUID de fleet et un paiement actif, et partage la limite de recalcul distincte du compte.

server_report accepte les UUID fleet et server ; fleet_report accepte l’UUID fleet ; cve_details accepte l’identifiant cve. list_servers renvoie l’UUID du parc dans fleet. Pour list_servers et patch_first, fleet est facultatif et utilise votre parc par défaut. Découvrez les schémas d’entrée avec tools/list. Les erreurs de protocole utilisent des réponses d’erreur JSON-RPC ; les échecs d’exécution des outils, y compris les limites de paiement et de recalcul, renvoient HTTP 200 avec isError: true.

Seule l’authentification Bearer statique est prise en charge : créez manuellement un jeton dans le tableau de bord et configurez-le dans votre client. Il n’existe ni serveur d’autorisation OAuth ni acquisition automatique de jeton OAuth. Ce mode est limité aux jetons statiques ; le flux d’autorisation OAuth complet de la spécification MCP n’est pas implémenté. Le point d’accès public /.well-known/oauth-protected-resource publie l’URL MCP, la documentation et le lien de création de jetons dans le tableau de bord (token_issuance_uri). En cas de 401, l’en-tête WWW-Authenticate: Bearer resource_metadata="…" pointe vers ces métadonnées. Utilisez un client acceptant un jeton Bearer configuré manuellement.

Claude Code

Définissez le jeton dans votre environnement, puis ajoutez le serveur HTTP :

claude mcp add --transport http patchfirst "https://patchfirst.dev/v1/mcp" \
  --header "Authorization: Bearer $PATCHFIRST_API_TOKEN"

Codex

Ajoutez ceci à ~/.codex/config.toml, puis lancez Codex avec PATCHFIRST_API_TOKEN défini :

[mcp_servers.patchfirst]
url = "https://patchfirst.dev/v1/mcp"
bearer_token_env_var = "PATCHFIRST_API_TOKEN"

Documentation officielle OpenAI pour la configuration MCP de Codex.

Cursor

Ajoutez le serveur dans les paramètres MCP ou dans votre fichier local ~/.cursor/mcp.json. Remplacez la valeur d’exemple par votre jeton et protégez ce fichier comme un secret :

{
  "mcpServers": {
    "patchfirst": {
      "url": "https://patchfirst.dev/v1/mcp",
      "headers": {"Authorization": "Bearer YOUR_API_TOKEN"}
    }
  }
}

Exemple de protocole

Le serveur est sans état. Envoyez Accept: application/json, text/event-stream et Content-Type: application/json. Initialisez d’abord, envoyez notifications/initialized, puis utilisez tools/list ou tools/call avec MCP-Protocol-Version: 2025-06-18. Les notifications renvoient 202 sans corps ; aucun identifiant de session serveur n’est requis. GET /v1/mcp renvoie 405 avec l’en-tête 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"}}}'

Recalculer via MCP

Exemple tools/call pour un jeton en écriture ; remplacez l’UUID du parc :

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"refresh_fleet","arguments":{"fleet":"11111111-1111-4111-8111-111111111111"}}}

MCP local avec déchiffrement des noms

Le module existant core/mcp_server.py reste disponible via stdio. Exécutez python3 /path/to/patchfirst/core/mcp_server.py localement avec votre client propriétaire configuré et vos fichiers de parc locaux (PSR_FLEETS, PSR_INVENTORY). Il peut restaurer les noms à l’aide de votre dictionnaire chiffré local. Le MCP distant conserve les noms chiffrés sous forme opaque.