TL;DR
Model Context Protocol (MCP) se convirtió en el estándar de facto para conectar LLMs con herramientas y datos empresariales. Pero la mayoría de ejemplos públicos son juguetes: un hello world en Python sin autenticación, sin row-level security y sin pruebas. En este artículo publicamos numoru-ia/mcp-templates-es, diez servidores MCP listos para producción: CRM (HubSpot/Pipedrive), WhatsApp Business Cloud, facturación CFDI 4.0 para México, Google Calendar, Postgres con RLS multi-tenant, RAG con Qdrant, tickets (Zendesk/Freshdesk), inventario, pagos (Stripe/Mercado Pago) y documentos (Google Drive). Todos en Go y TypeScript, con OAuth 2.1, tests e2e, Docker y despliegue opcional a Cloudflare Workers.
¿Por qué hacen falta "templates" MCP?
La especificación MCP resuelve el transporte (stdio, HTTP con SSE, streamable HTTP) y el shape de las respuestas (resource, tool, prompt). Pero deja al implementador tres decisiones críticas sin guía estandarizada:
- Autenticación y autorización. ¿Cómo valida el servidor que el usuario X puede leer los contactos de su empresa pero no los de otra?
- Idempotencia y escritura segura. ¿Qué pasa cuando el LLM llama dos veces a
create_invoicepor un timeout? ¿Cómo evitas duplicados? - Contratos tipados con errores predecibles. El LLM necesita respuestas consistentes; si tu tool a veces devuelve
nully a veces{"error": "..."}, el agente se rompe.
Los templates de este repo resuelven los tres puntos de forma uniforme. Cada servidor sigue la misma estructura:
mcp-<nombre>/
├── cmd/server/main.go # entrypoint (o src/index.ts para TS)
├── internal/
│ ├── auth/ # OAuth 2.1 + tenant resolution
│ ├── tools/ # herramientas expuestas
│ ├── resources/ # recursos expuestos
│ ├── prompts/ # prompts parametrizables
│ └── storage/ # persistencia
├── migrations/ # si usa DB propia
├── tests/e2e/ # cliente MCP real + assertions
├── Dockerfile
├── wrangler.toml # opcional: Cloudflare Workers
└── README.md
El patrón estándar resource/tool/prompt
Todo template expone los tres tipos de MCP con reglas estrictas:
Resources
Datos leíbles, identificados por URI. Siempre devuelven JSON válido y versionado.
// Ejemplo: resource de contactos CRM
// URI: crm://contacts/{contact_id}
type ContactResource struct {
ID string `json:"id"`
TenantID string `json:"tenant_id"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
// ...
}
Tools
Acciones con efecto lateral. Cada tool tiene un operation_id único que sirve de clave de idempotencia.
// create_invoice(customer_id, items, operation_id) → invoice_id
// Si ya existe una factura con ese operation_id, la devuelve; no crea duplicado.
Prompts
Plantillas reutilizables que el cliente LLM puede invocar por nombre.
"create_follow_up_email(contact_id, tone='friendly')"
→ devuelve mensajes formateados listos para Claude/GPT
Los 10 templates publicados
1. mcp-crm
Conecta HubSpot o Pipedrive. Resources: contacts, deals, companies. Tools: create_contact, update_deal_stage, log_activity. Autenticación OAuth 2.1 con refresh token en Postgres cifrado. Soporta multi-tenant: cada token está asociado a un workspace_id, y cualquier tool filtra por él antes de llamar a la API upstream.
func (s *Server) createContact(ctx context.Context, args CreateContactArgs) (*Contact, error) {
tenantID, err := auth.TenantFromContext(ctx)
if err != nil {
return nil, mcp.ErrUnauthorized
}
return s.hubspot.CreateContact(ctx, tenantID, args)
}
2. mcp-whatsapp
Wrapper de WhatsApp Business Cloud API. Resources: conversations, messages. Tools: send_text, send_template, send_media, mark_as_read. Incluye guardrail obligatorio: no permite enviar mensajes fuera de la ventana de 24h sin plantilla aprobada (evita que el LLM caiga en violación de política de Meta).
3. mcp-cfdi
Facturación electrónica México 4.0. Tools: create_invoice, cancel_invoice, get_xml, get_pdf. Integra con PAC (Facturama, Finkok, SW Sapien) vía driver intercambiable. Valida RFC, régimen fiscal y uso CFDI antes de timbrar. Guarda el XML timbrado en Spaces y devuelve URL firmada.
4. mcp-calendar
Google Calendar + Microsoft Graph. Resources: events, availability. Tools: create_event, find_slot, cancel. Incluye algoritmo find_slot que respeta zona horaria del usuario, horario laboral configurable y eventos existentes — el agente no tiene que implementar lógica de disponibilidad.
5. mcp-postgres-rls
El más crítico para SaaS multi-tenant. Expone Postgres como MCP con row-level security real activado a nivel de base de datos. El servidor establece SET app.current_tenant = $1 en cada conexión del pool, y las policies de RLS garantizan que una query inyectada por el LLM no pueda leer filas de otro tenant.
CREATE POLICY tenant_isolation ON contacts
USING (tenant_id::text = current_setting('app.current_tenant'));
Tools: query (SELECT validado por parser), execute (solo INSERT/UPDATE/DELETE con whitelist de tablas), describe_schema.
6. mcp-qdrant-rag
Retrieval Augmented Generation como servicio MCP. Resources: collections, documents. Tools: search_semantic, search_hybrid (dense + BM25), add_document, reindex. Soporta reranking con BGE-reranker v2-m3 local y Contextual Retrieval de Anthropic. Trazas opcionales a Langfuse.
7. mcp-tickets
Zendesk y Freshdesk. Resources: tickets, agents. Tools: create_ticket, assign, reply, close, merge. Incluye ranking de prioridad automático usando un small model local vía LiteLLM.
8. mcp-inventory
Genérico para catálogos: productos, stock, ubicaciones. Tools: search_product, check_stock, reserve, release. Driver por adaptador: Shopify, WooCommerce, Odoo, o base de datos propia.
9. mcp-payments
Stripe + Mercado Pago. Tools: create_payment_link, refund, get_transaction, list_disputes. No expone create_charge directo con datos de tarjeta — fuerza al LLM a usar hosted pages o tokens, mitigando riesgo PCI.
10. mcp-drive
Google Drive + Box. Resources: files, folders. Tools: search, download, upload, share. Incluye ingesta automática con Unstructured.io + chunking con Chonkie para que el contenido quede indexable por mcp-qdrant-rag.
OAuth 2.1 estandarizado
Todos los templates comparten el mismo flujo OAuth. El cliente MCP envía un token opaco; el servidor lo valida contra Postgres y resuelve el tenant. El token se refresca con 5 minutos de margen antes de expirar.
type Principal struct {
UserID string
TenantID string
Scopes []string
}
func (s *Server) middleware(next mcp.Handler) mcp.Handler {
return mcp.HandlerFunc(func(ctx context.Context, req mcp.Request) (mcp.Response, error) {
token := mcp.AuthTokenFromContext(ctx)
principal, err := s.auth.Validate(ctx, token)
if err != nil {
return nil, mcp.Unauthorized("token inválido")
}
ctx = auth.WithPrincipal(ctx, principal)
return next.Handle(ctx, req)
})
}
Idempotencia: la clave que todos olvidan
Cualquier tool con efecto lateral acepta un parámetro operation_id. El servidor guarda en Postgres una tabla operations(operation_id, tenant_id, tool, result_json, created_at) con índice único compuesto. Si la misma operación se recibe dos veces, se devuelve el resultado cacheado sin volver a llamar al upstream.
Esto resuelve tres bugs clásicos de agentes LLM:
- Retries del cliente tras timeout → duplicado de factura
- Agente que decide "mejor intentar de nuevo" → duplicado de email
- Flujo multi-step interrumpido a mitad → operación parcial repetida
Despliegue: tres opciones
Opción A — Docker Compose local
docker compose up -d levanta cualquier template con su Postgres, Redis y servidor HTTP. Ideal para desarrollo y para clientes que exigen self-host.
Opción B — Cloudflare Workers (serverless MCP)
Cada template TS incluye wrangler.toml. Deploy en un comando:
npx wrangler deploy
Cloudflare Workers soporta MCP sobre streamable-http nativamente desde finales de 2025. El servidor aguanta ráfagas sin pagar por tiempo de idle — perfecto para clientes PyME que reciben 200 requests al día.
Opción C — Digital Ocean droplet compartido
Usando el stack del artículo Stack de IA self-hosted en un droplet de DO, los 10 servidores MCP se montan tras Nginx como sub-paths (/mcp/crm, /mcp/whatsapp, ...). Una sola instancia Postgres compartida con schemas separados.
Testing e2e estandarizado
Cada template incluye una suite que levanta el servidor en un container efímero y corre un cliente MCP real contra él. No mocks — las aserciones validan flujo completo de OAuth, idempotencia y errores tipados.
func TestCreateInvoiceIdempotent(t *testing.T) {
srv := testutil.StartServer(t)
client := mcp.Dial(srv.URL, testToken)
args := CreateInvoiceArgs{OperationID: "op-123", /* ... */}
r1, _ := client.CallTool(ctx, "create_invoice", args)
r2, _ := client.CallTool(ctx, "create_invoice", args)
assert.Equal(t, r1.InvoiceID, r2.InvoiceID, "mismo operation_id debe devolver misma factura")
}
Integración con Claude Agent SDK
Ejemplo minimalista: un agente que usa tres de nuestros servidores MCP para agendar una demo comercial desde una conversación de WhatsApp.
from anthropic import Anthropic
from mcp import stdio_client
client = Anthropic()
servers = [
stdio_client("./mcp-whatsapp"),
stdio_client("./mcp-crm"),
stdio_client("./mcp-calendar"),
]
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
tools=await aggregate_tools(servers),
messages=[{
"role": "user",
"content": "Un lead nuevo escribió por WhatsApp pidiendo demo. Crea contacto en CRM y agenda slot el próximo martes 3pm."
}],
)
El agente orquesta los tres MCPs sin necesidad de glue code ad-hoc.
Compatibilidad con otros clientes MCP
Probados y funcionales con:
- Claude Desktop
- Claude Code CLI
- Cursor
- Continue.dev
- Windsurf
- OpenAI Agents SDK (vía shim)
- VS Code extension MCP
Impacto de negocio y casos
Por qué los templates comprimen los ciclos de venta
Un chatbot enterprise integrado con CRM + WhatsApp + calendario solía ser un build de 3 meses. Con templates, el delivery se reduce a 4-6 semanas porque 80% del código de integración ya está escrito, probado y desplegado. Eso cambia la conversación de venta: en lugar de "dame 90 días", cotizas "agente vivo en 6 semanas, precio fijo". Los compradores cierran más rápido a margen más alto.
Tiempo observado para un chatbot B2B con MCP de 5 tools: CRM + WhatsApp + calendario + pagos + CFDI. De kickoff a producción.
- Desde cero
- Con templates Numoru
Telemetría interna Numoru de engagements, 2024-2026.
Industrias y rangos de ticket
Build de chatbot sobre templates — ticket por vertical (USD)
Benchmarks públicos que respaldan el pitch
Anthropic — lanzamiento Model Context Protocol
Meta — adopción WhatsApp Business Platform
Caso ilustrativo — agencia LATAM revendiendo templates
Agencia IA boutique (México / Buenos Aires) usando templates para 8 builds enterprise
Calculadora ROI — comprador enterprise del chatbot integrado
Retailer mid-market reemplazando atención Tier-1 (12 meses)
| Implementación (one-time) | −$32,000 |
| Retainer ops (12 mo × $1,200) | −$14,400 |
| Costo variable bot (104k × $0.22) | −$22,880 |
| Labour de soporte evitado (104k × $4.80) | +$499,200 |
| Lift de conversión WhatsApp | +$180,000 |
| Automatización CFDI (tiempo) | +$42,000 |
| Contribución neta año 1 | +$651,920 |
Tiers de pricing Numoru
- Los 10 servidores productivos
- Implementaciones Go + TS
- OAuth 2.1 + RLS + idempotencia
- Tests + Docker + config Workers
- Soporte comunidad (GitHub issues)
- 3-6 tool integrations
- Orquestación Claude Agent SDK
- Canal WhatsApp / web / Slack
- Observabilidad Langfuse
- Delivery 4-8 semanas
- Warranty 60 días + handover
- Proyectos ilimitados con clientes finales
- Fork privado + logo
- SLA priority de bug-fix
- Updates trimestrales de templates
- 8% rev-share en builds entregados
- Opción co-marketing
Retainer de ops post-build: $900-2,400 / mes según alcance y SLA.
FAQ
¿Puedo usar estos templates comercialmente?Sí, licencia Apache 2.0. Fork, modifica, cobra.
¿Cuánto cuesta mantenerlos?El stack base (droplet + Postgres + Redis) son ~50 USD/mes. Los templates agregan negligible CPU/RAM porque casi todo el trabajo es I/O contra APIs upstream.
¿Qué pasa si el upstream (HubSpot, Stripe, etc.) cambia su API?Cada template tiene un directorio internal/driver/<vendor>/ aislado. El contrato MCP es estable; los cambios de vendor sólo tocan el driver.
¿Pueden convivir con MCPs oficiales de cada proveedor?Sí. Estos templates existen porque los oficiales son pocos, inmaduros o no cubren idempotencia + multi-tenancy. Cuando el oficial alcance, migrar es trivial.
¿Tests de seguridad?Pipeline CI corre Semgrep (reglas p/owasp-top-ten), Bearer (detección de PII) y Trivy (CVEs en imagen Docker) en cada PR.
Próximos pasos
El repo github.com/numoru-ia/mcp-templates-es está publicado con los 10 servidores, documentación ejecutable y una carpeta examples/ con agentes de referencia. El plan de 2026 es agregar 5 templates más: ERP (Odoo/NetSuite), e-commerce (Shopify/VTEX), RR.HH. (BambooHR), firma digital (Mifiel/DocuSign) e impuestos (SAT/AFIP).
Si tu PyME usa ChatGPT Enterprise, Claude for Work o cualquier agente comercial y quieres conectarlo a tu operación sin 6 meses de integración custom, estos templates son el punto de partida más corto que conocemos.
Si prefieres entender el protocolo desde abajo antes de usar plantillas, un servidor MCP desde cero en Go. Para verlo aplicado a un dominio concreto, los agentes de agenda clínica con LangGraph.