Aether
Allows querying a self-hosted SearXNG meta-search instance to retrieve web search results with titles, URLs, snippets, and publication dates.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Aether
A local, self-hosted web search and page-fetching MCP server.
Aether exposes two tools to any MCP-compatible client:
web_search— query a self-hosted SearXNG instance and return titles, URLs, snippets, and publication dates.fetch_page— download a public webpage and extract its readable text.
Everything runs on your machine: SearXNG handles the searching, and Aether talks to it over localhost. No API keys, no third-party search subscriptions.
Features
Self-hosted meta-search via SearXNG (Docker)
Plain-text extraction from HTML pages with
BeautifulSoupSearch results capped at 10 per query; page text capped at 12,000 characters
fetch_pagerefuses non-public hosts (loopback, private, link-local, etc.), credentials in URLs, and redirectsHard 1 MB response limit for fetched pages
Returned page content is clearly flagged as untrusted data
Related MCP server: Basic MCP Tools
Architecture
MCP client ──stdio──▶ server.py (Aether) ──HTTP──▶ SearXNG (Docker)
│
▼
upstream search
enginesserver.py is both the MCP server and the SearXNG client. It runs locally over the stdio transport, so your MCP client launches it as a child process.
Prerequisites
Docker with the Docker Compose plugin
Python 3.10+
gitAn MCP-compatible client (Claude Desktop, Claude Code, OpenCode, etc.)
Setup
1. Clone the repository
git clone https://github.com/DenivalHeitz/aether.git
cd aether2. Create the environment file
cp .env.example .envSet SEARXNG_SECRET to a random value:
sed -i "s/change-me/$(openssl rand -hex 32)/" .envOr edit .env by hand:
SEARXNG_SECRET=your-random-secret-here3. Start SearXNG
docker compose up -dCheck that it is running:
docker compose ps4. Verify the SearXNG JSON API
Aether requires SearXNG's JSON output format, which is already enabled in searxng/settings.yml.
curl "http://127.0.0.1:8080/search?q=test&format=json" | head -c 300You should get back JSON containing a results array. If you get HTML or a 403, confirm the search.formats list in searxng/settings.yml includes json and restart the container:
docker compose restart5. Install the Python dependencies
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"On Windows, activate with .venv\Scripts\activate instead.
If you only need to run the server and don't need the MCP Inspector, pip install -e . is enough.
pyproject.toml pins the MCP SDK to the 1.x line (mcp>=1.30,<2), which is the version that provides the FastMCP 1.x API used by server.py. The dev extra adds the mcp CLI for mcp dev. Do not upgrade to mcp 2.x without updating the code.
6. Test the server (optional)
server.py uses stdio, so running it directly just waits for an MCP client. To poke at the tools interactively, use the MCP Inspector:
mcp dev server.py7. Connect your MCP client
Point the client at the absolute path of the virtualenv's Python and server.py.
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"aether": {
"command": "/absolute/path/to/aether/.venv/bin/python",
"args": ["/absolute/path/to/aether/server.py"]
}
}
}Claude Code:
claude mcp add aether -- /absolute/path/to/aether/.venv/bin/python /absolute/path/to/aether/server.pyOpenCode (opencode.json):
{
"mcp": {
"servers": {
"local-web-search": {
"type": "local",
"command": [
"/absolute/path/to/aether/.venv/bin/python",
"/absolute/path/to/aether/server.py"
],
"environment": {
"SEARXNG_URL": "http://127.0.0.1:8080"
},
"codemode": false // codemode not needed for this mcp tool
}
}
}
}Restart your client after saving the config.
Usage
Once connected, ask your client something that needs the live web, for example:
Search the web for the latest Python release notes.
The client will call web_search, then optionally call fetch_page on a promising result to read it in full.
Tools
web_search
Parameter | Type | Default | Description |
| string | — | Search terms. Empty queries are rejected. |
| int |
| Number of results, clamped to the range 1–10. |
Returns:
{
"query": "latest python release",
"count": 2,
"results": [
{
"title": "Python 3.14 release notes",
"url": "https://docs.python.org/3/whatsnew/3.14.html",
"snippet": "...",
"published_date": null
}
]
}fetch_page
Parameter | Type | Description |
| string | Public |
Returns url, title, text, truncated, and a warning noting that page content is untrusted. Failures return {"error": "..."}.
Configuration
Variable | Default | Used by | Description |
|
|
| Base URL of the SearXNG instance. Set it if you changed the port. |
| — | Docker Compose | Secret key for SearXNG. Required; Compose fails without it. |
If SearXNG runs elsewhere, pass SEARXNG_URL through your client's MCP config, for example:
{
"mcpServers": {
"aether": {
"command": "/absolute/path/to/aether/.venv/bin/python",
"args": ["/absolute/path/to/aether/server.py"],
"env": { "SEARXNG_URL": "http://127.0.0.1:8080" }
}
}
}Tunable limits live at the top of server.py (TIMEOUT, MAX_PAGE_BYTES, MAX_TEXT_CHARS, MAX_CONNECT_ADDRESSES).
Security notes
SearXNG is bound to
127.0.0.1only and is not exposed to your network..envis git-ignored; only.env.exampleis committed.fetch_pageresolves the hostname once, rejects every non-public address, and then connects to that validated IP while preserving the originalHostheader and TLS SNI. This prevents DNS rebinding between the check and the request.IPv6 addresses must be in global unicast space (
2000::/3), which also blocks transition ranges such as NAT64 that embed an IPv4 address.Redirects are not followed, so a public URL cannot bounce to a private one.
HTTP proxy environment variables are ignored (
trust_env=False), so searches and fetches do not silently leave through a configured proxy.Fetched page text is untrusted input and is returned with an explicit warning. Do not treat it as agent instructions.
Stopping and cleaning up
docker compose down # stop SearXNG
docker compose down -v # also remove Docker volumesTroubleshooting
Symptom | Fix |
| Create |
| SearXNG is not reachable or returned an error. Check |
Search returns | JSON format is disabled. Ensure |
Agent can't see the tools | The client is probably pointing at the wrong Python or |
| The URL is unreachable, redirects, or resolves to a private address — all rejected by design. |
Project structure
.
├── docker-compose.yml # SearXNG service definition
├── pyproject.toml # Project metadata and deps (MCP pinned to 1.x)
├── server.py # MCP server with web_search and fetch_page
├── searxng/
│ └── settings.yml # SearXNG config (enables JSON output)
├── .env.example # Template for local secrets
└── README.mdLicense
MIT — see LICENSE.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Serper MCP — wraps the Serper Google Search API (serper.dev)
Web search API and MCP server for developers building AI agents.
One MCP server for all web data. Scrape, search, crawl, and AI research in one install.
Turn any public website into an MCP server for agents to search, read and navigate.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables privacy-focused web search via SearXNG for MCP clients, allowing users to perform searches with customizable parameters through natural language.223 npmMIT
- FlicenseNot gradedqualityBmaintenanceA self-hosted MCP server providing private web search, web page fetching, and current date/time tools, powered by a bundled SearXNG instance for API-key-free local search.2-
- AlicenseNot gradedqualityDmaintenanceMCP server that provides web search scraping from DuckDuckGo (with Mojeek fallback) and URL content fetching as markdown/text or raw HTML.1ISC
- AlicenseAqualityCmaintenanceMCP server that exposes SearXNG search and HTTP fetch tools for AI agents, enabling web search and clean page text extraction via natural language.4MIT