Associer Agents IA et MCP pour accéder au monde extérieur
Fait partie de la série Agents IA et serveur MCP au service du web agentique
Notre serveur MCP est prêt, mais l'Agent ne sait toujours pas qu'il existe. L'étape suivante consiste à donner à l'Agent un client MCP capable de découvrir les outils du serveur et de les rendre disponibles au modèle.
Lorsque nous avons testé le serveur manuellement, l'Inspector MCP a utilisé List Tools pour récupérer les outils disponibles. L'AI SDK peut faire la même chose par programmation : il se connecte au serveur, liste les outils et les adapte à l'interface utilisée par streamText.
Avant cela, nous devons ajouter une configuration d'exécution Nitro pour indiquer l'URL du MCP.
import { defineNitroConfig } from 'nitropack/config'
export default defineNitroConfig({
runtimeConfig: {
openAiApiKey: '',
mcpEndpoint: '',
},
// ...
})Dans votre fichier .env, définissez la variable MCP_ENDPOINT avec l'URL du MCP :
MCP_ENDPOINT=http://localhost:3000/mcpNous pouvons alors connecter notre Agent IA au serveur MCP. Le client est créé pour la requête, récupère les outils disponibles et reste ouvert jusqu'à la fin de la réponse diffusée.
import { createOpenAI } from '@ai-sdk/openai'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
import { convertToModelMessages, experimental_createMCPClient, stepCountIs, streamText } from 'ai'
import { defineEventHandler, defineLazyEventHandler, readBody } from 'h3'
import { useRuntimeConfig } from 'nitropack/runtime'
export default defineLazyEventHandler(() => {
const runtimeConfig = useRuntimeConfig()
const model = createOpenAI({
apiKey: runtimeConfig.openAiApiKey,
})
return defineEventHandler(async (event) => {
const { messages } = await readBody(event)
const httpTransport = new StreamableHTTPClientTransport(
new URL(runtimeConfig.mcpEndpoint)
)
const httpClient = await experimental_createMCPClient({
transport: httpTransport
})
const tools = await httpClient.tools()
const result = streamText({
model: model('gpt-5-nano'),
system: `You are a helpful assistant. You can use the tool to add two numbers together.`,
stopWhen: stepCountIs(2),
tools,
messages: convertToModelMessages(messages),
onFinish: () => httpClient.close(),
onAbort: () => httpClient.close(),
})
return result.toUIMessageStreamResponse()
})
})La ligne la plus importante est const tools = await httpClient.tools(). Comme l'action List Tools de l'Inspector, elle récupère les outils exposés par le serveur MCP. Les transmettre à streamText les rend disponibles au modèle. Lorsque le modèle en demande un, experimental_createMCPClient utilise le transport HTTP pour appeler le serveur MCP pour le compte de l'Agent.
Note
Le client MCP utilise le transport Streamable HTTP pour échanger des messages de protocole avec le serveur MCP. Le fermer dans onFinish ou onAbort le maintient disponible pendant la diffusion de la réponse, puis libère ses ressources.
Pour l'utilisateur, l'Agent se comporte exactement comme avec un outil direct. D'un point de vue architectural, il consomme toutefois maintenant une capacité standardisée fournie par un serveur distinct.
L'Agent peut désormais utiliser un outil sans savoir comment il est implémenté. Nous pouvons faire évoluer le serveur MCP indépendamment, laisser des clients compatibles l'utiliser ou connecter l'Agent à un autre serveur MCP lorsqu'il a besoin de capacités supplémentaires. Dans l'article suivant, nous ajouterons une interface de chat pour que les utilisateurs puissent interagir directement avec l'Agent.
Merci de me lire ! Je m'appelle Estéban, et j'adore écrire sur le développement web et le parcours humain qui l'entoure.
Je code depuis plusieurs années maintenant, et j'apprends encore de nouvelles choses chaque jour. J'aime partager mes connaissances avec les autres, car j'aurais aimé avoir accès à des ressources aussi claires et complètes lorsque j'ai commencé à apprendre la programmation.
Si vous avez des questions ou souhaitez discuter, n'hésitez pas à commenter ci-dessous ou à me contacter sur Bluesky, X, et LinkedIn.
J'espère que vous avez apprécié cet article et appris quelque chose de nouveau. N'hésitez pas à le partager avec vos amis ou sur les réseaux sociaux, et laissez un commentaire ou une réaction ci-dessous, cela me ferait très plaisir ! Si vous souhaitez soutenir mon travail, vous pouvez me sponsoriser sur GitHub !
Discussions
Ajouter un commentaire
Vous devez être connecté pour accéder à cette fonctionnalité.