Construire votre premier serveur MCP avec TypeScript : Outils, Ressources et Prompts

Équipe NoqtaAI Bot
Par Équipe Noqta & AI Bot ·

Chargement du lecteur de synthèse vocale...

Le protocole qui connecte l'IA a tout. MCP (Model Context Protocol) est le standard ouvert qui permet aux agents IA comme Claude et Cursor de decouvrir et utiliser vos outils. Dans ce tutoriel, vous allez en construire un de zero.

Ce que vous allez apprendre

A la fin de ce tutoriel, vous serez capable de :

  • Comprendre l'architecture MCP : serveurs, clients, hotes et transports
  • Mettre en place un projet de serveur MCP en TypeScript depuis zero
  • Enregistrer des outils que les agents IA peuvent invoquer
  • Exposer des ressources qui fournissent du contexte aux LLMs
  • Definir des prompts comme modeles reutilisables pour les taches courantes
  • Connecter votre serveur a Claude Desktop et Cursor
  • Tester et deboguer votre serveur avec le MCP Inspector

Prerequis

Avant de commencer, assurez-vous d'avoir :

  • Node.js 20+ installe (node --version)
  • Des connaissances en TypeScript (types, async/await, modules)
  • Un editeur de code — VS Code ou Cursor recommande
  • Claude Desktop ou Cursor installe (pour les tests)
  • Une comprehension basique de JSON-RPC et des APIs

Qu'est-ce que MCP ?

Le Model Context Protocol est un standard ouvert cree par Anthropic qui definit comment les applications d'IA communiquent avec les sources de donnees et les outils externes. Pensez-y comme l'USB-C de l'IA — un connecteur unique et universel qui remplace le desordre des integrations personnalisees.

Vue d'ensemble de l'architecture

┌─────────────────────────────────────────────┐
│  MCP Host (Claude Desktop, Cursor, etc.)    │
│                                             │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐    │
│  │ Client 1│  │ Client 2│  │ Client 3│    │
│  └────┬────┘  └────┬────┘  └────┬────┘    │
└───────┼────────────┼────────────┼──────────┘
        │            │            │
   ┌────▼────┐  ┌────▼────┐  ┌───▼─────┐
   │ Server A│  │ Server B│  │ Server C│
   │ (Files) │  │ (DB)    │  │ (APIs)  │
   └─────────┘  └─────────┘  └─────────┘
ComposantRole
Hote (Host)L'application IA (Claude Desktop, Cursor)
ClientMaintient une connexion 1:1 avec un serveur
Serveur (Server)Expose les outils, les ressources et les prompts
TransportCanal de communication (stdio, HTTP)

Ce que les serveurs peuvent exposer

Les serveurs MCP fournissent trois primitives :

  1. Outils (Tools) — Fonctions que l'IA peut appeler (comme des endpoints API)
  2. Ressources (Resources) — Donnees en lecture seule auxquelles l'IA peut acceder (comme des fichiers)
  3. Prompts — Modeles reutilisables pour les workflows courants

Etape 1 : Configuration du projet

Creez un nouveau repertoire et initialisez le projet.

mkdir my-mcp-server && cd my-mcp-server
npm init -y

Installez le SDK MCP et les dependances.

npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node

Note sur la version du SDK : Ce tutoriel utilise le MCP TypeScript SDK v1.x qui utilise @modelcontextprotocol/sdk. Le SDK v2 (prevu pour le T2 2026) reorganise les imports en @modelcontextprotocol/server et @modelcontextprotocol/node. Les concepts restent identiques — seuls les chemins d'import changent.

Initialisez TypeScript.

npx tsc --init

Mettez a jour votre tsconfig.json :

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"]
}

Mettez a jour package.json pour marquer le projet comme ESM et ajouter les scripts de build :

{
  "name": "my-mcp-server",
  "version": "1.0.0",
  "type": "module",
  "bin": {
    "my-mcp-server": "./build/index.js"
  },
  "scripts": {
    "build": "tsc",
    "start": "node build/index.js",
    "dev": "tsc --watch"
  }
}

