Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 2x 10x 3x 3x 2x 3x 1x 1x 1x 1x 10x 2x 2x 1x 1x 10x | import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import * as z from "zod/v4";
import type { BolClient } from "../bol-client.js";
import { toTextResult, toErrorResult } from "../tool-result.js";
export const registerInvoiceTools = (server: McpServer, client: BolClient): void => {
server.registerTool(
"list_invoices",
{
title: "List Invoices",
description:
"List invoices from bol.com. Optionally filter by date range using period start and end dates (format: YYYY-MM-DD). " +
"The date range must not exceed 31 days.",
annotations: { readOnlyHint: true, openWorldHint: true },
inputSchema: z.object({
periodStartDate: z
.string()
.optional()
.describe("Start date for the invoice period (YYYY-MM-DD)."),
periodEndDate: z
.string()
.optional()
.describe("End date for the invoice period (YYYY-MM-DD)."),
}),
},
async ({ periodStartDate, periodEndDate }) => {
try {
const response = await client.getInvoices(periodStartDate, periodEndDate);
const invoices = response.invoiceListItems ?? [];
if (invoices.length === 0) {
return toTextResult("No invoices found for the specified period.");
}
return toTextResult(
[
`Invoices: ${invoices.length} results`,
response.period ? `Period: ${response.period}` : null,
...invoices.map((inv) =>
[
` - Invoice ${inv.invoiceId}`,
inv.invoiceType ? ` Type: ${inv.invoiceType}` : null,
inv.issueDate ? ` Issued: ${inv.issueDate}` : null,
inv.invoicePeriod
? ` Period: ${inv.invoicePeriod.startDate} to ${inv.invoicePeriod.endDate}`
: null,
inv.legalMonetaryTotal?.payableAmount !== undefined
? ` Payable: ${inv.legalMonetaryTotal.payableAmount}`
: null,
]
.filter(Boolean)
.join("\n"),
),
]
.filter(Boolean)
.join("\n"),
{ invoices } as Record<string, unknown>,
);
} catch (error) {
return toErrorResult(error);
}
},
);
server.registerTool(
"get_invoice",
{
title: "Get Invoice Details",
description: "Get detailed information about a specific invoice.",
annotations: { readOnlyHint: true, openWorldHint: true },
inputSchema: z.object({
invoiceId: z.string().min(1).describe("The bol.com invoice ID."),
}),
},
async ({ invoiceId }) => {
try {
const invoice = await client.getInvoice(invoiceId);
return toTextResult(
`Invoice ${invoiceId} details retrieved.`,
invoice as Record<string, unknown>,
);
} catch (error) {
return toErrorResult(error);
}
},
);
server.registerTool(
"get_invoice_specification",
{
title: "Get Invoice Specification",
description:
"Get an invoice specification with a paginated list of its transactions. " +
"The specification contains detailed line items for the invoice.",
annotations: { readOnlyHint: true, openWorldHint: true },
inputSchema: z.object({
invoiceId: z.string().min(1).describe("The bol.com invoice ID."),
page: z.number().int().min(1).optional().describe("Page number (max 25,000 lines per page)."),
}),
},
async ({ invoiceId, page }) => {
try {
const specification = await client.getInvoiceSpecification(invoiceId, page);
return toTextResult(
`Invoice specification for ${invoiceId} retrieved.`,
specification as Record<string, unknown>,
);
} catch (error) {
return toErrorResult(error);
}
},
);
};
|