Le Model Context Protocol permet aux agents IA d'appeler des outils externes via une interface standardisée. Créer un serveur MCP personnalisé adossé à l'API Scavio vous donne un contrôle total sur les définitions d'outils, le formatage des réponses et la limitation de débit, tout en maintenant la compatibilité avec tout client MCP (Cursor, Claude Desktop, agents personnalisés). Ce tutoriel construit un serveur MCP Node.js avec des outils de recherche et d'extraction.
Prérequis
- Node.js 18+
- npm ou pnpm
- Une clé API Scavio depuis scavio.dev
- Familiarité de base avec le protocole MCP
Parcours
Étape 1: Configurer le projet de serveur MCP
Initialisez le projet avec le SDK MCP et les dépendances HTTP.
# Create project
mkdir scavio-mcp-server && cd scavio-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
# Project structure:
# scavio-mcp-server/
# index.js
# package.json
# package.json - add type module:
# { "type": "module", "main": "index.js" }Étape 2: Implémenter le serveur MCP avec l'outil de recherche
Créez le serveur MCP avec un outil de recherche qui appelle l'API Scavio.
// index.js
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const API_KEY = process.env.SCAVIO_API_KEY;
const SH = { 'x-api-key': API_KEY, 'Content-Type': 'application/json' };
const server = new McpServer({ name: 'scavio-search', version: '1.0.0' });
server.tool('search',
{ query: { type: 'string', description: 'Search query' },
platform: { type: 'string', description: 'Platform: google, reddit, youtube, amazon, walmart', default: 'google' },
country: { type: 'string', description: 'Country code', default: 'us' } },
async ({ query, platform, country }) => {
const body = { query, country_code: country || 'us' };
if (platform && platform !== 'google') body.platform = platform;
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH, body: JSON.stringify(body)
});
const data = await r.json();
const results = (data.organic_results || []).slice(0, 5)
.map(r => `${r.position}. ${r.title}\n ${r.link}\n ${(r.snippet || '').slice(0, 120)}`).join('\n\n');
return { content: [{ type: 'text', text: results || 'No results found.' }] };
}
);
console.error('Scavio MCP server starting...');Étape 3: Ajouter l'outil d'extraction
Ajoutez un outil d'extraction de contenu d'URL au serveur MCP.
// Add after the search tool definition:
server.tool('extract',
{ url: { type: 'string', description: 'URL to extract content from' } },
async ({ url }) => {
const r = await fetch('https://api.scavio.dev/api/v1/extract', {
method: 'POST', headers: SH, body: JSON.stringify({ url })
});
const data = await r.json();
const content = data.content || data.text || JSON.stringify(data);
return { content: [{ type: 'text', text: content.slice(0, 2000) }] };
}
);
// List available tools for debugging:
server.tool('list_platforms',
{},
async () => {
const platforms = ['google', 'youtube', 'amazon', 'walmart', 'reddit'];
const text = platforms.map(p => `- ${p}: Search ${p} results via Scavio API`).join('\n');
return { content: [{ type: 'text', text: `Available search platforms:\n${text}\n\nCost: $0.005 per search` }] };
}
);Étape 4: Démarrer le serveur et configurer les clients
Lancez le serveur MCP et connectez-le à Cursor ou Claude Desktop.
// Add at the end of index.js:
const transport = new StdioServerTransport();
await server.connect(transport);
// Run the server:
// SCAVIO_API_KEY=your_key node index.js
// Configure in Cursor (~/.cursor/mcp.json):
// {
// "mcpServers": {
// "scavio-custom": {
// "command": "node",
// "args": ["/path/to/scavio-mcp-server/index.js"],
// "env": { "SCAVIO_API_KEY": "your_key" }
// }
// }
// }
// Or in Claude Desktop (claude_desktop_config.json):
// {
// "mcpServers": {
// "scavio-custom": {
// "command": "node",
// "args": ["/path/to/scavio-mcp-server/index.js"],
// "env": { "SCAVIO_API_KEY": "your_key" }
// }
// }
// }Exemple Python
# Python MCP server alternative:
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def search(query, platform=None):
body = {'query': query, 'country_code': 'us'}
if platform: body['platform'] = platform
data = requests.post('https://api.scavio.dev/api/v1/search',
headers=SH, json=body).json()
for r in data.get('organic_results', [])[:3]:
print(f'{r["position"]}. {r["title"][:50]}')
search('mcp server tutorial')Exemple JavaScript
// Test the MCP server tools directly:
const API_KEY = process.env.SCAVIO_API_KEY;
const SH = { 'x-api-key': API_KEY, 'Content-Type': 'application/json' };
async function testSearch(query, platform) {
const body = { query, country_code: 'us' };
if (platform) body.platform = platform;
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: SH, body: JSON.stringify(body)
}).then(r => r.json());
(data.organic_results || []).slice(0, 3).forEach(r =>
console.log(`${r.position}. ${r.title.slice(0, 50)}`)
);
}
await testSearch('mcp server tutorial');Sortie attendue
Scavio MCP server starting...
# In Cursor after configuration:
Cursor Settings > MCP:
scavio-custom: Connected (3 tools)
# Tools available:
- search: Multi-platform web search
- extract: URL content extraction
- list_platforms: Show available platforms
# Test query in Cursor Composer:
User: Search Reddit for MCP server best practices
Agent: [Calling scavio-custom.search with platform='reddit']
1. Building MCP Servers - Best Practices for 2026
https://reddit.com/r/...
Here are the key patterns I've found...
Cost per search: $0.005