Skip to main content
Glama
benethos-hub

Unofficial Lexware Office MCP Server

by benethos-hub

Servidor MCP no oficial para Lexware Office

CI PyPI Python Coverage License

Aviso legal

  • Este proyecto no está afiliado, respaldado ni patrocinado por Lexware ni por Haufe-Lexware GmbH & Co. KG. "Lexware" y "Lexware Office" son marcas comerciales de sus respectivos propietarios.

  • Utiliza la API pública documentada con una clave de API que usted genera y puede revocar usted mismo. El uso de esa API se rige por los términos propios de Lexware, que usted acepta de forma independiente a este proyecto. La API puede cambiar en cualquier momento, y las solicitudes pueden estar sujetas a límites de frecuencia o ser bloqueadas.

  • Accede a registros contables reales. El acceso de escritura está desactivado por defecto. Si lo activa, cualquier cosa creada a través de la API es un registro real y jurídicamente relevante: un documento finalizado no se puede retirar a través de la API.

  • Los datos pueden estar incompletos o desactualizados. Nada de esto es asesoramiento fiscal, contable o legal. No se fíe de ello para declaraciones, auditorías o sus obligaciones de contabilidad.

  • Se proporciona "tal cual", sin garantía. Está pensado para uso personal y profesional bajo su propio riesgo. Consulte LICENSE.

  • Para uso comercial, revise los términos de la API de Lexware y sus propias obligaciones de conservación y documentación.

Un servidor MCP que conecta un cliente MCP como Claude Desktop a una cuenta de Lexware Office a través de la API REST pública oficial. Pregunte sobre facturas, contactos, artículos y comprobantes en lenguaje natural, y deje que el cliente los obtenga por usted.

Estado: 0.2.0. El servidor gestiona contactos, comprobantes y documentos: los busca, los lee, los crea, los modifica, comprueba lo que sigue sin pagar, descarga un PDF y sube un recibo. get_profile responde qué cuenta está conectada. Cada herramienta de la tabla siguiente está construida, y cada una se probó contra una cuenta real. Habla con stdio con un cliente que lo inicia, y con HTTP transmisible detrás de un token de portador cuando algo más tiene que alcanzarlo: como imagen de contenedor publicada, con un archivo Compose para ambos. Consulte SPECS.md para la especificación técnica completa y la hoja de ruta.

Por qué existe

Lexware Office contiene la contabilidad diaria de una pequeña empresa. La mayoría de las preguntas sobre ella son preguntas de lectura: qué sigue sin pagar, qué pidió este cliente, qué recibo corresponde a ese gasto — y esas son exactamente las preguntas que un asistente responde bien una vez que puede ver los datos. Este servidor lo hace posible sin exportar nada, usando una clave de API que el propietario de la cuenta genera y puede revocar.

Related MCP server: lexware-mcp-server

La seguridad es lo primero

El servidor apunta a un sistema contable real, por lo que los valores por defecto son prudentes.

Ejecútelo en modo de solo lectura a menos que tenga un motivo para no hacerlo. Este servidor puede cambiar registros contables reales — crear un contacto, registrar un comprobante, emitir una factura, adjuntar un recibo — y es el asistente el que decide cuándo llamar a una herramienta de este tipo, no usted. --tools read-only le da todo lo que necesita para responder preguntas sobre los libros, que es para lo que la mayoría de la gente lo quiere: buscar, leer y descargar. Nada de ese conjunto escribe.

Active una herramienta de escritura cuando tenga un trabajo para ella, y sepa lo que deja detrás. Esta API no puede eliminar un comprobante contable en absoluto, por lo que un error se corrige en la aplicación web en lugar de retirarse aquí, y una factura finalizada es un documento real con un número que ya se ha utilizado. Si no está seguro de qué herramientas necesita, el modo de solo lectura es el punto de partida honesto: la página de permisos añade una más tarde con un clic, y un cliente que respete notifications/tools/list_changed, como hace Claude Desktop, la recoge sin reiniciar.

  • Nada está activado hasta que usted lo diga. Una instalación nueva no tiene archivo de políticas, y un servidor sin él no ofrece ninguna herramienta. Lo que este servidor puede hacer es una decisión que alguien tomó, nunca un valor por defecto que ocurrió.

  • Una marca por herramienta, en un archivo JSON que usted escribe con --tools, marca a través de setup, o edita a mano. No es un nivel, no es un grupo: create_contact activado y upload_file desactivado es algo normal que se quiere, y no hay ninguna combinación que el archivo no pueda expresar.

  • Lo que una herramienta le cuesta es visible mientras decide. Cada herramienta activada se envía al asistente en cada solicitud, y la página de permisos pone ese número en cada fila.

  • El archivo se comprueba dos veces, una cuando se construye la lista de herramientas y otra cuando llega una llamada, para que una lista de herramientas obsoleta en el cliente no pueda pasar desapercibida.

  • La clave de API nunca se registra, nunca se devuelve en un resultado de herramienta y se redacta de los mensajes de error. Pertenece en el .env y en ningún otro sitio — no en el archivo de configuración de su cliente, que otro programa posee y reescribe, y que es el que la gente captura de pantalla cuando pide ayuda. Tampoco ninguna ruta de su máquina llega al asistente.

