Skip to main content
Glama
nudge-digital-lab

TiendaTech Support MCP Server

Agente de soporte con servidor MCP propio

Proyecto 1 de una serie de 7 proyectos chicos, cada uno enfocado en una habilidad puntual que aparece hoy en avisos de trabajo para desarrolladores de agentes de IA. Este cubre: construir y consumir un servidor MCP (Model Context Protocol) desde cero.

El problema que resuelve

Una tienda de electrónica ("TiendaTech") necesita un agente de soporte que pueda:

  • Responder preguntas de clientes sobre políticas (devoluciones, garantía, envíos) sin inventar información.

  • Consultar y crear tickets de soporte reales, no simulados.

En vez de meter toda esa lógica adentro del prompt o hardcodeada en el cliente del LLM, ese acceso a datos vive en un servidor MCP separado: un proceso independiente que expone qué información y qué acciones están disponibles, con un contrato bien definido. El agente (el cliente que habla con Claude) no sabe nada de archivos ni de JSON — solo sabe que existe un servidor con ciertos recursos y herramientas.

Esto es exactamente el problema que MCP fue diseñado para resolver: separar "qué puede hacer un agente" de "qué modelo lo está operando", para no tener que reescribir la integración de datos cada vez que cambiás de LLM o de cliente.

Related MCP server: E-Commerce Support Agent MCP Server

Arquitectura

flowchart LR
    subgraph Cliente["src/agent.ts (proceso 1)"]
        CLI[REPL en terminal]
        MCPClient[Cliente MCP]
        Claude[Anthropic SDK]
    end

    subgraph Servidor["src/server.ts (proceso 2, hijo)"]
        MCPServer[Servidor MCP]
        Tools[Tools: search_tickets / get_ticket / create_ticket]
        Resources[Resources: artículos de la KB]
    end

    DB[(data/tickets.json)]
    KB[(data/kb/*.md)]

    CLI --> MCPClient
    MCPClient <-->|stdio JSON-RPC| MCPServer
    MCPServer --> Tools
    MCPServer --> Resources
    Tools <--> DB
    Resources <--> KB
    MCPClient --> Claude
    Claude -->|decide qué tool llamar| MCPClient

Son dos procesos Node separados que se comunican por stdio con el protocolo MCP (JSON-RPC 2.0):

  1. src/server.ts — el servidor MCP. No sabe nada de Claude ni de IA. Solo expone:

    • Resources (kb://politica-devoluciones.md, etc.): los 3 artículos de la base de conocimiento, como contenido de solo lectura pensado para dar contexto.

    • Tools (search_tickets, get_ticket, create_ticket): acciones que leen y escriben sobre data/tickets.json, una base de tickets de soporte.

  2. src/agent.ts — el agente. Levanta el servidor como proceso hijo, se conecta como cliente MCP, y hace de puente entre MCP y la API de Claude:

    • Al arrancar, lee todos los resources y los inyecta en el system prompt como contexto fijo.

    • Traduce la lista de tools del servidor al formato de tool-use de la API de Claude.

    • Corre un loop de conversación: si Claude decide llamar una tool, el agente ejecuta esa llamada contra el servidor MCP real y le devuelve el resultado, hasta que Claude da una respuesta final en texto.

Decisiones técnicas y por qué

  • Resources vs. Tools, a propósito. MCP distingue explícitamente entre datos de contexto (resources, decisión de cuándo leerlos la toma el host/agente) y acciones invocables por el modelo (tools, decisión de cuándo usarlas la toma el LLM). Usar ambos primitivos — y no meter todo como tools — muestra que la separación es intencional, no que "tools es lo único que existe en MCP".

  • Transporte stdio, no HTTP/SSE. Para un servidor MCP local de un solo cliente, stdio es más simple: no hay puertos, no hay CORS, no hay que levantar un server HTTP aparte. El SDK oficial de Anthropic soporta stdio, SSE y Streamable HTTP — stdio es el punto de entrada correcto para entender el protocolo antes de pasar a un despliegue remoto.

  • JSON planos en vez de SQLite/Postgres. El foco del proyecto es demostrar el protocolo MCP (cómo se define un tool, cómo se valida su input, cómo un cliente lo descubre y lo invoca), no la capa de persistencia. Cambiar data/tickets.json por una base real implica tocar únicamente readTickets/writeTickets en server.ts — el contrato MCP hacia el agente no cambia.

  • TypeScript + SDK oficiales. @modelcontextprotocol/sdk (servidor y cliente) y @anthropic-ai/sdk son los paquetes oficiales de Anthropic. Se usa la API de alto nivel McpServer (registerTool/registerResource) en vez de la API de bajo nivel con setRequestHandler, porque valida automáticamente el input contra el schema de Zod y da mensajes de error más claros — importante cuando el que "llena" los argumentos es un LLM y no un humano.

  • Sin frameworks de agentes (LangChain, etc.). El loop de tool-use (llamar al modelo → detectar tool_use → ejecutar → devolver tool_result → repetir) se escribe a mano en ~40 líneas. Para un solo agente con 3 tools, un framework agrega abstracción sin resolver un problema real; y entender ese loop sin magia es la habilidad que se quiere mostrar acá.

Stack

  • Node.js 22 + TypeScript

  • @modelcontextprotocol/sdk — servidor y cliente MCP

  • @anthropic-ai/sdk — Claude (modelo claude-sonnet-4-5)

  • zod — validación de inputs de las tools

  • Sin base de datos externa: data/tickets.json + data/kb/*.md

Cómo correrlo

npm install
cp .env.example .env   # completar ANTHROPIC_API_KEY
npm start               # compila y levanta el agente (que a su vez levanta el servidor MCP)

Ejemplo de conversación:

Vos: hola, tengo un teclado que no me terminó gustando, ¿lo puedo devolver?
Agente: Sí, podés devolverlo dentro de los 30 días de la compra siempre que esté sin uso...

Vos: se me rompió el auricular izquierdo de mis auriculares, ¿tienen algún ticket mío?
  → llamando herramienta MCP: search_tickets({"query":"auricular"})
Agente: Sí, encontré el ticket #1 a nombre de Marcos Videla, sigue abierto...

Si querés inspeccionar el servidor MCP de forma aislada (sin Claude), se puede correr con el MCP Inspector oficial:

npm run build
npx @modelcontextprotocol/inspector node dist/server.js

Estructura

src/
  server.ts     # servidor MCP: resources + tools
  agent.ts      # cliente MCP + integración con Claude + REPL
data/
  kb/*.md       # base de conocimiento (resources)
  tickets.json  # base de tickets (tools)

Qué demuestra este proyecto

  • Entender MCP como protocolo (no solo como "una librería más"): distinción resources/tools, transporte, ciclo de vida de conexión.

  • Diseñar el input schema de una tool con Zod pensando en que quien la va a llamar es un LLM, no un formulario.

  • Integrar el tool-use de la API de Claude con una fuente de tools que no está hardcodeada, sino descubierta dinámicamente en runtime contra un servidor externo.

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers