Add erpnext-mcp/src/tools/domains.ts
This commit is contained in:
parent
1b069f63c9
commit
56f64d201f
1 changed files with 533 additions and 0 deletions
533
erpnext-mcp/src/tools/domains.ts
Normal file
533
erpnext-mcp/src/tools/domains.ts
Normal file
|
|
@ -0,0 +1,533 @@
|
||||||
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||||
|
import { ERPNextClient, truncateResponse } from "../services/erpnext-client.js";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export function registerManufacturingTools(server: McpServer, client: ERPNextClient): void {
|
||||||
|
|
||||||
|
// ─── 51. Get Work Order Details ────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_work_order_details",
|
||||||
|
{
|
||||||
|
title: "Get Work Order Details for Stock Entry",
|
||||||
|
description: `Get work order details needed to create a stock entry (manufacture).`,
|
||||||
|
inputSchema: z.object({ work_order: z.string(), company: z.string() }).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.stock.doctype.stock_entry.stock_entry.get_work_order_details",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 52. Make Work Order from SO ───────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_make_work_order_from_so",
|
||||||
|
{
|
||||||
|
title: "Create Work Orders from Sales Order",
|
||||||
|
description: `Create Work Orders for items in a Sales Order that have BOMs.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
sales_order: z.string(),
|
||||||
|
items: z.array(z.object({
|
||||||
|
item_code: z.string(),
|
||||||
|
bom: z.string().optional(),
|
||||||
|
warehouse: z.string().optional(),
|
||||||
|
qty: z.number().optional(),
|
||||||
|
})).optional(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.selling.doctype.sales_order.sales_order.make_work_orders",
|
||||||
|
{ items: JSON.stringify(params.items ?? []), sales_order: params.sales_order }
|
||||||
|
);
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 53. Get Default BOM ───────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_default_bom",
|
||||||
|
{
|
||||||
|
title: "Get Default BOM for Item",
|
||||||
|
description: `Get the default Bill of Materials for an item.`,
|
||||||
|
inputSchema: z.object({ item_code: z.string() }).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod("erpnext.stock.get_item_details.get_default_bom", params);
|
||||||
|
return { content: [{ type: "text", text: `Default BOM for ${params.item_code}: ${result}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerHRTools(server: McpServer, client: ERPNextClient): void {
|
||||||
|
|
||||||
|
// ─── 54. Get Employee Org Chart ────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_org_chart",
|
||||||
|
{
|
||||||
|
title: "Get Organization Chart",
|
||||||
|
description: `Get organizational hierarchy chart data.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
company: z.string(),
|
||||||
|
method: z.string().default("erpnext.utilities.hierarchy_chart.get_all_nodes"),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(params.method, { company: params.company });
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 55. Create Employee ───────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_create_employee",
|
||||||
|
{
|
||||||
|
title: "Create Employee",
|
||||||
|
description: `Create a new Employee record.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
first_name: z.string(),
|
||||||
|
last_name: z.string().optional(),
|
||||||
|
company: z.string(),
|
||||||
|
gender: z.string().optional(),
|
||||||
|
date_of_birth: z.string().optional(),
|
||||||
|
date_of_joining: z.string().optional(),
|
||||||
|
designation: z.string().optional(),
|
||||||
|
department: z.string().optional(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const doc = await client.createDocument("Employee", params);
|
||||||
|
return { content: [{ type: "text", text: `Created Employee: ${doc.name} (${params.first_name} ${params.last_name || ""})` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 56. Create User from Employee ─────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_create_user_from_employee",
|
||||||
|
{
|
||||||
|
title: "Create User from Employee",
|
||||||
|
description: `Create a system user account from an Employee record.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
employee: z.string(),
|
||||||
|
user: z.string().optional(),
|
||||||
|
email: z.string().optional(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod("erpnext.setup.doctype.employee.employee.create_user", params);
|
||||||
|
return { content: [{ type: "text", text: `User created: ${JSON.stringify(result)}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 57. Get Department Tree ───────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_department_tree",
|
||||||
|
{
|
||||||
|
title: "Get Department Tree",
|
||||||
|
description: `Get department hierarchy tree.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
parent: z.string().optional(),
|
||||||
|
company: z.string().optional(),
|
||||||
|
is_root: z.boolean().default(false),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.setup.doctype.department.department.get_children",
|
||||||
|
{ doctype: "Department", ...params }
|
||||||
|
);
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerCRMTools(server: McpServer, client: ERPNextClient): void {
|
||||||
|
|
||||||
|
// ─── 58. Create Lead ───────────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_create_lead",
|
||||||
|
{
|
||||||
|
title: "Create Lead",
|
||||||
|
description: `Create a new Lead record.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
lead_name: z.string().optional(),
|
||||||
|
first_name: z.string().optional(),
|
||||||
|
last_name: z.string().optional(),
|
||||||
|
company_name: z.string().optional(),
|
||||||
|
email_id: z.string().optional(),
|
||||||
|
mobile_no: z.string().optional(),
|
||||||
|
source: z.string().optional(),
|
||||||
|
territory: z.string().optional(),
|
||||||
|
status: z.string().optional(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const doc = await client.createDocument("Lead", params);
|
||||||
|
return { content: [{ type: "text", text: `Created Lead: ${doc.name}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 59. Create Opportunity ────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_create_opportunity",
|
||||||
|
{
|
||||||
|
title: "Create Opportunity",
|
||||||
|
description: `Create a new Opportunity from a Lead or Customer.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
opportunity_from: z.enum(["Lead", "Customer"]),
|
||||||
|
party_name: z.string(),
|
||||||
|
company: z.string(),
|
||||||
|
opportunity_type: z.string().optional(),
|
||||||
|
status: z.string().optional(),
|
||||||
|
expected_closing: z.string().optional(),
|
||||||
|
probability: z.number().optional(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const doc = await client.createDocument("Opportunity", params);
|
||||||
|
return { content: [{ type: "text", text: `Created Opportunity: ${doc.name}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 60. Get Opportunities by Lead Source ──────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_opportunities_by_source",
|
||||||
|
{
|
||||||
|
title: "Get Opportunities by Lead Source",
|
||||||
|
description: `Get opportunities grouped by lead source for analytics.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
from_date: z.string(),
|
||||||
|
to_date: z.string(),
|
||||||
|
company: z.string(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.selling.page.sales_funnel.sales_funnel.get_opp_by_lead_source",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerProjectTools(server: McpServer, client: ERPNextClient): void {
|
||||||
|
|
||||||
|
// ─── 61. Create Task ───────────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_create_task",
|
||||||
|
{
|
||||||
|
title: "Create Task",
|
||||||
|
description: `Create a new Task, optionally linked to a Project.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
subject: z.string(),
|
||||||
|
project: z.string().optional(),
|
||||||
|
status: z.string().default("Open"),
|
||||||
|
priority: z.string().optional(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
exp_start_date: z.string().optional(),
|
||||||
|
exp_end_date: z.string().optional(),
|
||||||
|
assigned_to: z.string().optional(),
|
||||||
|
parent_task: z.string().optional(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const data: Record<string, unknown> = { ...params };
|
||||||
|
if (params.assigned_to) {
|
||||||
|
delete data.assigned_to;
|
||||||
|
}
|
||||||
|
const doc = await client.createDocument("Task", data);
|
||||||
|
if (params.assigned_to) {
|
||||||
|
await client.callMethod("frappe.desk.form.assign_to.add", {
|
||||||
|
doctype: "Task",
|
||||||
|
name: doc.name,
|
||||||
|
assign_to: [params.assigned_to],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { content: [{ type: "text", text: `Created Task: ${doc.name} — ${params.subject}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 62. Create Project ────────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_create_project",
|
||||||
|
{
|
||||||
|
title: "Create Project",
|
||||||
|
description: `Create a new Project.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
project_name: z.string(),
|
||||||
|
company: z.string(),
|
||||||
|
status: z.string().default("Open"),
|
||||||
|
expected_start_date: z.string().optional(),
|
||||||
|
expected_end_date: z.string().optional(),
|
||||||
|
priority: z.string().optional(),
|
||||||
|
project_type: z.string().optional(),
|
||||||
|
is_active: z.string().default("Yes"),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const doc = await client.createDocument("Project", params);
|
||||||
|
return { content: [{ type: "text", text: `Created Project: ${doc.name}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 63. Get Project Tasks HTML ────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_project_tasks",
|
||||||
|
{
|
||||||
|
title: "Get Project Tasks",
|
||||||
|
description: `Get tasks for a project.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
project: z.string(),
|
||||||
|
start: z.number().default(0),
|
||||||
|
item_status: z.string().optional(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.templates.pages.projects.get_task_html",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerSupportTools(server: McpServer, client: ERPNextClient): void {
|
||||||
|
|
||||||
|
// ─── 64. Set Issue Status ──────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_set_issue_status",
|
||||||
|
{
|
||||||
|
title: "Set Issue Status",
|
||||||
|
description: `Set the status of a support Issue.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
name: z.string(),
|
||||||
|
status: z.string().describe('Status: "Open", "Replied", "Resolved", "Closed"'),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
await client.callMethod("erpnext.support.doctype.issue.issue.set_status", params);
|
||||||
|
return { content: [{ type: "text", text: `Issue ${params.name} status set to ${params.status}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 65. Bulk Set Issue Status ─────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_bulk_set_issue_status",
|
||||||
|
{
|
||||||
|
title: "Bulk Set Issue Status",
|
||||||
|
description: `Set the status of multiple Issues at once.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
names: z.array(z.string()),
|
||||||
|
status: z.string(),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
await client.callMethod("erpnext.support.doctype.issue.issue.set_multiple_status", {
|
||||||
|
names: JSON.stringify(params.names),
|
||||||
|
status: params.status,
|
||||||
|
});
|
||||||
|
return { content: [{ type: "text", text: `Updated ${params.names.length} issues to ${params.status}` }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 66. Make Task from Issue ──────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_make_task_from_issue",
|
||||||
|
{
|
||||||
|
title: "Make Task from Issue",
|
||||||
|
description: `Create a Task from a support Issue.`,
|
||||||
|
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.support.doctype.issue.issue.make_task",
|
||||||
|
{ 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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerSetupTools(server: McpServer, client: ERPNextClient): void {
|
||||||
|
|
||||||
|
// ─── 67. Get Company Tree ──────────────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_company_tree",
|
||||||
|
{
|
||||||
|
title: "Get Company Tree",
|
||||||
|
description: `Get company hierarchy tree.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
parent: z.string().optional(),
|
||||||
|
is_root: z.boolean().default(false),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.setup.doctype.company.company.get_children",
|
||||||
|
{ doctype: "Company", ...params }
|
||||||
|
);
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 68. Get Default Company Address ───────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_default_company_address",
|
||||||
|
{
|
||||||
|
title: "Get Default Company Address",
|
||||||
|
description: `Get the default/primary address for a company.`,
|
||||||
|
inputSchema: z.object({ name: z.string().describe("Company name") }).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.setup.doctype.company.company.get_default_company_address",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 69. Get Terms and Conditions ──────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_terms_and_conditions",
|
||||||
|
{
|
||||||
|
title: "Get Terms and Conditions",
|
||||||
|
description: `Get rendered terms and conditions template for a document.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
template_name: z.string(),
|
||||||
|
doc: z.record(z.unknown()).describe("Document data for template rendering"),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
return { content: [{ type: "text", text: String(result) }] };
|
||||||
|
} catch (error) {
|
||||||
|
return { isError: true, content: [{ type: "text", text: `Error: ${(error as Error).message}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ─── 70. Get Holiday List Events ───────────────────────
|
||||||
|
server.registerTool(
|
||||||
|
"erpnext_get_holidays",
|
||||||
|
{
|
||||||
|
title: "Get Holiday Events",
|
||||||
|
description: `Get holidays from a holiday list for a date range.`,
|
||||||
|
inputSchema: z.object({
|
||||||
|
start: z.string().describe("Start date (YYYY-MM-DD)"),
|
||||||
|
end: z.string().describe("End date (YYYY-MM-DD)"),
|
||||||
|
}).strict(),
|
||||||
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
try {
|
||||||
|
const result = await client.callMethod(
|
||||||
|
"erpnext.setup.doctype.holiday_list.holiday_list.get_events",
|
||||||
|
params
|
||||||
|
);
|
||||||
|
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}` }] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue