Qué es MCP: crea un servidor en Python para tu equipo
Descubre qué es MCP y crea un servidor en Python para consultar pedidos. Pruébalo con Inspector, conecta Claude Code y Cursor y añade HTTP con autenticación.
Publicado el

Para entender qué es MCP, piensa en una consulta cotidiana: Claude Code o Cursor puede responder cuál es el estado de un pedido con los datos de tu empresa, sin que copies el registro en el chat. Crea una herramienta MCP de solo lectura, comprueba que funciona en Inspector y después elige entre un proceso local y un servicio HTTP con autenticación que pueda compartir tu equipo.
Un primer servidor útil necesita una tarea concreta: recibir el ID de un pedido y devolver su estado. Empieza por ahí. Una herramienta que dé acceso general a la base de datos obliga al modelo a tomar demasiadas decisiones y le concede más acceso del que necesita este flujo de trabajo.
Esta guía sigue el tutorial oficial para crear un servidor. A fecha del 7 de octubre de 2026, la documentación utiliza la especificación MCP 2026-07-28 y el SDK oficial de Python, la biblioteca que gestiona los mensajes MCP, con su API MCPServer. El ejemplo fija la versión 2.3.0 del SDK, para que un tutorial antiguo y sus importaciones no cambien inadvertidamente lo que instalas.
¿Qué es MCP y qué ofrece tu servidor?
Un servidor MCP funciona como un mostrador de atención con acceso controlado entre una aplicación de IA y tus sistemas. La aplicación puede preguntar qué hay disponible, enviar una solicitud y recibir un resultado. Tu código decide qué puede hacer ese mostrador.
MCP, el Model Context Protocol, establece un formato común para esa conversación. El host es la aplicación que utilizas, como Claude Code o Cursor. Su cliente se encarga de la comunicación con tu servidor mediante el protocolo. Son funciones dentro de la arquitectura; no necesitas instalar tres aplicaciones adicionales.
Una herramienta puede ser de solo lectura. Llamar «recurso» a algo no sustituye las comprobaciones de acceso. Un prompt da instrucciones, no permisos. La compatibilidad y la presentación varían según el cliente, así que verifica las capacidades que realmente vas a ofrecer. Estas son las tres capacidades básicas de un servidor; el que vamos a crear solo necesita una herramienta.

Antes de empezar, comprueba si ya existe un conector con mantenimiento activo que resuelva tu necesidad. Nuestra selección de los mejores servidores MCP para 2026 es un buen punto de partida. Crear uno propio tiene sentido cuando tus datos internos, las reglas de permisos o el flujo de trabajo difieren de lo que ofrecen esos conectores.
Crea un servidor MCP en Python para consultar pedidos sin modificar datos
Deja que el SDK oficial gestione el protocolo y concentra tu código en la consulta. Necesitas Python 3.10 o posterior, uv, el gestor de proyectos de Python que utiliza el tutorial oficial, y Node.js para Inspector. La versión actual de Inspector requiere Node 22.19.0 o posterior.
Ejecuta estos comandos en orden desde una terminal:
uv init orders-mcpcd orders-mcpuv venvuv add "mcp[cli]==2.3.0"
Crea orders.py en esa carpeta y pega el servidor completo que aparece a continuación. Los registros son datos ficticios para practicar. No incluyen nombres de clientes, información de pago ni credenciales de API.
import json
from mcp.server import MCPServer
mcp = MCPServer("orders")
# Fictional training data. No customer records or credentials.
ORDERS = {
"A100": {"status": "shipped", "carrier": "Demo Courier"},
"A101": {"status": "packing", "carrier": "not assigned"},
}
@mcp.tool()
def lookup_order(order_id: str) -> str:
"""Look up a fictional order by ID, such as A100. Read-only.
Args:
order_id: Exact order ID, for example A100 or A101.
"""
key = order_id.strip().upper()
order = ORDERS.get(key)
if order is None:
return json.dumps({"found": False, "order_id": key})
return json.dumps({"found": True, "order_id": key, **order})
if __name__ == "__main__":
mcp.run(transport="stdio")El código sigue el patrón documentado en el tutorial: MCPServer, @mcp.tool() y mcp.run(transport="stdio"), con una consulta de pedidos en lugar de las herramientas meteorológicas. La anotación de tipo indica al SDK que order_id es un texto obligatorio. La cadena de documentación explica al cliente cuándo resulta útil la herramienta. El SDK crea su definición y gestiona los mensajes del protocolo.
Ejecuta uv run orders.py. Es normal que el proceso permanezca en silencio, esperando una entrada. stdio, la entrada y salida estándar, es el canal que utiliza el cliente para comunicarse con ese proceso. Detén esta ejecución manual antes de dejar que un cliente inicie su propia copia.
No envíes los registros de la aplicación a la salida estándar. Utiliza el módulo logging de Python, que por defecto escribe en la salida de error estándar. Un print() fuera de lugar puede corromper el flujo del protocolo. Es una restricción documentada de stdio, no una preferencia sobre cómo presentar los registros.
Cuando sustituyas el diccionario por una base de datos, conserva esa misma interfaz acotada. Utiliza una consulta parametrizada, una cuenta de base de datos que solo pueda leer los campos necesarios y una comprobación de permisos específica para quien hace la llamada antes de devolver un registro. Para esta tarea, nunca aceptes una sentencia SQL arbitraria del modelo.
Comprueba la herramienta con MCP Inspector
Verifica que la herramienta funciona antes de pedirle a un modelo que la use. Desde la carpeta del proyecto, ejecuta uv run mcp dev orders.py. El comando de desarrollo del SDK inicia MCP Inspector. Abre la URL del navegador que muestra el comando y conecta el servidor si todavía no está conectado.
En Tools, selecciona lookup_order. El formulario debe mostrar el campo obligatorio order_id. Invoca la herramienta con A100: el resultado debe contener found: true, status: shipped y carrier: Demo Courier. Consulta A101 para obtener packing. Consulta DOES-NOT-EXIST: el resultado debe contener found: false.
Prueba también una solicitud sin order_id. Debe fallar la validación de entrada en lugar de ejecutar una consulta. Las vistas Protocol y Console de Inspector ayudan a distinguir una solicitud mal formada de un fallo del proceso del servidor.
Para hacer una comprobación repetible desde la terminal, utiliza npx @modelcontextprotocol/inspector --cli uv run orders.py --method tools/list. Para invocar la herramienta, utiliza npx @modelcontextprotocol/inspector --cli uv run orders.py --method tools/call --tool-name lookup_order --tool-arg order_id=A100. Ambos comandos siguen la CLI documentada de Inspector.
La prueba tiene criterios concretos: una herramienta que el cliente pueda descubrir, el estado esperado para un pedido conocido y una respuesta explícita cuando el registro no existe. Un párrafo convincente generado por un modelo no demuestra que la consulta se haya ejecutado.
Conecta el mismo servidor a Claude Code y Cursor
Cada cliente local inicia su propio proceso del servidor. No necesitas mantener Inspector en ejecución. Usa rutas absolutas para que el inicio no dependa de la carpeta que tenga abierta el cliente.
Claude Code: ejecuta claude mcp add --transport stdio --scope local orders -- /ABSOLUTE/PATH/orders-mcp/.venv/bin/python /ABSOLUTE/PATH/orders-mcp/orders.py. En Windows, el intérprete es .venv\Scripts\python.exe. El comando sigue la sintaxis de Claude Code para servidores locales, incluido el separador -- antes del comando de inicio.
Ejecuta claude mcp get orders para comprobar la conexión. En una sesión de Claude Code, abre /mcp y después pide: «Usa lookup_order para consultar A100. Indica únicamente el estado y el transportista devueltos». Revisa la llamada a la herramienta y sus argumentos.
Cursor: crea .cursor/mcp.json en tu proyecto. Añade este JSON y sustituye las dos rutas absolutas: {"mcpServers":{"orders":{"type":"stdio","command":"/ABSOLUTE/PATH/orders-mcp/.venv/bin/python","args":["/ABSOLUTE/PATH/orders-mcp/orders.py"]}}}.
Abre Customize, habilita el servidor y haz la misma pregunta en Agent. Revisa la llamada según tu configuración de aprobaciones. La ubicación del archivo, los campos de inicio y los controles siguen la configuración MCP de Cursor. Si falla la conexión, comprueba la ruta del ejecutable y la salida de error estándar del servidor antes de modificar la herramienta.
Elige entre stdio local y HTTP remoto
Para un flujo de trabajo personal, mantén el servidor en local. Elige HTTP remoto cuando varias personas o clientes alojados necesiten un único servicio administrado.
El servicio remoto también necesita acceso de red a los datos de tu empresa. Publicar un endpoint no hace accesible una base de datos privada ni configura correctamente sus permisos.
El protocolo HTTP 2026-07-28 utiliza solicitudes autocontenidas. El SDK actual de Python también puede atender a clientes antiguos, cuyas sesiones pueden necesitar que las solicitudes sigan llegando a la misma réplica cuando añadas más réplicas. Antes de escalar, configura deliberadamente las opciones documentadas de compatibilidad con versiones anteriores; no des por hecho que todos los clientes conectados usan la revisión más reciente.