Creez le repertoire source :

mkdir src

Etape 2 : Creer le squelette du serveur

Creez src/index.ts — le point d'entree de votre serveur MCP.

#!/usr/bin/env node
 
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
 
// Create the MCP server
const server = new McpServer({
  name: "my-mcp-server",
  version: "1.0.0",
});
 
// Connect using stdio transport
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP server running on stdio");
}
 
main().catch(console.error);

Points cles :

  • McpServer est la classe de haut niveau qui gere la negociation du protocole
  • StdioServerTransport communique via stdin/stdout — le standard pour les serveurs MCP locaux
  • Nous loggons dans stderr car stdout est reserve pour les messages du protocole MCP

Compilez et verifiez :

npm run build

Vous avez maintenant un serveur MCP fonctionnel (mais vide). Ajoutons des capacites.


Etape 3 : Enregistrer les outils

Les outils sont la primitive MCP la plus puissante. Ils permettent aux agents IA d'effectuer des actions — appeler des APIs, interroger des bases de donnees, transformer des donnees ou executer des calculs.

Votre premier outil : Un compteur de mots

Ajoutez ceci avant la fonction main() dans src/index.ts :

import { z } from "zod";
 
server.tool(
  "count_words",
  "Count the number of words in a given text",
  {
    text: z.string().describe("The text to count words in"),
  },
  async ({ text }) => {
    const wordCount = text
      .trim()
      .split(/\s+/)
      .filter((w) => w.length > 0).length;
 
    return {
      content: [
        {
          type: "text",
          text: `The text contains ${wordCount} words.`,
        },
      ],
    };
  }
);

Decomposons la signature de server.tool() :

ParametreObjectif
"count_words"Nom unique de l'outil (snake_case par convention)
"Count the..."Description lisible par un humain pour l'IA
{ text: z.string() }Schema d'entree avec validation Zod
async ({ text }) => ...Fonction handler qui execute l'outil

Un outil plus pratique : Verificateur de statut URL

server.tool(
  "check_url",
  "Check if a URL is reachable and return its HTTP status code",
  {
    url: z.string().url().describe("The URL to check"),
    timeout: z
      .number()
      .optional()
      .default(5000)
      .describe("Timeout in milliseconds"),
  },
  async ({ url, timeout }) => {
    try {
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), timeout);
 
      const response = await fetch(url, {
        method: "HEAD",
        signal: controller.signal,
      });
 
      clearTimeout(timeoutId);
 
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                url,
                status: response.status,
                statusText: response.statusText,
                reachable: true,
              },
              null,
              2
            ),
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                url,
                reachable: false,
                error:
                  error instanceof Error ? error.message : "Unknown error",
              },
              null,
              2
            ),
          },
        ],
        isError: true,
      };
    }
  }
);

Remarquez le pattern :

  • Utilisez Zod pour la validation des entrees — l'IA voit le schema et sait quoi envoyer
  • Retournez content comme un tableau de blocs de contenu (text, image, ou resource)
  • Definissez isError: true quand l'outil echoue, pour que l'IA gere les erreurs gracieusement

Outil avec sortie structuree

Pour les outils qui retournent des donnees (pas juste des messages), vous pouvez definir un schema de sortie :

server.tool(
  "calculate_bmi",
  "Calculate Body Mass Index from weight and height",
  {
    weightKg: z.number().positive().describe("Weight in kilograms"),
    heightM: z.number().positive().describe("Height in meters"),
  },
  async ({ weightKg, heightM }) => {
    const bmi = weightKg / (heightM * heightM);
    const category =
      bmi < 18.5
        ? "Underweight"
        : bmi < 25
        ? "Normal"
        : bmi < 30
        ? "Overweight"
        : "Obese";
 
    return {
      content: [
        {
          type: "text",
          text: `BMI: ${bmi.toFixed(1)} (${category})`,
        },
      ],
    };
  }
);

Etape 4 : Exposer les ressources

Les ressources fournissent un contexte en lecture seule a l'IA. Contrairement aux outils (qui effectuent des actions), les ressources sont des donnees que l'IA peut consulter — fichiers de configuration, documentation, schemas de bases de donnees, ou etat du systeme en direct.

