Conocimiento

Por qué tu servidor MCP necesita una capa de proxy

Los servidores MCP que traen datos web en vivo chocan con los mismos bloqueos y muros geográficos que cualquier scraper. Por qué pasa, y cómo enrutar sus peticiones por proxies residenciales.

Chris Collins

Chris Collins

20 de junio de 2026 · 11 min de lectura

El Model Context Protocol resolvió primero la mitad equivocada del problema, y eso no es una crítica, es solo el orden en que pasaron las cosas. MCP nos dio una forma limpia y estándar de conectar un modelo de lenguaje a herramientas y datos. Lo que deliberadamente no hace es resolver qué pasa cuando una de esas herramientas sale a la web abierta y la web abierta le responde con un 403.

Si has construido o ejecutado un servidor MCP que trae URLs, scrapea páginas, consulta resultados de búsqueda o tira de datos en vivo para un modelo, probablemente ya te has topado con este muro. El servidor funciona perfecto en tu portátil. Lo despliegas en una máquina en la nube, apuntas tu agente hacia él, y de repente la mitad de los fetches vuelven como páginas CAPTCHA, “acceso denegado” o geo-redirecciones al sitio del país equivocado. Nada de tu código MCP cambió. La IP sí.

Este post va de esa brecha: por qué los servidores MCP que traen datos web se bloquean, por qué no es un problema que MCP deba arreglar, y cómo una capa de proxy residencial la cierra con unas pocas líneas de código.

Un repaso rápido de dónde ocurre el acceso web

MCP tiene una separación de roles limpia. Un host (Claude Desktop, un IDE, un runtime de agente) ejecuta un cliente MCP, que habla con uno o más servidores MCP. Cada servidor expone herramientas, recursos y prompts. Cuando el modelo decide usar una herramienta, la llamada fluye host → cliente → servidor, el servidor hace el trabajo real, y el resultado vuelve.

La parte importante para esta discusión: el servidor es donde ocurren los efectos en el mundo real. Cuando construyes una herramienta fetch, una herramienta search o una herramienta scrape_page, la petición HTTP de salida se origina desde el proceso del servidor MCP, dondequiera que ese proceso esté corriendo. El modelo no hace la petición. El host tampoco. El servidor sí.

Así que la IP que ve el sitio web de destino es la IP del servidor MCP. Y ese es todo el problema.

Por qué se bloquean los servidores MCP que traen datos web

Se acumulan tres cosas, y se acumulan específicamente contra los servidores MCP de una forma que no ocurre contra un humano con un navegador.

Tu servidor MCP está casi con seguridad en una IP de datacenter. Si lo desplegaste en AWS, GCP, Fly, Render, un VPS o cualquier host en la nube, su IP de salida pertenece a un ASN de proveedor de hosting. Los sistemas anti-bot (Cloudflare, Akamai, DataDome) tratan los ASN de datacenter como culpables hasta que se demuestre lo contrario. Una petición desde una IP de AWS a un sitio protegido se marca antes de que el servidor siquiera envíe una cabecera. Esta es la mayor razón por la que “funcionaba en local” se convierte en “está bloqueado en prod”: tu conexión de casa es residencial, tu máquina en la nube no.

El tráfico de agente es a ráfagas y concentrado. Un agente no navega como una persona. Dispara una secuencia de peticiones en una ventana estrecha, a menudo al mismo dominio, y luego se queda en silencio. Desde una sola IP, ese patrón se lee como automatización al instante. Escribimos sobre la forma del tráfico de agentes de IA por separado, pero la versión corta es: límites de tasa y detección de comportamiento que un humano nunca activa, un agente los activa constantemente, porque todo el tráfico viene de una sola dirección.

No tienes control geográfico. Tu servidor MCP corre en una región. Si el modelo necesita ver una página de producto como un comprador alemán, un resultado de búsqueda como un usuario de Tokio o un precio como un cliente estadounidense, un servidor de una sola región físicamente no puede. El sitio geolocaliza la IP del servidor y sirve el contenido del país equivocado, en silencio. El modelo entonces razona sobre datos que cree correctos y no lo son.

Ninguno de estos es un bug en tu servidor MCP. Son propiedades de dónde corre y de qué forma tiene. MCP está haciendo exactamente su trabajo, transportar la llamada de herramienta. Nunca tuvo la intención de lavar la IP.

Por qué esto no es trabajo de MCP resolver

