Para empresas Para grandes empresas Soluciones Aplicaciones Precios Desarrolladores Blog Documentación Iniciar un espacio de trabajo
Blog / MCP para software empresarial

MCP para ERP: una guía práctica

Una guía para constructores. Asume que has leído la especificación o el artículo complementario sobre qué es un servidor ERP MCP, y se concentra en las decisiones que la especificación deja a tu cargo: qué acciones publicar, cómo llamarlas, cómo la identidad del llamador llega a cada llamada y qué debe hacer una escritura cuando un modelo la reintenta. La herramienta de ejemplo es real.

7 minutos de lecturaActualizado 4 de septiembre de 2026Ingeniería de Sois, el equipo que construye la plataforma

Un banco de trabajo en un pequeño estudio de ingeniería: cajones de piezas etiquetados, un esquema impreso bajo un clip, un portátil cerrado y una lámpara de soldadura apagada.
Respuesta corta

Construir MCP para ERP se reduce a cuatro decisiones. Exponer transacciones, no tablas: una herramienta debe ser algo que una persona podría hacer en el sistema, como crear una factura o registrar un pago, con las reglas de negocio dentro de ella. Nombra y describe cada herramienta para el modelo que leerá la lista, con las restricciones que debe respetar en la descripción en lugar de en la documentación que nunca verá. Deja que la identidad OAuth en cada solicitud decida tanto qué herramientas se enumeran como si cada llamada se ejecuta. Y diseña cada escritura de manera que un reintento, una negativa o una pregunta sean seguros, porque un modelo producirá las tres.

El transporte, el descubrimiento y el inicio de sesión están especificados y cualquier SDK los maneja. El valor del servidor radica en esas cuatro decisiones, y un sistema empresarial que las acierte es operable por Claude, ChatGPT o cualquier otro cliente sin que ese cliente sepa nada al respecto.

Empieza por la transacción, no por la tabla.

El primer instinto al exponer un ERP es generar una herramienta por tabla con crear, leer, actualizar y eliminar en cada una. Produce una lista grande y uniforme que un modelo maneja mal, porque la regla de negocio de que una factura necesita una tasa de impuesto en cada línea, o que el stock no puede ser despachado antes de ser reservado, no está en ningún lugar que el modelo pueda ver. Exponer las acciones en su lugar. Una prueba útil es si una persona podría describir la herramienta como algo que hizo hoy: levantar una factura, registrar un pago, mover un trato, posponer un seguimiento. Cada uno de esos lleva sus reglas, valida sus entradas y devuelve un resultado legible.

Junto a las acciones, añade un pequeño número de herramientas de resumen que respondan a las preguntas que un modelo hace antes de actuar. Una llamada que devuelve el perfil de una cuenta, su estado, elementos abiertos e historia reciente ahorra al modelo cuatro llamadas y varios miles de tokens de contexto, y hace que la siguiente acción esté mejor informada. Sois llama a estas herramientas examinadoras; examinarContacto y obtenerResumenContable son dos. También mantén en vista la superficie total: Claude Code limita la salida de un servidor por llamada de forma predeterminada, y tanto Claude como OpenAI ofrecen carga diferida o búsqueda de herramientas para listas grandes, por lo que un servidor con varios cientos de herramientas debería devolverlas en un orden determinista (la especificación lo solicita para que los clientes puedan almacenar en caché) y debería filtrar por rol antes de listar.

Nombrar herramientas para que un modelo elija la correcta.

La especificación restringe los nombres ligeramente: uno de hasta 128 caracteres, letras, dígitos, guion bajo, guion y punto, sensible a mayúsculas y minúsculas, único dentro del servidor. Todo lo demás es convención, y la convención que funciona es un verbo seguido del sustantivo comercial en un caso consistente, con los mismos verbos significando lo mismo en todas partes. Un modelo eligiendo entre buscarFacturas, obtenerFactura y crear factura está eligiendo entre una lista, un registro y una escritura, y aprende ese patrón una vez para todo el servidor.

