@calybur/mcp 0.1.0 → 0.2.2
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 +37 -22
- package/dist/client.js +9 -6
- package/dist/config.d.ts +3 -0
- package/dist/config.js +14 -7
- package/dist/errors.js +1 -1
- package/dist/index.js +57 -39
- package/dist/tools/docs.js +3 -2
- package/dist/tools-manifest.d.ts +63 -0
- package/dist/tools-manifest.js +79 -0
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
# @calybur/mcp
|
|
2
2
|
|
|
3
|
-
Official MCP server for [Calybur](https://www.calybur.com) — connect
|
|
3
|
+
Official MCP server for [Calybur](https://www.calybur.com) — connect **external MCP-compatible agents** to your Malaysian payroll and HR data via the Partner API.
|
|
4
|
+
|
|
5
|
+
Most Calybur customers use **AI Workspace** inside the product for day-to-day questions. This package is for integrators who want Claude Desktop, custom agents, automation runners, or any MCP client to query Calybur with an API key.
|
|
4
6
|
|
|
5
7
|
## Requirements
|
|
6
8
|
|
|
7
9
|
- Node.js 20+
|
|
8
10
|
- Calybur **Starter** plan or above
|
|
9
|
-
- API key with `read` scope
|
|
11
|
+
- API key with `read` scope — create at **Settings → API Keys** in Calybur
|
|
12
|
+
- Optional MCP setup copy at **Settings → Integrations**
|
|
13
|
+
|
|
14
|
+
## Setup in Calybur
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
1. Create a Partner API key (`ezg_live_*`) with read scope.
|
|
17
|
+
2. Open **Settings → Integrations** and copy the MCP config snippet, or use the example below.
|
|
18
|
+
3. Paste the config into your MCP client (stdio transport).
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
## Connect any MCP client
|
|
14
21
|
|
|
15
22
|
```json
|
|
16
23
|
{
|
|
@@ -19,41 +26,49 @@ Add to `.cursor/mcp.json`:
|
|
|
19
26
|
"command": "npx",
|
|
20
27
|
"args": ["-y", "@calybur/mcp@latest"],
|
|
21
28
|
"env": {
|
|
22
|
-
"CALYBUR_API_KEY": "ezg_live_your_key_here"
|
|
23
|
-
"CALYBUR_API_BASE_URL": "https://YOUR_PROJECT.supabase.co/functions/v1",
|
|
24
|
-
"CALYBUR_SUPABASE_PUBLISHABLE_KEY": "your_supabase_publishable_key",
|
|
25
|
-
"CALYBUR_PLAN": "starter"
|
|
29
|
+
"CALYBUR_API_KEY": "ezg_live_your_key_here"
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
34
|
```
|
|
31
35
|
|
|
32
|
-
Restart
|
|
36
|
+
Restart your MCP client and enable the Calybur tools. Cursor, Claude Desktop, and other stdio MCP hosts use the same shape; only the config file location differs.
|
|
33
37
|
|
|
34
38
|
## Environment Variables
|
|
35
39
|
|
|
36
40
|
| Variable | Required | Description |
|
|
37
41
|
|----------|----------|-------------|
|
|
38
42
|
| `CALYBUR_API_KEY` | Yes | Partner API key (`ezg_live_*`) |
|
|
39
|
-
| `CALYBUR_API_BASE_URL` | Yes | Supabase Edge Functions base URL |
|
|
40
|
-
| `CALYBUR_SUPABASE_PUBLISHABLE_KEY` | Yes | Supabase publishable key (same as app frontend) |
|
|
41
43
|
| `CALYBUR_PLAN` | No | `starter` (default), `professional`, or `enterprise` |
|
|
44
|
+
| `CALYBUR_API_BASE_URL` | No | Defaults to `https://api.calybur.com` |
|
|
45
|
+
| `CALYBUR_SUPABASE_PUBLISHABLE_KEY` | No | Only if bypassing the gateway with a direct Supabase URL |
|
|
42
46
|
|
|
43
47
|
## Tools (MVP — read-only)
|
|
44
48
|
|
|
45
49
|
| Tool | Purpose |
|
|
46
50
|
|------|---------|
|
|
47
|
-
| `calybur_workforce` |
|
|
48
|
-
| `calybur_leave` |
|
|
49
|
-
| `calybur_payroll` |
|
|
50
|
-
| `calybur_attendance` |
|
|
51
|
-
| `calybur_commission` |
|
|
52
|
-
| `calybur_reports` |
|
|
53
|
-
| `calybur_status` | API key
|
|
54
|
-
| `calybur_docs` | API and Malaysia statutory
|
|
51
|
+
| `calybur_workforce` | Query employees, departments, positions, and work locations from Calybur. |
|
|
52
|
+
| `calybur_leave` | Query leave balances, requests, policies, and public holidays. |
|
|
53
|
+
| `calybur_payroll` | Query payroll periods, run status, and payslips. |
|
|
54
|
+
| `calybur_attendance` | Query attendance events and summaries. |
|
|
55
|
+
| `calybur_commission` | Query commission rules and calculation results. |
|
|
56
|
+
| `calybur_reports` | Fetch payroll summary or statutory export metadata for a period. |
|
|
57
|
+
| `calybur_status` | Check API key validity and remaining MCP client rate budget. |
|
|
58
|
+
| `calybur_docs` | Search bundled Calybur API and Malaysia statutory documentation. |
|
|
59
|
+
|
|
60
|
+
### Actions by tool
|
|
61
|
+
|
|
62
|
+
- **calybur_workforce**: list_employees, get_employee, list_departments, list_positions, list_work_locations
|
|
63
|
+
- **calybur_leave**: list_balances, list_requests, list_policies, list_holidays
|
|
64
|
+
- **calybur_payroll**: list_periods, get_run, list_payslips
|
|
65
|
+
- **calybur_attendance**: list_events, list_summaries
|
|
66
|
+
- **calybur_commission**: list_rules, list_calculations
|
|
67
|
+
- **calybur_reports**: payroll_summary, statutory_metadata
|
|
68
|
+
|
|
69
|
+
`calybur_status` and `calybur_docs` have dedicated input shapes (no `action` enum).
|
|
55
70
|
|
|
56
|
-
## Example
|
|
71
|
+
## Example prompts
|
|
57
72
|
|
|
58
73
|
- "Use calybur_status to verify my API connection"
|
|
59
74
|
- "List active employees with calybur_workforce"
|
|
@@ -66,10 +81,10 @@ cd packages/calybur-mcp
|
|
|
66
81
|
npm install
|
|
67
82
|
npm test
|
|
68
83
|
npm run build
|
|
69
|
-
CALYBUR_API_KEY
|
|
84
|
+
CALYBUR_API_KEY=ezg_live_... npm run dev
|
|
70
85
|
```
|
|
71
86
|
|
|
72
|
-
## Rate
|
|
87
|
+
## Rate limits
|
|
73
88
|
|
|
74
89
|
| Plan | API limit | MCP client budget (90%) |
|
|
75
90
|
|------|-----------|-------------------------|
|
package/dist/client.js
CHANGED
|
@@ -12,14 +12,17 @@ export class CalyburClient {
|
|
|
12
12
|
}
|
|
13
13
|
const query = new URLSearchParams(params).toString();
|
|
14
14
|
const url = `${this.config.baseUrl}/${functionPath}${query ? `?${query}` : ''}`;
|
|
15
|
+
const headers = {
|
|
16
|
+
'x-api-key': this.config.apiKey,
|
|
17
|
+
Accept: 'application/json',
|
|
18
|
+
};
|
|
19
|
+
if (!this.config.gatewayMode) {
|
|
20
|
+
headers.apikey = this.config.publishableKey;
|
|
21
|
+
headers.Authorization = `Bearer ${this.config.publishableKey}`;
|
|
22
|
+
}
|
|
15
23
|
const response = await fetch(url, {
|
|
16
24
|
method: 'GET',
|
|
17
|
-
headers
|
|
18
|
-
'x-api-key': this.config.apiKey,
|
|
19
|
-
apikey: this.config.publishableKey,
|
|
20
|
-
Authorization: `Bearer ${this.config.publishableKey}`,
|
|
21
|
-
Accept: 'application/json',
|
|
22
|
-
},
|
|
25
|
+
headers,
|
|
23
26
|
});
|
|
24
27
|
const body = await response.json().catch(() => ({}));
|
|
25
28
|
if (!response.ok) {
|
package/dist/config.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export type CalyburPlan = 'starter' | 'professional' | 'enterprise';
|
|
2
|
+
export declare const DEFAULT_PARTNER_API_BASE_URL = "https://api.calybur.com";
|
|
2
3
|
export interface CalyburConfig {
|
|
3
4
|
apiKey: string;
|
|
4
5
|
baseUrl: string;
|
|
5
6
|
publishableKey: string;
|
|
6
7
|
plan: CalyburPlan;
|
|
8
|
+
gatewayMode: boolean;
|
|
7
9
|
}
|
|
10
|
+
export declare function isGatewayBaseUrl(baseUrl: string): boolean;
|
|
8
11
|
export declare function loadConfig(env?: NodeJS.ProcessEnv): CalyburConfig;
|
|
9
12
|
export declare function defaultLimitForPlan(plan: CalyburPlan): number;
|
package/dist/config.js
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
|
+
export const DEFAULT_PARTNER_API_BASE_URL = 'https://api.calybur.com';
|
|
1
2
|
const VALID_PLANS = ['starter', 'professional', 'enterprise'];
|
|
3
|
+
export function isGatewayBaseUrl(baseUrl) {
|
|
4
|
+
try {
|
|
5
|
+
return new URL(baseUrl).hostname === 'api.calybur.com';
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
2
11
|
export function loadConfig(env = process.env) {
|
|
3
12
|
const apiKey = env.CALYBUR_API_KEY?.trim();
|
|
4
|
-
const baseUrl = env.CALYBUR_API_BASE_URL?.trim().replace(/\/$/, '');
|
|
13
|
+
const baseUrl = (env.CALYBUR_API_BASE_URL?.trim() || DEFAULT_PARTNER_API_BASE_URL).replace(/\/$/, '');
|
|
5
14
|
const publishableKey = env.CALYBUR_SUPABASE_PUBLISHABLE_KEY?.trim() ||
|
|
6
15
|
env.CALYBUR_SUPABASE_ANON_KEY?.trim() ||
|
|
7
16
|
'';
|
|
8
17
|
const planRaw = (env.CALYBUR_PLAN?.trim().toLowerCase() || 'starter');
|
|
18
|
+
const gatewayMode = isGatewayBaseUrl(baseUrl);
|
|
9
19
|
if (!apiKey) {
|
|
10
20
|
throw new Error('CALYBUR_API_KEY is required');
|
|
11
21
|
}
|
|
12
22
|
if (!apiKey.startsWith('ezg_')) {
|
|
13
23
|
throw new Error('CALYBUR_API_KEY must start with ezg_');
|
|
14
24
|
}
|
|
15
|
-
if (!
|
|
16
|
-
throw new Error('
|
|
17
|
-
}
|
|
18
|
-
if (!publishableKey) {
|
|
19
|
-
throw new Error('CALYBUR_SUPABASE_PUBLISHABLE_KEY is required (Supabase gateway auth for Edge Functions)');
|
|
25
|
+
if (!gatewayMode && !publishableKey) {
|
|
26
|
+
throw new Error('CALYBUR_SUPABASE_PUBLISHABLE_KEY is required when using a direct Supabase API URL');
|
|
20
27
|
}
|
|
21
28
|
if (!VALID_PLANS.includes(planRaw)) {
|
|
22
29
|
throw new Error(`CALYBUR_PLAN must be one of: ${VALID_PLANS.join(', ')}`);
|
|
23
30
|
}
|
|
24
|
-
return { apiKey, baseUrl, publishableKey, plan: planRaw };
|
|
31
|
+
return { apiKey, baseUrl, publishableKey, plan: planRaw, gatewayMode };
|
|
25
32
|
}
|
|
26
33
|
export function defaultLimitForPlan(plan) {
|
|
27
34
|
if (plan === 'enterprise')
|
package/dist/errors.js
CHANGED
|
@@ -12,7 +12,7 @@ export function formatApiError(error) {
|
|
|
12
12
|
if (error.status === 401) {
|
|
13
13
|
const body = error.body;
|
|
14
14
|
if (body?.code === 'UNAUTHORIZED_NO_AUTH_HEADER') {
|
|
15
|
-
return '
|
|
15
|
+
return 'Gateway misconfigured. Use https://api.calybur.com or set CALYBUR_SUPABASE_PUBLISHABLE_KEY for direct Supabase access.';
|
|
16
16
|
}
|
|
17
17
|
return 'API key invalid or expired. Regenerate at Calybur Settings → API Keys.';
|
|
18
18
|
}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { z } from 'zod';
|
|
|
5
5
|
import { CalyburClient } from './client.js';
|
|
6
6
|
import { loadConfig } from './config.js';
|
|
7
7
|
import { RateBudget } from './rate-budget.js';
|
|
8
|
+
import { CALYBUR_MCP_SERVER_VERSION, CALYBUR_MCP_TOOLS_MANIFEST, } from './tools-manifest.js';
|
|
8
9
|
import { handleAttendance } from './tools/attendance.js';
|
|
9
10
|
import { handleCommission } from './tools/commission.js';
|
|
10
11
|
import { handleDocs } from './tools/docs.js';
|
|
@@ -13,7 +14,7 @@ import { handlePayroll } from './tools/payroll.js';
|
|
|
13
14
|
import { handleReports } from './tools/reports.js';
|
|
14
15
|
import { handleStatus } from './tools/status.js';
|
|
15
16
|
import { handleWorkforce } from './tools/workforce.js';
|
|
16
|
-
const SERVER_INSTRUCTIONS = `Calybur MCP connects
|
|
17
|
+
const SERVER_INSTRUCTIONS = `Calybur MCP connects external MCP-compatible agents to Malaysian payroll and HR data via the Calybur Partner API.
|
|
17
18
|
|
|
18
19
|
Guidelines:
|
|
19
20
|
- Prefer read tools before write operations (write tools ship in a later release).
|
|
@@ -21,60 +22,73 @@ Guidelines:
|
|
|
21
22
|
- Default PII masking is on — IC, bank, and email fields are partially redacted.
|
|
22
23
|
- Starter plan: 100 API req/min — use list limits of 20 or lower.
|
|
23
24
|
- Malaysian statutory terms: EPF, SOCSO, EIS, PCB.
|
|
24
|
-
- Requires Starter+ plan and an API key with appropriate scopes from Calybur Settings → API Keys
|
|
25
|
+
- Requires Starter+ plan and an API key with appropriate scopes from Calybur Settings → API Keys.
|
|
26
|
+
- In-app AI Workspace inside Calybur does not use this MCP server.`;
|
|
25
27
|
const sharedPaginationSchema = {
|
|
26
28
|
page: z.number().int().min(1).optional().describe('Page number (default 1)'),
|
|
27
29
|
limit: z.number().int().min(1).max(100).optional().describe('Page size (Starter default 20)'),
|
|
28
30
|
mask_pii: z.boolean().optional().describe('Mask IC, bank, email fields (default true)'),
|
|
29
31
|
};
|
|
32
|
+
function manifestEntry(name) {
|
|
33
|
+
const entry = CALYBUR_MCP_TOOLS_MANIFEST.find((tool) => tool.name === name);
|
|
34
|
+
if (!entry) {
|
|
35
|
+
throw new Error(`Missing MCP tool manifest entry: ${name}`);
|
|
36
|
+
}
|
|
37
|
+
return entry;
|
|
38
|
+
}
|
|
39
|
+
function actionsFor(name) {
|
|
40
|
+
const actions = manifestEntry(name).actions;
|
|
41
|
+
if (!actions?.length) {
|
|
42
|
+
throw new Error(`Tool ${name} has no actions in manifest`);
|
|
43
|
+
}
|
|
44
|
+
return [...actions];
|
|
45
|
+
}
|
|
30
46
|
export function createCalyburMcpServer(client) {
|
|
31
47
|
const server = new McpServer({
|
|
32
48
|
name: 'calybur',
|
|
33
|
-
version:
|
|
49
|
+
version: CALYBUR_MCP_SERVER_VERSION,
|
|
34
50
|
}, {
|
|
35
51
|
instructions: SERVER_INSTRUCTIONS,
|
|
36
52
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
53
|
+
const workforce = manifestEntry('calybur_workforce');
|
|
54
|
+
server.registerTool(workforce.name, {
|
|
55
|
+
title: workforce.title,
|
|
56
|
+
description: workforce.description,
|
|
40
57
|
inputSchema: z.object({
|
|
41
|
-
action: z.enum(
|
|
42
|
-
'list_employees',
|
|
43
|
-
'get_employee',
|
|
44
|
-
'list_departments',
|
|
45
|
-
'list_positions',
|
|
46
|
-
'list_work_locations',
|
|
47
|
-
]),
|
|
58
|
+
action: z.enum(actionsFor(workforce.name)),
|
|
48
59
|
employee_id: z.string().uuid().optional(),
|
|
49
60
|
...sharedPaginationSchema,
|
|
50
61
|
}),
|
|
51
62
|
}, async (input) => handleWorkforce(client, input));
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
const leave = manifestEntry('calybur_leave');
|
|
64
|
+
server.registerTool(leave.name, {
|
|
65
|
+
title: leave.title,
|
|
66
|
+
description: leave.description,
|
|
55
67
|
inputSchema: z.object({
|
|
56
|
-
action: z.enum(
|
|
68
|
+
action: z.enum(actionsFor(leave.name)),
|
|
57
69
|
employee_id: z.string().uuid().optional(),
|
|
58
70
|
status: z.string().optional(),
|
|
59
71
|
year: z.number().int().optional(),
|
|
60
72
|
...sharedPaginationSchema,
|
|
61
73
|
}),
|
|
62
74
|
}, async (input) => handleLeave(client, input));
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
const payroll = manifestEntry('calybur_payroll');
|
|
76
|
+
server.registerTool(payroll.name, {
|
|
77
|
+
title: payroll.title,
|
|
78
|
+
description: payroll.description,
|
|
66
79
|
inputSchema: z.object({
|
|
67
|
-
action: z.enum(
|
|
80
|
+
action: z.enum(actionsFor(payroll.name)),
|
|
68
81
|
period_id: z.string().uuid().optional(),
|
|
69
82
|
status: z.string().optional(),
|
|
70
83
|
...sharedPaginationSchema,
|
|
71
84
|
}),
|
|
72
85
|
}, async (input) => handlePayroll(client, input));
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
86
|
+
const attendance = manifestEntry('calybur_attendance');
|
|
87
|
+
server.registerTool(attendance.name, {
|
|
88
|
+
title: attendance.title,
|
|
89
|
+
description: attendance.description,
|
|
76
90
|
inputSchema: z.object({
|
|
77
|
-
action: z.enum(
|
|
91
|
+
action: z.enum(actionsFor(attendance.name)),
|
|
78
92
|
employee_id: z.string().uuid().optional(),
|
|
79
93
|
status: z.string().optional(),
|
|
80
94
|
from: z.string().optional().describe('YYYY-MM-DD'),
|
|
@@ -82,32 +96,36 @@ export function createCalyburMcpServer(client) {
|
|
|
82
96
|
...sharedPaginationSchema,
|
|
83
97
|
}),
|
|
84
98
|
}, async (input) => handleAttendance(client, input));
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
const commission = manifestEntry('calybur_commission');
|
|
100
|
+
server.registerTool(commission.name, {
|
|
101
|
+
title: commission.title,
|
|
102
|
+
description: commission.description,
|
|
88
103
|
inputSchema: z.object({
|
|
89
|
-
action: z.enum(
|
|
104
|
+
action: z.enum(actionsFor(commission.name)),
|
|
90
105
|
status: z.string().optional(),
|
|
91
106
|
...sharedPaginationSchema,
|
|
92
107
|
}),
|
|
93
108
|
}, async (input) => handleCommission(client, input));
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
const reports = manifestEntry('calybur_reports');
|
|
110
|
+
server.registerTool(reports.name, {
|
|
111
|
+
title: reports.title,
|
|
112
|
+
description: reports.description,
|
|
97
113
|
inputSchema: z.object({
|
|
98
|
-
action: z.enum(
|
|
114
|
+
action: z.enum(actionsFor(reports.name)),
|
|
99
115
|
period_id: z.string().uuid(),
|
|
100
116
|
mask_pii: z.boolean().optional(),
|
|
101
117
|
}),
|
|
102
118
|
}, async (input) => handleReports(client, input));
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
119
|
+
const status = manifestEntry('calybur_status');
|
|
120
|
+
server.registerTool(status.name, {
|
|
121
|
+
title: status.title,
|
|
122
|
+
description: status.description,
|
|
106
123
|
inputSchema: z.object({}),
|
|
107
124
|
}, async () => handleStatus(client));
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
125
|
+
const docs = manifestEntry('calybur_docs');
|
|
126
|
+
server.registerTool(docs.name, {
|
|
127
|
+
title: docs.title,
|
|
128
|
+
description: docs.description,
|
|
111
129
|
inputSchema: z.object({
|
|
112
130
|
query: z.string().min(1),
|
|
113
131
|
}),
|
package/dist/tools/docs.js
CHANGED
|
@@ -19,8 +19,9 @@ Create keys at Calybur Settings → API Keys.`,
|
|
|
19
19
|
{
|
|
20
20
|
title: 'MCP Setup',
|
|
21
21
|
keywords: ['mcp', 'cursor', 'claude', 'setup', 'config'],
|
|
22
|
-
body: `Configure Cursor MCP with npx @calybur/mcp and env
|
|
23
|
-
CALYBUR_API_KEY
|
|
22
|
+
body: `Configure Cursor MCP with npx @calybur/mcp and env:
|
|
23
|
+
CALYBUR_API_KEY (required). Optional: CALYBUR_PLAN (starter|professional|enterprise).
|
|
24
|
+
Uses https://api.calybur.com gateway — no Supabase keys needed.`,
|
|
24
25
|
},
|
|
25
26
|
{
|
|
26
27
|
title: 'Rate Limits',
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for external Calybur MCP tools (read-only MVP).
|
|
3
|
+
* Used by server registration, README validation, and product-surface drift checks.
|
|
4
|
+
*/
|
|
5
|
+
export declare const CALYBUR_MCP_SERVER_VERSION = "0.2.2";
|
|
6
|
+
export declare const CALYBUR_MCP_PACKAGE_NAME = "@calybur/mcp@latest";
|
|
7
|
+
export type CalyburMcpToolManifestEntry = {
|
|
8
|
+
name: string;
|
|
9
|
+
title: string;
|
|
10
|
+
description: string;
|
|
11
|
+
actions?: readonly string[];
|
|
12
|
+
readOnly: true;
|
|
13
|
+
};
|
|
14
|
+
export declare const CALYBUR_MCP_TOOLS_MANIFEST: readonly [{
|
|
15
|
+
readonly name: "calybur_workforce";
|
|
16
|
+
readonly title: "Calybur Workforce";
|
|
17
|
+
readonly description: "Query employees, departments, positions, and work locations from Calybur.";
|
|
18
|
+
readonly actions: readonly ["list_employees", "get_employee", "list_departments", "list_positions", "list_work_locations"];
|
|
19
|
+
readonly readOnly: true;
|
|
20
|
+
}, {
|
|
21
|
+
readonly name: "calybur_leave";
|
|
22
|
+
readonly title: "Calybur Leave";
|
|
23
|
+
readonly description: "Query leave balances, requests, policies, and public holidays.";
|
|
24
|
+
readonly actions: readonly ["list_balances", "list_requests", "list_policies", "list_holidays"];
|
|
25
|
+
readonly readOnly: true;
|
|
26
|
+
}, {
|
|
27
|
+
readonly name: "calybur_payroll";
|
|
28
|
+
readonly title: "Calybur Payroll";
|
|
29
|
+
readonly description: "Query payroll periods, run status, and payslips.";
|
|
30
|
+
readonly actions: readonly ["list_periods", "get_run", "list_payslips"];
|
|
31
|
+
readonly readOnly: true;
|
|
32
|
+
}, {
|
|
33
|
+
readonly name: "calybur_attendance";
|
|
34
|
+
readonly title: "Calybur Attendance";
|
|
35
|
+
readonly description: "Query attendance events and summaries.";
|
|
36
|
+
readonly actions: readonly ["list_events", "list_summaries"];
|
|
37
|
+
readonly readOnly: true;
|
|
38
|
+
}, {
|
|
39
|
+
readonly name: "calybur_commission";
|
|
40
|
+
readonly title: "Calybur Commission";
|
|
41
|
+
readonly description: "Query commission rules and calculation results.";
|
|
42
|
+
readonly actions: readonly ["list_rules", "list_calculations"];
|
|
43
|
+
readonly readOnly: true;
|
|
44
|
+
}, {
|
|
45
|
+
readonly name: "calybur_reports";
|
|
46
|
+
readonly title: "Calybur Reports";
|
|
47
|
+
readonly description: "Fetch payroll summary or statutory export metadata for a period.";
|
|
48
|
+
readonly actions: readonly ["payroll_summary", "statutory_metadata"];
|
|
49
|
+
readonly readOnly: true;
|
|
50
|
+
}, {
|
|
51
|
+
readonly name: "calybur_status";
|
|
52
|
+
readonly title: "Calybur Status";
|
|
53
|
+
readonly description: "Check API key validity and remaining MCP client rate budget.";
|
|
54
|
+
readonly readOnly: true;
|
|
55
|
+
}, {
|
|
56
|
+
readonly name: "calybur_docs";
|
|
57
|
+
readonly title: "Calybur Docs";
|
|
58
|
+
readonly description: "Search bundled Calybur API and Malaysia statutory documentation.";
|
|
59
|
+
readonly readOnly: true;
|
|
60
|
+
}];
|
|
61
|
+
export declare const CALYBUR_MCP_TOOL_NAMES: ("calybur_workforce" | "calybur_leave" | "calybur_payroll" | "calybur_attendance" | "calybur_commission" | "calybur_reports" | "calybur_status" | "calybur_docs")[];
|
|
62
|
+
export declare function formatToolsMarkdownTable(): string;
|
|
63
|
+
export declare function formatActionsMarkdownList(): string;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for external Calybur MCP tools (read-only MVP).
|
|
3
|
+
* Used by server registration, README validation, and product-surface drift checks.
|
|
4
|
+
*/
|
|
5
|
+
export const CALYBUR_MCP_SERVER_VERSION = '0.2.2';
|
|
6
|
+
export const CALYBUR_MCP_PACKAGE_NAME = '@calybur/mcp@latest';
|
|
7
|
+
export const CALYBUR_MCP_TOOLS_MANIFEST = [
|
|
8
|
+
{
|
|
9
|
+
name: 'calybur_workforce',
|
|
10
|
+
title: 'Calybur Workforce',
|
|
11
|
+
description: 'Query employees, departments, positions, and work locations from Calybur.',
|
|
12
|
+
actions: [
|
|
13
|
+
'list_employees',
|
|
14
|
+
'get_employee',
|
|
15
|
+
'list_departments',
|
|
16
|
+
'list_positions',
|
|
17
|
+
'list_work_locations',
|
|
18
|
+
],
|
|
19
|
+
readOnly: true,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'calybur_leave',
|
|
23
|
+
title: 'Calybur Leave',
|
|
24
|
+
description: 'Query leave balances, requests, policies, and public holidays.',
|
|
25
|
+
actions: ['list_balances', 'list_requests', 'list_policies', 'list_holidays'],
|
|
26
|
+
readOnly: true,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'calybur_payroll',
|
|
30
|
+
title: 'Calybur Payroll',
|
|
31
|
+
description: 'Query payroll periods, run status, and payslips.',
|
|
32
|
+
actions: ['list_periods', 'get_run', 'list_payslips'],
|
|
33
|
+
readOnly: true,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'calybur_attendance',
|
|
37
|
+
title: 'Calybur Attendance',
|
|
38
|
+
description: 'Query attendance events and summaries.',
|
|
39
|
+
actions: ['list_events', 'list_summaries'],
|
|
40
|
+
readOnly: true,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'calybur_commission',
|
|
44
|
+
title: 'Calybur Commission',
|
|
45
|
+
description: 'Query commission rules and calculation results.',
|
|
46
|
+
actions: ['list_rules', 'list_calculations'],
|
|
47
|
+
readOnly: true,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'calybur_reports',
|
|
51
|
+
title: 'Calybur Reports',
|
|
52
|
+
description: 'Fetch payroll summary or statutory export metadata for a period.',
|
|
53
|
+
actions: ['payroll_summary', 'statutory_metadata'],
|
|
54
|
+
readOnly: true,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'calybur_status',
|
|
58
|
+
title: 'Calybur Status',
|
|
59
|
+
description: 'Check API key validity and remaining MCP client rate budget.',
|
|
60
|
+
readOnly: true,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'calybur_docs',
|
|
64
|
+
title: 'Calybur Docs',
|
|
65
|
+
description: 'Search bundled Calybur API and Malaysia statutory documentation.',
|
|
66
|
+
readOnly: true,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
export const CALYBUR_MCP_TOOL_NAMES = CALYBUR_MCP_TOOLS_MANIFEST.map((tool) => tool.name);
|
|
70
|
+
export function formatToolsMarkdownTable() {
|
|
71
|
+
const header = '| Tool | Purpose |\n|------|---------|';
|
|
72
|
+
const rows = CALYBUR_MCP_TOOLS_MANIFEST.map((tool) => `| \`${tool.name}\` | ${tool.description} |`);
|
|
73
|
+
return [header, ...rows].join('\n');
|
|
74
|
+
}
|
|
75
|
+
export function formatActionsMarkdownList() {
|
|
76
|
+
return CALYBUR_MCP_TOOLS_MANIFEST.flatMap((tool) => 'actions' in tool && tool.actions?.length
|
|
77
|
+
? [`- **${tool.name}**: ${tool.actions.join(', ')}`]
|
|
78
|
+
: []).join('\n');
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calybur/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "MCP server for Calybur payroll and HR Partner API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,10 +26,13 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"bin": {
|
|
29
|
-
"calybur-mcp": "
|
|
29
|
+
"calybur-mcp": "dist/index.js"
|
|
30
30
|
},
|
|
31
31
|
"main": "./dist/index.js",
|
|
32
|
-
"files": [
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
33
36
|
"scripts": {
|
|
34
37
|
"build": "tsc -p tsconfig.json",
|
|
35
38
|
"dev": "tsx src/index.ts",
|