DEV Community

dodou
dodou

Posted on

serpbase MCP Integration: From Zero to AI Agent Tool in 5 Minutes

Background

MCP (Model Context Protocol) is the AI agent tool standard launched by Anthropic in 2025. Claude Desktop / Cursor / Cline all support it. serpbase provides an official MCP server, so in 5 minutes any AI agent can call SERP as a tool.

1. Setup

# Official MCP server repo
git clone https://github.com/serpbase-dev/serpbase-mcp
cd serpbase-mcp
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode
export SERPBASE_KEY="sk_your_key"
Enter fullscreen mode Exit fullscreen mode

2. Claude Desktop Integration (5 minutes)

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "serpbase": {
      "command": "python",
      "args": ["-m", "serpbase_mcp"],
      "env": {
        "SERPBASE_KEY": "sk_your_key"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Claude Desktop. MCP tools auto-load. You should see 6 tools:

  • search_google
  • search_images
  • search_news
  • search_videos
  • search_maps
  • search_maps_detail

3. Cursor Integration

~/.cursor/mcp.json:

{
  "mcpServers": {
    "serpbase": {
      "command": "python",
      "args": ["-m", "serpbase_mcp"],
      "env": {
        "SERPBASE_KEY": "sk_your_key"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Cursor.

4. Cline (VSCode) Integration

VSCode settings.json:

{
  "mcp.servers": {
    "serpbase": {
      "command": "python",
      "args": ["-m", "serpbase_mcp"],
      "env": {
        "SERPBASE_KEY": "sk_your_key"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Custom MCP Client

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def use_serp_mcp():
    server_params = StdioServerParameters(
        command="python",
        args=["-m", "serpbase_mcp"],
        env={"SERPBASE_KEY": "sk_your_key"},
    )

    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            tools = await session.list_tools()
            print("Tools:", [t.name for t in tools.tools])

            result = await session.call_tool(
                "search_google",
                {"q": "best serp api", "gl": "us", "num": 5},
            )
            print("Result:", result.content)

            maps = await session.call_tool(
                "search_maps",
                {"q": "coffee shop", "lat": 37.77, "lng": -122.42},
            )
            print("Maps:", maps.content)
Enter fullscreen mode Exit fullscreen mode

6. 5 Engineering Details

Detail 1: Tool Schema Optimization

def search_google(
    query: str,
    gl: str = "us",
    hl: str = "en",
    num: int = 5,
) -> dict:
    """Search Google for current information.

    Use this tool when the user asks about:
    - Recent events (last 6 months)
    - Current pricing or statistics
    - Specific companies / products

    Returns top 5 organic search results.
    """
    r = requests.post(...)
    return r.json()
Enter fullscreen mode Exit fullscreen mode

LLM relies on the schema to decide when to call.

Detail 2: Tool Error Handling

def search_with_error_handling(query):
    try:
        return call_serpbase(query)
    except requests.exceptions.Timeout:
        return {"error": "SERP timeout, try again"}
    except Exception as e:
        return {"error": str(e)}
Enter fullscreen mode Exit fullscreen mode

Return error dict instead of raising exception. LLM sees errors and can retry.

Detail 3: Token Limit (Response Truncation)

def search_google(query, num=5):
    data = call_serpbase(query, num=num)
    data["organic"] = data.get("organic", [])[:num]
    return data
Enter fullscreen mode Exit fullscreen mode

Detail 4: Input Validation

def search_google(query: str, gl: str = "us", num: int = 5):
    if len(query) > 200:
        return {"error": "Query too long, max 200 chars"}
    if gl not in ["us", "cn", "uk", "jp", "de", "fr"]:
        return {"error": f"Invalid gl: {gl}"}
    if num < 1 or num > 20:
        return {"error": f"Invalid num: {num}, range 1-20"}
    # ...
Enter fullscreen mode Exit fullscreen mode

Detail 5: Tool Call Logging

import logging
logging.basicConfig(level=logging.INFO)

def search_google(query):
    logging.info(f"search_google called: query={query}")
    data = call_serpbase(query)
    logging.info(f"search_google returned: organic_count={len(data.get('organic', []))}")
    return data
Enter fullscreen mode Exit fullscreen mode

7. Testing & Debugging

import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def test_serp_mcp():
    server_params = StdioServerParameters(
        command="python",
        args=["-m", "serpbase_mcp"],
        env={"SERPBASE_KEY": "sk_test_key"},
    )

    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            assert "search_google" in [t.name for t in tools.tools]

            result = await session.call_tool("search_google", {"q": "test"})
            assert result.content is not None

asyncio.run(test_serp_mcp())
Enter fullscreen mode Exit fullscreen mode

8. 5 Best Practices

  1. Tool description describes usage scenario (LLM decision basis)
  2. Errors return JSON, don't raise exceptions
  3. Response truncated to 2k tokens (avoid LLM context explosion)
  4. Input parameter validation (gl / num range)
  5. Tool call logging (debugging essential)

Summary

serpbase MCP integration in 5 minutes:

  • Install MCP server
  • Configure Claude/Cursor/Cline (20 lines of JSON)
  • Tools auto-load to LLM
  • Real calls

serpbase's 1.4s P50 + auto-refund + 6 endpoints in MCP scenarios gives LLM high decision accuracy. 1 month, 3,200 calls, $0.96, zero engineer maintenance.

Top comments (0)