DébilMejorPor qué
facturacrear facturaUn sustantivo solo no indica si lee o escribe; un cliente no puede anotarlo y un modelo no puede clasificarlo frente a sus hermanos.
facturaCrearV2Finalcrear facturaLa versión y el estado pertenecen al servidor, no al nombre. Los nombres que cambian rompen las listas de herramientas en caché y los cachés de indicaciones.
hacerContabilidadregistrarPago, enviarRecordatoriosDeFacturaUn catch-all con un argumento de modo oculta la transacción. Un nombre por transacción permite al cliente aplicar confirmación por herramienta.
obtener_factura y obtenerContacto mezcladoUn caso en todoLos clientes agregados prefijan nombres por servidor; la consistencia dentro de un servidor es de lo que depende el modelo.

La descripción lleva el resto: cuándo usar la herramienta, cuándo no, y cualquier regla que el modelo debe respetar antes de llamarla.

Las descripciones son leídas por un modelo bajo presión para actuar, así que escríbelas como instrucciones. Indica lo que hace la herramienta en la primera frase, luego las condiciones. Si una herramienta hermana es la elección correcta para una solicitud cercana, dilo por nombre. Si un campo debe establecerse para que el resultado sea correcto, dilo en MAYÚSCULAS si es necesario; la herramienta de facturación de Sois le dice al modelo que la tasa de impuesto debe establecerse en cada línea y que las tasas exactas provienen de listar tipos de impuestos, because an invoice with no VAT is a worse failure than a refused call. Include one example call. Everything the model needs to call the tool correctly should be in the tool, because it will never open your documentation.

Una definición de herramienta de ejemplo.

Esta es una herramienta de facturación de Sois tal como la recibe un cliente de tools/list , recortado a los campos que importan, con anotaciones y un esquema de salida añadidos en la forma que define la especificación actual. Muestra el patrón: un nombre verbo-sustantivo, una descripción instructiva, un esquema cuyas descripciones de propiedades previenen errores del modelo, y pistas que un cliente puede usar para decidir si confirmar.

{
  "name": "createInvoice",
  "title": "Create invoice",
  "description": "Create a new invoice of any type and return the draft with its auto-generated number. TAX: set tax_rate on each line (for example 20 for 20% VAT); call listTaxTypes for this workspace's exact rates. If the user says 'plus VAT' you MUST set tax_rate or the invoice goes out with no VAT. To email the result use sendInvoice. Example: createInvoice({ type: \"sales_invoice\", contact_id: \"uuid\", currency: \"GBP\", lines: [{ description: \"Consulting\", quantity: 10, unit_price: 150 }] })",
  "inputSchema": {
    "type": "object",
    "properties": {
      "type": { "type": "string", "description": "sales_invoice, purchase_invoice, sales_credit_note or purchase_credit_note" },
      "contact_id": { "type": "string", "description": "Contact UUID (bill-to for sales, bill-from for purchases)" },
      "currency": { "type": "string", "description": "ISO code, for example GBP. Uses the workspace default if omitted" },
      "invoice_date": { "type": "string", "description": "ISO date. Defaults to today" },
      "reference": { "type": "string" },
      "lines": {
        "type": "array",
        "description": "Line items. Every line MUST carry the numeric unit_price the user asked for",
        "items": {
          "type": "object",
          "properties": {
            "description": { "type": "string" },
            "quantity": { "type": "number", "description": "Defaults to 1" },
            "unit_price": { "type": "number", "description": "NUMBER only: no currency symbols, no thousands separators. Use the exact amount stated; never guess or round" },
            "tax_rate": { "type": "number" },
            "discount_percent": { "type": "number" }
          },
          "required": ["description", "unit_price"]
        }
      }
    },
    "required": ["type"]
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "invoice_id": { "type": "string" },
      "number": { "type": "string" },
      "status": { "type": "string" },
      "total": { "type": "number" }
    },
    "required": ["invoice_id", "number", "status"]
  },
  "annotations": {
    "readOnlyHint": false,
    "destructiveHint": false,
    "idempotentHint": false,
    "openWorldHint": false
  }
}

