honeybook-mcp 0.1.7 → 0.1.9
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +171 -9
- package/dist/index.js +1 -1
- package/dist/tools/workspace_files.js +187 -7
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "HoneyBook client-portal tools for Claude Code",
|
|
10
|
-
"version": "0.1.
|
|
10
|
+
"version": "0.1.9"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "HoneyBook",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "HoneyBook client-portal MCP for Claude — view wedding-vendor contracts and invoices via MCP",
|
|
18
|
-
"version": "0.1.
|
|
18
|
+
"version": "0.1.9",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Chall"
|
|
21
21
|
},
|
package/dist/bundle.js
CHANGED
|
@@ -21406,6 +21406,149 @@ function pruneWorkspaceFile(file) {
|
|
|
21406
21406
|
}
|
|
21407
21407
|
return pruned;
|
|
21408
21408
|
}
|
|
21409
|
+
var WORKSPACE_FILE_SECTIONS = [
|
|
21410
|
+
"summary",
|
|
21411
|
+
"pricing",
|
|
21412
|
+
"agreement",
|
|
21413
|
+
"payments",
|
|
21414
|
+
"all",
|
|
21415
|
+
"raw"
|
|
21416
|
+
];
|
|
21417
|
+
function getObj(o, key) {
|
|
21418
|
+
const v = o?.[key];
|
|
21419
|
+
return v && typeof v === "object" ? v : void 0;
|
|
21420
|
+
}
|
|
21421
|
+
function getArr(o, key) {
|
|
21422
|
+
const v = o?.[key];
|
|
21423
|
+
return Array.isArray(v) ? v : [];
|
|
21424
|
+
}
|
|
21425
|
+
function getStr(o, key) {
|
|
21426
|
+
const v = o?.[key];
|
|
21427
|
+
return typeof v === "string" ? v : void 0;
|
|
21428
|
+
}
|
|
21429
|
+
function getNum(o, key) {
|
|
21430
|
+
const v = o?.[key];
|
|
21431
|
+
return typeof v === "number" ? v : void 0;
|
|
21432
|
+
}
|
|
21433
|
+
function buildSummary(file) {
|
|
21434
|
+
const vp = getObj(file, "vendor_proposal") ?? {};
|
|
21435
|
+
const payments = getArr(getObj(file, "payments_container"), "payments");
|
|
21436
|
+
const paymentsTotal = payments.reduce((s, p) => s + (getNum(p, "amount") ?? 0), 0);
|
|
21437
|
+
const paymentsPaid = payments.filter((p) => p.is_paid === true).reduce((s, p) => s + (getNum(p, "amount") ?? 0), 0);
|
|
21438
|
+
const owner = getObj(file, "owner");
|
|
21439
|
+
const company = getObj(file, "company");
|
|
21440
|
+
const event = getObj(file, "event");
|
|
21441
|
+
const agreement = getObj(file, "agreement");
|
|
21442
|
+
const packages = getArr(vp, "vendor_packages").map((p) => ({
|
|
21443
|
+
title: getStr(p, "title"),
|
|
21444
|
+
description: (getStr(p, "description") ?? "").slice(0, 400),
|
|
21445
|
+
price: getNum(p, "total_price") ?? getNum(p, "sub_total"),
|
|
21446
|
+
quantity: getNum(p, "quantity")
|
|
21447
|
+
}));
|
|
21448
|
+
const services = getArr(vp, "service_items").map((s) => ({
|
|
21449
|
+
title: getStr(s, "title"),
|
|
21450
|
+
description: (getStr(s, "description") ?? "").slice(0, 400),
|
|
21451
|
+
price: getNum(s, "total_price") ?? getNum(s, "sub_total"),
|
|
21452
|
+
quantity: getNum(s, "quantity")
|
|
21453
|
+
}));
|
|
21454
|
+
return {
|
|
21455
|
+
_id: file._id,
|
|
21456
|
+
file_title: file.file_title,
|
|
21457
|
+
file_type: file.file_type,
|
|
21458
|
+
status: file.status,
|
|
21459
|
+
status_name: file.status_name,
|
|
21460
|
+
status_type: file.status_type,
|
|
21461
|
+
sent_on: file.sent_on,
|
|
21462
|
+
created_at: file.created_at,
|
|
21463
|
+
auto_expiration: file.auto_expiration,
|
|
21464
|
+
is_file_accepted: file.is_file_accepted,
|
|
21465
|
+
is_booked_version: file.is_booked_version,
|
|
21466
|
+
is_canceled: file.is_canceled,
|
|
21467
|
+
has_pending_payment: file.has_pending_payment,
|
|
21468
|
+
currency: file.currency,
|
|
21469
|
+
workspace: {
|
|
21470
|
+
name: getStr(file, "workspace_name"),
|
|
21471
|
+
status_type: getStr(file, "workspace_status_type"),
|
|
21472
|
+
status_name: getStr(file, "workspace_status_name"),
|
|
21473
|
+
active_state: getStr(file, "workspace_active_state")
|
|
21474
|
+
},
|
|
21475
|
+
vendor: {
|
|
21476
|
+
company_name: getStr(company, "company_name"),
|
|
21477
|
+
owner_name: [getStr(owner, "first_name"), getStr(owner, "last_name")].filter(Boolean).join(" "),
|
|
21478
|
+
owner_email: getStr(owner, "email"),
|
|
21479
|
+
owner_phone: getStr(owner, "phone_number")
|
|
21480
|
+
},
|
|
21481
|
+
event: event ? {
|
|
21482
|
+
_id: event._id,
|
|
21483
|
+
date: getStr(event, "event_date"),
|
|
21484
|
+
type: getStr(event, "type"),
|
|
21485
|
+
couple_names: getStr(event, "couple_names")
|
|
21486
|
+
} : null,
|
|
21487
|
+
pricing: {
|
|
21488
|
+
sub_total: getNum(vp, "sub_total"),
|
|
21489
|
+
total_price: getNum(vp, "total_price"),
|
|
21490
|
+
discount: getNum(vp, "discount") ? { value: getNum(vp, "discount"), type: getStr(vp, "discount_type") } : null,
|
|
21491
|
+
tax: getNum(vp, "tax") ? { value: getNum(vp, "tax"), type: getStr(vp, "tax_type") } : null,
|
|
21492
|
+
svc: getNum(vp, "svc") ? { value: getNum(vp, "svc"), type: getStr(vp, "svc_type") } : null,
|
|
21493
|
+
total_tax: getNum(vp, "total_tax"),
|
|
21494
|
+
total_svc: getNum(vp, "total_svc"),
|
|
21495
|
+
packages,
|
|
21496
|
+
services
|
|
21497
|
+
},
|
|
21498
|
+
payments: {
|
|
21499
|
+
total: paymentsTotal,
|
|
21500
|
+
paid: paymentsPaid,
|
|
21501
|
+
remaining: paymentsTotal - paymentsPaid,
|
|
21502
|
+
count: payments.length,
|
|
21503
|
+
schedule: payments.map((p) => ({
|
|
21504
|
+
due_date: getStr(p, "due_date"),
|
|
21505
|
+
amount: getNum(p, "amount"),
|
|
21506
|
+
count_description: getStr(p, "count_description"),
|
|
21507
|
+
invoice: getStr(p, "invoice"),
|
|
21508
|
+
is_paid: p.is_paid === true,
|
|
21509
|
+
is_pending: p.is_pending === true,
|
|
21510
|
+
is_milestone: p.is_milestone === true
|
|
21511
|
+
}))
|
|
21512
|
+
},
|
|
21513
|
+
agreement: agreement ? {
|
|
21514
|
+
present: true,
|
|
21515
|
+
signatures: getArr(agreement, "contract_signatures").map((s) => ({
|
|
21516
|
+
signed_by: getStr(s, "signer_email") ?? getStr(s, "signer_name"),
|
|
21517
|
+
signed_at: getStr(s, "signed_at") ?? getStr(s, "signature_date"),
|
|
21518
|
+
is_vendor: s.is_vendor === true
|
|
21519
|
+
})),
|
|
21520
|
+
html_length: (getStr(agreement, "html_body") ?? "").length
|
|
21521
|
+
} : { present: false },
|
|
21522
|
+
sections_available: WORKSPACE_FILE_SECTIONS,
|
|
21523
|
+
hint: 'Call get_workspace_file again with section="pricing" (full line items + tax/svc detail), "agreement" (contract HTML + signatures), "payments" (full payment-schedule detail), "all" (pruned full response), or "raw" (full unpruned response \u2014 may exceed MCP size limit).'
|
|
21524
|
+
};
|
|
21525
|
+
}
|
|
21526
|
+
function extractPricing(file) {
|
|
21527
|
+
return {
|
|
21528
|
+
_id: file._id,
|
|
21529
|
+
file_title: file.file_title,
|
|
21530
|
+
currency: file.currency,
|
|
21531
|
+
vendor_proposal: file.vendor_proposal
|
|
21532
|
+
};
|
|
21533
|
+
}
|
|
21534
|
+
function extractAgreement(file) {
|
|
21535
|
+
return {
|
|
21536
|
+
_id: file._id,
|
|
21537
|
+
file_title: file.file_title,
|
|
21538
|
+
agreement: file.agreement
|
|
21539
|
+
};
|
|
21540
|
+
}
|
|
21541
|
+
function extractPayments(file) {
|
|
21542
|
+
return {
|
|
21543
|
+
_id: file._id,
|
|
21544
|
+
file_title: file.file_title,
|
|
21545
|
+
currency: file.currency,
|
|
21546
|
+
payment_type: file.payment_type,
|
|
21547
|
+
has_milestone_payment: file.has_milestone_payment,
|
|
21548
|
+
has_pending_payment: file.has_pending_payment,
|
|
21549
|
+
payments_container: file.payments_container
|
|
21550
|
+
};
|
|
21551
|
+
}
|
|
21409
21552
|
async function listWorkspaceFiles(args) {
|
|
21410
21553
|
const client = await getActiveClient(args.origin);
|
|
21411
21554
|
const res = await client.request(
|
|
@@ -21417,12 +21560,31 @@ async function listWorkspaceFiles(args) {
|
|
|
21417
21560
|
return { content: [{ type: "text", text: prefix + JSON.stringify(filtered, null, 2) }] };
|
|
21418
21561
|
}
|
|
21419
21562
|
async function getWorkspaceFile(args) {
|
|
21563
|
+
const section = args.section ?? "summary";
|
|
21420
21564
|
const client = await getActiveClient(args.origin);
|
|
21421
|
-
const
|
|
21422
|
-
|
|
21423
|
-
|
|
21424
|
-
|
|
21425
|
-
|
|
21565
|
+
const raw = await client.request("GET", `/api/v2/workspace_files/${args.file_id}`);
|
|
21566
|
+
let body;
|
|
21567
|
+
switch (section) {
|
|
21568
|
+
case "raw":
|
|
21569
|
+
body = raw;
|
|
21570
|
+
break;
|
|
21571
|
+
case "all":
|
|
21572
|
+
body = pruneWorkspaceFile(raw);
|
|
21573
|
+
break;
|
|
21574
|
+
case "pricing":
|
|
21575
|
+
body = extractPricing(raw);
|
|
21576
|
+
break;
|
|
21577
|
+
case "agreement":
|
|
21578
|
+
body = extractAgreement(raw);
|
|
21579
|
+
break;
|
|
21580
|
+
case "payments":
|
|
21581
|
+
body = extractPayments(raw);
|
|
21582
|
+
break;
|
|
21583
|
+
case "summary":
|
|
21584
|
+
default:
|
|
21585
|
+
body = buildSummary(raw);
|
|
21586
|
+
break;
|
|
21587
|
+
}
|
|
21426
21588
|
return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
|
|
21427
21589
|
}
|
|
21428
21590
|
function registerWorkspaceFileTools(server2) {
|
|
@@ -21443,14 +21605,14 @@ function registerWorkspaceFileTools(server2) {
|
|
|
21443
21605
|
server2.registerTool(
|
|
21444
21606
|
"get_workspace_file",
|
|
21445
21607
|
{
|
|
21446
|
-
description:
|
|
21608
|
+
description: 'Get detail for one workspace file. Returns a compact summary by default (metadata, vendor, event, pricing totals, payment schedule, agreement presence). Use `section` to drill into a specific part of the file: "pricing" for full line items + tax/svc detail, "agreement" for contract HTML + signatures, "payments" for full payment-schedule detail, "all" for the pruned full response, or "raw" for the entirely-unpruned response (may exceed MCP size limits on proposal-class files).',
|
|
21447
21609
|
inputSchema: {
|
|
21448
21610
|
file_id: external_exports.string().describe("The file _id from list_workspace_files."),
|
|
21449
21611
|
origin: external_exports.string().optional().describe(
|
|
21450
21612
|
"Portal origin (e.g. https://<vendor>.hbportal.co). Optional when only one session is active."
|
|
21451
21613
|
),
|
|
21452
|
-
|
|
21453
|
-
|
|
21614
|
+
section: external_exports.enum(WORKSPACE_FILE_SECTIONS).optional().describe(
|
|
21615
|
+
'Which view to return. Default "summary" (~5-15 kB). Others return focused sections of the raw response.'
|
|
21454
21616
|
)
|
|
21455
21617
|
},
|
|
21456
21618
|
annotations: { readOnlyHint: true }
|
|
@@ -21632,7 +21794,7 @@ try {
|
|
|
21632
21794
|
}
|
|
21633
21795
|
var server = new McpServer({
|
|
21634
21796
|
name: "honeybook-mcp",
|
|
21635
|
-
version: "0.1.
|
|
21797
|
+
version: "0.1.9"
|
|
21636
21798
|
});
|
|
21637
21799
|
registerSessionTools(server);
|
|
21638
21800
|
registerWorkspaceFileTools(server);
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { registerContractTools } from './tools/contracts.js';
|
|
|
18
18
|
import { registerInvoiceTools } from './tools/invoices.js';
|
|
19
19
|
const server = new McpServer({
|
|
20
20
|
name: 'honeybook-mcp',
|
|
21
|
-
version: '0.1.
|
|
21
|
+
version: '0.1.9',
|
|
22
22
|
});
|
|
23
23
|
registerSessionTools(server);
|
|
24
24
|
registerWorkspaceFileTools(server);
|
|
@@ -4,7 +4,7 @@ import { FILE_TYPES } from '../types.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Vendor-side sub-fields on `company` that a CLIENT never needs but that
|
|
6
6
|
* balloon the response (observed: `vendor_emails` alone was ~1.3 MB on a
|
|
7
|
-
* single real proposal). Stripped by default;
|
|
7
|
+
* single real proposal). Stripped by default; section='raw' keeps them.
|
|
8
8
|
*/
|
|
9
9
|
const HEAVY_COMPANY_FIELDS = [
|
|
10
10
|
'vendor_emails',
|
|
@@ -34,6 +34,164 @@ export function pruneWorkspaceFile(file) {
|
|
|
34
34
|
}
|
|
35
35
|
return pruned;
|
|
36
36
|
}
|
|
37
|
+
export const WORKSPACE_FILE_SECTIONS = [
|
|
38
|
+
'summary',
|
|
39
|
+
'pricing',
|
|
40
|
+
'agreement',
|
|
41
|
+
'payments',
|
|
42
|
+
'all',
|
|
43
|
+
'raw',
|
|
44
|
+
];
|
|
45
|
+
// Short helpers
|
|
46
|
+
function getObj(o, key) {
|
|
47
|
+
const v = o?.[key];
|
|
48
|
+
return v && typeof v === 'object' ? v : undefined;
|
|
49
|
+
}
|
|
50
|
+
function getArr(o, key) {
|
|
51
|
+
const v = o?.[key];
|
|
52
|
+
return Array.isArray(v) ? v : [];
|
|
53
|
+
}
|
|
54
|
+
function getStr(o, key) {
|
|
55
|
+
const v = o?.[key];
|
|
56
|
+
return typeof v === 'string' ? v : undefined;
|
|
57
|
+
}
|
|
58
|
+
function getNum(o, key) {
|
|
59
|
+
const v = o?.[key];
|
|
60
|
+
return typeof v === 'number' ? v : undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Compact summary: ~5-15 kB even for proposal-class files. Contains everything
|
|
64
|
+
* a caller typically needs up front (identity, status, vendor, event, totals,
|
|
65
|
+
* payment schedule, package titles + pricing). For the contract text or the
|
|
66
|
+
* full vendor_proposal, call again with section='agreement' or 'pricing'.
|
|
67
|
+
*/
|
|
68
|
+
export function buildSummary(file) {
|
|
69
|
+
const vp = getObj(file, 'vendor_proposal') ?? {};
|
|
70
|
+
const payments = getArr(getObj(file, 'payments_container'), 'payments');
|
|
71
|
+
const paymentsTotal = payments.reduce((s, p) => s + (getNum(p, 'amount') ?? 0), 0);
|
|
72
|
+
const paymentsPaid = payments
|
|
73
|
+
.filter((p) => p.is_paid === true)
|
|
74
|
+
.reduce((s, p) => s + (getNum(p, 'amount') ?? 0), 0);
|
|
75
|
+
const owner = getObj(file, 'owner');
|
|
76
|
+
const company = getObj(file, 'company');
|
|
77
|
+
const event = getObj(file, 'event');
|
|
78
|
+
const agreement = getObj(file, 'agreement');
|
|
79
|
+
const packages = getArr(vp, 'vendor_packages').map((p) => ({
|
|
80
|
+
title: getStr(p, 'title'),
|
|
81
|
+
description: (getStr(p, 'description') ?? '').slice(0, 400),
|
|
82
|
+
price: getNum(p, 'total_price') ?? getNum(p, 'sub_total'),
|
|
83
|
+
quantity: getNum(p, 'quantity'),
|
|
84
|
+
}));
|
|
85
|
+
const services = getArr(vp, 'service_items').map((s) => ({
|
|
86
|
+
title: getStr(s, 'title'),
|
|
87
|
+
description: (getStr(s, 'description') ?? '').slice(0, 400),
|
|
88
|
+
price: getNum(s, 'total_price') ?? getNum(s, 'sub_total'),
|
|
89
|
+
quantity: getNum(s, 'quantity'),
|
|
90
|
+
}));
|
|
91
|
+
return {
|
|
92
|
+
_id: file._id,
|
|
93
|
+
file_title: file.file_title,
|
|
94
|
+
file_type: file.file_type,
|
|
95
|
+
status: file.status,
|
|
96
|
+
status_name: file.status_name,
|
|
97
|
+
status_type: file.status_type,
|
|
98
|
+
sent_on: file.sent_on,
|
|
99
|
+
created_at: file.created_at,
|
|
100
|
+
auto_expiration: file.auto_expiration,
|
|
101
|
+
is_file_accepted: file.is_file_accepted,
|
|
102
|
+
is_booked_version: file.is_booked_version,
|
|
103
|
+
is_canceled: file.is_canceled,
|
|
104
|
+
has_pending_payment: file.has_pending_payment,
|
|
105
|
+
currency: file.currency,
|
|
106
|
+
workspace: {
|
|
107
|
+
name: getStr(file, 'workspace_name'),
|
|
108
|
+
status_type: getStr(file, 'workspace_status_type'),
|
|
109
|
+
status_name: getStr(file, 'workspace_status_name'),
|
|
110
|
+
active_state: getStr(file, 'workspace_active_state'),
|
|
111
|
+
},
|
|
112
|
+
vendor: {
|
|
113
|
+
company_name: getStr(company, 'company_name'),
|
|
114
|
+
owner_name: [getStr(owner, 'first_name'), getStr(owner, 'last_name')].filter(Boolean).join(' '),
|
|
115
|
+
owner_email: getStr(owner, 'email'),
|
|
116
|
+
owner_phone: getStr(owner, 'phone_number'),
|
|
117
|
+
},
|
|
118
|
+
event: event
|
|
119
|
+
? {
|
|
120
|
+
_id: event._id,
|
|
121
|
+
date: getStr(event, 'event_date'),
|
|
122
|
+
type: getStr(event, 'type'),
|
|
123
|
+
couple_names: getStr(event, 'couple_names'),
|
|
124
|
+
}
|
|
125
|
+
: null,
|
|
126
|
+
pricing: {
|
|
127
|
+
sub_total: getNum(vp, 'sub_total'),
|
|
128
|
+
total_price: getNum(vp, 'total_price'),
|
|
129
|
+
discount: getNum(vp, 'discount')
|
|
130
|
+
? { value: getNum(vp, 'discount'), type: getStr(vp, 'discount_type') }
|
|
131
|
+
: null,
|
|
132
|
+
tax: getNum(vp, 'tax') ? { value: getNum(vp, 'tax'), type: getStr(vp, 'tax_type') } : null,
|
|
133
|
+
svc: getNum(vp, 'svc') ? { value: getNum(vp, 'svc'), type: getStr(vp, 'svc_type') } : null,
|
|
134
|
+
total_tax: getNum(vp, 'total_tax'),
|
|
135
|
+
total_svc: getNum(vp, 'total_svc'),
|
|
136
|
+
packages,
|
|
137
|
+
services,
|
|
138
|
+
},
|
|
139
|
+
payments: {
|
|
140
|
+
total: paymentsTotal,
|
|
141
|
+
paid: paymentsPaid,
|
|
142
|
+
remaining: paymentsTotal - paymentsPaid,
|
|
143
|
+
count: payments.length,
|
|
144
|
+
schedule: payments.map((p) => ({
|
|
145
|
+
due_date: getStr(p, 'due_date'),
|
|
146
|
+
amount: getNum(p, 'amount'),
|
|
147
|
+
count_description: getStr(p, 'count_description'),
|
|
148
|
+
invoice: getStr(p, 'invoice'),
|
|
149
|
+
is_paid: p.is_paid === true,
|
|
150
|
+
is_pending: p.is_pending === true,
|
|
151
|
+
is_milestone: p.is_milestone === true,
|
|
152
|
+
})),
|
|
153
|
+
},
|
|
154
|
+
agreement: agreement
|
|
155
|
+
? {
|
|
156
|
+
present: true,
|
|
157
|
+
signatures: getArr(agreement, 'contract_signatures').map((s) => ({
|
|
158
|
+
signed_by: getStr(s, 'signer_email') ?? getStr(s, 'signer_name'),
|
|
159
|
+
signed_at: getStr(s, 'signed_at') ?? getStr(s, 'signature_date'),
|
|
160
|
+
is_vendor: s.is_vendor === true,
|
|
161
|
+
})),
|
|
162
|
+
html_length: (getStr(agreement, 'html_body') ?? '').length,
|
|
163
|
+
}
|
|
164
|
+
: { present: false },
|
|
165
|
+
sections_available: WORKSPACE_FILE_SECTIONS,
|
|
166
|
+
hint: 'Call get_workspace_file again with section="pricing" (full line items + tax/svc detail), "agreement" (contract HTML + signatures), "payments" (full payment-schedule detail), "all" (pruned full response), or "raw" (full unpruned response — may exceed MCP size limit).',
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function extractPricing(file) {
|
|
170
|
+
return {
|
|
171
|
+
_id: file._id,
|
|
172
|
+
file_title: file.file_title,
|
|
173
|
+
currency: file.currency,
|
|
174
|
+
vendor_proposal: file.vendor_proposal,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function extractAgreement(file) {
|
|
178
|
+
return {
|
|
179
|
+
_id: file._id,
|
|
180
|
+
file_title: file.file_title,
|
|
181
|
+
agreement: file.agreement,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function extractPayments(file) {
|
|
185
|
+
return {
|
|
186
|
+
_id: file._id,
|
|
187
|
+
file_title: file.file_title,
|
|
188
|
+
currency: file.currency,
|
|
189
|
+
payment_type: file.payment_type,
|
|
190
|
+
has_milestone_payment: file.has_milestone_payment,
|
|
191
|
+
has_pending_payment: file.has_pending_payment,
|
|
192
|
+
payments_container: file.payments_container,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
37
195
|
export async function listWorkspaceFiles(args) {
|
|
38
196
|
const client = await getActiveClient(args.origin);
|
|
39
197
|
const res = await client.request('GET', `/api/v2/users/${client.scope.userId}/workspace_files`);
|
|
@@ -46,9 +204,31 @@ export async function listWorkspaceFiles(args) {
|
|
|
46
204
|
return { content: [{ type: 'text', text: prefix + JSON.stringify(filtered, null, 2) }] };
|
|
47
205
|
}
|
|
48
206
|
export async function getWorkspaceFile(args) {
|
|
207
|
+
const section = args.section ?? 'summary';
|
|
49
208
|
const client = await getActiveClient(args.origin);
|
|
50
|
-
const
|
|
51
|
-
|
|
209
|
+
const raw = await client.request('GET', `/api/v2/workspace_files/${args.file_id}`);
|
|
210
|
+
let body;
|
|
211
|
+
switch (section) {
|
|
212
|
+
case 'raw':
|
|
213
|
+
body = raw;
|
|
214
|
+
break;
|
|
215
|
+
case 'all':
|
|
216
|
+
body = pruneWorkspaceFile(raw);
|
|
217
|
+
break;
|
|
218
|
+
case 'pricing':
|
|
219
|
+
body = extractPricing(raw);
|
|
220
|
+
break;
|
|
221
|
+
case 'agreement':
|
|
222
|
+
body = extractAgreement(raw);
|
|
223
|
+
break;
|
|
224
|
+
case 'payments':
|
|
225
|
+
body = extractPayments(raw);
|
|
226
|
+
break;
|
|
227
|
+
case 'summary':
|
|
228
|
+
default:
|
|
229
|
+
body = buildSummary(raw);
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
52
232
|
return { content: [{ type: 'text', text: JSON.stringify(body, null, 2) }] };
|
|
53
233
|
}
|
|
54
234
|
export function registerWorkspaceFileTools(server) {
|
|
@@ -67,17 +247,17 @@ export function registerWorkspaceFileTools(server) {
|
|
|
67
247
|
annotations: { readOnlyHint: true },
|
|
68
248
|
}, listWorkspaceFiles);
|
|
69
249
|
server.registerTool('get_workspace_file', {
|
|
70
|
-
description: 'Get
|
|
250
|
+
description: 'Get detail for one workspace file. Returns a compact summary by default (metadata, vendor, event, pricing totals, payment schedule, agreement presence). Use `section` to drill into a specific part of the file: "pricing" for full line items + tax/svc detail, "agreement" for contract HTML + signatures, "payments" for full payment-schedule detail, "all" for the pruned full response, or "raw" for the entirely-unpruned response (may exceed MCP size limits on proposal-class files).',
|
|
71
251
|
inputSchema: {
|
|
72
252
|
file_id: z.string().describe('The file _id from list_workspace_files.'),
|
|
73
253
|
origin: z
|
|
74
254
|
.string()
|
|
75
255
|
.optional()
|
|
76
256
|
.describe('Portal origin (e.g. https://<vendor>.hbportal.co). Optional when only one session is active.'),
|
|
77
|
-
|
|
78
|
-
.
|
|
257
|
+
section: z
|
|
258
|
+
.enum(WORKSPACE_FILE_SECTIONS)
|
|
79
259
|
.optional()
|
|
80
|
-
.describe('
|
|
260
|
+
.describe('Which view to return. Default "summary" (~5-15 kB). Others return focused sections of the raw response.'),
|
|
81
261
|
},
|
|
82
262
|
annotations: { readOnlyHint: true },
|
|
83
263
|
}, getWorkspaceFile);
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/honeybook-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.9",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "honeybook-mcp",
|
|
14
|
-
"version": "0.1.
|
|
14
|
+
"version": "0.1.9",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|