Sign inSign up

mekayelanik/fetch-mcp

By mekayelanik

β€’Updated about 1 month ago

Remote Deployment of Fetch MCP server to be used in AI IDEs, AI clients, and Coding CLIs

Buildkit cache
Image
Internet of things
Machine learning & AI
Web servers
0

3.5K

mekayelanik/fetch-mcp repository overview

⁠Fetch MCP Server

Docker Pulls Docker Stars GHCR License: GPL-3.0 Platforms GitHub Stars GitHub Forks GitHub Issues Last Commit

⁠Multi-Architecture Docker Image for Distributed Deployment

β πŸ“‹ Table of Contents


⁠Overview

Fetch MCP Server empowers AI assistants with powerful web content retrieval capabilities. Fetch any webpage and receive content in your preferred formatβ€”HTML, JSON, plain text, or Markdown. Seamlessly integrates with VS Code, Cursor, Windsurf, Claude Desktop, and any MCP-compatible client.

⁠Key Features

✨ Multiple Format Support - HTML, JSON, plain text, and Markdown conversion
πŸ”’ Secure & Configurable - Custom headers, SSL verification, redirect control
⚑ High Performance - Configurable timeouts, size limits, and redirect handling
🌐 CORS Ready - Built-in CORS support for browser-based clients
πŸš€ Multiple Protocols - HTTP, SSE, and WebSocket transport support
🎯 Zero Configuration - Works out of the box with sensible defaults
πŸ”§ Highly Customizable - Fine-tune every aspect via environment variables
πŸ“Š Health Monitoring - Built-in health check endpoint

⁠Supported Architectures
ArchitectureStatusNotes
x86-64βœ… StableIntel/AMD processors
ARM64βœ… StableRaspberry Pi, Apple Silicon
⁠Available Tags
TagStabilityUse Case
stable⭐⭐⭐Production (recommended)
latest⭐⭐⭐Latest stable features
1.x.x⭐⭐⭐Version pinning
beta⚠️Testing only

⁠Quick Start

⁠Prerequisites
  • Docker Engine 23.0+
  • Network access for fetching web content
services:
  fetch-mcp:
    image: mekayelanik/fetch-mcp:stable
    container_name: fetch-mcp
    restart: unless-stopped
    ports:
      - "8060:8060"
    environment:
      - PORT=8060
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Dhaka
      - PROTOCOL=SHTTP
      - CORS=*
      - DEFAULT_LIMIT=0
      - FETCH_TIMEOUT=30000
      - MAX_REDIRECTS=5
      - FOLLOW_REDIRECTS=true
      - VERIFY_SSL=true

Deploy:

docker compose up -d
docker compose logs -f fetch-mcp
⁠Docker CLI
docker run -d \
  --name=fetch-mcp \
  --restart=unless-stopped \
  -p 8060:8060 \
  -e PORT=8060 \
  -e PUID=1000 \
  -e PGID=1000 \
  -e PROTOCOL=SHTTP \
  -e CORS=* \
  mekayelanik/fetch-mcp:stable
⁠Access Endpoints
ProtocolEndpointUse Case
HTTPhttp://host-ip:8060/mcpRecommended
SSEhttp://host-ip:8060/sseReal-time streaming
WebSocketws://host-ip:8060/messageBidirectional
Healthhttp://host-ip:8060/healthzMonitoring

⏱️ Server ready in 5-10 seconds after container start


⁠Configuration

⁠Environment Variables
⁠Core Settings
VariableDefaultDescription
PORT8060Server port (1-65535)
PUID1000User ID for file permissions
PGID1000Group ID for file permissions
TZAsia/DhakaContainer timezone
PROTOCOLSHTTPTransport protocol
CORS(none)Cross-Origin configuration
⁠Fetch Settings
VariableDefaultDescription
DEFAULT_LIMIT0Max response size (bytes, 0=unlimited)
FETCH_TIMEOUT30000Request timeout (ms, 1000-300000)
MAX_REDIRECTS5Maximum redirect follow count (0-20)
FOLLOW_REDIRECTStrueEnable automatic redirect following
VERIFY_SSLtrueEnable SSL certificate verification
USER_AGENT(default)Custom User-Agent header
⁠Advanced Settings
VariableDefaultDescription
RATE_LIMIT0Max requests per RATE_LIMIT_PERIOD per IP (0 = disabled)
RATE_LIMIT_PERIOD10sSliding window for rate limiting (e.g., 10s, 1m, 1h)
MAX_CONNECTIONS_PER_IP0Max concurrent connections per IP (0 = disabled)
IP_ALLOWLIST(empty)Comma-separated IPs/CIDRs to allow (all others blocked)
IP_BLOCKLIST(empty)Comma-separated IPs/CIDRs to block
DEBUG_MODEfalseEnable debug mode (true, false, verbose)
⁠Protocol Configuration
# HTTP/Streamable HTTP (Recommended)
environment:
  - PROTOCOL=SHTTP

