Skip to main content
Glama

LLMMcp

An MCP server that gives agents two tools over the network this machine actually has:

  • web_search — Google first (rendered with a local headless browser), with Bing / Google News fallbacks.

  • web_fetch — HTTP(S) retrieval converted to markdown, text or raw HTML.

  • web_diagnose — the proxy, TLS and browser state the server resolved.

Direct sockets are blocked here and every request has to leave through the enterprise proxy, which also terminates TLS with an internal CA. LLMMcp owns that path so agent tools no longer depend on a search-provider API key.

Why this exists

Two failures motivated the project:

  1. The harness built-in web_fetch cannot reach the internet from this host (TypeError: fetch failed): Node does not use the Windows proxy settings and does not trust the corporate interception CA.

  2. The built-in web_search needs a provider API key (DEEPSEEK_API_KEY), which this deployment does not have.

LLMMcp closes both gaps:

  • Proxy resolution in one place: LLMMCP_PROXY, then HTTPS_PROXY / HTTP_PROXY / ALL_PROXY, then the config file, then Windows Internet Settings, with NO_PROXY honoured. Proxy credentials are never logged.

  • Corporate TLS through truststore, which reads the Windows certificate store, so interception CAs validate instead of failing.

  • Google without an API key: Google serves a JavaScript-only shell to plain HTTP clients, so the Google engine renders the results page in local headless Chrome or Edge and parses the settled DOM. Google result anchors are opaque /goto?url=... tokens, and each one is resolved to its real target URL through the redirect's Location header.

  • Offline-testable parsers: every engine is tested against captured HTML fixtures, so the suite runs without network access.

Related MCP server: Web Search MCP Server

Quick start

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"

Run the MCP server over stdio, which is what agent clients spawn:

.\.venv\Scripts\python.exe -m llmmcp

Or use the one-shot CLI:

.\.venv\Scripts\python.exe -m llmmcp search "ascend npu mfu"
.\.venv\Scripts\python.exe -m llmmcp fetch https://example.com
.\.venv\Scripts\python.exe -m llmmcp diagnose

MCP tools

Arguments: query (required), max_results (default 8), engine (default auto; also google, bing, gnews), lang, region, recency (d/w/m/y), timeout (default 60 s, because a Google render costs a browser launch).

Returns a numbered text list plus structuredContent shaped as {query, engine, results: [{title, url, snippet, engine}], elapsed_ms, warnings}.

web_fetch

Arguments: url (required), format (markdown default, or text, html), max_chars (default 100000, sets truncated when hit), timeout (default 30 s), include_links.

Returns the content plus structuredContent shaped as {url, final_url, status, content_type, title, content, truncated, bytes_read, elapsed_ms}.

web_diagnose

Reports the resolved proxy label (never credentials), TLS mode, browser path, engine availability and an optional live connectivity probe.

Configuration

Environment variables win over the config file; the file is read from $LLMMCP_CONFIG or ~/.llmmcp/config.json.

key

default

meaning

LLMMCP_PROXY

unset

explicit proxy URL, overrides everything

HTTPS_PROXY / HTTP_PROXY / ALL_PROXY

unset

standard proxy variables

NO_PROXY

unset

bypass list, comma separated

LLMMCP_TLS

truststore

truststore, certifi or off

LLMMCP_TIMEOUT

30

default request timeout, seconds

LLMMCP_MAX_BYTES

5000000

response body cap

LLMMCP_ENGINES

google,bing,gnews

fallback order for engine=auto

LLMMCP_GOOGLE_HOST

www.google.com

Google host

LLMMCP_BROWSER

auto-detected

Chrome or Edge executable used for rendering

LLMMCP_LOG_LEVEL

INFO

logging verbosity

Design

src/llmmcp/
  settings.py   configuration and proxy resolution
  http.py       the only place that opens sockets
  browser.py    headless Chrome/Edge DOM rendering
  fetch.py      URL to markdown/text/html
  search/       one module per engine plus the fallback chain
  server.py     MCP tool definitions
  cli.py        one-shot commands for humans and smoke tests

The contracts that keep these layers independent live in models.py (SearchResult, SearchResponse, FetchResponse, LlmmcpError) and search/base.py (SearchRequest, SearchContext, SearchEngine). Engines never import the server or the transport; they receive an HttpClient and a render callable through SearchContext.

Testing

.\.venv\Scripts\python.exe -m pytest -q          # offline, fixture based
.\.venv\Scripts\python.exe tools\mcp_smoke.py    # MCP stdio handshake

tools/mcp_smoke.py speaks raw newline-delimited JSON-RPC, so it verifies the wire protocol rather than an SDK. Pass --call web_fetch --args-file args.json to exercise a tool.

Using it from DSH

packages/dsh-web-mcp/ contains a small DSH plugin that registers this MCP server's search and fetch as ctx.web providers, which makes the harness native web_search and web_fetch tools run through LLMMcp. See that package's README for the wiring and rollback steps.

The plugin is also published through a DSH plugin market index, market/index.json (format 1). Add https://raw.githubusercontent.com/ai-v5/LLMMcp/main/market/index.json as an index source in Discover and the plugin installs from this repository, pinned to a commit; on first load it installs the Python runtime itself, so a fresh machine needs no manual pip install. Validate the index after editing it:

python tools/validate_market_index.py