Las anotaciones dicen: esto escribe, solo añade (un borrador), llamarlo dos veces crea dos borradores, y no toca nada fuera del sistema. Los clientes deben tratar las anotaciones como no confiables a menos que el servidor sea confiable, por lo que son pistas para el comportamiento de confirmación, no un sustituto de las propias comprobaciones del servidor.

Tres elecciones en esa definición son deliberadas. El resultado devuelve un identificador que el modelo debe llevar a enviar factura y registrarPago, que es la forma recomendada por la especificación para relacionar llamadas ahora que los servidores no mantienen estado de sesión. La herramienta crea un borrador, no una factura publicada, por lo que la escritura es aditiva y una persona o una herramienta de aprobación separada la finaliza. Y el esquema de salida significa que una integración puede leer el número y el total como datos, mientras que el modelo lee el mismo resultado como texto.

Limitar herramientas al usuario.

A través de HTTP, el llamador llega con un token de acceso OAuth vinculado a su servidor, y ese token identifica a una persona. La especificación permite que el resultado de tools/list variará según las credenciales en la solicitud, por lo que la primera decisión de alcance es filtrar la lista según el rol de esa persona antes de devolverla: un usuario de almacén no recibe aprobar facturaLa lista no debe variar por conexión ni como efecto secundario de otras llamadas, solo por autorización, lo que la hace almacenable en caché.

La segunda decisión es comprobar de nuevo en la ejecución. Un cliente puede enviar cualquier llamada que desee, y un modelo puede ser manipulado por texto en un resultado de herramienta para intentar una. Resuelve el usuario del token en cada llamada, verifica el permiso que la herramienta requiere y rechaza con un error de ejecución de herramienta que el modelo puede leer. Mantén los ámbitos de OAuth amplios (Sois emite ámbitos de lectura, escritura y fuera de línea) y deja que los propios roles del ERP sean el límite detallado, porque esos roles ya existen, ya se mantienen y ya significan algo para el negocio. Atribuye cada llamada a la persona en el registro con sus argumentos y resultado, para que el trabajo de un agente sea revisable exactamente como lo es el de una persona.

  1. El token llegaValida la firma y que el público sea este servidor, como requiere la RFC 8707; rechaza cualquier otra cosa con 401.
  2. Resuelve la personaAsocia el token a un usuario en el espacio de trabajo y carga su rol y aplicaciones instaladas.
  3. Filtra la listaDevuelve solo las herramientas que ese rol puede usar, en un orden estable, de tools/list.
  4. Verifica la llamadaEn tools/call, verifica de nuevo el permiso y rechaza con isError si falta; no se ejecuta nada.
  5. Ejecuta y registraEjecuta la transacción, mide si tu propio agente hizo el razonamiento, y escribe la llamada en el registro de auditoría bajo esa persona.

Manejo de escrituras.

Un modelo que recibe un resultado ambiguo volverá a llamar, y uno que recibe un error intentará una entrada corregida. Diseña para eso. Las escrituras que crean deben devolver un identificador y, cuando sea posible, aceptar una clave de idempotencia o una clave natural para que se detecte una repetición. Las escrituras que cambian de estado deben ser explícitas sobre la transición que realizan y rechazar las imposibles con una razón legible: registrar un pago contra una factura anulada es un isError resultado que lo indique, no una operación silenciosa y no un seguimiento de pila. Nunca dejes una escritura parcial; si una herramienta de múltiples pasos no puede completarse, revierte y reporta.

  • Prefiere borradores y aprobaciones. Haz que la creación sea aditiva (un borrador) y da a la finalización su propia herramienta con su propio permiso, de modo que el paso destructivo sea el que un cliente confirma y un rol controla.
  • Marca las herramientas destructivas. Establecer destructiveHint sobre anulaciones y eliminaciones y decirlo en la descripción; Claude y ChatGPT utilizan tales señales al decidir preguntar antes de llamar.
  • Pregunta en lugar de adivinar. Cuando una llamada necesita una decisión que la herramienta no puede tomar, devuelve un resultado que requiere entrada con una solicitud de elicitud; el cliente plantea la pregunta a la persona y vuelve a intentar la llamada con la respuesta.
  • Limita el radio de explosión. Limita la tasa por conexión, establece un límite de gasto por integración donde tu propio agente realiza razonamientos, y valida cada entrada del lado del servidor independientemente del esquema, porque el esquema es un consejo para el modelo, no una imposición.

