This release includes 4 security fixes for security teams reviewing exposed deployments.
Topics
Affected surfaces
ReleasePort's take
Light signalThe release makes Gemini TLS connects cancellable via native asyncio and stops leaking sensitive query data (status‑11) from logs, caches, and model inputs.
Why it matters: Enabling cancellable TLS connections improves deadline handling; preventing SENSITIVE_INPUT leakage safeguards user privacy in logs and caches.
Summary
AI summaryUpdates Version, Commit, and Workflow across a mixed release.
Changes in this release
| Type | Severity | Summary | CVE |
|---|---|---|---|
| Security | Critical |
Move Gemini TLS transport to native asyncio, making connects cancellable at request deadline. Move Gemini TLS transport to native asyncio, making connects cancellable at request deadline. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Security | High |
Stop leaking Gemini status‑11 (`SENSITIVE_INPUT`) query data in logs, model input, and cache keys. Stop leaking Gemini status‑11 (`SENSITIVE_INPUT`) query data in logs, model input, and cache keys. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Security | High |
Reject not‑yet‑valid certificates on TOFU first use by default, previously only warned unless `reject_expired` was set. Reject not‑yet‑valid certificates on TOFU first use by default, previously only warned unless `reject_expired` was set. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Security | Medium |
Reject empty and self‑referential Gemini redirects to prevent unbounded client re‑fetch loops. Reject empty and self‑referential Gemini redirects to prevent unbounded client re‑fetch loops. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Feature | Medium |
Add `GOPHER_MAX_MENU_ITEMS` config (default 1000) to cap returned Gopher menu items, mirroring gemtext character caps. Add `GOPHER_MAX_MENU_ITEMS` config (default 1000) to cap returned Gopher menu items, mirroring gemtext character caps. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Feature | Medium |
Add optional positive port allowlist (`GOPHER_ALLOWED_PORTS` / `GEMINI_ALLOWED_PORTS`) to close arbitrary‑port scanning gap. Add optional positive port allowlist (`GOPHER_ALLOWED_PORTS` / `GEMINI_ALLOWED_PORTS`) to close arbitrary‑port scanning gap. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Dependency | Low |
Drop hardcoded TLS 1.2 cipher allow‑list, using Python's secure defaults for better Gemini server interoperability. Drop hardcoded TLS 1.2 cipher allow‑list, using Python's secure defaults for better Gemini server interoperability. Source: llm_adapter@2026-06-09 Confidence: low |
— |
| Deprecation | Medium |
Remove unused `http`/`aiohttp` optional dependency, never‑read `development_mode` setting, and test‑only `create_tls_client` factory. Remove unused `http`/`aiohttp` optional dependency, never‑read `development_mode` setting, and test‑only `create_tls_client` factory. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Deprecation | Medium |
Remove `GeminiGemtextResult` helper properties `.summary`, `.plain_text`, and `.structured_content` as they were never serialized. Remove `GeminiGemtextResult` helper properties `.summary`, `.plain_text`, and `.structured_content` as they were never serialized. Source: llm_adapter@2026-06-09 Confidence: high |
— |
| Bugfix | Medium |
Apply `max_rendered_chars` cap to `text/gemini` responses, adding a `truncated` flag for both gemtext and menu results. Apply `max_rendered_chars` cap to `text/gemini` responses, adding a `truncated` flag for both gemtext and menu results. Source: llm_adapter@2026-06-09 Confidence: high |
— |
Full changelog
Security
- Move the Gemini TLS transport to native asyncio (
asyncio.open_connection
withssl=), so connect, handshake and every read are genuinely cancellable:
a slow-loris or stalled peer is now cut off at the request deadline instead of
parking a worker thread on a blockingrecv. The previous design ran blocking
socket I/O on a thread pool shared with DNS resolution (the SSRF guard for both
protocols), so a handful of slow Gemini reads could stall DNS for every request
and escalate one slow server into a whole-server denial of service. - Stop leaking a Gemini status-11 (
SENSITIVE_INPUT) answer: the percent-encoded
query is no longer written to logs, reflected back to the model via
requestInfo, or retained in a cache key. - Reject not-yet-valid certificates on TOFU first use by default (previously
pinned with only a warning unlessreject_expiredwas set). - Reject empty and self-referential Gemini redirects (
INVALID_REDIRECT) so a
malformed3xresponse cannot drive an unbounded client re-fetch loop.
Added
GOPHER_MAX_MENU_ITEMS(default 1000): caps the number of Gopher menu items
returned to the model, mirroring the existing text/gemtext character cap.- Optional positive port allowlist (
GOPHER_ALLOWED_PORTS/
GEMINI_ALLOWED_PORTS) to close the arbitrary-port port-scanning gap left by
the dangerous-ports denylist.
Changed
- Apply the
max_rendered_charscap totext/geminiresponses (previously only
text/*), so a large gemtext page no longer floods the model context; both
gemtext and menu results now carry atruncatedflag. - Drop the over-strict hardcoded TLS 1.2 cipher allow-list in favour of Python's
secure defaults, improving interop with conforming Gemini servers. - De-duplicate the two batch-fetch tools (
gopher_batch_fetch/
gemini_batch_fetch) onto a single shared implementation so the batch
error/contract behaviour has one source of truth (no behaviour change).
Removed
- The unused
http/aiohttpoptional dependency, the never-read
development_modesetting, and the test-onlycreate_tls_clientfactory. - The
GeminiGemtextResult.summary,.plain_textand.structured_content
helper properties: they were never serialized bymodel_dump()so the MCP
tools never exposed them (dead LLM-facing API). The parseddocumentand
raw_contentcarry the same information.
Fixed
- Correct the LLM-facing server instructions,
gopher_fetchparameter
description, and AI Assistant Guide to reference the real serialized
next_urlmenu field (not thenextUrl/urlnames that never appear in the
output). - Sync
server.jsonto the released version and replace placeholder
Release Information:
- Version: 0.4.2
- Release Date: 2026-06-09
- Commit: 93be258
- Workflow: 27209467836
Installation:
pip install gopher-mcp==0.4.2
Verification:
All packages are signed and can be verified using Sigstore.
Breaking Changes
- Removed `http`/`aiohttp` optional dependency, `development_mode` setting, and test‑only `create_tls_client` factory.
- Removed unused `GeminiGemtextResult.summary`, `.plain_text`, and `.structured_content` properties.
Security Fixes
- Gemini TLS transport now uses native asyncio for cancellable I/O, preventing worker‑thread stalls and denial‑of‑service from slow peers.
- Stopped leaking Gemini status‑11 (`SENSITIVE_INPUT`) data in logs, `requestInfo`, and cache keys.
- Reject not‑yet‑valid certificates on TOFU first use by default; previously only warned unless `reject_expired` was set.
- Reject empty and self‑referential Gemini redirects to prevent unbounded client re-fetch loops.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About cameronrye/gopher-mcp
Modern, cross-platform MCP server enabling AI assistants to browse and interact with both Gopher protocol and Gemini protocol resources safely and efficiently. Features dual protocol support, TLS security, and structured content extraction.
Related context
Related tools
Earlier breaking changes
- v0.5.0 Changes Gemini binary success responses to return only metadata, dropping base64‑inlined bodies.
- v0.3.0 Reject `--mount-path` for transports that ignore it instead of silently dropping.
- v0.3.0 Server settings now read under `GOPHER_MCP_` environment prefix; update any existing env vars accordingly.
Beta — feedback welcome: [email protected]