Traduit en Français

Si vous construisez des produits SaaS en 2025-2026, vous avez probablement remarqué que chaque responsable de produit veut maintenant des « fonctionnalités d'IA ». C'est normal. Mais la vraie question n'est pas de savoir s'il faut ajouter de l'IA -- c'est comment donner aux modèles d'IA un accès structuré et sécurisé aux données et aux capacités de votre application. C'est exactement ce que le Model Context Protocol (MCP) résout, et déployer des serveurs MCP sur Vercel avec Next.js est devenu l'un des modèles les plus pratiques que j'ai vus pour les équipes SaaS qui veulent avancer rapidement sans mettre en place une nouvelle infrastructure.

J'ai passé les derniers mois à construire des serveurs MCP pour des clients -- certains avec des configurations simples de services d'outils, d'autres avec des flux d'authentification multi-locataires complexes. Cet article couvre tout ce que j'ai appris sur la construction, le déploiement et la mise à l'échelle des serveurs MCP sur Vercel avec Next.js.

MCP Server Development: Deploy on Vercel with Next.js for SaaS

Table des matières

Qu'est-ce que MCP et pourquoi les équipes SaaS devraient s'en préoccuper

Le Model Context Protocol (MCP) est une norme ouverte -- développée à l'origine par Anthropic et maintenant largement adoptée -- qui définit comment les modèles d'IA interagissent avec les outils externes et les sources de données. Pensez-y comme un port USB-C pour l'IA : une interface standardisée que n'importe quel client d'IA peut utiliser pour se connecter à n'importe quel serveur compatible MCP.

Avant MCP, si vous vouliez que Claude, GPT ou tout autre modèle interagisse avec votre application SaaS, vous construiriez des intégrations personnalisées pour chaque fournisseur d'IA. L'appel de fonction avec OpenAI ressemblait à quelque chose de différent de l'utilisation d'outils avec Anthropic. MCP change cela. Vous construisez un serveur, et n'importe quel client compatible MCP peut l'utiliser.

Pour les équipes SaaS, cela importe parce que :

  • Vos utilisateurs s'attendent à des intégrations d'IA. À la mi-2026, environ 68 % des utilisateurs de SaaS B2B signalent l'utilisation d'assistants d'IA aux côtés de leurs outils principaux (Gartner, Q1 2026).
  • MCP devient la norme par défaut. Claude Desktop, Cursor, Windsurf, VS Code Copilot et des dizaines d'autres clients supportent maintenant MCP nativement.
  • Construire un serveur MCP est moins cher que de construire des intégrations personnalisées pour chaque fournisseur d'IA.

MCP par rapport aux intégrations API traditionnelles

Aspect API traditionnelle Serveur MCP
Compatibilité client Un à un par fournisseur N'importe quel client compatible MCP
Découverte Lecture manuelle de la documentation Découverte automatique des outils/ressources
Flux d'authentification Personnalisé par intégration OAuth 2.1 standardisé / clés API
Charge de maintenance Élevée (N intégrations) Faible (1 serveur)
Données en temps réel Polling ou webhooks Server-sent events / streaming
Temps de configuration Jours à semaines par client Heures pour le serveur, minutes par client

Aperçu de l'architecture : MCP sur Vercel

Voici l'architecture sur laquelle j'ai convergé après avoir itéré à travers plusieurs approches :

┌─────────────────┐     ┌──────────────────────┐     ┌─────────────────┐
│  Clients MCP    │     │  Vercel (Next.js)    │     │  Votre backend  │
│                 │     │                      │     │  SaaS           │
│  - Claude       │────▶│  /api/mcp (HTTP+SSE) │────▶│  - Base de      │
│  - Cursor       │     │  /api/mcp/sse        │     │    données      │
│  - Apps custom  │◀────│  /api/auth/[...mcp]  │     │  - APIs         │
└─────────────────┘     └──────────────────────┘     │  - Services     │
                                                      └─────────────────┘

L'insight clé : votre serveur MCP ne remplace pas votre API existante. Il se situe devant elle comme une couche de traduction. Le serveur MCP expose des outils et des ressources qui correspondent à votre fonctionnalité SaaS existante, mais dans un format que les modèles d'IA peuvent découvrir et utiliser.

Sur Vercel, cela s'exécute en tant que fonctions serverless. La dernière spécification MCP (v2025-12) supporte HTTP avec Server-Sent Events (SSE) comme transport, qui fonctionne bien avec le support de streaming de Vercel dans les gestionnaires de routes Next.js.

Pourquoi Next.js sur Vercel ?