Probar la superficie con un cliente real.

El inspector de MCP ejercerá tools/list y tools/call y seguir el flujo de OAuth. La verdadera prueba es un modelo. Conecta Claude como un conector personalizado, o ChatGPT en modo desarrollador, inicia sesión como un usuario con un rol limitado y pide un resultado rutinario que necesite tres o cuatro herramientas. Observa qué herramientas elige y por qué; una elección incorrecta es casi siempre un problema de descripción. Luego inicia sesión como un usuario sin uno de los permisos y confirma que la ejecución se detiene en la llamada correcta con una razón que el modelo repite.

Así es como se construye y verifica el servidor del espacio de trabajo de Sois: transacciones como herramientas, descripciones instructivas, una lista filtrada por roles, una segunda verificación en cada llamada, borradores antes de las aprobaciones y un registro que una persona puede leer. Los desarrolladores que crean aplicaciones para el mercado publican herramientas en la misma lista bajo las mismas reglas, por lo que una aplicación es operable por cualquier agente en el momento en que se instala. El patrón no es específico de un producto; cualquier ERP que lo adopte se convierte en algo que un agente puede ejecutar.

Preguntas que la gente hace

¿Cuántas herramientas debería exponer un servidor ERP MCP?

Tantas como transacciones que valga la pena automatizar, filtradas por usuario para que cada llamador vea un conjunto funcional. Varios cientos es normal para un sistema completo; lo que importa es que la lista sea estable, filtrada por rol y organizada por verbos consistentes para que el modelo pueda clasificar candidatos.

¿Debería usar ámbitos de OAuth para permisos granulares?

Utilice ámbitos amplios para la conexión y los propios roles del ERP para el límite granular, verificado en cada llamada. Los roles ya existen y son mantenidos por la empresa; un esquema de ámbitos paralelo se desviaría de ellos.

¿Cómo debería comportarse una escritura si el modelo la llama dos veces?

Detecte la repetición a través de una idempotencia o clave natural y devuelva el registro existente, o haga que la escritura sea aditiva y claramente informada para que el duplicado sea visible. Nunca falle en silencio y nunca deje una escritura parcial.

¿Las anotaciones de herramientas son impuestas por el cliente?

No. Son indicios, y la especificación indica a los clientes que las traten como no confiables a menos que el servidor sea de confianza. Los clientes las utilizan para elegir el comportamiento de confirmación; las propias verificaciones de permisos y validación del servidor son las que previenen daños.

Fuentes
  1. Especificación del Protocolo de Contexto del Modelo (2026-07-28): herramientas nombres de herramientas, esquemas, anotaciones, resultados estructurados, manejo de errores y la guía de manejo con estado
  2. especificación del Protocolo de Contexto del Modelo: autorización validación de audiencia de token, desafíos de ámbito y el modelo de autorización por solicitud
  3. OpenAI Apps SDK: construir un servidor MCP cómo ChatGPT utiliza readOnlyHint, destructiveHint y openWorldHint para el comportamiento de confirmación
  4. Documentación de Sois: el servidor MCP del espacio de trabajo la referencia de la herramienta de la que se extrae el ejemplo, filtrado de roles, límites y códigos de error

Este artículo se revisa cuando cambian los productos que describe. Próxima revisión programada: 4 de diciembre de 2026.

Comenzar

Construye sobre Sois.

Conecta tu propio agente a las herramientas de construcción, describe la aplicación, valídala, publícala y gana por su uso.

  • Gratis para empezar
  • Trae tu propio agente
  • Sin bloqueo de proveedor