Herramientas

Construida significa que funciona hoy. El resto están especificadas en SPECS.md y aún no están implementadas.

Herramientas de lectura:

Herramienta

Qué hace

Estado

get_profile

Perfil de la empresa y comprobación de conexión

construida

search_contacts

Busca clientes y proveedores por nombre, correo electrónico, número o rol

construida

get_contact

Un contacto con direcciones, roles y versión

construida

search_articles

Lista artículos, filtrados por número, código de barras o tipo. La API no ofrece búsqueda por título

construida

get_article

Un artículo con su bloque de precios y versión

construida

search_vouchers

La consulta central: filtra la lista de comprobantes por tipo, estado, contacto, rango de fechas y lo que sigue abierto

construida

get_sales_document

Lee una factura, presupuesto, nota de crédito, confirmación de pedido, albarán, recordatorio o factura de anticipo en su totalidad

construida

get_voucher

Lee un comprobante contable, por id o por su número de documento

construida

get_payments

Estado de pago e importe pendiente de un comprobante

construida

get_recurring_templates

Plantillas que emiten facturas según un calendario, una o una página de ellas

construida

get_master_data

Países, condiciones de pago, categorías de contabilización y diseños de impresión, con una búsqueda para acotarlos

construida

download_document

Guarda el PDF o XML renderizado de un documento de venta

construida

download_file

Guarda un archivo almacenado, como un recibo subido

construida

read_download

Pone un archivo descargado en la respuesta, para clientes que no pueden seguir un enlace de recurso

construida

get_deeplink

Construye un enlace permanente a un documento de venta, contacto o comprobante en la aplicación web, sin llamada a la API

construida

Herramientas de escritura. Estas cambian registros contables reales, así que actívelas una a una y contra una cuenta que esté dispuesto a que se modifique:

Herramienta

Qué hace

Estado

create_contact

Crea un cliente o proveedor

construida

update_contact

Modifica uno, sin tocar lo que no haya nombrado

construida

create_article

Añade un artículo al catálogo

construida

update_article

Modifica uno, sin tocar lo que no haya nombrado

construida

create_voucher

Registra un comprobante contable

construida

update_voucher

Modifica uno que ya esté registrado

construida

create_sales_document

Crea una factura, presupuesto, nota de abono, confirmación de pedido, albarán o recordatorio: un borrador a menos que pida que se emita, lo que el asistente solo puede hacer con su instrucción explícita

construida

upload_file

Sube un recibo, que también crea su comprobante

construida

attach_file_to_voucher

Cuelga un archivo en un comprobante que ya existe

construida

update_contact y update_voucher cuestan dos llamadas a la API en lugar de una. La API reemplaza un registro en lugar de parchearlo, así que el actual se lee primero y el cambio se aplica encima. Sin eso, cambiar solo una dirección de correo electrónico vaciaría las direcciones, la nota y todo lo demás. Ambas también necesitan la version que leyó por última vez: si el registro cambió en el mientras tanto, la actualización se rechaza y no se escribe nada.

Una herramienta elimina, y es la única:

Herramienta

Qué hace

Estado

delete_article

Elimina un artículo. La API no puede recuperarlo. Requiere confirm: true y no envía nada sin ello

creada

Es el único miembro del paso --tools irreversible hasta ahora, por lo que ese paso es la única forma de activarlo. Un artículo es también lo único que esta API te permite eliminar, que es la otra mitad de la cuestión:

--tools write no es lo mismo que reversible. Nada de lo que activa ese preset elimina un registro, pero dos de sus herramientas crean uno que no se puede eliminar después.

Un comprobante contable no se puede eliminar a través de la API. No existe ningún endpoint para ello, así que un create_voucher erróneo debe corregirse en la aplicación web de Lexware Office. Pasa unchecked para registrar una entrada para revisión en lugar de contabilizarla directamente. Lo mismo se aplica a upload_file: subir un recibo también crea el comprobante que lo acompaña, por lo que deja un registro atrás aunque su nombre solo mencione el archivo.

Las descargas se escriben en el directorio de descargas de la máquina en la que se ejecuta el servidor y se notifican de dos formas: una ruta, que es lo que quieres cuando el cliente y el servidor comparten esa máquina, y un URI de recurso, que el cliente puede leer para obtener los bytes esté donde esté el servidor. El archivo en sí nunca viaja dentro del resultado de la herramienta, porque base64 cuesta aproximadamente 1,37 veces el tamaño del archivo en contexto y ningún modelo puede leer un PDF de todos modos. Un archivo existente nunca se reemplaza: una segunda descarga se guarda junto a la primera con un contador en su nombre.