Vous pourriez construire un serveur MCP avec n'importe quel framework -- Express, Fastify, Hono, peu importe. Mais Next.js sur Vercel vous donne de vrais avantages pour SaaS :

  1. Votre site marketing, application et serveur MCP vivent dans un seul référentiel. Moins d'infrastructure à gérer.
  2. Edge middleware gère l'authentification avant que les requêtes ne frappent vos points d'extrémité MCP.
  3. Le support de streaming de Vercel fonctionne bien avec le transport MCP basé sur SSE.
  4. Mise à l'échelle automatique -- vous ne pensez pas aux serveurs.
  5. Si vous exécutez déjà Next.js (et statistiquement, vous le faites probablement), il n'y a pas d'infrastructure nouvelle.

Nous faisons beaucoup de développement Next.js chez Social Animal, et ce modèle est devenu l'une de nos architectures les plus demandées.

MCP Server Development: Deploy on Vercel with Next.js for SaaS - architecture

Configuration de votre serveur MCP Next.js

Construisons cela. Je suppose que vous êtes sur Next.js 15+ avec l'App Router.

Installation des dépendances

pnpm add @modelcontextprotocol/sdk zod
pnpm add -D @types/node

Le paquet @modelcontextprotocol/sdk (v1.12+ dès le début de 2026) inclut tout ce dont vous avez besoin pour le transport HTTP+SSE. Les versions antérieures ne supportaient que stdio, ce qui ne fonctionne pas sur serverless.

Création du gestionnaire de route MCP

// app/api/mcp/route.ts
import { McpServer } from '@modelcontextprotocol/sdk/server';
import { httpTransport } from '@modelcontextprotocol/sdk/server/http';
import { z } from 'zod';

const server = new McpServer({
  name: 'your-saas-mcp',
  version: '1.0.0',
  description: 'MCP server for YourSaaS platform',
});

// Enregistrer les outils (nous les développerons ensuite)
server.tool(
  'get-projects',
  'List all projects for the authenticated user',
  {
    status: z.enum(['active', 'archived', 'all']).optional().default('active'),
    limit: z.number().min(1).max(100).optional().default(20),
  },
  async ({ status, limit }, context) => {
    // Votre logique métier réelle ici
    const projects = await fetchProjects(context.auth.userId, { status, limit });
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(projects, null, 2),
        },
      ],
    };
  }
);

const handler = httpTransport(server, {
  sessionManagement: true,
  cors: {
    origin: '*', // Verrouillez ceci en production
  },
});

export const GET = handler;
export const POST = handler;
export const DELETE = handler;

Point d'extrémité SSE pour le streaming

Certains clients MCP préfèrent le transport SSE pour les opérations de longue durée :

// app/api/mcp/sse/route.ts
import { sseTransport } from '@modelcontextprotocol/sdk/server/sse';
import { server } from '../mcp-server'; // Extraire la configuration du serveur dans le module partagé

export const GET = sseTransport(server, {
  // Vercel a un délai d'attente de 30 secondes sur Hobby, 300s sur Pro
  // Pour les outils de longue durée, vous aurez besoin du plan Pro minimum
  keepAliveInterval: 15000,
});

Implémentation des outils et ressources MCP

