@t4dhg/mcp-factorial 1.0.0
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 +154 -0
- package/dist/api.d.ts +13 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +136 -0
- package/dist/api.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +306 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# MCP FactorialHR
|
|
2
|
+
|
|
3
|
+
> **Secure, privacy-focused access to FactorialHR data for AI assistants**
|
|
4
|
+
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://modelcontextprotocol.io/)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
A Model Context Protocol (MCP) server that provides AI assistants like Claude with secure, read-only access to your FactorialHR employee and organizational data. Built with privacy and security as core principles.
|
|
10
|
+
|
|
11
|
+
## Why This MCP Server?
|
|
12
|
+
|
|
13
|
+
- **Privacy-First Design**: Deliberately excludes payroll, compensation, and sensitive financial data. Your salary information stays private.
|
|
14
|
+
- **Read-Only Access**: No write operations - Claude can view but never modify your HR data.
|
|
15
|
+
- **Organizational Focus**: Optimized for team structure, employee directories, and location lookups - the data you actually need for AI-assisted workflows.
|
|
16
|
+
- **Enterprise Ready**: Built for companies who need AI integration without compromising data security.
|
|
17
|
+
|
|
18
|
+
## Security by Design
|
|
19
|
+
|
|
20
|
+
This MCP server intentionally **does NOT expose**:
|
|
21
|
+
- Payroll and salary information
|
|
22
|
+
- Bank account details
|
|
23
|
+
- Tax documents
|
|
24
|
+
- Compensation packages
|
|
25
|
+
- Benefits enrollment data
|
|
26
|
+
- Personal identification numbers
|
|
27
|
+
|
|
28
|
+
We believe AI assistants should help with organizational tasks without having access to your most sensitive HR data.
|
|
29
|
+
|
|
30
|
+
## Available Tools
|
|
31
|
+
|
|
32
|
+
| Tool | Description |
|
|
33
|
+
|------|-------------|
|
|
34
|
+
| `list_employees` | Get all employees with optional team/location filters |
|
|
35
|
+
| `get_employee` | Get employee details (name, role, contact, team assignments) |
|
|
36
|
+
| `search_employees` | Search employees by name or email |
|
|
37
|
+
| `list_teams` | View organizational team structure |
|
|
38
|
+
| `get_team` | Get team details and member list |
|
|
39
|
+
| `list_locations` | Get company office locations |
|
|
40
|
+
| `get_location` | Get location details (address, contact info) |
|
|
41
|
+
| `get_employee_contracts` | View job titles and employment dates |
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
### 1. Add to your MCP configuration
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"mcpServers": {
|
|
50
|
+
"factorial": {
|
|
51
|
+
"command": "npx",
|
|
52
|
+
"args": ["-y", "@t4dhg/mcp-factorial"]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Set your API key
|
|
59
|
+
|
|
60
|
+
Create a `.env` file in your project root:
|
|
61
|
+
|
|
62
|
+
```env
|
|
63
|
+
FACTORIAL_API_KEY=your-api-key-here
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or pass it directly in the MCP config:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"mcpServers": {
|
|
71
|
+
"factorial": {
|
|
72
|
+
"command": "npx",
|
|
73
|
+
"args": ["-y", "@t4dhg/mcp-factorial"],
|
|
74
|
+
"env": {
|
|
75
|
+
"FACTORIAL_API_KEY": "your-api-key-here"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 3. Start using it!
|
|
83
|
+
|
|
84
|
+
Once configured, ask Claude things like:
|
|
85
|
+
|
|
86
|
+
- *"Who's on the Engineering team?"*
|
|
87
|
+
- *"Find the email for John Smith"*
|
|
88
|
+
- *"What offices do we have?"*
|
|
89
|
+
- *"Show me the org structure"*
|
|
90
|
+
|
|
91
|
+
## Getting an API Key
|
|
92
|
+
|
|
93
|
+
1. Log in to [FactorialHR](https://app.factorialhr.com) as an administrator
|
|
94
|
+
2. Navigate to **Settings → Integrations → API**
|
|
95
|
+
3. Generate a new API key
|
|
96
|
+
4. Add it to your `.env` file
|
|
97
|
+
|
|
98
|
+
> **Important**: API keys have full access to FactorialHR and never expire. Store them securely and rotate them periodically.
|
|
99
|
+
|
|
100
|
+
## Use Cases
|
|
101
|
+
|
|
102
|
+
### For Managers
|
|
103
|
+
- Quickly look up team member contact information
|
|
104
|
+
- Understand org chart and reporting structures
|
|
105
|
+
- Find employees by skill or department
|
|
106
|
+
|
|
107
|
+
### For HR
|
|
108
|
+
- Power AI-assisted employee directory searches
|
|
109
|
+
- Streamline onboarding information lookups
|
|
110
|
+
- Support with organizational queries
|
|
111
|
+
|
|
112
|
+
### For Developers
|
|
113
|
+
- Build AI workflows that need employee context
|
|
114
|
+
- Create custom Claude integrations
|
|
115
|
+
- Automate org-chart-aware processes
|
|
116
|
+
|
|
117
|
+
## Development
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Clone the repository
|
|
121
|
+
git clone https://github.com/t4dhg/mcp-factorial.git
|
|
122
|
+
cd mcp-factorial
|
|
123
|
+
|
|
124
|
+
# Install dependencies
|
|
125
|
+
npm install
|
|
126
|
+
|
|
127
|
+
# Build
|
|
128
|
+
npm run build
|
|
129
|
+
|
|
130
|
+
# Run locally
|
|
131
|
+
FACTORIAL_API_KEY=your-key npm start
|
|
132
|
+
|
|
133
|
+
# Test with MCP Inspector
|
|
134
|
+
npx @modelcontextprotocol/inspector
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Configuration Options
|
|
138
|
+
|
|
139
|
+
| Environment Variable | Description | Required |
|
|
140
|
+
|---------------------|-------------|----------|
|
|
141
|
+
| `FACTORIAL_API_KEY` | Your FactorialHR API key | Yes |
|
|
142
|
+
| `DEBUG` | Enable debug logging (`true`/`false`) | No |
|
|
143
|
+
|
|
144
|
+
## Contributing
|
|
145
|
+
|
|
146
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT © [t4dhg](https://github.com/t4dhg)
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
*Built with the [Model Context Protocol](https://modelcontextprotocol.io/) by Anthropic*
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Employee, Team, Location, Contract } from './types.js';
|
|
2
|
+
export declare function listEmployees(options?: {
|
|
3
|
+
team_id?: number;
|
|
4
|
+
location_id?: number;
|
|
5
|
+
}): Promise<Employee[]>;
|
|
6
|
+
export declare function getEmployee(id: number): Promise<Employee>;
|
|
7
|
+
export declare function searchEmployees(query: string): Promise<Employee[]>;
|
|
8
|
+
export declare function listTeams(): Promise<Team[]>;
|
|
9
|
+
export declare function getTeam(id: number): Promise<Team>;
|
|
10
|
+
export declare function listLocations(): Promise<Location[]>;
|
|
11
|
+
export declare function getLocation(id: number): Promise<Location>;
|
|
12
|
+
export declare function listContracts(employeeId?: number): Promise<Contract[]>;
|
|
13
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmGrE,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAGtB;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAM/D;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAcxE;AAGD,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAGjD;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvD;AAGD,wBAAsB,aAAa,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAGzD;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAM/D;AAGD,wBAAsB,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAO5E"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// FactorialHR API Client
|
|
2
|
+
const FACTORIAL_BASE_URL = 'https://api.factorialhr.com/api/2025-10-01/resources';
|
|
3
|
+
const DEFAULT_TIMEOUT = 30000; // 30 seconds
|
|
4
|
+
const DEBUG = process.env.DEBUG === 'true';
|
|
5
|
+
function debug(message, data) {
|
|
6
|
+
if (DEBUG) {
|
|
7
|
+
const timestamp = new Date().toISOString();
|
|
8
|
+
if (data) {
|
|
9
|
+
console.error(`[${timestamp}] [mcp-factorial] ${message}`, JSON.stringify(data, null, 2));
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
console.error(`[${timestamp}] [mcp-factorial] ${message}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function getApiKey() {
|
|
17
|
+
const apiKey = process.env.FACTORIAL_API_KEY;
|
|
18
|
+
if (!apiKey) {
|
|
19
|
+
throw new Error('FACTORIAL_API_KEY is not set. ' +
|
|
20
|
+
'Please add it to your .env file or pass it via the MCP configuration. ' +
|
|
21
|
+
'See https://github.com/t4dhg/mcp-factorial for setup instructions.');
|
|
22
|
+
}
|
|
23
|
+
return apiKey;
|
|
24
|
+
}
|
|
25
|
+
async function factorialFetch(endpoint, params) {
|
|
26
|
+
const url = new URL(`${FACTORIAL_BASE_URL}${endpoint}`);
|
|
27
|
+
if (params) {
|
|
28
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
29
|
+
if (value !== undefined) {
|
|
30
|
+
url.searchParams.append(key, String(value));
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
debug(`Fetching: ${url.toString()}`);
|
|
35
|
+
const controller = new AbortController();
|
|
36
|
+
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
|
|
37
|
+
try {
|
|
38
|
+
const response = await fetch(url.toString(), {
|
|
39
|
+
method: 'GET',
|
|
40
|
+
headers: {
|
|
41
|
+
'x-api-key': getApiKey(),
|
|
42
|
+
'Accept': 'application/json',
|
|
43
|
+
},
|
|
44
|
+
signal: controller.signal,
|
|
45
|
+
});
|
|
46
|
+
clearTimeout(timeoutId);
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
const errorText = await response.text();
|
|
49
|
+
debug(`API error (${response.status}):`, errorText);
|
|
50
|
+
// Provide user-friendly error messages
|
|
51
|
+
if (response.status === 401) {
|
|
52
|
+
throw new Error('Invalid API key. Please check your FACTORIAL_API_KEY.');
|
|
53
|
+
}
|
|
54
|
+
if (response.status === 403) {
|
|
55
|
+
throw new Error('Access denied. Your API key may not have permission for this operation.');
|
|
56
|
+
}
|
|
57
|
+
if (response.status === 404) {
|
|
58
|
+
throw new Error('Resource not found. The requested employee, team, or location may not exist.');
|
|
59
|
+
}
|
|
60
|
+
if (response.status === 429) {
|
|
61
|
+
throw new Error('Rate limit exceeded. Please wait a moment before trying again.');
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`FactorialHR API error (${response.status}): ${errorText}`);
|
|
64
|
+
}
|
|
65
|
+
const data = await response.json();
|
|
66
|
+
debug('Response received', { endpoint, itemCount: Array.isArray(data) ? data.length : 1 });
|
|
67
|
+
return data;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
clearTimeout(timeoutId);
|
|
71
|
+
if (error instanceof Error) {
|
|
72
|
+
if (error.name === 'AbortError') {
|
|
73
|
+
throw new Error(`Request timed out after ${DEFAULT_TIMEOUT / 1000} seconds. Please try again.`);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
throw new Error('An unexpected error occurred while fetching data from FactorialHR.');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Employee endpoints
|
|
81
|
+
export async function listEmployees(options) {
|
|
82
|
+
const data = await factorialFetch('/employees/employees', options);
|
|
83
|
+
return data.data || [];
|
|
84
|
+
}
|
|
85
|
+
export async function getEmployee(id) {
|
|
86
|
+
if (!id || id <= 0) {
|
|
87
|
+
throw new Error('Invalid employee ID. Please provide a positive number.');
|
|
88
|
+
}
|
|
89
|
+
const data = await factorialFetch(`/employees/employees/${id}`);
|
|
90
|
+
return data.data;
|
|
91
|
+
}
|
|
92
|
+
export async function searchEmployees(query) {
|
|
93
|
+
if (!query || query.trim().length < 2) {
|
|
94
|
+
throw new Error('Search query must be at least 2 characters long.');
|
|
95
|
+
}
|
|
96
|
+
const employees = await listEmployees();
|
|
97
|
+
const lowerQuery = query.toLowerCase().trim();
|
|
98
|
+
return employees.filter(emp => emp.full_name?.toLowerCase().includes(lowerQuery) ||
|
|
99
|
+
emp.email?.toLowerCase().includes(lowerQuery) ||
|
|
100
|
+
emp.first_name?.toLowerCase().includes(lowerQuery) ||
|
|
101
|
+
emp.last_name?.toLowerCase().includes(lowerQuery));
|
|
102
|
+
}
|
|
103
|
+
// Team endpoints
|
|
104
|
+
export async function listTeams() {
|
|
105
|
+
const data = await factorialFetch('/teams/teams');
|
|
106
|
+
return data.data || [];
|
|
107
|
+
}
|
|
108
|
+
export async function getTeam(id) {
|
|
109
|
+
if (!id || id <= 0) {
|
|
110
|
+
throw new Error('Invalid team ID. Please provide a positive number.');
|
|
111
|
+
}
|
|
112
|
+
const data = await factorialFetch(`/teams/teams/${id}`);
|
|
113
|
+
return data.data;
|
|
114
|
+
}
|
|
115
|
+
// Location endpoints
|
|
116
|
+
export async function listLocations() {
|
|
117
|
+
const data = await factorialFetch('/locations/locations');
|
|
118
|
+
return data.data || [];
|
|
119
|
+
}
|
|
120
|
+
export async function getLocation(id) {
|
|
121
|
+
if (!id || id <= 0) {
|
|
122
|
+
throw new Error('Invalid location ID. Please provide a positive number.');
|
|
123
|
+
}
|
|
124
|
+
const data = await factorialFetch(`/locations/locations/${id}`);
|
|
125
|
+
return data.data;
|
|
126
|
+
}
|
|
127
|
+
// Contract endpoints
|
|
128
|
+
export async function listContracts(employeeId) {
|
|
129
|
+
if (employeeId !== undefined && employeeId <= 0) {
|
|
130
|
+
throw new Error('Invalid employee ID. Please provide a positive number.');
|
|
131
|
+
}
|
|
132
|
+
const params = employeeId ? { employee_id: employeeId } : undefined;
|
|
133
|
+
const data = await factorialFetch('/contracts/contract-versions', params);
|
|
134
|
+
return data.data || [];
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAIzB,MAAM,kBAAkB,GAAG,sDAAsD,CAAC;AAClF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,aAAa;AAE5C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC;AAE3C,SAAS,KAAK,CAAC,OAAe,EAAE,IAAc;IAC5C,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,qBAAqB,OAAO,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5F,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,qBAAqB,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,gCAAgC;YAChC,wEAAwE;YACxE,oEAAoE,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,QAAgB,EAChB,MAAoD;IAEpD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,kBAAkB,GAAG,QAAQ,EAAE,CAAC,CAAC;IAExD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAC9C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAErC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,eAAe,CAAC,CAAC;IAExE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC3C,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,WAAW,EAAE,SAAS,EAAE;gBACxB,QAAQ,EAAE,kBAAkB;aAC7B;YACD,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,KAAK,CAAC,cAAc,QAAQ,CAAC,MAAM,IAAI,EAAE,SAAS,CAAC,CAAC;YAEpD,uCAAuC;YACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;YAC7F,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAClG,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACpF,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAO,CAAC;QACxC,KAAK,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3F,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,2BAA2B,eAAe,GAAG,IAAI,6BAA6B,CAAC,CAAC;YAClG,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED,qBAAqB;AACrB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAGnC;IACC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAuB,sBAAsB,EAAE,OAAO,CAAC,CAAC;IACzF,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU;IAC1C,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAqB,wBAAwB,EAAE,EAAE,CAAC,CAAC;IACpF,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,aAAa,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAE9C,OAAO,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC5B,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;QACjD,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC7C,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;QAClD,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAClD,CAAC;AACJ,CAAC;AAED,iBAAiB;AACjB,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAmB,cAAc,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAU;IACtC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAiB,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACxE,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC;AAED,qBAAqB;AACrB,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAuB,sBAAsB,CAAC,CAAC;IAChF,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU;IAC1C,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAqB,wBAAwB,EAAE,EAAE,CAAC,CAAC;IACpF,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC;AAED,qBAAqB;AACrB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAmB;IACrD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,cAAc,CAAuB,8BAA8B,EAAE,MAAM,CAAC,CAAC;IAChG,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server for FactorialHR
|
|
4
|
+
*
|
|
5
|
+
* Provides access to employee and organizational data from FactorialHR
|
|
6
|
+
* through the Model Context Protocol for use with Claude Code and other MCP clients.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server for FactorialHR
|
|
4
|
+
*
|
|
5
|
+
* Provides access to employee and organizational data from FactorialHR
|
|
6
|
+
* through the Model Context Protocol for use with Claude Code and other MCP clients.
|
|
7
|
+
*/
|
|
8
|
+
import { config } from 'dotenv';
|
|
9
|
+
import { existsSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
// Load environment variables from .env file
|
|
12
|
+
// Priority: ENV_FILE_PATH > cwd/.env > home/.env
|
|
13
|
+
function loadEnv() {
|
|
14
|
+
// 1. Check if explicit path provided
|
|
15
|
+
if (process.env.ENV_FILE_PATH && existsSync(process.env.ENV_FILE_PATH)) {
|
|
16
|
+
config({ path: process.env.ENV_FILE_PATH });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// 2. Check current working directory
|
|
20
|
+
const cwdEnv = join(process.cwd(), '.env');
|
|
21
|
+
if (existsSync(cwdEnv)) {
|
|
22
|
+
config({ path: cwdEnv });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// 3. Check home directory
|
|
26
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
27
|
+
const homeEnv = join(homeDir, '.env');
|
|
28
|
+
if (existsSync(homeEnv)) {
|
|
29
|
+
config({ path: homeEnv });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// 4. Check common project locations
|
|
33
|
+
const commonPaths = [
|
|
34
|
+
join(homeDir, 'turborepo', '.env'),
|
|
35
|
+
join(homeDir, 'projects', '.env'),
|
|
36
|
+
];
|
|
37
|
+
for (const envPath of commonPaths) {
|
|
38
|
+
if (existsSync(envPath)) {
|
|
39
|
+
config({ path: envPath });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Fall back to default dotenv behavior
|
|
44
|
+
config();
|
|
45
|
+
}
|
|
46
|
+
loadEnv();
|
|
47
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
48
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
49
|
+
import * as z from 'zod';
|
|
50
|
+
import { listEmployees, getEmployee, searchEmployees, listTeams, getTeam, listLocations, getLocation, listContracts, } from './api.js';
|
|
51
|
+
const server = new McpServer({
|
|
52
|
+
name: 'factorial-hr',
|
|
53
|
+
version: '1.0.0',
|
|
54
|
+
});
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Employee Tools
|
|
57
|
+
// ============================================================================
|
|
58
|
+
server.registerTool('list_employees', {
|
|
59
|
+
title: 'List Employees',
|
|
60
|
+
description: 'Get all employees from FactorialHR. Can filter by team or location.',
|
|
61
|
+
inputSchema: {
|
|
62
|
+
team_id: z.number().optional().describe('Filter by team ID'),
|
|
63
|
+
location_id: z.number().optional().describe('Filter by location ID'),
|
|
64
|
+
},
|
|
65
|
+
}, async ({ team_id, location_id }) => {
|
|
66
|
+
try {
|
|
67
|
+
const employees = await listEmployees({ team_id, location_id });
|
|
68
|
+
const summary = employees.map(e => ({
|
|
69
|
+
id: e.id,
|
|
70
|
+
name: e.full_name,
|
|
71
|
+
email: e.email,
|
|
72
|
+
role: e.role,
|
|
73
|
+
team_ids: e.team_ids,
|
|
74
|
+
location_id: e.location_id,
|
|
75
|
+
}));
|
|
76
|
+
return {
|
|
77
|
+
content: [
|
|
78
|
+
{
|
|
79
|
+
type: 'text',
|
|
80
|
+
text: `Found ${employees.length} employees:\n\n${JSON.stringify(summary, null, 2)}`,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
return {
|
|
87
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
88
|
+
isError: true,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
server.registerTool('get_employee', {
|
|
93
|
+
title: 'Get Employee',
|
|
94
|
+
description: 'Get detailed information about a specific employee by their ID.',
|
|
95
|
+
inputSchema: {
|
|
96
|
+
id: z.number().describe('The employee ID'),
|
|
97
|
+
},
|
|
98
|
+
}, async ({ id }) => {
|
|
99
|
+
try {
|
|
100
|
+
const employee = await getEmployee(id);
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: 'text',
|
|
105
|
+
text: JSON.stringify(employee, null, 2),
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return {
|
|
112
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
113
|
+
isError: true,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
server.registerTool('search_employees', {
|
|
118
|
+
title: 'Search Employees',
|
|
119
|
+
description: 'Search for employees by name or email.',
|
|
120
|
+
inputSchema: {
|
|
121
|
+
query: z.string().describe('Search query (name or email)'),
|
|
122
|
+
},
|
|
123
|
+
}, async ({ query }) => {
|
|
124
|
+
try {
|
|
125
|
+
const employees = await searchEmployees(query);
|
|
126
|
+
if (employees.length === 0) {
|
|
127
|
+
return {
|
|
128
|
+
content: [{ type: 'text', text: `No employees found matching "${query}"` }],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const summary = employees.map(e => ({
|
|
132
|
+
id: e.id,
|
|
133
|
+
name: e.full_name,
|
|
134
|
+
email: e.email,
|
|
135
|
+
role: e.role,
|
|
136
|
+
}));
|
|
137
|
+
return {
|
|
138
|
+
content: [
|
|
139
|
+
{
|
|
140
|
+
type: 'text',
|
|
141
|
+
text: `Found ${employees.length} employees matching "${query}":\n\n${JSON.stringify(summary, null, 2)}`,
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
return {
|
|
148
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
149
|
+
isError: true,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
// ============================================================================
|
|
154
|
+
// Team Tools
|
|
155
|
+
// ============================================================================
|
|
156
|
+
server.registerTool('list_teams', {
|
|
157
|
+
title: 'List Teams',
|
|
158
|
+
description: 'Get all teams in the organization.',
|
|
159
|
+
inputSchema: {},
|
|
160
|
+
}, async () => {
|
|
161
|
+
try {
|
|
162
|
+
const teams = await listTeams();
|
|
163
|
+
const summary = teams.map(t => ({
|
|
164
|
+
id: t.id,
|
|
165
|
+
name: t.name,
|
|
166
|
+
description: t.description,
|
|
167
|
+
employee_count: t.employee_ids?.length || 0,
|
|
168
|
+
}));
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: 'text',
|
|
173
|
+
text: `Found ${teams.length} teams:\n\n${JSON.stringify(summary, null, 2)}`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
return {
|
|
180
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
181
|
+
isError: true,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
server.registerTool('get_team', {
|
|
186
|
+
title: 'Get Team',
|
|
187
|
+
description: 'Get detailed information about a specific team by its ID.',
|
|
188
|
+
inputSchema: {
|
|
189
|
+
id: z.number().describe('The team ID'),
|
|
190
|
+
},
|
|
191
|
+
}, async ({ id }) => {
|
|
192
|
+
try {
|
|
193
|
+
const team = await getTeam(id);
|
|
194
|
+
return {
|
|
195
|
+
content: [
|
|
196
|
+
{
|
|
197
|
+
type: 'text',
|
|
198
|
+
text: JSON.stringify(team, null, 2),
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return {
|
|
205
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
206
|
+
isError: true,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
// ============================================================================
|
|
211
|
+
// Location Tools
|
|
212
|
+
// ============================================================================
|
|
213
|
+
server.registerTool('list_locations', {
|
|
214
|
+
title: 'List Locations',
|
|
215
|
+
description: 'Get all company locations.',
|
|
216
|
+
inputSchema: {},
|
|
217
|
+
}, async () => {
|
|
218
|
+
try {
|
|
219
|
+
const locations = await listLocations();
|
|
220
|
+
const summary = locations.map(l => ({
|
|
221
|
+
id: l.id,
|
|
222
|
+
name: l.name,
|
|
223
|
+
city: l.city,
|
|
224
|
+
country: l.country,
|
|
225
|
+
}));
|
|
226
|
+
return {
|
|
227
|
+
content: [
|
|
228
|
+
{
|
|
229
|
+
type: 'text',
|
|
230
|
+
text: `Found ${locations.length} locations:\n\n${JSON.stringify(summary, null, 2)}`,
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
return {
|
|
237
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
238
|
+
isError: true,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
server.registerTool('get_location', {
|
|
243
|
+
title: 'Get Location',
|
|
244
|
+
description: 'Get detailed information about a specific location by its ID.',
|
|
245
|
+
inputSchema: {
|
|
246
|
+
id: z.number().describe('The location ID'),
|
|
247
|
+
},
|
|
248
|
+
}, async ({ id }) => {
|
|
249
|
+
try {
|
|
250
|
+
const location = await getLocation(id);
|
|
251
|
+
return {
|
|
252
|
+
content: [
|
|
253
|
+
{
|
|
254
|
+
type: 'text',
|
|
255
|
+
text: JSON.stringify(location, null, 2),
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
return {
|
|
262
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
263
|
+
isError: true,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
// ============================================================================
|
|
268
|
+
// Contract Tools
|
|
269
|
+
// ============================================================================
|
|
270
|
+
server.registerTool('get_employee_contracts', {
|
|
271
|
+
title: 'Get Employee Contracts',
|
|
272
|
+
description: 'Get contract versions for an employee, including job title and effective date.',
|
|
273
|
+
inputSchema: {
|
|
274
|
+
employee_id: z.number().describe('The employee ID'),
|
|
275
|
+
},
|
|
276
|
+
}, async ({ employee_id }) => {
|
|
277
|
+
try {
|
|
278
|
+
const contracts = await listContracts(employee_id);
|
|
279
|
+
return {
|
|
280
|
+
content: [
|
|
281
|
+
{
|
|
282
|
+
type: 'text',
|
|
283
|
+
text: `Found ${contracts.length} contracts:\n\n${JSON.stringify(contracts, null, 2)}`,
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
return {
|
|
290
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
|
|
291
|
+
isError: true,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
// ============================================================================
|
|
296
|
+
// Start Server
|
|
297
|
+
// ============================================================================
|
|
298
|
+
async function main() {
|
|
299
|
+
const transport = new StdioServerTransport();
|
|
300
|
+
await server.connect(transport);
|
|
301
|
+
}
|
|
302
|
+
main().catch((error) => {
|
|
303
|
+
console.error('Fatal error:', error);
|
|
304
|
+
process.exit(1);
|
|
305
|
+
});
|
|
306
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,4CAA4C;AAC5C,iDAAiD;AACjD,SAAS,OAAO;IACd,qCAAqC;IACrC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QACvE,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,qCAAqC;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IAED,0BAA0B;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,oCAAoC;IACpC,MAAM,WAAW,GAAG;QAClB,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC;QAClC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC;KAClC,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,MAAM,EAAE,CAAC;AACX,CAAC;AAED,OAAO,EAAE,CAAC;AAEV,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,EACf,SAAS,EACT,OAAO,EACP,aAAa,EACb,WAAW,EACX,aAAa,GACd,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;IACE,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,qEAAqE;IAClF,WAAW,EAAE;QACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAC5D,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;KACrE;CACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE;IACjC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,SAAS;YACjB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC,CAAC;QACJ,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,SAAS,CAAC,MAAM,kBAAkB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACpF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;IACE,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,iEAAiE;IAC9E,WAAW,EAAE;QACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KAC3C;CACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IACf,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;QACvC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;IACE,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,wCAAwC;IACrD,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;KAC3D;CACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IAClB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gCAAgC,KAAK,GAAG,EAAE,CAAC;aAC5E,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,SAAS;YACjB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI;SACb,CAAC,CAAC,CAAC;QACJ,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,SAAS,CAAC,MAAM,wBAAwB,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACxG;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;IACE,KAAK,EAAE,YAAY;IACnB,WAAW,EAAE,oCAAoC;IACjD,WAAW,EAAE,EAAE;CAChB,EACD,KAAK,IAAI,EAAE;IACT,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,cAAc,EAAE,CAAC,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC;SAC5C,CAAC,CAAC,CAAC;QACJ,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,KAAK,CAAC,MAAM,cAAc,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBAC5E;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,UAAU,EACV;IACE,KAAK,EAAE,UAAU;IACjB,WAAW,EAAE,2DAA2D;IACxE,WAAW,EAAE;QACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;KACvC;CACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IACf,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QAC/B,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;iBACpC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;IACE,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,4BAA4B;IACzC,WAAW,EAAE,EAAE;CAChB,EACD,KAAK,IAAI,EAAE;IACT,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,aAAa,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC,CAAC;QACJ,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,SAAS,CAAC,MAAM,kBAAkB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACpF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;IACE,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,+DAA+D;IAC5E,WAAW,EAAE;QACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KAC3C;CACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IACf,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;QACvC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;IACE,KAAK,EAAE,wBAAwB;IAC/B,WAAW,EAAE,gFAAgF;IAC7F,WAAW,EAAE;QACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KACpD;CACF,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;QACnD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,SAAS,CAAC,MAAM,kBAAkB,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACtF;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACvG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface Employee {
|
|
2
|
+
id: number;
|
|
3
|
+
first_name: string;
|
|
4
|
+
last_name: string;
|
|
5
|
+
full_name: string;
|
|
6
|
+
email: string;
|
|
7
|
+
birthday_on: string | null;
|
|
8
|
+
terminated_on: string | null;
|
|
9
|
+
gender: string | null;
|
|
10
|
+
nationality: string | null;
|
|
11
|
+
manager_id: number | null;
|
|
12
|
+
role: string | null;
|
|
13
|
+
timeoff_manager_id: number | null;
|
|
14
|
+
company_id: number;
|
|
15
|
+
legal_entity_id: number | null;
|
|
16
|
+
team_ids: number[];
|
|
17
|
+
location_id: number | null;
|
|
18
|
+
created_at: string;
|
|
19
|
+
updated_at: string;
|
|
20
|
+
}
|
|
21
|
+
export interface Team {
|
|
22
|
+
id: number;
|
|
23
|
+
name: string;
|
|
24
|
+
description: string | null;
|
|
25
|
+
company_id: number;
|
|
26
|
+
employee_ids: number[];
|
|
27
|
+
lead_ids: number[];
|
|
28
|
+
created_at: string;
|
|
29
|
+
updated_at: string;
|
|
30
|
+
}
|
|
31
|
+
export interface Location {
|
|
32
|
+
id: number;
|
|
33
|
+
name: string;
|
|
34
|
+
country: string | null;
|
|
35
|
+
phone_number: string | null;
|
|
36
|
+
state: string | null;
|
|
37
|
+
city: string | null;
|
|
38
|
+
address_line_1: string | null;
|
|
39
|
+
address_line_2: string | null;
|
|
40
|
+
postal_code: string | null;
|
|
41
|
+
company_id: number;
|
|
42
|
+
created_at: string;
|
|
43
|
+
updated_at: string;
|
|
44
|
+
}
|
|
45
|
+
export interface Contract {
|
|
46
|
+
id: number;
|
|
47
|
+
employee_id: number;
|
|
48
|
+
job_title: string | null;
|
|
49
|
+
effective_on: string;
|
|
50
|
+
created_at: string;
|
|
51
|
+
updated_at: string;
|
|
52
|
+
}
|
|
53
|
+
export interface ApiError {
|
|
54
|
+
error: string;
|
|
55
|
+
message: string;
|
|
56
|
+
status: number;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iCAAiC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@t4dhg/mcp-factorial",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for FactorialHR - Access employee and organizational data from FactorialHR in Claude Code and other MCP clients",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mcp-factorial": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"start": "node dist/index.js",
|
|
23
|
+
"dev": "tsc --watch"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"mcp",
|
|
27
|
+
"model-context-protocol",
|
|
28
|
+
"factorial",
|
|
29
|
+
"factorialhr",
|
|
30
|
+
"hr",
|
|
31
|
+
"claude",
|
|
32
|
+
"anthropic"
|
|
33
|
+
],
|
|
34
|
+
"author": "t4dhg",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/t4dhg/mcp-factorial.git"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
42
|
+
"dotenv": "^16.4.0",
|
|
43
|
+
"zod": "^3.24.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^22.10.0",
|
|
47
|
+
"typescript": "^5.7.0"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18.0.0"
|
|
51
|
+
}
|
|
52
|
+
}
|