# Server-Sent Events
environment:
  - PROTOCOL=SSE

# WebSocket
environment:
  - PROTOCOL=WS
⁠CORS Configuration
# Development - Allow all origins
environment:
  - CORS=*

# Production - Specific domains
environment:
  - CORS=https://example.com,https://app.example.com

# Mixed domains and IPs
environment:
  - CORS=https://example.com,192.168.1.100:3000,/.*\.myapp\.com$/

# Regex patterns
environment:
  - CORS=/^https:\/\/.*\.example\.com$/

⚠️ Security: Never use CORS=* in production environments

⁠Size Limit Examples
# Unlimited (default)
environment:
  - DEFAULT_LIMIT=0

# 1 MB limit
environment:
  - DEFAULT_LIMIT=1048576

# 5 MB limit
environment:
  - DEFAULT_LIMIT=5242880

# 10 MB limit
environment:
  - DEFAULT_LIMIT=10485760
⁠Timeout Examples
# Quick responses (10 seconds)
environment:
  - FETCH_TIMEOUT=10000

# Default (30 seconds)
environment:
  - FETCH_TIMEOUT=30000

# Long-running requests (2 minutes)
environment:
  - FETCH_TIMEOUT=120000
⁠Custom User Agent
environment:
  - USER_AGENT=MyBot/1.0 (+https://example.com/bot)

⁠MCP Client Setup

⁠Transport Compatibility
ClientHTTPSSERecommended
VS Code (Cline/Roo-Cline)βœ…βœ…
Claude Desktopβœ…βœ…
Cursorβœ…βœ…
Windsurfβœ…βœ…

⚠️ *WebSocket support is experimental

⁠VS Code (Cline/Roo-Cline)

Add to .vscode/settings.json:

{
  "mcp.servers": {
    "fetch": {
      "url": "http://host-ip:8060/mcp",
      "transport": "http",
      "autoApprove": [
        "fetch_html",
        "fetch_json",
        "fetch_txt",
        "fetch_markdown"
      ]
    }
  }
}
⁠Claude Desktop

Config Locations:

  • Linux: ~/.config/Claude/claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "fetch": {
      "transport": "http",
      "url": "http://localhost:8060/mcp"
    }
  }
}
⁠Cursor

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "fetch": {
      "transport": "http",
      "url": "http://host-ip:8060/mcp"
    }
  }
}
⁠Windsurf (Codeium)

Add to .codeium/mcp_settings.json:

{
  "mcpServers": {
    "fetch": {
      "transport": "http",
      "url": "http://host-ip:8060/mcp"
    }
  }
}
⁠Claude Code

Add to ~/.config/claude-code/mcp_config.json:

{
  "mcpServers": {
    "fetch": {
      "transport": "http",
      "url": "http://localhost:8060/mcp"
    }
  }
}

Or configure via CLI:

claude-code config mcp add fetch \
  --transport http \
  --url http://localhost:8060/mcp
⁠GitHub Copilot CLI

Add to ~/.github-copilot/mcp.json:

{
  "mcpServers": {
    "fetch": {
      "transport": "http",
      "url": "http://host-ip:8060/mcp"
    }
  }
}

Or use environment variable:

export GITHUB_COPILOT_MCP_SERVERS='{"fetch":{"transport":"http","url":"http://localhost:8060/mcp"}}'

⁠Available Tools

⁠🌐 fetch_html

Fetch a website and return raw HTML content.

Parameters:

  • url (string, required): URL of the website to fetch
  • headers (object, optional): Custom headers for the request

Use Cases:

  • Scraping structured web data
  • Analyzing page structure
  • Testing web applications
  • Extracting specific HTML elements

Example Prompts:


β πŸ“¦ fetch_json

Fetch and parse JSON data from a URL.

Parameters:

  • url (string, required): URL of the JSON resource
  • headers (object, optional): Custom headers for the request

Use Cases:

  • Consuming REST APIs
  • Reading configuration files
  • Processing structured data
  • API testing and debugging

Example Prompts:


β πŸ“„ fetch_txt

Fetch a website and return clean plain text (HTML tags removed).

Parameters:

  • url (string, required): URL of the website to fetch
  • headers (object, optional): Custom headers for the request

Use Cases:

  • Reading articles and blog posts
  • Text analysis and processing
  • Content extraction without markup
  • Accessibility-focused content retrieval

Example Prompts:


β πŸ“ fetch_markdown

Fetch a website and convert HTML to Markdown format.

