Desarrolla tus propias herramientas MCP
Qué cubre este artículo
- Cómo desarrollar herramientas MCP personalizadas para agentes de IA.
- Cómo configurar un servidor MCP y registrar herramientas.
- Cómo construir herramientas personalizadas para tareas específicas.
- Ejemplos prácticos para diferentes tipos de herramientas.
- Buenas prácticas en diseño, seguridad y documentación.
Introducción: herramientas MCP personalizadas explicadas
Las herramientas MCP personalizadas son integraciones a medida para tus agentes: conectan el agente con tus sistemas, APIs y fuentes de datos. No se trata solo de herramientas estándar, sino de instrumentos especializados diseñados para tus tareas específicas.
Este artículo está dirigido a desarrolladores que quieren construir herramientas MCP propias. Encontrarás los fundamentos en MCP y Permisos MCP.
¿Por qué necesito herramientas MCP personalizadas?
Imagina que tu agente debe consultar tu CRM interno. No existe una herramienta estándar para ello. Construyes una herramienta MCP personalizada: “query_crm(customer_id) → datos del cliente”. Ahora el agente puede usar tu CRM, especializado para tu infraestructura.
Herramientas MCP personalizadas en breve
Una herramienta MCP es una interfaz entre el agente y un sistema. Defines el nombre de la herramienta, descripción, parámetros, permisos y función. El agente utiliza la herramienta a través del invocador de herramientas.
La idea central es: integración personalizada para tareas específicas.
Para quién es este artículo
- Desarrolladores que construyen herramientas personalizadas para agentes.
- Especialistas en integración que conectan sistemas.
- Constructores de agentes que necesitan instrumentos especializados.
- DevOps que despliegan herramientas propias.
Conceptos clave
- MCP - Model Context Protocol. Útil para: integración de herramientas.
- Permisos MCP - Control de acceso. Útil para: seguridad.
- Invocador de herramientas - Llamar herramientas. Útil para: agentes.
- Ollama - Servidor de modelos local. Útil para: agentes.
Estructura de herramientas MCP
class CustomMCPTool:
"""Clase personalizada de herramienta MCP"""
def __init__(self):
self.name = "custom_tool"
self.description = "Qué hace esta herramienta"
self.permissions = {
"allowed_actions": ["read", "write"],
"rate_limit": 100
}
def get_tool_definition(self):
"""Definición de herramienta para MCP"""
return {
"name": self.name,
"description": self.description,
"parameters": {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Parámetro 1"
},
"param2": {
"type": "integer",
"description": "Parámetro 2"
}
},
"required": ["param1"]
}
}
def execute(self, param1, param2=None):
"""Ejecutar herramienta"""
# Verificar permisos
self.check_permission("execute")
# Lógica de la herramienta
result = self.do_something(param1, param2)
return result
Ejemplo práctico 1: herramienta CRM
class CRMTool:
"""Herramienta MCP para integración CRM"""
def __init__(self, crm_api_url, api_key):
self.api_url = crm_api_url
self.api_key = api_key
self.name = "query_crm"
self.description = "Consultar CRM"
def get_tool_definition(self):
return {
"name": self.name,
"description": "Consultar datos de clientes desde CRM",
"parameters": {
"type": "object",
"properties": {
"customer_id": {
"type": "string",
"description": "ID del cliente"
},
"fields": {
"type": "array",
"items": {"type": "string"},
"description": "Campos a retornar"
}
},
"required": ["customer_id"]
}
}
def query_crm(self, customer_id, fields=None):
"""Consultar CRM"""
# Verificar permisos
self.check_permission("read")
# Llamada a API
response = requests.get(
f"{self.api_url}/customers/{customer_id}",
headers={"Authorization": f"Bearer {self.api_key}"},
params={"fields": fields}
)
return response.json()
Ejemplo práctico 2: herramienta de correo electrónico
class EmailTool:
"""Herramienta MCP para envío de correos"""
def __init__(self, smtp_config):
self.smtp = smtp_config
self.name = "send_email"
self.description = "Enviar correo electrónico"
def get_tool_definition(self):
return {
"name": self.name,
"description": "Enviar correo electrónico",
"parameters": {
"type": "object",
"properties": {
"to": {"type": "string", "description": "Destinatario"},
"subject": {"type": "string", "description": "Asunto"},
"body": {"type": "string", "description": "Cuerpo del mensaje"}
},
"required": ["to", "subject", "body"]
}
}
def send_email(self, to, subject, body):
"""Enviar correo electrónico"""
# Verificar permisos
self.check_permission("send")
# Verificar límite de velocidad
self.check_rate_limit()
# Enviar correo
msg = MIMEText(body)
msg["Subject"] = subject
msg["To"] = to
with smtplib.SMTP(self.smtp["host"], self.smtp["port"]) as server:
server.send_message(msg)
return {"status": "sent", "to": to}
Ejemplo práctico 3: herramienta de extracción web
class WebScrapingTool:
"""Herramienta MCP para extracción de contenido web"""
def __init__(self):
self.name = "scrape_web"
self.description = "Extraer contenido de página web"
self.allowed_domains = ["example.com", "docs.example.com"]
def get_tool_definition(self):
return {
"name": self.name,
"description": "Extraer contenido de página web y texto",
"parameters": {
"type": "object",
"properties": {
"url": {"type": "string", "description": "URL"},
"selector": {"type": "string", "description": "Selector CSS (opcional)"}
},
"required": ["url"]
}
}
def scrape_web(self, url, selector=None):
"""Extraer contenido de página web"""
# Verificar dominio
domain = urlparse(url).netloc
if domain not in self.allowed_domains:
raise PermissionError(f"Dominio '{domain}' no permitido")
# Extracción
response = requests.get(url)
soup = BeautifulSoup(response.text, "html.parser")
if selector:
elements = soup.select(selector)
return [e.get_text() for e in elements]
else:
return soup.get_text()
Servidores MCP para herramientas personalizadas
from mcp import Server, Tool
# Crear servidor MCP
server = Server("custom-tools")
# Registrar tools
server.add_tool(Tool(
name="query_crm",
description="CRM abfragen",
parameters=crm_tool.get_tool_definition()["parameters"],
function=crm_tool.query_crm
))
server.add_tool(Tool(
name="send_email",
description="E-Mail senden",
parameters=email_tool.get_tool_definition()["parameters"],
function=email_tool.send_email
))
# Iniciar servidor
server.run(port=8000)
Consideraciones de seguridad
- Permisos: Cada tool debe validar permisos. Consulta Permisos MCP.
- Validación de entrada: Valida todos los parámetros (tipo, formato, rango).
- Rate-limiting: Establece límites de velocidad para APIs y llamadas externas.
- Secretos: No incluyas API keys en el código, usa variables de entorno.
- Auditoría: Registra todas las invocaciones de tools. Ver Audit Logging.
Errores frecuentes
- Tools demasiado complejos: Un tool debe tener una tarea clara. Evita herramientas que lo hacen todo.
- Descripciones deficientes: El modelo elige tools según su descripción. Sé preciso.
- Sin manejo de errores: El tool debe gestionar errores de forma robusta y devolver mensajes informativos.
- Documentación insuficiente: Documenta bien tus tools (parámetros, valores de retorno, errores).
- Demasiados parámetros: Más de 3-4 parámetros abruma al modelo. Agrupa parámetros complejos en objetos.
Enlaces relacionados
- MCP - Model Context Protocol.
- Permisos MCP - Control de acceso.
- Sistema de archivos MCP - MCP para sistemas de archivos.
- Seguridad MCP - Seguridad.
- Permisos de tools - Permisos.
Puntos clave:
- Tools MCP personalizadas: integración personalizada para tareas específicas.
- Estructura del tool: nombre, descripción, parámetros, permisos, función.
- Servidor MCP: registra tools y conecta agentes.
- Ideal para CRM, correo electrónico, web scraping, APIs internas.
- Los permisos, validación de entrada y auditoría son críticos.
FAQ
¿Qué es un tool MCP?
¿Cómo creo un tool MCP?
¿Qué tools puedo crear?
¿Cómo establezco permisos?
¿Qué tan importante es la descripción del tool?
¿Cómo aseguro mis tools?
¿Tools personalizados o estándar?
¿Cómo pruebo mis tools?
Fuentes y lecturas complementarias
- MCP - Model Context Protocol.
- MCP Specification - Especificación.