C'est là que le vrai travail se fait. MCP distingue entre les outils (actions que l'IA peut effectuer) et les ressources (données que l'IA peut lire). Bien faire cela fait la différence entre un serveur MCP que les clients d'IA aiment et celui avec lequel ils ont du mal.

Conception de bons outils

La plus grosse erreur que je vois : des outils qui sont trop granulaires ou trop larges. Si vous exposez 50 petits outils, les modèles d'IA sont submergés. Si vous exposez 3 méga-outils qui prennent chacun 20 paramètres, les modèles font des erreurs.

Ma règle empirique : un outil par intention utilisateur. Si un utilisateur dirait « montre-moi mes factures récentes », c'est un outil. Ne le divisez pas en list-invoices + filter-invoices + format-invoices.

// Bon : intention claire, paramètres raisonnables
server.tool(
  'search-customers',
  'Search for customers by name, email, or account ID. Returns matching customer profiles with recent activity.',
  {
    query: z.string().describe('Search term - can be name, email, or account ID'),
    includeInactive: z.boolean().optional().default(false),
  },
  async ({ query, includeInactive }, context) => {
    const customers = await customerService.search({
      query,
      tenantId: context.auth.tenantId,
      includeInactive,
    });
    
    return {
      content: [{
        type: 'text',
        text: JSON.stringify(customers.map(c => ({
          id: c.id,
          name: c.name,
          email: c.email,
          plan: c.plan,
          mrr: c.mrr,
          lastActive: c.lastActiveAt,
        })), null, 2),
      }],
    };
  }
);

Exposition de ressources

Les ressources sont des données en lecture seule que les clients d'IA peuvent extraire comme contexte. Pensez-y comme des fichiers que le modèle peut référencer :

server.resource(
  'api-docs',
  'Your SaaS API documentation',
  'text/markdown',
  async () => {
    const docs = await fs.readFile('./docs/api-reference.md', 'utf-8');
    return { content: docs };
  }
);

// Ressource dynamique avec modèle d'URI
server.resourceTemplate(
  'project/{projectId}/analytics',
  'Analytics summary for a specific project',
  'application/json',
  async ({ projectId }, context) => {
    const analytics = await analyticsService.getSummary(projectId, context.auth.tenantId);
    return { content: JSON.stringify(analytics) };
  }
);

Authentification et multi-location

C'est la partie que tout le monde se trompe la première fois. MCP supporte OAuth 2.1 pour l'authentification, et si vous construisez un SaaS multi-locataire, vous en avez absolument besoin.

Flux OAuth 2.1 pour MCP

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/api/mcp')) {
    const authHeader = request.headers.get('authorization');
    
    if (!authHeader?.startsWith('Bearer ')) {
      return NextResponse.json(
        { error: 'Missing or invalid authorization header' },
        { status: 401 }
      );
    }
    
    // Valider le jeton et injecter le contexte du locataire
    // C'est ici que votre système d'authentification existant se connecte
  }
}

export const config = {
  matcher: '/api/mcp/:path*',
};

Pour le point d'extrémité de découverte OAuth que les clients MCP ont besoin :

// app/.well-known/oauth-authorization-server/route.ts
export function GET() {
  return Response.json({
    issuer: 'https://your-saas.com',
    authorization_endpoint: 'https://your-saas.com/oauth/authorize',
    token_endpoint: 'https://your-saas.com/api/oauth/token',
    registration_endpoint: 'https://your-saas.com/api/oauth/register',
    scopes_supported: ['mcp:read', 'mcp:write', 'mcp:admin'],
    response_types_supported: ['code'],
    code_challenge_methods_supported: ['S256'],
  });
}

Isolement multi-locataire

Chaque invocation d'outil MCP doit être limitée au locataire authentifié. J'utilise un modèle où le contexte d'authentification est injecté automatiquement dans chaque gestionnaire d'outil :

const withTenant = (handler) => async (params, context) => {
  const tenant = await resolveTenant(context.auth.token);
  if (!tenant) throw new McpError('Invalid tenant');
  return handler(params, { ...context, tenant });
};

Ne faites jamais confiance aux paramètres d'outil pour l'identification du locataire. Dérivez-le toujours du jeton d'authentification.

Déploiement sur Vercel : configuration et pièges

Configuration vercel.json

{
  "functions": {
    "app/api/mcp/route.ts": {
      "maxDuration": 60
    },
    "app/api/mcp/sse/route.ts": {
      "maxDuration": 300
    }
  },
  "headers": [
    {
      "source": "/api/mcp/(.*)",
      "headers": [
        { "key": "Cache-Control", "value": "no-store" }
      ]
    }
  ]
}

Les pièges que personne ne vous dit

1. Délais d'expiration de fonction. Le plan Hobby de Vercel maxe à 30 secondes. Pro vous donne 300 secondes. Pour les outils MCP qui interrogent des bases de données lentes ou traitent les données, vous avez besoin du plan Pro minimum. À 20 $/mois par membre de l'équipe, ce n'est pas une grosse affaire pour la plupart des équipes SaaS.

2. Démarrages froids. Les démarrages froids serverless peuvent ajouter 200-800 ms à la première demande. Les clients MCP gèrent généralement cela bien -- ils ne s'attendent pas à des réponses sub-50ms. Mais si cela vous dérange, utilisez le cron de Vercel pour maintenir les fonctions au chaud.

3. SSE et streaming. Vercel supporte les réponses de streaming, mais il y a des cas limites avec leur couche CDN. Définissez Cache-Control: no-store sur toutes les routes MCP. J'ai appris cela à la dure quand les réponses SSE mises en cache ont fait que les clients reçoivent des listes d'outils obsolètes.

4. Taille du corps de la requête. Vercel limite la taille des corps de requête à 4,5 MB sur les fonctions serverless. Si vos outils MCP gèrent les téléchargements de fichiers ou les charges utiles volumineuses, vous devrez plutôt utiliser des URL d'upload signées.