La lista de recursos se rellena desde el directorio de descargas cuando el servidor se inicia, por lo que un URI sigue siendo legible después de un reinicio. Lo que el servidor no puede hacer es anunciar una descarga nueva: el MCP SDK no le da ninguna forma de enviar una notificación de cambio de lista, por lo que un cliente que lista una vez al inicio no verá nada obtenido más tarde en la sesión.

Entre eso y que Claude Desktop no sigue los enlaces de recursos en absoluto, read_download es la ruta que siempre funciona. Toma el mismo URI y pone el contenido en la respuesta. Lo que llega depende del archivo:

Archivo

Llega como

XML

texto, por lo que un XRechnung se puede leer de verdad

PDF

imágenes de sus páginas, las 10 primeras por defecto

Imagen

la imagen

Cualquier otra cosa

un binario incrustado para que lo maneje el cliente

Un PDF se renderiza en lugar de pasarse directamente porque Claude Desktop convierte un binario incrustado en un bloque de imagen cuando llama a la API, y application/pdf no es un tipo de imagen permitido allí, por lo que toda la solicitud se rechaza. El renderizado tampoco cuesta ninguna llamada a la API, ya que el archivo ya está en el servidor.

Un enlace a la aplicación web es una herramienta separada. get_deeplink convierte un id en una URL para un navegador, no cuesta ninguna llamada a la API y es la ruta que sigue funcionando cuando el cliente no puede mostrar ni el archivo ni un enlace de recurso: alguien lo abre por sí mismo. Una descarga no lo lleva — responde a dónde están los bytes, que es una pregunta diferente, y los dos se unieron una vez el tiempo suficiente para que un enlace roto viajara junto con una descarga que funcionaba.

upload_file acepta PDF, JPEG, PNG y XML, como máximo 5 MiB por archivo, que es lo que admite la API. Un archivo XML se trata como un XRechnung y se rechaza si no lo es.

Requisitos

  • uv, que trae su propio Python y el comando uvx que usan todos los ejemplos siguientes

  • Python 3.11 o más reciente, si prefieres traer el tuyo. La instalación incorpora el MCP SDK, httpx, platformdirs y pypdfium2, este último para renderizar páginas PDF

  • Una cuenta de Lexware Office con el add-on de API pública activado

  • Una clave de API de https://app.lexware.de/addons/public-api

Cómo obtener una clave de API

  1. Inicia sesión en Lexware Office como propietario de la cuenta.

  2. Abre el add-on de API pública en https://app.lexware.de/addons/public-api.

  3. Crea una clave y cópiala una sola vez: solo se muestra una única vez.

  4. Mantenla fuera de cualquier archivo que vaya al control de versiones. Ponla en config/.env, que está en gitignore, o pásala como variable de entorno. Una clave en config/.env se encuentra sin importar desde qué directorio se inicie el servidor, por lo que un cliente como Claude Desktop no necesita ninguna clave propia en su archivo de configuración.

Una clave se puede revocar en la misma página en cualquier momento, que es la forma más rápida de cortar el acceso si algo parece sospechoso.

Instalación

1. Instala uv, si aún no lo has hecho: la página de instalación de uv cubre todas las plataformas. Trae uvx, y eso es lo único que se necesita aquí.

2. Configura el servidor. No hay que instalar nada para esto: uvx obtiene el paquete y lo ejecuta.

uvx benethos-lexware-office-mcp setup

Eso abre la interfaz descrita en Configurarlo en un navegador: clave, ajustes y una casilla por herramienta. Todo lo que hace también se puede hacer a mano: inicia un archivo de ajustes con uvx benethos-lexware-office-mcp --settings-sample > config/.env, pon la clave en él y usa --tools como se describe a continuación.

Comprueba que funciona:

uvx benethos-lexware-office-mcp --help

3. Apunta Claude Desktop a él en claude_desktop_config.json:

{
  "mcpServers": {
    "benethos-lexware-office-mcp": {
      "command": "uvx",
      "args": ["benethos-lexware-office-mcp"]
    }
  }
}

Ninguna ruta de tu máquina aparece ahí, que es el punto: uvx busca el paquete por nombre. Dos cosas que vale la pena saber sobre esa entrada:

  • Fija una versión para mayor estabilidad: "args": ["benethos-lexware-office-mcp==0.2.0"]. Sin fijar, uvx toma la versión más reciente que pueda resolver, y un reinicio del cliente es suficiente para cambiar lo que ejecuta.

  • uvx tiene que estar en el PATH que usa el cliente, que no siempre es el que tiene tu terminal: algunos clientes gráficos pasan un entorno reducido. Si el servidor no se inicia, pon la ruta absoluta a uvx en command y reinicia el cliente por completo en lugar de recargarlo.