Lleva la consulta a HTTP con autenticación
Protege el acceso HTTP con tokens emitidos para este servicio. OAuth 2.1 es el marco de autorización de la especificación MCP: un proveedor de identidad autentica al usuario y emite un token que tu servidor MCP verifica. Un ámbito de permiso, o scope, es un permiso con nombre, como orders:read. La audiencia indica qué servicio puede aceptar el token.
El SDK proporciona la integración como servidor de recursos, no el sistema de inicio de sesión de tu empresa. Para este ejemplo, configura un proveedor de identidad con descubrimiento OAuth, registro de los clientes que vayas a utilizar, PKCE para el inicio de sesión de usuarios y un endpoint de introspección de tokens. PKCE demuestra que la aplicación que completa el inicio de sesión es la misma que lo inició. La introspección consulta al emisor si un token está activo y qué permite hacer.
Este adaptador requiere introspección por HTTPS con autenticación de cliente mediante HTTP Basic y una respuesta que contenga active, aud, exp, client_id y scope. Configura el emisor para incluir la URL pública exacta de este endpoint en aud y conceder orders:read. Si tu proveedor utiliza otro método de autenticación para la introspección, adapta la solicitud según su documentación. Si en cambio proporciona JWT, tokens firmados, implementa la verificación de firma, emisor, caducidad y audiencia en la misma interfaz TokenVerifier.
Añade uvicorn con uv add uvicorn y crea remote.py junto a orders.py. El código sigue el ejemplo oficial de introspección del SDK y sus interfaces documentadas de HTTP y autenticación. Reutiliza la consulta que acabas de probar.
import os
import time
from urllib.parse import urlsplit
import httpx2
from pydantic import AnyHttpUrl
from mcp.server import MCPServer
from mcp.server.auth.provider import AccessToken, TokenVerifier
from mcp.server.auth.settings import AuthSettings
from mcp.server.transport_security import TransportSecuritySettings
from orders import lookup_order as local_lookup
RESOURCE = os.environ["MCP_RESOURCE_URL"]
ISSUER = os.environ["MCP_ISSUER_URL"]
INTROSPECT = os.environ["MCP_INTROSPECTION_URL"]
if any(urlsplit(url).scheme != "https" for url in (RESOURCE, ISSUER, INTROSPECT)):
raise ValueError("Public auth and resource URLs must use HTTPS")
class OrderTokenVerifier(TokenVerifier):
async def verify_token(self, token: str) -> AccessToken | None:
try:
async with httpx2.AsyncClient(timeout=5.0) as client:
response = await client.post(
INTROSPECT,
data={"token": token},
auth=(os.environ["MCP_INTROSPECTION_CLIENT_ID"],
os.environ["MCP_INTROSPECTION_CLIENT_SECRET"]),
)
response.raise_for_status()
data = response.json()
audiences = data.get("aud", [])
if isinstance(audiences, str):
audiences = [audiences]
expiry = data.get("exp")
if (data.get("active") is not True or RESOURCE not in audiences
or not isinstance(expiry, int) or expiry <= time.time()):
return None
if data.get("iss", ISSUER) != ISSUER:
return None
return AccessToken(
token=token, client_id=data["client_id"],
scopes=data.get("scope", "").split(), expires_at=expiry,
resource=RESOURCE, subject=data.get("sub"),
)
except Exception:
return None
mcp = MCPServer(
"orders",
token_verifier=OrderTokenVerifier(),
auth=AuthSettings(
issuer_url=AnyHttpUrl(ISSUER),
resource_server_url=AnyHttpUrl(RESOURCE),
required_scopes=["orders:read"], validate_token_resource=True,
),
)
@mcp.tool()
def lookup_order(order_id: str) -> str:
"""Look up a fictional order by ID, such as A100. Read-only."""
return local_lookup(order_id)
hostname = urlsplit(RESOURCE).hostname
security = TransportSecuritySettings(
allowed_hosts=[hostname, f"{hostname}:*"],
allowed_origins=[os.environ["MCP_ALLOWED_ORIGIN"]],
)
app = mcp.streamable_http_app(transport_security=security)Configura estos valores en el entorno del despliegue o en su almacén de secretos:
La lista de hosts permitidos es explícita porque, de lo contrario, el SDK acepta localhost por defecto y rechaza un nombre de host público con 421 Misdirected Request. Los orígenes del navegador se comprueban por separado; incluye solo los que realmente utilizas. La aplicación devuelta ya incorpora su ciclo de inicio y apagado. Estos detalles siguen la documentación de despliegue del SDK y de la aplicación ASGI. ASGI es la interfaz que utilizan los servidores web de Python para ejecutar esta aplicación.
Iníciala detrás del proxy HTTPS de tu proveedor de alojamiento con uv run uvicorn remote:app --host 0.0.0.0 --port 8000. La URL pública del recurso sigue siendo HTTPS aunque el proxy se comunique con el proceso por HTTP. Configura la confianza en las cabeceras reenviadas según el límite real de ese proxy.
Antes de usar registros reales, ejecuta estas comprobaciones sobre HTTP:
- Sin token, con un token caducado o con uno destinado a otra audiencia: se rechaza el acceso.
- Con un token válido que no incluya
orders:read: se rechaza el acceso. - Con un token válido que tenga la audiencia y el ámbito de permiso correctos:
lookup_orderdevuelve el estado de demostración. /.well-known/oauth-protected-resource/mcp: los metadatos identifican el recurso y el emisor correctos.
Utiliza npx @modelcontextprotocol/inspector --server-url https://orders.example.com/mcp --transport http para inspeccionar el endpoint desplegado y completar su flujo de autenticación. Una prueba de la herramienta en memoria omite la autorización HTTP, así que no puede demostrar que este control funciona.
En Claude Code, añade otra conexión con claude mcp add --transport http orders-remote https://orders.example.com/mcp y autentícate desde /mcp. En Cursor, añade una entrada remota dentro de mcpServers con "url":"https://orders.example.com/mcp" y completa OAuth. Cursor también documenta un objeto auth con CLIENT_ID y scopes para clientes registrados previamente. Registra en tu emisor las URL de retorno correspondientes a cada cliente. Consulta la autenticación de Claude Code y la configuración OAuth remota de Cursor.
Este es un pequeño adaptador con autenticación, no un sistema de producción completo. Antes de sustituir el diccionario de demostración, aplica permisos por organización y por registro a partir de una identidad verificada, añade un evento de auditoría para la llamada, reutiliza las conexiones HTTP y limita las solicitudes. Un ámbito de permiso autoriza la operación; no demuestra que todos los pedidos pertenezcan a quien llama.
Aloja el servidor en Render o Cloudflare Workers
Para el servidor Python que acabamos de crear, empezaría por Render. Un servicio web de Python permite conservar la aplicación que ya has construido. Cloudflare Workers es una buena opción si quieres implementar la misma herramienta acotada con el manejador de Workers documentado.
Estos son los precios publicados por los proveedores y comprobados el 7 de octubre de 2026:
Fuentes: precios de Cloudflare Workers y precios de Render. El espacio de trabajo Pro de Render añade $25/mes más el cómputo si eliges sus funciones para equipos. Debes presupuestar por separado el almacenamiento, los servicios de identidad, el uso de modelos y otros extras; estas cifras corresponden al alojamiento, no al costo de un flujo de trabajo con IA.
Despliegue en Render: incluye orders.py, remote.py y requirements.txt en tu repositorio. El archivo de requisitos necesita mcp[cli]==2.3.0 y uvicorn, cada uno en su propia línea. Crea un Python Web Service, utiliza pip install -r requirements.txt como comando de construcción y uvicorn remote:app --host 0.0.0.0 --port $PORT como comando de inicio. Añade las variables de entorno anteriores y después configura MCP_RESOURCE_URL con el nombre de host asignado o tu dominio personalizado. Esto adapta el despliegue documentado de servicios web de Python en Render a la aplicación ASGI del SDK.
El servicio gratuito de Render sirve para una demostración, pero se suspende después de 15 minutos de inactividad y tarda alrededor de un minuto en reactivarse. Para una herramienta interactiva compartida, usaría recursos de cómputo de pago.
Despliegue en Cloudflare: utiliza la documentación actual del manejador MCP y la guía de servidores remotos. La implementación actual en TypeScript utiliza createMcpHandler de agents/mcp/server con @modelcontextprotocol/server. Implementa allí la misma consulta de pedidos y configura la autenticación antes de compartir la URL. El comando de inicio de uvicorn en Python está pensado para un alojamiento de Python; no sirve como procedimiento de despliegue de un Worker.
Mantén el acceso limitado a lo necesario
Concede al servidor únicamente el acceso que necesita su herramienta. Para consultar el estado de un pedido, eso significa una credencial de backend de solo lectura, campos seleccionados y una comprobación de permisos por registro. Gestiona los reembolsos, las cancelaciones y los cambios de dirección mediante herramientas y permisos independientes. Que el modelo elija unos argumentos nunca equivale a una autorización.
Valida el emisor, la caducidad, la audiencia y el ámbito de permiso de los tokens HTTP. Utiliza HTTPS y credenciales independientes cuando el servidor llame a una API de otro sistema. Las directrices de seguridad de MCP prohíben el reenvío directo de tokens: un token presentado a tu endpoint MCP no es automáticamente una credencial para tu sistema de pedidos. En stdio local, restringe el proceso que lo inicia, su entorno y su acceso al sistema de archivos.
Registra la identidad verificada de quien llama, el nombre de la herramienta, una referencia al registro con los datos sensibles debidamente ocultos, el resultado, la latencia y el ID de la solicitud. Evita registrar tokens y datos completos de clientes. Envía los registros a la salida de error estándar en stdio y al sistema de registros del proveedor de alojamiento en HTTP. Trata el texto recuperado de los registros como datos: una nota dentro de un pedido no debe conceder permiso para otra acción.
Añade un gateway cuando varios servidores o equipos necesiten compartir políticas de identidad, límites de solicitudes, recopilación de auditorías o revocación. El gateway puede centralizar esos controles; cada backend sigue necesitando permisos correctos por registro. Nuestra guía de gateways MCP explica cómo tomar esa decisión.