5. Variables d'environnement. N'oubliez pas de définir l'URL publique de votre serveur MCP comme variable d'environnement. Pendant le développement, vous utiliserez quelque chose comme ngrok ou les URL d'aperçu de Vercel, mais en production, il doit être votre domaine canonique.

# .env.production
MCP_SERVER_URL=https://your-saas.com/api/mcp
MCP_SERVER_NAME=your-saas-mcp

Optimisation des performances et mise à l'échelle

Stratégies de mise en cache

Les réponses des outils MCP peuvent être mises en cache lorsque les données ne changent pas fréquemment :

import { unstable_cache } from 'next/cache';

const getCachedAnalytics = unstable_cache(
  async (tenantId: string, projectId: string) => {
    return analyticsService.getSummary(tenantId, projectId);
  },
  ['analytics-summary'],
  { revalidate: 300 } // 5 minutes
);

Pooling de connexion

Si vos outils MCP frappent une base de données, utilisez le pooling de connexion. Sur Vercel, chaque invocation de fonction obtient son propre contexte d'exécution, donc sans pooling, vous épuiserez rapidement les connexions à la base de données.

import { Pool } from '@neondatabase/serverless';

// Le driver serverless de Neon gère automatiquement le pooling
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

Je recommanderais Neon ou PlanetScale pour les outils MCP soutenus par une base de données sur Vercel. Tous deux gèrent bien le modèle de connexion serverless.

Points de référence

Voici ce que nous avons mesuré sur plusieurs déploiements MCP de production sur Vercel Pro :

Métrique Démarrage froid Chaud P99
Outil simple (pas de BD) 420ms 45ms 180ms
Outil supporté par BD (Neon) 680ms 95ms 320ms
Outil avec API externe 850ms 280ms 1200ms
Configuration de connexion SSE 520ms 60ms 250ms
Découverte d'outil (liste) 380ms 30ms 120ms

Ces chiffres sont corrects pour les interactions des clients d'IA. Les modèles prennent des secondes pour générer des réponses de toute façon -- votre serveur MCP ne sera pas le goulot d'étranglement.

Monitoring et observabilité

Vous devez savoir ce qui se passe en production. Les serveurs MCP ont des besoins uniques d'observabilité parce que les « utilisateurs » sont des modèles d'IA, pas des humains.

Ce à suivre

  • Fréquence d'invocation des outils -- quels outils les modèles utilisent-ils réellement ?
  • Taux d'erreur par outil -- un outil spécifique échoue-t-il plus que les autres ?
  • Distribution de jeton/locataire -- un locataire martèle-t-il votre serveur ?
  • Tailles de charge utile de réponse -- les réponses surdimensionnées gaspillent les fenêtres de contexte du modèle
// Middleware de journalisation simple pour les outils MCP
const withLogging = (toolName: string, handler: Function) => {
  return async (params: any, context: any) => {
    const start = performance.now();
    try {
      const result = await handler(params, context);
      const duration = performance.now() - start;
      
      console.log(JSON.stringify({
        type: 'mcp_tool_invocation',
        tool: toolName,
        tenant: context.auth?.tenantId,
        duration,
        success: true,
        responseSize: JSON.stringify(result).length,
      }));
      
      return result;
    } catch (error) {
      console.error(JSON.stringify({
        type: 'mcp_tool_error',
        tool: toolName,
        tenant: context.auth?.tenantId,
        error: error.message,
      }));
      throw error;
    }
  };
};

Canalisez ces journaux vers Axiom (journalisation intégrée de Vercel), Datadog ou ce que vous utilisez déjà. Les flux de journaux intégrés de Vercel rendent cela simple.

Analyse des coûts : exécuter des serveurs MCP sur Vercel

Parlons argent. Voici une répartition des coûts réaliste pour un SaaS de taille moyenne exécutant un serveur MCP sur Vercel en 2026 :

Composant Hobby Pro Enterprise
Plan de base $0/mo $20/mo par siège Personnalisé
Invocations de fonction (incluses) 100K 1M Personnalisé
Invocations supplémentaires N/A $0.60 par 1M Négociable
Bande passante (incluse) 100GB 1TB Personnalisé
Durée maximale de fonction 30s 300s 900s
Middleware Edge Inclus Inclus Inclus
Estimation mensuelle (10K demandes MCP/jour) Non viable ~$25-40 Personnalisé

Pour la plupart des produits SaaS, le plan Pro gère confortablement le trafic MCP. À ~10 000 invocations d'outils MCP par jour (ce qui est assez actif), vous regardez ~300K invocations de fonction par mois -- bien dans l'allocation incluse de Pro.

