Tutorial

How to Add a Web Search Tool to Your Own MCP Server

Build a custom MCP server tool that wraps the Scavio API. Give any MCP-compatible AI assistant access to live web search in under 30 lines of TypeScript.

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.

JSON
{
  "mcpServers": {
    "my-tools": {
      "command": "npx",
      "args": ["tsx", "server.ts"],
      "env": {
        "SCAVIO_API_KEY": "your_scavio_api_key"
      }
    }
  }
}

Python Example

Python
# 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

JavaScript
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

JSON
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

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 or higher. npm install @modelcontextprotocol/sdk. A Scavio API key. Basic TypeScript knowledge. A Scavio API key gives you 500 free credits per month.

Yes. The free tier includes 500 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 tool that wraps the Scavio API. Give any MCP-compatible AI assistant access to live web search in under 30 lines of TypeScript.