Seis flujos de trabajo, ordenados por su utilidad inmediata
Estas son posibles ampliaciones del mismo patrón. Empieza por una tarea en la que alguien consulte repetidamente un dato concreto y pueda reconocer una respuesta correcta.
El cálculo de negocio debe partir de tu propio flujo de trabajo. Solo como ejemplo: 80 consultas al día de 2 minutos cada una consumen 160 minutos. Si al medirlo después compruebas que el flujo conectado ahorra 1 minuto por consulta, recuperas 80 minutos al día. Es un cálculo aritmético, no una prueba de rendimiento. Mide las respuestas correctas y el tiempo ahorrado antes de atribuir un retorno al gasto en alojamiento.
Dos oportunidades que merece la pena desarrollar
La oportunidad más sólida es un adaptador de contexto de pedidos para equipos de soporte. Un equipo podría comprar una integración acotada que recupere los datos correctos del envío dentro del asistente que ya usa. DataForSEO estima 260 búsquedas mensuales en Google en Estados Unidos de «customer support automation», una cifra comprobada el 7 de octubre de 2026. Refleja interés general en esa tarea, no un recuento de compradores de MCP. Intercom publica un precio de $0.99 por resultado para Fin, lo que muestra que ya existe presupuesto para automatizar el soporte; este pequeño adaptador aporta contexto en lugar de sustituir ese producto.
La versión mínima que se podría vender abarcaría un backend de pedidos, lookup_order, un inicio de sesión con permisos acotados, un historial de auditoría y un borrador de respuesta que cite los campos devueltos. Su ventaja sería ajustarse a los datos y las reglas de acceso de una empresa concreta. La dificultad es que los proveedores existentes quizá ya tengan ese conector, y las licencias de modelos del equipo, la limpieza de datos y el soporte siguen teniendo un costo. Valida esa necesidad con un responsable de soporte antes de añadir más herramientas.
La segunda oportunidad es una consulta de políticas que respete los permisos. Un responsable podría dar acceso a la colección de políticas aprobadas de una empresa mediante recursos o una herramienta de búsqueda acotada. DataForSEO estima 390 búsquedas mensuales en Google en Estados Unidos de «enterprise search», una cifra comprobada en la misma fecha. El MVP podría incluir una colección, citas de las fuentes, comprobaciones de vigencia y filtrado según los permisos de la persona que ha iniciado sesión. La dificultad es que la calidad de la recuperación y el control de acceso son el producto; dar acceso a una carpeta mediante MCP es fácil de copiar. La cifra de búsquedas es una señal de demanda para la tarea en general, no una prueba de que los usuarios pagarán por esta implementación.
Qué queda por resolver
MCP estandariza el acceso. La calidad de los datos, la autorización, la fiabilidad del backend y la decisión sobre qué puede hacer una herramienta siguen siendo tu responsabilidad. Un modelo puede interpretar mal un resultado válido, y los clientes conectados pueden diferir en las capacidades que admiten o en sus políticas de aprobación.
Crea este servidor cuando una interfaz de herramientas compartida vaya a mejorar un flujo de trabajo que puedas medir. Para una tarea por lotes fija en la que nunca haga falta que un asistente elija una herramienta, una llamada normal a una API o un script puede ser una implementación más adecuada.
Tu siguiente paso para el lunes: elige una consulta recurrente con alguien del equipo de soporte, conecta ambos clientes usando registros ficticios y después sustituye esos datos por una fuente accesible con una cuenta de solo lectura y comprueba los permisos por registro. Mantén las operaciones de escritura fuera de ese primer despliegue. Pasa a HTTP compartido cuando el flujo de trabajo y los controles de identidad estén preparados.
¿Es difícil crear un servidor MCP?
Crear un pequeño servidor de solo lectura con el SDK oficial es sencillo: define la función, describe su entrada y elige un transporte. Dar acceso seguro a los datos de una empresa requiere más trabajo, porque debes aplicar permisos, gestionar credenciales y operar el servicio.
¿Hay un servidor MCP gratuito para hacer pruebas?
El servidor de pedidos ficticios de este tutorial puede ejecutarse en local sin pagar alojamiento. MCP Inspector permite invocarlo sin una suscripción a un modelo. El alojamiento en la nube y el cliente de IA que elijas después tienen sus propias tarifas.
¿Cuánto cuesta un servidor MCP?
Un proceso local no necesita un plan de alojamiento independiente. Cloudflare Workers publica un nivel gratuito y un mínimo de $5/mes en el plan de pago. Render publica un precio de $7/mes por el cómputo de su servicio web de pago pequeño. Estas cifras excluyen el uso de modelos, los servicios de identidad, el almacenamiento y la ingeniería.
¿Tengo que instalar un servidor MCP?
Con stdio, el servidor se ejecuta en la máquina del cliente, así que su código y su entorno de ejecución deben estar disponibles allí. Con HTTP remoto, configuras un endpoint y te autenticas; el servidor se ejecuta en el proveedor de alojamiento. Utiliza un despliegue compatible con el cliente que hayas elegido.
Si quieres que construyamos y operemos un servicio MCP conectado a los datos de tu empresa para tu equipo, nuestro servicio de sistemas de IA en producción cubre la integración y sus controles de acceso.
- Publicado
- Categoría
- Build
- Idioma