Comparez cela à l'exécution d'un serveur MCP dédié sur AWS : vous auriez besoin au minimum d'une instance EC2 ($30-50/mo), d'un équilibreur de charge ($18/mo) et de votre temps pour gérer l'infrastructure. Vercel gagne sur la simplicité opérationnelle.

Si vous évaluez la bonne architecture pour votre SaaS, nous pouvons aider à délimiter cela. Consultez notre page de tarification ou contactez-nous directement.

FAQ

Qu'est-ce que le Model Context Protocol (MCP) et en quoi diffère-t-il de l'appel de fonction ?

MCP est une norme ouverte pour connecter les modèles d'IA aux outils externes et aux données. Contrairement à l'appel de fonction spécifique au fournisseur (appel de fonction OpenAI, utilisation d'outils Anthropic), MCP est universel. Vous construisez un serveur MCP, et n'importe quel client compatible -- Claude, Cursor, applications personnalisées -- peut découvrir et utiliser vos outils automatiquement. L'appel de fonction vous oblige à définir les outils séparément pour chaque fournisseur d'IA.

Puis-je déployer un serveur MCP sur le plan Hobby gratuit de Vercel ?

Techniquement oui, mais je ne le recommanderais pas pour la production. Le délai d'expiration de fonction de 30 secondes est trop restrictif pour les outils MCP qui interrogent les bases de données ou appellent les API externes. Vous obtenez également des invocations limitées (100K/mois). Le plan Pro à $20/mois par siège est le minimum que je suggérerais pour toute charge de travail réelle.

Comment gérer l'authentification entre les clients MCP et mon SaaS ?

La spécification MCP supporte OAuth 2.1. Vous exposez un point d'extrémité .well-known/oauth-authorization-server que les clients MCP découvrent automatiquement. Quand un utilisateur se connecte via un client d'IA comme Claude, il est redirigé vers votre flux OAuth standard, accorde les autorisations, et le client reçoit un jeton d'accès limité. Ce jeton est envoyé avec chaque demande MCP.

Quelle est la différence entre les outils MCP et les ressources MCP ?

Les outils sont des actions -- des choses que l'IA peut faire (créer un projet, envoyer un e-mail, exécuter une requête). Les ressources sont des données -- des choses que l'IA peut lire pour le contexte (documentation, fichiers de configuration, résumés analytiques). Les outils sont invoqués à la demande ; les ressources sont chargées dans la fenêtre de contexte du modèle. Concevez des outils pour les actions, des ressources pour le matériel de référence.

Combien d'outils MCP mon serveur doit-il exposer ?

À partir de mon expérience, 5-15 outils c'est le bon équilibre pour la plupart des produits SaaS. Moins de 5 et votre serveur MCP n'est pas très utile. Plus de 20 et les modèles d'IA commencent à faire de mauvais choix de sélection d'outils. Groupez les opérations connexes en outils uniques avec options de paramètres plutôt que d'exposer chaque opération CRUD séparément.

Cela fonctionne-t-il avec des frameworks autres que Next.js ?

Absolument. Le @modelcontextprotocol/sdk fonctionne avec n'importe quel framework Node.js. Vous pourriez utiliser Hono, Express, ou même Astro avec des points d'extrémité SSR. Next.js sur Vercel est juste une combinaison particulièrement pratique en raison du support de streaming intégré, du middleware Edge et du déploiement sans configuration. Si vous utilisez une pile différente, notre équipe de développement d'en-têtes CMS a construit des serveurs MCP sur plusieurs frameworks.

Comment tester mon serveur MCP pendant le développement ?

L'inspecteur MCP (partie de la boîte à outils MCP officielle) est votre meilleur ami. Il se connecte à votre serveur local et vous permet d'invoquer les outils, de parcourir les ressources et de déboguer les réponses de manière interactive. Pour les tests automatisés, écrivez des tests d'intégration qui instancient votre serveur MCP en processus et appellent les outils de manière programmatique -- le SDK supporte cela sans avoir besoin du transport HTTP.

Que se passe-t-il quand les fonctions Vercel commencent à froid lors d'une demande MCP ?

Les clients MCP sont conçus pour être tolérants à la latence -- ils attendent généralement les réponses du modèle d'IA qui prennent des secondes de toute façon. Un démarrage froid de 400-800 ms est imperceptible en pratique. Si vous êtes préoccupé, le plan Pro de Vercel vous permet de configurer un réchauffement basé sur cron, et le SDK comprend une logique de nouvelle tentative automatique pour les défaillances transitoires. En six mois d'utilisation en production, les démarrages froids n'ont jamais été un problème signalé par les utilisateurs pour nos clients.