¿Prefieres tener un comando propio? uv tool install benethos-lexware-office-mcp te da benethos-lexware-office-mcp sin el uvx delante, lo que merece la pena si cambias permisos desde la línea de comandos a menudo. No compra nada más: la misma versión se puede fijar de cualquier manera, y un arranque en caliente difiere en decenas de milisegundos. Una cosa que debes saber: uv lo instala en su propio directorio de herramientas, que no está en el PATH de una instalación nueva. Lo dice cuando termina. Ejecuta uv tool update-shell y abre una terminal nueva.

Desde las fuentes en su lugar, para desarrollar o ejecutar algo no publicado:

git clone https://github.com/benethos-hub/lexware-office-mcp
cd lexware-office-mcp
uv sync
uv run benethos-lexware-office-mcp setup

Un cliente necesita entonces el intérprete del entorno virtual de ese checkout, con command apuntando a .venv/Scripts/python.exe en Windows o .venv/bin/python en otros sistemas, con args de ["-m", "benethos_lexware_office_mcp"].

Sin clave ahí, a propósito. El servidor la encuentra en el .env. El archivo de configuración de un cliente es el lugar equivocado para una credencial: no es tuyo — otro programa lo posee, decide dónde vive y cuándo lo reescribe. Es el archivo que la gente captura de pantalla cuando pide ayuda con una configuración de MCP, es legible en la vista de ajustes del propio cliente y viaja a la siguiente máquina con el resto de la configuración de ese cliente. El .env es al menos un archivo que este proyecto documenta, que nada sincroniza en tu nombre y que la interfaz de configuración escribe sin mostrarte nunca la clave.

Ese .env ya es la parte con la que hay que tener cuidado. Contiene una credencial para un sistema de contabilidad en vivo, así que mantenlo fuera del control de versiones, fuera de carpetas compartidas y fuera de copias de seguridad que otras personas puedan leer. Cuando dejes de usar el servidor, elimínalo y revoca la clave en Extensiones, API pública: revocar es el único paso que realmente termina el acceso.

4. Reinicia Claude Desktop por completo: ciérralo desde la bandeja en lugar de cerrar la ventana. Eso es por el archivo de configuración que acabas de editar, que un cliente lee una vez al inicio, y es lo que también necesita un ajuste cambiado en el .env — el servidor los lee también al inicio. No es necesario para los permisos: cámbialos más tarde y el cliente en ejecución recibe la notificación, consulta Desactivar herramientas individuales.

Configurarlo en un navegador

uvx benethos-lexware-office-mcp setup

Tres páginas en 127.0.0.1, cerradas con Ctrl+C. Escriben los mismos archivos que la línea de comandos, por lo que puedes usar una u otra o ambas. Las pantallas están en alemán, porque Lexware Office se vende solo para empresas alemanas, y cada una se nombra a continuación por lo que hace con su etiqueta entre corchetes.

Resumen (Übersicht) — qué .env y qué tools.json están realmente en vigor, a qué se resuelve cada ajuste y de dónde viene ese valor, si cada archivo existe ya, cuántas herramientas están activadas y cuánto cuestan. Una prueba de conexión en el botón, nunca al cargar la página.

Credenciales (Zugangsdaten) — la clave de API, comprobada contra la API antes de guardarse a menos que indiques lo contrario, y los ajustes que no son secretos. La clave nunca se te muestra de nuevo, nunca se registra y nunca se exporta. Si una variable de entorno la está estableciendo, la página lo dice, porque eso anularía lo que guardes.

Permisos (Rechte) — una casilla por herramienta, agrupadas, con los presets como botones. En una instalación nueva sin archivo de política todavía, las herramientas de lectura vienen marcadas de antemano como punto de partida: una propuesta en un formulario, no un permiso: todavía no hay archivo y por lo tanto todavía no hay ninguna herramienta hasta que pulses guardar, y la página lo dice. Cada fila lleva lo que esa herramienta cuesta al asistente en contexto, y el total sigue tus marcas: cada herramienta activada se envía al modelo en cada solicitud, por lo que activar una es una decisión de presupuesto además de una de permisos. Las herramientas de escritura están marcadas, y las cuyo resultado la API no puede retirar están marcadas por separado: nur App para un contacto, que Lexware Office elimina sin ceremonia, y nur App · Buchhaltung para un registro que entra en los libros. Ninguna significa que esté atascada: nada queda fijado (festgeschrieben) cuando se crea, y una leyenda en la página nombra las cuatro cosas que sí vinculan un registro más tarde.

Los perfiles también viven aquí. Guarda la selección actual con un nombre, cárgala más tarde. Cargar solo rellena las casillas: nada llega a tools.json hasta que pulses guardar. Un nombre que ya está en uso se rechaza en lugar de reemplazar silenciosamente lo que hay — mayúsculas y espacios no crean un segundo perfil — y reemplazar uno es su propio botón junto a la lista. Se almacenan en tool_profiles.json junto al archivo de política.

