Unofficial Lexware Office MCP Server
Servidor MCP no oficial de Lexware Office
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 propios términos de Lexware, que acepta independientemente de este proyecto. La API puede cambiar en cualquier momento, y las solicitudes pueden estar sujetas a límites de velocidad o ser bloqueadas.
Accede a registros contables reales. El acceso de escritura está desactivado por defecto. Si lo habilita, cualquier cosa creada a través de la API es un registro real y legalmente 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 confíe en ello para declaraciones, auditorías o sus obligaciones contables.
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.2. El servidor gestiona contactos, comprobantes y documentos: los encuentra, los lee, los crea, los modifica, ve lo que aún está sin pagar, descarga un PDF y sube un recibo.
get_profileresponde qué cuenta está conectada. Cada herramienta de la tabla siguiente está construida y se probó con una cuenta real. Habla con stdio a un cliente que lo inicia, y HTTP transmisible detrás de un token de portador cuando algo más tiene que alcanzarlo: como una 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 esto
Lexware Office contiene la contabilidad diaria de una pequeña empresa. La mayoría de las preguntas al respecto son preguntas de lectura: qué está aún sin pagar, qué pidió este cliente, qué recibo pertenece 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, utilizando una clave de API que el propietario de la cuenta genera y puede revocar.
Related MCP server: lexware-mcp-server
Seguridad ante todo
El servidor apunta a un sistema contable real, por lo que los valores predeterminados son cautelosos.
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 quien decide cuándo llamar a dicha
herramienta, 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 en ese conjunto escribe.
Active una herramienta de escritura cuando tenga un trabajo para ella y sepa lo que deja
atrás. Esta API no puede eliminar un comprobante contable en absoluto, por lo que uno incorrecto
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 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 agrega una más tarde con un clic, y un cliente que respete
notifications/tools/list_changed, como hace Claude Desktop, lo recoge
sin reiniciar.
Nada está habilitado hasta que usted lo diga. Una instalación nueva no tiene archivo de políticas, y un servidor sin uno no ofrece ninguna herramienta. Lo que este servidor puede hacer es una decisión que alguien tomó, nunca un valor predeterminado que sucedió.
Una bandera por herramienta, en un archivo JSON que usted escribe con
--tools, marca a través desetup, o edita a mano. No es un nivel, no es un grupo:create_contactactivado yupload_filedesactivado es algo normal de querer, y no hay combinación que el archivo no pueda expresar.Lo que una herramienta le cuesta es visible mientras decide. Cada herramienta habilitada se envía al asistente en cada solicitud, y la página de permisos pone ese número en cada fila.
El archivo se verifica dos veces, una cuando se construye la lista de herramientas y otra cuando llega una llamada, por lo que una lista de herramientas obsoleta en el cliente no puede pasarlo por alto.
La clave de API nunca se registra, nunca se devuelve en un resultado de herramienta y se redacta de los mensajes de error. Pertenece al
.envy a ningún otro lugar — 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 desde su máquina llega al asistente.
Herramientas
Cada herramienta siguiente está construida y se probó con una cuenta real. Ninguna de ellas está habilitada hasta que el archivo de políticas la nombre.
Herramientas de lectura:
Herramienta | Qué hace |
| Perfil de la empresa y verificación de conexión |
| Encuentra clientes y proveedores por nombre, correo electrónico, número o rol |
| Un contacto con direcciones, roles y versión |
| Lista artículos, filtrados por número, código de barras o tipo. La API no ofrece búsqueda por título |
| Un artículo con su bloque de precios y versión |
| La consulta central: filtra la lista de comprobantes por tipo, estado, contacto, rango de fechas y lo que está abierto |
| Lee una factura, cotización, nota de crédito, confirmación de pedido, albarán, recordatorio o factura de anticipo en su totalidad |
| Lee un comprobante contable, por id o por su número de documento |
| Estado de pago y monto abierto de un comprobante |
| Plantillas que emiten facturas según un cronograma, una o una página de ellas |
| Países, condiciones de pago, categorías de contabilización y diseños de impresión, con una búsqueda para acotarlos |
| Guarda el PDF o XML renderizado de un documento de venta |
| Guarda un archivo almacenado, como un recibo subido |
| Coloca un archivo descargado en la respuesta, para clientes que no pueden seguir un enlace de recurso |
| Construye un enlace permanente a un documento de venta, contacto o comprobante en la aplicación web, sin una llamada a la API |
Herramientas de escritura. Estas cambian registros contables reales, así que actívelas una a la vez y contra una cuenta que esté dispuesto a que se modifique:
Herramienta | Qué hace |
| Crea un cliente o proveedor |
| Cambia uno, sin tocar lo que no nombró |
| Agrega un artículo al catálogo |
| Cambia uno, sin tocar lo que no nombró |
| Registra un comprobante contable |
| Cambia uno que ya está registrado |
| Crea una factura, cotización, nota de crédito, 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 |
| Sube un recibo, que también crea su comprobante |
| Cuelga un archivo en un comprobante que ya existe |
update_contact y update_voucher cuestan dos llamadas a la API en lugar de una.
La API reemplaza un registro en lugar de parchearlo, por lo que se lee primero
el actual y el cambio se superpone. 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 medio, la
actualización se rechaza y no se escribe nada.
Una herramienta elimina, y es la única:
Herramienta | Qué hace |
| Elimina un artículo. La API no puede recuperarlo. Requiere |
Es el único miembro del paso --tools irreversible hasta ahora, por lo que ese paso
es la única forma de activarlo. Un artículo también es lo único que esta API
le permite eliminar, que es la otra mitad del punto:
--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
quitar después.
Un comprobante contable no se puede eliminar a través de la API. No existe
un endpoint para ello, así que un create_voucher erróneo debe corregirse en
la aplicación web de Lexware Office, y se contabiliza en el momento en que se
crea: la API no acepta ningún estado en el camino. Lo mismo se aplica a
upload_file: subir un recibo también crea el comprobante asociado, por lo
que deja un registro detrás aunque su nombre solo mencione el archivo.
Las descargas se escriben en el directorio de descargas de la máquina donde se ejecuta el servidor, y se informan de dos maneras: 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 llena 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 nueva descarga: el SDK de MCP no le da forma de enviar una notificación de cambio de lista, por lo que un cliente que lista una vez al inicio no verá nada que se obtenga 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 |
imágenes de sus páginas, las primeras 10 por defecto | |
Imagen | la imagen |
Cualquier otro | un binario incrustado para que el cliente lo maneje |
Un PDF se renderiza en lugar de pasarse tal cual 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. Renderizar tampoco cuesta una 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 lleva uno: responde dónde están los bytes, que es una pregunta
diferente, y los dos se unieron una vez durante 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 acepta 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
uvxque usan todos los ejemplos siguientesPython 3.11 o más reciente, si prefieres traer el tuyo. La instalación incluye el SDK de MCP, httpx, platformdirs y pypdfium2, este último para renderizar páginas PDF
Una cuenta de Lexware Office con el complemento de API pública habilitado
Una clave de API de https://app.lexware.de/addons/public-api
Cómo obtener una clave de API
Inicia sesión en Lexware Office como propietario de la cuenta.
Abre el complemento de API pública en https://app.lexware.de/addons/public-api.
Crea una clave y cópiala una vez: solo se muestra una única vez.
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 enconfig/.envse encuentra sin importar desde qué directorio se inicie el servidor, por lo que un cliente como Claude Desktop no necesita su propia clave 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
La forma más sencilla de ejecutar el servidor: sin clonar, sin entorno virtual
manual, sin git. uvx lo obtiene y lo ejecuta bajo demanda desde
PyPI (publicado como
benethos-lexware-office-mcp). Para ejecutarlo en un contenedor en su lugar,
consulta En un contenedor.
1. Instala uv, si aún no lo tienes: 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 setupEso 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 abajo.
Comprueba que funciona:
uvx benethos-lexware-office-mcp --help3. Apunta Claude Desktop a ello en claude_desktop_config.json:
{
"mcpServers": {
"benethos-lexware-office-mcp": {
"command": "uvx",
"args": ["benethos-lexware-office-mcp"]
}
}
}No aparece ninguna ruta de tu máquina 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 estabilidad:
"args": ["benethos-lexware-office-mcp==0.2.2"]. Sin una fijación,uvxtoma la versión más reciente que pueda resolver, y un reinicio del cliente es suficiente para cambiar lo que ejecuta.uvxtiene que estar en elPATHque usa el cliente, que no siempre es el de tu terminal: algunos clientes gráficos pasan un entorno reducido. Si el servidor no se inicia, pon la ruta absoluta auvxencommand, 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 vale 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 a 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 nueva terminal.
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 setupUn cliente entonces necesita el intérprete del entorno virtual de ese checkout,
command apuntando a .venv/Scripts/python.exe en Windows o
.venv/bin/python en otros lugares, 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 de vuelta.
Ese .env ya es la parte con la que hay que tener cuidado. Contiene una
credencial para un sistema contable 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 para el archivo de configuración que acabas
de editar, que un cliente lee una vez al inicio, y también es lo que necesita
un ajuste cambiado en el .env: el servidor también los lee al inicio. No
es necesario para los permisos: cámbialos más tarde y el cliente en ejecución
es informado, consulta Desactivar herramientas individuales.
Configurarlo en un navegador
uvx benethos-lexware-office-mcp setupTres páginas en 127.0.0.1, cerradas con Ctrl+C. Escriben los mismos archivos
que la línea de comandos, así que puedes usar cualquiera o ambos. Las
pantallas están en alemán, porque Lexware Office se vende solo para empresas
alemanas, y cada una se nombra abajo por lo que hace con su etiqueta entre
corchetes.
Resumen (Übersicht): qué .env y qué tools.json están realmente en
efecto, a qué se resuelve cada ajuste y de dónde viene ese valor, si cada
archivo existe aún, 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, verificada contra la API
antes de guardarse a menos que digas lo contrario, y los ajustes que no son
secretos. La clave nunca se te muestra de vuelta, 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 aún,
las herramientas de lectura vienen pre-marcadas 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 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 habilitada se envía al modelo en
cada solicitud, así que activar una es una decisión de presupuesto además
de una de permiso. Las herramientas de escritura están marcadas, y las que la
API no puede retractar 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é atascado:
nada está fijado 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 bajo un nombre,
cárgala más tarde. Cargar solo llena 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 como es, 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 apagada 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 dicen qué archivos edita. A diferencia de en cualquier otro
lugar, esos archivos no tienen que existir aún.
Si tu cliente inicia el servidor con --tools-file, dale a setup el mismo
argumento: de lo contrario edita un archivo diferente e informa éxito.
Ambos procesos fijan sus archivos cuando se inician y nunca los cambian
después, y ninguno puede ver cómo se inició el otro. El resumen imprime la
línea "args" que hace que tu cliente coincida con los archivos que la
interfaz está manejando, que es la dirección más fácil.
Desactivar herramientas individuales
Un archivo JSON decide lo que este servidor ofrece, y nada más. O marca las
casillas bajo setup arriba, o inicia el archivo con
uvx benethos-lexware-office-mcp --tools read-onlyque escribe cada herramienta en tools.json, dejando las de lectura activadas y el resto desactivadas,
e imprime lo que ha hecho. Tres ajustes predefinidos, cada uno de los cuales incluye el anterior:
activa | |
| solo las consultas |
| y la creación y actualización |
| y el borrado de un artículo |
| no cambia ninguna marca, solo añade las herramientas que el archivo no conocía |
--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 allí.
Un ajuste predefinido sobrescribe todo el archivo, por lo que las ediciones manuales se pierden. Úsalo para
crear un archivo, no para actualizar uno. Cuando una actualización trae herramientas nuevas, ejecuta
--tools sync: las escribe como desactivadas, deja intactas todas las marcas que hayas establecido y nunca
activa nada. Esa última parte es la razón por la que es el único de estos que es seguro ejecutar desde un script.
El tercer paso es independiente porque es una decisión propia: lo que se borra desaparece,
por lo que debe elegirse nombrándolo en lugar de escoger la opción más amplia.
Exactamente una herramienta tiene ese efecto, delete_article, y eso
no es algo temporal: un artículo es lo único que esta API puede borrar,
y tampoco hay forma de reservar, finalizar o anular nada a posteriori.
Sin --tools-file, el archivo se busca exactamente igual que el .env, con la
precedencia más baja primero:
el directorio de configuración por usuario
config/de un checkout, cuando se ejecuta desde las fuentesconfig/y luego la raíz del directorio de trabajo
Gana el último que se encuentre, y un archivo que nadie ha creado todavía se resuelve al primero. Después, edítalo:
{
"create_contact": false,
"search_contacts": true,
"upload_file": false
}Una herramienta establecida en false no aparece en la lista y no se puede llamar. Una herramienta que el archivo
no menciona también está desactivada: el silencio es una negativa, así que una herramienta que llega
con una actualización espera a que la actives en lugar de aparecer por sí sola. Que no haya ningún archivo
significa que no hay ninguna herramienta, por eso --tools forma parte de la configuración del servidor.
El archivo se lee cuando se construye la lista de herramientas y de nuevo en cada llamada, por lo que una edición surte efecto de inmediato en ambas direcciones: sin reiniciar. El servidor también informa al cliente cuando cambia el conjunto de herramientas activadas, por lo que este vuelve a obtener la lista por sí mismo: Claude Desktop detecta el cambio mientras está en ejecución. Nada depende de ello en ningún caso, ya que una herramienta que se ha desactivado no se puede llamar sea cual sea la lista que el cliente siga mostrando. Si el tuyo no lo detecta, reinícialo: en Claude Desktop, saliendo desde la bandeja.
Cada herramienta también declara qué es: de lectura o escritura, a qué grupo
pertenece y si lo que escribe se puede eliminar de nuevo. Esa
clasificación es la que --tools read-only activa y la que la interfaz del navegador
agrupa y marca. Nunca decide una llamada: solo lo hace el archivo.
Configuración
De dónde viene un valor y cuál gana
Se aplica un único .env, nunca varios. Estos son los lugares donde se busca,
de menor a mayor precedencia, y el de mayor precedencia que exista es el archivo: los demás
no se leen:
.enven el directorio de configuración por usuarioconfig/.envdel checkout desde el que se ejecuta el servidor, si se ejecuta desde unoconfig/.envy luego.enven el directorio de trabajo
--env-file lo nombra en su lugar, y entonces no se realiza ninguna búsqueda. Esa es
la misma regla que sigue --tools-file para el archivo de políticas, por lo que ambas marcas significan
lo mismo: este archivo, y nada más.
Dos cosas quedan fuera de ese archivo, una por debajo y otra por encima:
el valor predeterminado integrado, para un ajuste que ningún archivo menciona
una variable de entorno real, que prevalece sobre lo que diga el archivo
La última es la que sorprende a la gente. Un ajuste exportado en tu shell,
puesto en el bloque env de un cliente o fijado en un archivo Compose no se puede
cambiar editando un .env: ni a mano, ni mediante setup. El
valor se escribe, el archivo es correcto y no ocurre nada.
La interfaz de configuración lo indica en lugar de dejar que lo descubras: cada ajuste lleva una insignia que nombra su origen, y uno que está siendo retenido por una variable de entorno se marca como tal. Cuando algo que has guardado parece ignorarse, esa insignia es la respuesta.
En un contenedor esto no es un caso límite. compose.yaml fija el
transporte, la dirección de enlace, el puerto y los hosts permitidos como variables
de entorno reales, porque pertenecen al contenedor y no a la
instalación que hay dentro de él. Todo lo demás (la clave de API, el token HTTP,
los límites) se deja al volumen de configuración, que es lo que permite a la
interfaz de configuración cambiarlo.
El mismo orden se aplica al archivo de políticas, y LXO_MCP_TOOL_POLICY y
--tools-file lo nombran directamente. La interfaz fija el archivo que encontró
al iniciarse, por lo que la página no puede cambiar su propio sujeto sin que te des cuenta.
Nombrando los archivos
--env-file PATH nombra un archivo de ajustes en lugar de buscarlo, y se combina
con --tools-file para que una sola entrada en la configuración de un cliente lleve su propia
cuenta 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 recurrir silenciosamente a la
búsqueda, excepto bajo setup, que existe en parte para crear una.
setup escribe este archivo por ti.
Los ajustes
Variable | Significado | Valor predeterminado |
| Tu clave de API de Lexware Office. Obligatoria. | — |
| Archivo de activación/desactivación por herramienta, ver más abajo |
|
| URL base de la API |
|
| Base de la aplicación web para enlaces profundos |
|
| Dónde se guardan los documentos descargados | directorio de caché del usuario |
| Tiempo de espera HTTP en segundos |
|
| Peticiones por segundo, global en todos los endpoints |
|
| Capacidad del cubo de tokens. El cubo propio de la cuenta contiene 4 |
|
| Filas por página que una búsqueda solicita y devuelve |
|
| Páginas de un PDF que |
|
| Nivel de registro en stderr |
|
|
|
|
| Secreto compartido que toda petición HTTP debe llevar. Obligatorio para un transporte HTTP | — |
| Dirección a la que enlazar para un transporte HTTP |
|
| Puerto al que enlazar |
|
| Ruta URL en la que sirve el transporte |
|
| Valores de | — |
| Crear un token al iniciar si no hay ninguno y escribirlo en el archivo de ajustes | desactivado |
| Terminar el proceso cuando cambie el archivo de ajustes, para algo que lo reinicie | desactivado |
Todos los ajustes anteriores están en uso. LXO_MCP_PAGE_SIZE está limitado a 250, que es
el tamaño de página más bajo que acepta cualquier endpoint, y un valor mayor se rechaza
al iniciar en lugar de convertirse en un error de API más tarde.
Transporte
stdio es el valor predeterminado y el que usan Claude Desktop y clientes locales similares: el cliente inicia el servidor como su propio proceso hijo, y nada más puede hablar con él.
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 8770Dos cosas se interponen ante ese puerto, y ninguna es opcional. Un token de portador
que toda petición debe llevar como Authorization: Bearer <token>: sin
LXO_MCP_BEARER_TOKEN el servidor se niega a iniciar un transporte HTTP por completo,
porque cualquiera que pueda alcanzar el puerto podría gastar tus credenciales de Lexware.
Y la protección contra el rebinding de DNS del SDK, que comprueba Host y
Origin contra una lista de permitidos de los nombres de loopback, ampliada por
--allowed-hosts cuando un contenedor o un proxy pone otro nombre delante.
Ninguna de las dos hace que el puerto sea seguro para publicar en una red. Lo hacen
sobrevivible en una máquina compartida con otros procesos. --host enlaza en un lugar distinto
de loopback, lo que un contenedor tiene que hacer: consulta En un contenedor
para saber por qué eso no es la relajación que parece.
En un contenedor
La imagen se publica para linux/amd64 y linux/arm64, por lo que no se necesita
nada de este repositorio para ejecutar una:
docker pull ghcr.io/benethos-hub/lexware-office-mcp:latestFija una versión para cualquier cosa de la que dependas: :0.2.2 para una versión
exacta, :0.2 para seguir sus versiones de parche. :latest se mueve con cada versión, y
:edge se construye bajo demanda desde lo que contenga main y no es una versión
en absoluto.
Con Compose
docker compose up -d # the server, on 127.0.0.1:8770
docker compose --profile setup up -d # add the configuration interface
docker compose rm -f -s setup # take the interface away againNo uses docker compose --profile setup down. Ese es todo el proyecto: derriba
el servidor con él. rm -f -s setup detiene y elimina el único
servicio y deja el servidor en ejecución. docker compose stop setup también funciona
y conserva el contenedor detenido para la próxima vez.
Tal como se distribuye, compose.yaml se construye desde este checkout. Dos líneas comentadas en
cada uno de sus dos servicios lo cambian a la imagen publicada, y ese archivo es
entonces lo único que necesitas 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:latestEl token que generó para sí mismo está en el volumen de configuración, que es de donde lo lees:
docker exec lexware-office-mcp grep LXO_MCP_BEARER_TOKEN /config/.envEsa única línea en lugar de todo el archivo: una vez que se ha introducido una clave, la clave de API también está ahí dentro, y no tiene por qué desplazarse por una terminal de la que podrías hacer una captura de pantalla.
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.jsonSe inició con --rm, por lo que detenerlo también es su fin:
docker stop lexware-office-mcp-setup--restart unless-stopped no es decoración aquí. El contenedor termina su
proceso cuando cambia el archivo de ajustes, que es lo que lleva un ajuste guardado
a un servidor en ejecución. Sin una política de reinicio, termina y permanece terminado.
Apaga la interfaz cuando hayas terminado
Abre http://127.0.0.1:8771/, introduce la clave, marca las herramientas... y luego detenla. Nada la detiene por ti. No tiene inicio de sesión, acepta una clave de API y seguirá sirviendo esa página felizmente mientras la máquina esté encendida.
docker compose rm -f -s setup # Compose
docker stop lexware-office-mcp-setup # a single container
docker ps --filter name=setup # nothing listed means it is offEl servidor está pensado para ejecutarse. La interfaz está pensada para ejecutarse durante los minutos que configuras en ella, por eso un simple docker compose up la deja fuera y por eso no tiene política de reinicio: una vez detenida, permanece detenida hasta que la vuelves a solicitar.
No hay que preparar nada de antemano. En su primer arranque, el servidor genera un bearer token, lo escribe en el volumen de configuración y lo anuncia — la interfaz lo muestra, y ese es el valor que necesita un cliente. No está incrustado en la imagen, donde cada copia lo compartiría.
El contenedor se vincula a 0.0.0.0, y eso no es una relajación. Un proceso en el loopback del propio contenedor no se puede alcanzar a través de un puerto publicado en absoluto. El aislamiento es el namespace de red, y quién puede alcanzar el puerto lo decide la publicación, que mapea solo 127.0.0.1.
Una configuración guardada en el navegador llega al servidor en ejecución. La configuración se lee una sola vez al arrancar, así que se le indica al contenedor que termine cuando su archivo de configuración 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 vinculación, el puerto, los hosts permitidos — pertenece al contenedor y no se puede cambiar desde el volumen; ver Configuración.
Ejemplos de prompts
Una vez que el servidor está conectado, prompts como estos son el uso previsto:
"¿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 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 con un token bucket. Ese presupuesto es global — cubre todos los endpoints de la API al mismo tiempo, así que leer un contacto y leer una factura se descuentan de la misma asignación.
El servidor refleja esto con un único token bucket compartido por cada solicitud en el proceso, rellenándose ligeramente por debajo de la tasa documentada por defecto. Lexware señala que aplicar el límite exactamente, sin margen, tiende a producir 429 de todos modos una vez que la fluctuación de la red desplaza los tiempos de llegada, así que el valor predeterminado deja margen. Las solicitudes se serializan a través de ese bucket en lugar de lanzarse en paralelo, lo que significa que una pregunta amplia que toca muchos documentos se vuelve más lenta en lugar de bloquearse.
Dos cosas que vale la pena saber:
El presupuesto pertenece a tu cuenta, no a este proceso. Una segunda instancia del servidor, otra integración o un script que ejecutes tú mismo gastan de los mismos dos por segundo.
Lexware advierte que un cliente que sigue insistiendo después de un 429 puede permanecer bloqueado permanentemente. Por lo tanto, el servidor retrocede exponencialmente y se rinde después de algunos intentos en lugar de reintentar con más fuerza.
El bucket de la cuenta se midió el 2026-08-21 y contiene cuatro: cinco solicitudes lanzadas 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úbelo a 4 solo si sabes que este servidor es el único consumidor.
Ambos valores del limitador son configurables mediante LXO_MCP_RATE y LXO_MCP_BURST si tu 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 mypyLa suite de pruebas es totalmente offline. Simula la capa HTTP y no necesita clave de API, así que se ejecuta en cualquier lugar. Dos tipos de prueba salen del proceso sin salir de la máquina: tres inician el servidor como un subproceso real y le hablan por MCP a través de stdio, lo que también demuestra que nada escribe en stdout en la ruta de arranque, y la interfaz de configuración se maneja a través de un servidor HTTP loopback real con una cookie jar real, porque sus protecciones CSRF solo merecen probarse como las encuentra un navegador.
No se incluye ninguna clave de API en este repositorio y ninguna pertenece a CI, así que un checkout nunca puede hablar con Lexware por sí solo. Verificar el servidor contra la API real es, por lo tanto, siempre una ejecución local deliberada con una clave que tú proporcionas, separada de la suite anterior y nunca parte de ella:
uv run python tests/smoke.py
uv run python tests/smoke.py --env-file path/to/.envLee tu cuenta y no escribe nada en ella. El servidor que construye recibe el preset de solo lectura, así que las herramientas de escritura no están disponibles para ser llamadas en absoluto. Imprime lo que verificó, para qué no tenía nada la cuenta y qué falló, y enmascara los ids de registro para que el informe se pueda pegar en algún lugar. pytest nunca lo ejecuta. Consulta SPECS.md sección 14.1 para saber por qué una verificación en vivo no es una puerta de entrada.
Las contribuciones y los problemas son bienvenidos. SPECS.md es donde se registran las decisiones de diseño, con el razonamiento y las mediciones que las respaldan.
Licencia
MIT. Ver LICENSE.
Marcas comerciales y afiliación
Este proyecto no está afiliado, respaldado ni patrocinado por Lexware, Haufe-Lexware GmbH & Co. KG, ni por ninguna 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 se integra este software, en un sentido descriptivo.
El software habla 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 aceptas independientemente de este proyecto.
Maintenance
Related MCP Connectors
Read Lexware Office contacts, articles, invoices and vouchers; create contacts and draft invoices.
211Connect Exact Online to your AI assistant via MCP. Manage Exact Online with natural language.
Connect Claude or Cursor to books, invoices, bills, payroll, and sealed closes.
Read incoming supplier invoices through a remote MCP server and get structured data for accounting.
41
Related MCP Servers
- FlicenseBqualityDmaintenanceMCP server for DACH accounting automation. Connect AI assistants to sevDesk and Lexoffice — create invoices, manage contacts, handle bookings and vouchers for German-speaking businesses.1543 npm-
- AlicenseBqualityAmaintenanceMCP server for the Lexware Office API that enables management of invoices, contacts, articles, vouchers, and more through the Model Context Protocol.66460 npm6Functional Source , Version 1.1, MIT Future
- AlicenseAqualityBmaintenanceEnables MCP-capable assistants to query and manage Lexware Office contacts, sales documents, vouchers, files, payments, webhooks, and reference data via the Lexware Office public API. Adds bank reconciliation tools for matching bank statement CSVs against Lexware vouchers or scanned receipt PDFs.4MIT
- AlicenseAqualityBmaintenanceMCP server for Lexware Office that enables querying and managing contacts, sales documents, vouchers, files, payments, and webhooks through a sandboxed two-tool interface (search/execute) with read-only-by-default write safety.2MIT