Parameters:

  • url (string, required): URL of the website to fetch
  • headers (object, optional): Custom headers for the request

Use Cases:

  • Converting web content to Markdown
  • Creating documentation from web pages
  • Archiving web content in readable format
  • Content migration to Markdown-based systems

Example Prompts:

  • "Convert https://example.com⁠ to Markdown"
  • "Get this webpage in Markdown format"
  • "Fetch and convert this article to Markdown"

⁠Advanced Usage

⁠Custom Headers Example
{
  "url": "https://api.example.com/data",
  "headers": {
    "Authorization": "Bearer YOUR_TOKEN",
    "Accept": "application/json",
    "User-Agent": "MyApp/1.0"
  }
}
⁠Production Configuration
services:
  fetch-mcp:
    image: mekayelanik/fetch-mcp:stable
    container_name: fetch-mcp
    restart: unless-stopped
    ports:
      - "8060:8060"
    environment:
      # Core settings
      - PORT=8060
      - PUID=1000
      - PGID=1000
      - TZ=UTC
      - PROTOCOL=SHTTP
      
      # Security
      - CORS=https://app.example.com,https://admin.example.com
      - VERIFY_SSL=true
      
      # Performance
      - DEFAULT_LIMIT=5242880  # 5 MB limit
      - FETCH_TIMEOUT=30000    # 30 seconds
      - MAX_REDIRECTS=5
      - FOLLOW_REDIRECTS=true
      
      # Custom identification
      - USER_AGENT=MyCompany-Bot/1.0 (+https://example.com/bot)
    
    # Resource limits
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
    
    # Health check
    healthcheck:
      test: ["CMD", "nc", "-z", "localhost", "8060"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
⁠Reverse Proxy Setup
⁠Nginx
server {
    listen 80;
    server_name fetch.example.com;
    
    location / {
        proxy_pass http://localhost:8060;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Timeouts for long-running requests
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 300;
    }
}
⁠Traefik
services:
  fetch-mcp:
    image: mekayelanik/fetch-mcp:stable
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.fetch-mcp.rule=Host(`fetch.example.com`)"
      - "traefik.http.routers.fetch-mcp.entrypoints=websecure"
      - "traefik.http.routers.fetch-mcp.tls.certresolver=myresolver"
      - "traefik.http.services.fetch-mcp.loadbalancer.server.port=8060"
⁠Docker Network Setup
services:
  fetch-mcp:
    image: mekayelanik/fetch-mcp:stable
    container_name: fetch-mcp
    networks:
      - mcp-network
    environment:
      - PORT=8060
      - PROTOCOL=SHTTP
    
  other-service:
    image: other-service:latest
    networks:
      - mcp-network
    environment:
      - FETCH_MCP_URL=http://fetch-mcp:8060/mcp

networks:
  mcp-network:
    driver: bridge
⁠Multiple Instances
services:
  fetch-mcp-primary:
    image: mekayelanik/fetch-mcp:stable
    container_name: fetch-mcp-primary
    ports:
      - "8060:8060"
    environment:
      - PORT=8060
      - FETCH_TIMEOUT=30000
  
  fetch-mcp-fast:
    image: mekayelanik/fetch-mcp:stable
    container_name: fetch-mcp-fast
    ports:
      - "8061:8060"
    environment:
      - PORT=8060
      - FETCH_TIMEOUT=10000
      - DEFAULT_LIMIT=1048576  # 1 MB for quick fetches
  
  fetch-mcp-large:
    image: mekayelanik/fetch-mcp:stable
    container_name: fetch-mcp-large
    ports:
      - "8062:8060"
    environment:
      - PORT=8060
      - FETCH_TIMEOUT=120000
      - DEFAULT_LIMIT=52428800  # 50 MB for large content


⁠Memory & Concurrency Tuning

This image embeds mcp-proxy (sparfenyuk/mcp-proxy) as the stdio↔HTTP bridge.

  • MCP_PROXY_STATELESS=false (default): one stdio backend child is shared across all MCP sessions.
  • HAPROXY_FRONTEND_MAXCONN / HAPROXY_SERVER_MAXCONN: HAProxy-level caps. Defaults 64/16.
  • WebSocket transport is no longer supported (mcp-proxy upstream does not implement it).

Root cause: supergateway 3.4.3 stateless mode leaks child processes (supercorp-ai/supergateway#108).

⁠Troubleshooting

⁠Pre-Flight Checklist
  • βœ… Docker 23.0+
  • βœ… Port 8060 available
  • βœ… Network connectivity
  • βœ… Latest stable image
  • βœ… Correct environment variables
⁠Common Issues

Container Won't Start

# Check logs
docker logs fetch-mcp

# Pull latest image
docker pull mekayelanik/fetch-mcp:stable

# Restart container
docker restart fetch-mcp

Connection Refused

# Verify container is running
docker ps | grep fetch-mcp

# Check port binding
docker port fetch-mcp

# Test health endpoint
curl http://localhost:8060/healthz

Timeout Errors

# Increase timeout for slow websites
environment:
  - FETCH_TIMEOUT=60000  # 60 seconds

# Adjust redirect limit
environment:
  - MAX_REDIRECTS=10

SSL Certificate Errors

# Disable SSL verification (not recommended for production)
environment:
  - VERIFY_SSL=false

# Or update CA certificates in container
docker exec fetch-mcp apk add --update ca-certificates

CORS Errors

# Development - allow all
environment:
  - CORS=*

# Production - specific origins
environment:
  - CORS=https://yourdomain.com,https://app.yourdomain.com

Permission Errors

# Check your user ID
id $USER

# Update PUID/PGID
environment:
  - PUID=1001  # Your actual UID
  - PGID=1001  # Your actual GID

Size Limit Exceeded

# Increase or remove size limit
environment:
  - DEFAULT_LIMIT=0  # Unlimited
  # or
  - DEFAULT_LIMIT=10485760  # 10 MB

Debug Mode

# Enable verbose debugging
environment:
  - DEBUG_MODE=verbose

# Then check logs
docker logs -f fetch-mcp
⁠Health Check Testing
# Basic health check
curl http://localhost:8060/healthz

# Test MCP endpoint
curl http://localhost:8060/mcp

# Test with tool invocation
curl -X POST http://localhost:8060/mcp \
  -H "Content-Type: application/json" \
  -d '{"method":"tools/list"}'

⁠Resources & Support

⁠Documentation
⁠MCP Resources
⁠Getting Help

Docker Image Issues:

General Questions:

  • Check logs: docker logs fetch-mcp
  • Test health: curl http://localhost:8060/healthz
  • Review configuration in this README
⁠Updating
# Docker Compose
docker compose pull
docker compose up -d

# Docker CLI
docker pull mekayelanik/fetch-mcp:stable
docker stop fetch-mcp
docker rm fetch-mcp
# Re-run your docker run command
⁠Version Pinning
# Use specific version
services:
  fetch-mcp:
    image: mekayelanik/fetch-mcp:1.0.0

# Or use stable tag (recommended)
services:
  fetch-mcp:
    image: mekayelanik/fetch-mcp:stable

⁠Performance Tips

⁠Optimize for Speed
environment:
  - FETCH_TIMEOUT=10000      # Faster timeout
  - DEFAULT_LIMIT=1048576    # 1 MB limit
  - MAX_REDIRECTS=3          # Fewer redirects
  - FOLLOW_REDIRECTS=true
⁠Optimize for Large Content
environment:
  - FETCH_TIMEOUT=120000     # 2 minutes
  - DEFAULT_LIMIT=0          # No limit
  - MAX_REDIRECTS=10
⁠Resource Limits
deploy:
  resources:
    limits:
      cpus: '2.0'
      memory: 1G
    reservations:
      cpus: '1.0'
      memory: 512M
⁠Rate Limiting and IP Access Control
  • Rate limiting: Set RATE_LIMIT=100 to allow 100 requests per RATE_LIMIT_PERIOD (default 10s) per IP. Exceeding the limit returns HTTP 429 with a Retry-After header.
  • Connection limiting: Set MAX_CONNECTIONS_PER_IP=50 to cap concurrent connections per IP. Exceeding returns HTTP 429.
  • IP blocklist: Set IP_BLOCKLIST=192.0.2.0/24,198.51.100.5 to block specific IPs/CIDRs. Blocked IPs receive HTTP 403.
  • IP allowlist: Set IP_ALLOWLIST=10.0.0.0/8,192.168.1.0/24 to allow only listed IPs/CIDRs. All others receive HTTP 403. Localhost is always allowed.
  • All features default to disabled. Combine as needed β€” blocklist is checked before allowlist.

⁠Security Best Practices

  1. Never use CORS=* in production
  2. Always use VERIFY_SSL=true except for development
  3. Set appropriate size limits to prevent abuse
  4. Use reverse proxy with rate limiting
  5. Run as non-root (default PUID/PGID)
  6. Monitor logs for suspicious activity
  7. Keep Docker image updated
  8. Use specific version tags for production

⁠License

Docker Image: GPL License - See LICENSE⁠ for details.

Disclaimer: Unofficial Docker image for mcp-fetch-server⁠. Users are responsible for compliance with terms of service of fetched websites and applicable laws.


Tag summary

Content type

Image

Digest

sha256:b17b9db6b…

Size

98.6 MB

Last updated

about 1 month ago

docker pull mekayelanik/fetch-mcp