VantagePeers Docs

Sécurité d'enveloppe

Anti-patterns de débordement pour les outils list_* de VantagePeers — fields=lite, plafond limit 200, anti-patterns à éviter, et pourquoi chaque outil list_* adopte par défaut une forme d'enveloppe sûre.

Sécurité d'enveloppe

Le serveur MCP VantagePeers applique un ensemble cohérent de protections sur chaque réponse list_* pour éviter que les payloads de réponse ne dépassent le budget de contexte de l'agent appelant. Cette page documente les protections, le système de projection fields=lite|full, le plafond strict de 200 lignes, et les anti-patterns ayant causé des incidents en production.

Les trois protections

Chaque outil list_* de VantagePeers applique trois couches de protection :

  1. Plafond strict de lignes (200) : L'argument limit est validé comme z.number().int().min(1).max(200).optional(). Toute valeur supérieure à 200 est rejetée au niveau MCP avant d'atteindre Convex. La valeur par défaut quand aucun limit n'est fourni est de 20 lignes.

  2. Projection fields=lite : Tous les outils list_* acceptent fields: "lite" | "full". La projection lite retourne au maximum 6 champs par ligne, gardant les pages compactes même pour les documents avec un grand contenu texte (ex. mémoires avec un long content, briefings avec de longs tableaux decisions).

  3. Limite douce de 50 Ko (enforceEnvelopeCap) : Après projection des lignes, le serveur mesure la taille JSON sérialisée de l'enveloppe. Si le résultat dépasse 50 000 octets, le serveur divise le nombre de lignes de moitié et mesure à nouveau, en répétant jusqu'à ce que le payload soit dans les limites. Ce garde-fou existe en plus du plafond de lignes — il protège contre les lignes schéma complet avec du texte embarqué volumineux.

fields=lite vs fields=full

ValeurChamps retournésTaille typique par ligne
"lite"_id, _creationTime, plus 2 à 4 champs d'affichage~200–400 octets
"full"Tous les champs du schéma incluant le contenu texte complet~2 000–20 000 octets

La valeur par défaut est "full". Pour toute boucle traitant plus d'une page, toujours passer fields: "lite".

Exemple de projection lite pour list_tasks :

{
  "_id": "k17abc...",
  "_creationTime": 1751020800000,
  "title": "Corriger la pagination list_memories",
  "status": "done",
  "assignedTo": "sigma",
  "priority": "urgent"
}

La même tâche en mode full inclut description (potentiellement des centaines de caractères), completionNote, blockers, dependsOn, missionId, orgId, createdBy, updatedAt, et tous les autres champs du schéma.

Comportement du plafonnement de limite

La fonction clampLimit dans mcp-server/src/paging.ts applique ces règles dans l'ordre :

  1. Si limit est indéfini, retourner DEFAULT_LIMIT (20 pour la plupart des outils).
  2. Si limit < 1, retourner 1.
  3. Si limit > MAX_LIMIT (200), retourner 200.
  4. Sinon retourner limit inchangé.

Cela signifie qu'un appelant ne peut pas accidentellement demander un résultat non borné en passant une limit très grande. Le plafond de 200 lignes est appliqué quel que soit ce que l'appelant envoie.

Anti-patterns

Les motifs suivants ont causé des incidents en production vérifiés. Chacun est interdit dans toutes les implémentations de serveur MCP VantageOS.

Pourquoi chaque outil list_* adopte par défaut une forme d'enveloppe sûre

L'objectif de conception est qu'un appelant ne passant aucun argument reçoive quand même une réponse sûre. La combinaison par défaut limit: 20 et fields: "full" produit au maximum ~400 Ko pour les outils les plus riches en documents, bien dans le budget de contexte sûr pour tous les clients supportés (Claude.ai, Claude Code, ChatGPT, Codex).

Pour les boucles de parcours en production — balayage de toutes les tâches d'une BU, export d'un namespace complet, etc. — toujours surcharger avec limit: 200 et fields: "lite" pour maximiser le débit sans risque.

Référence des exports paging.ts

L'utilitaire partagé mcp-server/src/paging.ts centralise toute la logique de pagination. Ses exports clés :

ExportTypeDescription
pagingArgsSchemaz.ZodObjectSchéma Zod partagé : { limit, cursor, fields }
DEFAULT_LIMIT50Valeur de repli de clampLimit quand undefined est fourni
MAX_LIMIT200Plafond strict appliqué par clampLimit
ENVELOPE_TARGET_BYTES50 000Limite douce en octets pour enforceEnvelopeCap
clampLimitfonctionPlafonne limit à [1, MAX_LIMIT], par défaut DEFAULT_LIMIT
encodeCursorfonctionCursorPayload → chaîne base64url
decodeCursorfonction`chaîne base64url → CursorPayload
enforceEnvelopeCapfonctionDivise les lignes de moitié jusqu'à rester sous ENVELOPE_TARGET_BYTES

L'export DEFAULT_LIMIT de clampLimit est 50. Les outils individuels surchargent cela à 20 via DEFAULT_PAGING.limit = 20 dans applyPagingDefaults. Quand aucune limite n'est fournie à un outil liste spécifique, la valeur par défaut de l'outil de 20 s'applique — pas la constante DEFAULT_LIMIT.

Références croisées

On this page