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.