beeswax-mcp 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -1
- package/dist/client.js +7 -0
- package/dist/index.js +3 -1
- package/dist/tools.js +22 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,12 +66,31 @@ if the agent should be able to use the matching write tools.
|
|
|
66
66
|
|
|
67
67
|
To build quotes you need `quotes:write` plus the three lookups a quote is
|
|
68
68
|
assembled from: `companies:read` (the client), `projects:read` (the project) and
|
|
69
|
-
`transaction_accounts:read` (the chart of accounts each line bills to
|
|
69
|
+
`transaction_accounts:read` (the chart of accounts each line bills to — the same
|
|
70
|
+
scope also covers the account's tax codes).
|
|
70
71
|
|
|
71
72
|
**Keep the token secret.** It sits in plain text in your client's config file, and
|
|
72
73
|
anyone who can read that file can read your account data. Revoke tokens you no
|
|
73
74
|
longer use from the same settings page.
|
|
74
75
|
|
|
76
|
+
## Multiple accounts
|
|
77
|
+
|
|
78
|
+
A token is bound to one account, so you connect several accounts by registering **one
|
|
79
|
+
server entry per account**, each with its own token and a distinct name
|
|
80
|
+
(`beeswax-acme`, `beeswax-steamuk`, …). Tools are namespaced by server name, so the
|
|
81
|
+
agent picks the account by picking the tool.
|
|
82
|
+
|
|
83
|
+
In Claude Desktop the one-click `.mcpb` extension and manual
|
|
84
|
+
`claude_desktop_config.json` entries can be enabled side by side. Two things catch
|
|
85
|
+
people out. A freshly installed extension is **disabled** until you flip the toggle at
|
|
86
|
+
the top of its settings — saving the token does not enable it, and while it is
|
|
87
|
+
disabled it exposes no tools at all. And the config file is read only at launch, so
|
|
88
|
+
adding an entry or changing a token in one needs a **full restart** of the app; a
|
|
89
|
+
Cowork or cloud session already linked to your computer needs that restart *and* a
|
|
90
|
+
re-link before it sees the change. The Connectors screen, the naming trade-offs and
|
|
91
|
+
the Cowork details are in the setup guide:
|
|
92
|
+
<https://www.beeswaxapp.com/support/mcp-setup#connecting-more-than-one-account>
|
|
93
|
+
|
|
75
94
|
## Configuration
|
|
76
95
|
|
|
77
96
|
| Environment variable | Required | Default |
|
|
@@ -106,6 +125,7 @@ reports the same on demand.
|
|
|
106
125
|
| `list_milestones`, `get_milestone` | `/milestones` |
|
|
107
126
|
| `list_projects`, `get_project` | `/active_account/projects` |
|
|
108
127
|
| `list_transaction_accounts` | `/active_account/transaction_accounts` |
|
|
128
|
+
| `list_taxes` | `/active_account/taxes` |
|
|
109
129
|
| `list_companies` | `/active_account/companies` |
|
|
110
130
|
| `list_task_files`, `list_task_file_versions` | `/tasks/:id/files` (+ per-file version history) |
|
|
111
131
|
| `list_project_documents`, `get_project_document`, `create_project_document` (write), `update_project_document` (write), `list_project_document_versions`, `get_project_document_version`, `restore_project_document_version` (write) | `/project_documents` (+ per-document version history) |
|
|
@@ -127,6 +147,14 @@ reports the same on demand.
|
|
|
127
147
|
fetches. `outstanding: true` is the looser "not paid/draft, any due date" set.
|
|
128
148
|
- **Dates.** `from` / `to` accept ISO (`2026-01-01`) or loose strings
|
|
129
149
|
(`Jan 1 2026`); they are normalized to `YYYY-MM-DD` before being sent.
|
|
150
|
+
- **Tax codes.** `list_taxes` is the lookup a product's `sell_tax_id` /
|
|
151
|
+
`buy_tax_id` needs. Read `sides` rather than `tax_type` to decide whether a
|
|
152
|
+
code can be used on a document: an account that is not registered for GST/VAT
|
|
153
|
+
still carries usable zero-rated codes, and those are stored as `tax_type`
|
|
154
|
+
`"none"` rather than income or expense. `side: "sell"` returns what a sale
|
|
155
|
+
(invoice or quote) offers, `"buy"` what an expense offers, `"payroll"` the
|
|
156
|
+
withholding codes. `default` marks the code Beeswax reaches for on its own.
|
|
157
|
+
Needs `transaction_accounts:read`.
|
|
130
158
|
- **Products & services.** Beeswax stores the catalogue as *transaction
|
|
131
159
|
templates*. `kind` is the **buy/sell mode**, not a product-vs-service label:
|
|
132
160
|
`"sell"` offers the item on invoices and quotes, `"buy"` on expenses,
|
package/dist/client.js
CHANGED
|
@@ -120,6 +120,13 @@ export class BeeswaxClient {
|
|
|
120
120
|
const message = parsed && typeof parsed === "object" && parsed.error ? parsed.error : res.statusText;
|
|
121
121
|
throw new Error(`Beeswax API ${res.status} on ${method} ${path}: ${message}`);
|
|
122
122
|
}
|
|
123
|
+
// Every API destroy answers `head :no_content` (204, empty body). Returning
|
|
124
|
+
// `undefined` here made index.ts JSON.stringify to a non-string, which the
|
|
125
|
+
// MCP SDK rejected — so every successful delete surfaced as "Tool execution
|
|
126
|
+
// failed" after the record was already gone. Always hand back an object.
|
|
127
|
+
if (parsed === undefined) {
|
|
128
|
+
return { ok: true, status: res.status, method, path };
|
|
129
|
+
}
|
|
123
130
|
return parsed;
|
|
124
131
|
}
|
|
125
132
|
}
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
34
34
|
}
|
|
35
35
|
try {
|
|
36
36
|
const result = await tool.handler(client, request.params.arguments ?? {});
|
|
37
|
-
|
|
37
|
+
// JSON.stringify(undefined) is undefined, not a string — a text-less
|
|
38
|
+
// content block fails the SDK's result schema and reads as a failed call.
|
|
39
|
+
let text = JSON.stringify(result ?? { ok: true }, null, 2) ?? "{}";
|
|
38
40
|
const update = client.updateAvailable;
|
|
39
41
|
if (update && !updateNoticeShown && request.params.name !== "check_beeswax_connection") {
|
|
40
42
|
updateNoticeShown = true;
|
package/dist/tools.js
CHANGED
|
@@ -473,8 +473,8 @@ export const TOOLS = [
|
|
|
473
473
|
},
|
|
474
474
|
sell_amount: { type: "number", description: "Sell price per unit. Defaults to 0 — pass it." },
|
|
475
475
|
buy_amount: { type: "number", description: "Buy price per unit. Defaults to 0." },
|
|
476
|
-
sell_tax_id: { type: "integer", description: "Tax code applied when the item is sold." },
|
|
477
|
-
buy_tax_id: { type: "integer", description: "Tax code applied when the item is bought." },
|
|
476
|
+
sell_tax_id: { type: "integer", description: "Tax code applied when the item is sold — resolve it with list_taxes (side 'sell')." },
|
|
477
|
+
buy_tax_id: { type: "integer", description: "Tax code applied when the item is bought — resolve it with list_taxes (side 'buy')." },
|
|
478
478
|
description: { type: "string", description: "Longer description shown on documents." },
|
|
479
479
|
item_category_id: { type: "integer", description: "Category by id instead of by name. Takes precedence over item_category." },
|
|
480
480
|
active: { type: "boolean", description: "Defaults to true. false files it as archived." },
|
|
@@ -526,8 +526,8 @@ export const TOOLS = [
|
|
|
526
526
|
buy_transaction_account_id: { type: "integer", description: "Expense account the item is bought to." },
|
|
527
527
|
sell_amount: { type: "number" },
|
|
528
528
|
buy_amount: { type: "number" },
|
|
529
|
-
sell_tax_id: { type: "integer" },
|
|
530
|
-
buy_tax_id: { type: "integer" },
|
|
529
|
+
sell_tax_id: { type: "integer", description: "Tax code applied when the item is sold — see list_taxes." },
|
|
530
|
+
buy_tax_id: { type: "integer", description: "Tax code applied when the item is bought — see list_taxes." },
|
|
531
531
|
description: { type: "string" },
|
|
532
532
|
active: { type: "boolean", description: "false archives the item — it stays on existing documents but is no longer offered." },
|
|
533
533
|
physical_resource: { type: "boolean" },
|
|
@@ -926,6 +926,24 @@ export const TOOLS = [
|
|
|
926
926
|
bank: args.bank,
|
|
927
927
|
}),
|
|
928
928
|
},
|
|
929
|
+
{
|
|
930
|
+
name: "list_taxes",
|
|
931
|
+
description: "List the account's tax codes — the ids `sell_tax_id` / `buy_tax_id` on a product, and a document line's tax, have to point at. " +
|
|
932
|
+
"Read `sides` rather than `tax_type` to decide whether a code can be used: 'sell' means invoices and quotes, 'buy' means expenses, and a zero-rated 'no tax' code often appears on both. " +
|
|
933
|
+
"An account that is not registered for GST/VAT still has usable codes here — they are the zero-percent ones. `default` marks the code Beeswax applies when nothing else is chosen. " +
|
|
934
|
+
"Requires a token with transaction_accounts:read.",
|
|
935
|
+
inputSchema: {
|
|
936
|
+
type: "object",
|
|
937
|
+
properties: {
|
|
938
|
+
side: {
|
|
939
|
+
type: "string",
|
|
940
|
+
enum: ["sell", "buy", "payroll"],
|
|
941
|
+
description: "Return only the codes offered on this side: 'sell' = invoices and quotes, 'buy' = expenses, 'payroll' = payroll withholding codes.",
|
|
942
|
+
},
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
handler: (client, args) => client.getList("/active_account/taxes", "taxes", { side: args.side }),
|
|
946
|
+
},
|
|
929
947
|
{
|
|
930
948
|
name: "list_companies",
|
|
931
949
|
description: "List the account's clients and suppliers. Use this to resolve a client name to the company_id create_quote needs. " +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeswax-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Official MCP server for Beeswax (beeswaxapp.com) — query invoices, quotes, expenses, payments, journals, time entries, projects, products & services and tax returns from Claude and other MCP clients, and build quotes priced from your catalogue.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.beeswaxapp.com/support/mcp-setup",
|