El archivo de política en sí se puede descargar y volver a leer desde la misma página — el archivo tal cual, por lo que funciona en otra instalación con o sin esta interfaz, y un tools.json escrito por --tools se lee aquí. Leer uno solo marca las casillas, y guardar sigue siendo una pulsación separada. Una herramienta que el archivo no menciona permanece desactivada y la página dice cuántas son, que es lo que hace --tools sync en la línea de comandos.

Dos cosas que vale la pena saber. Se vincula a 127.0.0.1 y nada más — las páginas no tienen contraseña, lo que solo es defendible mientras no se puedan alcanzar desde otra máquina, por lo que no hay opción para cambiarlo. Y es un comando separado: el servidor MCP nunca sirve HTTP, y un cliente como Claude Desktop inicia ese, no este.

--port N lo mueve, --no-browser solo imprime la dirección, y --env-file y --tools-file indican qué archivos edita. A diferencia de todos los demás sitios, esos archivos no tienen que existir todavía.

Si tu cliente inicia el servidor con --tools-file, pásale a setup el mismo argumento; de lo contrario, edita un archivo distinto e informa de que todo ha sido un éxito. Ambos procesos fijan sus archivos cuando arrancan y nunca los cambian después, y ninguno puede ver cómo se inició el otro. La vista general imprime la línea "args" que hace que tu cliente coincida con los archivos que la interfaz tiene en uso, que es la dirección más fácil.

Desactivar herramientas individuales

Un único archivo JSON decide lo que ofrece este servidor, y nada más lo hace. O marca las casillas en setup de más arriba, o inicia el archivo con

uvx benethos-lexware-office-mcp --tools read-only

que escribe todas las herramientas en tools.json, activa unas y desactiva el resto, e imprime lo que hizo. Hay tres preajustes, cada uno más amplio que el anterior:

activa

--tools read-only

solo consultas

--tools write

además, crear y actualizar

--tools irreversible

y eliminar un artículo

--tools sync

no cambia ninguna marca; solo añade las herramientas que el archivo no conoce

--tools show solo informa. --tools-file PATH indica dónde escribir y funciona con todos ellos; --tools write --tools-file ./tools.json crea el archivo ahí.

Un preajuste sobrescribe el archivo completo, así que los cambios hechos a mano se pierden. Usa uno para crear un archivo, no para actualizarlo. Cuando una actualización trae herramientas nuevas, ejecuta --tools sync: las escribe en off (desactivadas), deja tranquilo todo lo que hayas configurado y nunca activa nada por su cuenta. Esta última parte es la razón por la que es el único entre ellos que se puede ejecutar desde un script de formasegura.

El tercer preajuste es un caso aparte porque es una decisión propia: lo que se elimina ha desaparecido, así que debe elegirse por su nombre y no por coger la opción más grande. Exactamente una herramienta tiene ese efecto, delete_article, y no es una situación temporal: un artículo es lo único que esta API puede eliminar, y tampoco hay modo de reservar, finalizar o anular nada después.

Sin --tools-file, el archivo se busca exactamente igual que el .env, con la prioridad más baja primero:

  1. el directorio de configuración del usuario

  2. config/ de un checkout, cuando se ejecuta desde las fuentes

  3. config/ y luego la raíz del directorio de trabajo

El último que se encuentre gana, y si aún nadie ha creado el archivo, se usa el primero. Después, edítalo:

{
 "create_contact": false,
 "search_contacts": true,
 "upload_file": false
}

Una herramienta marcada como false no aparece en la lista y no puede llamarse3. Una herramienta de que el archivo no menciona también está off-block. El siete es una negación: una herramienta que llega con una actualización se queda esperándote, no aparece por sí sola. Que no exista ningún archivo significa que no hay ninguna herramienta, y por eso --tools forma parte de laconfiguracióninicialdel servidor.

El archivo se lee cuando se construye la lista de herramientas y otra vez en cada llamada, así que una edición tiene efecto inmediato en las dos direcciones — no hay que reiniciar. El servidor también avisa al cliente cuando cambia el conjunto de herramientas habilitadas; de modo que aquél vuelve por sí mismo a consultar la lista: Claude Desktop detecta el cambio mientras está funcionando. Nada depende de ello en cualquier caso, porque una herramienta que se ha apagado no puede ser llamada haga la lista que el cliente siga mostrando. Si el client tuyo no lo aprecia, reiníicialo — Claude Desktop, hasta la barra de sistemas.

Configuración

De dónde viene un valor y cuál gana

Seis fuentes, en orden de menor prioridad a mayor: una fuente posterior sustituye a una anterior.

  1. el valor integrado por defecto

  2. .env en el directorio de configuración del usuario

  3. config/.env del checkout desde el que se ejecuta el servidor, si el servidor se ejecuta desde un checkout

  4. config/.env y después .env en el directorio de trabajo

  5. el archivo que nombra --env-file, que se lee después que todos esos en lugar de en vez de ellos: se ha nombrado, no encontrado delante de ellos, así que está por encima

  6. una variable de entorno real, que vence a cualquier archivo