Ressource statique

server.resource(
  "server-info",
  "info://server",
  async (uri) => {
    return {
      contents: [
        {
          uri: uri.href,
          mimeType: "application/json",
          text: JSON.stringify(
            {
              name: "my-mcp-server",
              version: "1.0.0",
              capabilities: ["word counting", "URL checking", "BMI calculation"],
              uptime: process.uptime(),
            },
            null,
            2
          ),
        },
      ],
    };
  }
);

Ressource dynamique avec modeles

Les modeles de ressources vous permettent d'exposer des donnees parametrees — comme des enregistrements individuels d'une base de donnees.

// Simulated data store
const projects = new Map([
  [
    "web-app",
    {
      name: "Web Application",
      status: "active",
      tech: ["Next.js", "TypeScript", "PostgreSQL"],
    },
  ],
  [
    "api",
    {
      name: "REST API",
      status: "active",
      tech: ["Hono", "Bun", "SQLite"],
    },
  ],
  [
    "mobile",
    {
      name: "Mobile App",
      status: "planning",
      tech: ["React Native", "Expo"],
    },
  ],
]);
 
// Resource template — the {id} is a URI parameter
server.resource(
  "project",
  "projects://{id}",
  async (uri) => {
    const id = uri.pathname.replace("//", "");
    const project = projects.get(id);
 
    if (!project) {
      throw new Error(`Project "${id}" not found`);
    }
 
    return {
      contents: [
        {
          uri: uri.href,
          mimeType: "application/json",
          text: JSON.stringify(project, null, 2),
        },
      ],
    };
  }
);

Quand un agent IA se connecte a votre serveur, il peut parcourir les ressources disponibles et les lire pour obtenir du contexte — exactement comme parcourir des fichiers sur un disque.


Etape 5 : Definir les prompts

Les prompts sont des modeles reutilisables qui guident l'IA vers des taches specifiques. Ce sont comme des instructions sauvegardees qui acceptent des arguments.

server.prompt(
  "code-review",
  "Review code for bugs, security issues, and best practices",
  {
    code: z.string().describe("The code to review"),
    language: z
      .string()
      .optional()
      .default("typescript")
      .describe("Programming language"),
    focus: z
      .enum(["bugs", "security", "performance", "all"])
      .optional()
      .default("all")
      .describe("What to focus on in the review"),
  },
  async ({ code, language, focus }) => {
    const focusInstructions = {
      bugs: "Focus on finding logical errors, edge cases, and potential runtime exceptions.",
      security:
        "Focus on security vulnerabilities: injection, XSS, authentication flaws, data exposure.",
      performance:
        "Focus on performance: unnecessary allocations, O(n²) algorithms, missing caching.",
      all: "Review for bugs, security vulnerabilities, performance issues, and adherence to best practices.",
    };
 
    return {
      messages: [
        {
          role: "user",
          content: {
            type: "text",
            text: `Review the following ${language} code. ${focusInstructions[focus]}
 
\`\`\`${language}
${code}
\`\`\`
 
Provide your review as:
1. **Critical Issues** — Must fix before merging
2. **Warnings** — Should fix, but not blocking
3. **Suggestions** — Nice-to-have improvements
4. **Summary** — Overall code quality assessment`,
          },
        },
      ],
    };
  }
);

Un autre prompt : Generateur de requetes SQL

server.prompt(
  "generate-sql",
  "Generate SQL queries from natural language descriptions",
  {
    description: z
      .string()
      .describe("Natural language description of the query"),
    dialect: z
      .enum(["postgresql", "mysql", "sqlite"])
      .optional()
      .default("postgresql")
      .describe("SQL dialect to target"),
    schema: z
      .string()
      .optional()
      .describe("Database schema context (CREATE TABLE statements)"),
  },
  async ({ description, dialect, schema }) => {
    let contextBlock = "";
    if (schema) {
      contextBlock = `\nHere is the database schema:\n\`\`\`sql\n${schema}\n\`\`\`\n`;
    }
 
    return {
      messages: [
        {
          role: "user",
          content: {
            type: "text",
            text: `Generate a ${dialect} SQL query for the following request:
 
"${description}"
${contextBlock}
Requirements:
- Use proper ${dialect} syntax
- Include comments explaining the query
- Use parameterized queries where user input is involved
- Optimize for readability and performance`,
          },
        },
      ],
    };
  }
);

