Tutorial

How to Build a Custom MCP Search Server

Build a custom MCP server backed by Scavio API with search and extract tools. Node.js implementation compatible with any MCP client.

The Model Context Protocol lets AI agents call external tools through a standardized interface. Building a custom MCP server backed by Scavio API gives you full control over tool definitions, response formatting, and rate limiting while maintaining compatibility with any MCP client (Cursor, Claude Desktop, custom agents). This tutorial builds a Node.js MCP server with search and extract tools.

Prerequisites

  • Node.js 18+
  • npm or pnpm
  • A Scavio API key from scavio.dev
  • Basic familiarity with MCP protocol

Walkthrough

Step 1: Set up the MCP server project

Initialize the project with MCP SDK and HTTP dependencies.

Bash
# 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" }

Step 2: Implement the MCP server with search tool

Create the MCP server with a search tool that calls Scavio API.

JavaScript
// 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...');

Step 3: Add the extract tool

Add a URL content extraction tool to the MCP server.

JavaScript
// 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` }] };
  }
);

Step 4: Start the server and configure clients

Launch the MCP server and connect it to Cursor or Claude Desktop.

Bash
// 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" }
//     }
//   }
// }

Python Example

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')

JavaScript Example

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');

Expected Output

JSON
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

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Node.js 18+. npm or pnpm. A Scavio API key from scavio.dev. Basic familiarity with MCP protocol. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Build a custom MCP server backed by Scavio API with search and extract tools. Node.js implementation compatible with any MCP client.