La última es la que sorprende a la gente. Una opción exportada en tu shell, metida en el bloque env de un cliente o fijada en un archivo Compose no se puede cambiar editando un .env — ni a mano, ni a través de setup. El valor se escribe, el archivo está correcto, no pasa nada.

La interfaz de configuración lo dice en lugar de dejar que lo descubras: cada ajuste lleva una etiqueta (badge) que indica su fuente, y uno que esté siendo sostenido por una variable de entorno está marcado claramente. Cuando algo guardado parece que se ignora, esa insignia es la respuesta.

En un contenedor con esto no es cuestión marginal. compose.yaml fija el transporte, la dirección de enlace, el puerto y los hosts permitidos como variables de entorno de verdad, porque eso pertenece al contenedor, no a la instalación que vive dentro de él. Todo lo demás — la clave de API, el token HTTP, los límites — queda en el volumen de configuración, que es justamente lo que permite a la interfaz de configuración cambiarlo.

El mismo orden se aplica al archivo de política, y LXO_MCP_TOOL_POLICY y --tools-file designan uno directamente. La interfaz enclava el archivo que encuentre al arrancar, de modo que la página no puede hacer que cambie su propio sujeto por debajo del usuario.

Cómo se nombran los archivos

--env-file PATH nombra un archivo de configuración en lugar de buscarlo, y se empareja con --tools-file para que una sola entrada de la configuración de como cliente cuantexa con su propio token y sus propios permisos:

"args": ["--env-file", "/path/to/test.env",
         "--tools-file", "/path/to/test-tools.json"]

Una ruta que no existe se rechaza en lugar de devolver silenciosamente la búsqueda… excepto bajo setup, que existe en parte para crear một.

setup te escribe este archivo.

Los valores de configuración

Variable

Significado

Valor por defecto

LXO_MCP_API_KEY

Tu clave de API de Lexware Office. Obligatoria.

LXO_MCP_TOOL_POLICY

Archivo de off/on por herramienta, véalo más abajo

tools.json del directorio de config

LXO_MCP_BASE_URL

URL base de la API

https://api.lexware.io

LXO_MCP_APP_BASE_URL

Base de la aplicación web para los enlaces profundos

https://app.lexware.de

LXO_MCP_DOWNLOAD_DIR

Carpeta de registro de las descargas

directorio de caché del usuario

LXO_MCP_TIMEOUT

Timeout de HTTP en segundos

30

LXO_MCP_RATE

Peticiones por segundo, global para todos los endpoints

1.5

LXO_MCP_BURST

Capacidad del cubo de tokens. El cubo del acuerdo in total holds 4

2

LXO_MCP_PAGE_SIZE

Líneas por página que una búsqueda solicita y entrega

25

LXO_MCP_PDF_PAGES

Páginas de un PDF que read_download renderiza por defecto

10

LXO_MCP_LOG_LEVEL

Nivel de registro en stderr

INFO

LXO_MCP_TRANSPORT

stdio, streamable-http o sse

stdio

LXO_MCP_BEARER_OTOKEN

Secreto comunitario que toda petición HTTP debe llevar. Obligatorio para transporte HTTP

LXO_MCP_HTTP_HOST

Dirección de bind para tranquospor HTTP

127.0.0.1

LXO_MCP_HTTP_PORT

Puerto de bind

8770

LXO_MCP_HTTP_PATH

Ruta URL que sirve el transporte

/mcp

LXO_MCP_ALLOWED_HOSTS

Valores Host aceptados además de loopback, separados por comas

LXO_MCP_GENERATE_BEARER_TOKEN

Genera un token al arranque si no hay ninguno establecido y lo escribe en el archivo de configuración

desactivado

LXO_MCP_EXIT_ON_CONFIG_CHANGE

Termina el proceso cuando cambia el archivo de configuración, para algo que lo reinicia

desactivado

Todos los valores de esta tabla están en uso. LXO_MCP_PAGE_SIZE está limitado a 250, que es el mayor tamaño de página que acepta cualquier endpoint, y un mayor valor es devuelto al arranque en lugar de provocar un error una y sin quejarse.

Transporte

stdio es el valor por defecto y el que usan Claude Desktop y clientes locales similares: el cliente inicia el servidor como proceso hijo suyo, y nadie más puede hablar con ese transp.

streamable-HTTP y SSE sirven las mismas herramientas en un puerto, para un contenedor o una máquina propia:

uvx benethos-lexware-office-mcp --transport streamable-http --port 8770

Hay dos cosas delante de ese puerto, y ninguna es opcional. Un token portador que toda petición debe llevar así: Authorization: Bearer <token>; sin LXO_MCP_BEARER_TOKEN el servidor se niega por completo a iniciar un transporte HTTP, porque cualquiera que pudiera alcanzar el puerto podría gastarse tus credenciales de Lexware. Y la que el SDK usa contra el secuestro de DNS (DNS rebinding) — comprueba Host y Origin contra una lista blanca de los nombres de loopback, ampliada con --allowed-hosts cuando un contenedor o un proxy pone otro nombre delante.

