noxctl
Fortnox的命令行界面(CLI)和模型上下文协议(MCP)服务器——从终端或Claude Code等人工智能代理管理发票、客户、簿记和增值税(VAT)。
noxctl init # interactive setup wizard
noxctl company info # verify connection
noxctl customers list # list customers
noxctl invoices list --filter unpaid # unpaid invoices
noxctl -o json invoices list | jq . # JSON output for scripting/AI状态
noxctl是一个独立的开源项目。它不隶属于Fortnox AB,也没有Fortnox AB的背书或认证。
将其与您自己的Fortnox帐户和开发人员凭据一起使用。您有责任遵守Fortnox条款、瑞典簿记/税务规则以及您自己的隐私义务。
先决条件
- Node.js 20+
- Fortnox帐户 使用API(应用程序编程接口)访问
- 您自己的Fortnox开发者应用 启用了所需的作用域
- 仅限Linux:
secret-tool可用于安全凭据存储
Fortnox产品计划、API激活要求和集成许可可能会发生变化。在发布或依赖此设置进行关键业务工作之前,请验证当前的Fortnox要求。
设置
1.创建Fortnox应用程序
提示: 跑 npx noxctl init (npx是npm(节点包管理器)附带的一个工具),用于交互式设置向导,指导您完成所有这些步骤。- 首选 developer.fortnox.se 然后单击 集成器 / 集成
- 创建新应用程序(集成)
- 在 OAuth(开放授权) 选项卡:
- 集 重定向URI(统一资源标识符) 到 http://localhost:9876/callback - 检查 “启用授权作为服务帐户” / “启用服务帐户授权” (推荐) - 复制您的 客户端ID 和 客户端密钥
- 在 集成 选项卡,在下启用这些作用域 权限 / 权限:
| 瑞典语(SV) | 英语(EN) | 需要 |
|---|---|---|
| 文章 | 文章 | 文章、价格、价目表 |
| Bokföring | 簿记 | 凭单、账目、财务报告 |
| Faktura | 发票 | 发票、发票付款、报价、订单、减税 |
| 公司信息 | 公司信息 | |
| 设置 | 设置 | 财政年度, 锁定期 |
| Kund | 客户 | 顾客 |
| Leverantör | 供应商 | 供应商 |
| Leverantörsfaktura | 供应商发票 | 供应商发票,供应商发票付款 |
| 项目 | 项目 | 项目 |
| 成本中心 | 成本中心 | |
| Priser | 价格 | 价目表,价格 |
为您打算使用的资源启用每个范围。缺少的示波器表面为 403 Forbidden 一个提示指向正确的那个。
- 保存集成
您正在此处创建并授权自己的Fortnox应用程序。noxctl不提供共享的Fortnox凭据,也不会绕过Fortnox的授权模型。
2.身份验证
运行交互式安装向导:
npx noxctl init如果从本地克隆运行:
npm run build
node dist/cli.js init向导将提示您输入客户端ID和客户端密钥(掩码输入),运行OAuth流,验证连接,并可选择使用Claude Code注册MCP服务器。
授权后,凭据将存储在OS(操作系统)安全存储中:
- macOS: 钥匙扣(
security) - Linux: 特勤局通过
secret-tool - 窗户: DPAPI(数据保护API)-受保护的用户存储
设置后,令牌管理是自动的——以后不需要环境变量。
- 使用服务帐户: 使用客户端凭据流
TenantId--没有要管理的刷新令牌。租户ID在安装过程中自动获取。 - 无服务帐户(默认): 使用标准的OAuth2刷新令牌流。
3.注册为MCP服务器(可选——适用于克劳德桌面/Web)
如果您使用Claude Desktop或Claude.ai,请注册MCP服务器,以便这些环境可以访问Fortnox。Claude Code可以直接使用CLI,因此此步骤在那里是可选的。
claude mcp add fortnox -- npx noxctl serve如果你从本地克隆而不是npm运行:
claude mcp add fortnox -- node /absolute/path/to/noxctl/dist/cli.js serve4.验证连接
noxctl company info如果从源代码运行:
node dist/cli.js company info您应该看到您的公司名称、组织编号和地址。如果这行得通,你就准备好了。
配置文件(多租户)
noxctl支持单个安装中的多个Fortnox租户——如果您为多家公司记账,或者想将沙盒租户与生产分开,这很有用。每个配置文件在操作系统安全存储(macOS Keychain/Linux Secret Service/Windows DPAPI)中都有自己的OAuth凭据,按配置文件名称键入。
针对特定配置文件运行
按优先级顺序选择配置文件的三种方法(最高获胜):
--profile旗帜 --显式,按命令NOXCTL_PROFILE环境变量 --仅限于shell会话- 活动指针 —
~/.fortnox-mcp/active-profile,由设置noxctl profile use
如果这些都没有设置,noxctl将使用 default 配置文件(现有用户一直在使用的内容——不需要选择加入)。
noxctl init --profile staging # authorize a second tenant
noxctl --profile staging invoices list # one-off against staging
NOXCTL_PROFILE=staging noxctl company info # shell-scoped
noxctl profile use staging # sticky — persists to the pointer
noxctl profile current # show resolved profile + source
noxctl profile list # list known profilesMCP服务器
当Claude Desktop/Claude.ai启动时,MCP服务器会解析以下配置文件 NOXCTL_PROFILE 并在启动时绑定活动指针。通过启动时 noxctl --profile serve,CLI会转发该标志。
要并行运行多个MCP服务器(每个租户一个),请使用不同的名称和作用域环境注册它们:
claude mcp add fortnox-prod -- npx noxctl serve
claude mcp add fortnox-staging -e NOXCTL_PROFILE=staging -- npx noxctl serve非默认会话打印 [profile: ] 启动时的stderr横幅,并在每个Fortnox API错误和token-refresh失败前加上相同的标记,因此可以从单个错误行诊断错误的会话。
关闭指针语义失败
如果活动指针变得不可读或损坏,并且没有明确指示 --profile 旗帜或 NOXCTL_PROFILE 设置, noxctl serve 拒绝开始 而不是默默地倒退 default这可以防止损坏的指针将生产MCP会话路由到错误的租户。CLI doctor 和 profile use 命令是豁免的——它们仍然可以对损坏的指针运行,这样你就可以修复它。
工具
每个操作都可以作为CLI命令和MCP工具使用。CLI是主要界面;MCP服务器向AI代理公开相同的操作。所有突变——每一行都有标签 (mutation) --在TTY上提示确认并要求 --yes (CLI)或 confirm: true (MCP)管道时。看 突变安全性.
客户
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl customers list [--search ] | fortnox_list_customers | 列出/搜索客户 |
noxctl customers get | fortnox_get_customer | 获得一个客户 |
noxctl customers create --name | fortnox_create_customer | 创建客户(突变) |
noxctl customers update --input | fortnox_update_customer | 更新客户(突变) |
供应商
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl suppliers list [--search ] | fortnox_list_suppliers | 列出/搜索供应商 |
noxctl suppliers get | fortnox_get_supplier | 获得单一供应商 |
noxctl suppliers create --name | fortnox_create_supplier | 创建供应商(突变) |
noxctl suppliers update --input | fortnox_update_supplier | 更新供应商(突变) |
条款
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl articles list [--search ] | fortnox_list_articles | 列出/搜索文章 |
noxctl articles get | fortnox_get_article | 获取一篇文章 |
noxctl articles create --description | fortnox_create_article | 创建文章(突变) |
noxctl articles update --input | fortnox_update_article | 更新文章(突变) |
发票
| CLI | MCP工具 | 说明 | ||
|---|---|---|---|---|
noxctl invoices list [--filter ] [--customer ] | fortnox_list_invoices | 列出/过滤发票。过滤器: cancelled, fullypaid, unpaid, unpaidoverdue, unbooked | ||
noxctl invoices get | fortnox_get_invoice | 获取单一发票 | ||
noxctl invoices create --customer --input | fortnox_create_invoice | 创建发票(突变) | ||
noxctl invoices update --input | fortnox_update_invoice | 更新未记账的发票(突变) | ||
| `noxctl invoices send [--method email\ | print\ | einvoice] [--subject ] [--body ] [--bcc ]` | fortnox_send_invoice | 通过电子邮件(默认)、打印或电子发票(突变)发送 |
noxctl invoices bookkeep | fortnox_bookkeep_invoice | 记账发票(突变) | ||
noxctl invoices credit | fortnox_credit_invoice | 贷记发票(突变) |
发票付款(英镑)
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl invoice-payments list [--invoice ] /别名 noxctl ip list | fortnox_list_invoice_payments | 列出发票付款 |
noxctl invoice-payments get | fortnox_get_invoice_payment | 获得单一发票付款 |
noxctl invoice-payments create --invoice --amount --date | fortnox_create_invoice_payment | 根据发票登记付款(突变) |
noxctl invoice-payments bookkeep | -- | 记账发票付款(突变) |
noxctl invoice-payments delete | fortnox_delete_invoice_payment | 删除发票付款(突变) |
供应商发票(leverantörsfakturor)
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl supplier-invoices list [--filter ] [--supplier ] /别名 si list | fortnox_list_supplier_invoices | 列出/过滤供应商发票 |
noxctl supplier-invoices get | fortnox_get_supplier_invoice | 获取单一供应商发票 |
noxctl supplier-invoices create --supplier --input | fortnox_create_supplier_invoice | 创建供应商发票(突变) |
noxctl supplier-invoices bookkeep | fortnox_bookkeep_supplier_invoice | 记账供应商发票(突变) |
供应商发票付款(utbetalningar)
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl supplier-invoice-payments list [--invoice ] /别名 sip list | fortnox_list_supplier_invoice_payments | 列出供应商发票付款 |
noxctl supplier-invoice-payments get | fortnox_get_supplier_invoice_payment | 获得单一供应商发票付款 |
noxctl supplier-invoice-payments create --invoice --amount --date | fortnox_create_supplier_invoice_payment | 根据供应商发票登记付款(突变) |
noxctl supplier-invoice-payments delete | fortnox_delete_supplier_invoice_payment | 删除供应商发票付款(突变) |
优惠(offerer)
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl offers list [--filter ] [--customer ] | fortnox_list_offers | 列出/筛选报价。过滤器: cancelled, expired, ordercreated, invoicecreated |
noxctl offers get | fortnox_get_offer | 获得单一报价 |
noxctl offers create --customer --input | fortnox_create_offer | 创建报价(突变) |
noxctl offers update --input | fortnox_update_offer | 更新报价(突变) |
noxctl offers create-invoice | fortnox_create_invoice_from_offer | 转换优惠→ 发票(突变) |
noxctl offers create-order | fortnox_create_order_from_offer | 转换优惠→ 顺序(突变) |
订单(ordrar)
| CLI | 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 | 转换订单→ 发票(突变) |
簿记
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl vouchers list [--series ] [--from ] [--to ] | fortnox_list_vouchers | 列出凭证,可选择按系列和日期范围筛选 |
noxctl vouchers get | fortnox_get_voucher | 获取一张有行的凭单 |
noxctl vouchers create --input | fortnox_create_voucher | 创建带有借记/贷记行的凭证(突变) |
noxctl accounts list [--search ] | fortnox_list_accounts | 查看会计科目表,按姓名或数字搜索 |
财务报告
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl reports income [--year ] [--from ] [--to ] /别名 reports resultat | fortnox_income_statement 收益表(Income Statement) | |
noxctl reports balance [--year ] [--to ] /别名 reports balans | fortnox_balance_sheet 资产负债表(Balance Sheet) |
税
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl tax report --from --to | fortnox_tax_report | 一段时间的增值税信息摘要。在提交申请之前,与Fortnox达成和解。日期在 YYYY-MM-DD 格式 |
减税(ROT/RUT)
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl tax-reductions list [--filter ] | fortnox_list_taxreductions | 列出减税(ROT/RUT) |
noxctl tax-reductions get | fortnox_get_taxreduction | 获得一次减税 |
noxctl tax-reductions create --reference --type --document-type --customer-name --amount | fortnox_create_taxreduction | 创建ROT/RUT减税(突变) |
项目
| CLI | 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 | 更新项目(突变) |
成本中心(Cost Centers)
| CLI | 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 | 删除成本中心(突变) |
价目表和价格
| CLI | 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 | 更新价格(突变) |
公司
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl company info | fortnox_company_info | 公司名称、组织编号、地址和设置 |
效用
| CLI | MCP工具 | 说明 |
|---|---|---|
noxctl init | -- | 交互式设置向导--连接到Fortnox,存储凭据,可选择注册MCP服务器 |
noxctl doctor | fortnox_status | 验证设置:节点版本、凭据、令牌状态、API连接和作用域 |
noxctl logout | -- | 从操作系统密钥链中删除存储的凭据 |
noxctl profile use | -- | 设置活动配置文件(写入 ~/.fortnox-mcp/active-profile) |
noxctl profile current | -- | 显示当前解析的配置文件及其来源 |
noxctl profile list | -- | 列出索引中的已知配置文件 |
CLI输出
默认情况下, noxctl 用途 表格输出 交互式终端和 JSON 当管道或重定向时。覆盖 -o:
noxctl invoices list # table on terminal, JSON when piped
noxctl -o json invoices list # force JSON (JavaScript Object Notation)
noxctl -o table invoices list # force table
noxctl invoices list | jq . # auto-JSON (piped)从本地克隆而不是已安装的二进制文件运行时,请替换 noxctl 随着 node dist/cli.js.
突变安全性
修改命令在执行前需要确认。在交互式终端上,CLI会提示 [y/N]。在非交互式上下文中(管道输入,CI),传递 --yes 否则命令将安全失败。
CLI:
noxctl invoices send 1001 # prompts: "Send invoice 1001 via email. Continue? [y/N]"
noxctl invoices send 1001 --yes # skip prompt (scripting/AI)
noxctl invoices send 1001 --dry-run # preview without sending
noxctl customers update 42 --input customer.json # prompts for confirmation
noxctl vouchers create --input voucher.json --dry-run # preview payloadMCP工具:
- 突变工具需要
confirm: true - 使用
dryRun: true预览请求而不发送请求 - 原始Fortnox JSON可通过以下方式选择加入
includeRaw: true includeRaw: true与汇总的默认输出相比,可以向人工智能成绩单、日志和终端暴露更多的会计和个人数据
隐私和人工智能使用
如果您通过Claude、MCP客户端或其他AI工具使用noxctl,客户、供应商、发票和簿记数据可能会离开本地Fortnox UI上下文并进入第三方系统。
- 保持
includeRaw除非你真的需要全部有效载荷 - 查看您的AI提供商的保留、记录和处理器条款
- 确保您的GDPR设置涵盖了这种使用,包括处理器协议和任何所需的第三国转移评估
- 在测试提示、演示和示例时,更喜欢合成数据
看 隐私.md 针对特定项目的隐私说明。
税务和会计限额
noxctl可以帮助您检查Fortnox数据并提交您选择确认的操作。它不会为你做出法律判断。
- 增值税报告是一份信息摘要,而不是一份已提交的声明
- 瑞典的簿记责任仍由公司所有者或董事会承担
- 在确认或提交任何文件之前,请先审查发票、凭证和增值税总额
- 在提交给Skatteverket之前,根据Fortnox自己的妈妈支持和您的会计记录核对增值税数据
示例
自然地问克劳德——他同时用瑞典语和英语工作:
- “为客户42创建10个咨询小时的发票,价格为1200美元”
- “为客户开具发票42:10个咨询小时,1200瑞典克朗”
- “显示所有未付发票”
- “2025年第一季度的增值税是什么?”
- “Book office supplies for 1250 SEK incl VAT” / “Book office supplies for 1250 SEK incl VAT” / “Book office supplies for 1250 SEK incl VAT” / “Book office supplies for 1250 SEK incl VAT” / “Book office supplies for 1250 SEK incl VAT”
- “Skicka faktura 1001通过电子邮箱”/“通过电子邮件发送发票1001”
故障排除
“stdin不是TTY。将FORTNO_CLIENT_ID和FORTNO_CLIENT_SECRET环境变量设置为非交互式运行”
noxctl init 通常是交互式的——它会提示输入客户端ID和密码。在CI或其他非TTY环境中,它又回到了从环境变量中读取它们:
export FORTNOX_CLIENT_ID=
export FORTNOX_CLIENT_SECRET=
export FORTNOX_SERVICE_ACCOUNT=1 # optional, enables service account mode
noxctl init一旦获得授权,令牌就会存储在操作系统密钥链中。之后不需要env变量——只需要重新运行 init 非交互式。
“未通过身份验证。运行 noxctl init"
凭据丢失或未保存。重新运行安装步骤。在macOS上,检查Keychain Access是否未阻止 security 命令。在Linux上,确保 secret-tool 已安装(sudo apt install libsecret-tools).
403 Fortnox API禁用
你的应用程序缺少一个或多个作用域。错误消息指定了所需的特定范围(例如。 Missing "supplier" scope).首选 developer.fortnox.se,打开您的应用程序,并在下启用匹配权限 权限 / 权限 --查看完整的表格 设置→ 创建Fortnox应用程序。然后重新运行 noxctl init.
“令牌刷新失败”
您的刷新令牌可能已过期或被吊销。重新运行安装程序以重新进行身份验证。
端口9876已在使用中
另一个进程正在使用OAuth回调端口。请关闭它或等待之前的安装尝试完成,然后重试。
发展
npm install
npm run build # compile TypeScript
npm test # run tests
npm run test:watch # watch mode
npm run lint # ESLint with typescript-eslint
npm run format # format建筑
看 建筑.md 了解详情。
安全
- 存储在操作系统安全存储中的凭据,而不是明文存储库或主目录JSON
- 初始设置后环境变量中没有秘密
- OAuth回调绑定到环回,并使用每次运行的OAuth进行验证
state - OAuth/客户端凭据机密永远不会在工具响应中发出
- 突变行为需要明确确认或
dryRun - 默认情况下汇总MCP响应;原始Fortnox JSON是可选的
- 检索仅限于幂等请求
术语表
| 缩写 | 完整术语 |
|---|---|
| AI | 人工智能 |
| API | 应用程序编程接口 |
| BCC | 盲抄送——一个电子邮件字段,在其他收件人看不到的情况下将副本发送给某人 |
| CLI | 命令行界面——一种通过键入命令与软件交互的基于文本的方式 |
| DPAPI | 数据保护API-用于加密存储凭据的Windows功能 |
| JSON | JavaScript对象表示法——一种广泛使用的结构化数据格式 |
| MCP | 模型上下文协议——一种允许AI助手使用外部工具和数据源的标准 |
| 麻省理工学院-指的是宽松的开源软件许可证 | |
| npm | 节点包管理器——一个用于安装和管理JavaScript包的工具 |
| npx | npm附带的一个工具,用于在不全局安装的情况下运行包 |
| OAuth | 开放授权——一种标准协议,用于在不共享密码的情况下授予应用程序对帐户的有限访问权限 |
| OS | 操作系统——运行计算机的软件(例如macOS、Windows、Linux) |
| SEK | 瑞典克朗——瑞典的货币 |
| URI | 统一资源标识符——标识资源的地址(类似于web链接) |
| 增值税 | 增值税——在生产的每个阶段增加的消费税 |
免责声明
noxctl是一个独立的开源项目,不隶属于Fortnox AB,也没有得到Fortnox AB的认可或认证。
你对自己的簿记负责。 根据瑞典法律(Bokföringslagen),公司所有者或董事会对所有会计记录的正确性承担全部责任,无论使用何种工具。noxctl是一种执行指令的工具——在确认之前检查条目,尤其是在使用 --yes 或 confirm: true.
隐私说明: 当使用noxctl和人工智能助手时,客户和供应商数据可能会进入第三方人工智能系统。使用 includeRaw: false 除非需要完整的有效载荷,并确保您的使用符合GDPR、处理器协议和任何所需的传输评估。
税务说明: 增值税报告仅供参考。在向Skatteverket提交任何内容之前,请将其与Fortnox和您的会计记录进行核对。
Fortnox API访问 需要您自己的开发人员凭据和Fortnox设置。您必须遵守适用的Fortnox条款。noxctl不会重新分发任何Fortnox拥有的代码或数据。
许可证
麻省理工学院
