lexware-mcp-server
lexware-mcp-server
用于 Lexware Office API 的 MCP 服务器。通过 Model Context Protocol 管理发票、联系人、商品、凭证等。
非官方 — 社区项目。 与 Lexware GmbH 或 Haufe Group 无关联,未获其认可或支持。"Lexware" 和 "Lexware Office" 是其各自所有者的商标;此处仅用于标识此客户端所针对的 API(合理使用)。
20 个资源域中的 66 个工具,提供 6 个入口点,以便您根据 MCP 客户端的工具数量限制选择合适的服务器。
安装
npm install -g @lazyants/lexware-mcp-server或直接运行:
npx @lazyants/lexware-mcp-serverRelated MCP server: e-rechnung-mcp
配置
API 令牌按以下顺序解析:
操作系统密钥环(推荐 — 令牌不会以明文形式写入磁盘)
环境变量
LEXWARE_API_TOKEN
将令牌存储在操作系统密钥环中
从 Lexware Office API 设置 获取您的令牌,然后使用操作系统的原生凭据管理器进行存储。
[!IMPORTANT] 以下命令从交互式提示符读取令牌,而不是将其作为参数传入,因此它绝不会出现在您的 shell 历史记录或进程列表中。请避免将令牌直接粘贴到命令行中。
macOS
省略 -w 后的值会让 security 提示输入令牌(并确认):
security add-generic-password -s "lexware-mcp" -a "api-token" -wWindows(PowerShell)
cmdkey 只能将令牌作为命令行参数接收,这会将其暴露在进程列表中。因此,请从隐藏提示符读取令牌,并通过 CredWrite 直接写入 Windows 凭据管理器,这样令牌永远不会进入 argv。凭据的目标名称是 <account>.<service> — 默认服务为 api-token.lexware-mcp — 这正是服务器读回的名称:
$secure = Read-Host -AsSecureString "Lexware API token"
Add-Type -Namespace LexwareKeyring -Name Native -MemberDefinition @'
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CREDENTIAL {
public uint Flags;
public uint Type;
[MarshalAs(UnmanagedType.LPWStr)] public string TargetName;
[MarshalAs(UnmanagedType.LPWStr)] public string Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public uint CredentialBlobSize;
public IntPtr CredentialBlob;
public uint Persist;
public uint AttributeCount;
public IntPtr Attributes;
[MarshalAs(UnmanagedType.LPWStr)] public string TargetAlias;
[MarshalAs(UnmanagedType.LPWStr)] public string UserName;
}
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CredWriteW(ref CREDENTIAL credential, uint flags);
'@
$blob = [Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($secure)
try {
$cred = New-Object LexwareKeyring.Native+CREDENTIAL
$cred.Type = 1 # CRED_TYPE_GENERIC
$cred.Persist = 2 # CRED_PERSIST_LOCAL_MACHINE
$cred.TargetName = 'api-token.lexware-mcp' # "<account>.<service>"
$cred.UserName = 'api-token'
$cred.CredentialBlob = $blob
$cred.CredentialBlobSize = $secure.Length * 2 # UTF-16 bytes, no terminator
if (-not [LexwareKeyring.Native]::CredWriteW([ref]$cred, 0)) {
throw "CredWrite failed (Win32 error $([Runtime.InteropServices.Marshal]::GetLastWin32Error()))"
}
Write-Host 'Stored Lexware API token in Windows Credential Manager.'
} finally {
[Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($blob)
$secure.Dispose()
Remove-Variable secure, blob
}使用自定义的
LEXWARE_KEYRING_SERVICE(例如acme)?请将TargetName设置为api-token.acme以匹配 — 服务器会在<account>.<service>下查找令牌。
Linux
secret-tool store --label="Lexware Office API" service lexware-mcp username api-token
# (prompts for the token value)存储后,MCP 配置文件无需任何凭据 — 服务器会在启动时从密钥环读取令牌。
改用环境变量
如果您不想使用密钥环,可以在 shell 或 MCP 客户端配置中设置 LEXWARE_API_TOKEN:
export LEXWARE_API_TOKEN=your-token-here环境变量
变量 | 默认值 | 描述 |
| — | API 令牌;在配置的服务没有密钥环条目时使用 |
|
| 密钥环服务名称。当同时连接多个 Lexware 账户时覆盖此值 — 每个账户运行一个服务器实例,各自使用自己的服务名称 |
可选:覆盖 lexware_verify_webhook_signature 使用的 webhook 签名公钥(默认从 Lexware 获取并缓存):
export LEXWARE_WEBHOOK_PUBLIC_KEY="$(cat lexware-webhook-public.pem)"入口点
命令 | 域 | 工具 |
| 全部 20 个域 | 66 |
| 发票、贷项通知单、报价单、订单确认、交货单、预付款发票、催款单、凭证列表 | 32 |
| 联系人、商品 | 10 |
| 凭证、凭证列表、付款 | 8 |
| 国家、付款条件、过账类别、资料、打印版式 | 5 |
| 事件订阅、文件、定期模板 | 12 |
使用拆分服务器来减小上下文大小 — 只选择您需要的拆分。
Claude Code
添加到 ~/.claude/settings.json。如果您已将令牌存储在操作系统密钥环中并使用默认服务名称 lexware-mcp(推荐),则无需 env 键:
{
"mcpServers": {
"lexware": {
"command": "npx",
"args": ["-y", "@lazyants/lexware-mcp-server"]
}
}
}如果您倾向于使用环境变量方式:
{
"mcpServers": {
"lexware": {
"command": "npx",
"args": ["-y", "@lazyants/lexware-mcp-server"],
"env": { "LEXWARE_API_TOKEN": "your-token-here" }
}
}
}拆分服务器
使用拆分服务器来减小上下文大小 — 只选择您需要的入口点。-p @lazyants/lexware-mcp-server 标志告诉 npx 从哪个包获取命令;最后一个参数(例如 lexware-mcp-sales)是该包中定义的特定入口点二进制文件(参见 入口点):
{
"mcpServers": {
"lexware-sales": {
"command": "npx",
"args": ["-y", "-p", "@lazyants/lexware-mcp-server", "lexware-mcp-sales"]
},
"lexware-contacts": {
"command": "npx",
"args": ["-y", "-p", "@lazyants/lexware-mcp-server", "lexware-mcp-contacts"]
}
}
}多账户示例(两个 Lexware 公司,令牌存储在不同的密钥环服务名称下):
{
"mcpServers": {
"lexware-company-a": {
"command": "npx",
"args": ["-y", "@lazyants/lexware-mcp-server"],
"env": { "LEXWARE_KEYRING_SERVICE": "lexware-company-a" }
},
"lexware-company-b": {
"command": "npx",
"args": ["-y", "@lazyants/lexware-mcp-server"],
"env": { "LEXWARE_KEYRING_SERVICE": "lexware-company-b" }
}
}
}Claude Desktop
添加到 claude_desktop_config.json。使用操作系统密钥环(推荐 — 假设令牌存储在默认服务名称 lexware-mcp 下):
{
"mcpServers": {
"lexware": {
"command": "npx",
"args": ["-y", "@lazyants/lexware-mcp-server"]
}
}
}或者改用环境变量:
{
"mcpServers": {
"lexware": {
"command": "npx",
"args": ["-y", "@lazyants/lexware-mcp-server"],
"env": { "LEXWARE_API_TOKEN": "your-token-here" }
}
}
}工具
发票(5 个工具)— 销售
lexware_create_invoice(支持创建时 finalize=true)、lexware_get_invoice、lexware_download_invoice_file、lexware_pursue_invoice、lexware_deeplink_invoice
贷项通知单(5 个工具)— 销售
lexware_create_credit_note、lexware_get_credit_note、lexware_download_credit_note_file、lexware_pursue_credit_note、lexware_deeplink_credit_note
报价单(4 个工具)— 销售
lexware_create_quotation、lexware_get_quotation、lexware_download_quotation_file、lexware_deeplink_quotation
订单确认(5 个工具)— 销售
lexware_create_order_confirmation、lexware_get_order_confirmation、lexware_download_order_confirmation_file、lexware_pursue_order_confirmation、lexware_deeplink_order_confirmation
交货单(5 个工具)— 销售
lexware_create_delivery_note、lexware_get_delivery_note、lexware_download_delivery_note_file、lexware_pursue_delivery_note、lexware_deeplink_delivery_note
预付款发票(3 个工具)— 销售
lexware_get_down_payment_invoice、lexware_download_down_payment_invoice_file、lexware_deeplink_down_payment_invoice
催款单(4 个工具)— 销售
lexware_get_dunning、lexware_download_dunning_file、lexware_pursue_dunning、lexware_deeplink_dunning
凭证列表(1 个工具)— 销售、簿记
lexware_list_voucherlist
默认情况下,这是 API 响应的单页直通。两个附加功能为可选启用:
fetchAllPages: true会持续翻页直到检索完所有页面,上限为 100 次请求。结果会添加fetchedPages和truncated字段,后者用于标记因达到上限而被截断的集合 — API 字段(如totalElements)保持不变。contactName(SQL 风格%/_通配符,不区分大小写)和hasOpenAmount会在获取后在客户端进行过滤,且两者都隐含fetchAllPages。它们在此处而非在lexware_list_vouchers上应用,是因为/voucherlist是携带contactName和openAmount的响应结构。
page 不能与上述三个选项中的任何一个组合使用 — 这些模式会读取每一页,因此起始偏移量毫无意义。请改用 size 来控制批量大小。组合使用会被拒绝而非静默忽略,这样就不会有人误以为偏移量已被生效。
联系人(5 个工具)— 联系人
lexware_list_contacts、lexware_get_contact、lexware_create_contact、lexware_update_contact、lexware_deeplink_contact
商品(5 个工具)— 联系人
lexware_list_articles、lexware_get_article、lexware_create_article、lexware_update_article、lexware_delete_article
凭证(6 个工具)— 簿记
lexware_list_vouchers、lexware_get_voucher、lexware_create_voucher、lexware_update_voucher、lexware_upload_voucher_file、lexware_deeplink_voucher
lexware_list_vouchers 必须提供 voucherNumber。GET /vouchers 是查找端点,而非可浏览的集合 — 缺少该参数时 API 会返回 400 "voucherNumber parameter is required"。要浏览或筛选凭证,请使用 lexware_list_voucherlist,它是集合端点,并且还携带 /vouchers 所没有的汇总字段(contactName、openAmount)。
lexware_get_voucher 会将 voucherStatus 规范化为小写,并在 404 时重试三次(1 秒 / 2 秒 / 4 秒)以覆盖上传后的索引延迟;如果凭证仍然缺失,则返回 { voucherId, status: "processing", message }。其他失败会作为错误报告。
付款(1 个工具)— 簿记
lexware_get_payments
国家(1 个工具)— 参考
lexware_list_countries
付款条件(1 个工具)— 参考
lexware_list_payment_conditions
过账类别(1 个工具)— 参考
lexware_list_posting_categories
资料(1 个工具)— 参考
lexware_get_profile
打印版式(1 个工具)— 参考
lexware_list_print_layouts
事件订阅(5 个工具)— 系统
lexware_create_event_subscription、lexware_list_event_subscriptions、lexware_get_event_subscription、lexware_delete_event_subscription、lexware_verify_webhook_signature
文件(4 个工具)— 系统
lexware_upload_file、lexware_download_file、lexware_get_file_status、lexware_deeplink_file
lexware_get_file_status 调用 GET /files/{id}/status。裸的 GET /files/{id} 是二进制下载路由 — 即使使用 Accept: application/json,它仍会以 base64 编码的文件体返回 200,因此永远无法提供状态元数据。状态路由受作用域限制:没有所需权限的 API 密钥会从 Lexware 收到 access_denied 而非状态信息。
两个上传工具(lexware_upload_file 和 lexware_upload_voucher_file)都接受 contentBase64 或 filePath 形式的文件 — filePath 必须是 MCP 服务器进程可读的绝对路径。对于较大的文件,优先使用 filePath:base64 会使负载膨胀约三分之一,并且必须经过模型的上下文窗口传输。使用 filePath 时,fileName 默认为文件的基本名称,contentType 会自动检测 .png、.jpg/.jpeg、.tiff/.tif 和 .xml,其余情况回退为 application/pdf。请恰好提供两者之一 — 同时提供两者或两者都不提供都是验证错误。
上传大小上限为 5 MB。对于 filePath,大小是在读取文件之前从打开的描述符获取的,因此超大文件只需一次 stat 调用而无需完整加载到内存中;任何非普通文件都会被直接拒绝(否则读取 /dev/zero 将永远不会返回)。解码后的字节数会在之后再次检查,这也覆盖了 contentBase64。失败时会携带 file_too_large 错误以及实际大小和最大大小。
定期模板(3 个工具)— 系统
lexware_list_recurring_templates、lexware_get_recurring_template、lexware_deeplink_recurring_template
安全性
使用操作系统密钥环,将你的 API 令牌完全排除在配置文件之外,也不会进入 shell 历史(参见配置)
切勿将你的 API 令牌提交到版本控制
当只需要列出/获取资源时,请使用只读访问权限
创建、更新和删除工具会修改真实的业务数据 —— 即你 Lexware 账户中的发票、联系人和会计记录
速率限制会自动处理:请求在遇到 429 时会以指数退避方式重试,包括文件上传 —— multipart 请求体在每次重试时都会重新构建,因此可以安全地重放
发布
发布通过 GitHub Release 事件进行。维护者流程:
在
package.json、package-lock.json和server.json中提升版本号(npm version <x.y.z> --no-git-tag-version会同时更新前两个文件)。npm run check-versions在package.json#/version、server.json#/packages[0].version以及package-lock.json的两个版本字段(根字段和packages[""])不一致时会硬性失败。server.json#/version的检查较为宽松:它必须存在,但仅与packages[0].version进行回归性比较 —— 它可能合理地超前(仅注册表重新发布时只提升该字段),因此停留在上一版本的值会通过检查并输出WARN:行,不会导致失败。对于普通发布,两者应同步变动,所以请阅读脚本输出而不是只相信退出码。CHANGELOG.md完全不检查。更新
CHANGELOG.md。提交,并在创建 Release 之前将版本提升合并到
main。然后自行创建标签,基于你已检查过的 SHA,最后才从该标签创建 Release:V=X.Y.Z && PR=<release-pr-number> && SHA="$(gh pr view "$PR" --json mergeCommit -q .mergeCommit.oid)" && test -n "$SHA" && git fetch origin main && git merge-base --is-ancestor "$SHA" origin/main && PKG="$(git show "$SHA:package.json")" && test "$(printf '%s' "$PKG" | node -pe 'JSON.parse(require("fs").readFileSync(0,"utf8")).version')" = "$V" && CL="$(git show "$SHA:CHANGELOG.md")" && printf '%s\n' "$CL" | awk -v v="$V" 'index($0,"## ["v"]")==1{f=1;next} /^## \[/{f=0} /^\[[0-9]+\.[0-9]+\.[0-9]+\]:/{f=0} f' > "/tmp/notes-v$V.md" && grep -q '[^[:space:]]' "/tmp/notes-v$V.md" && git tag -a "v$V" "$SHA" -m "v$V" && git push origin "v$V" && gh release create "v$V" --verify-tag --notes-file "/tmp/notes-v$V.md"此流程防止的故障:在没有现有标签的情况下,
gh release create会将标签放在默认分支的顶端,因此如果在版本提升仍在发布分支上时运行该命令,就会给上一个版本的提交打上标签。工作流随后会发布该提交的package.json中找到的任何版本,结果就是你得到一个vX.Y.Z的 GitHub Release,却静默地重新发布了旧版本。自 5.2.0 起,发布工作流本身会在GITHUB_REF_NAME不是v<package.json version>时拒绝继续(#103),因此错误打标签的 Release 现在会在npm publish之前失败,而不是静默重新发布。不过该保护只在工作流已经开始运行后才会触发 —— 上述流程才是从一开始就阻止错误提交被打上标签的关键,所以请继续使用它,而不是依赖工作流来发现错误。每个环节都至关重要:
gh pr view … .mergeCommit.oid获取的是发布 PR 自身的压缩合并提交。不要用git rev-parse origin/main替代 —— 那只是你查看时main上的当前内容,因此间隙中落入的任何无关合并都会被错误地打标签并发布。gh对未合并的 PR 会以退出码 0 退出且不输出任何内容,因此需要显式的test -n。&&链会在第一步失败时停止,而不是继续执行到不可逆的步骤。两次git show调用都赋值给变量而不是直接管道输出,这样它们的退出状态才会被真正检查 —— 管道只报告最后一个命令的状态,除非设置了pipefail,而这里并不假定已设置。git merge-base --is-ancestor证明该提交确实可以从main到达。仅仅存在是不够的 —— 一个提交可能因为拉取了其他分支而在本地存在,如果其版本文件恰好匹配,它就会通过其余所有检查。版本检查读取的是目标提交中的
package.json,而不是工作树 —— 工作树在$SHA指向别处时仍会显示正确的版本。awk从该提交的CHANGELOG.md中提取该版本对应的章节,用于--notes-file。没有它,Release 正文就是--notes-from-tag在注解中找到的内容 —— 对于此流程来说,就是字面字符串vX.Y.Z,这对任何版本来说都是糟糕的发布说明,对带有破坏性变更的主版本来说更是具有误导性。它在下一个## [标题或第一个链接引用定义处停止,因为文件中最早的条目后面没有标题,否则会吞掉整个链接引用块。使用grep -q而不是test -s来保护结果:一个除空行外为空的章节仍会产生一个一字节的文件,而test -s会接受它。--verify-tag使gh在推送未成功时中止而不是凭空创建标签 —— 这是防止gh回退到上述默认分支顶端行为的保护。
如果标签已推送但
gh release create失败,不要重新运行整个代码块 —— 它会在git tag处停止,这是正确的。只需重新运行最后一条命令。Publish to npm + MCP Registry工作流会自动运行:它使用 provenance 执行npm publish,轮询注册表直到 tarball 可用,然后通过mcp-publisher将匹配的server.json推送到 MCP Registry。
如果版本已存在于 npm 上,工作流会干净地跳过 npm publish(针对部分手动发布的 Release 的切换保护)。
发布认证 —— npm Trusted Publishing(无令牌)
发布使用基于 OIDC 的 npm Trusted Publishing —— 没有 NPM_TOKEN 密钥。工作流的 id-token: write 权限在发布时被兑换为短期、一次性的发布令牌,使用的是在 npm Web 界面中为 @lazyants/lexware-mcp-server 配置的 trusted-publisher 绑定。唯一需要的设置就是 npm 上的那个 trusted-publisher 绑定;仓库密钥中无需存储任何内容。
免责声明
这是一个非官方的、独立的社区项目。它与 Lexware GmbH、Haufe Group 或其任何关联公司均无隶属关系、未经其认可、赞助或支持。如需官方 Lexware 支持,请直接联系 Lexware —— 本 MCP 服务器的问题应在此处报告,而不是报告给 Lexware。
"Lexware" 和 "Lexware Office" 是其各自所有者的商标,在本项目的名称和文档中仅以指名合理使用(nominative fair use)的方式使用,目的是标识此客户端所连接的第三方 API。
创建、更新和删除操作会修改你 Lexware 账户中的真实业务数据。作者按"原样"提供本软件,对意外更改、数据丢失或因使用本软件而产生的任何其他损害不承担任何责任。在对生产数据执行写操作之前,请先在沙盒或非关键账户中进行测试。
许可证
FSL-1.1-MIT —— 完整条款见 LICENSE。
Maintenance
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
- FlicenseBqualityCmaintenanceMCP server for DACH accounting automation. Connect AI assistants to sevDesk and Lexoffice — create invoices, manage contacts, handle bookings and vouchers for German-speaking businesses.1537
- FlicenseNot gradedqualityCmaintenanceMCP server for German e-invoicing with tools to generate and validate XRechnung CII XML locally, supporting German VAT rates and § 19 UStG.
- 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
Related MCP Connectors
MCP server for the PDFGate API. Generate PDFs, manage documents and handle e-signatures.
Hosted MCP server for Mini Accountant: invoices, expenses, customers, analytics, tax estimates.
A MCP server for the Frankfurter API for currency exchange rates.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/lazyants/lexware-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server