Ninguno hace seguro el puerto para publicar una red. Lo hacen soportable en una máquina compartida con otros procesos. --host vincula en algún lugar que no sea loopback, que lo que un contenedor no tiene más remedio que El ejemplo — ver En un contenedor para entender por que no esta excepción que parece.

En un contenedor

La imagen se publica para linux/amd64 y linux/arm64, así que no no haces falta nada de este repositorio para ejecutar una:

docker pull ghcr.io/benethos-hub/lexware-office-mcp:latest

Usa :0.2.0 en lugar de :latest para fijar una versión.

Con Compose

docker compose up -d                      # the server, on 127.0.0.1:8770
docker compose --profile setup up -d      # add the configuration interface

Tal como viene, compose.yaml compila desde este checkout. Dos líneas comentadas en cada uno de sus dos servicios lo cambian por la imagen publicada, y desde entonces ese archivo es lo único que te llevas de aquí.

Como contenedores individuales

docker run -d --name lexware-office-mcp \
  --restart unless-stopped \
  -p 127.0.0.1:8770:8770 \
  -v lxo-config:/config -v lxo-downloads:/downloads \
  ghcr.io/benethos-hub/lexware-office-mcp:latest

El token que se ha generado queda en el volumen de configura, y de ahí lo lees:

docker exec lexware-office-mcp cat /config/.env

La interfaz de configuración es la misma imagen con su otro comando, apuntando al mismo volumen:

docker run --rm -d --name lexware-office-mcp-setup \
  -p 127.0.0.1:8771:8771 \
  -v lxo-config:/config -v lxo-downloads:/downloads \
  ghcr.io/benethos-hub/lexware-office-mcp:latest \
  setup --no-browser --host 0.0.0.0 --port 8771 \
        --env-file /config/.env --tools-file /config/tools.json

--restart unless-stopped no es decoración. El contenedor termina su proceso cuando cambia el archivo de ajustes, y eso es lo que mete un valor guardado en un servidor que está corriendo. Sin la política de reinicio, el contenedor termina y ya no vuelve.

En cualquier de las dos formas

Abre http://127.0.0.1:8771/, introduce la clave, marca las herramientas y luego vuelve a detener la interfaz — docker compose --profile setup down, o bien docker stop lexware-office-mcp-setup. Está pensada para que se ejecute durante los minutos que se necesite, no permanentemente, porque no tiene login y pide una clave API.

Nada hay que preparar antes. En el primer arranque el servidor crea el token portador, lo escribe en el volumen de configuración y lo avisa: la interfaz lo muestra, y ese es el valor que un cliente necesita. No viene cocido en la imagen, donde é. La run el habría en la que se imprenta.

El contenedor se vincula a 0.0.0.0, y eso no es una relajación. Un proceso en el loopback del contenedor no puede alcanzarse a través de un puerto publicado en absoluto. El aislamiento es el espacio de nombres de red, y quién puede alcanzar el puerto lo decide la publicación, que mapea 127.0.0.1 solamente.

Un ajuste guardado en el navegador llega al servidor en ejecución. Los ajustes se leen una vez al arrancar, así que al contenedor se le indica que termine cuando su archivo de ajustes cambia y Compose lo inicia de nuevo un segundo después. Lo que Compose fija como variables de entorno reales — el transporte, la dirección de enlace, el puerto, los hosts permitidos — pertenece al contenedor y no puede cambiarse desde el volumen; consulte Configuración.

Ejemplos de consultas

Una vez que el servidor está conectado, estas son las consultas previstas:

  • "¿Qué facturas siguen abiertas y cuáles están vencidas?"

  • "Muéstrame todo lo que facturamos al cliente Muster GmbH este trimestre."

  • "¿Qué contiene la factura RE-2024-0142 y se ha pagado?"

  • "Busca el artículo con el número A-1007 y dime su precio actual."

  • "Descarga el PDF de la última nota de crédito que emitimos."

  • "Dame un enlace para abrir el comprobante X en Lexware Office."

Límites de tasa

La API de Lexware permite dos solicitudes por segundo, aplicadas mediante un token bucket. Ese presupuesto es global: cubre todos los endpoints de la API al mismo tiempo, de modo que leer un contacto y leer una factura consumen del mismo cupo.

El servidor replica esto con un único token bucket compartido por cada solicitud en el proceso, que se rellena ligeramente por debajo de la tasa documentada por defecto. Lexware señala que aplicar el límite exacto, sin margen, tiende a producir errores 429 en cuanto la fluctuación de la red altera los tiempos de llegada, así que el valor predeterminado deja margen. Las solicitudes se serializan a través de ese bucket en lugar de dispararse en paralelo, lo que significa que una consulta amplia que toca muchos documentos se vuelve más lenta en lugar de quedar bloqueada.