Limitations

  • Google rendering costs a browser launch: a search takes roughly 10 to 15 s on this machine. Other engines answer in about a second.

  • Google markup is unofficial and can change; the parser reports a clear GOOGLE_BLOCKED error instead of returning empty results.

  • Google News results point at news.google.com/rss/articles/... redirect links.

  • Only text-like bodies are converted (text/html, text/plain, application/json, application/xhtml+xml); PDFs and binaries are refused with an explicit UNSUPPORTED_CONTENT_TYPE error.

  • A page whose plain HTML carries almost no text is rendered once in the headless browser before conversion, so JavaScript documentation sites return content instead of an empty shell. Expect a browser launch (~10-30 s) for those pages.

Repository rules

See AGENTS.md for the working agreements used when developing this repository.

Local configuration and publishing

Hosts, paths and account names that belong to one machine or company never enter the repository:

  • The proxy, install paths and profile directory are read from LLMMCP_* environment variables or ~/.llmmcp/config.json, which sits outside the checkout, so git status stays clean. See docs/local-setup.md.

  • Tests use tests/local_env.py, which falls back to generic placeholders, so a fresh clone passes offline with nothing configured.

  • Before publishing, run the gate:

    python tools/check_repo_hygiene.py

    It fails on absolute user paths, corporate e-mail addresses, private proxy hosts, committed profile patches and real-looking credentials in URLs.

License

AGPL-3.0-or-later. See LICENSE.

The license covers the Python MCP server and the DSH bridge plugin in this repository. Running LLMMcp as a network service counts as distribution under the AGPL: if you expose a modified version to other users over a network, section 13 requires offering them the corresponding source.

The releases published before this change (v0.1.0) were released under MIT and remain available under those terms; every later release is AGPL-3.0-or-later.

Available Tools

3 tools
web_diagnoseA

Diagnose the local setup: resolved proxy (credentials redacted), TLS mode, browser availability, search engines and an optional live connectivity probe.

NameRequiredDescriptionDefault
probeNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden, and it does disclose the concrete things it inspects plus a useful security note that proxy credentials are redacted. It also signals that the probe performs a live connectivity check. It stops short of stating that the tool is read-only/no-side-effects and how the probe toggles network access.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with the diagnostic scope front-loaded and zero filler. Every listed item earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value documentation is unnecessary, and the description adequately covers what the tool reports. It is nearly complete, missing only a note on when to invoke it relative to its siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must supply the meaning of the lone "probe" parameter, and it does by calling it "an optional live connectivity probe." It does not clarify the default (true) or what changes when probe is false, keeping it just short of full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description pairs a specific verb ("Diagnose") with a specific resource ("the local setup") and enumerates exactly what is inspected: resolved proxy, TLS mode, browser availability, search engines, and an optional connectivity probe. This clearly distinguishes it from the sibling web_search and web_fetch action tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied — an agent can infer this is for troubleshooting setup when search/fetch misbehave, but the description never states when to run it, when not to, or that it should precede using web_search/web_fetch. No explicit routing or prerequisites are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

web_fetchB

Fetch a URL and return its readable content. format is markdown (default), text or html; JSON is pretty printed; binaries are rejected.

NameRequiredDescriptionDefault
urlYes
formatNomarkdown
timeoutNo
max_charsNo
include_linksNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It usefully discloses that JSON is pretty printed and binaries are rejected, which goes beyond the name, but it says nothing about redirect handling, error responses, timeout behavior, or authentication requirements for protected URLs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences with zero filler, front-loading the core action and then the output-formatting rules. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value detail is not needed, and the description covers the format behavior adequately. However, with four undocumented parameters (timeout, max_chars, include_links, url) and no annotations, the definition is incomplete for an agent trying to control request behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 5 parameters, so the description must compensate and largely does not. It explains the format parameter's allowed values and default, but leaves url, timeout, max_chars, and include_links entirely unexplained in both the schema and the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ('Fetch a URL and return its readable content'), which makes the tool's function unambiguous and clearly distinct from a search tool. It does not, however, explicitly contrast itself with the siblings web_search or web_diagnose, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the tool to call when it already has a URL. There is no explicit statement of when to prefer this over web_search or web_diagnose, and no exclusions beyond the implicit 'binaries are rejected' constraint.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.1
    • First observedweb_diagnose
    • First observedweb_fetch
    • First observedweb_search

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct operation: web_search retrieves results, web_fetch retrieves content from a URL, and web_diagnose inspects local configuration. There is no overlap in purpose or expected inputs, making selection unambiguous.

Naming Consistency5/5

All three tools follow the same predictable pattern: a 'web_' prefix plus a clear verb (search, fetch, diagnose). The convention is consistent and self-explanatory.

Tool Count4/5

Three tools is a focused, well-scoped set for a web access server, and each tool has a clear role. It is slightly on the lean side relative to the 3-15 typical range, but nothing feels superfluous or missing at this scale.

Completeness4/5

The core lifecycle for web access is covered: searching, fetching results, and diagnosing the environment. Minor gaps exist, such as no batch-fetch or multi-URL operations, but these are workarounds rather than blockers.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides web search and page fetch capabilities using a browser-based approach, enabling LLMs to search DuckDuckGo, Google, or Yandex and retrieve rendered HTML from URLs.
    5
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to perform web searches, extract webpage content, and conduct end-to-end search-and-extract operations using multiple search providers and content extraction methods.
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables agents to search the live web and fetch URLs as clean Markdown, returning ranked search results and paginated page content through two lightweight tools.
    2
    8 npm
    MIT