Etape 6 : Code complet du serveur

Voici le fichier src/index.ts complet avec toutes les primitives enregistrees. C'est la version complete et executable :

#!/usr/bin/env node
 
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
 
// ── Server ──────────────────────────────────────────────
 
const server = new McpServer({
  name: "my-mcp-server",
  version: "1.0.0",
});
 
// ── Tools ───────────────────────────────────────────────
 
server.tool(
  "count_words",
  "Count the number of words in a given text",
  { text: z.string().describe("The text to count words in") },
  async ({ text }) => {
    const wordCount = text
      .trim()
      .split(/\s+/)
      .filter((w) => w.length > 0).length;
 
    return {
      content: [{ type: "text", text: `The text contains ${wordCount} words.` }],
    };
  }
);
 
server.tool(
  "check_url",
  "Check if a URL is reachable and return its HTTP status code",
  {
    url: z.string().url().describe("The URL to check"),
    timeout: z.number().optional().default(5000).describe("Timeout in ms"),
  },
  async ({ url, timeout }) => {
    try {
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), timeout);
      const response = await fetch(url, {
        method: "HEAD",
        signal: controller.signal,
      });
      clearTimeout(timeoutId);
 
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                url,
                status: response.status,
                statusText: response.statusText,
                reachable: true,
              },
              null,
              2
            ),
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                url,
                reachable: false,
                error: error instanceof Error ? error.message : "Unknown error",
              },
              null,
              2
            ),
          },
        ],
        isError: true,
      };
    }
  }
);
 
// ── Resources ───────────────────────────────────────────
 
const projects = new Map([
  ["web-app", { name: "Web Application", status: "active", tech: ["Next.js", "TypeScript", "PostgreSQL"] }],
  ["api", { name: "REST API", status: "active", tech: ["Hono", "Bun", "SQLite"] }],
  ["mobile", { name: "Mobile App", status: "planning", tech: ["React Native", "Expo"] }],
]);
 
server.resource("server-info", "info://server", async (uri) => ({
  contents: [
    {
      uri: uri.href,
      mimeType: "application/json",
      text: JSON.stringify(
        {
          name: "my-mcp-server",
          version: "1.0.0",
          capabilities: ["word counting", "URL checking"],
          uptime: process.uptime(),
        },
        null,
        2
      ),
    },
  ],
}));
 
server.resource("project", "projects://{id}", async (uri) => {
  const id = uri.pathname.replace("//", "");
  const project = projects.get(id);
  if (!project) throw new Error(`Project "${id}" not found`);
  return {
    contents: [
      { uri: uri.href, mimeType: "application/json", text: JSON.stringify(project, null, 2) },
    ],
  };
});
 
// ── Prompts ─────────────────────────────────────────────
 
server.prompt(
  "code-review",
  "Review code for bugs, security issues, and best practices",
  {
    code: z.string().describe("The code to review"),
    language: z.string().optional().default("typescript").describe("Programming language"),
    focus: z
      .enum(["bugs", "security", "performance", "all"])
      .optional()
      .default("all")
      .describe("Review focus area"),
  },
  async ({ code, language, focus }) => {
    const focusMap = {
      bugs: "Focus on logical errors and edge cases.",
      security: "Focus on security vulnerabilities.",
      performance: "Focus on performance bottlenecks.",
      all: "Review bugs, security, performance, and best practices.",
    };
 
    return {
      messages: [
        {
          role: "user" as const,
          content: {
            type: "text" as const,
            text: `Review this ${language} code. ${focusMap[focus]}\n\n\`\`\`${language}\n${code}\n\`\`\``,
          },
        },
      ],
    };
  }
);
 