Dos cosas que vale la pena saber:

  • El presupuesto pertenece a su cuenta, no a este proceso. Una segunda instancia del servidor, otra integración o un script que usted mismo ejecute consumen del mismo cupo de dos por segundo.

  • Lexware advierte que un cliente que siga insistiendo tras un 429 puede quedar bloqueado permanentemente. Por lo tanto, el servidor aplica una retroceso exponencial y abandona tras algunos intentos en lugar de seguir reintentando con más fuerza.

El bucket de la cuenta se midió el 2026-08-21 y contiene cuatro: cinco solicitudes disparadas a la vez lograron pasar cuatro y una fue rechazada. El valor predeterminado de 2 deja la mitad de eso para todo lo demás que consume de la misma cuenta — la aplicación web, otra integración, una segunda instancia de este servidor. Súbalo a 4 solo si sabe que este servidor es el único consumidor.

Ambos valores del limitador se pueden configurar mediante LXO_MCP_RATE y LXO_MCP_BURST si su cuenta se comporta de manera diferente.

Desarrollo

uv sync --extra dev
uv run pytest -q
uv run ruff check .
uv run ruff format --check .
uv run mypy

La suite de pruebas es totalmente offline. Simula la capa HTTP y no necesita ninguna clave de API, por lo que se ejecuta en cualquier lugar. Dos tipos de prueba dejan el proceso sin salir de la máquina: tres inician el servidor como un subproceso real y se comunican con MCP a través de stdio, lo que también demuestra que nada se escribe en stdout durante la ruta de arranque, y la interfaz de configuración se maneja mediante un servidor loopback HTTP real con un contenedor de cookies real, porque sus protecciones CSRF solo merecen probarse de la manera en que un navegador las encontraría.

No se incluye ninguna clave de API con el repositorio y no se necesita ninguna en CI, por lo que un clon nunca puede hablar con Lexware por su cuenta. Probar contra la API real es, por lo tanto, siempre una ejecución local deliberada con una clave que usted proporciona, separada de la suite y nunca parte de ella:

uv run python tests/smoke.py
uv run python tests/smoke.py --env-file path/to/.env

Lee su cuenta y no escribe nada en ella. El servidor que construye obtiene el preajuste de solo lectura, por lo que las herramientas de escritura no están disponibles para ser invocadas. Imprime lo que comprobó, lo que la cuenta no tenía y lo que falló, y enmascara los IDs de los registros para que el informe pueda pegarse en cualquier lugar. pytest nunca lo ejecuta. Consulte SPECS.md, sección 14.1, para saber por qué una verificación en vivo no es una compuerta.

Las contribuciones y los problemas son bienvenidos una vez que exista el primer lanzamiento. Hasta entonces, SPECS.md es el lugar donde se registran las decisiones de diseño, incluidas las preguntas abiertas que aún deben resolverse contra la API en vivo.

Licencia

MIT. Consulte LICENSE.

Marcas comerciales y afiliación

Este proyecto no está afiliado, respaldado ni patrocinado por Lexware, Haufe-Lexware GmbH & Co. KG, ni por cualquiera de sus subsidiarias. "Lexware" y "Lexware Office" son marcas comerciales de sus respectivos propietarios y se utilizan aquí solo para nombrar la API con la que este software se integra, con fines descriptivos.

El software se comunica exclusivamente con la API pública documentada, utilizando credenciales que el propietario de la cuenta proporciona y puede revocar. El uso de esa API se rige por los propios términos de Lexware, que usted acepta de manera independiente a este proyecto.

Install Server
A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
2Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

  • F
    license
    B
    quality
    C
    maintenance
    MCP server for DACH accounting automation. Connect AI assistants to sevDesk and Lexoffice — create invoices, manage contacts, handle bookings and vouchers for German-speaking businesses.
    15
    37
  • A
    license
    B
    quality
    A
    maintenance
    MCP server for the Lexware Office API that enables management of invoices, contacts, articles, vouchers, and more through the Model Context Protocol.
    66
    161
    6
    Functional Source , Version 1.1, MIT Future
  • A
    license
    C
    quality
    C
    maintenance
    Enables natural language interaction with the WeFact invoicing platform, allowing users to manage debtors, invoices, products, subscriptions, and perform various administrative tasks via MCP-compatible clients.
    18
    1
    AGPL 3.0
  • A
    license
    B
    quality
    C
    maintenance
    An MCP server for Danish accounting via Billy.dk API, enabling natural-language control over invoices, bank lines, reports, and more, with a write-guard for safety.
    65
    MIT

View all related MCP servers

Related MCP Connectors

  • Log, query, and edit expenses, budgets, and accounts in Ledgy from any MCP-compatible AI assistant.

  • Hosted MCP server for Mini Accountant: invoices, expenses, customers, analytics, tax estimates.

  • Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/benethos-hub/lexware-office-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server