{
  "markdown": "# SourceWeave Web Search\n\n![Python 3.12+](https://img.shields.io/badge/Python-3.12+-3776AB?logo=python&logoColor=white)\n![MIT License](https://img.shields.io/badge/License-MIT-111111?logo=opensourceinitiative&logoColor=white)\n![MCP](https://img.shields.io/badge/MCP-stdio%20%7C%20HTTP-0EA5E9)\n![Docker managed runtime](https://img.shields.io/badge/Docker-managed%20runtime-2496ED?logo=docker&logoColor=white)\n\nSearch-first MCP server and CLI for web research.\n\n<!-- mcp-name: io.github.MRNAQA/sourceweave-web-search -->\n\n> [!NOTE]\n> `sourceweave-search-mcp` is the default local entrypoint. When explicit `SOURCEWEAVE_SEARCH_*` endpoint variables are absent, it discovers or starts the local Docker-backed stack automatically. If you already run the services yourself, set explicit endpoints and it will use them instead.\n\n[Overview](#overview) • [Getting started](#getting-started) • [Managed local runtime](#managed-local-runtime) • [MCP client setup](#mcp-client-setup) • [CLI](#cli) • [Container deployments](#container-deployments) • [OpenWebUI](#openwebui) • [Runtime configuration](#runtime-configuration) • [Development](#development)\n\n## Overview\n\nSourceWeave Web Search gives MCP clients a compact three-tool contract for web research:\n\n- `search_web(query, domains?, urls?, effort?)` discovers sources and returns compact results with stable `page_id` handles.\n- `read_pages(page_ids, focus?)` reads stored pages by `page_id`.\n- `read_urls(urls, focus?)` reads direct URLs without searching first.\n\nIt combines:\n\n| Component | Role |\n| --- | --- |\n| SearXNG | Search discovery |\n| Crawl4AI | Clean HTML extraction |\n| Redis or Valkey | Persisted page cache and `page_id` store |\n| MarkItDown | Document conversion for PDFs and other supported files |\n\n## Getting started\n\n### Requirements\n\n- Python `3.12+`\n- Docker with Compose support for the default managed local runtime\n- Explicit `SOURCEWEAVE_SEARCH_*` endpoints only if you want hosted or self-managed services\n\n### Managed local runtime\n\nRun the server from the published package:\n\n```bash\nuvx --from sourceweave-web-search sourceweave-search-mcp\n```\n\nOr start the MCP server over HTTP:\n\n```bash\nuvx --from sourceweave-web-search sourceweave-search-mcp \\\n  --transport streamable-http \\\n  --host 127.0.0.1 \\\n  --port 8000\n```\n\nWhen no endpoint env vars are set, `sourceweave-search-mcp`:\n\n| Mode | What happens |\n| --- | --- |\n| Managed stack found | Join the existing SourceWeave-managed stack for the current runtime state directory |\n| Healthy external stack found | Reuse the canonical local ports `19080`, `19235`, and `16379` without ownership |\n| No reusable stack | Start and supervise a Docker-backed stack on canonical or free local ports |\n\nManaged state lives under `~/.sourceweave-local/managed-runtime`. Multiple MCP processes on the same machine share one managed stack per state directory.\n\n> [!IMPORTANT]\n> Managed runtime removes containers only when the last active SourceWeave-managed process exits. Named volumes are preserved, so cache data survives restarts. If the original owning process dies, a later process can recover the same stack from Docker project identity and persisted runtime state.\n\n### Explicit endpoint mode\n\nIf you already run SearXNG, Crawl4AI, and Redis or Valkey yourself, or want to point at hosted services, set explicit endpoints and the MCP entrypoint will bypass managed Docker startup:\n\n```bash\nSOURCEWEAVE_SEARCH_SEARXNG_BASE_URL=\"http://127.0.0.1:19080/search?format=json&q=<query>\" \\\nSOURCEWEAVE_SEARCH_CRAWL4AI_BASE_URL=\"http://127.0.0.1:19235\" \\\nSOURCEWEAVE_SEARCH_CACHE_REDIS_URL=\"redis://127.0.0.1:16379/2\" \\\nuvx --from sourceweave-web-search sourceweave-search-mcp\n```\n\n### Direct CLI\n\n`sourceweave-search` runs the tool directly. Use it when the supporting services are already available or when you provide explicit endpoints. It does not start Docker.\n\n```bash\nsourceweave-search --query \"python programming\" --read-first-pages 2\nsourceweave-search --read-url \"https://packaging.python.org/en/latest/\"\n```\n\n> [!TIP]\n> The direct CLI also accepts `--searxng-base-url`, `--crawl4ai-base-url`, and `--cache-redis-url` overrides.\n\n## MCP client setup\n\n### OpenCode\n\nExample `opencode.json` / `opencode.jsonc` / `~/.config/opencode/opencode.json`:\n\n```jsonc\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"sourceweave\": {\n      \"type\": \"local\",\n      \"command\": [\n        \"uvx\",\n        \"--from\",\n        \"sourceweave-web-search\",\n        \"sourceweave-search-mcp\"\n      ],\n      \"enabled\": true,\n      \"timeout\": 300000\n    }\n  }\n}\n```\n\nFor a shared HTTP endpoint instead:\n\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"sourceweave\": {\n      \"type\": \"remote\",\n      \"url\": \"http://127.0.0.1:18000/mcp\",\n      \"enabled\": true,\n      \"timeout\": 300000\n    }\n  }\n}\n```\n\n### VS Code Copilot\n\nExample `.vscode/mcp.json`:\n\n```json\n{\n  \"servers\": {\n    \"sourceweave\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\n        \"--from\",\n        \"sourceweave-web-search\",\n        \"sourceweave-search-mcp\"\n      ]\n    }\n  }\n}\n```\n\nFor a shared HTTP endpoint instead:\n\n```json\n{\n  \"servers\": {\n    \"sourceweave\": {\n      \"type\": \"http\",\n      \"url\": \"http://127.0.0.1:18000/mcp\"\n    }\n  }\n}\n```\n\n### Claude Code\n\nExample `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"sourceweave\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\n        \"--from\",\n        \"sourceweave-web-search\",\n        \"sourceweave-search-mcp\"\n      ]\n    }\n  }\n}\n```\n\nFor a project-scoped shared config, place the same block in `.mcp.json` at the repo root.\n\n## CLI\n\nThe direct CLI is useful once the supporting services are already reachable. It gives you the same search-first workflow without the MCP wrapper.\n\n```bash\nsourceweave-search --query \"react useEffect cleanup example\" --read-first-page\nsourceweave-search --query \"HTTP overview\" --domain developer.mozilla.org --read-first-page\nsourceweave-search --read-url \"https://packaging.python.org/en/latest/\"\n```\n\n## Container deployments\n\nThe managed local runtime is for host-side `uvx` or `uv run` launches. Containerized deployments still use explicit endpoint wiring.\n\n- Image: `ghcr.io/mrnaqa/sourceweave-web-search-mcp`\n- Repo-local compose entrypoint: `docker compose up -d --build mcp`\n\nExample container run:\n\n```bash\ndocker run --rm -p 8000:8000 \\\n  -e SOURCEWEAVE_SEARCH_SEARXNG_BASE_URL=\"http://host.docker.internal:19080/search?format=json&q=<query>\" \\\n  -e SOURCEWEAVE_SEARCH_CRAWL4AI_BASE_URL=\"http://host.docker.internal:19235\" \\\n  -e SOURCEWEAVE_SEARCH_CACHE_REDIS_URL=\"redis://host.docker.internal:16379/2\" \\\n  ghcr.io/mrnaqa/sourceweave-web-search-mcp:latest\n```\n\n## OpenWebUI\n\nThis repo also ships a generated standalone OpenWebUI tool file at `artifacts/sourceweave_web_search.py`.\n\nFrom a repo checkout, verify it is in sync with the canonical implementation:\n\n```bash\nuv run sourceweave-build-openwebui --check\n```\n\nPaste that artifact into OpenWebUI when you want the standalone tool-file deployment path. The generated file rewrites the default endpoints to the repo-local compose service names so it matches the container deployment path out of the box.\n\n## Runtime configuration\n\nOptional environment variables:\n\n| Variable | Purpose |\n| --- | --- |\n| `SOURCEWEAVE_SEARCH_SEARXNG_BASE_URL` | SearXNG URL template. Must contain `<query>`. |\n| `SOURCEWEAVE_SEARCH_CRAWL4AI_BASE_URL` | Crawl4AI base URL. |\n| `SOURCEWEAVE_SEARCH_CACHE_REDIS_URL` | Redis or Valkey URL used for caching. |\n| `FASTMCP_HOST` | Host for `sse` or `streamable-http` transport. |\n| `FASTMCP_PORT` | Port for `sse` or `streamable-http` transport. |\n\nIf the endpoint variables are unset, `sourceweave-search-mcp` defaults to managed local runtime.\n\n- Canonical host endpoints remain the preferred defaults and the external-reuse probe targets.\n- A SourceWeave-managed stack may use different free host ports when the canonical defaults are already occupied.\n- Multiple MCP processes on the same machine share one managed stack per local runtime state directory.\n\nDefault endpoint values:\n\n- SearXNG: `http://127.0.0.1:19080/search?format=json&q=<query>`\n- Crawl4AI: `http://127.0.0.1:19235`\n- Redis: `redis://127.0.0.1:16379/2`\n\nDefault preferred host ports for managed startup:\n\n- SearXNG: `19080`\n- Crawl4AI: `19235`\n- Redis: `16379`\n- MCP: `8000` when run directly with `uvx`; `18000` at `/mcp` when using the repo's `mcp` compose service\n\n## Development\n\n```bash\ngit clone https://github.com/MRNAQA/sourceweave-web-search.git\ncd sourceweave-web-search\nuv sync --locked --group dev\nuv run sourceweave-search-mcp\n```\n\nUseful checks:\n\n```bash\nuv run sourceweave-build-openwebui --check\nuv run sourceweave-search-mcp --help\nuv run pytest tests/test_config.py tests/test_packaging.py tests/test_tool.py tests/test_managed_runtime.py -m \"not integration\"\n```\n",
  "bytes": 8876,
  "sha": "7d8ed0ecbe2eb3e9524e4fe9c09da4385e9c663303daa1029b6dd2de11a960ae",
  "repo_slug": "mrnaqa/sourceweave-web-search",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_mrnaqa_sourceweave_web_search_e92fb7aa/readme"
}