Le Model Context Protocol (MCP) permet aux agents IA d'appeler des outils externes via une interface standardisée. Un agent MCP multi-outils peut combiner recherche web, accès au système de fichiers, requêtes de base de données et API personnalisées en une seule conversation. Ce tutoriel construit un agent MCP avec un outil de recherche basé sur l'API Scavio, un outil de fichier et une calculatrice. Le modèle s'adapte à n'importe quel nombre d'outils. Les appels de recherche coûtent 0,005 $ chacun via Scavio.
Prérequis
- Python 3.10+ installé
- Paquet mcp installé (pip install mcp)
- Une clé API Scavio depuis scavio.dev
- Compréhension de base des modèles d'utilisation d'outils
Parcours
Étape 1: Définir le serveur d'outil de recherche MCP
Créez un serveur d'outil MCP qui expose une fonction web_search. Ce serveur gère l'appel API et retourne des résultats structurés à l'agent.
from mcp.server import Server
from mcp.types import Tool, TextContent
import requests, os, json
server = Server('search-tools')
API_KEY = os.environ['SCAVIO_API_KEY']
@server.tool()
async def web_search(query: str, country: str = 'us') -> str:
"""Search the web for current information."""
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': country})
results = resp.json().get('organic_results', [])[:5]
return json.dumps([{'title': r['title'], 'url': r['link'],
'snippet': r.get('snippet', '')} for r in results], indent=2)Étape 2: Ajouter un outil de recherche TikTok au même serveur
Ajoutez un second outil qui recherche sur TikTok. Les deux outils partagent le même serveur MCP, donc l'agent peut utiliser l'un ou l'autre en une seule session.
@server.tool()
async def tiktok_search(keyword: str, count: int = 10) -> str:
"""Search TikTok for videos about a topic."""
resp = requests.post('https://api.scavio.dev/api/v1/tiktok/search/videos',
headers={'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'},
json={'keyword': keyword, 'count': count, 'cursor': 0})
videos = resp.json().get('data', {}).get('videos', [])
return json.dumps([{'author': v.get('author', {}).get('nickname', ''),
'desc': v.get('desc', ''), 'plays': v.get('stats', {}).get('playCount', 0)}
for v in videos], indent=2)Étape 3: Ajouter une calculatrice et un outil de lecture de fichier
Montrez le modèle multi-outils en ajoutant des outils non liés à la recherche. L'agent décide quel outil utiliser en fonction de la requête de l'utilisateur.
import math
@server.tool()
async def calculate(expression: str) -> str:
"""Evaluate a mathematical expression safely."""
allowed = set('0123456789+-*/.() ')
if not all(c in allowed for c in expression):
return 'Error: only numeric expressions allowed'
try:
result = eval(expression)
return str(result)
except Exception as e:
return f'Error: {e}'
@server.tool()
async def read_file(path: str) -> str:
"""Read a local text file."""
try:
with open(path, 'r') as f:
content = f.read(10000) # limit to 10KB
return content
except FileNotFoundError:
return f'File not found: {path}'Étape 4: Configurer le manifeste du serveur MCP
Créez le fichier de configuration .mcp.json qui indique au client MCP où trouver votre serveur d'outils et quels outils sont disponibles.
// .mcp.json
{
"mcpServers": {
"search-tools": {
"command": "python",
"args": ["search_tools_server.py"],
"env": {
"SCAVIO_API_KEY": "your_scavio_api_key"
}
}
}
}
// The server exposes: web_search, tiktok_search, calculate, read_fileÉtape 5: Exécuter le serveur MCP
Démarrez le serveur avec le transport stdio. Tout client compatible MCP (Claude Desktop, Cursor, agents personnalisés) peut maintenant se connecter et utiliser les quatre outils.
import asyncio
from mcp.server.stdio import stdio_server
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
if __name__ == '__main__':
asyncio.run(main())
# Test manually:
# echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | python search_tools_server.py
# Should list: web_search, tiktok_search, calculate, read_fileExemple Python
from mcp.server import Server
from mcp.server.stdio import stdio_server
import requests, os, json, asyncio
server = Server('search-tools')
API_KEY = os.environ['SCAVIO_API_KEY']
@server.tool()
async def web_search(query: str, country: str = 'us') -> str:
"""Search the web for current information."""
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': country})
results = resp.json().get('organic_results', [])[:5]
return json.dumps([{'title': r['title'], 'snippet': r.get('snippet', '')} for r in results])
@server.tool()
async def tiktok_search(keyword: str, count: int = 10) -> str:
"""Search TikTok videos."""
resp = requests.post('https://api.scavio.dev/api/v1/tiktok/search/videos',
headers={'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'},
json={'keyword': keyword, 'count': count, 'cursor': 0})
return json.dumps(resp.json().get('data', {}).get('videos', [])[:5])
async def main():
async with stdio_server() as (read, write):
await server.run(read, write)
if __name__ == '__main__':
asyncio.run(main())Exemple JavaScript
// MCP servers are typically Python; this shows a JS HTTP wrapper
const API_KEY = process.env.SCAVIO_API_KEY;
const tools = {
async web_search({ query, country = 'us' }) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, country_code: country })
});
const data = await resp.json();
return (data.organic_results || []).slice(0, 5)
.map(r => ({ title: r.title, snippet: r.snippet || '' }));
},
async tiktok_search({ keyword, count = 10 }) {
const resp = await fetch('https://api.scavio.dev/api/v1/tiktok/search/videos', {
method: 'POST',
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ keyword, count, cursor: 0 })
});
return (await resp.json()).data?.videos || [];
}
};
async function main() {
const results = await tools.web_search({ query: 'MCP protocol 2026' });
console.log(JSON.stringify(results, null, 2));
}
main().catch(console.error);Sortie attendue
Available tools:
- web_search: Search the web for current information
- tiktok_search: Search TikTok for videos about a topic
- calculate: Evaluate a mathematical expression
- read_file: Read a local text file
[
{"title": "MCP Protocol Documentation", "snippet": "The Model Context Protocol..."}
{"title": "Building MCP Agents in 2026", "snippet": "A guide to creating..."}
]
Cost: $0.005 per web_search call, $0.005 per tiktok_search call