The Model Context Protocol (MCP) lets AI assistants like Claude invoke external tools through a standardized interface. While Scavio provides an official MCP server, you may want to add web search as one tool among many in your own custom MCP server. This tutorial shows how to build an MCP server tool that wraps the Scavio API, register it in your server's tool list, and handle incoming search requests from any MCP client.
Prerequisites
- Node.js 18 or higher
- npm install @modelcontextprotocol/sdk
- A Scavio API key
- Basic TypeScript knowledge
Walkthrough
Step 1: Initialize the MCP server
Create a new MCP server using the official SDK. This server will expose your custom tools to any MCP client.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "my-tools",
version: "1.0.0",
});Step 2: Register the web search tool
Define a web_search tool that accepts a query and optional platform parameter. The handler calls the Scavio API and returns formatted results.
const SCAVIO_KEY = process.env.SCAVIO_API_KEY!;
server.tool(
"web_search",
"Search the web for current information. Returns top results with titles, snippets, and URLs.",
{
query: z.string().describe("The search query"),
platform: z.enum(["google", "youtube", "amazon", "walmart", "reddit"]).default("google").describe("Search platform"),
},
async ({ query, platform }) => {
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: { "x-api-key": SCAVIO_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ platform, query, country_code: "us" }),
});
const data = await res.json();
const results = data.organic_results || data.products || data.videos || [];
const text = results.slice(0, 5).map((r: any, i: number) =>
`[${i + 1}] ${r.title || r.name}\n${r.snippet || r.description || ""}\n${r.link || r.url || ""}`
).join("\n\n");
return { content: [{ type: "text", text }] };
}
);Step 3: Start the server
Connect the server to stdio transport so MCP clients can communicate with it.
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main();Step 4: Configure in Claude Desktop
Point Claude Desktop to your custom MCP server binary so it can use the web_search tool.
{
"mcpServers": {
"my-tools": {
"command": "npx",
"args": ["tsx", "server.ts"],
"env": {
"SCAVIO_API_KEY": "your_scavio_api_key"
}
}
}
}Python Example
# Python MCP server with Scavio web search tool
import os
import json
import sys
import requests
SCAVIO_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
def handle_search(query: str, platform: str = "google") -> str:
r = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": SCAVIO_KEY},
json={"platform": platform, "query": query, "country_code": "us"}
)
r.raise_for_status()
data = r.json()
results = data.get("organic_results", data.get("products", []))[:5]
return "\n\n".join(
f"[{i+1}] {r.get('title', '')}\n{r.get('snippet', '')}\n{r.get('link', '')}"
for i, r in enumerate(results)
)
# This is a simplified example. Use the mcp Python SDK for production.
if __name__ == "__main__":
result = handle_search("latest AI news 2026")
print(result)JavaScript Example
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "my-tools", version: "1.0.0" });
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
server.tool(
"web_search",
"Search the web for current information",
{ query: z.string(), platform: z.enum(["google", "youtube", "amazon", "walmart", "reddit"]).default("google") },
async ({ query, platform }) => {
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: { "x-api-key": SCAVIO_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ platform, query, country_code: "us" }),
});
const data = await res.json();
const results = (data.organic_results || data.products || []).slice(0, 5);
const text = results.map((r, i) => `[${i+1}] ${r.title}\n${r.snippet || ""}\n${r.link || ""}`).join("\n\n");
return { content: [{ type: "text", text }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);Expected Output
MCP server started on stdio
Tool: web_search
Input: {"query": "latest AI news", "platform": "google"}
[1] OpenAI Launches New Agent Platform
OpenAI announced a comprehensive agent building platform...
https://example.com/openai-agents
[2] Anthropic Claude 4 Release Details
Anthropic released Claude 4 with expanded context...
https://example.com/claude-4