payrolla-mcp 0.2.3 → 0.2.5
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 +7 -3
- package/dist/index.js +97 -22
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -55,15 +55,19 @@ Calculate payroll for a single employee.
|
|
|
55
55
|
- `month` - Starting month (1-12)
|
|
56
56
|
- `periodCount` - Number of months (optional, default: 1)
|
|
57
57
|
- `ssiType` - SSI type: 'S4A', 'S4B', or 'S4C' (optional, default: 'S4A')
|
|
58
|
-
- `extraPayments` - Array of extra payments (optional)
|
|
58
|
+
- `extraPayments` - Array of extra payments (optional, supports `paymentType` = RegularPayment/Overtime/SocialAid/ExtraPay)
|
|
59
59
|
- `customParams` - Custom global parameters (optional)
|
|
60
|
+
- `cumulativeIncomeTaxBase` - Starting income tax base to carry over
|
|
61
|
+
- `cumulativeMinWageIncomeTaxBase` - Starting minimum wage income tax base to carry over
|
|
62
|
+
- `transferredSSIBase1` - Starting transferred SSI base 1
|
|
63
|
+
- `transferredSSIBase2` - Starting transferred SSI base 2
|
|
60
64
|
|
|
61
65
|
### calculate_bulk_payroll
|
|
62
66
|
|
|
63
67
|
Calculate payroll for multiple employees with shared parameters.
|
|
64
68
|
|
|
65
69
|
**Input:**
|
|
66
|
-
- `employees` - Array of employee objects
|
|
70
|
+
- `employees` - Array of employee objects (each can include extra payments with `paymentType` and starting cumulative/transfer bases)
|
|
67
71
|
- `year` - Calculation year
|
|
68
72
|
- `month` - Starting month
|
|
69
73
|
- `periodCount` - Number of months (use 12 for yearly)
|
|
@@ -120,4 +124,4 @@ Plan yearly payroll considering potential changes.
|
|
|
120
124
|
|
|
121
125
|
```
|
|
122
126
|
User: I have 3 employees: Ali 35k net, Ayse 45k net, Mehmet 60k gross.
|
|
123
|
-
What's my yearly budget if I give 10% raise and minimum wage becomes 30k?
|
|
127
|
+
What's my yearly budget if I give 10% raise and minimum wage becomes 30k?
|
package/dist/index.js
CHANGED
|
@@ -30,11 +30,27 @@ function mapSSIType(ssiType) {
|
|
|
30
30
|
function mapCalculationType(calcType) {
|
|
31
31
|
return calcType === "Gross" ? CalculationType.Gross : CalculationType.Net;
|
|
32
32
|
}
|
|
33
|
+
function mapPaymentType(paymentType) {
|
|
34
|
+
switch (paymentType) {
|
|
35
|
+
case 1:
|
|
36
|
+
case "RegularPayment":
|
|
37
|
+
return PaymentType.RegularPayment;
|
|
38
|
+
case 2:
|
|
39
|
+
case "Overtime":
|
|
40
|
+
return PaymentType.Overtime;
|
|
41
|
+
case 3:
|
|
42
|
+
case "SocialAid":
|
|
43
|
+
return PaymentType.SocialAid;
|
|
44
|
+
case 4:
|
|
45
|
+
case "ExtraPay":
|
|
46
|
+
default:
|
|
47
|
+
return PaymentType.ExtraPay;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
33
50
|
function buildCustomGlobalParams(customParams) {
|
|
34
51
|
if (!customParams) return void 0;
|
|
35
52
|
return {
|
|
36
53
|
minWage: customParams.minWage,
|
|
37
|
-
minWageNet: customParams.minWageNet,
|
|
38
54
|
ssi_LowerLimit: customParams.ssiLowerLimit,
|
|
39
55
|
ssi_UpperLimit: customParams.ssiUpperLimit,
|
|
40
56
|
stampTaxRatio: customParams.stampTaxRatio,
|
|
@@ -51,7 +67,11 @@ async function calculatePayroll(client, input) {
|
|
|
51
67
|
month,
|
|
52
68
|
periodCount = 1,
|
|
53
69
|
extraPayments,
|
|
54
|
-
customParams
|
|
70
|
+
customParams,
|
|
71
|
+
cumulativeIncomeTaxBase = 0,
|
|
72
|
+
cumulativeMinWageIncomeTaxBase = 0,
|
|
73
|
+
transferredSSIBase1 = 0,
|
|
74
|
+
transferredSSIBase2 = 0
|
|
55
75
|
} = input;
|
|
56
76
|
const payments = [
|
|
57
77
|
{
|
|
@@ -67,21 +87,17 @@ async function calculatePayroll(client, input) {
|
|
|
67
87
|
payments.push({
|
|
68
88
|
paymentAmount: extra.amount,
|
|
69
89
|
paymentName: extra.name,
|
|
70
|
-
paymentType:
|
|
90
|
+
paymentType: mapPaymentType(extra.paymentType),
|
|
71
91
|
paymentRef: `extra_${i + 2}`,
|
|
72
92
|
calculationType: extra.type === "Net" ? CalculationType.Net : CalculationType.Gross
|
|
73
93
|
});
|
|
74
94
|
}
|
|
75
95
|
}
|
|
76
|
-
const
|
|
77
|
-
calcDate: `${year}-${String(month).padStart(2, "0")}-01`,
|
|
96
|
+
const baseModel = {
|
|
78
97
|
wageAmount: wage,
|
|
79
|
-
cumulativeIncomeTaxBase: 0,
|
|
80
|
-
cumulativeMinWageIncomeTaxBase: 0,
|
|
81
98
|
ssiType: mapSSIType(ssiType),
|
|
82
99
|
wageCalculationType: mapCalculationType(calculationType),
|
|
83
100
|
wagePeriodType: PaymentPeriodType.Monthly,
|
|
84
|
-
periodCount,
|
|
85
101
|
periodLengthType: PeriodLengthType.Month,
|
|
86
102
|
payments,
|
|
87
103
|
calculationParams: {
|
|
@@ -89,16 +105,40 @@ async function calculatePayroll(client, input) {
|
|
|
89
105
|
customGlobalParams: buildCustomGlobalParams(customParams)
|
|
90
106
|
}
|
|
91
107
|
};
|
|
92
|
-
const result = await client.calculate(model);
|
|
93
108
|
let totalCost = 0;
|
|
94
109
|
let totalNet = 0;
|
|
95
110
|
let totalGross = 0;
|
|
96
111
|
const periods = [];
|
|
97
|
-
|
|
112
|
+
let incomeTaxBase = cumulativeIncomeTaxBase;
|
|
113
|
+
let minWageIncomeTaxBase = cumulativeMinWageIncomeTaxBase;
|
|
114
|
+
let transferredBase1 = transferredSSIBase1;
|
|
115
|
+
let transferredBase2 = transferredSSIBase2;
|
|
116
|
+
for (let i = 0; i < periodCount; i++) {
|
|
117
|
+
const calcDate = new Date(year, month - 1 + i, 1);
|
|
118
|
+
const calcYear = calcDate.getFullYear();
|
|
119
|
+
const calcMonth = calcDate.getMonth() + 1;
|
|
120
|
+
const model = {
|
|
121
|
+
...baseModel,
|
|
122
|
+
calcDate: `${calcYear}-${String(calcMonth).padStart(2, "0")}-01`,
|
|
123
|
+
cumulativeIncomeTaxBase: incomeTaxBase,
|
|
124
|
+
cumulativeMinWageIncomeTaxBase: minWageIncomeTaxBase,
|
|
125
|
+
transferredSSIBase1: transferredBase1,
|
|
126
|
+
transferredSSIBase2: transferredBase2,
|
|
127
|
+
periodCount: 1
|
|
128
|
+
};
|
|
129
|
+
const result = await client.calculate(model);
|
|
130
|
+
const payroll = result.payrolls?.[0];
|
|
131
|
+
if (!payroll) {
|
|
132
|
+
throw new Error("Payrolla calculation returned no payroll data");
|
|
133
|
+
}
|
|
98
134
|
const pr = payroll.payrollResult;
|
|
99
135
|
totalCost += payroll.totalCost;
|
|
100
136
|
totalNet += pr.totalNet;
|
|
101
137
|
totalGross += pr.totalGross;
|
|
138
|
+
const nextIncomeTaxBase = incomeTaxBase + pr.totalIncomeTaxBase;
|
|
139
|
+
const nextMinWageIncomeTaxBase = pr.totalMinWageIncomeTaxExemptionBase;
|
|
140
|
+
const nextTransferredBase1 = pr.transferredSSIBase1 ?? transferredBase1;
|
|
141
|
+
const nextTransferredBase2 = pr.transferredSSIBase2 ?? transferredBase2;
|
|
102
142
|
periods.push({
|
|
103
143
|
year: payroll.year,
|
|
104
144
|
month: payroll.month,
|
|
@@ -108,8 +148,16 @@ async function calculatePayroll(client, input) {
|
|
|
108
148
|
incomeTax: pr.totalIncomeTax,
|
|
109
149
|
stampTax: pr.totalStampTax,
|
|
110
150
|
employeeSSI: pr.totalSSIWorkerPrem,
|
|
111
|
-
employerSSI: pr.totalSSIEmployerPrem
|
|
151
|
+
employerSSI: pr.totalSSIEmployerPrem,
|
|
152
|
+
cumulativeIncomeTaxBase: nextIncomeTaxBase,
|
|
153
|
+
cumulativeMinWageIncomeTaxBase: nextMinWageIncomeTaxBase,
|
|
154
|
+
transferredSSIBase1: nextTransferredBase1,
|
|
155
|
+
transferredSSIBase2: nextTransferredBase2
|
|
112
156
|
});
|
|
157
|
+
incomeTaxBase = nextIncomeTaxBase;
|
|
158
|
+
minWageIncomeTaxBase = nextMinWageIncomeTaxBase;
|
|
159
|
+
transferredBase1 = nextTransferredBase1;
|
|
160
|
+
transferredBase2 = nextTransferredBase2;
|
|
113
161
|
}
|
|
114
162
|
return {
|
|
115
163
|
employee: name,
|
|
@@ -135,7 +183,11 @@ async function calculateBulkPayroll(client, input) {
|
|
|
135
183
|
month,
|
|
136
184
|
periodCount,
|
|
137
185
|
extraPayments: emp.extraPayments,
|
|
138
|
-
customParams
|
|
186
|
+
customParams,
|
|
187
|
+
cumulativeIncomeTaxBase: emp.cumulativeIncomeTaxBase,
|
|
188
|
+
cumulativeMinWageIncomeTaxBase: emp.cumulativeMinWageIncomeTaxBase,
|
|
189
|
+
transferredSSIBase1: emp.transferredSSIBase1,
|
|
190
|
+
transferredSSIBase2: emp.transferredSSIBase2
|
|
139
191
|
});
|
|
140
192
|
employeeResults.push({
|
|
141
193
|
name: result.employee,
|
|
@@ -170,9 +222,21 @@ var DEFAULT_PARAMS_2025 = {
|
|
|
170
222
|
incomeTaxBrackets: [
|
|
171
223
|
{ limit: 158e3, rate: 0.15, description: "158,000 TL'ye kadar %15" },
|
|
172
224
|
{ limit: 33e4, rate: 0.2, description: "158,000-330,000 TL aras\u0131 %20" },
|
|
173
|
-
{
|
|
174
|
-
|
|
175
|
-
|
|
225
|
+
{
|
|
226
|
+
limit: 12e5,
|
|
227
|
+
rate: 0.27,
|
|
228
|
+
description: "330,000-1,200,000 TL aras\u0131 %27"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
limit: 43e5,
|
|
232
|
+
rate: 0.35,
|
|
233
|
+
description: "1,200,000-4,300,000 TL aras\u0131 %35"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
limit: Number.MAX_SAFE_INTEGER,
|
|
237
|
+
rate: 0.4,
|
|
238
|
+
description: "4,300,000 TL'den fazlas\u0131 %40"
|
|
239
|
+
}
|
|
176
240
|
]
|
|
177
241
|
};
|
|
178
242
|
|
|
@@ -191,9 +255,6 @@ function applyScenario(defaults, scenario) {
|
|
|
191
255
|
if (scenario.minWage !== void 0) {
|
|
192
256
|
result.minWage = scenario.minWage;
|
|
193
257
|
}
|
|
194
|
-
if (scenario.minWageNet !== void 0) {
|
|
195
|
-
result.minWageNet = scenario.minWageNet;
|
|
196
|
-
}
|
|
197
258
|
if (scenario.ssiLimitIncreasePercent !== void 0) {
|
|
198
259
|
const multiplier = 1 + scenario.ssiLimitIncreasePercent / 100;
|
|
199
260
|
result.ssiLowerLimit = defaults.ssiLowerLimit * multiplier;
|
|
@@ -256,7 +317,6 @@ async function simulateBudget(client, input) {
|
|
|
256
317
|
scenarioApplied: {
|
|
257
318
|
salaryRaisePercent: scenario.salaryRaisePercent || 0,
|
|
258
319
|
effectiveMinWage: customParams.minWage || defaults.minWage,
|
|
259
|
-
effectiveMinWageNet: customParams.minWageNet || defaults.minWageNet,
|
|
260
320
|
effectiveTaxBrackets
|
|
261
321
|
},
|
|
262
322
|
summary: {
|
|
@@ -485,7 +545,14 @@ function registerPrompts(server) {
|
|
|
485
545
|
var ExtraPaymentSchema = z2.object({
|
|
486
546
|
name: z2.string().describe("Name of the extra payment"),
|
|
487
547
|
amount: z2.number().describe("Payment amount"),
|
|
488
|
-
type: z2.enum(["Net", "Gross"]).describe("Payment type")
|
|
548
|
+
type: z2.enum(["Net", "Gross"]).describe("Payment type"),
|
|
549
|
+
paymentType: z2.union([
|
|
550
|
+
z2.literal(1),
|
|
551
|
+
z2.literal(2),
|
|
552
|
+
z2.literal(3),
|
|
553
|
+
z2.literal(4),
|
|
554
|
+
z2.enum(["RegularPayment", "Overtime", "SocialAid", "ExtraPay"])
|
|
555
|
+
]).optional().describe("Payment type (1: RegularPayment, 2: Overtime, 3: SocialAid, 4: ExtraPay)")
|
|
489
556
|
});
|
|
490
557
|
var CustomParamsSchema = z2.object({
|
|
491
558
|
minWage: z2.number().optional().describe("Custom minimum wage (gross)"),
|
|
@@ -503,7 +570,11 @@ var EmployeeInputSchema = z2.object({
|
|
|
503
570
|
wage: z2.number().describe("Wage amount"),
|
|
504
571
|
calculationType: z2.enum(["Gross", "Net"]).describe("Whether wage is gross or net"),
|
|
505
572
|
ssiType: z2.enum(["S4A", "S4B", "S4C"]).optional().describe("SSI type (default: S4A)"),
|
|
506
|
-
extraPayments: z2.array(ExtraPaymentSchema).optional().describe("Extra payments like bonuses")
|
|
573
|
+
extraPayments: z2.array(ExtraPaymentSchema).optional().describe("Extra payments like bonuses"),
|
|
574
|
+
cumulativeIncomeTaxBase: z2.number().optional().describe("Starting cumulative income tax base"),
|
|
575
|
+
cumulativeMinWageIncomeTaxBase: z2.number().optional().describe("Starting cumulative minimum wage income tax base"),
|
|
576
|
+
transferredSSIBase1: z2.number().optional().describe("Starting transferred SSI base 1"),
|
|
577
|
+
transferredSSIBase2: z2.number().optional().describe("Starting transferred SSI base 2")
|
|
507
578
|
});
|
|
508
579
|
var ScenarioConfigSchema = z2.object({
|
|
509
580
|
name: z2.string().optional().describe("Scenario name for comparison"),
|
|
@@ -549,7 +620,11 @@ function registerTools(server, client) {
|
|
|
549
620
|
month: z2.number().min(1).max(12).describe("Starting month (1-12)"),
|
|
550
621
|
periodCount: z2.number().min(1).max(12).optional().describe("Number of months to calculate (default: 1)"),
|
|
551
622
|
extraPayments: z2.array(ExtraPaymentSchema).optional().describe("Extra payments like bonuses"),
|
|
552
|
-
customParams: CustomParamsSchema.optional().describe("Custom global parameters to override defaults")
|
|
623
|
+
customParams: CustomParamsSchema.optional().describe("Custom global parameters to override defaults"),
|
|
624
|
+
cumulativeIncomeTaxBase: z2.number().optional().describe("Starting cumulative income tax base to carry from previous months"),
|
|
625
|
+
cumulativeMinWageIncomeTaxBase: z2.number().optional().describe("Starting cumulative minimum wage income tax base"),
|
|
626
|
+
transferredSSIBase1: z2.number().optional().describe("Starting transferred SSI base 1"),
|
|
627
|
+
transferredSSIBase2: z2.number().optional().describe("Starting transferred SSI base 2")
|
|
553
628
|
},
|
|
554
629
|
async (params) => {
|
|
555
630
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payrolla-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "MCP server for Payrolla payroll budget simulations - enables LLMs to calculate Turkish payroll and simulate budget scenarios",
|
|
5
5
|
"author": "Payrolla",
|
|
6
6
|
"license": "MIT",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
50
|
-
"payrolla": "^0.2.
|
|
50
|
+
"payrolla": "^0.2.4",
|
|
51
51
|
"zod": "^3.25.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|