openclaw / serpapi-mcp

Run SerpAPI searches via SerpAPI's MCP server using mcporter. Use when the user asks to search the web with SerpAPI/SerpAPI MCP, wants SerpAPI inside Clawdbot, or to use the /serp command.

0 views
0 installs

Skill Content

---
name: serpapi-mcp
description: Run SerpAPI searches via SerpAPI's MCP server using mcporter. Use when the user asks to search the web with SerpAPI/SerpAPI MCP, wants SerpAPI inside Clawdbot, or to use the /serp command.
---

# serpapi-mcp

A wrapper skill that calls **SerpAPI’s MCP server** (Model Context Protocol) via the **`mcporter`** CLI.

## What this skill provides

- Runs SerpAPI searches from OpenClaw via MCP (HTTP).
- Returns the full SerpAPI JSON to stdout (the primary contract).
- Optionally persists each query + response into **Airtable**:
  - raw JSON (full SerpAPI payload)
  - a structured “summary” (Top 10 organics, PAA/Related questions, videos, images, counts, flags)

## /serp usage

Treat this skill as providing the `/serp` command.

Syntax:
- `/serp <query>`
- `/serp <query> [engine] [num] [mode]`

Defaults:
- `engine=google_light`
- `num=5`
- `mode=compact`

Notes:
- If you want SERP features such as **People also ask (PAA)**, video packs, knowledge graph, etc., prefer:
  - `engine=google`
  - `mode=complete`

Examples:
- `/serp site:cnmv.es "educación financiera"`
- `/serp "AAPL stock" google 3 compact`
- `/serp "mortgage pay off vs invest" google 10 complete`

## How it works

Main script (prints JSON to stdout):
- `skills/serpapi-mcp/scripts/serp.sh "<query>" [engine] [num] [mode]`

It calls this MCP tool endpoint:
- `https://mcp.serpapi.com/$SERPAPI_API_KEY/mcp.search`

Optional Airtable logger:
- `skills/serpapi-mcp/scripts/airtable_log.mjs`

## Requirements

### 1) MCP client (`mcporter`)

This skill requires **`mcporter`** installed on the host.

Install:
- `npm install -g mcporter`

Verify:
- `mcporter --help`

### 2) SerpAPI key(s) + failover

You can configure either a single key or a failover pool:

- Single key:
  - `SERPAPI_API_KEY`
- Failover pool (comma-separated, tried in order):
  - `SERPAPI_API_KEYS`

Recommended placement (any of these is supported):
- Skill-scoped:
  - `skills.entries.serpapi-mcp.env.SERPAPI_API_KEY`
  - `skills.entries.serpapi-mcp.env.SERPAPI_API_KEYS`
- Global:
  - `env.vars.SERPAPI_API_KEY`
  - `env.vars.SERPAPI_API_KEYS`

Failover behavior:
- The script retries with the next key on common **quota / auth / rate-limit** errors (e.g. 429/401/403, “quota exceeded”, “rate limit”).
- For other errors (e.g. malformed request), it stops early and returns the error.

## Optional: store searches/results in Airtable

### Enable / disable

Enable logging:
- `SERP_LOG_AIRTABLE=1` (or `true`)

You can set this globally in the Gateway env (always on) or per-run when executing the script.

### Airtable configuration (Gateway env)

Set these environment variables (do not store secrets in the repo/workspace):
- `AIRTABLE_TOKEN` (Airtable Personal Access Token)
- `AIRTABLE_BASE_ID`
- `AIRTABLE_TABLE` (table name **or** table id)

### Write behavior & compatibility

- Airtable does **not** auto-create fields.
- The logger is **schema-aware**:
  - It reads the table schema via Airtable Metadata API.
  - It only writes fields that already exist in your table (by name).
  - It coerces values to the Airtable field type when possible (checkbox/number/text/select/date).

### Airtable table schema (recommended)

Field names must match exactly.

Core:
- `Query` → Single line text
- `Engine` → Single line text
- `Num` → Number (integer)
- `Mode` → Single line text
- `CreatedAt` → Date/Time

Provenance:
- `SerpApiSearchId` → Single line text
- `SerpApiJsonEndpoint` → URL
- `GoogleUrl` → URL

Raw payload:
- `ResultJson` → Long text
- `ResultJsonTruncatedFlag` → Checkbox
  - (Back-compat: the logger also supports `ResultJsonTruncated` if you prefer that name.)

Structured summary:
- `SummaryJson` → Long text
- `SummaryJsonTruncated` → Checkbox
- `OrganicTop10Json` → Long text
- `RelatedQuestionsTop10Json` → Long text
- `ShortVideosTop10Json` → Long text
- `VideosTop10Json` → Long text
- `ImagesTop10Json` → Long text

Flags + counts:
- `HasAiOverview` → Checkbox
- `HasAnswerBox` → Checkbox
- `HasKnowledgeGraph` → Checkbox
- `OrganicCount` → Number (integer)
- `RelatedQuestionsCount` → Number (integer)
- `ShortVideosCount` → Number (integer)
- `VideosCount` → Number (integer)
- `ImagesCount` → Number (integer)

### Airtable size limits

Airtable has per-cell size limits. The logger truncates JSON strings if needed:
- `AIRTABLE_MAX_JSON_CHARS` (default: 90000)
- `AIRTABLE_MAX_SUMMARY_CHARS` (default: 90000)

## Output

Returns SerpAPI JSON. Depending on engine and what Google shows, the payload may include keys like:
- `organic_results`
- `short_videos` / `videos_results`
- `images_results`
- `related_questions`
- `knowledge_graph`
- `answer_box` / `ai_overview`
- ads blocks (`top_ads`, `bottom_ads`, etc.)