AI Assistant Guide
This guide helps AI assistants effectively use the Gopher & Gemini MCP Server to explore alternative internet protocols.
Quick Start
The server provides two main tools:
gopher_fetch
: For exploring Gopherspace (vintage internet protocol)gemini_fetch
: For exploring Geminispace (modern privacy-focused protocol)
Understanding the Protocols
Gopher Protocol
Gopher is a vintage internet protocol from 1991 that predates the Web:
- Menu-based navigation: Hierarchical directory structure
- Simple text format: Plain text with minimal markup
- No encryption: All traffic is unencrypted
- Unique communities: Active communities with vintage computing focus
Gemini Protocol
Gemini is a modern protocol designed for privacy and simplicity:
- Mandatory TLS: All connections are encrypted
- Gemtext markup: Lightweight text format with basic formatting
- Privacy-focused: Minimal tracking and data collection
- Certificate-based auth: Uses client certificates for authentication
Using gopher_fetch
Basic Usage
Response Handling
Always check the kind
field to determine response type:
result = gopher_fetch(url)
if result["kind"] == "menu":
# Handle menu items
for item in result["items"]:
print(f"{item['type']}: {item['display_text']}")
elif result["kind"] == "text":
# Handle text content
print(result["content"])
elif result["kind"] == "binary":
# Handle binary file metadata
print(f"Binary file: {result['description']}")
elif result["kind"] == "error":
# Handle errors
print(f"Error: {result['error']}")
Gopher Item Types
Type | Description | Action |
---|---|---|
0 |
Text file | Fetch and display content |
1 |
Menu/Directory | Browse submenu |
7 |
Search server | Prompt for search terms |
4,5,6,9,g,I |
Binary files | Show metadata only |
h |
HTML file | Fetch and display |
i |
Info text | Display as-is |
Navigation Patterns
- Start with root menu:
gopher://hostname/1/
- Follow menu items: Use the
url
field from menu items - Handle search servers: Type 7 items require search terms
- Respect binary files: Don't fetch large binary content
Common Gopher Sites
gopher://gopher.floodgap.com/1/
- Floodgap (main Gopher site)gopher://gopher.quux.org/1/
- Quux.orggopher://sdf.org/1/
- SDF Public Access UNIX Systemgopher://gopherpedia.com/1/
- Gopherpedia (Wikipedia mirror)
Using gemini_fetch
Basic Usage
Response Handling
Handle different response types based on kind
:
result = gemini_fetch(url)
if result["kind"] == "gemtext":
# Handle gemtext content
doc = result["document"]
for line in doc["lines"]:
if line["type"] == "heading1":
print(f"# {line['text']}")
elif line["type"] == "link":
print(f"Link: {line['text']} -> {line['url']}")
elif line["type"] == "text":
print(line["text"])
elif result["kind"] == "success":
# Handle other content types
mime = result["mime_type"]
if mime["is_text"]:
print(result["content"])
else:
print(f"Binary content: {mime['full_type']}")
elif result["kind"] == "input":
# Handle input requests
print(f"Input required: {result['prompt']}")
# Note: In MCP context, you cannot provide input
elif result["kind"] == "redirect":
# Handle redirects
new_url = result["url"]
print(f"Redirected to: {new_url}")
# Follow redirect if appropriate
elif result["kind"] == "error":
# Handle errors
print(f"Error {result['status']}: {result['message']}")
Gemini Status Codes
Range | Type | Handling |
---|---|---|
10-11 | Input | Cannot provide input in MCP context |
20-29 | Success | Process content normally |
30-31 | Redirect | Follow redirect if appropriate |
40-49 | Temporary Error | May retry later |
50-59 | Permanent Error | Do not retry |
60-69 | Certificate Required | Cannot provide certificates in MCP context |
Gemtext Format
Gemtext is a lightweight markup format:
# Heading 1
## Heading 2
### Heading 3
Regular paragraph text.
* List item
* Another list item
> Quoted text
Common Gemini Sites
gemini://geminiprotocol.net/
- Gemini protocol homepagegemini://warmedal.se/~antenna/
- Antenna (gemlog aggregator)gemini://kennedy.gemi.dev/
- Kennedy (search engine)gemini://rawtext.club/
- Rawtext Club (community)
Best Practices
For Both Protocols
- Always check response type: Use the
kind
field to determine how to handle responses - Handle errors gracefully: Provide helpful error messages to users
- Respect rate limits: Don't make too many requests in quick succession
- Follow redirects carefully: Check for redirect loops
- Be mindful of content size: Large responses may be truncated
Gopher-Specific
- Start with menus: Begin exploration with directory listings
- Understand item types: Different types require different handling
- Handle search servers: Type 7 items need search terms appended to URL
- Respect the vintage nature: Gopher content often reflects historical computing
Gemini-Specific
- Parse gemtext properly: Use the structured document format
- Handle input requests: Explain that input cannot be provided in MCP context
- Follow certificate requirements: Some sites require client certificates
- Respect privacy focus: Gemini emphasizes privacy and minimal tracking
Common Use Cases
Content Discovery
# Explore a Gopher menu
result = gopher_fetch("gopher://gopher.floodgap.com/1/")
if result["kind"] == "menu":
for item in result["items"]:
if item["type"] == "1": # Submenu
print(f"Directory: {item['display_text']}")
elif item["type"] == "0": # Text file
print(f"Text file: {item['display_text']}")
# Browse Gemini content
result = gemini_fetch("gemini://geminiprotocol.net/")
if result["kind"] == "gemtext":
# Show headings and links
for heading in result["document"]["headings"]:
print(f"Section: {heading['text']}")
for link in result["document"]["links"]:
print(f"Link: {link['text']} -> {link['url']}")
Search Operations
# Gopher search (Veronica-2)
search_url = "gopher://gopher.floodgap.com/7/v2/vs?python"
result = gopher_fetch(search_url)
if result["kind"] == "menu":
print(f"Found {len(result['items'])} results for 'python'")
# Note: Gemini doesn't have built-in search, but some sites provide search pages
Content Analysis
# Analyze gemtext structure
result = gemini_fetch("gemini://example.org/article")
if result["kind"] == "gemtext":
doc = result["document"]
print(f"Article has {len(doc['headings'])} sections")
print(f"Contains {len(doc['links'])} links")
print(f"Total lines: {len(doc['lines'])}")
Error Handling
Common Errors
- Connection timeouts: Server not responding
- Invalid URLs: Malformed protocol URLs
- Certificate issues: TLS/TOFU problems (Gemini only)
- Content too large: Response exceeds size limits
- Host restrictions: Server not in allowlist
Error Recovery
def safe_fetch(url, protocol="auto"):
try:
if protocol == "gopher" or url.startswith("gopher://"):
return gopher_fetch(url)
elif protocol == "gemini" or url.startswith("gemini://"):
return gemini_fetch(url)
except Exception as e:
return {
"kind": "error",
"error": str(e),
"suggestions": [
"Check if the URL is correct",
"Verify the server is online",
"Try again later if it's a temporary issue"
]
}
Tips for AI Assistants
- Explain the protocols: Help users understand what Gopher and Gemini are
- Provide context: Explain the vintage/modern nature of the protocols
- Suggest starting points: Recommend good sites for exploration
- Handle limitations: Explain when input or certificates are required
- Encourage exploration: These protocols have unique communities and content
- Respect the culture: Both protocols have distinct communities and etiquette
Troubleshooting
Common Issues
- "Host not allowed": Server not in configured allowlist
- "Certificate validation failed": TOFU or TLS certificate issues
- "Input required": Site needs user input (not possible in MCP)
- "Client certificate required": Site needs client authentication
- "Content too large": Response exceeds configured size limit
Solutions
- Check server configuration and allowlists
- Verify TLS/certificate settings
- Explain limitations to users
- Try alternative sites or content
- Adjust size limits if appropriate
Remember: These protocols offer unique perspectives on internet content and communities. Encourage exploration while respecting the distinct cultures and technical constraints of each protocol.