小雪
A. 模型上下文协议 将AI代理连接到的(MCP)服务器 由纪 通过Yuki的SOAP API进行会计。
使用Node.js、TypeScript和 @modelcontextprotocol/sdk.
______________________________________________________________________
安装
npm install @codemill-solutions/yuki-mcp然后将其添加到MCP主机配置中(例如。 claude_desktop_config.json):
{
"mcpServers": {
"yuki": {
"command": "node",
"args": ["node_modules/@codemill-solutions/yuki-mcp/dist/index.js"],
"env": {
"YUKI_API_KEY": "your-api-key-here",
"YUKI_DOMAIN_ID": "your-administration-guid-here"
}
}
}
}______________________________________________________________________
先决条件
- Node.js 20+
- 启用API访问的Yuki帐户
- 您的Yuki API密钥(Yuki→ 设置→ API)
______________________________________________________________________
设置
1.安装依赖项
npm install2.配置环境变量
cp .env.example .env编辑 .env:
YUKI_API_KEY=your-api-key-here
YUKI_DOMAIN_ID=your-administration-guid-here # optional at startupYUKI_DOMAIN_ID 可以留空——服务器在没有它的情况下启动。调用 get_administrations 要发现正确的GUID,请通过 administrationId 单个工具上的参数。
3.建造
npm run build4.连接到MCP主机
添加到MCP主机配置中(例如。 claude_desktop_config.json):
{
"mcpServers": {
"yuki": {
"command": "node",
"args": ["/absolute/path/to/yuki-mcp/dist/index.js"],
"env": {
"YUKI_API_KEY": "your-api-key-here",
"YUKI_DOMAIN_ID": "your-administration-guid-here"
}
}
}
}______________________________________________________________________
多管理支持
如果你能做到 多届Yuki政府 (每个都有自己的API密钥),您可以提供一个JSON文件,该文件映射 administrationId 到其对应的API密钥。然后,服务器会自动对每次管理进行身份验证,不需要单个共享密钥。
密钥文件格式
{
"a1b2c3d4-0000-0000-0000-000000000001": "api-key-for-admin-1",
"a1b2c3d4-0000-0000-0000-000000000002": "api-key-for-admin-2"
}路径解析(第一场比赛获胜)
| 优先级 | 路径 |
|---|---|
| 1 | YUKI_API_KEYS_FILE 环境变量(显式路径) |
| 2 | ~/.yuki/api-keys.json (默认用户级位置) |
| 3 | ./api-keys.json (当地发展后备方案) |
环境变量
YUKI_API_KEYS_FILE=/path/to/your/api-keys.json当存在密钥文件时, YUKI_API_KEY 变为可选--文件密钥用于所有特定于管理的工具调用,以及 YUKI_API_KEY (如果设置)作为不针对特定管理的工具的后备方案(例如。 get_administrations).
如果两者都没有 YUKI_API_KEY 启动时找不到密钥文件,服务器会记录一个警告,但会继续运行——工具在调用时会返回一个错误。
______________________________________________________________________
可用工具(30)
行政部门
| 工具 | 说明 |
|---|---|
get_administrations | 列出此API密钥的所有管理机构(公司)。 先运行这个 找到正确的 administrationId. |
get_administration_id | 按确切名称查找管理的GUID。当您知道名称但不知道GUID时很有用。 |
关系
| 工具 | 关键参数 | 说明 |
|---|---|---|
search_relations | searchValue, searchOption?, active?, pageNumber? | 按名称、代码、增值税号、电子邮件等搜索客户和供应商。每页最多返回100个结果。 |
upsert_contact | fullName, contactCode?, contactType?,… | 创建或更新联系人。当 contactCode 匹配更新的现有记录;否则创建新联系人。 |
销货
| 工具 | 关键参数 | 说明 |
|---|---|---|
get_sales_invoices | dateOutstanding?, sortOrder?, includeBankTransactions? | 检索未付的销售发票。 |
process_sales_invoice | reference, subject, date, dueDate, contact, lines | 创建并预订新的销售发票。可选择将其通过电子邮件发送给客户。 |
购货发票
| 工具 | 关键参数 | 说明 |
|---|---|---|
get_missing_invoices | -- | 检索仍需要匹配的购买发票的银行付款--相当于“Postbus”→ Yuki网络界面中的“Ontbrekende manufacturer” |
get_purchase_invoices | dateOutstanding?, sortOrder?, includeBankTransactions? | 检索未付的采购发票。 |
process_purchase_invoice | date, invoiceAmount, invoiceVatAmount, contact, lines | 预订进货发票。接受可选的base64格式的PDF。 |
交易和银行
| 工具 | 关键参数 | 说明 |
|---|---|---|
get_transactions | glAccountCode, startDate, endDate | 检索日期范围内总账账户(如银行账户)的日记账分录。使用 get_gl_accounts 找到正确的代码。 |
get_transaction_details | reference | 检查未完成的项目是否仍然存在,并检索其当前状态。 |
process_journal | subject, entries[] | 发表一篇普通日记(回忆录)。所有输入金额的总和必须恰好为0。用于银行对账、更正和自定义预订。 |
会计
| 工具 | 关键参数 | 说明 |
|---|---|---|
get_gl_accounts | date? | 检索给定日期的所有总账账户及其余额(商业视图)。调用前使用此功能查找帐户代码 get_transactions. |
get_gl_accounts_fiscal | date? | 与 get_gl_accounts 但包括财政调整。用于必须与Yuki的财务报告相匹配的资产负债表和损益表视图。 |
get_net_revenue | startDate, endDate, fiscal? | 检索日期范围内的净收入(netto omzet)。集 fiscal=true 包括财政修正。 |
会计信息
从中获得更丰富的只读视图 AccountingInfo.asmx 服务——标准不提供 Accounting.asmx.
| 工具 | 关键参数 | 说明 |
|---|---|---|
get_gl_account_scheme | -- | 检索完整的总账科目方案(rekeningschema):所有具有类型、子类型、描述和活动/非活动状态的代码。用于验证总账代码或构建账户选择器。 |
get_period_table | yearId | 检索一年的会计期间表:期间编号、名称和日期范围。用于将交易日期转换为人类可读的报告期间名称。 |
get_gl_transactions_detailed | startDate, endDate, glAccountCode?, financialMode? | 详细的交易列表,包括文档类型、存档文件夹、会计期间ID、项目代码和突变用户。比更完整 get_transactions.离开 glAccountCode 所有帐户均为空。 |
get_transaction_document | transactionId | 以base64格式下载已预订交易的源PDF。使用 id 或 hID 从 get_gl_transactions_detailed. |
get_start_balances | yearId, financialMode? | 检索一个会计年度每个总账账户的期初余额(beginbalansen)。 |
文件
| 工具 | 关键参数 | 说明 |
|---|---|---|
upload_document | fileName, dataBase64, folder?, amount? | 通过将PDF的内容以base64字符串的形式传递,将其上传到Yuki存档。使用 get_document_folders 首先找到正确的文件夹ID |
upload_document_from_path | filePath, fileName?, folder?, amount? | 从本地文件路径上传PDF。在内部读取和编码文件——优先于 upload_document 当文件在磁盘上可用时。上传前验证文件是否存在并且是有效的PDF。 |
get_document_folders | -- | 列出管理中可用的所有存档文件夹。 |
list_documents | folderId | 列出特定存档文件夹中的文档。返回文档ID、文件名、日期和金额。 |
search_documents | searchText | 对所有存档文档(文件名、金额、OCR内容)进行全文搜索。 |
get_document | documentId | 按ID(名称、文件夹、日期、金额、状态)检索单个存档文档的元数据。 |
download_document | documentId | 以base64编码字符串的形式下载存档文档 |
get_cost_categories | -- | 列出可用的总账成本类别,用作 costCategory 上传工具中的参数。 |
后台办公室
| 工具 | 关键参数 | 说明 |
|---|---|---|
get_workflow | administrationId? | 检索后台工作流程项目——无法自动处理并等待会计审查的文档。 |
get_outstanding_questions | administrationId? | 在处理相关文件之前,检索会计师提出的需要回复的未决问题。 |
______________________________________________________________________
测试
选项1-MCP检查员(工具级,无LLM)
npm run inspect在以下位置打开浏览器UI http://localhost:5173 在那里,您可以调用单个工具并检查原始响应。
选项2——代理测试工具(带Claude)
运行一个完整的代理循环:Claude对任务进行推理,调用工具,并返回最终答案——就像AI代理使用此MCP一样。
将您的Anthropic API密钥添加到 .env:
ANTHROPIC_API_KEY=sk-ant-...然后运行一个场景:
npm run agent # default: get_administrations
npm run agent -- --scenario outstanding-invoices
npm run agent -- --scenario search-relations --arg "Bedrijf BV"
npm run agent -- --scenario gl-accounts
npm run agent -- --scenario bank-transactions --arg "1200"
npm run agent -- --scenario full-workflow可用场景: get-administrations, search-relations, outstanding-invoices, outstanding-payables, gl-accounts, bank-transactions, full-workflow.
______________________________________________________________________
建筑
src/
├── index.ts # Entry point — loads env + keys file, registers tools, starts stdio transport
├── yuki-client.ts # SOAP client: per-key session cache, envelope builder, axios HTTP, fast-xml-parser
└── tools/
├── administrations.ts # get_administrations, get_administration_id
├── relations.ts # search_relations, upsert_contact
├── invoices.ts # get_sales_invoices, get_purchase_invoices,
│ # process_sales_invoice, process_purchase_invoice
├── transactions.ts # get_transactions, get_transaction_details, process_journal
├── accounting.ts # get_gl_accounts, get_gl_accounts_fiscal, get_net_revenue
├── accounting-info.ts # get_gl_account_scheme, get_period_table,
│ # get_gl_transactions_detailed, get_transaction_document,
│ # get_start_balances, get_missing_invoices
├── documents.ts # upload_document, upload_document_from_path,
│ # get_document_folders, list_documents, search_documents,
│ # get_document, download_document, get_cost_categories
└── backoffice.ts # get_workflow, get_outstanding_questions
scripts/
└── test-agent.ts # Agent test harness (Claude + MCP client loop)认证流程
Yuki使用两步身份验证模式:
Authenticate(accessKey)→ 返回临时sessionID- 所有后续通话都包括
sessionID
YukiClient.getSessionID(adminId?) 透明地处理这个问题。当与A通话时 administrationId,它从加载的密钥映射中解析匹配的API密钥。在进程的生命周期内,每个API键缓存会话ID- Authenticate 每个键只调用一次,而不是每个工具调用一次。
注: Yuki服务中的参数大小写不同--sessionId(小写d)onSales.asmx和Purchase.asmx;sessionID(大写D)onAccounting.asmx,AccountingInfo.asmx,Contact.asmx,以及Archive.asmx。这是按工具处理的。
XML文档
编写工具(process_sales_invoice, process_purchase_invoice, process_journal, upsert_contact)将结构化数据作为XML字符串传递给Yuki xmlDoc SOAP参数。这 XmlValue 包装器确保此XML原始嵌入(不是实体编码)在SOAP信封中。所有用户提供的值都是通过XML转义的 escapeXml().
______________________________________________________________________
费率限制
Yuki执行 每天1000个API请求 (可升级至5000至10000)。每次工具调用都是一个请求。会话ID已缓存,因此 Authenticate 每个服务器进程每个API键只调用一次,而不是每个工具调用一次。
设计代理工作流,一次性获取广泛列表并从代理的上下文窗口引用它们,而不是在每一步都重新获取。
______________________________________________________________________
故障排除
| 错误 | 可能原因 |
|---|---|
SOAP Fault: Authentication failed | YUKI_API_KEY 不正确或在Yuki设置中未启用API访问 |
No API key found for administration … | The administrationId 传递给工具的密钥不在加载的密钥文件中--检查 YUKI_API_KEYS_FILE |
SOAP Fault: Administration not found | 错了 administrationId --奔跑 get_administrations 获取正确的GUID |
Journal entries do not balance | 金额 process_journal 总和不等于0——检查借记/贷记标志 |
HTTP 500 from api.yukiworks.nl | 通常是错误的XML命名空间或格式错误 xmlDoc --在以下位置检查WSDL https://api.yukiworks.nl/ws/{Service}.asmx?wsdl |
File does not appear to be a PDF | 文件位于 filePath 不以开头 %PDF magic bytes--检查您是否指向有效的PDF |
File not found | filePath 传递给 upload_document_from_path 不存在或无法访问 |
Network error | 没有连接到 api.yukiworks.nl --请求在30秒后超时 |
______________________________________________________________________
关于CodeMill解决方案
CodeMill解决方案 是一家总部位于荷兰的荷兰软件公司。我们构建智能、可扩展和定制的解决方案,帮助组织发展、优化流程并实现其数字化目标。
我们的服务包括:
- 定制应用 --门户、仪表板、业务软件和真正增值的完全定制的平台。
- API集成 -通过智能API连接将您的应用程序与其他系统和外部平台连接。
- 移动应用 --iOS和Android应用程序作为web应用程序的逻辑扩展。
yuki-mcp 是我们的开源集成之一,使Yuki的会计平台可以通过模型上下文协议供人工智能代理访问。
📧 info@codemill.dev 🌐 codemill.dev 💼 领英 🐙
______________________________________________________________________
许可证
麻省理工学院——见 许可证.