Vale la pena ser explícito, porque a veces la gente espera a que el protocolo desarrolle una función que no va a llegar. MCP es un protocolo para la comunicación modelo-herramienta. Estandariza cómo se describe, se llama una herramienta, y cómo vuelven los resultados. El transporte entre cliente y servidor (stdio, o Streamable HTTP) va de la fontanería del agente, no de cómo el servidor llega a internet.

Cómo habla tu herramienta fetch con el mundo exterior es un detalle de implementación de tu servidor, exactamente igual que qué librería HTTP usas o cómo parseas la respuesta. El protocolo no debería dictarlo, y no lo hace. Lo que significa que la capa de acceso web es tuya para añadir. La buena noticia es que es una capa pequeña y bien entendida: enrutar las peticiones de salida del servidor a través de IPs residenciales.

El arreglo: un proxy residencial detrás de la herramienta fetch

El patrón es simple. En lugar de que la herramienta de tu servidor MCP haga una petición directa desde su IP de datacenter, hace la petición a través de un gateway de proxy residencial. El sitio de destino ve una IP de consumidor real en el país correcto, con el perfil de confianza de una conexión de casa de verdad, y la petición pasa.

Aquí tienes un servidor MCP mínimo en Python con una herramienta fetch_url que enruta a través del gateway de Shifter. El andamiaje MCP es FastMCP estándar; la parte que importa es el cableado de proxies en el cliente HTTP.

import os
import httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("web-fetch")
# Un endpoint de gateway, el targeting va codificado en el nombre de usuario.
# Mantén las credenciales en env, nunca en la definición de la herramienta.
USER = os.environ["SHIFTER_USER"] # p. ej. "customer-<id>"
PASS = os.environ["SHIFTER_PASS"]
GATEWAY = "p.shifter.io:443"
def proxy_url(country: str = "us") -> str:
return f"http://{USER}-country-{country}:{PASS}@{GATEWAY}"
@mcp.tool()
async def fetch_url(url: str, country: str = "us") -> str:
"""Trae una URL a través de una IP residencial en el país dado."""
proxies = proxy_url(country)
async with httpx.AsyncClient(proxy=proxies, timeout=30) as client:
r = await client.get(url, follow_redirects=True)
r.raise_for_status()
return r.text
if __name__ == "__main__":
mcp.run()

Ese es todo el cambio. El modelo llama a fetch_url("https://example.com/product", country="de"), la petición sale a través de una IP residencial en Alemania, y el sitio sirve la página alemana a lo que parece un comprador alemán. Cambia country y el modelo ve la misma página a través de los ojos de otro mercado, sin redeploy y sin un segundo servidor.

El geo-targeting es la parte que los agentes más necesitan

El problema de bloqueo es el que la gente nota primero, pero el problema geográfico es el que silenciosamente corrompe los resultados. Un servidor MCP fijado a una región es un LLM mirando el mundo por una sola mirilla.

Como el gateway de Shifter codifica el targeting en el nombre de usuario, tu herramienta fetch puede tomar un argumento country (o estado, ciudad, incluso ASN) y dejar que el modelo elija por llamada. Eso convierte un servidor de una sola región en uno global. Un agente de investigación comparando precios entre mercados, un agente de QA de localización comprobando cómo renderiza un sitio en cinco países, un agente de monitorización de SERP tirando de resultados de Google como un usuario local, todos ellos necesitan exactamente esto y no pueden obtenerlo de una herramienta fetch vanilla alojada en la nube.

Para flujos multi-paso donde el agente necesita la misma IP a lo largo de varias llamadas (un login, luego una secuencia de páginas autenticadas), añade una sesión sticky incluyendo un id de sesión y un TTL en el nombre de usuario, la misma IP se mantiene durante la vida del TTL:

def sticky_proxy_url(country: str, session: str, ttl: int = 600) -> str:
return f"http://{USER}-country-{country}-sid-{session}-ttl-{ttl}:{PASS}@{GATEWAY}"

Ahora una herramienta browse_session puede llevar una identidad estable a lo largo de los pasos de una tarea en lugar de saltar de IP a mitad de flujo y activar cada comprobación de sesión del sitio.

Qué tener en cuenta

Una capa de proxy no es un interruptor mágico de “nunca bloqueado”, y tratarla como tal es como la gente desperdicia ancho de banda. Unas notas prácticas:

Cachea agresivamente. Los agentes vuelven a traer las mismas URLs constantemente. Una pequeña caché delante de tu herramienta fetch recorta el ancho de banda del proxy (y tu coste) drásticamente, y además es más rápida para el modelo. No proxyees una petición de la que ya tienes la respuesta.

Pasa el país, no lo hardcodees. Todo el valor es el control geográfico por llamada. Haz de country un argumento de herramienta que el modelo pueda fijar, con un valor por defecto sensato, en lugar de hornear una región en el servidor.

Respeta el destino. Un proxy cambia desde qué IP viene la petición, no si deberías estar haciéndola. Honra robots.txt donde sea relevante, mantén las tasas de petición razonables, y no machaques un sitio solo porque los bloqueos desaparecieron. Nuestra política de uso aceptable es la fuente de la verdad para lo que está permitido.

Mantén las credenciales fuera del esquema de la herramienta. El usuario y la contraseña del proxy viven en variables de entorno en el servidor, nunca en la definición de herramienta que ve el modelo. El modelo debería elegir un país, no tener la contraseña de tu gateway.

Datacenter está bien para fetches no protegidos y neutrales en geografía. Si una herramienta solo da en tus propias APIs o endpoints públicos que no bloquean y no geolocalizan, no necesita el proxy. Reserva la capa residencial para los fetches de la web abierta que de verdad enfrentan bloqueos o necesitan geo. (Para una comparación más completa de cuándo encaja cada tipo de IP, ve proxies residenciales vs datacenter.)

Preguntas frecuentes

¿Tiene MCP soporte de proxy integrado? No, y no debería. MCP estandariza la comunicación modelo-herramienta, no cómo una herramienta llega a internet. El acceso web de salida es un detalle de implementación de tu servidor. Añades un proxy a nivel de cliente HTTP dentro de la herramienta, exactamente como se muestra arriba.

¿Por qué no ejecutar mi servidor MCP desde una conexión residencial? Podrías, pero no escala, no te da control geográfico por petición, y ata la fiabilidad de tu agente al uptime de una conexión de casa y una sola IP. Un gateway de proxy residencial te da un pool grande y rotativo y targeting por país por llamada sin alojar nada en una línea residencial.

¿Un proxy evitará por completo que mi agente se bloquee? Elimina la mayor causa (la IP de datacenter) y te da control geográfico, pero el comportamiento sigue importando. Patrones de petición a ráfagas, cabeceras ausentes o inconsistentes, e ignorar los límites de tasa todavía pueden marcarte. El proxy es necesario, no suficiente, combínalo con un comportamiento de petición sensato.

¿Funciona también con servidores MCP en TypeScript? Sí. El concepto es idéntico, configura tu cliente HTTP (fetch con un agent, axios, undici, got) para enrutar a través del gateway. El formato de la URL del proxy y el targeting por petición son los mismos sin importar el lenguaje.

¿Puede el modelo elegir el país por petición? Sí, ese es el patrón recomendado. Expón country (y opcionalmente estado/ciudad) como argumento de herramienta con un valor por defecto. El modelo lo fija según la tarea, y tu servidor lo codifica en el nombre de usuario del proxy al vuelo.

¿Enrutar a través de un proxy cambia cómo me factura Shifter? No. Es el gateway residencial estándar al precio habitual por GB. Un servidor MCP es solo otro cliente conectándose al mismo endpoint. El ancho de banda es ancho de banda.

En resumen

MCP es una respuesta limpia a “cómo llama un modelo a una herramienta”. Nunca tuvo la intención de responder “cómo llega esa herramienta a una web abierta hostil desde una IP de datacenter marcada en el país equivocado”. Esa segunda pregunta es real, es tuya para responder, y la respuesta es una fina capa de proxy residencial detrás de tus herramientas fetch.

El cableado son unas pocas líneas. La recompensa es un servidor MCP cuyas herramientas web de verdad funcionan en producción, devuelven los datos del país correcto, y no se caen la primera vez que un agente las apunta a un sitio protegido. Si estás construyendo agentes conectados a la web, empieza con el gateway residencial y ponlo detrás de tus herramientas desde el día uno, es mucho más fácil que adaptarlo después de que empiecen los bloqueos. Para más sobre dar a los agentes acceso web fiable, ve los mejores proxies para agentes de IA que navegan la web.

Etiquetas: mcp ai agents model context protocol residential proxies llm tools web access

¿Listo para empezar?

Prueba los proxies residenciales de Shifter, más de 205M IPs, más de 195 países, desde 1,00 $/GB.

Comenzar