GrokSearch Rs logo

GrokSearch Rs

Community
Episkey-G

Rust MCP server for Grok web search and Tavily-backed source retrieval

PublisherEpiskey-G
RepositoryGrokSearch-rs
LanguageRust
Forks
47
Stars
451
Available tools
0
Transport typestdio
Categories
LicenseMIT
Links
  • Connect tools to AI workflows

    GrokSearch Rs exposes MCP capabilities that can be used by compatible AI clients and agents.

  • 0 available tools

    Browse the callable actions below, including names and descriptions when provided by the server.

  • Ready-to-copy setup

    Use the installation snippets to configure this server in your preferred MCP client.

  • Open source signals

    451 stars and 47 forks from the linked repository.

GrokSearch-rs

GrokSearch-rs product banner

A lightweight Rust MCP server for Grok / OpenAI‑compatible web search, backed by an ordered source chain — Tavily, Exa, TinyFish, Firecrawl — for supplemental sources, fetch, and map.

grok-search-rs is an MCP server — run it locally over stdio (your client launches it; you do not run it directly) or as a remote Streamable HTTP service for mobile / multi‑device access (see self-hosting). It exposes one set of tools (web_search, get_sources, web_fetch, web_map, doctor) and supports two upstream transports so you can plug into either xAI's official API or any OpenAI‑compatible relay.


Features

  • 🔎 Live web search with cited sources, cached for follow‑up get_sources calls. Opt‑in include_content enriches the top sources with full extracted text in one call.
  • 📏 Response budgeting — web_search keeps responses inside agent context limits: only the top max_inline_sources carry inline text, a whole‑response char budget (response_max_chars, default 45k — sized to stay under the MCP client token ceiling after JSON serialization) trims tail sources with recovery notes, response_format: "concise" | "detailed" picks the payload size, and get_sources pages through cached sources with offset/limit. The session cache always keeps full content.
  • 🧩 Structured web_fetch — GitHub issues/PRs/releases, StackExchange/MathOverflow, arXiv, and Wikipedia URLs are parsed by specialist extractors into clean Markdown (title, state/labels, release notes, accepted‑answer ordering, abstracts, vote‑sorted answers). Specialist extractors need no API key. Anything else falls back to the generic source chain (Tavily → Exa → TinyFish → Firecrawl, as configured) — so with no source provider configured, ordinary URLs cannot be fetched at all, only the specialist families above. Output carries source_type and a fallback_reason when a specialist was skipped.
  • 🔀 Two transports — native xAI Responses (/v1/responses) or any OpenAI‑compatible chat‑completions gateway (/v1/chat/completions). Pick by env vars; no flag.
  • 🔐 Optional Grok OAuth mode — login/status/logout commands store a local xAI OAuth token for Responses auth, so the MCP server can run without GROK_SEARCH_API_KEY.
  • 🌐 Optional remote mode — build with --features http to serve the same tools over Streamable HTTP (multi‑tenant, bring‑your‑own‑key via request headers) for mobile / multi‑device access. See self-hosting.
  • 📥 Pluggable source chain — supplemental sources and generic fetch walk an ordered provider chain: Tavily (RAG‑tuned search + extract + map), Exa (semantic search, native domain/date filters), TinyFish (free search + JS‑rendering fetch), Firecrawl (robust scrape fallback). First provider with results wins; GROK_SEARCH_SOURCE_PROVIDERS reorders. TAVILY_API_KEY accepts a comma‑separated key list — keys rotate round‑robin with automatic failover on rate/quota errors.
  • 🐦 Optional X/Twitter search via x_search (Responses transport only).
  • 🚦 Concurrent stdio requests — up to 8 tool calls are handled at once; anything beyond that queues rather than being refused. Responses come back in completion order, paired to requests by JSON‑RPC id.
  • 🩺 doctor — connectivity probe + redacted config in one tool call, including whether your config file was found, loaded, or rejected (and why).
  • 🗂 Single global config file so multiple MCP clients share one set of keys.