// ── Start ───────────────────────────────────────────────
 
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP server running on stdio");
}
 
main().catch(console.error);

Compilez le serveur :

npm run build

Etape 7 : Tester avec le MCP Inspector

Avant de vous connecter a Claude Desktop, utilisez le MCP Inspector pour tester votre serveur de maniere interactive.

npx @modelcontextprotocol/inspector node build/index.js

Cela ouvre une interface web ou vous pouvez :

  1. Lister les outils — Voir tous les outils enregistres et leurs schemas
  2. Appeler les outils — Executer des outils avec des entrees de test et voir les reponses
  3. Parcourir les ressources — Voir les ressources disponibles et lire leur contenu
  4. Utiliser les prompts — Selectionner des prompts, remplir les arguments et voir les messages generes

Essayez d'appeler l'outil count_words avec "Hello world, this is my MCP server" — vous devriez voir la reponse The text contains 7 words.


Etape 8 : Connecter a Claude Desktop

Ouvrez votre fichier de configuration Claude Desktop :

  • macOS : ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows : %APPDATA%\Claude\claude_desktop_config.json

Ajoutez votre serveur :

{
  "mcpServers": {
    "my-mcp-server": {
      "command": "node",
      "args": ["/absolute/path/to/my-mcp-server/build/index.js"]
    }
  }
}

Important : Utilisez le chemin absolu vers votre fichier build/index.js. Les chemins relatifs ne fonctionneront pas. Remplacez /absolute/path/to/ par le chemin reel de votre projet.

Redemarrez Claude Desktop. Vous devriez voir une icone de marteau indiquant que les outils sont disponibles. Essayez de demander a Claude :

  • "Compte les mots dans ce paragraphe : ..."
  • "Verifie si https://noqta.tn est accessible"
  • "Utilise le prompt de revue de code pour revoir cette fonction"

Etape 9 : Connecter a Cursor

Cursor supporte nativement les serveurs MCP. Ajoutez votre serveur dans les parametres MCP de Cursor :

  1. Ouvrez Cursor Settings (Cmd+Shift+J sur macOS)
  2. Naviguez vers MCP Servers
  3. Cliquez sur Add Server
  4. Configurez :
    • Name : my-mcp-server
    • Type : stdio
    • Command : node /absolute/path/to/my-mcp-server/build/index.js

Alternativement, creez un fichier .cursor/mcp.json a la racine de votre projet :

{
  "mcpServers": {
    "my-mcp-server": {
      "command": "node",
      "args": ["/absolute/path/to/my-mcp-server/build/index.js"]
    }
  }
}

Vos outils sont maintenant disponibles dans le mode Agent de Cursor. L'IA peut decouvrir et appeler vos outils automatiquement pendant les sessions de developpement.


Etape 10 : Ajouter la gestion des erreurs et la journalisation

Les serveurs MCP en production necessitent une gestion des erreurs robuste. Voici un pattern pour des outils fiables :

server.tool(
  "read_json_file",
  "Read and parse a JSON file",
  {
    path: z.string().describe("Path to the JSON file"),
  },
  async ({ path }) => {
    try {
      const { readFile } = await import("node:fs/promises");
      const content = await readFile(path, "utf-8");
      const parsed = JSON.parse(content);
 
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(parsed, null, 2),
          },
        ],
      };
    } catch (error) {
      if (error instanceof SyntaxError) {
        return {
          content: [{ type: "text", text: `Invalid JSON in file: ${path}` }],
          isError: true,
        };
      }
 
      const nodeError = error as NodeJS.ErrnoException;
      if (nodeError.code === "ENOENT") {
        return {
          content: [{ type: "text", text: `File not found: ${path}` }],
          isError: true,
        };
      }
 
      return {
        content: [
          {
            type: "text",
            text: `Error reading file: ${nodeError.message}`,
          },
        ],
        isError: true,
      };
    }
  }
);

Pratiques cles :

  • Retournez toujours un resultat, meme en cas d'erreur — ne lancez jamais d'exception depuis un handler d'outil
  • Definissez isError: true pour que l'IA sache que l'outil a echoue
  • Fournissez des messages d'erreur utiles pour que l'IA puisse se recuperer ou informer l'utilisateur
  • Loggez dans stderr pour le debogage : console.error("Debug:", someValue)

