内容
# noxctl
终端命令行界面(CLI)和模型上下文协议(MCP)服务器,用于Fortnox — 在终端或通过Claude Code等人工智能(AI)代理管理发票、客户、会计和增值税。
```bash
noxctl init # 交互式设置向导
noxctl company info # 验证连接
noxctl customers list # 列出客户
noxctl invoices list --filter unpaid # 未支付发票
noxctl -o json invoices list | jq . # 脚本/AI的JSON输出
```
## 状态
noxctl是一个独立的、**非官方**的开源项目。**不隶属于Fortnox AB,也不被其认可或认证**。
请使用您自己的Fortnox账户和开发者凭证。**它按原样提供,不提供任何保证或责任** — 作者对您使用它不承担任何责任;您完全自行承担风险,并负责遵守Fortnox条款、瑞典会计/税务/工资单规则和您自己的隐私义务。参见完整的[免责声明](#免责声明)。
## 先决条件
- **Node.js** 20+
- **Fortnox账户**,具有API(应用程序接口)访问权限
- **您自己的Fortnox开发者应用程序**,启用了所需的范围
- **仅限Linux:** `secret-tool` 可用于安全凭证存储
Fortnox产品计划、API激活要求和集成许可可能会发生变化。在发布或依赖此设置进行关键业务工作之前,请验证当前的Fortnox要求。
## 设置
### 如何连接到Fortnox
noxctl是 **Fortnox REST API(v3)** 在 `https://api.fortnox.se/3` 上的一个薄客户端。它使用 **自带应用程序** 模型 — 没有共享后端,也没有中间人:
1. **您** 创建一个Fortnox开发者应用程序(集成)并选择其权限(范围)。
2. **您** 通过OAuth2(`noxctl init`)授权该应用程序访问您的Fortnox公司。
3. noxctl将生成的令牌存储在您的操作系统密钥链中,并直接从您的机器调用Fortnox API — 任何内容都不会通过作者运营的服务器进行代理。
因此,您可以控制凭证、范围和连接的公司。以下三个步骤设置了此连接。
### 1. 创建Fortnox应用程序
> **提示:** 运行 `npx noxctl init` (npx是npm,Node Package Manager附带的工具)以获取交互式设置向导,引导您完成所有这些步骤。
1. 前往 [developer.fortnox.se](https://developer.fortnox.se/) 并点击 **Integrationer** / **集成**
2. 创建一个新的应用程序(集成)
3. 在 **OAuth(开放授权)** 选项卡上:
- 将 **重定向URI(统一资源标识符)** 设置为 `http://localhost:9876/callback`
- 选中 **"Möjliggör auktorisering som servicekonto"** / **"启用服务账户授权"** (推荐)
- 复制您的 **客户端ID** 和 **客户端密钥**
4. 在 **集成** 选项卡上,在 **Behörigheter** / **权限** 下启用这些范围:
| 瑞典语(SV) | 英语(EN) | 所需功能 |
|----------------------|---------------------|------------------------------------------------|
| Artikel | 文章 | 文章、价格、价格列表 |
| Bokföring | 会计 | 凭证、账户、财务报告 |
| Faktura | 发票 | 发票、发票付款、报价、订单、税收减免 |
| Företagsinformation | 公司信息 | 公司信息 |
| Inställningar | 设置 | 财务年度、锁定期间 |
| Kund | 客户 | 客户 |
| Leverantör | 供应商 | 供应商 |
| Leverantörsfaktura | 供应商发票 | 供应商发票、供应商发票付款 |
| Projekt | 项目 | 项目 |
| Kostnadsställe | 成本中心 | 成本中心 |
| Priser | 价格 | 价格列表、价格 |
| Lön | 工资 | 工资单:员工、工资/出勤/缺勤交易、时间表 — **可选**,见下文 |
为您打算使用的资源启用每个范围。缺少的范围将显示为 `403 Forbidden`,并附有指向正确范围的提示。
**工资(Lön)是可选的。** `salary`范围默认不被请求,因为请求应用程序未授予的范围会破坏授权。要使用工资命令,请启用上面的 **Lön** 权限,然后使用 `noxctl init --with-salary` (或为非交互式设置设置 `FORTNOX_WITH_SALARY=1`)授权。授予的范围集每配置文件记住,因此令牌刷新保持有效。
5. 保存集成
您正在此处创建和授权您自己的Fortnox应用程序。noxctl不附带共享的Fortnox凭证,也不绕过Fortnox的授权模型。
### 2. 认证
运行交互式设置向导:
```bash
npx noxctl init
```
如果从本地克隆运行:
```bash
npm run build
node dist/cli.js init
```
向导将提示您输入客户端ID和客户端密钥(掩码输入),运行OAuth流程,验证连接,并可选地为Claude Code注册MCP服务器。
授权后,凭证存储在操作系统的安全存储中:
- **macOS:** 密钥链(`security`)
- **Linux:** 通过 `secret-tool` 的秘密服务
- **Windows:** DPAPI(数据保护API)保护的用户存储
令牌管理在设置后自动进行 — 以后不需要环境变量。
- **使用服务账户:** 使用带有`TenantId`的客户端凭证流 — 无需管理刷新令牌。租户ID在设置期间自动获取。
- **不使用服务账户(默认):** 使用标准OAuth2刷新令牌流。
### 3. 注册为MCP服务器(可选 — 适用于Claude Desktop/Web)
如果您使用Claude Desktop或claude.ai,请注册MCP服务器,以便这些环境可以访问Fortnox。Claude Code可以直接使用CLI,因此此步骤是可选的。
```bash
claude mcp add fortnox -- npx noxctl serve
```
如果您从本地克隆运行而不是从npm运行:
```bash
claude mcp add fortnox -- node /absolute/path/to/noxctl/dist/cli.js serve
```
### 4. 验证连接
```bash
noxctl company info
```
如果从源代码运行:
```bash
node dist/cli.js company info
```
您应该会看到您的公司名称、组织编号和地址。如果这有效,则表示您已设置完成。
## 配置文件(多租户)
noxctl支持单个安装中的多个Fortnox租户 — 如果您为多个公司记账,或希望将沙盒租户与生产环境分开,则非常有用。每个配置文件在其操作系统的安全存储(macOS密钥链 / Linux秘密服务 / Windows DPAPI)中都有自己的OAuth凭证,按配置文件名称索引。
### 运行针对特定配置文件
按优先级顺序(最高优先级获胜)选择配置文件的三种方法:
1. **`--profile <name>`标志** — 显式,每命令
2. **`NOXCTL_PROFILE`环境变量** — 限定在shell会话中
3. **活动指针** — `~/.fortnox-mcp/active-profile`,由`noxctl profile use`设置
如果以上均未设置,则noxctl使用`default`配置文件(所有用户一直使用的配置文件 — 无需选择加入)。
```bash
noxctl init --profile staging # 授权第二个租户
noxctl --profile staging invoices list # 针对staging进行一次性操作
NOXCTL_PROFILE=staging noxctl company info # shell范围
noxctl profile use staging # 粘性 — 持续到指针
noxctl profile current # 显示已解析的配置文件 + 源
noxctl profile list # 列出已知配置文件
```
### MCP服务器
当Claude Desktop / claude.ai启动时,MCP服务器从`NOXCTL_PROFILE`和启动时的活动指针解析配置文件,并为会话绑定。当通过`noxctl --profile <name> serve`启动时,CLI转发标志。
要并行运行多个MCP服务器(每个租户一个),请使用不同的名称和作用域环境注册它们:
```bash
claude mcp add fortnox-prod -- npx noxctl serve
claude mcp add fortnox-staging -e NOXCTL_PROFILE=staging -- npx noxctl serve
```
非默认会话在启动时打印 `[profile: <name>]` 标准错误横幅,并将每个Fortnox API错误和令牌刷新失败的前缀为相同的标签,以便从单个错误行中可以诊断绑定不正确的会话。
### 失败关闭指针语义
如果活动指针变得不可读或损坏,并且未设置明确的 `--profile` 标志或 `NOXCTL_PROFILE`,则 `noxctl serve` **拒绝启动**,而不是静默地回落到 `default`。这可以防止损坏的指针将生产MCP会话路由到错误的租户。CLI的 `doctor` 和 `profile use` 命令是豁免的 — 它们仍然可以针对损坏的指针运行,以便您修复它。
## YubiKey锁定的密钥链(macOS)
默认情况下,凭证存储在您的macOS **登录密钥链** 中,该密钥链在您登录时自动解锁。这样很方便,但这意味着AI代理(或以您的身份运行的任何东西)可以在您进行会话确认之前读取令牌。
可选的 **专用密钥链** 将凭证移动到一个单独的、锁定睡眠的密钥链中,其密码通过YubiKey的HMAC-SHA1质询响应派生。您在每个会话开始时使用单个点击解锁它;当您的Mac睡眠时,它会自动重新锁定。密钥链密码永远不会被输入或存储 — 它仅存在于YubiKey上。
这是可选的,仅限于macOS。它不会改变Linux或Windows上存储凭证的方式。
### 一次性YubiKey设置
为质询响应编程OTP插槽2(需要触摸)。**这只会写入空的OTP插槽2** — FIDO2、PIV、OATH、OpenPGP和插槽1不受影响,并且可以通过`ykman otp delete 2`恢复。
```bash
brew install ykman # 如果尚未安装
ykman otp chalresp --generate --touch 2 # 编程插槽2
```
### 启用
```bash
noxctl keychain init # 生成挑战,点击以派生密码,
# 创建锁定密钥链,将现有凭证复制到其中
```
`init` 使用 **复制和保留**:您的现有登录密钥链凭证将被复制到新密钥链中,但保留原样作为回滚。一旦您确认新流程正常工作,请删除原始凭证:
```bash
noxctl keychain seal # 删除登录密钥链副本(不可逆)
```
直到您 `seal`,登录副本仍然可读,无需点击 — 因此每个会话的保护还不完全有效。
### 每天使用
```bash
noxctl keychain unlock # 点击您的YubiKey — 打开直到Mac下次睡眠
noxctl keychain status # 模式、锁定状态、ykman/YubiKey存在
noxctl keychain lock # 立即锁定
```
当密钥链被锁定需要凭证时,任何命令都会快速失败,并显示一条消息,提示您运行 `noxctl keychain unlock` — 它不会弹出macOS密码对话框(质询响应密码无法输入到其中)。
### 如果您丢失YubiKey
密钥链密码仅存在于密钥上,因此丢失或重新编程密钥意味着专用密钥链无法解锁。只要您 **没有** 运行 `seal`,您的凭证仍在登录密钥链中 — 删除专用密钥链和挑战文件以恢复:
```bash
security delete-keychain ~/Library/Keychains/fortnox-mcp.keychain-db
rm ~/.fortnox-mcp/keychain-challenge
```
如果您 **已经** 封印,请重新运行 `noxctl init` 以从头开始认证。
## 工具
每个操作都可以通过CLI命令和MCP工具获得。CLI是主要接口;MCP服务器向AI代理公开相同的操作。所有变更 — 每个标记为 `(mutation)` 的行 — 都需要在TTY上确认,并需要 `--yes`(CLI)或 `confirm: true`(MCP)时通过管道传输。参见 [变更安全性](#变更安全性)。
### 客户
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl customers list [--search <term>]` | `fortnox_list_customers` | 列出/搜索客户 |
| `noxctl customers get <number>` | `fortnox_get_customer` | 获取单个客户 |
| `noxctl customers create --name <name>` | `fortnox_create_customer` | 创建客户(变更) |
| `noxctl customers update <number> --input <file>` | `fortnox_update_customer` | 更新客户(变更) |
### 供应商
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl suppliers list [--search <term>]` | `fortnox_list_suppliers` | 列出/搜索供应商 |
| `noxctl suppliers get <number>` | `fortnox_get_supplier` | 获取单个供应商 |
| `noxctl suppliers create --name <name>` | `fortnox_create_supplier` | 创建供应商(变更) |
| `noxctl suppliers update <number> --input <file>` | `fortnox_update_supplier` | 更新供应商(变更) |
### 文章
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl articles list [--search <term>]` | `fortnox_list_articles` | 列出/搜索文章 |
| `noxctl articles get <number>` | `fortnox_get_article` | 获取单个文章 |
| `noxctl articles create --description <text>` | `fortnox_create_article` | 创建文章(变更) |
| `noxctl articles update <number> --input <file>` | `fortnox_update_article` | 更新文章(变更) |
### 发票
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl invoices list [--filter <status>] [--customer <number>]` | `fortnox_list_invoices` | 列出/过滤发票。过滤器:`cancelled`,`fullypaid`,`unpaid`,`unpaidoverdue`,`unbooked` |
| `noxctl invoices get <docNumber>` | `fortnox_get_invoice` | 获取单个发票 |
| `noxctl invoices create --customer <number> --input <file>` | `fortnox_create_invoice` | 创建发票(变更) |
| `noxctl invoices update <docNumber> --input <file>` | `fortnox_update_invoice` | 更新未记账的发票(变更) |
| `noxctl invoices send <docNumber> [--method email\|print\|einvoice] [--subject <s>] [--body <s>] [--bcc <email>]` | `fortnox_send_invoice` | 通过电子邮件(默认)、打印或电子发票发送(变更) |
| `noxctl invoices bookkeep <docNumber>` | `fortnox_bookkeep_invoice` | 记账发票(变更) |
| `noxctl invoices credit <docNumber>` | `fortnox_credit_invoice` | 冲销发票(变更) |
### 发票付款(inbetalningar)
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl invoice-payments list [--invoice <number>]` / 别名 `noxctl ip list` | `fortnox_list_invoice_payments` | 列出发票付款 |
| `noxctl invoice-payments get <number>` | `fortnox_get_invoice_payment` | 获取单个发票付款 |
| `noxctl invoice-payments create --invoice <n> --amount <a> --date <date>` | `fortnox_create_invoice_payment` | 注册发票付款(变更) |
| `noxctl invoice-payments bookkeep <number>` | — | 记账发票付款(变更) |
| `noxctl invoice-payments delete <number>` | `fortnox_delete_invoice_payment` | 删除发票付款(变更) |
### 供应商发票(leverantörsfakturor)
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl supplier-invoices list [--filter <status>] [--supplier <number>]` / 别名 `si list` | `fortnox_list_supplier_invoices` | 列出/过滤供应商发票 |
| `noxctl supplier-invoices get <givenNumber>` | `fortnox_get_supplier_invoice` | 获取单个供应商发票 |
| `noxctl supplier-invoices create --supplier <n> --input <file>` | `fortnox_create_supplier_invoice` | 创建供应商发票(变更) |
| `noxctl supplier-invoices bookkeep <givenNumber>` | `fortnox_bookkeep_supplier_invoice` | 记账供应商发票(变更) |
### 供应商发票付款(utbetalningar)
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl supplier-invoice-payments list [--invoice <number>]` / 别名 `sip list` | `fortnox_list_supplier_invoice_payments` | 列出供应商发票付款 |
| `noxctl supplier-invoice-payments get <number>` | `fortnox_get_supplier_invoice_payment` | 获取单个供应商发票付款 |
| `noxctl supplier-invoice-payments create --invoice <n> --amount <a> --date <date>` | `fortnox_create_supplier_invoice_payment` | 注册供应商发票付款(变更) |
| `noxctl supplier-invoice-payments delete <number>` | `fortnox_delete_supplier_invoice_payment` | 删除供应商发票付款(变更) |
### 报价(offerter)
| CLI | MCP工具 | 描述 |
|-----|----------|-------------|
| `noxctl offers list [--filter <status>] [--customer <number>]` | `fortnox_list_offers` | 列出/过滤报价。过滤器:`cancelled`,`expired`,`ordercreated`,`invoicecreated` |
| `noxctl offers get <docNumber>` | `fortnox_get_offer` | 获取单个报价 |
| `noxctl offers create --customer <number> --input <file>` | `fortnox_create_offer` | 创建报价(变更) |
| `noxctl offers update <docNumber> --input <file>` | `fortnox_update_offer` | 更新报价(变更) |
| `noxctl offers create-invoice <docNumber>` | `fortnox_create_invoice_from_offer` | 转换为发票(变更) |
| `noxctl offers create-order <docNumber>` | `fortnox_create_order_from_offer` | 转换为订单(变更) |
### 订单(订单)
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl orders list [--filter <状态>] [--customer <编号>]` | `fortnox_list_orders` | 列出/筛选订单。筛选条件:`cancelled`, `invoicecreated`, `invoicenotcreated` |
| `noxctl orders get <文档编号>` | `fortnox_get_order` | 获取单个订单 |
| `noxctl orders create --customer <编号> --input <文件>` | `fortnox_create_order` | 创建订单(变更) |
| `noxctl orders update <文档编号> --input <文件>` | `fortnox_update_order` | 更新订单(变更) |
| `noxctl orders create-invoice <文档编号>` | `fortnox_create_invoice_from_order` | 将订单转换为发票(变更) |
### 会计
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl vouchers list [--series <系列>] [--from <日期>] [--to <日期>]` | `fortnox_list_vouchers` | 列出凭证,可选按系列和日期范围筛选 |
| `noxctl vouchers get <系列> <编号>` | `fortnox_get_voucher` | 获取单个凭证及其行 |
| `noxctl vouchers create --input <文件>` | `fortnox_create_voucher` | 创建凭证,含借方/贷方行(变更) |
| `noxctl vouchers attach <系列> <编号> <文件...> [--year]` | `fortnox_attach_voucher_files` | 上传收据/凭证文件并链接到凭证(变更;需要 Fortnox 存档范围) |
| `noxctl accounts list [--search <搜索词>]` | `fortnox_list_accounts` | 查看会计科目表,可按名称或编号搜索 |
### 财务报告
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl reports income [--year <年份>] [--from <日期>] [--to <日期>]` / 别名 `reports resultat` | `fortnox_income_statement` | 损益表(resultaträkning) |
| `noxctl reports balance [--year <年份>] [--to <日期>]` / 别名 `reports balans` | `fortnox_balance_sheet` | 资产负债表(balansräkning) |
### 税务
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl tax report --from <日期> --to <日期>` | `fortnox_tax_report` | 指定期间的增值税汇总信息。在提交前请与 Fortnox 进行核对。日期格式为 `YYYY-MM-DD` |
### 税收减免(ROT/RUT)
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl tax-reductions list [--filter <类型>]` | `fortnox_list_taxreductions` | 列出税收减免(ROT/RUT) |
| `noxctl tax-reductions get <ID>` | `fortnox_get_taxreduction` | 获取单个税收减免 |
| `noxctl tax-reductions create --reference <编号> --type <rot\|rut> --document-type <类型> --customer-name <名称> --amount <奥瑞>` | `fortnox_create_taxreduction` | 创建 ROT/RUT 税收减免(变更) |
### 项目
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl projects list` | `fortnox_list_projects` | 列出项目 |
| `noxctl projects get <编号>` | `fortnox_get_project` | 获取单个项目 |
| `noxctl projects create --description <文本>` | `fortnox_create_project` | 创建项目(变更) |
| `noxctl projects update <编号> --input <文件>` | `fortnox_update_project` | 更新项目(变更) |
### 成本中心(kostnadsställen)
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl costcenters list` | `fortnox_list_costcenters` | 列出成本中心 |
| `noxctl costcenters get <代码>` | `fortnox_get_costcenter` | 获取单个成本中心 |
| `noxctl costcenters create --code <代码> --description <文本>` | `fortnox_create_costcenter` | 创建成本中心(变更) |
| `noxctl costcenters update <代码> --input <文件>` | `fortnox_update_costcenter` | 更新成本中心(变更) |
| `noxctl costcenters delete <代码>` | `fortnox_delete_costcenter` | 删除成本中心(变更) |
### 价格列表和价格
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl pricelists list` | `fortnox_list_pricelists` | 列出价格列表 |
| `noxctl pricelists get <代码>` | `fortnox_get_pricelist` | 获取单个价格列表 |
| `noxctl pricelists create --code <代码> --description <文本>` | `fortnox_create_pricelist` | 创建价格列表(变更) |
| `noxctl pricelists update <代码> --input <文件>` | `fortnox_update_pricelist` | 更新价格列表(变更) |
| `noxctl prices list --pricelist <代码> [--article <编号>]` | `fortnox_list_prices` | 列出价格列表中的价格 |
| `noxctl prices get --pricelist <代码> --article <编号>` | `fortnox_get_price` | 获取特定价格 |
| `noxctl prices update --pricelist <代码> --article <编号> --input <文件>` | `fortnox_update_price` | 更新价格(变更) |
### 合同(avtal — 定期发票)
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl contracts list [--filter active\|inactive\|finished]` | `fortnox_list_contracts` | 列出/筛选合同 |
| `noxctl contracts get <编号>` | `fortnox_get_contract` | 获取单个合同 |
| `noxctl contracts create --customer <编号> --input <文件>` | `fortnox_create_contract` | 创建合同(变更) |
| `noxctl contracts update <编号> --input <文件>` | `fortnox_update_contract` | 更新合同(变更) |
| `noxctl contracts finish <编号>` | `fortnox_finish_contract` | 完成合同(变更) |
| `noxctl contracts create-invoice <编号>` | `fortnox_create_invoice_from_contract` | 立即创建下一张发票(变更) |
| `noxctl contracts increase-invoice-count <编号>` | `fortnox_increase_contract_invoice_count` | 扩展一个发票(变更) |
### 财务年度和锁定期间
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl financial-years list [--date <日期>]` | `fortnox_list_financialyears` | 列出财务年度(räkenskapsår) |
| `noxctl financial-years get <ID>` | `fortnox_get_financialyear` | 获取单个财务年度 |
| `noxctl financial-years locked-period` | `fortnox_get_lockedperiod` | 显示会计截止日期 |
### 薪资(Lön)
> **需要 `salary` 权限**,该权限是**可选的**。在 Fortnox 应用中启用 **Lön** 权限,然后运行 `noxctl init --with-salary`(或在非交互式设置中设置 `FORTNOX_WITH_SALARY=1`)。如果没有启用,则这些端点返回 `403 Forbidden`。请参阅 [设置](#1-create-a-fortnox-app)。
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl employees list` | `fortnox_list_employees` | 列出员工 |
| `noxctl employees get <员工ID>` | `fortnox_get_employee` | 获取单个员工 |
| `noxctl employees create --first-name <名> --last-name <姓> --email <邮箱> [--employment-form <表单> --personel-type <类型> --salary-form <表单>]` | `fortnox_create_employee` | 创建员工(变更)。 `--employment-form`/`--personel-type`/`--salary-form` 是必需的 *除非* 公司有默认的就业协议,否则 Fortnox 会以 `ftgavtalid` 错误拒绝 |
| `noxctl employees update <员工ID> --input <文件>` | `fortnox_update_employee` | 更新员工(变更) |
| `noxctl salary-transactions list [--employee <ID>] [--date <日期>]` | `fortnox_list_salarytransactions` | 列出工资交易 |
| `noxctl salary-transactions get <工资行>` | `fortnox_get_salarytransaction` | 获取单个工资交易 |
| `noxctl salary-transactions create --employee <ID> --salary-code <代码> --date <日期> [--amount <金额>]` | `fortnox_create_salarytransaction` | 创建工资交易(变更) |
| `noxctl salary-transactions delete <工资行>` | `fortnox_delete_salarytransaction` | 删除工资交易(变更) |
| `noxctl attendance-transactions list [--employee <ID>] [--date <日期>]` | `fortnox_list_attendancetransactions` | 列出考勤(närvaro)交易 |
| `noxctl attendance-transactions get <ID>` | `fortnox_get_attendancetransaction` | 获取单个考勤交易 |
| `noxctl attendance-transactions create --employee <ID> --cause-code <代码> --date <日期> [--hours <小时>]` | `fortnox_create_attendancetransaction` | 创建考勤交易(变更) |
| `noxctl attendance-transactions delete <ID>` | `fortnox_delete_attendancetransaction` | 删除考勤交易(变更) |
| `noxctl absence-transactions list [--employee <ID>] [--date <日期>]` | `fortnox_list_absencetransactions` | 列出缺勤(frånvaro)交易 |
| `noxctl absence-transactions get <ID>` | `fortnox_get_absencetransaction` | 获取单个缺勤交易 |
| `noxctl absence-transactions create --employee <ID> --cause-code <代码> --date <日期> [--hours <小时>] [--extent <extent>]` | `fortnox_create_absencetransaction` | 创建缺勤交易(变更) |
| `noxctl absence-transactions delete <ID>` | `fortnox_delete_absencetransaction` | 删除缺勤交易(变更) |
| `noxctl schedule-times get <员工ID> <日期>` | `fortnox_get_scheduletime` | 获取某员工在某日期的日程安排 |
| `noxctl schedule-times update <员工ID> <日期> --input <文件>` | `fortnox_update_scheduletime` | 更新某员工某日的日程安排(变更) |
| `noxctl schedule-times reset-day <员工ID> <日期> --input <文件>` | `fortnox_reset_scheduletime_day` | 更新某员工某日的日程安排并重置该日(变更) |
### 分析和仪表盘
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl analytics overdue` | `fortnox_overdue_invoices` | 逾期发票汇总 |
| `noxctl analytics unpaid` | `fortnox_unpaid_totals` | 未付金额汇总,含逾期金额细分 |
| `noxctl analytics top-customers [--period <期间>]` | `fortnox_top_customers` | 按发票金额列出主要客户 |
| `noxctl analytics vat --period <期间>` | `fortnox_vat_summary` | 增值税汇总,含净增值税位置 |
| `noxctl dashboard` | — | 一览:未付、逾期、最近的发票、每月收入 |
### 公司
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl company info` | `fortnox_company_info` | 公司名称、组织编号、地址和设置 |
### 实用工具
| 命令行接口 | MCP 工具 | 描述 |
| --- | --- | --- |
| `noxctl init` | — | 交互式设置向导 — 连接到 Fortnox、存储凭证、可选注册 MCP 服务器 |
| `noxctl doctor` | `fortnox_status` | 验证设置:Node 版本、凭证、令牌状态、API 连接性和范围 |
| `noxctl logout` | — | 从 OS 密钥链中删除存储的凭证 |
| `noxctl profile use <名称>` | — | 设置活动配置文件(写入 `~/.fortnox-mcp/active-profile`) |
| `noxctl profile current` | — | 显示当前解析的配置文件及其来源 |
| `noxctl profile list` | — | 从索引中列出已知配置文件 |
| `noxctl completion <bash\|zsh\|fish>` | — | 生成 Shell 补全脚本 |
## CLI 输出
默认情况下,`noxctl` 在交互式终端使用 **表格输出**,在管道或重定向时使用 **JSON**。使用 `-o` 覆盖:
```bash
noxctl invoices list # 终端使用表格输出,管道使用 JSON
noxctl -o json invoices list # 强制 JSON(JavaScript Object Notation)
noxctl -o table invoices list # 强制表格
noxctl invoices list | jq . # 自动 JSON(管道)
```
JSON 输出具有稳定的信封:列表命令在复数资源键下包装(`{"Invoices": [...], "MetaInformation": {...}}`),而单资源命令在单数键下(`{"Invoice": {...}}`),因此脚本调用者可以依赖固定访问器。JSON 模式下的失败以结构化信封形式发出到 stderr:
```json
{ "error": { "status": 400, "message": "...", "source": "fortnox-api" } }
```
自然日期期间在 `--from`/`--to` 均可使用,通过 `--period`:`Q1`、`2025-Q3`、`march`/`mars`、`this-quarter`、`last-quarter`、`this-month`、`last-month`、`ytd`、`this-year`、`last-year` 或纯年。期间基于 **calendar-year**(不支持破碎的财政年度)。
运行本地克隆而非安装二进制文件时,请将 `noxctl` 替换为 `node dist/cli.js`。
## 变更安全性
变更命令在执行前需要确认。在交互式终端,CLI 提示 `[y/N]`。在非交互式上下文(管道输入、CI),请显式传递 `--yes` 或命令将安全失败。
CLI:
```bash
noxctl invoices send 1001 # 提示: "Send invoice 1001 via email. Continue? [y/N]"
noxctl invoices send 1001 --yes # 跳过提示(脚本/AI)
noxctl invoices send 1001 --dry-run # 预览而不发送
noxctl customers update 42 --input customer.json # 提示确认
noxctl vouchers create --input voucher.json --dry-run # 预览负载
```
MCP 工具:- 变更工具需要 `confirm: true`
- 使用 `dryRun: true` 预览请求而不发送它
- 原始 Fortnox JSON 是通过 `includeRaw: true` 可选的
- `includeRaw: true` 可以将更多会计和个人数据暴露给 AI 转录日志和终端日志,而不仅仅是汇总输出
## 隐私和 AI 使用
如果您通过 Claude、MCP 客户端或其他 AI 工具使用 noxctl,客户、供应商、发票和会计数据可能会离开本地 Fortnox UI 上下并进入第三方系统。
- 保持 `includeRaw` 关闭,除非您真正需要完整的数据
- 审查 AI 提供商的保留、日志记录和处理器条款
- 确保您的 GDPR 设置涵盖此用途,包括处理器协议和任何所需的第三方转移评估
- 合规请参阅 [PRIVACY.md](PRIVACY.md) 中的项目特定隐私说明。
## 税务和会计限制
noxctl 可以帮助您检查 Fortnox 数据并提交您选择的 操作。
- 增值税报告是信息性总结,而不是提交声明
- 瑞典记账责任仍由公司所有者或董事会负责
- 审查发票、凭证和增值税总额后再确认或提交任何内容
- 在提交给 Skatteverket 之前对增值税数字进行核对
## 示例
问 Claude 自然语言支持瑞语和英语:
- "Skapa en faktura till kund 42 为 10 咨询小时 á 1200 kr"
- "Create an invoice for customer 42: 10 consulting hours at 1200 SEK (Swedish Krona)"
- "Visa obetalda fakturor / Show all unpaid invoices"
- "Vad har vi för utgående moms Q1 2025? / What's our outgoing VAT for Q1 2025?"
- " Bokför kontorsmaterial för 1250 kr inkl moms / Book office supplies for 1250 SEK incl VAT"
- "Skicka faktura 1001 via e-post / Send invoice 1001 by email"
## 术语表
| 缩写 | 全称 |
|---|---|
| AI | 人工智能 |
| API | 应用程序接口 |
| BCC | 盲碳复制 — 一种电子邮件字段,向某人发送副本,而其他收件人看不到 |
| CLI | 命令行接口 — 一种基于文本的方式,通过输入命令与软件交互 |
| DPAPI | 数据保护 API — Windows 中用于加密存储凭据的功能 |
| JSON | JavaScript 对象表示法 — 一种广泛使用的结构化数据格式 |
| MCP | 模型上下文协议 — 一种标准,允许 AI 助手使用外部工具和数据源 |
| MIT | 麻省理工学院 — 指一种宽容的开源软件许可 |
| npm | 节点包管理器 — 用于安装和管理 JavaScript 包的工具 |
| npx | 随 npm 提供的工具,用于在全局安装包之前运行它们 |
| OAuth | 开放授权 — 一种标准协议,用于授予应用有限的帐户访问权限,而无需共享密码 |
| OS | 操作系统 — 运行计算机的软件(例如 macOS、Windows、Linux) |
| SEK | 瑞典克朗 — 瑞典的货币 |
| URI | 统一资源标识符 — 一种标识资源的地址(类似于网页链接) |
| VAT | 增值税 — 在生产各阶段添加的消费税 |
## 免责声明
noxctl 是一个独立的、**非官方的**开源项目 — **与 Fortnox AB 无关,不受 Fortnox AB 认可或认证**。“Fortnox”是 Fortnox AB 的商标,仅在此用于描述互操作性。
**无担保,无责任**。noxctl 按“原样”提供,不提供任何形式的担保,明确或暗示。作者和贡献者对因使用 noxctl 而产生的任何后果 **不承担任何责任和义务**,包括但不限于:错误、不完整或丢失的记账;错误的发票、付款、工资或税务申报;数据泄露或丢失;服务中断;经济损失;或 Fortnox 合同的任何违反。**您自行承担全部风险**。(参见下面的 MIT 许可 — 相同的限制完全适用。)
**您对使用 noxctl 所做的一切负责**。根据瑞典法律(Bokföringslagen),公司所有者或董事会对其会计和工资记录的准确性承担全部责任,无论使用何种工具。noxctl 只执行您给出的指令 — 在确认之前请审查条目,特别是使用 `--yes` / `confirm: true` 时,并与 Fortnox 和您自己的记录进行核对。
**隐私/个人数据**。noxctl 可以将会计数据和**个人数据**移出 Fortnox — 客户/供应商详细信息,以及通过工资命令,员工个人数据,如瑞典个人身份号码(personnummer)、工资和缺勤记录。当与 AI 助手或 MCP 主机一起使用时,这些数据可能会进入第三方系统。除非必要完整有效载荷,否则请保持 `includeRaw: false`,并确保您的使用符合 GDPR、处理器/数据处理协议和任何所需的传输评估。请参阅 `PRIVACY.md`。
**税务说明**:增值税报告仅为信息摘要。在向 Skatteverket 提交任何内容之前,请与 Fortnox 和您的会计记录进行核对。
**Fortnox API 访问** 需要您自己的 Fortnox 帐户、开发者应用和凭证。您必须遵守适用的 Fortnox 开发者条款。noxctl 不提供共享凭证,不重新分发 Fortnox 拥有的代码或数据(甚至不是 Fortnox 的 OpenAPI 规范 — 只有不透明的漂移检测哈希),并且不通过作者运营的任何服务器路由 — 它直接从您的机器调用 Fortnox API。
### 您在 Fortnox 条款下的责任
当您注册 Fortnox 开发者应用以使用 noxctl 时,**您**(而不是 noxctl 作者)接受 Fortnox 的 [开发者协议](https://www.fortnox.se/developer),并且是合同方。特别是:
- **资格**:注册 Fortnox 开发者应用需要根据瑞典法律注册的公司(开发者协议第 5.1 条)。
- **为他人运行 Fortnox** (例如,为客户担任簿记员/会计师)使您成为数据处理器 — 您必须与该客户(第 12.3 条)具有数据处理协议(*personuppgiftsbiträdesavtal*)。为自己的公司使用它不会触发此要求。
- **将数据发送到 AI/LLM**:Fortnox 不禁止,但您负责个人数据分发的合法性(第 13.5 条 + GDPR) — 特别是工资(Lön)和 ROT/RUT 数据,其中包含个人身份号码(personnummer)。确保合法的基础,并在需要时,与您的 AI 提供商和非欧盟/EES 提供商的有效传输机制具有数据处理协议。
- noxctl 是 **Fortnox 自己的 API 的客户端** — 补充,而不是替代 — 仅使用已文档化的端点和您自己的凭证。
## 许可
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器