Install

bash
npm install -g grok-search-rs

The npm package ships a native Rust binary; the grok-search-rs command is what your MCP client launches.


Quick Start

Option A — use the hosted instance (no install). Point any MCP client that supports remote HTTP + custom headers at the public endpoint and pass your own keys as headers:

bash
claude mcp add --transport http grok-search https://mcp.episkeyai.com/groksearch_rs/mcp \
  --header "X-Grok-Api-Key: xai-..." \
  --header "X-Tavily-Api-Key: tvly-..."

The default gateway is xAI official (api.x.ai) — use an xAI key. For any other Grok‑compatible gateway, add --header "X-Grok-Base-Url: https://your-gateway.example/v1" with a matching key, and optionally --header "X-Grok-Model: <model>" (model ids are gateway‑specific). No keys are stored server-side; best-effort availability. Prefer your own server? See self-hosting.

Option B — install locally (stdio).

  1. After npm install -g grok-search-rs, add this MCP server entry to your client config:

    json
    {
      "grok-search-rs": {
        "command": "grok-search-rs",
        "args": [],
        "env": {
          "GROK_SEARCH_API_KEY": "",
          "GROK_SEARCH_URL": "",
          "GROK_SEARCH_MODEL": "grok-4.20-fast",
          "TAVILY_API_KEY": "",
          "TAVILY_API_URL": "https://api.tavily.com",
          "FIRECRAWL_API_KEY": ""
        }
      }
    }

    For Codex TOML config:

    toml
    [mcp_servers.grok-search-rs]
    type = "stdio"
    command = "grok-search-rs"
    
    [mcp_servers.grok-search-rs.env]
    FIRECRAWL_API_KEY = ""
    GROK_SEARCH_API_KEY = ""
    GROK_SEARCH_MODEL = "grok-4.20-fast"
    GROK_SEARCH_URL = ""
    TAVILY_API_KEY = ""
    TAVILY_API_URL = "https://api.tavily.com"

    Put your real keys in the empty values. If your client expects a top-level mcpServers / mcp_servers object, place the grok-search-rs entry under that section.

  2. Optional: scaffold a shared global config file instead of duplicating env blocks in every MCP client:

    bash
    grok-search-rs --init
    $EDITOR ~/.config/grok-search-rs/config.toml
  3. Verify:

    text
    Ask your assistant: "call doctor"

    Successful output shows reachable: true for each enabled upstream and transport: Responses (or ChatCompletions).


Configuration

The MCP transport decides how config reaches the server — same values, different channel (forced by the transport, not a project setting):

  • stdio (local): environment variables — the env block in your MCP client config.
  • remote HTTP: per-request HTTP headers — the server stores no keys.
Settingstdio envremote header
Grok API keyGROK_SEARCH_API_KEYX-Grok-Api-Key
Grok gateway URLGROK_SEARCH_URLX-Grok-Base-Url
Grok modelGROK_SEARCH_MODELX-Grok-Model
Tavily API keyTAVILY_API_KEYX-Tavily-Api-Key
Firecrawl API keyFIRECRAWL_API_KEYX-Firecrawl-Api-Key
TinyFish API keyTINYFISH_API_KEYX-Tinyfish-Api-Key
Exa API keyEXA_API_KEYX-Exa-Api-Key
GitHub tokenGITHUB_TOKENX-GitHub-Token

The tables below use env-key names (they also drive config.toml / stdio); on the remote transport send the header from the row above. Full reference and per-transport examples: docs/CONFIGURATION.md. All source-provider keys (Tavily / Exa / TinyFish / Firecrawl) are shared across transports.

A. Native Grok Responses (default)