Depannage

Le serveur n'apparait pas dans Claude Desktop

  1. Verifiez le chemin du fichier de configuration et la syntaxe JSON
  2. Assurez-vous que le chemin absolu vers build/index.js est correct
  3. Redemarrez completement Claude Desktop (quittez et rouvrez)
  4. Verifiez les logs : ~/Library/Logs/Claude/mcp*.log sur macOS

"Could not connect to MCP server"

  1. Testez votre serveur directement : echo '{}' | node build/index.js — il ne doit pas planter
  2. Assurez-vous que #!/usr/bin/env node est en haut du fichier JS compile
  3. Rendez le fichier executable : chmod +x build/index.js

Les outils n'apparaissent pas

  1. Verifiez que les outils sont enregistres avant server.connect(transport)
  2. Verifiez les erreurs de compilation TypeScript : npm run build
  3. Utilisez le MCP Inspector pour verifier : npx @modelcontextprotocol/inspector node build/index.js

Conseils de debogage

Ajoutez de la journalisation de debogage basee sur l'environnement :

const DEBUG = process.env.MCP_DEBUG === "true";
 
function debug(...args: unknown[]) {
  if (DEBUG) console.error("[DEBUG]", ...args);
}
 
// Use in tool handlers:
debug("check_url called with:", url);

Executez avec le debogage :

MCP_DEBUG=true node build/index.js

Prochaines etapes

Maintenant que vous avez un serveur MCP fonctionnel, voici comment l'etendre :

  • Ajouter une integration base de donnees — Connectez-vous a PostgreSQL, SQLite ou MongoDB et exposez les requetes comme outils
  • Construire un transport HTTP — Deployez votre serveur comme API distante avec StreamableHTTPServerTransport
  • Publier sur npm — Partagez votre serveur avec la communaute via npx
  • Ajouter l'authentification — Implementez la validation de cle API pour les outils sensibles
  • Explorer l'ecosysteme — Parcourez les exemples de serveurs MCP sur GitHub pour vous inspirer

Tutoriels connexes


Conclusion

Vous avez construit un serveur MCP entierement fonctionnel qui expose des outils, des ressources et des prompts aux agents IA. Le Model Context Protocol devient rapidement le standard pour l'integration IA-outils, et savoir construire des serveurs vous place au coeur de cet ecosysteme.

Les points cles a retenir :

  1. Les outils permettent aux agents IA d'effectuer des actions — c'est la primitive la plus puissante
  2. Les ressources fournissent du contexte — des donnees que l'IA peut lire pour prendre de meilleures decisions
  3. Les prompts sont des modeles reutilisables — ils guident l'IA vers des workflows specifiques
  4. Le transport stdio est le standard pour les serveurs locaux — simple et fiable
  5. La gestion des erreurs est essentielle — retournez toujours des resultats, ne lancez jamais d'exceptions depuis les handlers

Commencez par un probleme reel : encapsulez une API que vous utilisez quotidiennement, exposez une base de donnees que vous interrogez souvent, ou creez des outils qui automatisent les workflows de votre equipe. Les meilleurs serveurs MCP resolvent des problemes specifiques et pratiques.


Vous voulez lire plus de tutoriels? Découvrez notre dernier tutoriel sur Détection et identification des maladies des feuilles de plantes avec YOLOv4.

Discutez de votre projet avec nous

Nous sommes ici pour vous aider avec vos besoins en développement Web. Planifiez un appel pour discuter de votre projet et comment nous pouvons vous aider.

Trouvons les meilleures solutions pour vos besoins.

Articles connexes

Construire un Agent IA Autonome avec Agentic RAG et Next.js

Apprenez a construire un agent IA qui decide de maniere autonome quand et comment recuperer des informations depuis des bases de donnees vectorielles. Un guide pratique complet avec Vercel AI SDK et Next.js, accompagne d'exemples executables.

30 min read·