Add erpnext-mcp/src/tools/buying.ts

This commit is contained in:
Zac Gaetano 2026-03-31 15:33:32 -04:00
parent ad1dad03d9
commit b2777e44c4

View file

@ -0,0 +1,141 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { ERPNextClient, truncateResponse } from "../services/erpnext-client.js";
import { z } from "zod";
export function registerBuyingTools(server: McpServer, client: ERPNextClient): void {
// ─── 31. Make Purchase Order from MR ───────────────────
server.registerTool(
"erpnext_make_purchase_order_from_mr",
{
title: "Make Purchase Order from Material Request",
description: `Create a Purchase Order from a Material Request.`,
inputSchema: z.object({ source_name: z.string().describe("Material Request name") }).strict(),
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
},
async (params) => {
try {
const result = await client.callMethod(
"erpnext.stock.doctype.material_request.material_request.make_purchase_order",
{ source_name: params.source_name }
);
return { content: [{ type: "text", text: truncateResponse(JSON.stringify(result, null, 2)) }] };
} catch (error) {
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
}
}
);
// ─── 32. Make Purchase Receipt from PO ─────────────────
server.registerTool(
"erpnext_make_purchase_receipt_from_po",
{
title: "Make Purchase Receipt from Purchase Order",
description: `Create a Purchase Receipt from a submitted Purchase Order.`,
inputSchema: z.object({ source_name: z.string().describe("Purchase Order name") }).strict(),
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
},
async (params) => {
try {
const result = await client.callMethod(
"erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
{ source_name: params.source_name }
);
return { content: [{ type: "text", text: truncateResponse(JSON.stringify(result, null, 2)) }] };
} catch (error) {
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
}
}
);
// ─── 33. Make Purchase Invoice from PO ─────────────────
server.registerTool(
"erpnext_make_purchase_invoice_from_po",
{
title: "Make Purchase Invoice from Purchase Order",
description: `Create a Purchase Invoice from a submitted Purchase Order.`,
inputSchema: z.object({ source_name: z.string().describe("Purchase Order name") }).strict(),
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
},
async (params) => {
try {
const result = await client.callMethod(
"erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice",
{ source_name: params.source_name }
);
return { content: [{ type: "text", text: truncateResponse(JSON.stringify(result, null, 2)) }] };
} catch (error) {
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
}
}
);
// ─── 34. Close/Reopen Purchase Order ───────────────────
server.registerTool(
"erpnext_update_purchase_order_status",
{
title: "Close/Reopen Purchase Order",
description: `Close or reopen a Purchase Order.`,
inputSchema: z.object({
name: z.string(),
status: z.enum(["Closed", "Re-open"]),
}).strict(),
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
},
async (params) => {
try {
await client.callMethod("erpnext.buying.doctype.purchase_order.purchase_order.update_status", {
status: params.status === "Re-open" ? "Draft" : params.status,
name: params.name,
});
return { content: [{ type: "text", text: `Purchase Order ${params.name} status updated.` }] };
} catch (error) {
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
}
}
);
// ─── 35. Make Supplier Quotation from MR ───────────────
server.registerTool(
"erpnext_make_supplier_quotation_from_mr",
{
title: "Make Supplier Quotation from Material Request",
description: `Create a Supplier Quotation from a Material Request.`,
inputSchema: z.object({ source_name: z.string() }).strict(),
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
},
async (params) => {
try {
const result = await client.callMethod(
"erpnext.stock.doctype.material_request.material_request.make_supplier_quotation",
{ source_name: params.source_name }
);
return { content: [{ type: "text", text: truncateResponse(JSON.stringify(result, null, 2)) }] };
} catch (error) {
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
}
}
);
// ─── 36. Make RFQ from MR ──────────────────────────────
server.registerTool(
"erpnext_make_rfq_from_mr",
{
title: "Make Request for Quotation from Material Request",
description: `Create a Request for Quotation from a Material Request.`,
inputSchema: z.object({ source_name: z.string() }).strict(),
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
},
async (params) => {
try {
const result = await client.callMethod(
"erpnext.stock.doctype.material_request.material_request.make_request_for_quotation",
{ source_name: params.source_name }
);
return { content: [{ type: "text", text: truncateResponse(JSON.stringify(result, null, 2)) }] };
} catch (error) {
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
}
}
);
}