VariableDefaultPurpose
GROK_SEARCH_AUTH_MODEapi_keyapi_key uses GROK_SEARCH_API_KEY; oauth uses the local token from grok-search-rs login.
GROK_SEARCH_API_KEY— (required in api_key mode)Bearer token for the Grok / xAI gateway.
GROK_SEARCH_AUTH_FILE<home>/.config/grok-search-rs/auth.jsonOptional OAuth token file override.
GROK_SEARCH_URLhttps://api.x.aiRoot, /v1, or full‑endpoint URL.
GROK_SEARCH_MODELgrok-4-1-fast-reasoningModel name.
GROK_SEARCH_WEB_SEARCHtrueOffer web_search tool to Grok.
GROK_SEARCH_X_SEARCHfalseOffer x_search tool (X/Twitter) to Grok.

Verified upstream: xAI (https://api.x.ai, both tools). Other Grok‑compatible gateways work with a matching key; x_search availability depends on the gateway.

OAuth mode is a single-binary flow:

bash
grok-search-rs login
grok-search-rs status
grok-search-rs logout

Then configure your MCP client with:

toml
[mcp_servers.grok-search-rs]
command = "grok-search-rs"

[mcp_servers.grok-search-rs.env]
GROK_SEARCH_AUTH_MODE = "oauth"
GROK_SEARCH_MODEL = "grok-4.3"
GROK_SEARCH_WEB_SEARCH = "true"

OAuth mode reuses Hermes' xAI OAuth client id and stores auth.json locally. That may violate xAI terms or affect your account; do not share the token file. If xAI changes or blocks that OAuth flow, switch back to api_key mode.

B. OpenAI‑compatible chat/completions

Activate by setting the URL and key while leaving GROK_SEARCH_API_KEY unset. Suitable for any OpenAI‑compatible relay (one‑api, vLLM, LiteLLM, marybrown, Perplexity‑style gateways, etc.).

VariableDefaultPurpose
OPENAI_COMPATIBLE_API_URL—Root, /v1, or full‑endpoint URL.
OPENAI_COMPATIBLE_API_KEY—Bearer token for the relay.
OPENAI_COMPATIBLE_MODELfalls back to GROK_SEARCH_MODELModel name to send.

Notes:

  • GROK_SEARCH_WEB_SEARCH=true (default) appends tools:[{"type":"web_search"}] to the payload. Relays that auto‑search server‑side simply ignore it.
  • GROK_SEARCH_X_SEARCH=true is silently ignored on this transport (a one‑line stderr warning prints at startup). x_search only exists on the Responses API.
  • Source extraction reads four parallel paths and de‑duplicates by URL: OpenAI annotations[].url_citation, Perplexity‑style citations, top‑level search_sources[], and inline [[n]](url) markers.

Source providers (shared)

VariableDefaultPurpose
TAVILY_API_KEY— (required for web_map)Tavily key. Comma‑separated list rotates round‑robin with failover on HTTP 401/403/429/432/433.
TAVILY_API_URLhttps://api.tavily.comTavily base.
GROK_SEARCH_EXTRA_SOURCES3Extra chain‑served sources after a Grok answer (0 disables).
GROK_SEARCH_FALLBACK_SOURCES5Fallback source count when the AI step can't verify itself.
FIRECRAWL_API_KEYunsetEnables Firecrawl as web_fetch / source fallback.
FIRECRAWL_API_URLhttps://api.firecrawl.devFirecrawl base; defaults to /v2, preserving explicit /v1 or /v2 and gateway prefixes.
TINYFISH_API_KEYunsetEnables TinyFish (free search + JS‑rendering fetch) in the chain.
EXA_API_KEYunsetEnables Exa (semantic search, native filters) in the chain.
GROK_SEARCH_SOURCE_PROVIDERSunsetExplicit chain order, e.g. tinyfish,tavily,firecrawl. Unset = canonical order tavily, exa, tinyfish, firecrawl over configured providers.
GROK_SEARCH_CACHE_SIZE256Max cached web_search sessions.
GROK_SEARCH_TIMEOUT_SECONDS60HTTP timeout for all upstreams.
GROK_SEARCH_FETCH_MAX_CHARSunsetDefault char cap on web_fetch.
GROK_SEARCH_MAX_INLINE_SOURCES5Max web_search sources carrying inline content; the rest are metadata‑only.
GROK_SEARCH_RESPONSE_MAX_CHARS45000Whole‑response char budget for web_search; over‑budget output is truncated tail‑first with truncated: true. Sized to keep the serialized result under the MCP client token ceiling (Claude Code default MAX_MCP_OUTPUT_TOKENS=25000).

Source extraction (web_fetch specialists / web_search enrichment)

VariableDefaultPurpose
GITHUB_TOKENunsetAuthenticates GitHub issue/PR/release fetches (higher API rate limit; private repos). Specialist works unauthenticated but is rate‑limited.
GROK_SEARCH_SOURCE_MAX_ANSWERS5StackExchange answers rendered before folding.
GROK_SEARCH_SOURCE_MAX_COMMENTS30GitHub / StackExchange comments rendered before folding.
GROK_SEARCH_ENRICH_CONCURRENCY3Parallel source enrichments for web_search include_content (clamped 1..5).
GROK_SEARCH_ENRICH_MAX_CHARS15000Char cap per enriched source body.

These specialists need no Tavily/Firecrawl key — they hit the public GitHub, StackExchange, arXiv, and Wikipedia APIs directly. Tavily/Firecrawl are only used for the generic fallback path.

Selection rules at startup

  1. If GROK_SEARCH_AUTH_MODE=oauth → Responses transport with the local OAuth token.
  2. Else if GROK_SEARCH_API_KEY is set → Responses transport with a static Bearer key.
  3. Else if both OPENAI_COMPATIBLE_API_URL and OPENAI_COMPATIBLE_API_KEY are set → ChatCompletions transport.
  4. Else → server fails with a clear MissingConfig error.

Global config file

Tired of duplicating env blocks across clients? Run grok-search-rs --init once to scaffold <home>/.config/grok-search-rs/config.toml, fill in your keys, and every client can shrink to {"command": "grok-search-rs"}.

Path orderLocation
1$GROK_SEARCH_CONFIG (explicit override, any platform)
2$HOME/.config/grok-search-rs/config.toml (Unix / macOS / Git Bash)
3%USERPROFILE%\.config\grok-search-rs\config.toml (native Windows)

Precedence: per‑client env > config file > built‑in defaults. File keys are lowercase snake_case (env GROK_SEARCH_MODEL → file grok_model). Unknown keys are rejected. Full reference: docs/CONFIGURATION.md.


MCP Tools

ToolWhen to call it
web_searchSourced summary for a topic. Sources cached for follow‑up. response_format: "concise" returns answer + metadata only; "detailed" inlines source text within the response budget.
get_sourcesRe‑fetch sources of a previous web_search by session_id. Supports offset / limit pagination for large source sets.
web_fetchPage content as clean Markdown. Key‑free specialist extractors for GitHub / StackExchange / arXiv / Wikipedia; every other URL goes through the source chain, which needs at least one provider key. Returns source_type + fallback_reason.
web_mapDiscover URLs on a domain via Tavily Map.
doctorLive connectivity probe + redacted config, plus the config file's path and whether it was absent / loaded / rejected. Run first when something looks off.

Self-hosting (remote HTTP)

Besides the default stdio mode, grok-search-rs can run as a remote, multi‑tenant Streamable HTTP MCP server so mobile / on‑the‑go / multi‑device clients can reach it over the network. It is opt‑in behind the http Cargo feature — the default build is unchanged (pure stdio, no HTTP dependencies linked in).

Bring‑your‑own‑key, zero shared credentials. The server stores no API keys. Each request carries the caller's own keys as headers, so many users can share one endpoint and each pays with their own keys:

  • X-Grok-Api-Key, X-Tavily-Api-Key, X-Firecrawl-Api-Key (optional X-GitHub-Token)
  • Optional non‑secret overrides: X-Grok-Base-Url (gateway), X-Grok-Model (model name, since model ids are gateway‑specific)

This cuts both ways: setting TAVILY_API_KEY / FIRECRAWL_API_KEY in the server's own environment (compose file, .env, systemd unit) has no effect — those are stripped from every per‑request config, so requests that don't carry the header run with no source fallback at all. The server logs a warning at startup for each such variable it finds.

A missing required key returns 401 (fail‑closed); OAuth is rejected on this transport (stdio only). The operator sets the default Grok‑compatible gateway via GROK_SEARCH_URL (default https://api.x.ai), and callers may point at any other Grok‑compatible gateway with an X-Grok-Base-Url header (any public gateway is honored; internal/private addresses are rejected). The remote transport uses the Grok Responses API only; the OpenAI-compatible chat-completions transport is stdio-only.

No local build needed. Every release ships ready‑to‑run server artifacts for Linux x86_64 + aarch64 (static musl) — ideal for low‑RAM/small‑disk boards where a native cargo build would OOM or fill the disk:

  • Prebuilt binary — download grok-search-rs-http_Linux_<arch>.tar.gz from the latest release and run GROK_MCP_BIND=0.0.0.0:8080 ./grok-search-rs --http. (The plain grok-search-rs_… assets are stdio‑only: the HTTP transport is compile‑time gated and not in them.)
  • Docker image — multi‑arch amd64/arm64: docker pull ghcr.io/episkey-g/grok-search-rs:latest (serves on :8080).

Building from source instead:

bash
cargo build --profile release-http --features http    # release-http => panic=unwind (handler panic won't kill the server)
GROK_MCP_BIND=127.0.0.1:8080 target/release-http/grok-search-rs --http   # bind loopback; terminate TLS upstream

Put a TLS‑terminating reverse proxy (e.g. Caddy) in front. The repo ships a Dockerfile, Dockerfile.deploy (runtime‑only, multi‑arch amd64/arm64 — cross‑compile the binaries first with scripts/build-deploy-dist.sh; ideal for low‑RAM hosts), docker-compose.yml, and Caddyfile for a one‑command deploy with automatic HTTPS. Set MCP_HOSTNAME (your domain or a <dashed-ip>.sslip.io name) via the environment or a git‑ignored .env — not in the repo.

Connect a client the same way as the hosted instance (Quick Start), pointing url at your own host (https://<your-host>/groksearch_rs/mcp).

Rotating a key

Keys are never stored server‑side, so rotation is entirely client‑side:

  • stdio — update the key in your MCP client's env block (or the global config.toml) and restart the client.
  • remote HTTP — update the header value in your client config. For Claude Code:
    bash
    claude mcp remove grok-search -s user
    claude mcp add --transport http grok-search https://<your-host>/groksearch_rs/mcp \
      --header "X-Grok-Api-Key: <new-key>" --header "X-Tavily-Api-Key: <new-key>"

Rotate immediately if a key was ever printed, logged, or shared.


Build from source

bash
git clone https://github.com/Episkey-G/GrokSearch-rs.git
cd GrokSearch-rs
cargo build --release

The binary lands at target/release/grok-search-rs. Point your MCP client's command at the absolute path.


Development

bash
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test

More docs:


⭐ Star History


Acknowledgements

  • Inspired by GuDaStudio/GrokSearch — the original Python implementation that pioneered the Grok + Tavily + Firecrawl combo this project rewrites in Rust.
  • Thanks to the LinuxDo community for the discussions, feedback, and the prior art that inspired this rewrite.

License

MIT — see LICENSE.

Installation

TypingMind
{
  "mcpServers": {
    "groksearch-rs": {
      "command": "./target/release/grok-search-rs",
      "args": [],
      "env": {
        "GROK_SEARCH_RS_PROVIDER": "<GROK_SEARCH_RS_PROVIDER>"
      }
    }
  }
}

Use GrokSearch Rs MCP with multiple AI models

TypingMind connects MCP tools at the workspace level, so once GrokSearch Rs is connected, you can use it with different AI models in TypingMind instead of setting it up separately for each model. This MCP runs locally through the TypingMind MCP connector on your device.

Setup guide to use the local connector

Use this when the MCP server needs access to local files, apps, or private resources on your computer.

1

Open the MCP settings

In TypingMind, go to Settings, Advanced Settings, then Model Context Protocol and choose Setup Connector.

  1. Open TypingMind in your browser.
  2. Click the Settings icon.
  3. Go to Advanced Settings.
  4. Open the Model Context Protocol section.
  5. Click Setup Connector and choose This Device.
TypingMind MCP connector setup screen with This Device selected
2

Run the connector command

Choose This Device, copy the command from TypingMind, and run it in Terminal. Keep the process running while you use MCP.

  1. Copy the setup command shown by TypingMind.
  2. Open Terminal on macOS or Windows Terminal on Windows.
  3. Paste and run the command.
  4. Approve the package install if Terminal asks you to proceed.
  5. Keep the Terminal window running while using MCP tools.
3

Add GrokSearch Rs as a server

When the connector status is Ready, click Edit Servers and paste the MCP server configuration.

  1. Wait until the connector status shows Ready.
  2. Click Edit Servers.
  3. Paste the GrokSearch Rs MCP server configuration.
  4. Save the server list.
  5. Refresh if you want to confirm the connector is still ready.
TypingMind MCP settings showing active server and Edit Servers button
{
  "mcpServers": {
    "groksearch-rs": {
      "command": "npx",
      "args": [
        "-y",
        "<mcp-server-package>"
      ]
    }
  }
}
4

Use it across models

Save the server list, open Plugins, enable the GrokSearch Rs MCP tools, then select any supported AI model in TypingMind and use the tools in chat or assign them to an AI agent.

  1. Open the Plugins page in TypingMind.
  2. Enable the GrokSearch Rs MCP tools.
  3. Start a chat and choose the AI model you want to use.
  4. Use the MCP tools in chat or assign them to an AI agent.
  5. Switch to another AI model whenever needed without reconnecting MCP.
TypingMind chat using enabled MCP tools with a selected AI model
Can you use GrokSearch Rs to help me with this task?
GrokSearch Rs
Sure. I read it.
Here is what I found using GrokSearch Rs.

Frequently asked questions

What is the GrokSearch Rs MCP server used for?

GrokSearch Rs is an MCP server that lets compatible AI clients connect to external tools and context. In TypingMind, you can add this MCP server once and make its tools available in your AI workspace.

Can I use GrokSearch Rs MCP with multiple AI models in TypingMind?

Yes. TypingMind connects MCP tools at the workspace level, so you can use GrokSearch Rs with different AI models such as Claude, ChatGPT, Gemini, or other models you have configured in TypingMind without setting up the MCP server separately for each model.

Why use GrokSearch Rs MCP with TypingMind?

TypingMind is one of the best frontends for LLM chat because it brings multiple AI models, prompts, plugins, AI agents, API keys, and MCP tools into one workspace. With GrokSearch Rs connected, you can use its MCP tools across your preferred models while keeping your chat workflow organized in TypingMind.

How do I connect GrokSearch Rs MCP to TypingMind?

GrokSearch Rs runs through the TypingMind local MCP connector. This is best when the MCP server needs access to local files, desktop apps, command-line tools, or private resources on your computer.

What tools does GrokSearch Rs MCP provide in TypingMind?

GrokSearch Rs exposes MCP capabilities that can be enabled from the TypingMind Plugins page and used in chat or assigned to AI agents.

Do I need to share my API keys with TypingMind to use GrokSearch Rs MCP?

No. TypingMind is local-first and lets you keep your model providers, API keys, prompts, and MCP configuration under your control. If GrokSearch Rs requires authentication, add the required headers, OAuth settings, or local configuration for that MCP server when you create the connection.

Related MCP Servers

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