Tots els articles

Per què construïm un servidor MCP per a gairebé tot

Publicat 13 de febr. del 20263 min de lectura
  • Enginyeria
  • IA

Idees clau

  • MCP estandarditza la mateixa disciplina que hi ha darrere de l'agent de WhatsApp de Lueira: eines petites, tipades i validades en lloc d'accions lliures del model.
  • El nostre servidor MCP intern de Ringover exposa 26 eines amb autenticació per petició, perquè qualsevol client de MCP pugui actuar sense una integració a mida.
  • MCP no és només per a chatbots: el servidor de catàleg del marketplace renderitza widgets interactius, però continua sense encaixar en panells purament humans.

En algun punt entre llançar l'agent d'IA de WhatsApp de Lueira i muntar una eina interna per al nostre propi equip d'operacions, em vaig adonar que havíem deixat de preguntar-nos "això hauria de ser una API REST o un panell?" i havíem començat a preguntar-nos "quines eines necessita el client d'IA?". És un canvi petit d'enfocament, però ha canviat com construïm gairebé tot allò que no és una pantalla purament orientada a persones. Aquest post tracta de senyalar aquest patró en veu alta, a través de tres peces d'eines internes molt diferents.

1. El patró que vam començar sense adonar-nos-en

En un post anterior vaig escriure sobre com funciona l'agent d'IA de WhatsApp de Lueira: no un model improvisant contra un calendari de reserves, sinó un conjunt petit i estrictament tipat d'eines — check_availability, create_booking, send_payment_link — que el model pot invocar, cadascuna validada contra el motor de reserves real abans que res es confirmi. L'objectiu d'aquell disseny no era la part d'IA; era la disciplina. Definir una superfície estreta d'accions, tipar cada entrada i sortida, i no deixar mai que el model toqui la base de dades directament.

Un cop aquesta disciplina existeix per a un producte, resulta ser la resposta correcta per a problemes que no tenen res a veure amb WhatsApp ni amb reserves. Model Context Protocol (MCP) — el protocol obert d'Anthropic — és essencialment aquesta mateixa idea estandarditzada: en lloc de construir una integració a mida entre "el model" i "el nostre sistema", exposes un conjunt d'eines tipades sobre un transport comú, i qualsevol client compatible amb MCP les pot descobrir i invocar.

2. Ringover: convertir una API de telefonia en eines reutilitzables

L'exemple més clar és intern, no de cara al client. Fem servir Ringover per a trucades, SMS, plantilles de WhatsApp i contactes, i com la majoria de proveïdors de telefonia SaaS té una API REST que ningú a Maladeta vol integrar a mà cada vegada que algú necessita saber "pots comprovar qui ens va trucar la setmana passada?". Així que vam construir un servidor MCP per a ella — fent servir el framework xmcp — que exposa 26 eines seleccionades entre trucades, analítica de trucades per IA, contactes, missatgeria, control de trucades en directe i cerques de directori.

L'autenticació és per petició: el servidor no emmagatzema les credencials de Ringover de ningú, reenvia la pròpia API key de Ringover de qui fa la trucada en cada petició. El que això ens dona a la pràctica és que qualsevol amb un client compatible amb MCP pot preguntar "quantes trucades perdudes vam tenir la setmana passada?" o "envia un SMS a aquest client dient que anem tard" i obtenir una resposta o una acció, sense que ningú escrigui codi d'integració a mida. Així és, de manera simplificada, com és una d'aquestes eines:

export const schema = {
  to: z.string().describe("E.164 phone number of the recipient"),
  message: z.string().max(1600).describe("SMS body to send"),
  from_number_id: z.string().describe("Ringover number to send the SMS from"),
};

export const metadata = {
  name: "ringover_send_sms",
  description: "Send an SMS to a contact through Ringover",
};

export default async function ringoverSendSms(
  { to, message, from_number_id },
  { ringoverApiKey }
) {
  const result = await ringoverClient(ringoverApiKey).sms.send({
    to,
    body: message,
    number_id: from_number_id,
  });

  if (!result.ok) {
    throw new Error(`Ringover rejected the SMS: ${result.error}`);
  }

  return { status: "sent", message_id: result.id };
}

3. Widgets interactius, no només dades

La plataforma de Marketplace Genèric — el nucli compartit darrere de RocRoi, KayakGrandTour i NaturaAdventour — va portar el patró a un lloc que no esperava: més enllà de les dades i cap a la interfície. El seu servidor MCP de catàleg no només exposa eines que retornen JSON; també exposa widgets "MCP App", com una fitxa de producte o un calendari de disponibilitat, que es renderitzen directament dins la pròpia interfície d'un client compatible amb MCP — Claude o ChatGPT, sense que cap dels dos productes hagi hagut de construir una interfície a mida per a això.

4. Quan MCP és la resposta correcta, i quan no

Un panell purament orientat a persones no millora perquè hi cargolis un servidor MCP. MCP es guanya el seu lloc específicament quan un client d'IA necessita fer de manera fiable una acció real o extreure dades reals, i prefereixes definir això un cop en lloc de construir una integració a mida cada vegada.

Construir bé un servidor MCP requereix exactament la mateixa disciplina que sempre ha requerit construir una bona API. És temptador embolicar cada taula de la teva base de dades en una eina i dir-ne "habilitat per a MCP", i això és una idea pitjor que no construir-ne cap.

El que ha canviat per a nosaltres no és la disciplina — és el punt de partida per defecte. Fa un any, "necessitem que la IA parli amb aquest sistema" volia dir una integració puntual. Ara vol dir: definir un conjunt petit d'eines tipades, validar cada crida contra el sistema de registre real, i exposar-les sobre MCP.